Class: Slamdown::Conversion::Renderer
- Inherits:
-
Object
- Object
- Slamdown::Conversion::Renderer
- Defined in:
- lib/slamdown/conversion/renderer.rb
Overview
Traverses the normalised tree through shared inline and block primitives, delegating only genuine format differences to a strategy.
Constant Summary collapse
- ENTITY_KINDS =
[:entity, :typographic_symbol, :smart_quote].freeze
- LIST_KINDS =
[:ordered_list, :unordered_list].freeze
- FAILED_RENDERING =
Object.new.freeze
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(configuration, format) ⇒ Renderer
constructor
A new instance of Renderer.
- #render(root) ⇒ Object
-
#render_blocks(nodes) ⇒ Object
Renders a block sequence with exactly one blank line between neighbouring constructs.
-
#render_container_contents(node) ⇒ Object
Renders the children of structural containers whose parser shape may be inline or block-oriented.
-
#render_inlines(nodes, suppress_strong: false, line_start: true) ⇒ Object
Renders one inline sequence, with optional strong-marker suppression used by Markdown definition terms.
Constructor Details
#initialize(configuration, format) ⇒ Renderer
Returns a new instance of Renderer.
18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/slamdown/conversion/renderer.rb', line 18 def initialize(configuration, format) raise ArgumentError, "configuration must be a Slamdown conversion configuration" unless configuration.is_a?(Configuration) raise ArgumentError, "format must be markdown or kramdown" unless ["markdown", "kramdown"].include?(format) @configuration = configuration @escaper = Rendering::Escaper.new @entity_encoder = Rendering::EntityEncoder.new(configuration.entities) @html = Rendering::Html.new(configuration, @entity_encoder) @strategy = Rendering::Strategy.build(format) @format = format @diagnostics = [] end |
Class Method Details
Instance Method Details
#render(root) ⇒ Object
31 32 33 34 35 36 |
# File 'lib/slamdown/conversion/renderer.rb', line 31 def render(root) raise ArgumentError, "root must be a normalised Slamdown document" unless root.is_a?(NormalisedNode) && root.kind == :document @diagnostics = [] Rendering::Result.new(canonicalise(render_blocks(root.children)), @diagnostics) end |
#render_blocks(nodes) ⇒ Object
Renders a block sequence with exactly one blank line between neighbouring constructs.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/slamdown/conversion/renderer.rb', line 39 def render_blocks(nodes) parts = [] inline_run = [] flush = lambda do unless inline_run.empty? value = render_inlines(inline_run) parts << value unless value.empty? inline_run = [] end end nodes.each do |node| if block_node?(node) flush.call value = safely_render(node) { render_block(node) } parts << value unless value.equal?(FAILED_RENDERING) || value.empty? else inline_run << node end end flush.call parts.join("\n\n") end |
#render_container_contents(node) ⇒ Object
Renders the children of structural containers whose parser shape may be inline or block-oriented.
64 65 66 |
# File 'lib/slamdown/conversion/renderer.rb', line 64 def render_container_contents(node) node.children.any? { |child| block_node?(child) } ? render_blocks(node.children) : render_inlines(node.children) end |
#render_inlines(nodes, suppress_strong: false, line_start: true) ⇒ Object
Renders one inline sequence, with optional strong-marker suppression used by Markdown definition terms.
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/slamdown/conversion/renderer.rb', line 69 def render_inlines(nodes, suppress_strong: false, line_start: true) result = "" failed_rendering = false nodes.each do |node| value = safely_render(node) { render_inline(node, line_start && result.empty?, suppress_strong) } if value.equal?(FAILED_RENDERING) failed_rendering = true next end # Dropping a failed inline node can make its surrounding text spaces newly adjacent, so restore the already-normalised boundary. if failed_rendering value = value.sub(/\A +/, "") if result.empty? || (result.end_with?(" ") && value.start_with?(" ")) failed_rendering = false end result += value end failed_rendering ? result.sub(/ +\z/, "") : result end |