From db101f0c1ad7e5c6bf2dd88a80e89fa70160093e Mon Sep 17 00:00:00 2001 From: Piotr Chabelski Date: Thu, 25 Aug 2022 09:20:17 +0200 Subject: [PATCH] Add Markdown guide --- website/docs/guides/markdown.md | 275 ++++++++++++++++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 website/docs/guides/markdown.md diff --git a/website/docs/guides/markdown.md b/website/docs/guides/markdown.md new file mode 100644 index 0000000000..be06bf6fd5 --- /dev/null +++ b/website/docs/guides/markdown.md @@ -0,0 +1,275 @@ +--- +title: Markdown (experimental) +sidebar_position: 21 +--- + +import {ChainedSnippets} from "../../src/components/MarkdownComponents.js"; + +Scala CLI can compile, run, test, and package markdown (`.md`) sources. + +:::note +This feature is a work in progress and should currently be treated as experimental. +Markdown sources are ignored by default unless passed explicitly as inputs. +You can enable including non-explicit `.md` inputs by passing the `--enable-markdown` option. +::: + +## Plain `scala` snippets + +````markdown title=Example.md +# Example + +This is a simple example of an `.md` file with a Scala snippet. + +```scala +val message = "Hello from Markdown" +println(message) +``` +```` + +Plain `scala` snippets are treated similarly to `.sc` scripts in that any kind of statement is accepted at the +top-level. + + + +```bash ignore +scala-cli run Example.md +``` + +```text +Hello from Markdown +``` + + + +Similarly to `.sc` scripts, when multiple `.md` files with plain `scala` snippets are being run, each of them will have +its own main class, that can be run. + + + +```bash ignore +scala-cli Example1.md Example2.md +``` + +```text +[error] Found several main classes: Example1_md, Example2_md +``` + + + +When multiple such sources are passed as inputs, the main class has to be passed explicitly with the `--main-class` +option. + + + +```bash ignore +scala-cli Example1.md Example2.md --main-class Example1_md +``` + +```text +Hello from Markdown +``` + + + +You can always check what main classes are available in the context with the `--list-main-classes` option. + + + +```bash ignore +scala-cli Example1.md Example2.md --list-main-classes +``` + +```text +Example1_md Example2_md +``` + + + +## `scala raw` snippets + +You can mark a `scala` code block with the `raw` keyword, indicating that this snippet should not be wrapped as a script +and should instead be treated as is. This is the equivalent of code in a `.scala` file. For a `raw` snippet to be +runnable a main class has to be included. + +````markdown title=RawExample.md +# `raw` example + +This is a simple example of an `.md` file with a raw Scala snippet. + +```scala raw +object Main extends App { + val message = "Hello from Markdown" + println(message) +} +``` +```` + + + +```bash ignore +scala-cli RawExample.md +``` + +```text +Hello from Markdown +``` + + + +## `scala test` snippets + +It is possible to run tests from `scala` code blocks marked as `test`. This is similar to `raw` snippets in that the +code is not wrapped and is treated as is. + +You can run `scala test` code blocks with the `test` sub-command. + +````markdown title=TestExample.md +# `test` example +This is a simple example of an `.md` file with a test Scala snippet. + +```scala test +//> using lib "org.scalameta::munit:0.7.29" +class Test extends munit.FunSuite { + test("example test") { + assert(true) + } +} +``` +```` + + + +```bash ignore +scala-cli test TestExample.md +``` + +```text +Test: + + example test +``` + + + +## `reset` scope for `scala` snippets + +When multiple plain `scala` snippets are used in a single `.md` file, by default they are actually treated as a single +script. They share context and when run, are executed one after another, as if they were all in a single `.sc` file. + +If you want a snippet to use a fresh context instead, you can rely on the `reset` keyword. This allows you to start a +fresh scope for the marked snippet (and any coming after it). + +````markdown title=ResetExample.md +# `reset` scope +This is an example of an `.md` file with multiple `scala` snippets with separate scopes + +## Scope 1 +```scala +val message = "Hello" +``` + +## Still scope 1, since `reset` wasn't used yet +```scala +println(message) +``` + +## Scope 2 +```scala reset +val message = "world" +println(message) +``` + +## Scope 3 +```scala reset +val message = "!" +println(message) +``` +```` + + + +```bash ignore +scala-cli test ResetExample.md +``` + +```text +Hello +world +! +``` + + + +## Referring to code from Markdown + +### Plain `scala` code blocks + +Referring to code from plain `scala` snippets in Markdown requires using their package name. +Similarly to scripts, the package is inferred based on the relative path to the source file in your project. + +You also have to point to the Scope under which the code is located. +Scopes are numbered according to their order in a given `.md` file (starting from 0 for the first plain `scala` +snippet): `Scope{scopeNumber}`. The `snippetNumber` is omitted for the first script code block (0). In other words, +the first scope is just `Scope`, the second is `Scope1`, then `Scope2` and so on. + +````markdown title=src/markdown/Example.md +## Scope 1 +```scala +def hello: String = "Hello" +``` + +## Still scope 1, since `reset` wasn't used yet +```scala +def space: String = " " +``` + +## Scope 2 +```scala reset +def world: String = "world" +``` +```` + +```scala title=Main.scala +object Main extends App { + val hello = src.markdown.Example_md.Scope.hello + val space = src.markdown.Example_md.Scope.space + val world = src.markdown.Example_md.Scope.world + println(s"$hello$space$world) +} +``` + + + +```bash ignore +scala-cli . --enable-markdown --main-class Main +``` + +```text +Hello world +``` + + + +### `scala raw` and `scala test` code blocks + +You can refer to code from `scala raw` and `scala test` snippets as if they were the contents of a `.scala` file. + +````markdown title=RawSnippetToReferTo.md +# `raw` snippet +```scala raw +object Something { + def message: String = "Hello" +} +``` +```` + + + +```bash ignore +scala-cli RawSnippetToReferTo.md -e 'println(Something.message)' +``` + +```text +Hello +``` + +