class MarkdownIt::Renderer
Attributes
Public Class Methods
# File lib/motion-markdown-it/renderer.rb, line 25 def self.code_block(tokens, idx, options, env, renderer) token = tokens[idx] return '<pre' + renderer.renderAttrs(token) + '><code>' + escapeHtml(tokens[idx].content) + "</code></pre>\n" end
Default Rules
# File lib/motion-markdown-it/renderer.rb, line 16 def self.code_inline(tokens, idx, options, env, renderer) token = tokens[idx] return '<code' + renderer.renderAttrs(token) + '>' + escapeHtml(tokens[idx].content) + '</code>' end
# File lib/motion-markdown-it/renderer.rb, line 34 def self.fence(tokens, idx, options, env, renderer) token = tokens[idx] info = token.info ? unescapeAll(token.info).strip : '' langName = '' if !info.empty? langName = info.split(/\s+/)[0] end if options[:highlight] highlighted = options[:highlight].call(token.content, langName) || escapeHtml(token.content) else highlighted = escapeHtml(token.content) end if highlighted.start_with?('<pre') return highlighted + "\n" end # If language exists, inject class gently, without modifying original token. # May be, one day we will add .clone() for token and simplify this part, but # now we prefer to keep things local. if !info.empty? i = token.attrIndex('class') tmpAttrs = token.attrs ? token.attrs.dup : [] if i < 0 tmpAttrs.push([ 'class', options[:langPrefix] + langName ]) else tmpAttrs[i][1] += ' ' + options[:langPrefix] + langName end # Fake token just to render attributes tmpToken = Token.new(nil, nil, nil) tmpToken.attrs = tmpAttrs return '<pre><code' + renderer.renderAttrs(tmpToken) + '>' + highlighted + "</code></pre>\n" end return '<pre><code' + renderer.renderAttrs(token) + '>' + highlighted + "</code></pre>\n" end
# File lib/motion-markdown-it/renderer.rb, line 93 def self.hardbreak(tokens, idx, options) return options[:xhtmlOut] ? "<br />\n" : "<br>\n" end
# File lib/motion-markdown-it/renderer.rb, line 106 def self.html_block(tokens, idx) return tokens[idx].content end
# File lib/motion-markdown-it/renderer.rb, line 109 def self.html_inline(tokens, idx) return tokens[idx].content end
# File lib/motion-markdown-it/renderer.rb, line 79 def self.image(tokens, idx, options, env, renderer) token = tokens[idx] # "alt" attr MUST be set, even if empty. Because it's mandatory and # should be placed on proper position for tests. # # Replace content with actual value token.attrs[token.attrIndex('alt')][1] = renderer.renderInlineAsText(token.children, options, env) return renderer.renderToken(tokens, idx, options); end
new Renderer()
Creates new [[Renderer]] instance and fill [[Renderer#rules]] with defaults.
# File lib/motion-markdown-it/renderer.rb, line 118 def initialize @default_rules = { 'code_inline' => lambda {|tokens, idx, options, env, renderer| Renderer.code_inline(tokens, idx, options, env, renderer)}, 'code_block' => lambda {|tokens, idx, options, env, renderer| Renderer.code_block(tokens, idx, options, env, renderer)}, 'fence' => lambda {|tokens, idx, options, env, renderer| Renderer.fence(tokens, idx, options, env, renderer)}, 'image' => lambda {|tokens, idx, options, env, renderer| Renderer.image(tokens, idx, options, env, renderer)}, 'hardbreak' => lambda {|tokens, idx, options, env, renderer| Renderer.hardbreak(tokens, idx, options)}, 'softbreak' => lambda {|tokens, idx, options, env, renderer| Renderer.softbreak(tokens, idx, options)}, 'text' => lambda {|tokens, idx, options, env, renderer| Renderer.text(tokens, idx)}, 'html_block' => lambda {|tokens, idx, options, env, renderer| Renderer.html_block(tokens, idx)}, 'html_inline' => lambda {|tokens, idx, options, env, renderer| Renderer.html_inline(tokens, idx)} } # Renderer#rules -> Object # # Contains render rules for tokens. Can be updated and extended. # # ##### Example # # ```javascript # var md = require('markdown-it')(); # # md.renderer.rules.strong_open = function () { return '<b>'; }; # md.renderer.rules.strong_close = function () { return '</b>'; }; # # var result = md.renderInline(...); # ``` # # Each rule is called as independet static function with fixed signature: # # ```javascript # function my_token_render(tokens, idx, options, env, renderer) { # // ... # return renderedHTML; # } # ``` # # See [source code](https://github.com/markdown-it/markdown-it/blob/master/lib/renderer.js) # for more details and examples. @rules = assign({}, @default_rules) end
# File lib/motion-markdown-it/renderer.rb, line 96 def self.softbreak(tokens, idx, options) return options[:breaks] ? (options[:xhtmlOut] ? "<br />\n" : "<br>\n") : "\n" end
# File lib/motion-markdown-it/renderer.rb, line 101 def self.text(tokens, idx) return escapeHtml(tokens[idx].content) end
Public Instance Methods
Renderer.render
(tokens, options, env) -> String
-
tokens (Array): list on block tokens to renter
-
options (
Object
): params of parser instance -
env (
Object
): additional data from parsed input (references, for example)
Takes token stream and generates HTML. Probably, you will never need to call this method directly.
# File lib/motion-markdown-it/renderer.rb, line 301 def render(tokens, options, env) result = '' rules = @rules 0.upto(tokens.length - 1) do |i| type = tokens[i].type if type == 'inline' result += renderInline(tokens[i].children, options, env) elsif rules[type] != nil result += rules[tokens[i].type].call(tokens, i, options, env, self) else result += renderToken(tokens, i, options) end end return result end
Renderer.renderAttrs(token)
-> String
Render token attributes to string.
# File lib/motion-markdown-it/renderer.rb, line 165 def renderAttrs(token) return '' if !token.attrs result = '' 0.upto(token.attrs.length - 1) do |i| result += ' ' + escapeHtml(token.attrs[i][0]) + '="' + escapeHtml(token.attrs[i][1].to_s) + '"' end return result end
Renderer.renderInline
(tokens, options, env) -> String
-
tokens (Array): list on block tokens to renter
-
options (
Object
): params of parser instance -
env (
Object
): additional data from parsed input (references, for example)
The same as [[Renderer.render]], but for single token of `inline` type.
# File lib/motion-markdown-it/renderer.rb, line 250 def renderInline(tokens, options, env) result = '' rules = @rules 0.upto(tokens.length - 1) do |i| type = tokens[i].type if rules[type] != nil result += rules[type].call(tokens, i, options, env, self) else result += renderToken(tokens, i, options) end end return result; end
internal Renderer.renderInlineAsText
(tokens, options, env) -> String
-
tokens (Array): list on block tokens to renter
-
options (
Object
): params of parser instance -
env (
Object
): additional data from parsed input (references, for example)
Special kludge for image `alt` attributes to conform CommonMark spec. Don't try to use it! Spec requires to show `alt` content with stripped markup, instead of simple escaping.
# File lib/motion-markdown-it/renderer.rb, line 278 def renderInlineAsText(tokens, options, env) result = '' 0.upto(tokens.length - 1) do |i| if tokens[i].type == 'text' result += tokens[i].content elsif tokens[i].type == 'image' result += renderInlineAsText(tokens[i].children, options, env) end end return result end
Renderer.renderToken
(tokens, idx, options) -> String
-
tokens (Array): list of tokens
-
idx (Numbed): token index to render
-
options (
Object
): params of parser instance
Default token renderer. Can be overriden by custom function in [[Renderer#rules]].
# File lib/motion-markdown-it/renderer.rb, line 185 def renderToken(tokens, idx, options, env = nil, renderer = nil) result = '' needLf = false token = tokens[idx] # Tight list paragraphs return '' if token.hidden # Insert a newline between hidden paragraph and subsequent opening # block-level tag. # # For example, here we should insert a newline before blockquote: # - a # > # if token.block && token.nesting != -1 && idx && tokens[idx - 1].hidden result += "\n" end # Add token name, e.g. `<img` result += (token.nesting == -1 ? '</' : '<') + token.tag # Encode attributes, e.g. `<img src="foo"` result += renderAttrs(token) # Add a slash for self-closing tags, e.g. `<img src="foo" /` if token.nesting == 0 && options[:xhtmlOut] result += ' /' end # Check if we need to add a newline after this tag if token.block needLf = true if token.nesting == 1 if idx + 1 < tokens.length nextToken = tokens[idx + 1] if nextToken.type == 'inline' || nextToken.hidden # Block-level tag containing an inline tag. # needLf = false elsif nextToken.nesting == -1 && nextToken.tag == token.tag # Opening tag + closing tag of the same type. E.g. `<li></li>`. # needLf = false end end end end result += needLf ? ">\n" : '>' return result end