-
I am trying to upgrade from val t = Transform
.from(Markdown)
.or(ReStructuredText) When I compile this (Mill plugin), I get this error:
A looked at the Builder API and only see TIA |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments
-
Yes, sorry, it is one of the breaking changes and it's not in the migration guide, as I wasn't aware whether this is widely used. The method had to go as the core API is now pure and only goes from string to string where alternative formats would not make sense (you only transform one item at a time). It has moved to the new laika-io module which adds parallel processing and stream/file IO. If you show me your full example for how you used it previously I can give you an example for the new syntax. |
Beta Was this translation helpful? Give feedback.
-
Thanks for the confirmation. The original code I used is shown below (see this). I was already using the At this point in time I am having trouble with Cats. I suspect its a classpath issue with clashing Cats versions. So I still need time to test the API. TIA. def useOutputFormat[A](format: String, level:MessageLevel, in:String, out:String): Unit = {
val s = format.trim.toLowerCase
val t = Transform
.from(Markdown)
.or(ReStructuredText)
s match {
//case "md" | "markdown" => t.to(Markdown)
//case "rst" => t.to(ReStructuredText)
case "html" =>
t.to(HTML)
.withMessageLevel(level)
.using(GitHubFlavor)
.withRawContent
.inParallel
.fromDirectory(in)
.toDirectory(out)
case "epub" =>
val outFilePath = os.Path(out) / "all.epub"
val outFile = outFilePath.toIO.getAbsolutePath
t.to(EPUB)
.using(GitHubFlavor)
.withRawContent
.withMessageLevel(level)
.inParallel
.fromDirectory(in)
.toFile(out)
case "pdf" =>
val outFilePath = os.Path(out) / "all.pdf"
val outFile = outFilePath.toIO.getAbsolutePath
Transform
.from(Markdown)
.or(ReStructuredText)
.to(PDF)
.using(GitHubFlavor)
.withRawContent
.withMessageLevel(level)
.inParallel
.fromDirectory(in)
.toFile(outFile)
case "fo" | "xslfo" | "xsl-fo" => Transform
.from(Markdown)
.or(ReStructuredText)
.to(XSLFO)
.using(GitHubFlavor)
.withRawContent
.withMessageLevel(level)
.inParallel
.fromDirectory(in)
.toDirectory(out)
case "formatted-ast" | "ast" => Transform
.from(Markdown)
.or(ReStructuredText)
.to(AST)
.using(GitHubFlavor)
.withRawContent
.withMessageLevel(level)
.inParallel
.fromDirectory(in)
.toDirectory(out)
case _ => throw new IllegalArgumentException(s"Unsupported format: $format")
} |
Beta Was this translation helpful? Give feedback.
-
I'll give you an example for one of the blocks, the rest is hopefully self-explanatory. First switch your dependency from Then add the io implicits: And somewhere outside of the function you are showing: implicit val cs: ContextShift[IO] =
IO.contextShift(ExecutionContext.global)
val blocker = Blocker.liftExecutionContext(
ExecutionContext.fromExecutor(Executors.newCachedThreadPool())
) These objects should not be recreated on each run. Likewise I'd recommend to pull the parser creation out of the function, as it is a performance and memory overhead to recreate them on each run: val parser = MarkupParser
.of(Markdown)
.withRawContent
.using(GitHubFlavor)
.io(blocker)
.parallel[IO]
.withAlternativeParser(MarkupParser.of(ReStructuredText).withRawContent)
.build Your HTML case would then look like this: case "html" =>
val renderer = Renderer
.of(HTML)
.withConfig(parser.config)
.withMessageLevel(level)
.io(blocker)
.parallel[IO]
.build
val op = parser.fromDirectory(in).parse.flatMap { tree =>
renderer.from(tree.root)
.toDirectory(out)
.render
}
op.unsafeRunSync() This is more or less how Laika's own sbt plugin does the transformation with alternative markup formats. It's a bit more verbose in code, but gives you full control over the execution model and thread pools and full referential transparency. Sorry for the big impact of these changes, but Laika is 7 years old and has never been brought in line with more recent FP patterns. There won't be any change of this scale on the road to 1.0 anymore. |
Beta Was this translation helpful? Give feedback.
-
Thank you for the examples and the advice on setting this up. Appreciate your effort in maintaining this. I know it takes a lot of work. I have changed the code accordingly for one case to check that it compiles and runs. Thanks once again.
|
Beta Was this translation helpful? Give feedback.
-
Yes, you seem to have a version conflict. The Parallel type class in cats went from 2 type params to just one between cats 1.x and 2.0. Laika needs 2.0 as only that version supports Scala 2.13 which Laika also supports. You should get eviction warnings when compiling. One of your/Mill's dependencies pulls in cats 1.x. You would need to find a version that works with cats 2.0. Most projects have published for cats 2.0 by now, if the dependency you need hasn't you would need to wait until it does before upgrading to Laika 0.12. |
Beta Was this translation helpful? Give feedback.
-
Latest snapshot of Mill does not have this problem. So its compiling and running. |
Beta Was this translation helpful? Give feedback.
I'll give you an example for one of the blocks, the rest is hopefully self-explanatory.
First switch your dependency from
laika-core
tolaika-io
. The fromDirectory/toDirectory functionality is no longer part of core which is now a pure, side-effect free kernel.Then add the io implicits:
import laika.io.implicits._
.And somewhere outside of the function you are showing:
These objects should not be recreated on each run.
Likewise I'd recommend to pull the parser creation out of the function, as it i…