From 8275950801dd2637e2239cc16f69058760a6f157 Mon Sep 17 00:00:00 2001 From: Dan Allen Date: Wed, 26 Aug 2020 00:14:08 -0600 Subject: [PATCH] resolves #264 add line highlighting option - add line highlighting option to HTMLLinewise formatter - add dedicated formatter to add line highlighting (only marks highlighted lines) --- README.md | 5 ++++ lib/rouge.rb | 1 + lib/rouge/formatters/html_line_highlighter.rb | 26 +++++++++++++++++ spec/formatters/html_line_highlighter_spec.rb | 28 +++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 lib/rouge/formatters/html_line_highlighter.rb create mode 100644 spec/formatters/html_line_highlighter_spec.rb diff --git a/README.md b/README.md index ff493afba6..5e719063e4 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,11 @@ The built-in formatters are: your code into lines, each contained in its own div. The `class` option will be used to add a class name to the div, given the line number. +* `Rouge::Formatters::HTMLLineHighlighter.new(formatter, highlight_lines: [3, 5])` + will split your code into lines and wrap the lines specified by the + `highlight_lines` option in a span with a class name specified by the + `highlight_line_class` option (default: `hll`). + * `Rouge::Formatters::HTMLLineTable.new(formatter, opts={})` will output an HTML table containing numbered lines, each contained in its own table-row. Options are: diff --git a/lib/rouge.rb b/lib/rouge.rb index 6f43a16ecb..de016154ae 100644 --- a/lib/rouge.rb +++ b/lib/rouge.rb @@ -83,6 +83,7 @@ def load_lexers Rouge.load_file 'formatters/html_pygments' Rouge.load_file 'formatters/html_legacy' Rouge.load_file 'formatters/html_linewise' +Rouge.load_file 'formatters/html_line_highlighter' Rouge.load_file 'formatters/html_line_table' Rouge.load_file 'formatters/html_inline' Rouge.load_file 'formatters/terminal256' diff --git a/lib/rouge/formatters/html_line_highlighter.rb b/lib/rouge/formatters/html_line_highlighter.rb new file mode 100644 index 0000000000..f1cbee4558 --- /dev/null +++ b/lib/rouge/formatters/html_line_highlighter.rb @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Formatters + class HTMLLineHighlighter < Formatter + tag 'html_line_highlighter' + + def initialize(delegate, opts = {}) + @delegate = delegate + @highlight_line_class = opts.fetch(:highlight_line_class, 'hll') + @highlight_lines = opts[:highlight_lines] || [] + end + + def stream(tokens) + lineno = 0 + token_lines(tokens) do |tokens_in_line| + lineno += 1 + line = %(#{@delegate.format(tokens_in_line)}\n) + line = %(#{line}) if @highlight_lines.include? lineno + yield line + end + end + end + end +end diff --git a/spec/formatters/html_line_highlighter_spec.rb b/spec/formatters/html_line_highlighter_spec.rb new file mode 100644 index 0000000000..c4c0495039 --- /dev/null +++ b/spec/formatters/html_line_highlighter_spec.rb @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +describe Rouge::Formatters::HTMLLineHighlighter do + let(:subject) { Rouge::Formatters::HTMLLineHighlighter.new(formatter, options) } + let(:formatter) { Rouge::Formatters::HTML.new } + + let(:options) { {} } + let(:output) { subject.format(input_stream) } + + describe 'highlight lines' do + let(:input_stream) { [[Token['Text'], "foo\n"], [Token['Name'], "bar\n"]] } + let(:options) { { highlight_lines: [2] } } + + it 'should add highlight line class to lines specified by :highlight_lines option' do + assert { output == %(foo\nbar\n) } + end + end + + describe 'configure highlight line class' do + let(:input_stream) { [[Token['Text'], "foo\n"], [Token['Name'], "bar\n"]] } + let(:options) { { highlight_lines: [1, 2], highlight_line_class: 'hiline' } } + + it 'should add highlight line class to lines specified by :highlight_lines option' do + assert { output == %(foo\nbar\n) } + end + end +end