15

我想在数学 Scala 代码的 Scaladoc 文档中输入数学公式。在 Java 中,我发现了一个名为 LatexTaglet 的库,它可以通过在 Latex 中编写公式来为 Javadoc 做到这一点:http: //latextaglet.sourceforge.net/

它似乎与 Maven 很好地集成(POM 的报告/插件部分)。Scaladoc 是否有等效的库?如果没有,我如何将此库与 SBT 集成?

我也考虑过使用 MathML ( http://www.w3.org/Math/ ),但看起来太冗长了。有没有推荐的编辑器?MathML 是否与 Scaladoc 很好地集成?

谢谢您的帮助!

4

4 回答 4

8

要遵循@mergeconflict 的答案,我是这样做的

由于没有合适的解决方案,我所做的是实现一个解析所有生成的 html 文件的爬虫,并通过导入 MathJax 脚本替换任何找到的“导入标记”(参见下面的代码):

lazy val mathFormulaInDoc  = taskKey[Unit]("add MathJax script import in doc html to display nice latex formula")

mathFormulaInDoc := {
  val apiDir = (doc in Compile).value
  val docDir = apiDir    // /"some"/"subfolder"  // in my case, only api/some/solder is parsed
  // will replace this "importTag" by "scriptLine
  val importTag  = "##import MathJax"
  val scriptLine = "<script type=\"text/javascript\" src=\"https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"> </script>"
  // find all html file and apply patch
  if(docDir.isDirectory)
    listHtmlFile(docDir).foreach { f =>
      val content = Source.fromFile(f).getLines().mkString("\n")
        if(content.contains(importTag)) {
          val writer = new PrintWriter(f)
          writer.write(content.replace(importTag, scriptLine))
          writer.close()
        }
    }
}

// attach this task to doc task
mathFormulaInDoc <<= mathFormulaInDoc triggeredBy (doc in Compile)

// function that find html files recursively
def listHtmlFile(dir: java.io.File): List[java.io.File] = {
  dir.listFiles.toList.flatMap { f =>
    if(f.getName.endsWith(".html")) List(f)
    else if(f.isDirectory)          listHtmlFile(f)
    else                            List[File]()
  }
}

如您所见,此爬虫任务附加到 doc 任务,它由sbt doc.

这是一个将使用公式呈现的文档示例

/**
 * Compute the energy using formula:
 *
 * ##import MathJax
 *
 * $$e = m\times c^2$$
 */
def energy(m: Double, c: Double) = m*c*c 

现在,可以改进此代码。例如:

  • 在 html 头部分添加脚本导入
  • 避免读取整个文件(也许添加一个规则,即导入标签应该在前几行
  • 将脚本添加到 sbt 包,并使用一些合适的任务将其添加到 target/api 文件夹
于 2015-08-20T09:29:27.100 回答
6

最简洁的答案是不。JavaDoc Taglet API 使 LaTeXTaglet 成为可能。Scaladoc 中没有等价物,因此没有干净的解决方案。

但是,我可以想到一个可能很容易做到的黑客:

有一个名为MathJax的库,它在 HTML 页面中查找 LaTeX 风格的数学公式,并在适当的位置动态呈现它。以前用过,挺好看的;您所要做的就是包含脚本。所以你可以做两件事:

  1. 编辑并重建Scaladoc源代码以包含 MathJax,或者...
  2. 编写一个小后处理器在运行后抓取 Scaladoc 的所有 HTML 输出,并将 MathJax 注入每个文件。

这样,您可以直接在 Scala 注释中编写 LaTeX 公式,它们应该在浏览器中呈现。当然,如果您想要一个非 hacky 的解决方案,我建议您为 Scaladoc 创建一个类似 taglet 的 API;)

于 2013-04-20T01:02:28.800 回答
1

即将推出的 scala3 aka Dotty内置了对降价的支持,它允许使用 Latex 的子集渲染简单的数学公式。

于 2019-04-14T16:23:41.247 回答
0

我通过使用与 Spark 相同的方法解决了这个问题。

将此 JavaScript 放在项目中某处的文件中:

// From Spark, licensed APL2
// https://github.com/apache/spark/commit/36827ddafeaa7a683362eb8da31065aaff9676d5

function injectMathJax() {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.async = true;
    script.onload = function(){
        MathJax.Hub.Config({
            displayAlign: "left",
            tex2jax: {
                inlineMath: [ ["$", "$"], ["\\\\(","\\\\)"] ],
                displayMath: [ ["$$","$$"], ["\\[", "\\]"] ],
                processEscapes: true,
                skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'a']
            }
        });
    };
    script.src = ('https:' == document.location.protocol ? 'https://' : 'http://') +
        'cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML';
    document.getElementsByTagName('head')[0].appendChild(script);
}

document.addEventListener('DOMContentLoaded', injectMathJax)

这一点进入你的build.sbt

lazy val injectMathJax = taskKey[Unit]("Injects MathJax Javascript into Scaladoc template.js")

injectMathJax := {
    val docPath = (Compile / doc).value
    val templateJsOutput = docPath / "lib" / "template.js"
    streams.value.log.info(s"Adding MathJax initialization to $templateJsOutput")
    // change this path, obviously
    IO.append(templateJsOutput, IO.readBytes(file("doc/static/js/mathjax_init.js")))
  },
  injectMathJax := (injectMathJax triggeredBy (Compile / doc)).value

我最终会为此构建并公开发布一个插件,因为我可能会使用 Scala 2.x 很长时间。

这种方法的注意事项:

  • 公式必须在$Scaladoc$$注释中。
  • 最好用另一个元素将它们进一步包含在注释中。我一直在使用<blockquote>
  • 至少对于 Scala 2.11.x 中包含的 Scaladoc,公式只会显示在类、对象和特征顶级符号上。当存在 MathJax-inject 元素时,切换中的某些内容会显示完整的注释中断我还没有弄清楚,但如果我这样做了,我会直接向 Scaladoc 提交一个补丁。

例子:

/**
  * A Mean Absolute Scaled Error implementation
  *
  * Non-seasonal MASE formula:
  * <blockquote>
  * $$
  * \mathrm{MASE} = \mathrm{mean}\left( \frac{\left| e_j \right|}{\frac{1}{T-1}\sum_{t=2}^T \left| Y_t-Y_{t-1}\right|} \right) = \frac{\frac{1}{J}\sum_{j}\left| e_j \right|}{\frac{1}{T-1}\sum_{t=2}^T \left| Y_t-Y_{t-1}\right|}
  * $$
  * </blockquote>
 **/
object MeanAbsoluteScaledError {
于 2019-12-13T20:29:02.107 回答