================ @@ -0,0 +1,229 @@ +#include "MDParser.h" +#include "clang/Basic/CharInfo.h" +#include "llvm/ADT/AllocatorList.h" + +namespace clang { +namespace doc { +namespace { +bool isEmphasisDelimiter(char &Token) { + // TODO: support '_' + if (Token == '*') + return true; + return false; +} +} // namespace + +std::pair<std::optional<DelimiterContext>, size_t> +MarkdownParser::processDelimiters(SmallString<64> &Line, const size_t &Origin) { + size_t Idx = Origin; + while (Idx < Line.size() && Line[Idx] == Line[Origin]) { + ++Idx; + } + + char Preceeding = (Origin == 0) ? ' ' : Line[Origin - 1]; + char Proceeding = (Idx >= Line.size()) ? ' ' : Line[Idx]; + + bool LeftFlanking = !isWhitespace(Proceeding) && + (!isPunctuation(Proceeding) || isWhitespace(Preceeding) || + isPunctuation(Preceeding)); + bool RightFlanking = !isWhitespace(Preceeding) && + (!isPunctuation(Preceeding) || isWhitespace(Proceeding) || + isPunctuation(Proceeding)); + + if (LeftFlanking && RightFlanking) + return {DelimiterContext{LeftFlanking, RightFlanking, true, true}, Idx}; + if (LeftFlanking) + return {DelimiterContext{LeftFlanking, RightFlanking, true, false}, Idx}; + if (RightFlanking) + return {DelimiterContext{LeftFlanking, RightFlanking, false, true}, Idx}; + return {std::nullopt, 0}; +} + +Node *MarkdownParser::createTextNode(const std::list<LineNode *> &Text) { + Node *TextNode = new (Arena) Node(); + for (const auto *Node : Text) { + TextNode->Content.append(Node->Content); + } + TextNode->Type = MDType::Text; + return TextNode; +} + +Node *MarkdownParser::reverseIterateLine(std::list<LineNode *> &Stack, + std::list<LineNode *>::iterator &It) { + auto ReverseIt = std::make_reverse_iterator(It); + std::list<LineNode *> Text; + while (ReverseIt != Stack.rend()) { + auto *ReverseCurrent = *ReverseIt; + if (!ReverseCurrent->DelimiterContext && !ReverseCurrent->Content.empty()) { + Text.push_back(ReverseCurrent); + ReverseIt++; + continue; + } + + if (ReverseCurrent->DelimiterContext && + ReverseCurrent->DelimiterContext->CanOpen) { + if (Text.empty()) { + // If there is no text between the runs, there is no emphasis, so both + // delimiter runs are literal text. + auto *DelimiterTextNode = new (Arena) Node(); + DelimiterTextNode->Content = + Saver.save((*It)->Content + ReverseCurrent->Content); + DelimiterTextNode->Type = MDType::Text; + return DelimiterTextNode; + } + Node *Emphasis = nullptr; + + auto &Closer = (*It)->DelimiterContext; + auto &Opener = ReverseCurrent->DelimiterContext; + + if (Closer->Length >= 2 && Opener->Length >= 2) { + // We have at least one strong node. + Closer->Length -= 2; + Opener->Length -= 2; + Emphasis = new (Arena) Node(); + Emphasis->Type = MDType::Strong; + auto *Child = createTextNode(Text); + Child->Parent = Emphasis; + Emphasis->Children.push_back(Child); + } else if (Closer->Length == 1 && Opener->Length == 1) { + Closer->Length -= 1; + Opener->Length -= 1; + Emphasis = new (Arena) Node(); + Emphasis->Type = MDType::Emphasis; + auto *Child = createTextNode(Text); + Child->Parent = Emphasis; + Emphasis->Children.push_back(Child); + } + + if (Closer->Length == 0) + It = Stack.erase(It); + if (Opener->Length == 0) + ReverseIt = std::make_reverse_iterator(Stack.erase(ReverseIt.base())); ---------------- ilovepi wrote:
This seems a little hairy. https://github.com/llvm/llvm-project/pull/155887 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits