From 7558ecb1f7c4d5c078783f39befdbe544b5cfece Mon Sep 17 00:00:00 2001 From: Olly Headey Date: Thu, 3 Nov 2022 14:40:54 +0000 Subject: [PATCH] Allow marking specific highlighted lines via Liquid (#9138) Merge pull request 9138 --- .github/actions/spelling/patterns.txt | 3 ++ docs/_docs/liquid/tags.md | 19 ++++++++++++ features/highlighting.feature | 27 +++++++++++++++++ lib/jekyll/tags/highlight.rb | 43 ++++++++++++++++++++------- 4 files changed, 81 insertions(+), 11 deletions(-) diff --git a/.github/actions/spelling/patterns.txt b/.github/actions/spelling/patterns.txt index 341825df..91e276a4 100644 --- a/.github/actions/spelling/patterns.txt +++ b/.github/actions/spelling/patterns.txt @@ -73,3 +73,6 @@ apiKey: '[a-f0-9]+' # ignore long runs of a single character: \b([A-Za-z])\g{-1}{3,}\b + +# ignore inline code +`\w+` diff --git a/docs/_docs/liquid/tags.md b/docs/_docs/liquid/tags.md index 0e134fe5..ebc7a815 100644 --- a/docs/_docs/liquid/tags.md +++ b/docs/_docs/liquid/tags.md @@ -66,6 +66,25 @@ end ``` {% endraw %} +### Marking specific lines + +You can mark specific lines in a code snippet by using the optional +argument `mark_lines`. This argument takes a space-separated list of +line numbers which must be wrapped in double quotes. For example, the +following code block will mark lines 1 and 2 but not line 3: + +{% raw %} +```liquid +{% highlight ruby mark_lines="1 2" %} +def foo + puts 'foo' +end +{% endhighlight %} +``` +{% endraw %} + +A default class name of `hll` will be applied to the marked lines. + ### Stylesheets for syntax highlighting In order for the highlighting to show up, you’ll need to include a highlighting diff --git a/features/highlighting.feature b/features/highlighting.feature index 9a547b53..28d168c0 100644 --- a/features/highlighting.feature +++ b/features/highlighting.feature @@ -16,3 +16,30 @@ Feature: Syntax Highlighting When I run jekyll build Then I should get a zero exit-status And I should see "RewriteCond" in "_site/index.html" + + Scenario: marking lines 1 and 2 in a Ruby code block with valid syntax + Given I have an "index.html" page with content: + """ + {% highlight ruby mark_lines="1 2" %} + module Jekyll + module Tags + class HighlightBlock < Liquid::Block + {% endhighlight %} + """ + When I run jekyll build + Then I should get a zero exit-status + And I should see "module Jekyll" in "_site/index.html" + And I should see " module Tags" in "_site/index.html" + And I should see "class HighlightBlock [linenos] + Valid syntax: highlight [linenos] [mark_lines="3 4 5"] + + See https://jekyllrb.com/docs/liquid/tags/#code-snippet-highlighting for more details. MSG end end @@ -81,20 +83,39 @@ module Jekyll def render_rouge(code) require "rouge" formatter = ::Rouge::Formatters::HTML.new - if @highlight_options[:linenos] - formatter = ::Rouge::Formatters::HTMLTable.new( - formatter, - { - :css_class => "highlight", - :gutter_class => "gutter", - :code_class => "code", - } - ) - end + formatter = line_highlighter_formatter(formatter) if @highlight_options[:mark_lines] + formatter = table_formatter(formatter) if @highlight_options[:linenos] + lexer = ::Rouge::Lexer.find_fancy(@lang, code) || Rouge::Lexers::PlainText formatter.format(lexer.lex(code)) end + def line_highlighter_formatter(formatter) + ::Rouge::Formatters::HTMLLineHighlighter.new( + formatter, + :highlight_lines => mark_lines + ) + end + + def mark_lines + value = @highlight_options[:mark_lines] + return value.map(&:to_i) if value.is_a?(Array) + + raise SyntaxError, "Syntax Error for mark_lines declaration. Expected a " \ + "double-quoted list of integers." + end + + def table_formatter(formatter) + ::Rouge::Formatters::HTMLTable.new( + formatter, + { + :css_class => "highlight", + :gutter_class => "gutter", + :code_class => "code", + } + ) + end + def render_codehighlighter(code) h(code).strip end