From d6be0ea1898777f358a5c0d772d3eadb97d83127 Mon Sep 17 00:00:00 2001 From: pacien Date: Sun, 7 Jan 2018 23:03:21 +0100 Subject: Import project Signed-off-by: pacien --- .../org/pacien/pandoc/filter/plantuml/Filter.java | 84 ++++++++++++++++++++++ .../pacien/pandoc/filter/plantuml/FilterTest.java | 27 +++++++ src/test/resources/expected.json | 1 + src/test/resources/input.json | 1 + 4 files changed, 113 insertions(+) create mode 100644 src/main/java/org/pacien/pandoc/filter/plantuml/Filter.java create mode 100644 src/test/java/org/pacien/pandoc/filter/plantuml/FilterTest.java create mode 100644 src/test/resources/expected.json create mode 100644 src/test/resources/input.json (limited to 'src') diff --git a/src/main/java/org/pacien/pandoc/filter/plantuml/Filter.java b/src/main/java/org/pacien/pandoc/filter/plantuml/Filter.java new file mode 100644 index 0000000..66abc2d --- /dev/null +++ b/src/main/java/org/pacien/pandoc/filter/plantuml/Filter.java @@ -0,0 +1,84 @@ +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 net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; +import net.sourceforge.plantuml.SourceStringReader; + +import java.io.*; +import java.util.Iterator; +import java.util.stream.Collectors; + +final public class Filter { + + private static final String BEGIN_TAG = "\\begin{tikzpicture}[yscale=-1]"; + private static final String LINE_SEP = "\n"; + private static final String TYPE_KEY = "t"; + private static final String CONTENT_KEY = "c"; + private static final String CODE_BLOCK_TYPE = "CodeBlock"; + private static final String RAW_BLOCK_TYPE = "RawBlock"; + private static final String PLANTUML_TYPE = "puml"; + private static final String LATEX_TYPE = "latex"; + private static final int META_INDEX = 0; + private static final int META_PROP_INDEX = 1; + private static final int META_PROP_TYPE_INDEX = 0; + private static final int CONTENT_INDEX = 1; + + private static String plantumlToLatex(String puml) throws IOException { + try (ByteArrayOutputStream s = new ByteArrayOutputStream()) { + new SourceStringReader(puml).generateImage(s, new FileFormatOption(FileFormat.LATEX_NO_PREAMBLE)); + try (BufferedReader r = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(s.toByteArray())))) { + return BEGIN_TAG + LINE_SEP + r.lines().filter(l -> !l.equals(BEGIN_TAG)).collect(Collectors.joining(LINE_SEP)); + } + } + } + + private static void renderPlantumlNode(ObjectNode n) throws IOException { + String puml = n.get(CONTENT_KEY).get(CONTENT_INDEX).asText(); + String tikz = plantumlToLatex(puml); + + n.set(TYPE_KEY, TextNode.valueOf(RAW_BLOCK_TYPE)); + ((ArrayNode) n.get(CONTENT_KEY)).removeAll() + .add(TextNode.valueOf(LATEX_TYPE)) + .add(TextNode.valueOf(tikz)); + } + + private static boolean isPlantumlNode(JsonNode n) { + return n.path(TYPE_KEY).asText().equals(CODE_BLOCK_TYPE) && + n.path(CONTENT_KEY).path(META_INDEX).path(META_PROP_INDEX).path(META_PROP_TYPE_INDEX).asText().equals(PLANTUML_TYPE); + } + + private static void walk(JsonNode n) throws IOException { + if (isPlantumlNode(n)) + renderPlantumlNode((ObjectNode) n); + else if (n.isContainerNode()) + for (Iterator i = n.elements(); i.hasNext(); ) walk(i.next()); + } + + public static void filter(InputStream i, OutputStream o) throws IOException { + ObjectMapper m = new ObjectMapper(); + JsonNode t = m.readTree(i); + if (t != null) { + walk(t); + m.writeValue(o, t); + } + } + + public static void main(String args[]) { + try { + filter(System.in, System.out); + } catch (IOException e) { + e.printStackTrace(); + System.exit(1); + } + } + + private Filter() { + // static class + } + +} diff --git a/src/test/java/org/pacien/pandoc/filter/plantuml/FilterTest.java b/src/test/java/org/pacien/pandoc/filter/plantuml/FilterTest.java new file mode 100644 index 0000000..f720b22 --- /dev/null +++ b/src/test/java/org/pacien/pandoc/filter/plantuml/FilterTest.java @@ -0,0 +1,27 @@ +package org.pacien.pandoc.filter.plantuml; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.*; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Paths; + +final public class FilterTest { + + private static final String INPUT_FILE = "/input.json"; + private static final String EXPECTED_FILE = "/expected.json"; + + @Test + public void filterTest() { + try (ByteArrayOutputStream o = new ByteArrayOutputStream()) { + byte[] e = Files.readAllBytes(Paths.get(getClass().getResource(EXPECTED_FILE).toURI())); + Filter.filter(getClass().getResourceAsStream(INPUT_FILE), o); + Assert.assertArrayEquals(o.toByteArray(), e); + } catch (IOException | URISyntaxException e) { + Assert.fail(); + } + } + +} diff --git a/src/test/resources/expected.json b/src/test/resources/expected.json new file mode 100644 index 0000000..7131399 --- /dev/null +++ b/src/test/resources/expected.json @@ -0,0 +1 @@ +[{"unMeta":{}},[{"t":"Header","c":[1,["test-document",[],[]],[{"t":"Str","c":"Test"},{"t":"Space","c":[]},{"t":"Str","c":"document"}]]},{"t":"Para","c":[{"t":"Str","c":"This"},{"t":"Space","c":[]},{"t":"Str","c":"paragraph"},{"t":"Space","c":[]},{"t":"Str","c":"should"},{"t":"Space","c":[]},{"t":"Str","c":"be"},{"t":"Space","c":[]},{"t":"Str","c":"left"},{"t":"Space","c":[]},{"t":"Str","c":"as"},{"t":"Space","c":[]},{"t":"Str","c":"is"},{"t":"Space","c":[]},{"t":"Str","c":"by"},{"t":"Space","c":[]},{"t":"Str","c":"the"},{"t":"Space","c":[]},{"t":"Str","c":"filter."}]},{"t":"CodeBlock","c":[["",[],[]],"This generic code block too.\nOnly PlantUML code blocks should be rendered."]},{"t":"RawBlock","c":["latex","\\begin{tikzpicture}[yscale=-1]\n% generated by Plantuml 8059 \n\\definecolor{plantucolor0000}{RGB}{254,254,206}\n\\definecolor{plantucolor0001}{RGB}{168,0,54}\n\\definecolor{plantucolor0002}{RGB}{173,209,178}\n\\definecolor{plantucolor0003}{RGB}{0,0,0}\n\\definecolor{plantucolor0004}{RGB}{0,0,255}\n\\draw[color=plantucolor0001,fill=plantucolor0000,line width=1.5pt] (87pt,8pt) rectangle (186pt,68.8047pt);\n\\draw[color=plantucolor0001,fill=plantucolor0002,line width=1.0pt] (102pt,24pt) ellipse (11pt and 11pt);\n\\draw[color=black,fill=black] (104.9688pt,29.6406pt) ..controls (104.3906pt,29.9375pt) .. (103.75pt,30.0859pt) ..controls (103.1094pt,30.2344pt) .. (102.4063pt,30.2344pt) ..controls (99.9063pt,30.2344pt) .. (98.5859pt,28.5859pt) ..controls (97.2656pt,26.9375pt) .. (97.2656pt,23.8125pt) ..controls (97.2656pt,20.6875pt) .. (98.5859pt,19.0313pt) ..controls (99.9063pt,17.375pt) .. (102.4063pt,17.375pt) ..controls (103.1094pt,17.375pt) .. (103.7578pt,17.5313pt) ..controls (104.4063pt,17.6875pt) .. (104.9688pt,17.9844pt) -- (104.9688pt,20.7031pt) ..controls (104.3438pt,20.125pt) .. (103.75pt,19.8516pt) ..controls (103.1563pt,19.5781pt) .. (102.5313pt,19.5781pt) ..controls (101.1875pt,19.5781pt) .. (100.5pt,20.6484pt) ..controls (99.8125pt,21.7188pt) .. (99.8125pt,23.8125pt) ..controls (99.8125pt,25.9063pt) .. (100.5pt,26.9766pt) ..controls (101.1875pt,28.0469pt) .. (102.5313pt,28.0469pt) ..controls (103.1563pt,28.0469pt) .. (103.75pt,27.7734pt) ..controls (104.3438pt,27.5pt) .. (104.9688pt,26.9219pt) -- (104.9688pt,29.6406pt);\n\\node at (116pt,17.0156pt)[below right]{Subscriber};\n\\draw[color=plantucolor0001,line width=1.5pt] (88pt,40pt) -- (185pt,40pt);\n\\node at (93pt,44pt)[below right]{subscriberId};\n\\draw[color=plantucolor0001,line width=1.5pt] (88pt,60.8047pt) -- (185pt,60.8047pt);\n\\draw[color=plantucolor0001,fill=plantucolor0000,line width=1.5pt] (6pt,148pt) rectangle (119pt,208.8047pt);\n\\draw[color=plantucolor0001,fill=plantucolor0002,line width=1.0pt] (21pt,164pt) ellipse (11pt and 11pt);\n\\draw[color=black,fill=black] (23.9688pt,169.6406pt) ..controls (23.3906pt,169.9375pt) .. (22.75pt,170.0859pt) ..controls (22.1094pt,170.2344pt) .. (21.4063pt,170.2344pt) ..controls (18.9063pt,170.2344pt) .. (17.5859pt,168.5859pt) ..controls (16.2656pt,166.9375pt) .. (16.2656pt,163.8125pt) ..controls (16.2656pt,160.6875pt) .. (17.5859pt,159.0313pt) ..controls (18.9063pt,157.375pt) .. (21.4063pt,157.375pt) ..controls (22.1094pt,157.375pt) .. (22.7578pt,157.5313pt) ..controls (23.4063pt,157.6875pt) .. (23.9688pt,157.9844pt) -- (23.9688pt,160.7031pt) ..controls (23.3438pt,160.125pt) .. (22.75pt,159.8516pt) ..controls (22.1563pt,159.5781pt) .. (21.5313pt,159.5781pt) ..controls (20.1875pt,159.5781pt) .. (19.5pt,160.6484pt) ..controls (18.8125pt,161.7188pt) .. (18.8125pt,163.8125pt) ..controls (18.8125pt,165.9063pt) .. (19.5pt,166.9766pt) ..controls (20.1875pt,168.0469pt) .. (21.5313pt,168.0469pt) ..controls (22.1563pt,168.0469pt) .. (22.75pt,167.7734pt) ..controls (23.3438pt,167.5pt) .. (23.9688pt,166.9219pt) -- (23.9688pt,169.6406pt);\n\\node at (35pt,157.0156pt)[below right]{AccumUsage};\n\\draw[color=plantucolor0001,line width=1.5pt] (7pt,180pt) -- (118pt,180pt);\n\\node at (12pt,184pt)[below right]{subscriberId};\n\\draw[color=plantucolor0001,line width=1.5pt] (7pt,200.8047pt) -- (118pt,200.8047pt);\n\\draw[color=plantucolor0001,fill=plantucolor0000,line width=1.5pt] (154pt,129pt) rectangle (267pt,228.2188pt);\n\\draw[color=plantucolor0001,fill=plantucolor0002,line width=1.0pt] (178.45pt,145pt) ellipse (11pt and 11pt);\n\\draw[color=black,fill=black] (181.4188pt,150.6406pt) ..controls (180.8406pt,150.9375pt) .. (180.2pt,151.0859pt) ..controls (179.5594pt,151.2344pt) .. (178.8563pt,151.2344pt) ..controls (176.3563pt,151.2344pt) .. (175.0359pt,149.5859pt) ..controls (173.7156pt,147.9375pt) .. (173.7156pt,144.8125pt) ..controls (173.7156pt,141.6875pt) .. (175.0359pt,140.0313pt) ..controls (176.3563pt,138.375pt) .. (178.8563pt,138.375pt) ..controls (179.5594pt,138.375pt) .. (180.2078pt,138.5313pt) ..controls (180.8563pt,138.6875pt) .. (181.4188pt,138.9844pt) -- (181.4188pt,141.7031pt) ..controls (180.7938pt,141.125pt) .. (180.2pt,140.8516pt) ..controls (179.6063pt,140.5781pt) .. (178.9813pt,140.5781pt) ..controls (177.6375pt,140.5781pt) .. (176.95pt,141.6484pt) ..controls (176.2625pt,142.7188pt) .. (176.2625pt,144.8125pt) ..controls (176.2625pt,146.9063pt) .. (176.95pt,147.9766pt) ..controls (177.6375pt,149.0469pt) .. (178.9813pt,149.0469pt) ..controls (179.6063pt,149.0469pt) .. (180.2pt,148.7734pt) ..controls (180.7938pt,148.5pt) .. (181.4188pt,147.9219pt) -- (181.4188pt,150.6406pt);\n\\node at (194.55pt,138.0156pt)[below right]{IpSession};\n\\draw[color=plantucolor0001,line width=1.5pt] (155pt,161pt) -- (266pt,161pt);\n\\node at (160pt,165pt)[below right]{ipAddress};\n\\node at (160pt,177.8047pt)[below right]{specificData};\n\\node at (160pt,190.6094pt)[below right]{sapcOriginStateId};\n\\node at (160pt,203.4141pt)[below right]{apnId};\n\\draw[color=plantucolor0001,line width=1.5pt] (155pt,220.2188pt) -- (266pt,220.2188pt);\n\\draw[color=plantucolor0004,line width=1.0pt] (152.375pt,69.104pt) ..controls (160.988pt,85.167pt) and (171.898pt,105.512pt) .. (181.933pt,124.227pt);\n\\draw[color=plantucolor0004,fill=plantucolor0004,line width=1.0pt] (184.464pt,128.9464pt) -- (183.7353pt,119.1245pt) -- (182.1008pt,124.5401pt) -- (176.6853pt,122.9056pt) -- (184.464pt,128.9464pt) -- cycle;\n\\node at (146.8242pt,76.9968pt)[below right]{1};\n\\node at (156.1855pt,105.9167pt)[below right]{1..*};\n\\draw[color=plantucolor0001,line width=1.0pt] (120.625pt,69.104pt) ..controls (108.92pt,90.933pt) and (92.9726pt,120.673pt) .. (80.7427pt,143.4799pt);\n\\draw[color=plantucolor0001,fill=plantucolor0001,line width=1.0pt] (78.3486pt,147.9445pt) -- (86.1271pt,141.9034pt) -- (80.7116pt,143.5381pt) -- (79.0769pt,138.1226pt) -- (78.3486pt,147.9445pt) -- cycle;\n\\node at (108.5258pt,76.9968pt)[below right]{1};\n\\node at (55.1905pt,124.6557pt)[below right]{0..1};\n\\end{tikzpicture}"]}]] \ No newline at end of file diff --git a/src/test/resources/input.json b/src/test/resources/input.json new file mode 100644 index 0000000..0b07e87 --- /dev/null +++ b/src/test/resources/input.json @@ -0,0 +1 @@ +[{"unMeta":{}},[{"t":"Header","c":[1,["test-document",[],[]],[{"t":"Str","c":"Test"},{"t":"Space","c":[]},{"t":"Str","c":"document"}]]},{"t":"Para","c":[{"t":"Str","c":"This"},{"t":"Space","c":[]},{"t":"Str","c":"paragraph"},{"t":"Space","c":[]},{"t":"Str","c":"should"},{"t":"Space","c":[]},{"t":"Str","c":"be"},{"t":"Space","c":[]},{"t":"Str","c":"left"},{"t":"Space","c":[]},{"t":"Str","c":"as"},{"t":"Space","c":[]},{"t":"Str","c":"is"},{"t":"Space","c":[]},{"t":"Str","c":"by"},{"t":"Space","c":[]},{"t":"Str","c":"the"},{"t":"Space","c":[]},{"t":"Str","c":"filter."}]},{"t":"CodeBlock","c":[["",[],[]],"This generic code block too.\nOnly PlantUML code blocks should be rendered."]},{"t":"CodeBlock","c":[["",["puml"],[]],"@startuml\nclass Subscriber {\n subscriberId\n}\n\nclass AccumUsage {\n subscriberId\n}\n\nclass IpSession {\n ipAddress\n specificData \n sapcOriginStateId \n apnId\n}\n\nSubscriber \"1\" -[#blue]-> \"1..*\" IpSession\nSubscriber \"1\" --> \"0..1\" AccumUsage\n@enduml"]}]] \ No newline at end of file -- cgit v1.2.3