mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 00:07:36 +00:00
LibMarkdown: Add support for indented code blocks
This commit is contained in:
parent
dbb2347000
commit
0270e23997
2 changed files with 69 additions and 4 deletions
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
|
* Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
|
||||||
|
* Copyright (c) 2022, Peter Elliott <pelliott@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -76,16 +77,52 @@ RecursionDecision CodeBlock::walk(Visitor& visitor) const
|
||||||
|
|
||||||
static Regex<ECMA262> style_spec_re("\\s*([\\*_]*)\\s*([^\\*_\\s]*).*");
|
static Regex<ECMA262> style_spec_re("\\s*([\\*_]*)\\s*([^\\*_\\s]*).*");
|
||||||
|
|
||||||
|
static constexpr auto tick_tick_tick = "```";
|
||||||
|
|
||||||
|
static Optional<int> line_block_prefix(StringView const& line)
|
||||||
|
{
|
||||||
|
int characters = 0;
|
||||||
|
int indents = 0;
|
||||||
|
|
||||||
|
for (char ch : line) {
|
||||||
|
if (indents == 4)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (ch == ' ') {
|
||||||
|
++characters;
|
||||||
|
++indents;
|
||||||
|
} else if (ch == '\t') {
|
||||||
|
++characters;
|
||||||
|
indents = 4;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indents == 4)
|
||||||
|
return characters;
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
OwnPtr<CodeBlock> CodeBlock::parse(LineIterator& lines)
|
OwnPtr<CodeBlock> CodeBlock::parse(LineIterator& lines)
|
||||||
{
|
{
|
||||||
if (lines.is_end())
|
if (lines.is_end())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
constexpr auto tick_tick_tick = "```";
|
|
||||||
|
|
||||||
StringView line = *lines;
|
StringView line = *lines;
|
||||||
if (!line.starts_with(tick_tick_tick))
|
if (line.starts_with(tick_tick_tick))
|
||||||
|
return parse_backticks(lines);
|
||||||
|
|
||||||
|
if (line_block_prefix(line).has_value())
|
||||||
|
return parse_indent(lines);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
OwnPtr<CodeBlock> CodeBlock::parse_backticks(LineIterator& lines)
|
||||||
|
{
|
||||||
|
StringView line = *lines;
|
||||||
|
|
||||||
// Our Markdown extension: we allow
|
// Our Markdown extension: we allow
|
||||||
// specifying a style and a language
|
// specifying a style and a language
|
||||||
|
@ -124,4 +161,29 @@ OwnPtr<CodeBlock> CodeBlock::parse(LineIterator& lines)
|
||||||
return make<CodeBlock>(language, style, builder.build());
|
return make<CodeBlock>(language, style, builder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OwnPtr<CodeBlock> CodeBlock::parse_indent(LineIterator& lines)
|
||||||
|
{
|
||||||
|
bool first = true;
|
||||||
|
StringBuilder builder;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (lines.is_end())
|
||||||
|
break;
|
||||||
|
StringView line = *lines;
|
||||||
|
|
||||||
|
auto prefix_length = line_block_prefix(line);
|
||||||
|
if (!prefix_length.has_value())
|
||||||
|
break;
|
||||||
|
|
||||||
|
line = line.substring_view(prefix_length.value());
|
||||||
|
++lines;
|
||||||
|
|
||||||
|
if (!first)
|
||||||
|
builder.append('\n');
|
||||||
|
builder.append(line);
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return make<CodeBlock>("", "", builder.build());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,9 @@ private:
|
||||||
String m_code;
|
String m_code;
|
||||||
String m_language;
|
String m_language;
|
||||||
String m_style;
|
String m_style;
|
||||||
|
|
||||||
|
static OwnPtr<CodeBlock> parse_backticks(LineIterator& lines);
|
||||||
|
static OwnPtr<CodeBlock> parse_indent(LineIterator& lines);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue