X-Git-Url: http://www2.svjatoslav.eu/gitweb/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Feu%2Fsvjatoslav%2Fsixth%2Fcore%2Fdocument%2FHeading.java;h=ca7232159e98b2816e0f08c4e09c5d659483eb68;hb=1f96525468e7f76c1ce817a8a7b22c93a39e40b4;hp=f9c3e6d74a7effa9a443bdf7637e3810ceb5ba07;hpb=4d6637215622edcf65ed246e0a63c9e7191e3fc3;p=sixth.git diff --git a/src/main/java/eu/svjatoslav/sixth/core/document/Heading.java b/src/main/java/eu/svjatoslav/sixth/core/document/Heading.java index f9c3e6d..ca72321 100644 --- a/src/main/java/eu/svjatoslav/sixth/core/document/Heading.java +++ b/src/main/java/eu/svjatoslav/sixth/core/document/Heading.java @@ -1,14 +1,134 @@ package eu.svjatoslav.sixth.core.document; +import eu.svjatoslav.commons.string.String2; +import eu.svjatoslav.commons.string.tokenizer.Tokenizer; +import eu.svjatoslav.commons.string.tokenizer.TokenizerMatch; +import eu.svjatoslav.sixth.core.document.content.ListElement; +import eu.svjatoslav.sixth.core.document.text.FormattedText; + +import java.util.ArrayList; +import java.util.List; + +import static eu.svjatoslav.sixth.core.document.Helper.TG_LIST; + public class Heading { - public final String name; + public final FormattedText name; public final int level; public final Heading parent; + private final List children = new ArrayList<>(); - public Heading(String name, int level, Heading parent){ + public final ListElement rootListElement = new ListElement(null, -2, null, ""); + private ListElement currentListElement = rootListElement; + + public Heading(FormattedText name, int level, Heading parent){ this.level = level; this.name = name; this.parent = parent; } + public void addChild(Heading heading){ + children.add(heading); + } + + public List getChildren(){ + return children; + } + + public String toMD () { + StringBuilder sb = new StringBuilder(); + + if (level > 0) sb.append(enlistTitleInMD()); + + rootListElement.toMD(sb, -2); + + children.stream().map(Heading::toMD).forEach(sb::append); + + return sb.toString(); + } + + private String enlistTitleInMD() { + String2 s = new String2(); + s.append("#", level).append(" ").append(name.toMD(0)).append("\n"); + return s.toString(); + } + + public ListElement getCurrentHeading(){ + return currentListElement; + } + + public void parse(TokenizerMatch tm){ + + if (tm.isGroup(TG_LIST)){ + parseList(tm); + return; + } + + currentListElement.parse(tm); + } + + private void parseList(TokenizerMatch tm) { + String[] listSections = tm.getRegExpGroups(); + int indent = listSections[0].length(); + String type = listSections[1]; + FormattedText title = FormattedText.fromOrg(parseFullListTitle(getPartialTitle(listSections), tm.getTokenizer(), indent)); + + if (indent > currentListElement.indent){ + // list dept increases + ListElement newElement = new ListElement(title, indent, currentListElement, type); + currentListElement.addContent(newElement); + currentListElement = newElement; + return; + } + + if (indent > currentListElement.parent.indent){ + // list depth is the same + ListElement newElement = new ListElement(title, indent, currentListElement.parent, type); + currentListElement.parent.addContent(newElement); + currentListElement = newElement; + return; + } + + // list dept decreases + while (true){ + if (currentListElement.parent.indent <= indent){ + ListElement newElement = new ListElement(title, indent, currentListElement.parent.parent, type); + currentListElement.parent.parent.addContent(newElement); + currentListElement = newElement; + return; + } + currentListElement = currentListElement.parent; + } + + } + + private String getPartialTitle(String[] listSections) { + return listSections.length > 2 ? listSections[2] : ""; + } + + private String parseFullListTitle(String partialTitle, Tokenizer tokenizer, int listIndent){ + StringBuilder sb = new StringBuilder(); + sb.append(partialTitle); + + while (tokenizer.hasMoreContent()){ + final TokenizerMatch tm = tokenizer.getNextToken(); + + if (isContentContinuation(tm, listIndent, Helper.TG_NORMAL_TEXT)){ + String titleContinuation = tm.token.substring(listIndent).trim(); + sb.append("\n").append(titleContinuation); + continue; + } + + tokenizer.unreadToken(); + break; + } + + return sb.toString(); + } + + public static boolean isContentContinuation(TokenizerMatch tm, int requiredIndent, String requiredGroup) { + if (tm.token.length() <= requiredIndent) return false; + + return tm.isGroup(requiredGroup) && tm.token.substring(0, requiredIndent +1).trim().length() == 0; + } + }