Class: RedQuilt::FootnoteDefinition::Parser
- Inherits:
-
Object
- Object
- RedQuilt::FootnoteDefinition::Parser
- Defined in:
- lib/red_quilt/footnote_definition.rb
Overview
Cached collaborator for BlockParser (created once per document and reused for every definition). Footnote definitions are document-global: the parser lazily creates a single FOOTNOTES_SECTION under the root and memoizes it; per-call state otherwise lives in locals so the recursive parse_lines call is safe.
Constant Summary collapse
- CONTENT_INDENT =
GFM footnote continuation indent (columns). Lines indented at least this much (plus blank lines between them) belong to the definition.
4
Instance Method Summary collapse
-
#initialize(block_parser) ⇒ Parser
constructor
A new instance of Parser.
-
#move_section_to_end(root_id) ⇒ Object
Make the footnotes section root’s last child so it renders last and the inline pass numbers body references before any nested references inside the definitions.
-
#parse(lines, index, match, registry, root_id) ⇒ Object
Consumes the definition opening at ‘lines` (its `match` already parsed), registers it in `registry`, and returns the next unconsumed line index.
Constructor Details
#initialize(block_parser) ⇒ Parser
Returns a new instance of Parser.
47 48 49 50 51 |
# File 'lib/red_quilt/footnote_definition.rb', line 47 def initialize(block_parser) @block_parser = block_parser @arena = block_parser.arena @section_id = nil end |
Instance Method Details
#move_section_to_end(root_id) ⇒ Object
Make the footnotes section root’s last child so it renders last and the inline pass numbers body references before any nested references inside the definitions. No-op when no definition was found.
84 85 86 87 88 89 |
# File 'lib/red_quilt/footnote_definition.rb', line 84 def move_section_to_end(root_id) return if @section_id.nil? @arena.detach(@section_id) @arena.append_child(root_id, @section_id) end |
#parse(lines, index, match, registry, root_id) ⇒ Object
Consumes the definition opening at ‘lines` (its `match` already parsed), registers it in `registry`, and returns the next unconsumed line index.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/red_quilt/footnote_definition.rb', line 56 def parse(lines, index, match, registry, root_id) first = lines[index] content_lines = [content_line(match[:content], first.start_byte + match[:content_start], first.end_byte)] consumed_index = collect_continuation(lines, index + 1, content_lines) label = ReferenceDefinition.normalize_label(match[:label]) span = SourceSpan.new(first.start_byte, lines[consumed_index - 1].end_byte) if registry.defined?(label) @block_parser.diagnostics << Diagnostic.new( severity: :warning, rule: :duplicate_footnote, message: "Duplicate footnote definition #{label.inspect} — keeping the first", source_span: span, ) return consumed_index end def_id = @arena.add_node(NodeType::FOOTNOTE_DEFINITION, source_start: span.start_byte, source_len: span.length, str1: label) @arena.append_child(section_id(root_id), def_id) registry.define(label, def_id) @block_parser.parse_lines(def_id, content_lines, transformed: true) consumed_index end |