def block_code(code, language)
if language.present? && Redmine::SyntaxHighlighting.language_supported?(language)
- "<pre><code class=\"#{CGI.escapeHTML language} syntaxhl\">" +
- Redmine::SyntaxHighlighting.highlight_by_language(code, language) +
- "</code></pre>"
+ html = Redmine::SyntaxHighlighting.highlight_by_language(code, language)
+ classattr = " class=\"#{CGI.escapeHTML language} syntaxhl\""
else
- "<pre>" + CGI.escapeHTML(code) + "</pre>"
+ html = CGI.escapeHTML(code)
end
+ # original language for extension development
+ langattr = " data-language=\"#{CGI.escapeHTML language}\"" if language.present?
+ "<pre><code#{classattr}#{langattr}>#{html}</code></pre>"
end
def image(link, title, alt_text)
if content.match(/<code\s+class=(?:"([^"]+)"|'([^']+)')>\s?(.*)/m)
language = $1 || $2
text = $3
+ # original language for extension development
+ langattr = " data-language=\"#{CGI.escapeHTML language}\"" if language.present?
if Redmine::SyntaxHighlighting.language_supported?(language)
text.gsub!(/x%x%/, '&')
- content = "<code class=\"#{language} syntaxhl\">" +
+ content = "<code class=\"#{CGI.escapeHTML language} syntaxhl\"#{langattr}>" +
Redmine::SyntaxHighlighting.highlight_by_language(text, language)
else
- content = "<code>#{ERB::Util.h(text)}"
+ content = "<code#{langattr}>#{ERB::Util.h(text)}"
end
end
content
</code></pre>
RAW
expected = <<~EXPECTED
- <pre><code class="ECMA_script syntaxhl"><span class="cm">/* Hello */</span><span class="nb">document</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="dl">"</span><span class="s2">Hello World!</span><span class="dl">"</span><span class="p">);</span></code></pre>
+ <pre><code class="ECMA_script syntaxhl" data-language=\"ECMA_script\"><span class="cm">/* Hello */</span><span class="nb">document</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="dl">"</span><span class="s2">Hello World!</span><span class="dl">"</span><span class="p">);</span></code></pre>
EXPECTED
assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
end
</code></pre>
RAW
expected = <<~EXPECTED
- <pre><code class=\"ruby syntaxhl\"><span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">a</span> <span class=\"o\">&</span> <span class=\"n\">b</span></code></pre>
+ <pre><code class=\"ruby syntaxhl\" data-language=\"ruby\"><span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">a</span> <span class=\"o\">&</span> <span class=\"n\">b</span></code></pre>
EXPECTED
with_settings :text_formatting => 'textile' do
assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
STR
assert_select_in @formatter.new(text).to_html, 'pre code.ruby.syntaxhl' do
assert_select 'span.k', :text => 'def'
+ assert_select "[data-language='ruby']"
end
end
test
~~~
STR
- assert_equal "<pre>test\n</pre>", @formatter.new(text).to_html
+ assert_equal "<pre><code data-language=\"foo\">test\n</code></pre>", @formatter.new(text).to_html
+ end
+
+ def test_should_preserve_code_block_language_in_data_language
+ text = <<~STR
+ ~~~c-k&r
+ test
+ ~~~
+ STR
+ assert_equal "<pre><code data-language=\"c-k&r\">test\n</code></pre>", @formatter.new(text).to_html
end
def test_external_links_should_have_external_css_class
end
def test_should_not_allow_arbitrary_class_attribute_on_offtags
- %w(code pre kbd).each do |tag|
- assert_html_output({"<#{tag} class=\"foo\">test</#{tag}>" => "<#{tag}>test</#{tag}>"}, false)
- assert_html_output({"<#{tag} class='foo'>test</#{tag}>" => "<#{tag}>test</#{tag}>"}, false)
- assert_html_output({"<#{tag} class=\"ruby foo\">test</#{tag}>" => "<#{tag}>test</#{tag}>"}, false)
- assert_html_output({"<#{tag} class='ruby foo'>test</#{tag}>" => "<#{tag}>test</#{tag}>"}, false)
- assert_html_output({"<#{tag} class=\"ruby \"foo\" bar\">test</#{tag}>" => "<#{tag}>test</#{tag}>"}, false)
+ {
+ "class=\"foo\"" => "data-language=\"foo\"",
+ "class='foo'" => "data-language=\"foo\"",
+ "class=\"ruby foo\"" => "data-language=\"ruby foo\"",
+ "class='ruby foo'" => "data-language=\"ruby foo\"",
+ "class=\"ruby \"foo\" bar\"" => "data-language=\"ruby \"",
+ }.each do |classattr, codeattr|
+ assert_html_output({"<code #{classattr}>test</code>" => "<code #{codeattr}>test</code>"}, false)
+ assert_html_output({"<pre #{classattr}>test</pre>" => "<pre>test</pre>"}, false)
+ assert_html_output({"<kbd #{classattr}>test</kbd>" => "<kbd>test</kbd>"}, false)
end
assert_html_output({"<notextile class=\"foo\">test</notextile>" => "test"}, false)
# language name is double-quoted
assert_html_output(
{"<code class=\"ruby\">test</code>" =>
- "<code class=\"ruby syntaxhl\"><span class=\"nb\">test</span></code>"},
+ "<code class=\"ruby syntaxhl\" data-language=\"ruby\"><span class=\"nb\">test</span></code>"},
false
)
# language name is single-quoted
assert_html_output(
{"<code class='ruby'>test</code>" =>
- "<code class=\"ruby syntaxhl\"><span class=\"nb\">test</span></code>"},
+ "<code class=\"ruby syntaxhl\" data-language=\"ruby\"><span class=\"nb\">test</span></code>"},
+ false
+ )
+ end
+
+ def test_should_preserve_code_language_class_attribute_in_data_language
+ assert_html_output(
+ {
+ "<code class=\"foolang\">unsupported language</code>" =>
+ "<code data-language=\"foolang\">unsupported language</code>",
+ "<code class=\"c-k&r\">special-char language</code>" =>
+ "<code data-language=\"c-k&r\">special-char language</code>",
+ },
false
)
end