aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.gradle27
-rw-r--r--readme.md35
-rw-r--r--src/main/java/org/pacien/pandoc/filter/plantuml/Filter.java84
-rw-r--r--src/main/kotlin/org/pacien/pandoc/filter/plantuml/Filter.kt57
-rw-r--r--src/main/kotlin/org/pacien/pandoc/filter/plantuml/Latex.kt16
-rw-r--r--src/main/kotlin/org/pacien/pandoc/filter/plantuml/Main.kt5
-rw-r--r--src/main/kotlin/org/pacien/pandoc/filter/plantuml/PandocNode.kt30
-rw-r--r--src/main/kotlin/org/pacien/pandoc/filter/plantuml/PlantUml.kt21
-rw-r--r--src/test/java/org/pacien/pandoc/filter/plantuml/FilterTest.java27
-rw-r--r--src/test/kotlin/org/pacien/pandoc/filter/plantuml/FilterTest.kt39
-rw-r--r--src/test/resources/attributes.expected.json1
-rw-r--r--src/test/resources/attributes.input.json1
-rw-r--r--src/test/resources/identifyblock.expected.json (renamed from src/test/resources/expected.json)2
-rw-r--r--src/test/resources/identifyblock.input.json (renamed from src/test/resources/input.json)0
-rw-r--r--src/test/resources/resize.expected.json1
-rw-r--r--src/test/resources/resize.input.json1
16 files changed, 224 insertions, 123 deletions
diff --git a/build.gradle b/build.gradle
index f6a0a4f..c7a64f4 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,13 +1,13 @@
1group 'org.pacien.pandoc.filter.plantuml' 1group 'org.pacien.pandoc.filter.plantuml'
2version '1.0-SNAPSHOT' 2version '1.0-SNAPSHOT'
3 3
4apply plugin: 'java' 4apply plugin: 'kotlin'
5 5
6sourceCompatibility = 1.8 6sourceCompatibility = 1.8
7 7
8jar { 8jar {
9 manifest { 9 manifest {
10 attributes 'Main-Class': 'org.pacien.pandoc.filter.plantuml.Filter' 10 attributes 'Main-Class': 'org.pacien.pandoc.filter.plantuml.MainKt'
11 } 11 }
12 12
13 from { 13 from {
@@ -23,4 +23,27 @@ dependencies {
23 testCompile group: 'junit', name: 'junit', version: '4.12' 23 testCompile group: 'junit', name: 'junit', version: '4.12'
24 compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.6' 24 compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.6'
25 compile group: 'net.sourceforge.plantuml', name: 'plantuml', version: '8059' 25 compile group: 'net.sourceforge.plantuml', name: 'plantuml', version: '8059'
26 compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
27}
28
29buildscript {
30 ext.kotlin_version = '1.2.51'
31 repositories {
32 mavenCentral()
33 }
34 dependencies {
35 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
36 }
37}
38
39compileKotlin {
40 kotlinOptions {
41 jvmTarget = "1.8"
42 }
43}
44
45compileTestKotlin {
46 kotlinOptions {
47 jvmTarget = "1.8"
48 }
26} 49}
diff --git a/readme.md b/readme.md
index 015e375..c139337 100644
--- a/readme.md
+++ b/readme.md
@@ -3,34 +3,38 @@ pandoc-filter-plantuml
3 3
4A Pandoc AST filter rendering PlantUML code blocks into vector diagrams. 4A Pandoc AST filter rendering PlantUML code blocks into vector diagrams.
5 5
6This filter produces TikZ code that must then be rendered using another filter such as 6This filter produces TikZ code that can be rendered as vector diagrams in PDF documents,
7[tikz.py][tikz]. 7or as raster graphics by using another filter such as [tikz.py][tikz].
8 8
9 9
10Usage 10Example
11----- 11-------
12 12
13A PlantUML diagram in an example Pandoc Markdown file `example.md`: 13A PlantUML diagram in an example Pandoc Markdown file `example.md`:
14 14
15 ```puml 15 ---
16 header-includes: \usepackage{tikz}
17 ---
18
19 ```{.puml .centered caption="Courtesy protocol" width=\columnwidth}
16 @startuml 20 @startuml
17 Bob->Alice : hello 21 Bob->Alice : hello
22 Alice->Bob : hi
18 @enduml 23 @enduml
19 ``` 24 ```
20 25
21Using the helper scripts [tikz.py][tikz] and `pandoc-filter-plantuml.sh`: 26Using the helper scripts `pandoc-filter-plantuml.sh`:
22 27
23 #/bin/sh 28 #/bin/sh
24 java -jar pandoc-filter-plantuml.jar <&0 29 java -jar pandoc-filter-plantuml.jar <&0
25 30
26Can be rendered and included as a vector resource in a PDF by running: 31Can be rendered as a vector resource in a PDF by running:
27 32
28 % pandoc --filter=pandoc-filter-plantuml.sh \ 33 % pandoc --filter=pandoc-filter-plantuml.sh \
29 --filter=tikz.py \
30 --output=example.pdf \ 34 --output=example.pdf \
31 example.md 35 example.md
32 36
33Or as an image in an HTML document with the following command: 37Or as a raster image using [tikz.py][tikz] in an HTML document with the following command:
34 38
35 % pandoc --filter=pandoc-filter-plantuml.sh \ 39 % pandoc --filter=pandoc-filter-plantuml.sh \
36 --filter=tikz.py \ 40 --filter=tikz.py \
@@ -38,6 +42,18 @@ Or as an image in an HTML document with the following command:
38 example.md 42 example.md
39 43
40 44
45Options
46-------
47
48The following rendering options can be supplied as [fenced code attributes][fenced_code_attribute]:
49
50* `.centered`: centers the diagram horizontally on the page
51* `caption="Some caption"`: adds a figure caption below the diagram
52* `label="somelabel`: adds a label to the figure
53* `width=\columnwidth` and `height=100pt`: resize the diagram using the `\resizebox` command,
54 keeping the aspect ration of only one of the two is given
55
56
41Build 57Build
42----- 58-----
43 59
@@ -54,3 +70,4 @@ See /license.txt
54 70
55 71
56[tikz]: https://github.com/jgm/pandocfilters/blob/master/examples/tikz.py 72[tikz]: https://github.com/jgm/pandocfilters/blob/master/examples/tikz.py
73[fenced_code_attribute]: http://pandoc.org/MANUAL.html#fenced-code-blocks
diff --git a/src/main/java/org/pacien/pandoc/filter/plantuml/Filter.java b/src/main/java/org/pacien/pandoc/filter/plantuml/Filter.java
deleted file mode 100644
index 66abc2d..0000000
--- a/src/main/java/org/pacien/pandoc/filter/plantuml/Filter.java
+++ /dev/null
@@ -1,84 +0,0 @@
1package org.pacien.pandoc.filter.plantuml;
2
3import com.fasterxml.jackson.databind.JsonNode;
4import com.fasterxml.jackson.databind.ObjectMapper;
5import com.fasterxml.jackson.databind.node.ArrayNode;
6import com.fasterxml.jackson.databind.node.ObjectNode;
7import com.fasterxml.jackson.databind.node.TextNode;
8import net.sourceforge.plantuml.FileFormat;
9import net.sourceforge.plantuml.FileFormatOption;
10import net.sourceforge.plantuml.SourceStringReader;
11
12import java.io.*;
13import java.util.Iterator;
14import java.util.stream.Collectors;
15
16final public class Filter {
17
18 private static final String BEGIN_TAG = "\\begin{tikzpicture}[yscale=-1]";
19 private static final String LINE_SEP = "\n";
20 private static final String TYPE_KEY = "t";
21 private static final String CONTENT_KEY = "c";
22 private static final String CODE_BLOCK_TYPE = "CodeBlock";
23 private static final String RAW_BLOCK_TYPE = "RawBlock";
24 private static final String PLANTUML_TYPE = "puml";
25 private static final String LATEX_TYPE = "latex";
26 private static final int META_INDEX = 0;
27 private static final int META_PROP_INDEX = 1;
28 private static final int META_PROP_TYPE_INDEX = 0;
29 private static final int CONTENT_INDEX = 1;
30
31 private static String plantumlToLatex(String puml) throws IOException {
32 try (ByteArrayOutputStream s = new ByteArrayOutputStream()) {
33 new SourceStringReader(puml).generateImage(s, new FileFormatOption(FileFormat.LATEX_NO_PREAMBLE));
34 try (BufferedReader r = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(s.toByteArray())))) {
35 return BEGIN_TAG + LINE_SEP + r.lines().filter(l -> !l.equals(BEGIN_TAG)).collect(Collectors.joining(LINE_SEP));
36 }
37 }
38 }
39
40 private static void renderPlantumlNode(ObjectNode n) throws IOException {
41 String puml = n.get(CONTENT_KEY).get(CONTENT_INDEX).asText();
42 String tikz = plantumlToLatex(puml);
43
44 n.set(TYPE_KEY, TextNode.valueOf(RAW_BLOCK_TYPE));
45 ((ArrayNode) n.get(CONTENT_KEY)).removeAll()
46 .add(TextNode.valueOf(LATEX_TYPE))
47 .add(TextNode.valueOf(tikz));
48 }
49
50 private static boolean isPlantumlNode(JsonNode n) {
51 return n.path(TYPE_KEY).asText().equals(CODE_BLOCK_TYPE) &&
52 n.path(CONTENT_KEY).path(META_INDEX).path(META_PROP_INDEX).path(META_PROP_TYPE_INDEX).asText().equals(PLANTUML_TYPE);
53 }
54
55 private static void walk(JsonNode n) throws IOException {
56 if (isPlantumlNode(n))
57 renderPlantumlNode((ObjectNode) n);
58 else if (n.isContainerNode())
59 for (Iterator<JsonNode> i = n.elements(); i.hasNext(); ) walk(i.next());
60 }
61
62 public static void filter(InputStream i, OutputStream o) throws IOException {
63 ObjectMapper m = new ObjectMapper();
64 JsonNode t = m.readTree(i);
65 if (t != null) {
66 walk(t);
67 m.writeValue(o, t);