Skip to content

Commit 6d7f946

Browse files
authored
Ignore shebang headers in scala code blocks in Markdown inputs (#1647)
1 parent 210657a commit 6d7f946

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

modules/build/src/main/scala/scala/build/internal/markdown/MarkdownOpenFence.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package scala.build.internal.markdown
22

33
import scala.build.Position
44
import scala.build.errors.MarkdownUnclosedBackticksError
5+
import scala.build.preprocessing.SheBang
56

67
/** Representation for an open code block in Markdown. (open meaning the closing backticks haven't
78
* yet been parsed or they aren't at all present)
@@ -37,9 +38,11 @@ case class MarkdownOpenFence(
3738
): MarkdownCodeBlock = {
3839
val start: Int = tickStartLine + 1
3940
val bodyLines: Array[String] = lines.slice(start, tickEndLine)
41+
val body = bodyLines.mkString("\n")
42+
val (bodyWithNoSheBang, _) = SheBang.ignoreSheBangLines(body)
4043
MarkdownCodeBlock(
4144
info.split("\\s+").toList, // strip info by whitespaces
42-
bodyLines.mkString("\n"),
45+
bodyWithNoSheBang,
4346
start, // snippet has to begin in the new line
4447
tickEndLine - 1 // ending backticks have to be placed below the snippet
4548
)

modules/build/src/test/scala/scala/build/tests/markdown/MarkdownCodeBlockTests.scala

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,28 @@ class MarkdownCodeBlockTests extends munit.FunSuite {
4646
expect(actualResult == expectedResult)
4747
}
4848

49+
test("shebang line is ignored in plain scala code blocks") {
50+
val code = """println("Hello")""".stripMargin
51+
val markdown =
52+
s"""# Some snippet
53+
|
54+
|```scala
55+
|#!/usr/bin/env -S scala-cli shebang
56+
|$code
57+
|```
58+
|""".stripMargin
59+
val expectedResult =
60+
MarkdownCodeBlock(
61+
info = PlainScalaInfo,
62+
body = "\n" + code,
63+
startLine = 3,
64+
endLine = 4
65+
)
66+
val Right(Seq(actualResult: MarkdownCodeBlock)) =
67+
MarkdownCodeBlock.findCodeBlocks(os.sub / "Example.md", markdown)
68+
expect(actualResult == expectedResult)
69+
}
70+
4971
test("a raw Scala code block is extracted correctly from markdown") {
5072
val code = """object Main extends App {
5173
| println("Hello")
@@ -69,6 +91,31 @@ class MarkdownCodeBlockTests extends munit.FunSuite {
6991
expect(actualResult == expectedResult)
7092
}
7193

94+
test("shebang line is ignored in raw scala code blocks") {
95+
val code =
96+
"""object Main extends App {
97+
| println("Hello")
98+
|}""".stripMargin
99+
val markdown =
100+
s"""# Some snippet
101+
|
102+
|```scala raw
103+
|#!/usr/bin/env -S scala-cli shebang
104+
|$code
105+
|```
106+
|""".stripMargin
107+
val expectedResult =
108+
MarkdownCodeBlock(
109+
info = RawScalaInfo,
110+
body = "\n" + code,
111+
startLine = 3,
112+
endLine = 6
113+
)
114+
val Right(Seq(actualResult: MarkdownCodeBlock)) =
115+
MarkdownCodeBlock.findCodeBlocks(os.sub / "Example.md", markdown)
116+
expect(actualResult == expectedResult)
117+
}
118+
72119
test("a test Scala snippet is extracted correctly from markdown") {
73120
val code =
74121
"""//> using lib "org.scalameta::munit:0.7.29"

website/docs/guides/markdown.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,18 @@ world
337337

338338
</ChainedSnippets>
339339

340+
## `shebang` header and Markdown code blocks
341+
The `shebang` line in `scala` code blocks inside a markdown input are always ignored.
342+
You can use them (i.e. to give an example of their usage), but they do not change how the code is handled.
343+
344+
````markdown
345+
## Self executable Scala script
346+
```scala
347+
#!/usr/bin/env -S scala-cli shebang
348+
println("Hello world")
349+
```
350+
````
351+
340352
## `using` directives and Markdown code blocks
341353

342354
It is possible to define `using` directives at the beginning of a `scala` code block inside a markdown input.

0 commit comments

Comments
 (0)