This post introduces how mdoc evaluates Scala code examples with good performance while reporting clear error messages. mdoc is a markdown documentation tool inspired by tut.
Like tut, mdoc reads markdown files as input and produces markdown files as output with the Scala code examples evaluated. Unlike tut, mdoc does not use the Scala REPL to evaluate Scala code examples. Instead, mdoc translates each markdown file into a regular Scala program that evaluates in one run. In this post, we look into the implications of this change and how it can deliver up to 27x faster performance when processing invalid documents.
You can now write mdoc:js code fences that compile with Scala.js and evaluate as JavaScript in the browser. This features is great for Scala.js libraries to write interactive documentation. To learn more, see the documentation.
No spurious -Ywarn-discard-value warnings
He mdoc generated code previously reported a warning when compiled with the -Ywarn-discard-value option. Now, the generated code no longer reports warnings.
Clearer error messages for generated code
Previously, errors in generated mdoc code only reported the message without a position making it difficult to track down the problem. Now, errors in generated code show the generated code making it easier to see what's going on.
It is no longer possible to make --out a subdirectory of --in to prevent the number of files for mdoc to process to grow exponentially. Previously, this situation could silently happen with mis-configuration in the build but now mdoc fails fast when it happens.
Build sbt-mdoc against sbt 1.0.0
The sbt-mdoc plugin is now compiled against sbt 1.0.0 to avoid binary compatibility issues.
Scala 2.12 introduced a regression that caused asynchronous code to hang forever in object constructors, see scala-dev/#195. This caused mdoc issues like #124, where futures would timeout. To workaround this problem, mdoc now uses the compiler option -Ydelambdafy:inline by default.
New --no-link-hygiene option
Use the command-line argument --no-link-hygiene to disable link hygiene so that warnings are not reported. With sbt-mdoc, add
mdocExtraArguments := List("--no-link-hygiene")
Markdown footnotes now work
Previously, markdown footnotes would render incorrectly, which has now been fixed so it's possible to write like below.
Paragraph with a footnote reference[^1]
[^1]: Footnote text added at the bottom of the document
Improved stack traces
Previously, exceptions with causes were printed with full stack traces. Now, all exception stacktraces are trimmed to only show relevant parts.
It's now possible to declare sealed ADTs like below without getting a warning warning: The outer reference in this type test cannot be checked at run time..
sealedabstractclassMaybe[+A] extendsProductwithSerializablefinalcaseclassJust[A](value: A) extendsMaybe[A]finalcaseobjectNothingextendsMaybe[Nothing]
The error happened because we wrapped the code in class Session { class App { ... } }. Now, we wrap the code in object Session { object App { ... } } instead, which removes the warning.
It's now possible to combine modifiers like reset:silent or reset:fail.
```scala mdoc
val x = 1
``````scala mdoc:reset:fail
println(x)
```
This example produces the following output.
val x = 1// x: Int = 1
println(x)
// error: not found: value x// println(x)// ^
Relative filenames in :crash stacktraces
Previously, stack traces from :crash included absolute paths. Now they include only relative filenames.
// scala.MatchError: final val x = 2 (of class scala.meta.Defn$Val$DefnValImpl)
-// at repl.Session.$anonfun$app$47(/Users/ollie/dev/scalameta-tutorial/docs/trees/guide.md:252)+// at repl.Session.$anonfun$app$47(guide.md:252)
I am pleased to announce the release of mdoc v1.0.0. mdoc is a markdown documentation tool for Scala inspired by tut.
New website
The mdoc readme has been replaced with this website and the documentation has been expanded to cover mdoc features in more depth. There is a new "Coming from tut" guide to help tut users migrate to mdoc.
New sbt plugin
There is now an sbt-mdoc plugin that makes it easier to use mdoc from sbt builds. See the installation instructions to learn how to use sbt-mdoc.
Docusaurus integration
The sbt-mdoc plugin includes a DocusaurusPlugin to integrate mdoc with Docusaurus. Several projects already use mdoc in combination with Docusaurus:
See the docusaurus instructions to learn how to use DocusaurusPlugin and configure CI to publish to GitHub pages.
Improved :fail modifier
Previously, mdoc used Scala macros to implement the :fail modifier which produces incorrect compilation errors in rare cases. See #95. Now, mdoc translates each :fail modifier into a standalone Scala program and compiles it with the Scala compiler ensuring that compile errors are always accurate.
New :reset modifier
Now it's possible to clear all leading imports and declarations in the markdown document with the mdoc:reset modifier.
New organization
Previously, the mdoc repository lived in olafurpg/mdoc and was published under com.geirsson. Now, mdoc lives in scalameta/mdoc and is published under org.scalameta.