@@ -5,9 +5,90 @@ module Markup
55 class Markdown < Implementation
66 MARKDOWN_GEMS = {
77 "commonmarker" => proc { |content , options : { } |
8- commonmarker_opts = [ :GITHUB_PRE_LANG ] . concat ( options . fetch ( :commonmarker_opts , [ ] ) )
9- commonmarker_exts = options . fetch ( :commonmarker_exts , [ :tagfilter , :autolink , :table , :strikethrough ] )
10- CommonMarker . render_html ( content , commonmarker_opts , commonmarker_exts )
8+ legacy_opts = options . fetch ( :commonmarker_opts , [ ] )
9+ legacy_exts = options . fetch (
10+ :commonmarker_exts ,
11+ [ :tagfilter , :autolink , :table , :strikethrough ] ,
12+ )
13+
14+ parse_options = { }
15+ # commonmarker 2.x changes several render defaults that diverge from cmark-gfm 0.x:
16+ # - hardbreaks defaults to true in 2.x but was false in 0.x.
17+ # - escaped_char_spans defaults to true in 2.x and wraps backslash-escaped chars in
18+ # <span data-escaped-char>; 0.x emitted bare characters.
19+ # - gfm_quirks defaults to false in 2.x; 0.x (cmark-gfm) always had the quirk on,
20+ # which collapses ****foo**** to <strong>foo</strong> instead of nesting.
21+ # - github_pre_lang defaults to true in 2.x; set explicitly to match the legacy contract.
22+ render_options = {
23+ github_pre_lang : true ,
24+ hardbreaks : false ,
25+ escaped_char_spans : false ,
26+ gfm_quirks : true ,
27+ }
28+ extension_options = { }
29+
30+ legacy_opts . each do |opt |
31+ case opt
32+ when :DEFAULT then nil
33+ when :SOURCEPOS then render_options [ :sourcepos ] = true
34+ when :HARDBREAKS then render_options [ :hardbreaks ] = true
35+ when :NOBREAKS then render_options [ :hardbreaks ] = false
36+ when :SMART then parse_options [ :smart ] = true
37+ when :GITHUB_PRE_LANG then render_options [ :github_pre_lang ] = true
38+ when :UNSAFE then render_options [ :unsafe ] = true
39+ when :FOOTNOTES then extension_options [ :footnotes ] = true
40+ when :FULL_INFO_STRING then render_options [ :full_info_string ] = true
41+ # The legacy options below existed in cmark-gfm 0.x but have no direct commonmarker
42+ # 2.x equivalent. Accept them so existing callers don't break, but they have no effect:
43+ # :VALIDATE_UTF8 / :LIBERAL_HTML_TAG - enforced at the Rust type layer in 2.x.
44+ # :TABLE_PREFER_STYLE_ATTRIBUTES - no 2.x render knob for inline table styles.
45+ # :STRIKETHROUGH_DOUBLE_TILDE - 2.x always accepts both single and double tilde.
46+ when :VALIDATE_UTF8 , :LIBERAL_HTML_TAG ,
47+ :TABLE_PREFER_STYLE_ATTRIBUTES , :STRIKETHROUGH_DOUBLE_TILDE
48+ nil
49+ else
50+ raise ArgumentError , "unknown commonmarker option: #{ opt . inspect } "
51+ end
52+ end
53+
54+ legacy_exts . each do |ext |
55+ case ext
56+ when :strikethrough , :tagfilter , :autolink , :table , :tasklist ,
57+ :shortcodes , :footnotes , :multiline_block_quotes ,
58+ :math_dollars , :math_code , :wikilinks_title_after_pipe ,
59+ :wikilinks_title_before_pipe , :underline , :subscript , :spoiler ,
60+ :greentext , :alerts , :description_lists
61+ extension_options [ ext ] = true
62+ when :header_ids
63+ # header_ids takes a string prefix in 2.x rather than a boolean. The legacy contract
64+ # only passed it as a symbol, so use an empty prefix to enable anchor generation.
65+ extension_options [ :header_ids ] = ""
66+ else
67+ raise ArgumentError , "unknown commonmarker extension: #{ ext . inspect } "
68+ end
69+ end
70+
71+ # Several extensions (tagfilter, autolink, table, strikethrough, tasklist, shortcodes)
72+ # are enabled by default in commonmarker 2.x but were strictly opt-in in 0.x. Explicitly
73+ # disable any extension the caller did not request so behavior matches the legacy contract.
74+ [ :strikethrough , :tagfilter , :autolink , :table , :tasklist , :shortcodes ] . each do |ext |
75+ extension_options [ ext ] = false unless extension_options [ ext ]
76+ end
77+
78+ # header_ids is enabled by default in commonmarker 2.x (it injects anchor tags inside
79+ # every heading). The legacy 0.x wrapper never enabled it implicitly, so disable it
80+ # unless the caller explicitly requested it.
81+ extension_options [ :header_ids ] = nil unless extension_options . key? ( :header_ids )
82+
83+ Commonmarker . to_html (
84+ content ,
85+ options : {
86+ parse : parse_options ,
87+ render : render_options ,
88+ extension : extension_options ,
89+ } ,
90+ plugins : { syntax_highlighter : nil } ,
91+ )
1192 } ,
1293 "github/markdown" => proc { |content , options : { } |
1394 GitHub ::Markdown . render ( content )
0 commit comments