forked from OSchip/llvm-project
132 lines
4.4 KiB
C++
132 lines
4.4 KiB
C++
//===--- Markup.h -------------------------------------------*- C++-*------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// A model of formatted text that can be rendered to plaintext or markdown.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_MARKUP_H
|
|
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_MARKUP_H
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include <cstddef>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace clang {
|
|
namespace clangd {
|
|
namespace markup {
|
|
|
|
/// Holds text and knows how to lay it out. Multiple blocks can be grouped to
|
|
/// form a document. Blocks include their own trailing newlines, container
|
|
/// should trim them if need be.
|
|
class Block {
|
|
public:
|
|
virtual void renderMarkdown(llvm::raw_ostream &OS) const = 0;
|
|
virtual void renderPlainText(llvm::raw_ostream &OS) const = 0;
|
|
virtual std::unique_ptr<Block> clone() const = 0;
|
|
std::string asMarkdown() const;
|
|
std::string asPlainText() const;
|
|
|
|
virtual bool isRuler() const { return false; }
|
|
virtual ~Block() = default;
|
|
};
|
|
|
|
/// Represents parts of the markup that can contain strings, like inline code,
|
|
/// code block or plain text.
|
|
/// One must introduce different paragraphs to create separate blocks.
|
|
class Paragraph : public Block {
|
|
public:
|
|
void renderMarkdown(llvm::raw_ostream &OS) const override;
|
|
void renderPlainText(llvm::raw_ostream &OS) const override;
|
|
std::unique_ptr<Block> clone() const override;
|
|
|
|
/// Append plain text to the end of the string.
|
|
Paragraph &appendText(llvm::StringRef Text);
|
|
|
|
/// Append inline code, this translates to the ` block in markdown.
|
|
/// \p Preserve indicates the code span must be apparent even in plaintext.
|
|
Paragraph &appendCode(llvm::StringRef Code, bool Preserve = false);
|
|
|
|
/// Ensure there is space between the surrounding chunks.
|
|
/// Has no effect at the beginning or end of a paragraph.
|
|
Paragraph &appendSpace();
|
|
|
|
private:
|
|
struct Chunk {
|
|
enum {
|
|
PlainText,
|
|
InlineCode,
|
|
} Kind = PlainText;
|
|
// Preserve chunk markers in plaintext.
|
|
bool Preserve = false;
|
|
std::string Contents;
|
|
// Whether this chunk should be surrounded by whitespace.
|
|
// Consecutive SpaceAfter and SpaceBefore will be collapsed into one space.
|
|
// Code spans don't usually set this: their spaces belong "inside" the span.
|
|
bool SpaceBefore = false;
|
|
bool SpaceAfter = false;
|
|
};
|
|
std::vector<Chunk> Chunks;
|
|
};
|
|
|
|
/// Represents a sequence of one or more documents. Knows how to print them in a
|
|
/// list like format, e.g. by prepending with "- " and indentation.
|
|
class BulletList : public Block {
|
|
public:
|
|
void renderMarkdown(llvm::raw_ostream &OS) const override;
|
|
void renderPlainText(llvm::raw_ostream &OS) const override;
|
|
std::unique_ptr<Block> clone() const override;
|
|
|
|
class Document &addItem();
|
|
|
|
private:
|
|
std::vector<class Document> Items;
|
|
};
|
|
|
|
/// A format-agnostic representation for structured text. Allows rendering into
|
|
/// markdown and plaintext.
|
|
class Document {
|
|
public:
|
|
Document() = default;
|
|
Document(const Document &Other) { *this = Other; }
|
|
Document &operator=(const Document &);
|
|
Document(Document &&) = default;
|
|
Document &operator=(Document &&) = default;
|
|
|
|
void append(Document Other);
|
|
|
|
/// Adds a semantical block that will be separate from others.
|
|
Paragraph &addParagraph();
|
|
/// Inserts a horizontal separator to the document.
|
|
void addRuler();
|
|
/// Adds a block of code. This translates to a ``` block in markdown. In plain
|
|
/// text representation, the code block will be surrounded by newlines.
|
|
void addCodeBlock(std::string Code, std::string Language = "cpp");
|
|
/// Heading is a special type of paragraph that will be prepended with \p
|
|
/// Level many '#'s in markdown.
|
|
Paragraph &addHeading(size_t Level);
|
|
|
|
BulletList &addBulletList();
|
|
|
|
/// Doesn't contain any trailing newlines.
|
|
/// We try to make the markdown human-readable, e.g. avoid extra escaping.
|
|
/// At least one client (coc.nvim) displays the markdown verbatim!
|
|
std::string asMarkdown() const;
|
|
/// Doesn't contain any trailing newlines.
|
|
std::string asPlainText() const;
|
|
|
|
private:
|
|
std::vector<std::unique_ptr<Block>> Children;
|
|
};
|
|
} // namespace markup
|
|
} // namespace clangd
|
|
} // namespace clang
|
|
|
|
#endif
|