Separate multiline code block language from remaining parameters
authorSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Thu, 10 Sep 2020 18:15:00 +0000 (21:15 +0300)
committerSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Fri, 11 Sep 2020 06:22:40 +0000 (09:22 +0300)
Parse document property
Parse separators

src/main/java/eu/svjatoslav/sixth/core/document/Document.java
src/main/java/eu/svjatoslav/sixth/core/document/Utils.java
src/main/java/eu/svjatoslav/sixth/core/document/content/DocumentPropertyCollection.java [new file with mode: 0644]
src/main/java/eu/svjatoslav/sixth/core/document/content/ListElement.java
src/main/java/eu/svjatoslav/sixth/core/document/content/MultilineCode.java
src/main/java/eu/svjatoslav/sixth/core/document/content/PropertyCollection.java [deleted file]
src/main/java/eu/svjatoslav/sixth/core/document/content/Separator.java [new file with mode: 0644]
src/main/java/eu/svjatoslav/sixth/core/document/content/TextBlock.java

index e4c45bd..c61d613 100644 (file)
@@ -62,7 +62,7 @@ public class Document {
 
         // DocumentProperty:
         // "#+OPTIONS: H:20 num:20"
-        tokenizer.addTerminator(PRESERVE, "#\\+[^\\s]+:.*\\r?\\n", TG_DOCUMENT_PROPERTY);
+        tokenizer.addTerminator(PRESERVE, "#\\+([^\\s]+):(.*)\\r?\\n", TG_DOCUMENT_PROPERTY);
 
         // Drawer property:
         //  " :ID:       533734b9-0456-4448-9830-a43646345615"
index 406e7ef..00166ef 100644 (file)
@@ -20,4 +20,8 @@ public class Utils {
         return sb.toString();
     }
 
+    public static boolean isBlank(String s){
+        return s.trim().length() == 0;
+    }
+
 }
diff --git a/src/main/java/eu/svjatoslav/sixth/core/document/content/DocumentPropertyCollection.java b/src/main/java/eu/svjatoslav/sixth/core/document/content/DocumentPropertyCollection.java
new file mode 100644 (file)
index 0000000..adb3c12
--- /dev/null
@@ -0,0 +1,40 @@
+package eu.svjatoslav.sixth.core.document.content;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Things like:
+ * #+RESULTS:
+ * #+LATEX_HEADER: \\usepackage{parskip}
+ * #+OPTIONS: H:20 num:20
+ * #+attr_latex: :width 300px
+ */
+
+public class DocumentPropertyCollection implements Content {
+    private Map<String, List<String>> keyToValue = new HashMap<>();
+
+    @Override
+    public void toMD(StringBuilder sb, int indent) {
+    }
+
+    public void addProperty(String key, String value){
+        getOrCreateValueList(key).add(value);
+    }
+
+    private List<String> getOrCreateValueList(String key){
+        String actualKey = key.toLowerCase();
+        if (keyToValue.containsKey(actualKey))
+            return keyToValue.get(actualKey);
+
+        List valueList = new ArrayList<String>();
+        keyToValue.put(actualKey, valueList);
+        return valueList;
+    }
+
+    public boolean hasProperty(String key){
+        return keyToValue.containsKey(key.toLowerCase());
+    }
+}
index e1cf33d..0db636f 100644 (file)
@@ -8,6 +8,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 import static eu.svjatoslav.sixth.core.document.Helper.*;
+import static eu.svjatoslav.sixth.core.document.Utils.isBlank;
 
 public class ListElement implements Content {
     public final FormattedText name;
@@ -15,7 +16,6 @@ public class ListElement implements Content {
     public final ListElement parent;
     private final String type;
     private final List<Content> content = new ArrayList<>();
-    StringBuilder normalTextAccumulator = new StringBuilder();
 
     public ListElement(FormattedText name, int indent, ListElement parent, String type) {
         this.indent = indent;
@@ -24,25 +24,26 @@ public class ListElement implements Content {
         this.parent = parent;
     }
 
-    public void addContent(Content content) {
-        applyTextAccumulator();
-        this.content.add(content);
+    private Content findCurrentContentElement(){
+        if (content.isEmpty()) return null;
+        return content.get(content.size()-1);
     }
 
-    private void applyTextAccumulator(){
-        if (normalTextAccumulator.length() == 0)
-            return;
+    private boolean isLastContentElement(Class aClass){
+        Content contentElement = findCurrentContentElement();
+        if (contentElement == null) return false;
 
-        content.add(new TextBlock(normalTextAccumulator.toString()));
+        return contentElement.getClass().isInstance(aClass);
+    }
 
-        normalTextAccumulator.setLength(0);
+    public void addContent(Content contentElement){
+        content.add(contentElement);
     }
 
     public void parse(TokenizerMatch tm) {
 
         if (tm.isGroup(TG_DOCUMENT_PROPERTY)) {
-            // TODO
-            // System.out.println("DOCUMENT PROPERTY!!!: " + tm.token);
+            parseDocumentProperty(tm);
             return;
         }
 
@@ -53,14 +54,19 @@ public class ListElement implements Content {
         }
 
         if (tm.isGroup(TG_NORMAL_TEXT)) {
-            normalTextAccumulator.append(tm.token);
+            if (isBlank(tm.token)){
+                parseSeparator();
+                return;
+            }
+
+            parseTextBlock(tm);
             return;
         }
 
         if (tm.isGroup(TG_MULTILINE_CODE)){
            // System.out.println(tm.toString());
             String[] groups = tm.getRegExpGroups();
-            addContent(new MultilineCode(
+            content.add(new MultilineCode(
                     groups[3], // language
                     groups[5]  // code
             ));
@@ -69,16 +75,51 @@ public class ListElement implements Content {
 
         if (tm.isGroup(TG_VERSE)){
             String[] groups = tm.getRegExpGroups();
-            addContent(new Verse(groups[5]));
+            content.add(new Verse(groups[5]));
             return;
         }
 
         System.out.println("ERROR!!!! Unable to handle: " + tm);
     }
 
+    private void parseTextBlock(TokenizerMatch tm) {
+        TextBlock textBlock;
+        if (isLastContentElement(TextBlock.class)) {
+            textBlock = ((TextBlock) findCurrentContentElement());
+        } else {
+            textBlock = new TextBlock();
+            content.add(textBlock);
+        }
+
+        textBlock.addContent(tm.token + "\n");
+    }
+
+    private void parseDocumentProperty(TokenizerMatch tm) {
+        DocumentPropertyCollection documentPropertyCollection;
+
+        if (isLastContentElement(DocumentPropertyCollection.class)){
+            documentPropertyCollection = (DocumentPropertyCollection)findCurrentContentElement();
+        } else {
+            documentPropertyCollection = new DocumentPropertyCollection();
+            content.add(documentPropertyCollection);
+        }
+
+        documentPropertyCollection.addProperty(
+                tm.getRegExpGroups()[0],
+                tm.getRegExpGroups()[1]);
+    }
+
+    private void parseSeparator() {
+        if (isLastContentElement(Separator.class)){
+            ((Separator)findCurrentContentElement()).addLine();
+        } else {
+            content.add(new Separator()); 
+        }
+    }
+
 
     public void toMD(StringBuilder sb, int indent) {
-        applyTextAccumulator();
+        disablePlantUmlExport();
 
         if (this.indent >= 0) {
             String2 s = new String2();
@@ -90,4 +131,24 @@ public class ListElement implements Content {
             c.toMD(sb, this.indent + 2);
         }
     }
+
+    private void disablePlantUmlExport() {
+
+        for (int i = 0; i< (content.size()-2); i++){
+            if (!(content.get(i) instanceof MultilineCode)) continue;
+
+            MultilineCode code = (MultilineCode) content.get(i);
+            if (!"plantuml".equalsIgnoreCase(code.language)) continue;;
+
+            if (!(content.get(i+1) instanceof DocumentPropertyCollection)) continue;
+            DocumentPropertyCollection property = (DocumentPropertyCollection) content.get(i+1);
+
+            if (!property.hasProperty("results")) continue;;
+
+            if (!(content.get(i+2) instanceof TextBlock)) continue;
+            TextBlock textBlock = (TextBlock) content.get(i+2);
+
+            textBlock.disableForExport();
+        }
+    }
 }
index db64e3e..212d412 100644 (file)
@@ -1,13 +1,24 @@
 package eu.svjatoslav.sixth.core.document.content;
 
 import eu.svjatoslav.commons.string.String2;
+import eu.svjatoslav.commons.string.tokenizer.Tokenizer;
+
+import static eu.svjatoslav.commons.string.tokenizer.Terminator.TerminationStrategy.DROP;
 
 public class MultilineCode implements Content {
     public final String language;
     public final String code;
 
-    public MultilineCode(String language, String code) {
-        this.language = language;
+    public MultilineCode(String languageAndParams, String code) {
+
+        final Tokenizer tokenizer = new Tokenizer(languageAndParams);
+        tokenizer.addTerminator(DROP, "[ \\t]+", "whitespace");
+        if (tokenizer.hasMoreContent()){
+            language = tokenizer.getNextToken().token;
+        } else {
+            language = null;
+        }
+
         this.code = code;
     }
 
@@ -22,7 +33,6 @@ public class MultilineCode implements Content {
     }
 
     public String getMDlanguage(){
-        // TODO: do not append ORG parameters to language, like: file: ....
         if (language == null) return "";
         return language;
     }
diff --git a/src/main/java/eu/svjatoslav/sixth/core/document/content/PropertyCollection.java b/src/main/java/eu/svjatoslav/sixth/core/document/content/PropertyCollection.java
deleted file mode 100644 (file)
index 4034670..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-package eu.svjatoslav.sixth.core.document.content;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class PropertyCollection implements Content {
-
-    private Map<String, String> propertyToValue = new HashMap<>();
-
-    @Override
-    public void toMD(StringBuilder sb, int indent) {
-        // TODO
-    }
-}
diff --git a/src/main/java/eu/svjatoslav/sixth/core/document/content/Separator.java b/src/main/java/eu/svjatoslav/sixth/core/document/content/Separator.java
new file mode 100644 (file)
index 0000000..44097e9
--- /dev/null
@@ -0,0 +1,20 @@
+package eu.svjatoslav.sixth.core.document.content;
+
+public class Separator implements Content {
+
+    private int numLines = 1;
+
+    public Separator(){
+    }
+
+    @Override
+    public void toMD(StringBuilder sb, int indent) {
+        for (int i = 0; i < numLines; i++) {
+            sb.append("\n");
+        }
+    }
+
+    public void addLine(){
+        numLines++;
+    }
+}
index a3a4611..56177b6 100644 (file)
@@ -3,14 +3,25 @@ package eu.svjatoslav.sixth.core.document.content;
 import eu.svjatoslav.sixth.core.document.text.FormattedText;
 
 public class TextBlock implements Content {
-    private final FormattedText text;
+    private StringBuilder orgAccumulator = new StringBuilder();
+    private boolean enabledForExport = true;
 
-    public TextBlock (String contentInOrgMarkup){
-        text = FormattedText.fromOrg(contentInOrgMarkup);
+    public TextBlock (){
+    }
+
+    public void addContent(String content){
+        orgAccumulator.append(content);
     }
 
     @Override
     public void toMD(StringBuilder sb, int indent) {
+        if (!enabledForExport) return;
+
+        FormattedText text = FormattedText.fromOrg(orgAccumulator.toString());
         sb.append(text.toMD(indent) + "\n");
     }
+
+    public void disableForExport(){
+        enabledForExport = false;
+    }
 }