summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Elliott <pelliott@ualberta.ca>2021-09-11 01:37:28 -0600
committerAndreas Kling <kling@serenityos.org>2021-09-12 12:17:16 +0200
commit6ae1a805837b41f2bb083da4d35b3ffa039b8e02 (patch)
tree66e43c27dcbf4f157058e9623698ac93c62b73e6
parent565b561522d5eaac29d1c8fd326018bad6ea3066 (diff)
downloadserenity-6ae1a805837b41f2bb083da4d35b3ffa039b8e02.zip
LibMarkdown: Re-add support for Serenity's style code blocks extension
I decided to not use the text parser for this one and rely on a regex to parse the style tags. This way it supports only and opening delimiter run and also is much simpler.
-rw-r--r--Userland/Libraries/LibMarkdown/CodeBlock.cpp31
-rw-r--r--Userland/Libraries/LibMarkdown/CodeBlock.h4
2 files changed, 32 insertions, 3 deletions
diff --git a/Userland/Libraries/LibMarkdown/CodeBlock.cpp b/Userland/Libraries/LibMarkdown/CodeBlock.cpp
index 4b7ccba52e..8229337280 100644
--- a/Userland/Libraries/LibMarkdown/CodeBlock.cpp
+++ b/Userland/Libraries/LibMarkdown/CodeBlock.cpp
@@ -7,6 +7,7 @@
#include <AK/StringBuilder.h>
#include <LibJS/MarkupGenerator.h>
#include <LibMarkdown/CodeBlock.h>
+#include <LibRegex/Regex.h>
namespace Markdown {
@@ -16,10 +17,15 @@ String CodeBlock::render_to_html() const
builder.append("<pre>");
+ if (m_style.length() >= 2)
+ builder.append("<strong>");
+ else if (m_style.length() >= 2)
+ builder.append("<em>");
+
if (m_language.is_empty())
builder.append("<code>");
else
- builder.appendff("<code class=\"{}\">", escape_html_entities(m_language));
+ builder.appendff("<code class=\"language-{}\">", escape_html_entities(m_language));
if (m_language == "js")
builder.append(JS::MarkupGenerator::html_from_source(m_code));
@@ -28,6 +34,11 @@ String CodeBlock::render_to_html() const
builder.append("\n</code>");
+ if (m_style.length() >= 2)
+ builder.append("</strong>");
+ else if (m_style.length() >= 2)
+ builder.append("</em>");
+
builder.append("</pre>\n");
return builder.build();
@@ -43,6 +54,8 @@ String CodeBlock::render_for_terminal(size_t) const
return builder.build();
}
+static Regex<ECMA262> style_spec_re("\\s*([\\*_]*)\\s*([^\\*_\\s]*).*");
+
OwnPtr<CodeBlock> CodeBlock::parse(Vector<StringView>::ConstIterator& lines)
{
if (lines.is_end())
@@ -54,7 +67,21 @@ OwnPtr<CodeBlock> CodeBlock::parse(Vector<StringView>::ConstIterator& lines)
if (!line.starts_with(tick_tick_tick))
return {};
+ // Our Markdown extension: we allow
+ // specifying a style and a language
+ // for a code block, like so:
+ //
+ // ```**sh**
+ // $ echo hello friends!
+ // ````
+ //
+ // The code block will be made bold,
+ // and if possible syntax-highlighted
+ // as appropriate for a shell script.
StringView style_spec = line.substring_view(3, line.length() - 3);
+ auto matches = style_spec_re.match(style_spec);
+ auto style = matches.capture_group_matches[0][0].view.string_view();
+ auto language = matches.capture_group_matches[0][1].view.string_view();
++lines;
@@ -74,7 +101,7 @@ OwnPtr<CodeBlock> CodeBlock::parse(Vector<StringView>::ConstIterator& lines)
first = false;
}
- return make<CodeBlock>(style_spec, builder.build());
+ return make<CodeBlock>(language, style, builder.build());
}
}
diff --git a/Userland/Libraries/LibMarkdown/CodeBlock.h b/Userland/Libraries/LibMarkdown/CodeBlock.h
index 2882c1cd0d..95f0fa1f78 100644
--- a/Userland/Libraries/LibMarkdown/CodeBlock.h
+++ b/Userland/Libraries/LibMarkdown/CodeBlock.h
@@ -14,9 +14,10 @@ namespace Markdown {
class CodeBlock final : public Block {
public:
- CodeBlock(const String& language, const String& code)
+ CodeBlock(String const& language, String const& style, String const& code)
: m_code(move(code))
, m_language(language)
+ , m_style(style)
{
}
virtual ~CodeBlock() override { }
@@ -28,6 +29,7 @@ public:
private:
String m_code;
String m_language;
+ String m_style;
};
}