1 package eu.svjatoslav.sixth.core.document;
3 import eu.svjatoslav.commons.string.tokenizer.Tokenizer;
4 import eu.svjatoslav.commons.string.tokenizer.TokenizerMatch;
5 import eu.svjatoslav.sixth.core.document.content.ListElement;
6 import eu.svjatoslav.sixth.core.document.text.FormattedText;
8 import java.util.ArrayList;
11 import static eu.svjatoslav.sixth.core.document.Helper.TG_LIST;
13 public class Heading {
14 public final FormattedText name;
15 public final int level;
16 public final Heading parent;
17 private final List<Heading> children = new ArrayList<>();
19 public final ListElement rootListElement = new ListElement(null, -1, null, "");
20 private ListElement currentListElement = rootListElement;
22 public Heading(FormattedText name, int level, Heading parent){
28 public void addChild(Heading heading){
29 children.add(heading);
32 public List<Heading> getChildren(){
36 public String toMD () {
37 StringBuilder sb = new StringBuilder();
39 if (level > 0) sb.append(enlistTitleInMD());
41 rootListElement.toMD(sb, -2);
43 children.stream().map(Heading::toMD).forEach(sb::append);
48 private String enlistTitleInMD() {
49 StringBuilder sb = new StringBuilder();
50 for (int i = 0; i < level; i++)
53 sb.append(" ").append(name.toMD()).append("\n");
57 public ListElement getCurrentHeading(){
58 return currentListElement;
61 public void parse(TokenizerMatch tm){
63 if (tm.isGroup(TG_LIST)){
68 currentListElement.parse(tm);
71 private void parseList(TokenizerMatch tm) {
72 String[] listSections = tm.getRegExpGroups();
73 int indent = listSections[0].length();
74 String type = listSections[1];
76 FormattedText title = FormattedText.fromOrg(parseFullListTitle(listSections.length > 2 ? listSections[2] : "", tm.getTokenizer(), indent));
78 // System.out.println(" indent: " + indent);
79 // System.out.println(" type: " + type);
80 // System.out.println(" title: " + title);
82 ListElement parent = null;
84 if (indent > currentListElement.indent){
85 ListElement newElement = new ListElement(title, indent, parent, type);
86 currentListElement.addContent(newElement);
87 currentListElement = newElement;
93 private String parseFullListTitle(String partialTitle, Tokenizer tokenizer, int listIndent){
94 StringBuilder sb = new StringBuilder();
95 sb.append(partialTitle);
97 while (tokenizer.hasMoreContent()){
98 final TokenizerMatch tm = tokenizer.getNextToken();
100 if (isContentContinuation(tm, listIndent, null)){
101 String titleContinuation = tm.token.substring(listIndent).trim();
102 sb.append("\n").append(titleContinuation);
106 tokenizer.unreadToken();
110 return sb.toString();
113 public static boolean isContentContinuation(TokenizerMatch tm, int requiredIndent, String requiredGroup) {
114 if (tm.token.length() <= requiredIndent) return false;
116 return tm.isGroup(requiredGroup) && tm.token.substring(0, requiredIndent +1).trim().length() == 0;