Class: MarkdownViews::Renderer
- Inherits:
-
Object
- Object
- MarkdownViews::Renderer
- Defined in:
- lib/markdown_views/renderer.rb
Class Method Summary collapse
- .render(template) ⇒ Object
-
.render_md(input) ⇒ Object
remainder all considered private.
- .rouge_formatter ⇒ Object
-
.strip_comments(input) ⇒ Object
removes single & multi-line comments if any content besides comment & whitespace is on same line(s), strips just the comment.
- .transform_code_blocks(doc) ⇒ Object
Class Method Details
.render(template) ⇒ Object
5 6 7 8 9 10 11 |
# File 'lib/markdown_views/renderer.rb', line 5 def render(template) out = template.to_s out = strip_comments(out) if MarkdownViews.strip_comments out = render_md(out) out = strip_comments(out) if MarkdownViews.strip_comments out.html_safe end |
.render_md(input) ⇒ Object
remainder all considered private
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/markdown_views/renderer.rb', line 15 def render_md(input) doc = Commonmarker.parse(input, options: { extension: MarkdownViews.extensions, parse: MarkdownViews.parsing_opts, }) if MarkdownViews.transformers.include? :code_blocks code_blocks = transform_code_blocks(doc) end out = doc.to_html( options: { extension: MarkdownViews.extensions, render: MarkdownViews.rendering_opts, }, plugins: MarkdownViews.plugins ) code_blocks&.each do |uuid, cb| out.sub! uuid, cb end out end |
.rouge_formatter ⇒ Object
38 39 40 |
# File 'lib/markdown_views/renderer.rb', line 38 def rouge_formatter MarkdownViews.rouge_opts[:formatter] || Rouge::Formatters::HTML.new end |
.strip_comments(input) ⇒ Object
removes single & multi-line comments
if any content besides comment & whitespace is on same line(s), strips just the comment.
if no other content, strips the lines & whitespace too.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/markdown_views/renderer.rb', line 45 def strip_comments(input) # ^[ \t]*(<!--.*?-->)++[ \t]*\r?\n lines with just comments # | or # <!--.*?--> comments on lines with other content # # ^ start of line # [ \t]* optional spaces or tabs # (<!--.*?-->)++ # <!-- start of html comment # .*? any char, incl linefeed (for multi-line comments) # lazy (non-greedy): *? # --> end of html comment # ++ possessive match - prevents a match across comment boundaries # ie: prevent matching this: <!-- a --> keep <!-- b --> # explanation: initially .*? will refuse to match --> because it's # non-greedy. but, in search of pre/post whitespace, the regex engine # could backtrack and ask .*? to match an --> as long as there's # another --> later. possessive disables the backtracking. # can combine <!-- a --><!-- b --> into one match, which is of no harm. # [ \t]* optional spaces or tabs # \r?\n end of line (either unix or windows style) input.gsub(/^[ \t]*(<!--.*?-->)++[ \t]*\r?\n|<!--.*?-->/m, '') end |
.transform_code_blocks(doc) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/markdown_views/renderer.rb', line 69 def transform_code_blocks(doc) code_blocks = {} doc.walk do |node| next unless node.type == :code_block next if node.fence_info == '' lang = node.fence_info code = node.string_content lexer = Rouge::Lexer.find(lang) || Rouge::Lexers::PlainText html = rouge_formatter.format(lexer.lex code).rstrip if MarkdownViews.rouge_opts[:wrap] html = %Q{<pre lang="#{lang.gsub(/[^a-z0-9_-]/,'')}"><code class="rouge-highlight">#{html}</code></pre>} end uuid = SecureRandom.uuid code_blocks[uuid] = html new_node = Commonmarker::Node.new(:text, content: "#{uuid}\n") node.replace new_node end code_blocks end |