Skip to content

Commit

Permalink
MarkdownParser: add formatter using mdoc parser
Browse files Browse the repository at this point in the history
  • Loading branch information
kitbellew committed Nov 9, 2023
1 parent 56aa7bf commit 4306100
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 143 deletions.
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ lazy val core = crossProject(JVMPlatform)
scalacOptions ++= scalacJvmOptions.value,
libraryDependencies ++= Seq(
scalameta.value,
"org.scalameta" %% "mdoc-parser" % mdocV,
// scala-reflect is an undeclared dependency of fansi, see #1252.
// Scalafmt itself does not require scala-reflect.
"org.scala-lang" % "scala-reflect" % scalaVersion.value
Expand Down
1 change: 1 addition & 0 deletions project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ object Dependencies {
val scalacheckV = "1.17.0"
val coursier = "2.1.2"
val munitV = "0.7.29"
val mdocV = "2.5.0"

val scalapb = Def.setting {
ExclusionRule(
Expand Down
26 changes: 5 additions & 21 deletions scalafmt-core/shared/src/main/scala/org/scalafmt/Scalafmt.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import org.scalafmt.internal.FormatOps
import org.scalafmt.internal.FormatWriter
import org.scalafmt.rewrite.Rewrite
import org.scalafmt.sysops.FileOps
import org.scalafmt.util.{MarkdownFile, MarkdownPart}
import org.scalafmt.util.MarkdownParser

/** WARNING. This API is discouraged when integrating with Scalafmt from a build
* tool or editor plugin. It is recommended to use the `scalafmt-dynamic`
Expand Down Expand Up @@ -118,25 +118,9 @@ object Scalafmt {
file: String,
range: Set[Range]
): Try[String] =
if (FileOps.isMarkdown(file)) {
val markdown = MarkdownFile.parse(Input.VirtualFile(file, code))

val resultIterator: Iterator[Try[String]] =
markdown.parts.iterator.collect {
case fence: MarkdownPart.CodeFence
if fence.info.startsWith("scala mdoc") =>
val res = doFormatOne(fence.body, style, file)
res.foreach { formatted =>
fence.newBody = Some(formatted.trim)
}
res
}
if (resultIterator.isEmpty) Success(code)
else
resultIterator
.find(_.isFailure)
.getOrElse(Success(markdown.renderToString))
} else
if (FileOps.isMarkdown(file))
MarkdownParser.transformMdoc(code)(doFormatOne(_, style, file, range))
else
doFormatOne(code, style, file, range)

private[scalafmt] def toInput(code: String, file: String): Input = {
Expand All @@ -148,7 +132,7 @@ object Scalafmt {
code: String,
style: ScalafmtConfig,
file: String,
range: Set[Range] = Set.empty
range: Set[Range]
): Try[String] =
if (code.matches("\\s*")) Success("")
else {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.scalafmt.util

import scala.util.Success
import scala.util.Try

import mdoc.parser._

private[scalafmt] object MarkdownParser {

private val settings: ParserSettings = new ParserSettings {
override val allowCodeFenceIndented: Boolean = true
}

def transformMdoc(code: String)(fmt: String => Try[String]): Try[String] = {
var hadFencedParts = false
val parts = MarkdownPart.parse(code, settings)
parts.foreach {
case p: CodeFence if p.getMdocMode.isDefined =>
fmt(p.body.value) match {
case Success(b) => hadFencedParts = true; p.newBody = Some(b.trim)
case failure => return failure // RETURNING!
}
case _ =>
}

Success {
if (hadFencedParts) {
val out = new StringBuilder()
parts.foreach(_.renderToString(out))
if (out.last != '\n') out.append('\n')
out.toString()
} else code
}
}

}
2 changes: 1 addition & 1 deletion scalafmt-tests/src/test/resources/unit/Markdown.source
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ case class Foo(a: String)
//> using dep io.scalaland::chimney::{{ git.tag or local.tag }}
import io.scalaland.chimney.Transformer

case class Foo (a : String)
case class Foo(a: String)
```
4 changes: 2 additions & 2 deletions scalafmt-tests/src/test/scala/org/scalafmt/cli/CliTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1168,7 +1168,7 @@ class CliTest extends AbstractCliTest with CliTestBehavior {
}

// This test might need to change based on maintainer feedback/requirements
test(s"does not apply to .md files with indented fenced content ") {
test(s"does apply to .md files with indented fenced content ") {
val input = string2dir(
s"""|/foobar2.md
| Intro text:
Expand All @@ -1181,7 +1181,7 @@ class CliTest extends AbstractCliTest with CliTestBehavior {
s"""|/foobar2.md
| Intro text:
| ```scala mdoc
| object A { }
| object A {}
| ```
|""".stripMargin
runArgs(
Expand Down

0 comments on commit 4306100

Please sign in to comment.