clang-tools 20.0.0git
Markup.h
Go to the documentation of this file.
1//===--- Markup.h -------------------------------------------*- C++-*------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// A model of formatted text that can be rendered to plaintext or markdown.
10//
11//===----------------------------------------------------------------------===//
12#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_MARKUP_H
13#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_MARKUP_H
14
15#include "llvm/Support/raw_ostream.h"
16#include <cstddef>
17#include <memory>
18#include <string>
19#include <vector>
20
21namespace clang {
22namespace clangd {
23namespace markup {
24
25/// Holds text and knows how to lay it out. Multiple blocks can be grouped to
26/// form a document. Blocks include their own trailing newlines, container
27/// should trim them if need be.
28class Block {
29public:
30 virtual void renderMarkdown(llvm::raw_ostream &OS) const = 0;
31 virtual void renderPlainText(llvm::raw_ostream &OS) const = 0;
32 virtual std::unique_ptr<Block> clone() const = 0;
33 std::string asMarkdown() const;
34 std::string asPlainText() const;
35
36 virtual bool isRuler() const { return false; }
37 virtual ~Block() = default;
38};
39
40/// Represents parts of the markup that can contain strings, like inline code,
41/// code block or plain text.
42/// One must introduce different paragraphs to create separate blocks.
43class Paragraph : public Block {
44public:
45 void renderMarkdown(llvm::raw_ostream &OS) const override;
46 void renderPlainText(llvm::raw_ostream &OS) const override;
47 std::unique_ptr<Block> clone() const override;
48
49 /// Append plain text to the end of the string.
50 Paragraph &appendText(llvm::StringRef Text);
51
52 /// Append inline code, this translates to the ` block in markdown.
53 /// \p Preserve indicates the code span must be apparent even in plaintext.
54 Paragraph &appendCode(llvm::StringRef Code, bool Preserve = false);
55
56 /// Ensure there is space between the surrounding chunks.
57 /// Has no effect at the beginning or end of a paragraph.
59
60private:
61 struct Chunk {
62 enum {
64 InlineCode,
65 } Kind = PlainText;
66 // Preserve chunk markers in plaintext.
67 bool Preserve = false;
68 std::string Contents;
69 // Whether this chunk should be surrounded by whitespace.
70 // Consecutive SpaceAfter and SpaceBefore will be collapsed into one space.
71 // Code spans don't usually set this: their spaces belong "inside" the span.
72 bool SpaceBefore = false;
73 bool SpaceAfter = false;
74 };
75 std::vector<Chunk> Chunks;
76};
77
78/// Represents a sequence of one or more documents. Knows how to print them in a
79/// list like format, e.g. by prepending with "- " and indentation.
80class BulletList : public Block {
81public:
84
85 void renderMarkdown(llvm::raw_ostream &OS) const override;
86 void renderPlainText(llvm::raw_ostream &OS) const override;
87 std::unique_ptr<Block> clone() const override;
88
89 class Document &addItem();
90
91private:
92 std::vector<class Document> Items;
93};
94
95/// A format-agnostic representation for structured text. Allows rendering into
96/// markdown and plaintext.
97class Document {
98public:
99 Document() = default;
100 Document(const Document &Other) { *this = Other; }
101 Document &operator=(const Document &);
102 Document(Document &&) = default;
104
105 void append(Document Other);
106
107 /// Adds a semantical block that will be separate from others.
109 /// Inserts a horizontal separator to the document.
110 void addRuler();
111 /// Adds a block of code. This translates to a ``` block in markdown. In plain
112 /// text representation, the code block will be surrounded by newlines.
113 void addCodeBlock(std::string Code, std::string Language = "cpp");
114 /// Heading is a special type of paragraph that will be prepended with \p
115 /// Level many '#'s in markdown.
116 Paragraph &addHeading(size_t Level);
117
119
120 /// Doesn't contain any trailing newlines.
121 /// We try to make the markdown human-readable, e.g. avoid extra escaping.
122 /// At least one client (coc.nvim) displays the markdown verbatim!
123 std::string asMarkdown() const;
124 /// Doesn't contain any trailing newlines.
125 std::string asPlainText() const;
126
127private:
128 std::vector<std::unique_ptr<Block>> Children;
129};
130} // namespace markup
131} // namespace clangd
132} // namespace clang
133
134#endif
BindArgumentKind Kind
std::string Code
llvm::raw_string_ostream OS
Definition: TraceTests.cpp:160
Holds text and knows how to lay it out.
Definition: Markup.h:28
virtual bool isRuler() const
Definition: Markup.h:36
virtual std::unique_ptr< Block > clone() const =0
virtual void renderPlainText(llvm::raw_ostream &OS) const =0
virtual ~Block()=default
std::string asPlainText() const
Definition: Markup.cpp:337
std::string asMarkdown() const
Definition: Markup.cpp:330
virtual void renderMarkdown(llvm::raw_ostream &OS) const =0
Represents a sequence of one or more documents.
Definition: Markup.h:80
void renderPlainText(llvm::raw_ostream &OS) const override
Definition: Markup.cpp:409
class Document & addItem()
Definition: Markup.cpp:456
std::unique_ptr< Block > clone() const override
Definition: Markup.cpp:452
void renderMarkdown(llvm::raw_ostream &OS) const override
Definition: Markup.cpp:399
A format-agnostic representation for structured text.
Definition: Markup.h:97
Paragraph & addParagraph()
Adds a semantical block that will be separate from others.
Definition: Markup.cpp:473
std::string asMarkdown() const
Doesn't contain any trailing newlines.
Definition: Markup.cpp:485
Document & operator=(const Document &)
Definition: Markup.cpp:461
Paragraph & addHeading(size_t Level)
Heading is a special type of paragraph that will be prepended with Level many '#'s in markdown.
Definition: Markup.cpp:498
Document & operator=(Document &&)=default
void append(Document Other)
Definition: Markup.cpp:468
void addCodeBlock(std::string Code, std::string Language="cpp")
Adds a block of code.
Definition: Markup.cpp:480
BulletList & addBulletList()
Definition: Markup.cpp:493
std::string asPlainText() const
Doesn't contain any trailing newlines.
Definition: Markup.cpp:489
Document(const Document &Other)
Definition: Markup.h:100
Document(Document &&)=default
void addRuler()
Inserts a horizontal separator to the document.
Definition: Markup.cpp:478
Represents parts of the markup that can contain strings, like inline code, code block or plain text.
Definition: Markup.h:43
void renderMarkdown(llvm::raw_ostream &OS) const override
Definition: Markup.cpp:344
std::unique_ptr< Block > clone() const override
Definition: Markup.cpp:367
Paragraph & appendText(llvm::StringRef Text)
Append plain text to the end of the string.
Definition: Markup.cpp:423
void renderPlainText(llvm::raw_ostream &OS) const override
Definition: Markup.cpp:382
Paragraph & appendSpace()
Ensure there is space between the surrounding chunks.
Definition: Markup.cpp:417
Paragraph & appendCode(llvm::StringRef Code, bool Preserve=false)
Append inline code, this translates to the ` block in markdown.
Definition: Markup.cpp:436
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//