New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expose unwrapped Rouge HTML formatter #4472
base: main
Are you sure you want to change the base?
Expose unwrapped Rouge HTML formatter #4472
Conversation
This exposes the Rouge HTML formatter prior to any extension wrapping in order to allow further customizations when overriding the `Asciidoctor::SyntaxHighlighter::RougeAdapter` class. Prior to these changes, executing for example this code: ```ruby class ExtendedRougeSyntaxHighlighter < (Asciidoctor::SyntaxHighlighter.for 'rouge') register_for 'rouge' def create_formatter node, source, lang, opts formatter = super formatter.singleton_class.prepend (Module.new do def safe_span tok, safe_val if tok.token_chain[0].matches? ::Rouge::Token::Tokens::Comment safe_val = safe_val.gsub(/https?:\/\/\S+/, '<a href="\&">\&</a>') end super end end) formatter end end ``` Could potentially cause to override classes that do not implement `safe_span()`, for example `RougeExt::Formatters::HTMLTableLineNumberer` as we expect `Rouge::Formatters::HTML` instead. Those other classes (`RougeExt::Formatters::*`) may be useful for extensions to keep enabled but currently need to be disabled as they are shadowing `Rouge::Formatters::HTML`.
I'm open to introducing another method that creates the base HTML formatter. However, in order to proceed, I would need to see the following changes:
|
Thank you for the review @mojavelinux! I want to add three test cases:
I was looking into those for this pull request following your request, but I'm not quite sure how to proceed. As an illustration, attached is an example test case and what it could look like: diff --git a/test/syntax_highlighter_test.rb b/test/syntax_highlighter_test.rb
index 7a6fd2f2..e9f7a7df 100644
--- a/test/syntax_highlighter_test.rb
+++ b/test/syntax_highlighter_test.rb
@@ -1147,6 +1147,42 @@ def highlight?
result = run_command(asciidoctor_cmd, '-r', (fixture_path 'include-asciidoctor.rb'), '-s', '-o', '-', '-a', 'source-highlighter=rouge', (fixture_path 'source-block.adoc'), use_bundler: true) {|out| out.read }
assert_xpath '//pre[@class="rouge highlight"]', result, 1
end
+
+ test 'should invoke overridden safe_span when linenums option is enabled' do
+ begin
+ # (Will need to move this outside the test so it can be reused for different test cases)
+ Class.new Asciidoctor::SyntaxHighlighter.for 'rouge' do
+ register_for 'rouge'
+ def create_base_formatter node, source, lang, opts
+ formatter = super
+ raise "Formatter doesn't have method 'safe_span'" unless formatter.respond_to?(:safe_span)
+ formatter.singleton_class.prepend (Module.new do
+ def safe_span tok, safe_val
+ if tok.token_chain[0].matches? ::Rouge::Token::Tokens::Comment
+ safe_val = safe_val.gsub(/https?:\/\/\S+/, '<a href="\&">\&</a>')
+ end
+ super
+ end
+ end)
+ formatter
+ end
+ end
+
+ input = <<~'EOS'
+ [source,ruby]
+ ----
+ puts 'Hello, World!' # https://example.com
+ ----
+ EOS
+
+ doc = document_from_string input, attributes: { 'source-highlighter' => 'rouge' }
+ output = doc.convert
+ assert_include '# <a href="https://example.com">https://example.com</a>', output
+ end
+ ensure
+ # Here we should unregister the class
+ # [...]
+ end
end
context 'Pygments', if: ENV['PYGMENTS_VERSION'] do First problem: to be able to test extensions against I considered adding new methods, such as Other solution would be to allow to unregister by class object (e.g. Another way could have been to use directly Easiest way would probably be to put the tested class into a ruby file, and start a child process so we do not need to unregister anything, e.g., Second problem: the class from autolink-urls-in-comments.rb seems like a good fit for testing the proper behaviors against I would think it could be a good idea instead of adding the tests into Thank you in advance for your inputs! |
This exposes the Rouge HTML formatter prior to any extension wrapping in order to allow further customizations when overriding the
Asciidoctor::SyntaxHighlighter::RougeAdapter
class.This is a similar fix to an older issue reported at #3953.
Prior to these changes, executing for example this code (autolink-urls-in-comments.rb):
Could potentially cause to override classes that do not implement
safe_span()
, for exampleRougeExt::Formatters::HTMLTableLineNumberer
as we expectRouge::Formatters::HTML
instead.Those other classes (
RougeExt::Formatters::*
) may be useful for extensions to keep enabled but currently need to be disabled as they are shadowingRouge::Formatters::HTML
.The autolink-urls-in-comments.rb example would only work when not passing the attributes
%linenums
, andhighlight
:HTML Output (look for
<a
presence):HTML Output after the fix (this PR):