This is an in-depth explanation of what Subatomic does when added to your build and why it needs to do so. You don't need to know this in 90% of usage scenarios
When building a static site for a library there are several things we want the site builder to take care of us:
-
Markdown documents with Scala examples should be compiled and verified, using the classpath of the library we're documenting
-
We want to be able to pass the version from the build into markdown documents, so that our installation instructions don't get outdated
Subatomic manually invokes Mdoc as a separate Java process, so to make it aware of the classpath of the project we're building, we need to configure the build properly.
Say we have a SBT build as such:
build.sbt
lazy val core = project.in(file("core")).settings(...)
lazy val api = project.in(file("api")).dependsOn(core)
And we want to create documentation site for it, where snippets use code from both core
and api
.
We need to
-
Create a new
docs
project:lazy val docs = project.in(file("docs")).dependsOn(core, api)
-
Enable subatomic SBT plugin:
project/plugins.sbt
addSbtPlugin("com.indoorvivants" % "sbt-plugin" % "0.0.8+1-bf82d81a-SNAPSHOT")
build.sbt
lazy val docs = project .in(file("docs")) .dependsOn(core, api) .enablePlugins(SubatomicPlugin) .settings( subatomicInheritClasspath := true, // default, can be omitted subatomicBuildersDependency := true, // default, can be omitted subatomicMdocVariables := Map("VERSION" -> version.value) // default, can be omitted )
Doing so leads to two things happening:
-
docs
project now has dependency on"com.indoorvivants" %% "subatomic-builders" % "0.0.8+1-bf82d81a-SNAPSHOT"
- which brings all the core things Subatomic will need to build the site -
A managed resource file called subatomic.properties is created (and kept updated)
The subatomic.properties file can be accessed by Subatomic when building the site and in our example it will contain the following information:
classpath=...
variable.VERSION=...
I hope variable.VERSION
does not need explanation, so let's see what will classpath
contain:
docs
dependencies classpath (including Subatomic builders)docs
compiled classescore
dependencies classpathapi
dependencies classpathcore
compiled classesapi
compiled classes
This contains enough information to be passed to Mdoc so that it can compile and run examples in the documentation.
Note, that because the classpath contains docs
own classes, you can add
some class you need for documentation rendering (for example, subatomic itself uses several classes to render ANSI-coloured outputs), and use it from markdown documents.
For example:
docs/src/main/scala/PrettyOutput.scala
object Prettify {
def apply(out: String) =
s"<div class='pretty'>$out</div>"
}
And in your docs:
Pretty-printing:
```scala mdoc:passthrough
val result = (1 to 25).mkString(",")
println(Prettify(result))
```