Allow marking specific highlighted lines via Liquid (#9138)
Merge pull request 9138
This commit is contained in:
parent
99cfe52cd8
commit
7558ecb1f7
|
@ -73,3 +73,6 @@ apiKey: '[a-f0-9]+'
|
||||||
|
|
||||||
# ignore long runs of a single character:
|
# ignore long runs of a single character:
|
||||||
\b([A-Za-z])\g{-1}{3,}\b
|
\b([A-Za-z])\g{-1}{3,}\b
|
||||||
|
|
||||||
|
# ignore inline code
|
||||||
|
`\w+`
|
||||||
|
|
|
@ -66,6 +66,25 @@ end
|
||||||
```
|
```
|
||||||
{% endraw %}
|
{% 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
|
### Stylesheets for syntax highlighting
|
||||||
|
|
||||||
In order for the highlighting to show up, you’ll need to include a highlighting
|
In order for the highlighting to show up, you’ll need to include a highlighting
|
||||||
|
|
|
@ -16,3 +16,30 @@ Feature: Syntax Highlighting
|
||||||
When I run jekyll build
|
When I run jekyll build
|
||||||
Then I should get a zero exit-status
|
Then I should get a zero exit-status
|
||||||
And I should see "<span class="nc">RewriteCond</span>" in "_site/index.html"
|
And I should see "<span class="nc">RewriteCond</span>" 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 "<span class=\"hll\"><span class=\"k\">module</span> <span class=\"nn\">Jekyll</span>" in "_site/index.html"
|
||||||
|
And I should see "<span class=\"hll\"> <span class=\"k\">module</span> <span class=\"nn\">Tags</span>" in "_site/index.html"
|
||||||
|
And I should see "<span class=\"k\">class</span> <span class=\"nc\">HighlightBlock</span" in "_site/index.html"
|
||||||
|
|
||||||
|
Scenario: marking a single line in a Ruby code block with invalid syntax
|
||||||
|
Given I have an "index.html" page with content:
|
||||||
|
"""
|
||||||
|
{% highlight ruby mark_lines=1 %}
|
||||||
|
module Jekyll
|
||||||
|
module Tags
|
||||||
|
class HighlightBlock < Liquid::Block
|
||||||
|
{% endhighlight %}
|
||||||
|
"""
|
||||||
|
When I run jekyll build
|
||||||
|
Then I should see "Liquid Exception: Syntax Error" in the build output
|
||||||
|
|
|
@ -23,7 +23,9 @@ module Jekyll
|
||||||
|
|
||||||
#{markup}
|
#{markup}
|
||||||
|
|
||||||
Valid syntax: highlight <lang> [linenos]
|
Valid syntax: highlight <lang> [linenos] [mark_lines="3 4 5"]
|
||||||
|
|
||||||
|
See https://jekyllrb.com/docs/liquid/tags/#code-snippet-highlighting for more details.
|
||||||
MSG
|
MSG
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -81,20 +83,39 @@ module Jekyll
|
||||||
def render_rouge(code)
|
def render_rouge(code)
|
||||||
require "rouge"
|
require "rouge"
|
||||||
formatter = ::Rouge::Formatters::HTML.new
|
formatter = ::Rouge::Formatters::HTML.new
|
||||||
if @highlight_options[:linenos]
|
formatter = line_highlighter_formatter(formatter) if @highlight_options[:mark_lines]
|
||||||
formatter = ::Rouge::Formatters::HTMLTable.new(
|
formatter = table_formatter(formatter) if @highlight_options[:linenos]
|
||||||
formatter,
|
|
||||||
{
|
|
||||||
:css_class => "highlight",
|
|
||||||
:gutter_class => "gutter",
|
|
||||||
:code_class => "code",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
end
|
|
||||||
lexer = ::Rouge::Lexer.find_fancy(@lang, code) || Rouge::Lexers::PlainText
|
lexer = ::Rouge::Lexer.find_fancy(@lang, code) || Rouge::Lexers::PlainText
|
||||||
formatter.format(lexer.lex(code))
|
formatter.format(lexer.lex(code))
|
||||||
end
|
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)
|
def render_codehighlighter(code)
|
||||||
h(code).strip
|
h(code).strip
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue