How to write Scala documentation with runnable snippets, similar to mdbook? - scala

The Rust tool mdbook generates documentation from Markdown. It lets the reader edit and run Rust snippets directly in the browser by piping them to the Rust Playground. This lets you write readable documentation while letting your reader try out examples without cut-and-paste into a local editor. The Rust documentation uses this.
Is there anything like this for Scala? Scala has a playground (SCastie) so it seems the hard part has been dealt with. Perhaps there is a more general tool like gitbook that can do this by configuring SCastie as a backend?

Mdoc allows creating SCastie snippets out of your code.
From docs:
Before:
```scala mdoc:scastie
val x = 1 + 2
println(x)
```
After:
<script src="https://scastie.scala-lang.org/embedded.js"></script>
<pre class='scastie-snippet-2bc0b4f2-db76-4c68-8e7f-3a472d59c50d'></pre>
<script>window.addEventListener('load', function() {
scastie.Embedded('.scastie-snippet-2bc0b4f2-db76-4c68-8e7f-3a472d59c50d', {
code: `val x = 1 + 2
println(x)`,
theme: 'light',
isWorksheetMode: true,
targetType: 'jvm',
scalaVersion: '2.12.6'
})
})</script>

You can make scalafiddle snippets. See the documentation at https://github.com/scalafiddle/scalafiddle-core/blob/master/integrations/README.md

Related

org_scalajs_dom_raw_HTMLDocument(...).createRange is not a function

I'm upgrading scalatags from 0.6.7 to 0.9.3 as part of upgrading scalaJS from 0.6.x to 1.4.0.
I got the following error in some of my tests:
scala.scalajs.js.JavaScriptException: TypeError: $m_Lorg_scalajs_dom_package$(...).document__Lorg_scalajs_dom_raw_HTMLDocument(...).createRange is not a function
Tracing the code, I believe it occurs while executing line 141 of the following scalatags code in `scalatags.JsDom:
I extracted just the createRange call into a separate test and got the same error. "creating range" was printed; "created range" was not and it produced the same exception as above.
createRange() is a native function.
Googling "createRange is not a function" yields a number of similar issues, all seem to be related to testing (but not with ScalaJS). Many of them indicate the "fix" is to monkey-patch document with your own version of createRange. Really?
I initially thought this was an issue with scalatags. Then I thought it's with the scalajs library. Now I'm thinking it's something with Node.js, although Google is not producing any smoking guns.
Suggestions on how to proceed? Try to monkey patch document?
Summary: jsdom appears to be missing the document.createRange function when using Node.js for testing. Others in other languages have similar problems.
The following monkey patch worked for me. After developing this, I noticed that Facade Types has a section on monkey typing.
Also, the library code that tickled this bug (scalatags) actually calls document.createRange().createContextualFragment(v). So I needed to provide something for that as well.
import scala.scalajs.js
import org.scalajs.dom.document
js.Dynamic.global.document.createRange = () ⇒
js.Dynamic.literal(
setStart = () => js.Dynamic.literal(),
setEnd = () => js.Dynamic.literal(),
commonAncestorContainer = js.Dynamic.literal(
nodeName = "BODY",
ownerDocument = document
),
createContextualFragment = (v: String) ⇒ {
val p = document.createElement("p")
p.appendChild(document.createTextNode(v))
}
)

How does babel option ""auxiliaryCommentBefore" or "auxiliaryCommentAfter" work?

I installed Babel("babel-cli": "^6.26.0") and and made a .babelrc like
{
"auxiliaryCommentBefore": "testBefore",
"auxiliaryCommentAfter": "testAfter"
}
and also made a simple test.js like
var a = 5;
and finally run babel test.js.
It secceded but no comment above is attached..
My expectation is something like below.
testBefore
var a = 5;
testAfter
Is there anything required missing??
The honest answer to your question is "they don't" :D
The specific behavior of those two options are extremely under-defined and I would love to rip them out of Babel entirely, and I would except that I don't want to needlessly break existing users when they upgrade.
If you need to annotate some input code in a particular way, you should write your own Babel plugin to inject whatever you need instead.

How to embed Markdown in Scala code?

I know that in Scala we have sbt plugins which allow us to execute code embedded in Markdown, plugins like tut and sbt-site. But how can we do the opposite? I would like to embed Markdown in Scala code as part of comments.
E.g.:
// number.sc file
// # Markdown code
// some text
1 + 1
//res0: Int = 2
And the code will than be converted to markdown.
Here is how you add numbers:
```scala
scala> 1 + 1
res0: Int = 2
```
Does someone know if something similar already exists?

How to render a scalate template manually?

I want to try Scalate in this way:
Provide a scalate template, say: index.html
Use scala code to render it with some data manually
Any template format is OK(mustache, Scaml, SSP, Jade)
But I sad found nothing to do this even if I have read all the documentation and source code I found.
In order to make this question more clear, so I have such a template user.html:
<%# var user: User %>
<p>Hi ${user.name},</p>
#for (i <- 1 to 3)
<p>${i}</p>
#end
<p>See, I can count!</p>
I want to render it with a user instance User(name="Mike"). How to do it?
Suppose you have the following simple_example.mustache template:
I like {{programming_language}}
The code is {{code_description}}
You can render the template with this code:
import org.fusesource.scalate.TemplateEngine
val sourceDataPath = os.pwd/"simple_example.mustache".toString
val engine = new TemplateEngine
val someAttributes = Map(
"programming_language" -> "Scala",
"code_description" -> "pretty"
)
engine.layout(sourceDataPath, someAttributes)
Here's the result:
I like Scala
The code is pretty
Once you get past the initial learning hump, Scalate is actually pretty nice to work with (the docs don't make the lib easy to use).

How to define custom macros in MathJax

I'm trying to define custom macros used in LaTeX files in MathJax.
Can define simple macros (single parameter) without any issue such as;
\newcommand{\braket}[1]{\langle #1 \rangle}
as
Macros: {
braket: ['{\\langle #1 \\rangle}', 1]
}
But struggle with complicated ones;
\newcommand{\Abs}[2][]{\left\lvert#2\right\rvert_{\text{#1}}}
trying to define it like;
Macros: {
Abs: ['{\\left\\lvert#2\\rvert_{\\text{#1}}}', 2]
}
but no luck.
This is how it is used in LaTeX file
\begin{align}\nonumber
p_e = \Abs{\braket{e|\psi(t)}}^2 = \sin^2\Omega t\, .
\end{align}
Not sure where I did wrong.
I'm not a LaTeX expert, but just a developer trying to display LaTeX files on a web app (for Quantum Physics community), so I would greatly appreciate your help. thanks.
P.S this question was asked and closed on SE they redirected me to SO.
I've updated the codepen from my comment.
Primarliy, you forgot a \\right; I also modified your macro definition so that it has an optional parameter. In other words, something along the lines of:
Macros: {
braket: ['{\\langle #1 \\rangle}', 1],
Abs: ['\\left\\lvert #2 \\right\\rvert_{\\text{#1}}', 2, ""]
}},