clang-tools  14.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 
21 namespace clang {
22 namespace clangd {
23 namespace 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.
28 class Block {
29 public:
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.
43 class Paragraph : public Block {
44 public:
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 
60 private:
61  struct Chunk {
62  enum {
63  PlainText,
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.
80 class BulletList : public Block {
81 public:
82  void renderMarkdown(llvm::raw_ostream &OS) const override;
83  void renderPlainText(llvm::raw_ostream &OS) const override;
84  std::unique_ptr<Block> clone() const override;
85 
86  class Document &addItem();
87 
88 private:
89  std::vector<class Document> Items;
90 };
91 
92 /// A format-agnostic representation for structured text. Allows rendering into
93 /// markdown and plaintext.
94 class Document {
95 public:
96  Document() = default;
97  Document(const Document &Other) { *this = Other; }
98  Document &operator=(const Document &);
99  Document(Document &&) = default;
100  Document &operator=(Document &&) = default;
101 
102  void append(Document Other);
103 
104  /// Adds a semantical block that will be separate from others.
106  /// Inserts a horizontal separator to the document.
107  void addRuler();
108  /// Adds a block of code. This translates to a ``` block in markdown. In plain
109  /// text representation, the code block will be surrounded by newlines.
110  void addCodeBlock(std::string Code, std::string Language = "cpp");
111  /// Heading is a special type of paragraph that will be prepended with \p
112  /// Level many '#'s in markdown.
113  Paragraph &addHeading(size_t Level);
114 
116 
117  /// Doesn't contain any trailing newlines.
118  /// We try to make the markdown human-readable, e.g. avoid extra escaping.
119  /// At least one client (coc.nvim) displays the markdown verbatim!
120  std::string asMarkdown() const;
121  /// Doesn't contain any trailing newlines.
122  std::string asPlainText() const;
123 
124 private:
125  std::vector<std::unique_ptr<Block>> Children;
126 };
127 } // namespace markup
128 } // namespace clangd
129 } // namespace clang
130 
131 #endif
clang::clangd::markup::Document::asPlainText
std::string asPlainText() const
Doesn't contain any trailing newlines.
Definition: Markup.cpp:488
clang::clangd::markup::BulletList
Represents a sequence of one or more documents.
Definition: Markup.h:80
clang::clangd::MarkupKind::PlainText
@ PlainText
clang::clangd::markup::Block::~Block
virtual ~Block()=default
clang::clangd::markup::Paragraph
Represents parts of the markup that can contain strings, like inline code, code block or plain text.
Definition: Markup.h:43
clang::clangd::markup::BulletList::clone
std::unique_ptr< Block > clone() const override
Definition: Markup.cpp:451
clang::clangd::markup::Block::renderMarkdown
virtual void renderMarkdown(llvm::raw_ostream &OS) const =0
clang::clangd::markup::Paragraph::appendText
Paragraph & appendText(llvm::StringRef Text)
Append plain text to the end of the string.
Definition: Markup.cpp:422
Kind
BindArgumentKind Kind
Definition: AvoidBindCheck.cpp:59
clang::clangd::markup::Document::addCodeBlock
void addCodeBlock(std::string Code, std::string Language="cpp")
Adds a block of code.
Definition: Markup.cpp:479
clang::clangd::markup::Block
Holds text and knows how to lay it out.
Definition: Markup.h:28
clang::clangd::markup::Document::addParagraph
Paragraph & addParagraph()
Adds a semantical block that will be separate from others.
Definition: Markup.cpp:472
Text
std::string Text
Definition: HTMLGenerator.cpp:80
clang::clangd::markup::Document::Document
Document()=default
clang::clangd::markup::Document::Document
Document(const Document &Other)
Definition: Markup.h:97
clang::clangd::markup::Document
A format-agnostic representation for structured text.
Definition: Markup.h:94
clang::clangd::markup::Document::addBulletList
BulletList & addBulletList()
Definition: Markup.cpp:492
clang::clangd::markup::Document::addRuler
void addRuler()
Inserts a horizontal separator to the document.
Definition: Markup.cpp:477
clang::clangd::markup::BulletList::renderMarkdown
void renderMarkdown(llvm::raw_ostream &OS) const override
Definition: Markup.cpp:398
clang::clangd::markup::Block::asMarkdown
std::string asMarkdown() const
Definition: Markup.cpp:332
clang::clangd::markup::Document::asMarkdown
std::string asMarkdown() const
Doesn't contain any trailing newlines.
Definition: Markup.cpp:484
clang::clangd::markup::Paragraph::appendSpace
Paragraph & appendSpace()
Ensure there is space between the surrounding chunks.
Definition: Markup.cpp:416
clang::clangd::markup::Paragraph::renderMarkdown
void renderMarkdown(llvm::raw_ostream &OS) const override
Definition: Markup.cpp:346
Code
std::string Code
Definition: FindTargetTests.cpp:67
clang::clangd::markup::Document::addHeading
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:497
clang::clangd::markup::BulletList::renderPlainText
void renderPlainText(llvm::raw_ostream &OS) const override
Definition: Markup.cpp:408
clang::clangd::markup::Document::append
void append(Document Other)
Definition: Markup.cpp:467
clang::clangd::markup::Document::operator=
Document & operator=(const Document &)
Definition: Markup.cpp:460
clang::clangd::markup::Paragraph::appendCode
Paragraph & appendCode(llvm::StringRef Code, bool Preserve=false)
Append inline code, this translates to the ` block in markdown.
Definition: Markup.cpp:435
clang::clangd::markup::Block::asPlainText
std::string asPlainText() const
Definition: Markup.cpp:339
clang::clangd::markup::Block::isRuler
virtual bool isRuler() const
Definition: Markup.h:36
clang::clangd::markup::Paragraph::clone
std::unique_ptr< Block > clone() const override
Definition: Markup.cpp:369
clang::clangd::markup::Block::renderPlainText
virtual void renderPlainText(llvm::raw_ostream &OS) const =0
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
OS
llvm::raw_string_ostream OS
Definition: TraceTests.cpp:163
clang::clangd::markup::Block::clone
virtual std::unique_ptr< Block > clone() const =0
clang::clangd::markup::BulletList::addItem
class Document & addItem()
Definition: Markup.cpp:455
clang::clangd::markup::Paragraph::renderPlainText
void renderPlainText(llvm::raw_ostream &OS) const override
Definition: Markup.cpp:384