From 69bc6c2ae35883286d9c2b8cc77d5fa0a8c37351 Mon Sep 17 00:00:00 2001 From: pacien Date: Thu, 26 Jul 2018 11:34:06 +0200 Subject: Kotlin rewrite, adding diagram options --- .../org/pacien/pandoc/filter/plantuml/Filter.kt | 57 ++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/main/kotlin/org/pacien/pandoc/filter/plantuml/Filter.kt (limited to 'src/main/kotlin/org/pacien/pandoc/filter/plantuml/Filter.kt') diff --git a/src/main/kotlin/org/pacien/pandoc/filter/plantuml/Filter.kt b/src/main/kotlin/org/pacien/pandoc/filter/plantuml/Filter.kt new file mode 100644 index 0000000..82a78b5 --- /dev/null +++ b/src/main/kotlin/org/pacien/pandoc/filter/plantuml/Filter.kt @@ -0,0 +1,57 @@ +package org.pacien.pandoc.filter.plantuml + +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.databind.node.ArrayNode +import com.fasterxml.jackson.databind.node.ObjectNode +import com.fasterxml.jackson.databind.node.TextNode +import java.io.InputStream +import java.io.OutputStream + +object Filter { + private val mapper = ObjectMapper() + + private inline fun T.conditionally(condition: Boolean, block: (T) -> T): T = + if (condition) block(this) else this + + private inline fun T.withNonNull(value: A?, block: (T, A) -> T): T = + if (value != null) block(this, value) else this + + private fun JsonNode.isCodeBlock() = type() == "CodeBlock" + private fun JsonNode.isPlantUmlBlock() = isCodeBlock() && "puml" in classNames() + + private fun Latex.resizeBox(attrs: Map) = + resizeBox(attrs["width"] ?: "!", attrs["height"] ?: "!") + + private fun Latex.setOptions(classes: List, attrs: Map) = + this + .conditionally("width" in attrs || "height" in attrs) { it -> it.resizeBox(attrs) } + .conditionally("centered" in classes, Latex::centering) + .withNonNull(attrs["caption"], Latex::caption) + .withNonNull(attrs["label"], Latex::label) + .conditionally("caption" in attrs || "label" in attrs, Latex::figure) + + private fun arrayNodeOf(type: String, content: String): ArrayNode = + mapper.createArrayNode() + .add(TextNode.valueOf(type)) + .add(TextNode.valueOf(content)) + + private fun renderPlantumlNode(node: ObjectNode) { + val puml = node.content() + val tikz = PlantUml.renderTikz(puml) + val block = tikz.setOptions(node.classNames(), node.attributeMap()) + node.setBlock("RawBlock", arrayNodeOf("latex", block.raw())) + } + + private fun walk(node: JsonNode): Unit = when { + node.isPlantUmlBlock() -> renderPlantumlNode(node as ObjectNode) + else -> node.forEach(Filter::walk) + } + + fun filter(input: InputStream, output: OutputStream) { + mapper.readTree(input)?.let { tree -> + walk(tree) + mapper.writeValue(output, tree) + } + } +} -- cgit v1.2.3