Skip to content
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

Handle Guesser::Ambiguous during markdown processing #1349

Merged
merged 1 commit into from Oct 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions lib/rouge/lexer.rb
Expand Up @@ -49,6 +49,9 @@ def find(name)
#
# Lexer.find_fancy('guess', "#!/bin/bash\necho Hello, world")
#
# If the code matches more than one lexer then Guesser::Ambiguous
# is raised.
#
# This is used in the Redcarpet plugin as well as Rouge's own
# markdown lexer for highlighting internal code blocks.
#
Expand Down
8 changes: 7 additions & 1 deletion lib/rouge/lexers/markdown.rb
Expand Up @@ -34,7 +34,13 @@ def html

rule %r/^([ \t]*)(```|~~~)([^\n]*\n)((.*?)(\2))?/m do |m|
name = m[3].strip
sublexer = Lexer.find_fancy(name.empty? ? "guess" : name, m[5], @options)
sublexer =
begin
Lexer.find_fancy(name.empty? ? "guess" : name, m[5], @options)
rescue Guesser::Ambiguous => e
e.alternatives.first.new(@options)
end

sublexer ||= PlainText.new(@options.merge(:token => Str::Backtick))
sublexer.reset!

Expand Down
8 changes: 7 additions & 1 deletion lib/rouge/plugins/redcarpet.rb
Expand Up @@ -9,7 +9,13 @@ module Rouge
module Plugins
module Redcarpet
def block_code(code, language)
lexer = Lexer.find_fancy(language, code) || Lexers::PlainText
lexer =
begin
Lexer.find_fancy(language, code)
rescue Guesser::Ambiguous => e
e.alternatives.first
end
lexer ||= Lexers::PlainText

# XXX HACK: Redcarpet strips hard tabs out of code blocks,
# so we assume you're not using leading spaces that aren't tabs,
Expand Down
8 changes: 8 additions & 0 deletions spec/lexers/markdown_spec.rb
Expand Up @@ -39,6 +39,14 @@
assert_has_token("Comment.Single","```\n#!/usr/bin/env ruby\n```\n")
end

it 'picks a sub-lexer when the code-block-content is ambiguous' do
source = "Index: ): Awaitable<\n"
assert_raises Rouge::Guesser::Ambiguous do
Rouge::Lexer.find_fancy(nil, source)
end
assert_no_errors "```\n#{source}```\n"
end

it 'recognizes backticks instead of code block if inside string' do
assert_has_token("Literal.String.Backtick","\nx```ruby\nfoo\n```\n")
deny_has_token("Name.Label","\nx```ruby\nfoo\n```\n")
Expand Down
10 changes: 10 additions & 0 deletions spec/plugins/redcarpet_spec.rb
Expand Up @@ -42,6 +42,16 @@
assert { result.include?(%(<pre class="highlight ruby"><code>)) }
end

it 'chooses when a guess is ambiguous' do
result = markdown.render <<-mkd
``` guess
Index: ): Awaitable<
```
mkd

assert { result.include?(%(<pre class="highlight)) }
end

it 'passes options' do
result = markdown.render <<-mkd
``` shell?k=v
Expand Down