-
Notifications
You must be signed in to change notification settings - Fork 789
Description
Hello!
I was trying out a new Jekyll feature — Marking Specific Lines, implemented here — and encountered some strange behavior.
The issue can be reproduced by rendering the following (I'm using the Minima v3 theme).
{% highlight ruby linenos mark_lines="2" %}
def foo
puts 'foo'
end
{% endhighlight %}
{% highlight ruby linenos %}
def foo
puts 'foo'
end
{% endhighlight %}
And it should look something like the following:
I would expect the first block to present the same content as the second one. However, this doesn't happen due to what I believe is a bug in the HTML generation. Specifically, a newline is appended to the last processed line (after <span class="k">end</span>).
Generated HTML:
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="code"><pre><span class="k">def</span> <span class="nf">foo</span>
<span class="hll"> <span class="nb">puts</span> <span class="s1">'foo'</span>
</span><span class="k">end</span>
</pre></td></tr></tbody></table></code></pre></figure>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="code"><pre><span class="k">def</span> <span class="nf">foo</span>
<span class="nb">puts</span> <span class="s1">'foo'</span>
<span class="k">end</span>
</pre></td></tr></tbody></table></code></pre></figure>I think the root cause for this behavior is here, where the newline character is appended without checking whether the line is the last one being processed.
While I don’t usually code in Ruby — apologies if the implementation quality is lacking — the following rewrite of the stream function effectively fixes the issue on my setup:
def stream(tokens)
last_line = nil
token_lines(tokens).with_index(1) do |line_tokens, lineno|
if last_line
yield last_line + "\n"
end
line = @delegate.format(line_tokens)
line = %(<span class="#{@highlight_line_class}">#{line}</span>) if @highlight_lines.include?(lineno)
last_line = line
end
yield last_line if last_line
endResulting in the following generated HTML:
Correctly generated HTML
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="code"><pre><span class="k">def</span> <span class="nf">foo</span>
<span class="hll"> <span class="nb">puts</span> <span class="s1">'foo'</span></span>
<span class="k">end</span>
</pre></td></tr></tbody></table></code></pre></figure>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="code"><pre><span class="k">def</span> <span class="nf">foo</span>
<span class="nb">puts</span> <span class="s1">'foo'</span>
<span class="k">end</span>
</pre></td></tr></tbody></table></code></pre></figure>System:
- OS:
Linux 9fe7e33eef81 6.8.0-1020-raspi #24-Ubuntu SMP PREEMPT_DYNAMIC Sun Feb 23 08:39:32 UTC 2025 aarch64 GNU/Linux - Ruby version :
ruby 3.3.8 (2025-04-09 revision b200bad6cd) [aarch64-linux] - Rouge version :
Rouge 4.5.1
Let me know if I can provide any additional useful information.

