diff options
Diffstat (limited to 'clang-tools-extra/clangd/support/Markup.cpp')
-rw-r--r-- | clang-tools-extra/clangd/support/Markup.cpp | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/clang-tools-extra/clangd/support/Markup.cpp b/clang-tools-extra/clangd/support/Markup.cpp index 89bdc65..304917d 100644 --- a/clang-tools-extra/clangd/support/Markup.cpp +++ b/clang-tools-extra/clangd/support/Markup.cpp @@ -199,10 +199,16 @@ bool needsLeadingEscape(char C, llvm::StringRef Before, llvm::StringRef After, return needsLeadingEscapeMarkdown(C, After); } -/// Escape a markdown text block. +/// \brief Render text for markdown output. +/// /// If \p EscapeMarkdown is true it ensures the punctuation will not introduce /// any of the markdown constructs. +/// /// Else, markdown syntax is not escaped, only HTML tags and entities. +/// HTML is escaped because usually clients do not support HTML rendering by +/// default. Passing unescaped HTML will therefore often result in not showing +/// the HTML at all. +/// \note In markdown code spans, we do not escape anything. std::string renderText(llvm::StringRef Input, bool StartsLine, bool EscapeMarkdown) { std::string R; @@ -213,6 +219,10 @@ std::string renderText(llvm::StringRef Input, bool StartsLine, bool IsFirstLine = true; + // Inside markdown code spans, we do not escape anything when EscapeMarkdown + // is false. + bool InCodeSpan = false; + for (std::tie(Line, Rest) = Input.split('\n'); !(Line.empty() && Rest.empty()); std::tie(Line, Rest) = Rest.split('\n')) { @@ -226,12 +236,27 @@ std::string renderText(llvm::StringRef Input, bool StartsLine, R.append(LeadingSpaces); } + // Handle the case where the user escaped a character themselves. + // This is relevant for markdown code spans if EscapeMarkdown is false, + // because if the user escaped a backtick, we must treat the enclosed text + // as normal markdown text. + bool UserEscape = false; for (unsigned I = LeadingSpaces.size(); I < Line.size(); ++I) { - if (needsLeadingEscape(Line[I], Line.substr(LeadingSpaces.size(), I), + + if (!EscapeMarkdown && !UserEscape && Line[I] == '`') + InCodeSpan = !InCodeSpan; + + if (!InCodeSpan && + needsLeadingEscape(Line[I], Line.substr(LeadingSpaces.size(), I), Line.substr(I + 1), StartsLineIntern, EscapeMarkdown)) R.push_back('\\'); R.push_back(Line[I]); + + if (Line[I] == '\\') + UserEscape = !UserEscape; + else + UserEscape = false; } IsFirstLine = false; |