Module: MarkdownComposer::MarkdownRenderer
- Defined in:
- lib/markdown_composer/markdown_renderer.rb
Class Method Summary collapse
- .apply_link_modes(html, modes, diagnostics: Diagnostics.new) ⇒ Object
- .escape(text) ⇒ Object
- .escape_attribute(text) ⇒ Object
- .fallback_html(markdown) ⇒ Object
- .flush_list(html, list_items) ⇒ Object
- .merge_rel(link, value) ⇒ Object
- .render_inline(text) ⇒ Object
- .render_with_commonmarker(markdown) ⇒ Object
- .to_html(markdown, diagnostics: Diagnostics.new) ⇒ Object
Class Method Details
.apply_link_modes(html, modes, diagnostics: Diagnostics.new) ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/markdown_composer/markdown_renderer.rb', line 18 def apply_link_modes(html, modes, diagnostics: Diagnostics.new) modes = Array(modes).map(&:to_s) return html if html.to_s.empty? || modes.empty? require "nokogiri" fragment = Nokogiri::HTML5.fragment(html) fragment.css("a[href]").each do |link| href = link["href"].to_s next if href.empty? || href.start_with?("#") merge_rel(link, "nofollow") if modes.include?("nofollow") if modes.include?("target_blank") link["target"] = "_blank" merge_rel(link, "noopener") merge_rel(link, "noreferrer") end end fragment.to_html rescue LoadError, StandardError => e diagnostics.warn("transform.html_link_postprocess_failed", "HTML link transform skipped: #{e.}", path: "transform") html end |
.escape(text) ⇒ Object
91 92 93 |
# File 'lib/markdown_composer/markdown_renderer.rb', line 91 def escape(text) text.gsub("&", "&").gsub("<", "<").gsub(">", ">") end |
.escape_attribute(text) ⇒ Object
95 96 97 |
# File 'lib/markdown_composer/markdown_renderer.rb', line 95 def escape_attribute(text) escape(text.to_s).gsub('"', """) end |
.fallback_html(markdown) ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/markdown_composer/markdown_renderer.rb', line 49 def fallback_html(markdown) html = [] list_items = [] markdown.lines.each do |line| case line when /\A\s*[-*+]\s+(.+)/ list_items << "<li>#{render_inline(Regexp.last_match(1).strip)}</li>" when /\A(\#{1,6})\s+(.+)/ flush_list(html, list_items) level = Regexp.last_match(1).length html << "<h#{level}>#{render_inline(Regexp.last_match(2).strip)}</h#{level}>" when /\A\s*$/ flush_list(html, list_items) else flush_list(html, list_items) html << "<p>#{render_inline(line.strip)}</p>" end end flush_list(html, list_items) html.join("\n") end |
.flush_list(html, list_items) ⇒ Object
84 85 86 87 88 89 |
# File 'lib/markdown_composer/markdown_renderer.rb', line 84 def flush_list(html, list_items) return if list_items.empty? html << "<ul>#{list_items.join}</ul>" list_items.clear end |
.merge_rel(link, value) ⇒ Object
99 100 101 102 103 |
# File 'lib/markdown_composer/markdown_renderer.rb', line 99 def merge_rel(link, value) rel_values = link["rel"].to_s.split(/\s+/).reject(&:empty?) rel_values << value unless rel_values.include?(value) link["rel"] = rel_values.join(" ") end |
.render_inline(text) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/markdown_composer/markdown_renderer.rb', line 71 def render_inline(text) rendered = +"" last_index = 0 text.to_s.to_enum(:scan, /(?<!!)\[([^\]]+)\]\(([^)\s]+)\)/).each do match = Regexp.last_match rendered << escape(text.to_s[last_index...match.begin(0)].to_s) rendered << "<a href=\"#{escape_attribute(match[2])}\">#{escape(match[1])}</a>" last_index = match.end(0) end rendered << escape(text.to_s[last_index..].to_s) rendered end |
.render_with_commonmarker(markdown) ⇒ Object
41 42 43 44 45 46 47 |
# File 'lib/markdown_composer/markdown_renderer.rb', line 41 def render_with_commonmarker(markdown) return CommonMarker.render_html(markdown) if defined?(CommonMarker) && CommonMarker.respond_to?(:render_html) return Commonmarker.to_html(markdown) if defined?(Commonmarker) && Commonmarker.respond_to?(:to_html) return CommonMarker.render_doc(markdown).to_html if defined?(CommonMarker) && CommonMarker.respond_to?(:render_doc) raise "unsupported CommonMarker API" end |
.to_html(markdown, diagnostics: Diagnostics.new) ⇒ Object
7 8 9 10 11 12 13 14 15 16 |
# File 'lib/markdown_composer/markdown_renderer.rb', line 7 def to_html(markdown, diagnostics: Diagnostics.new) begin require "commonmarker" return render_with_commonmarker(markdown) rescue LoadError, StandardError diagnostics.warn("output.html_fallback", "CommonMarker HTML rendering unavailable; using simple fallback", path: "output") end fallback_html(markdown) end |