Go to the documentation of this file.
12 #include <unordered_map>
29 Target(
const std::string& url_,
const std::string& title_):
33 std::optional<Target>
find(
const std::string&
id)
const;
34 void add(
const std::string&
id,
const std::string& url,
const
38 using Table = std::unordered_map<std::string, Target>;
40 static std::string _scrubKey(std::string
str);
55 virtual void writeToken(std::ostream& out)
const = 0;
56 virtual void writeToken(
size_t indent, std::ostream& out)
const
58 out << std::string(indent * 2,
' ');
67 virtual std::optional<std::string>
text()
const
114 size_t isValidTag(
const std::string& tag,
bool nonBlockFirst =
false);
123 mEncodingFlags(encodingFlags) { }
125 void writeAsHtml(std::ostream& out)
const override;
129 out <<
"TextHolder: " << mText <<
'\n';
132 std::optional<std::string>
text()
const override
139 return mCanContainMarkup;
143 const std::string mText;
144 const bool mCanContainMarkup;
145 const int mEncodingFlags;
156 out <<
"RawText: " << *
text() <<
'\n';
162 using ReplacementTable = std::vector<TokenPtr>;
164 static std::string _processHtmlTagAttributes(std::string src, ReplacementTable& replacements);
165 static std::string _processCodeSpans(std::string src, ReplacementTable& replacements);
166 static std::string _processEscapedCharacters(
const std::string& src);
167 static std::string _processLinksImagesAndTags(
const std::string& src, ReplacementTable& replacements,
const LinkIds& idTable);
168 static std::string _processSpaceBracketedGroupings(
const std::string& src, ReplacementTable& replacements);
169 static TokenGroup _processBoldAndItalicSpans(
const std::string& src, ReplacementTable& replacements);
171 static TokenGroup _encodeProcessedItems(
const std::string& src, ReplacementTable& replacements);
172 static std::string _restoreProcessedItems(
const std::string& src, ReplacementTable& replacements);
182 out <<
"HtmlTag: " << *
text() <<
'\n';
196 class HtmlAnchorTag: public TextHolder
199 HtmlAnchorTag(const std::string& url, const std::string& title = std::string());
201 void writeToken(std::ostream& out) const override
203 out << "HtmlAnchorTag: " << *text() << '\n
';
207 class InlineHtmlContents: public TextHolder
210 InlineHtmlContents(const std::string& contents): TextHolder(contents, false,
213 void writeToken(std::ostream& out) const override
215 out << "InlineHtmlContents: " << *text() << '\n
';
219 class InlineHtmlComment: public TextHolder
222 InlineHtmlComment(const std::string& contents): TextHolder(contents, false,
225 void writeToken(std::ostream& out) const override
227 out << "InlineHtmlComment: " << *text() << '\n
';
231 class CodeBlock: public TextHolder
234 CodeBlock(const std::string& actualContents): TextHolder(actualContents,
235 false, cDoubleAmps | cAngles | cQuotes) { }
237 void writeAsHtml(std::ostream& out) const override;
239 void writeToken(std::ostream& out) const override
241 out << "CodeBlock: " << *text() << '\n
';
245 class CodeSpan: public TextHolder
248 CodeSpan(const std::string& actualContents): TextHolder(actualContents,
249 false, cDoubleAmps | cAngles | cQuotes) { }
251 void writeAsHtml(std::ostream& out) const override;
252 void writeAsOriginal(std::ostream& out) const override;
253 void writeToken(std::ostream& out) const override
255 out << "CodeSpan: " << *text() << '\n
';
259 class Header: public TextHolder
262 Header(size_t level, const std::string& text): TextHolder(text, true,
263 cAmps | cAngles | cQuotes), mLevel(level) { }
265 void writeToken(std::ostream& out) const override
268 mLevel << ": " << *text() << '\n
';
271 bool inhibitParagraphs() const override
277 void preWrite(std::ostream& out) const override
279 out << "<h" << mLevel << ">";
281 void postWrite(std::ostream& out) const override
283 out << "</h" << mLevel << ">\n";
290 class BlankLine: public TextHolder
293 BlankLine(const std::string& actualContents = std::string()):
294 TextHolder(actualContents, false, 0) { }
296 void writeToken(std::ostream& out) const override
298 out << "BlankLine: " << *text() << '\n
';
301 bool isBlankLine() const override
309 class EscapedCharacter: public Token
312 EscapedCharacter(char c): mChar(c) { }
314 void writeAsHtml(std::ostream& out) const override
318 void writeAsOriginal(std::ostream& out) const override
320 out << '\\
' << mChar;
322 void writeToken(std::ostream& out) const override
324 out << "EscapedCharacter: " << mChar << '\n
';
333 class Container: public Token
336 Container(const TokenGroup& contents = TokenGroup()): mSubTokens(contents),
337 mParagraphMode(false) { }
339 const TokenGroup& subTokens() const
343 void appendSubtokens(TokenGroup& tokens)
345 mSubTokens.splice(mSubTokens.end(), tokens);
347 void swapSubtokens(TokenGroup& tokens)
349 mSubTokens.swap(tokens);
352 bool isContainer() const override
357 void writeAsHtml(std::ostream& out) const override;
359 void writeToken(std::ostream& out) const override
361 out << "Container: error!" << '\n
';
363 void writeToken(size_t indent, std::ostream& out) const override;
365 std::optional<TokenGroup> processSpanElements(const LinkIds& idTable) override;
367 virtual TokenPtr clone(const TokenGroup& newContents) const
369 return TokenPtr(new Container(newContents));
371 virtual std::string containerName() const
377 TokenGroup mSubTokens;
381 class InlineHtmlBlock: public Container
384 InlineHtmlBlock(const TokenGroup& contents, bool isBlockTag = false):
385 Container(contents), mIsBlockTag(isBlockTag) { }
386 InlineHtmlBlock(const std::string& contents): mIsBlockTag(false)
388 mSubTokens.push_back(TokenPtr(new InlineHtmlContents(contents)));
391 bool inhibitParagraphs() const override
396 TokenPtr clone(const TokenGroup& newContents) const override
398 return TokenPtr(new InlineHtmlBlock(newContents));
400 std::string containerName() const override
402 return "InlineHtmlBlock";
405 // Inline HTML blocks always end with a blank line, so report it as one for
407 bool isBlankLine() const override
416 class ListItem: public Container
419 ListItem(const TokenGroup& contents): Container(contents),
420 mInhibitParagraphs(true) { }
422 void inhibitParagraphs(bool set)
424 mInhibitParagraphs = set;
427 bool inhibitParagraphs() const override
429 return mInhibitParagraphs;
432 TokenPtr clone(const TokenGroup& newContents) const override
434 return TokenPtr(new ListItem(newContents));
436 std::string containerName() const override
442 void preWrite(std::ostream& out) const override
446 void postWrite(std::ostream& out) const override
452 bool mInhibitParagraphs;
455 class UnorderedList: public Container
458 UnorderedList(const TokenGroup& contents, bool paragraphMode = false);
460 TokenPtr clone(const TokenGroup& newContents) const override
462 return TokenPtr(new UnorderedList(newContents));
464 std::string containerName() const override
466 return "UnorderedList";
470 void preWrite(std::ostream& out) const override
474 void postWrite(std::ostream& out) const override
480 class OrderedList: public UnorderedList
483 OrderedList(const TokenGroup& contents, bool paragraphMode = false):
484 UnorderedList(contents, paragraphMode) { }
486 TokenPtr clone(const TokenGroup& newContents) const override
488 return TokenPtr(new OrderedList(newContents));
490 std::string containerName() const override
492 return "OrderedList";
496 void preWrite(std::ostream& out) const override
500 void postWrite(std::ostream& out) const override
506 class BlockQuote: public Container
509 BlockQuote(const TokenGroup& contents): Container(contents) { }
511 TokenPtr clone(const TokenGroup& newContents) const override
513 return TokenPtr(new BlockQuote(newContents));
515 std::string containerName() const override
521 void preWrite(std::ostream& out) const override
523 out << "<blockquote>\n";
525 void postWrite(std::ostream& out) const override
527 out << "\n</blockquote>\n";
531 class Paragraph: public Container
535 Paragraph(const TokenGroup& contents): Container(contents) { }
537 TokenPtr clone(const TokenGroup& newContents) const override
539 return TokenPtr(new Paragraph(newContents));
541 std::string containerName() const override
547 void preWrite(std::ostream& out) const override
551 void postWrite(std::ostream& out) const override
559 class BoldOrItalicMarker: public Token
562 BoldOrItalicMarker(bool open, char c, size_t size): mOpenMarker(open),
563 mTokenCharacter(c), mSize(size), mMatch(0), mCannotMatch(false),
564 mDisabled(false), mId(-1) { }
566 bool isUnmatchedOpenMarker() const override
568 return (mOpenMarker && mMatch == 0 && !mCannotMatch);
570 bool isUnmatchedCloseMarker() const override
572 return (!mOpenMarker && mMatch == 0 && !mCannotMatch);
574 bool isMatchedOpenMarker() const override
576 return (mOpenMarker && mMatch != 0);
578 bool isMatchedCloseMarker() const override
580 return (!mOpenMarker && mMatch != 0);
582 void writeAsHtml(std::ostream& out) const override;
583 void writeToken(std::ostream& out) const override;
585 bool isOpenMarker() const
589 char tokenCharacter() const
591 return mTokenCharacter;
599 return (mMatch != 0);
601 BoldOrItalicMarker* matchedTo() const
610 void matched(BoldOrItalicMarker* match, int id = -1)
615 void cannotMatch(bool set)
621 mCannotMatch = mDisabled = true;
625 bool mOpenMarker; // Otherwise it's a close-marker
626 char mTokenCharacter;
637 Image(
const std::string& altText,
const std::string& url,
const std::string&
638 title): mAltText(altText), mUrl(url), mTitle(title) { }
640 void writeAsHtml(std::ostream& out)
const override;
644 out <<
"Image: " << mUrl <<
'\n';
648 const std::string mAltText, mUrl, mTitle;
std::optional< std::string > text() const override
virtual bool isUnmatchedOpenMarker() const
void writeToken(std::ostream &out) const override
virtual bool isMatchedOpenMarker() const
Target(const std::string &url_, const std::string &title_)
RawText(const std::string &text, bool canContainMarkup=true)
HtmlTag(const std::string &contents)
virtual std::optional< std::string > text() const
TextHolder(const std::string &text, bool canContainMarkup, unsigned int encodingFlags)
virtual bool inhibitParagraphs() const
virtual bool isBlankLine() const
virtual bool isContainer() const
size_t isValidTag(const std::string &tag, bool nonBlockFirst)
void postWrite(std::ostream &out) const override
bool canContainMarkup() const override
void add(const std::string &id, const std::string &url, const std::string &title)
void preWrite(std::ostream &out) const override
double a(double t, double a0, double j)
virtual void writeToken(size_t indent, std::ostream &out) const
virtual std::optional< TokenGroup > processSpanElements(const LinkIds &idTable)
TokenGroup::iterator TokenGroupIter
virtual void writeToken(std::ostream &out) const =0
virtual bool canContainMarkup() const
virtual void writeAsHtml(std::ostream &) const =0
virtual void preWrite(std::ostream &out) const
virtual void writeAsOriginal(std::ostream &out) const
TokenGroup::const_iterator CTokenGroupIter
virtual void postWrite(std::ostream &out) const
virtual bool isMatchedCloseMarker() const
void writeToken(std::ostream &out) const override
void writeAsHtml(std::ostream &out) const override
void writeToken(std::ostream &out) const override
std::list< TokenPtr > TokenGroup
std::optional< TokenGroup > processSpanElements(const LinkIds &idTable) override
void writeToken(std::ostream &out) const override
std::optional< Target > find(const std::string &id) const
double s(double t, double s0, double v0, double a0, double j)
virtual bool isUnmatchedCloseMarker() const
Image(const std::string &altText, const std::string &url, const std::string &title)