Feature #32424 » 0005-CommonMark-unify-code-blocks-35104.patch
| lib/redmine/wiki_formatting/common_mark/sanitization_filter.rb | ||
|---|---|---|
| 44 | 44 |
node = env[:node] |
| 45 | 45 |
return unless node.name == "code" |
| 46 | 46 |
return unless node.has_attribute?("class")
|
| 47 |
unless node["class"] =~ /\Alanguage-(\w+)\z/
|
|
| 47 |
unless node["class"] =~ /\Alanguage-(\S+)\z/
|
|
| 48 | 48 |
node.remove_attribute("class")
|
| 49 | 49 |
end |
| 50 | 50 |
} |
| lib/redmine/wiki_formatting/common_mark/syntax_highlight_filter.rb | ||
|---|---|---|
| 28 | 28 |
def call |
| 29 | 29 |
doc.search("pre > code").each do |node|
|
| 30 | 30 |
next unless lang = node["class"].presence |
| 31 |
next unless lang =~ /\Alanguage-(\w+)\z/
|
|
| 31 |
next unless lang =~ /\Alanguage-(\S+)\z/
|
|
| 32 | 32 | |
| 33 | 33 |
lang = $1 |
| 34 | 34 |
text = node.inner_text |
| 35 | 35 | |
| 36 |
# original language for extension development |
|
| 37 |
node["data-language"] = lang unless node["data-language"] |
|
| 38 | ||
| 36 | 39 |
if Redmine::SyntaxHighlighting.language_supported?(lang) |
| 37 | 40 |
html = Redmine::SyntaxHighlighting.highlight_by_language(text, lang) |
| 38 | 41 |
next if html.nil? |
| 39 | 42 |
node.inner_html = html |
| 40 | 43 |
node["class"] = "#{lang} syntaxhl"
|
| 41 | 44 |
else |
| 42 |
# unsupported language, strip out the code tag |
|
| 43 |
node.parent.inner_html = text |
|
| 45 |
node.remove_attribute("class")
|
|
| 44 | 46 |
end |
| 45 | 47 |
end |
| 46 | 48 |
doc |
| test/unit/lib/redmine/wiki_formatting/common_mark/formatter_test.rb | ||
|---|---|---|
| 94 | 94 |
end |
| 95 | 95 | |
| 96 | 96 |
def test_should_support_syntax_highlight |
| 97 |
text = <<-STR
|
|
| 98 |
~~~ruby |
|
| 99 |
def foo |
|
| 100 |
end |
|
| 101 |
~~~ |
|
| 102 |
STR |
|
| 97 |
text = <<~STR
|
|
| 98 |
~~~ruby
|
|
| 99 |
def foo
|
|
| 100 |
end
|
|
| 101 |
~~~
|
|
| 102 |
STR
|
|
| 103 | 103 |
assert_select_in format(text), 'pre code.ruby.syntaxhl' do |
| 104 | 104 |
assert_select 'span.k', :text => 'def' |
| 105 |
assert_select "[data-language='ruby']" |
|
| 105 | 106 |
end |
| 106 | 107 |
end |
| 107 | 108 | |
| 108 | 109 |
def test_should_not_allow_invalid_language_for_code_blocks |
| 109 |
text = <<-STR |
|
| 110 |
~~~foo |
|
| 111 |
test |
|
| 112 |
~~~ |
|
| 113 |
STR |
|
| 114 |
assert_equal "<pre>test\n</pre>", format(text) |
|
| 110 |
text = <<~STR |
|
| 111 |
~~~foo |
|
| 112 |
test |
|
| 113 |
~~~ |
|
| 114 |
STR |
|
| 115 |
assert_equal "<pre><code data-language=\"foo\">test\n</code></pre>", format(text) |
|
| 116 |
end |
|
| 117 | ||
| 118 |
def test_should_preserve_code_block_language_in_data_language |
|
| 119 |
text = <<~STR |
|
| 120 |
~~~c-k&r |
|
| 121 |
test |
|
| 122 |
~~~ |
|
| 123 |
STR |
|
| 124 |
assert_equal "<pre><code data-language=\"c-k&r\">test\n</code></pre>", format(text) |
|
| 115 | 125 |
end |
| 116 | 126 | |
| 117 | 127 |
def test_external_links_should_have_external_css_class |
| ... | ... | |
| 125 | 135 |
end |
| 126 | 136 | |
| 127 | 137 |
def test_markdown_should_not_require_surrounded_empty_line |
| 128 |
text = <<-STR
|
|
| 129 |
This is a list: |
|
| 130 |
* One |
|
| 131 |
* Two |
|
| 132 |
STR |
|
| 138 |
text = <<~STR
|
|
| 139 |
This is a list:
|
|
| 140 |
* One
|
|
| 141 |
* Two
|
|
| 142 |
STR
|
|
| 133 | 143 |
assert_equal "<p>This is a list:</p>\n<ul>\n<li>One</li>\n<li>Two</li>\n</ul>", format(text) |
| 134 | 144 |
end |
| 135 | 145 | |
| 136 | 146 |
def test_footnotes |
| 137 |
text = <<-STR
|
|
| 138 |
This is some text[^1]. |
|
| 139 | ||
| 140 |
[^1]: This is the foot note |
|
| 141 |
STR |
|
| 142 | ||
| 143 |
expected = <<-EXPECTED
|
|
| 144 |
<p>This is some text<sup><a href="#fn1" id="fnref1">1</a></sup>.</p> |
|
| 145 |
<ol> |
|
| 146 |
<li id="fn1"> |
|
| 147 |
<p>This is the foot note <a href="#fnref1">↩</a></p> |
|
| 148 |
</li> |
|
| 149 |
</ol> |
|
| 150 |
EXPECTED |
|
| 147 |
text = <<~STR
|
|
| 148 |
This is some text[^1].
|
|
| 149 | ||
| 150 |
[^1]: This is the foot note
|
|
| 151 |
STR
|
|
| 152 | ||
| 153 |
expected = <<~EXPECTED
|
|
| 154 |
<p>This is some text<sup><a href="#fn1" id="fnref1">1</a></sup>.</p>
|
|
| 155 |
<ol>
|
|
| 156 |
<li id="fn1">
|
|
| 157 |
<p>This is the foot note <a href="#fnref1">↩</a></p>
|
|
| 158 |
</li>
|
|
| 159 |
</ol>
|
|
| 160 |
EXPECTED
|
|
| 151 | 161 | |
| 152 | 162 |
assert_equal expected.gsub(%r{[\r\n\t]}, ''), format(text).gsub(%r{[\r\n\t]}, '')
|
| 153 | 163 |
end |
| test/unit/lib/redmine/wiki_formatting/common_mark/syntax_highlight_filter_test.rb | ||
|---|---|---|
| 22 | 22 |
</code></pre> |
| 23 | 23 |
HTML |
| 24 | 24 |
expected = <<-HTML |
| 25 |
<pre><code class="ruby syntaxhl"> |
|
| 25 |
<pre><code class="ruby syntaxhl" data-language="ruby">
|
|
| 26 | 26 |
<span class="k">def</span> <span class="nf">foo</span> |
| 27 | 27 |
<span class="k">end</span> |
| 28 | 28 |
</code></pre> |
| ... | ... | |
| 30 | 30 |
assert_equal expected, filter(input) |
| 31 | 31 |
end |
| 32 | 32 | |
| 33 |
def test_should_strip_code_for_unknown_lang |
|
| 33 |
def test_should_strip_code_class_for_unknown_lang
|
|
| 34 | 34 |
input = <<-HTML |
| 35 | 35 |
<pre><code class="language-foobar"> |
| 36 | 36 |
def foo |
| ... | ... | |
| 38 | 38 |
</code></pre> |
| 39 | 39 |
HTML |
| 40 | 40 |
expected = <<-HTML |
| 41 |
<pre> |
|
| 41 |
<pre><code data-language="foobar">
|
|
| 42 | 42 |
def foo |
| 43 | 43 |
end |
| 44 |
</pre> |
|
| 44 |
</code></pre> |
|
| 45 |
HTML |
|
| 46 |
assert_equal expected, filter(input) |
|
| 47 |
end |
|
| 48 | ||
| 49 |
def test_should_preserve_lang_in_data_language_attribute |
|
| 50 |
input = <<-HTML |
|
| 51 |
<pre><code class="language-c-k&r"> |
|
| 52 |
int i; |
|
| 53 |
</code></pre> |
|
| 54 |
HTML |
|
| 55 |
expected = <<-HTML |
|
| 56 |
<pre><code data-language="c-k&r"> |
|
| 57 |
int i; |
|
| 58 |
</code></pre> |
|
| 45 | 59 |
HTML |
| 46 | 60 |
assert_equal expected, filter(input) |
| 47 | 61 |
end |