mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 01:27:43 +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) 2022, Peter Elliott <pelliott@serenityos.org>
|
||||
*
|
||||
* 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 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)
|
||||
{
|
||||
if (lines.is_end())
|
||||
return {};
|
||||
|
||||
constexpr auto tick_tick_tick = "```";
|
||||
|
||||
StringView line = *lines;
|
||||
if (!line.starts_with(tick_tick_tick))
|
||||
return {};
|
||||
if (line.starts_with(tick_tick_tick))
|
||||
return parse_backticks(lines);
|
||||
|
||||
if (line_block_prefix(line).has_value())
|
||||
return parse_indent(lines);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
OwnPtr<CodeBlock> CodeBlock::parse_backticks(LineIterator& lines)
|
||||
{
|
||||
StringView line = *lines;
|
||||
|
||||
// Our Markdown extension: we allow
|
||||
// specifying a style and a language
|
||||
|
@ -124,4 +161,29 @@ OwnPtr<CodeBlock> CodeBlock::parse(LineIterator& lines)
|
|||
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());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue