From: Svjatoslav Agejenko Date: Thu, 10 Sep 2020 18:15:00 +0000 (+0300) Subject: Separate multiline code block language from remaining parameters X-Git-Url: http://www2.svjatoslav.eu/gitweb/?p=sixth.git;a=commitdiff_plain;h=9b683d223e06fc5ec9e2561c659de5a79d3a8194 Separate multiline code block language from remaining parameters Parse document property Parse separators --- diff --git a/src/main/java/eu/svjatoslav/sixth/core/document/Document.java b/src/main/java/eu/svjatoslav/sixth/core/document/Document.java index e4c45bd..c61d613 100644 --- a/src/main/java/eu/svjatoslav/sixth/core/document/Document.java +++ b/src/main/java/eu/svjatoslav/sixth/core/document/Document.java @@ -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" diff --git a/src/main/java/eu/svjatoslav/sixth/core/document/Utils.java b/src/main/java/eu/svjatoslav/sixth/core/document/Utils.java index 406e7ef..00166ef 100644 --- a/src/main/java/eu/svjatoslav/sixth/core/document/Utils.java +++ b/src/main/java/eu/svjatoslav/sixth/core/document/Utils.java @@ -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 index 0000000..adb3c12 --- /dev/null +++ b/src/main/java/eu/svjatoslav/sixth/core/document/content/DocumentPropertyCollection.java @@ -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> keyToValue = new HashMap<>(); + + @Override + public void toMD(StringBuilder sb, int indent) { + } + + public void addProperty(String key, String value){ + getOrCreateValueList(key).add(value); + } + + private List getOrCreateValueList(String key){ + String actualKey = key.toLowerCase(); + if (keyToValue.containsKey(actualKey)) + return keyToValue.get(actualKey); + + List valueList = new ArrayList(); + keyToValue.put(actualKey, valueList); + return valueList; + } + + public boolean hasProperty(String key){ + return keyToValue.containsKey(key.toLowerCase()); + } +} diff --git a/src/main/java/eu/svjatoslav/sixth/core/document/content/ListElement.java b/src/main/java/eu/svjatoslav/sixth/core/document/content/ListElement.java index e1cf33d..0db636f 100644 --- a/src/main/java/eu/svjatoslav/sixth/core/document/content/ListElement.java +++ b/src/main/java/eu/svjatoslav/sixth/core/document/content/ListElement.java @@ -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 = 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(); + } + } } diff --git a/src/main/java/eu/svjatoslav/sixth/core/document/content/MultilineCode.java b/src/main/java/eu/svjatoslav/sixth/core/document/content/MultilineCode.java index db64e3e..212d412 100644 --- a/src/main/java/eu/svjatoslav/sixth/core/document/content/MultilineCode.java +++ b/src/main/java/eu/svjatoslav/sixth/core/document/content/MultilineCode.java @@ -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 index 4034670..0000000 --- a/src/main/java/eu/svjatoslav/sixth/core/document/content/PropertyCollection.java +++ /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 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 index 0000000..44097e9 --- /dev/null +++ b/src/main/java/eu/svjatoslav/sixth/core/document/content/Separator.java @@ -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++; + } +} diff --git a/src/main/java/eu/svjatoslav/sixth/core/document/content/TextBlock.java b/src/main/java/eu/svjatoslav/sixth/core/document/content/TextBlock.java index a3a4611..56177b6 100644 --- a/src/main/java/eu/svjatoslav/sixth/core/document/content/TextBlock.java +++ b/src/main/java/eu/svjatoslav/sixth/core/document/content/TextBlock.java @@ -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; + } }