TDME2  1.9.200
Markdown.cpp
Go to the documentation of this file.
2 
3 #include <string>
4 #include <vector>
5 
6 #include <tdme/tdme.h>
7 #include <tdme/gui/GUIParser.h>
11 
12 using std::string;
13 using std::to_string;
14 using std::vector;
15 
17 
22 
23 const string Markdown::createGUIXML(const string& pathName, const string& fileName, vector<TOCEntry>& toc) {
24  vector<string> markdownLines;
25  FileSystem::getInstance()->getContentAsStringArray(pathName, fileName, markdownLines);
26  string xml;
27  xml+= "<screen id='markdown' min-width='1024' min-height='768' max-width='3200' max-height='1800'>\n";
28  xml+= "\t<scrollarea width='100%' height='100%'>\n";
29  xml+= "\t\t<layout alignment='vertical' width='100%' height='auto'>\n";
30  auto inTable = false;
31  auto inTableIdx = 0;
32  auto inCode = false;
33  string inCodeString;
34  int tocIdx = 1;
35  auto tocLevel1 = 0;
36  auto tocLevel2 = 0;
37  auto tocLevel3 = 0;
38  auto tocLevel4 = 0;
39  for (auto markdownLine: markdownLines) {
40  markdownLine = StringTools::replace(markdownLine, "&nbsp;", " ");
41  //
42  markdownLine = StringTools::replace(markdownLine, "\\<", "<");
43  markdownLine = StringTools::replace(markdownLine, "\\>", ">");
44  // TODO: support <sub> and </sub>
45  markdownLine = StringTools::replace(markdownLine, "<sub>", "");
46  markdownLine = StringTools::replace(markdownLine, "</sub>", "");
47  // TODO: support <i> and </i>
48  markdownLine = StringTools::replace(markdownLine, "<i>", "");
49  markdownLine = StringTools::replace(markdownLine, "</i>", "");
50  //
51  auto markdownLineTrimmed = StringTools::trim(markdownLine);
52  //
53  if (inTable == true && StringTools::startsWith(markdownLine, "|") == false) {
54  inTable = false;
55  inTableIdx = 0;
56  xml+= "</table>\n";
57  }
58  if (StringTools::startsWith(markdownLine, "```") == true) {
59  if (inCode == false) {
60  inCode = true;
61  } else {
62  xml+= "<space height='10'/>\n";
63  xml+= "<styled-text font='{$font.default}' size='{$fontsize.default}' color='{$color.font_normal}' background-color='{$color.element_midground}' border-color='{$color.element_frame}' border='1' padding='5' width='*' height='auto' preformatted='true'>\n";
64  xml+= " <![CDATA[\n";
65  xml+= StringTools::replace(StringTools::replace(inCodeString, "[", "\\["), "]", "\\]");
66  xml+= " ]]>\n";
67  xml+= "</styled-text>\n";
68  xml+= "<space height='10'/>\n";
69  inCodeString.clear();
70  inCode = false;
71  }
72  } else
73  if (inCode == true) {
74  inCodeString+= markdownLine + "\n";
75  } else
76  if (inTable == false && markdownLineTrimmed.empty() == true) {
77  xml+= "<space height='20'/>\n";
78  } else
79  if (inTable == false && StringTools::startsWith(markdownLineTrimmed, "-") == true) {
80  string textSize = "{$fontsize.default}";
81  auto bulletPointIdx = StringTools::firstIndexOf(markdownLine, '-');
82  auto bulletPoint = StringTools::trim(StringTools::substring(markdownLine, bulletPointIdx + 1));
83  auto indent = bulletPointIdx / 2;
84  xml+= "<layout alignment='horizontal' width='100%' height='auto'>\n";
85  xml+= "\t<space width='" + to_string((bulletPointIdx + 1) * 10) + "'/>\n";
86  xml+= "\t<styled-text font='{$font.default}' size='" + textSize + "' color='{$color.font_normal}' width='*' height='auto'>• " + GUIParser::escape(bulletPoint) + "</styled-text>\n";
87  xml+= "</layout>\n";
88  } else
89  // image
90  if (StringTools::startsWith(markdownLine, "!") == true) {
91  string tooltip;
92  {
93  auto tooltipStartPosition = StringTools::indexOf(markdownLine, '[');
94  auto tooltipEndPosition = StringTools::indexOf(markdownLine, ']');
95  if (tooltipStartPosition != string::npos &&
96  tooltipEndPosition != string::npos &&
97  tooltipEndPosition > tooltipStartPosition) {
98  tooltip = StringTools::substring(markdownLine, tooltipStartPosition + 1, tooltipEndPosition);
99  }
100  }
101  string source;
102  {
103  string url;
104  auto urlStartPosition = StringTools::indexOf(markdownLine, '(');
105  auto urlEndPosition = StringTools::indexOf(markdownLine, ')');
106  if (urlStartPosition != string::npos &&
107  urlEndPosition != string::npos &&
108  urlEndPosition > urlStartPosition) {
109  url = StringTools::substring(markdownLine, urlStartPosition + 1, urlEndPosition);
110  }
111  if (StringTools::startsWith(url, "https://raw.githubusercontent.com/andreasdr/tdme2/master/") == true) {
112  source = StringTools::substring(url, string("https://raw.githubusercontent.com/andreasdr/tdme2/master/").size());
113  }
114  }
115  //
116  if (source.empty() == false) {
117  xml+= "<image src='" + GUIParser::escape(FileSystem::getInstance()->getCurrentWorkingPathName() + "/" + source) + "' tooltip='" + GUIParser::escape(tooltip) + "' />\n";
118  }
119  } else
120  if (StringTools::startsWith(markdownLine, "|") == true) {
121  if (inTable == false) {
122  inTable = true;
123  xml+= "<table width='auto' height='auto'>\n";
124  }
125  markdownLine = StringTools::trim(markdownLine);
126  vector<string> tableColumnStrings = { "" };
127  auto separator = true;
128  for (auto i = 1; i < markdownLine.size(); i++) {
129  if (markdownLine[i - 1] != '\\' && markdownLine[i] == '|') {
130  if (i != markdownLine.size() - 1) tableColumnStrings.push_back(string());
131  continue;
132  }
133  tableColumnStrings[tableColumnStrings.size() - 1]+= markdownLine[i];
134  if (markdownLine[i] != '-' && markdownLine[i] != ' ' && markdownLine[i] != '\t' && markdownLine[i] != '|') separator = false;
135  }
136  if (separator == false) {
137  xml+= "<table-row>\n";
138  for (auto tableColumnString: tableColumnStrings) {
139  tableColumnString = StringTools::replace(tableColumnString, "\\<", "<");
140  tableColumnString = StringTools::replace(tableColumnString, "\\>", ">");
141  tableColumnString = StringTools::replace(tableColumnString, "\\|", "|");
142  string textSize = "{$fontsize.default}";
143  string backgroundColor = (inTableIdx % 2) == 0?"{$color.element_midground}":"{$color.element_background}";
144  xml+= "<table-cell padding='5' background-color='" + backgroundColor + "' border='1' border-color='{$color.element_frame}'>\n";
145  xml+= "\t<text font='{$font.default}' size='" + textSize + "' text='" + GUIParser::escape(StringTools::trim(tableColumnString)) + "' color='{$color.font_normal}' width='auto' height='auto' />\n";
146  xml+= "</table-cell>\n";
147  }
148  xml+= "</table-row>\n";
149  inTableIdx++;
150  }
151  } else {
152  // text
153  string tocId;
154  string textSize = "{$fontsize.default}";
155  if (StringTools::startsWith(markdownLine, "####") == true) {
156  markdownLine = StringTools::trim(StringTools::substring(markdownLine, 4));
157  textSize = "{$fontsize.h4}";
158  tocId = to_string(tocIdx++);
159  tocLevel4++;
160  string tocLevel;
161  tocLevel+= StringTools::padLeft(to_string(tocLevel1), "0", 3) + ".";
162  tocLevel+= StringTools::padLeft(to_string(tocLevel2), "0", 3) + ".";
163  tocLevel+= StringTools::padLeft(to_string(tocLevel3), "0", 3) + ".";
164  tocLevel+= StringTools::padLeft(to_string(tocLevel4), "0", 3) + ".";
165  toc.push_back(
166  {
167  .id = tocId,
168  .level = tocLevel,
169  .title = markdownLine
170  }
171  );
172  } else
173  if (StringTools::startsWith(markdownLine, "###") == true) {
174  markdownLine = StringTools::trim(StringTools::substring(markdownLine, 3));
175  textSize = "{$fontsize.h3}";
176  tocId = to_string(tocIdx++);
177  tocLevel3++;
178  tocLevel4 = 0;
179  string tocLevel;
180  tocLevel+= StringTools::padLeft(to_string(tocLevel1), "0", 3) + ".";
181  tocLevel+= StringTools::padLeft(to_string(tocLevel2), "0", 3) + ".";
182  tocLevel+= StringTools::padLeft(to_string(tocLevel3), "0", 3) + ".";
183  toc.push_back(
184  {
185  .id = tocId,
186  .level = tocLevel,
187  .title = markdownLine
188  }
189  );
190  } else
191  if (StringTools::startsWith(markdownLine, "##") == true) {
192  markdownLine = StringTools::trim(StringTools::substring(markdownLine, 2));
193  textSize = "{$fontsize.h2}";
194  tocId = to_string(tocIdx++);
195  tocLevel2++;
196  tocLevel3 = 0;
197  tocLevel4 = 0;
198  string tocLevel;
199  tocLevel+= StringTools::padLeft(to_string(tocLevel1), "0", 3) + ".";
200  tocLevel+= StringTools::padLeft(to_string(tocLevel2), "0", 3) + ".";
201  toc.push_back(
202  {
203  .id = tocId,
204  .level = tocLevel,
205  .title = markdownLine
206  }
207  );
208  } else
209  if (StringTools::startsWith(markdownLine, "#") == true) {
210  markdownLine = StringTools::trim(StringTools::substring(markdownLine, 1));
211  textSize = "{$fontsize.h1}";
212  tocId = to_string(tocIdx++);
213  tocLevel1++;
214  tocLevel2 = 0;
215  tocLevel3 = 0;
216  tocLevel4 = 0;
217  string tocLevel;
218  tocLevel+= StringTools::padLeft(to_string(tocLevel1), "0", 3) + ".";
219  toc.push_back(
220  {
221  .id = tocId,
222  .level = tocLevel,
223  .title = markdownLine
224  }
225  );
226  }
227  xml+= "<styled-text " + (tocId.empty() == false?"id = '" + tocId + "' ":"") + "font='{$font.default}' size='" + textSize + "' color='{$color.font_normal}' width='*' height='auto'>" + GUIParser::escape(markdownLine) + "</styled-text>\n";
228  }
229  }
230  if (inCode == true) {
231  xml+= "<space height='10'/>\n";
232  xml+= "<styled-text font='{$font.default}' size='{$fontsize.default}' color='{$color.font_normal}' background-color='{$color.element_midground}' border-color='{$color.element_frame}' border='1' padding='5' width='*' height='auto' preformatted='true'>\n";
233  xml+= " <![CDATA[\n";
234  xml+= StringTools::replace(StringTools::replace(inCodeString, "[", "\\["), "]", "\\]");
235  xml+= " ]]>\n";
236  xml+= "</styled-text>\n";
237  xml+= "<space height='10'/>\n";
238  }
239  if (inTable == true) xml+= "</table>\n";
240  //
241  xml+= "\t\t</layout>\n";
242  xml+= "\t</scrollarea>\n";
243  xml+= "</screen>\n";
244  // FileSystem::getStandardFileSystem()->setContentFromString(".", "xxx.xml", xml);
245  return xml;
246 }
GUI parser.
Definition: GUIParser.h:40
File system singleton class.
Definition: FileSystem.h:17
String tools class.
Definition: StringTools.h:22