9 #include "clang/Basic/CharInfo.h" 10 #include "llvm/ADT/StringRef.h" 11 #include "llvm/Support/ErrorHandling.h" 12 #include "llvm/Support/FormatVariadic.h" 22 static std::string renderText(llvm::StringRef Input) {
25 R
"txt(!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)txt"; 28 for (
size_t From = 0; From < Input.size();) {
29 size_t Next = Input.find_first_of(Punctuation, From);
30 R += Input.substr(From, Next - From);
31 if (Next == llvm::StringRef::npos)
43 static std::string renderInlineBlock(llvm::StringRef Input) {
46 for (
size_t From = 0; From < Input.size();) {
47 size_t Next = Input.find(
"`", From);
48 R += Input.substr(From, Next - From);
49 if (Next == llvm::StringRef::npos)
57 if (llvm::StringRef(R).startswith(
"`") || llvm::StringRef(R).endswith(
"`"))
58 return "` " + std::move(R) +
" `";
62 if (llvm::StringRef(R).startswith(
" ") && llvm::StringRef(R).endswith(
" "))
63 return "` " + std::move(R) +
" `";
64 return "`" + std::move(R) +
"`";
69 static std::string renderCodeBlock(llvm::StringRef Input,
70 llvm::StringRef Language) {
73 unsigned MaxBackticks = 0;
74 unsigned Backticks = 0;
75 for (
char C : Input) {
80 MaxBackticks = std::max(MaxBackticks, Backticks);
83 MaxBackticks = std::max(Backticks, MaxBackticks);
85 std::string BlockMarker(std::max(3u, MaxBackticks + 1),
'`');
86 return BlockMarker + Language.str() +
"\n" + Input.str() +
"\n" + BlockMarker;
93 C.Kind = ChunkKind::PlainText;
100 C.Kind = ChunkKind::CodeBlock;
101 C.Contents = std::move(Code);
102 C.Language = std::move(Language);
103 Chunks.push_back(std::move(C));
108 C.Kind = ChunkKind::InlineCodeBlock;
109 C.Contents = std::move(Code);
110 Chunks.push_back(std::move(C));
115 auto EnsureWhitespace = [&R]() {
117 if (!R.empty() && !isWhitespace(R.back()))
120 for (
const auto &C : Chunks) {
122 case ChunkKind::PlainText:
123 if (!C.Contents.empty() && !isWhitespace(C.Contents.front()))
125 R += renderText(C.Contents);
127 case ChunkKind::InlineCodeBlock:
129 R += renderInlineBlock(C.Contents);
131 case ChunkKind::CodeBlock:
132 if (!R.empty() && !llvm::StringRef(R).endswith(
"\n"))
134 R += renderCodeBlock(C.Contents, C.Language);
138 llvm_unreachable(
"unhanlded ChunkKind");
145 auto EnsureWhitespace = [&]() {
146 if (R.empty() || isWhitespace(R.back()))
150 Optional<bool> LastWasBlock;
151 for (
const auto &C : Chunks) {
152 bool IsBlock = C.Kind == ChunkKind::CodeBlock;
153 if (LastWasBlock.hasValue() && (IsBlock || *LastWasBlock))
155 LastWasBlock = IsBlock;
158 case ChunkKind::PlainText:
162 case ChunkKind::InlineCodeBlock:
166 case ChunkKind::CodeBlock:
171 while (!R.empty() && isWhitespace(R.back()))
179 for (
const auto &C : Chunks) {
181 case ChunkKind::PlainText:
182 R +=
"text[" + C.Contents +
"]";
184 case ChunkKind::InlineCodeBlock:
185 R +=
"code[" + C.Contents +
"]";
187 case ChunkKind::CodeBlock:
190 R += llvm::formatv(
"codeblock({0}) [\n{1}\n]\n", C.Language, C.Contents);
194 while (!R.empty() && isWhitespace(R.back()))
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//