mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 15:17:36 +00:00
LibMarkdown: Support multi-line list items
You can now continue one list item across several lines, as long as you indent it the same as the first line of the item. For example: * This is the first item, which spans multiple lines. * This is the second item, which also has some *emphasis* in it.
This commit is contained in:
parent
d4bfcea570
commit
183fa98214
1 changed files with 40 additions and 12 deletions
|
@ -69,6 +69,20 @@ String List::render_for_terminal() const
|
||||||
bool List::parse(Vector<StringView>::ConstIterator& lines)
|
bool List::parse(Vector<StringView>::ConstIterator& lines)
|
||||||
{
|
{
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
size_t offset = 0;
|
||||||
|
StringBuilder item_builder;
|
||||||
|
auto flush_item_if_needed = [&] {
|
||||||
|
if (first)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Text text;
|
||||||
|
bool success = text.parse(item_builder.string_view());
|
||||||
|
ASSERT(success);
|
||||||
|
m_items.append(move(text));
|
||||||
|
|
||||||
|
item_builder.clear();
|
||||||
|
};
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (lines.is_end())
|
if (lines.is_end())
|
||||||
break;
|
break;
|
||||||
|
@ -77,12 +91,12 @@ bool List::parse(Vector<StringView>::ConstIterator& lines)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
bool appears_unordered = false;
|
bool appears_unordered = false;
|
||||||
size_t offset = 0;
|
if (line.length() > 2) {
|
||||||
if (line.length() > 2)
|
|
||||||
if (line[1] == ' ' && (line[0] == '*' || line[0] == '-')) {
|
if (line[1] == ' ' && (line[0] == '*' || line[0] == '-')) {
|
||||||
appears_unordered = true;
|
appears_unordered = true;
|
||||||
offset = 2;
|
offset = 2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool appears_ordered = false;
|
bool appears_ordered = false;
|
||||||
for (size_t i = 0; i < 10 && i < line.length(); i++) {
|
for (size_t i = 0; i < 10 && i < line.length(); i++) {
|
||||||
|
@ -98,21 +112,35 @@ bool List::parse(Vector<StringView>::ConstIterator& lines)
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(!(appears_unordered && appears_ordered));
|
ASSERT(!(appears_unordered && appears_ordered));
|
||||||
if (!appears_unordered && !appears_ordered)
|
|
||||||
return false;
|
if (appears_unordered || appears_ordered) {
|
||||||
if (first)
|
if (first)
|
||||||
m_is_ordered = appears_ordered;
|
m_is_ordered = appears_ordered;
|
||||||
else if (m_is_ordered != appears_ordered)
|
else if (m_is_ordered != appears_ordered)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
flush_item_if_needed();
|
||||||
|
|
||||||
|
while (offset + 1 < line.length() && line[offset + 1] == ' ')
|
||||||
|
offset++;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (first)
|
||||||
|
return false;
|
||||||
|
for (size_t i = 0; i < offset; i++) {
|
||||||
|
if (line[i] != ' ')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
first = false;
|
first = false;
|
||||||
Text text;
|
if (!item_builder.is_empty())
|
||||||
bool success = text.parse(line.substring_view(offset, line.length() - offset));
|
item_builder.append(' ');
|
||||||
ASSERT(success);
|
item_builder.append(line.substring_view(offset, line.length() - offset));
|
||||||
m_items.append(move(text));
|
|
||||||
++lines;
|
++lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flush_item_if_needed();
|
||||||
return !first;
|
return !first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue