diff --git a/cli/src/main/scala/mdoc/PreModifierContext.scala b/cli/src/main/scala/mdoc/PreModifierContext.scala index 46686317..59169a59 100644 --- a/cli/src/main/scala/mdoc/PreModifierContext.scala +++ b/cli/src/main/scala/mdoc/PreModifierContext.scala @@ -6,9 +6,11 @@ import mdoc.internal.cli.Settings import mdoc.internal.cli.CliEnrichments._ import scala.meta.io.AbsolutePath import mdoc.internal.cli.InputFile +import mdoc.parser.Text final class PreModifierContext private[mdoc] ( val info: String, + val fences: Text, val originalCode: Input, val reporter: Reporter, private[mdoc] val file: InputFile, diff --git a/docs/tut.md b/docs/tut.md index 7955c6db..307b6959 100644 --- a/docs/tut.md +++ b/docs/tut.md @@ -47,7 +47,7 @@ Use the sbt-mdoc plugin instead of sbt-tut and run `sbt docs/mdoc` instead of + enablePlugins(MdocPlugin) ``` -The sbt-mdoc plugin exposes only one task `mdoc`. +The sbt-mdoc plugin exposes only one task `mdoc` . | tut | mdoc | | ---------------------- | ---------------------------------------- | diff --git a/mdoc-js/src/main/scala/mdoc/modifiers/JsModifier.scala b/mdoc-js/src/main/scala/mdoc/modifiers/JsModifier.scala index 357d8303..881fd6c5 100644 --- a/mdoc-js/src/main/scala/mdoc/modifiers/JsModifier.scala +++ b/mdoc-js/src/main/scala/mdoc/modifiers/JsModifier.scala @@ -199,15 +199,15 @@ class JsModifier extends mdoc.PreModifier { } override def process(ctx: PreModifierContext): String = { - JsMods.parse(ctx.infoInput, ctx.reporter) match { - case Some(mods) => - process(ctx, mods) - case None => + JsMods.parse(ctx.fences, ctx.infoInput, ctx.reporter) match { + case AllMods(Some(jsmods), remaining) => + process(ctx, jsmods, remaining) + case AllMods(None, _) => "" } } - def process(ctx: PreModifierContext, mods: JsMods): String = { + def process(ctx: PreModifierContext, mods: JsMods, remainingMods: Array[String]): String = { val separator = "\n---\n" val text = ctx.originalCode.text val separatorIndex = text.indexOf(separator) @@ -252,7 +252,11 @@ class JsModifier extends mdoc.PreModifier { runs += code new CodeBuilder() - .printlnIf(!mods.isInvisible, s"```scala\n${input.text}\n```") + .printIf(!mods.isInvisible, s"```scala") + .printIf(!remainingMods.isEmpty && !mods.isInvisible, remainingMods.mkString(" ", " ", "")) + .printIf(remainingMods.isEmpty && !mods.isInvisible, s"\n") + .printIf(!mods.isInvisible, s"${input.text}\n```") + .printIf(!mods.isInvisible, s"\n") .printlnIf(mods.isEntrypoint, s"""
$body
""") .toString } diff --git a/mdoc-js/src/main/scala/mdoc/modifiers/JsMods.scala b/mdoc-js/src/main/scala/mdoc/modifiers/JsMods.scala index 588f6360..b305f576 100644 --- a/mdoc-js/src/main/scala/mdoc/modifiers/JsMods.scala +++ b/mdoc-js/src/main/scala/mdoc/modifiers/JsMods.scala @@ -4,6 +4,10 @@ import mdoc.Reporter import mdoc.internal.pos.PositionSyntax._ import scala.annotation.tailrec import scala.meta.inputs.Input +import mdoc.parser.Text +import mdoc.internal.markdown.LinkHygiene + +case class AllMods(jsMods: Option[JsMods], otherMods: Array[String]) class JsMods private (val mods: Set[String]) { def isShared: Boolean = mods("shared") @@ -13,7 +17,7 @@ class JsMods private (val mods: Set[String]) { } object JsMods { - val all = Set("shared", "invisible", "compile-only") + val validFences = Set("shared", "invisible", "compile-only") def parse(info: Input, reporter: Reporter): Option[JsMods] = { val text = info.text @tailrec def loop(from: Int, accum: Set[String]): Option[Set[String]] = { @@ -25,7 +29,7 @@ object JsMods { } else { text.substring(from, colon) } - val isValid = all.contains(mod) + val isValid = validFences.contains(mod) if (isValid && colon < 0) { loop(text.length + 1, accum + mod) } else if (isValid) { @@ -49,4 +53,18 @@ object JsMods { } } } + + def parse(fences: Text, info: Input, reporter: Reporter): AllMods = { + val jsMods = parse(info, reporter) + + if (reporter.hasErrors) { + AllMods(jsMods, Array[String]()) + } else { + // We already know that the scala fences are valid. + val fenceBlocks = fences.value.split(" ") + val dropScala = fenceBlocks.tail // first entry is scala + val remainingFences = dropScala.filterNot(_.contains("mdoc:js")) + AllMods(jsMods, remainingFences) + } + } } diff --git a/mdoc/src/main/scala/mdoc/internal/markdown/Processor.scala b/mdoc/src/main/scala/mdoc/internal/markdown/Processor.scala index 0cda09c7..e1d5e394 100644 --- a/mdoc/src/main/scala/mdoc/internal/markdown/Processor.scala +++ b/mdoc/src/main/scala/mdoc/internal/markdown/Processor.scala @@ -78,11 +78,12 @@ class Processor(implicit ctx: Context) { } def processPreInput(doc: MarkdownFile, custom: PreFenceInput): Unit = { - val PreFenceInput(block, input, Pre(mod, info)) = custom + val PreFenceInput(block: CodeFence, input, Pre(mod, info)) = custom try { val inputFile = doc.file.relpath val preCtx = new PreModifierContext( info, + block.info, input, ctx.reporter, doc.file, @@ -249,6 +250,7 @@ class Processor(implicit ctx: Context) { case c: Modifier.Pre => val preCtx = new PreModifierContext( c.info, + block.info, section.input, ctx.reporter, doc.file, diff --git a/tests/unit-js/src/test/scala/tests/js/JsSuite.scala b/tests/unit-js/src/test/scala/tests/js/JsSuite.scala index 9ca4cccf..56adba9c 100644 --- a/tests/unit-js/src/test/scala/tests/js/JsSuite.scala +++ b/tests/unit-js/src/test/scala/tests/js/JsSuite.scala @@ -32,6 +32,22 @@ class JsSuite extends BaseMarkdownSuite { """.stripMargin ) + check( + "extra_fences", + """ + |```scala mdoc:js sc:nocompile + |println("hello world!") + |``` + |""".stripMargin, + """|```scala sc:nocompile + |println("hello world!") + |``` + |
+ | + | + """.stripMargin + ) + checkError( "error", """