Class: Coradoc::AsciiDoc::Parser::BlockAssembler

Inherits:
Object
  • Object
show all
Defined in:
lib/coradoc/asciidoc/parser/block_assembler.rb

Overview

Single Responsibility: Assemble block AST from metadata hints Takes metadata analysis and input text, returns proper AST structure

Class Method Summary collapse

Class Method Details

.assemble(input, metadata_analysis) ⇒ Hash

Main entry point: assemble block AST from input and metadata

Parameters:

  • input (String)

    The input text to parse

  • metadata_analysis (Hash)

    Analysis from MetadataDetector

Returns:

  • (Hash)

    AST hash => {…}



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/coradoc/asciidoc/parser/block_assembler.rb', line 13

def self.assemble(input, )
  return nil unless 

  pattern = [:pattern]

  # Delegate to pattern-specific methods (Open/Closed Principle)
  case pattern
  when :title_attr_delim
    assemble_title_attr_delim(input, )
  when :title_delim
    assemble_title_delim(input, )
  when :attr_delim
    assemble_attr_delim(input, )
  when :plain_delim
    assemble_plain_delim(input, )
  end
end

.assemble_attr_delim(input, metadata) ⇒ Hash

Handle: Attribute + Delimiter pattern (no title)

Parameters:

  • input (String)

    The input text

  • metadata (Hash)

    Metadata analysis

Returns:

  • (Hash)

    Block hash without title



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/coradoc/asciidoc/parser/block_assembler.rb', line 81

def self.assemble_attr_delim(input, )
  lines = input.lines
  delimiter_line = [:delimiter_line]
  delimiter = [:delimiter][:delimiter]

  # Extract components
  attr_list = parse_attribute_list([:attributes])

  # Extract block content
  block_lines = extract_block_lines(lines, delimiter_line, delimiter)

  {
    attribute_list: attr_list,
    delimiter: delimiter,
    lines: block_lines
  }
end

.assemble_plain_delim(input, metadata) ⇒ Hash

Handle: Just Delimiter pattern

Parameters:

  • input (String)

    The input text

  • metadata (Hash)

    Metadata analysis

Returns:

  • (Hash)

    Minimal block hash



103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/coradoc/asciidoc/parser/block_assembler.rb', line 103

def self.assemble_plain_delim(input, )
  lines = input.lines
  delimiter_line = [:delimiter_line]
  delimiter = [:delimiter][:delimiter]

  # Extract block content
  block_lines = extract_block_lines(lines, delimiter_line, delimiter)

  {
    delimiter: delimiter,
    lines: block_lines
  }
end

.assemble_title_attr_delim(input, metadata) ⇒ Hash

Handle: Title + Attribute + Delimiter pattern

Parameters:

  • input (String)

    The input text

  • metadata (Hash)

    Metadata analysis

Returns:

  • (Hash)

    Complete block hash



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/coradoc/asciidoc/parser/block_assembler.rb', line 35

def self.assemble_title_attr_delim(input, )
  lines = input.lines
  delimiter_line = [:delimiter_line]
  delimiter = [:delimiter][:delimiter]

  # Extract components
  title_text = [:title][:text]
  attr_list = parse_attribute_list([:attributes])

  # Extract block content
  block_lines = extract_block_lines(lines, delimiter_line, delimiter)

  {
    title: title_text,
    attribute_list: attr_list,
    delimiter: delimiter,
    lines: block_lines
  }
end

.assemble_title_delim(input, metadata) ⇒ Hash

Handle: Title + Delimiter pattern (no attributes)

Parameters:

  • input (String)

    The input text

  • metadata (Hash)

    Metadata analysis

Returns:

  • (Hash)

    Block hash without attributes



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/coradoc/asciidoc/parser/block_assembler.rb', line 59

def self.assemble_title_delim(input, )
  lines = input.lines
  delimiter_line = [:delimiter_line]
  delimiter = [:delimiter][:delimiter]

  # Extract components
  title_text = [:title][:text]

  # Extract block content
  block_lines = extract_block_lines(lines, delimiter_line, delimiter)

  {
    title: title_text,
    delimiter: delimiter,
    lines: block_lines
  }
end

.extract_block_lines(lines, delimiter_line, delimiter) ⇒ Array<Hash>

Helper: Extract content between delimiters

Parameters:

  • lines (Array<String>)

    All lines of input

  • delimiter_line (Integer)

    Line number of opening delimiter

  • delimiter (String)

    The delimiter string (e.g., “****”)

Returns:

  • (Array<Hash>)

    Array of => “…”, :line_break => “n”



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/coradoc/asciidoc/parser/block_assembler.rb', line 122

def self.extract_block_lines(lines, delimiter_line, delimiter)
  block_lines = []

  # Start from line after opening delimiter
  i = delimiter_line + 1

  # Collect lines until closing delimiter
  while i < lines.length
    line = lines[i]

    # Check if this is the closing delimiter
    break if line.strip == delimiter

    # Handle empty lines vs content lines
    if line.strip.empty?
      block_lines << { line_break: "\n" }
    else
      # Remove trailing newline for processing
      text = line.chomp
      block_lines << { text: text, line_break: "\n" }
    end

    i += 1
  end

  block_lines
end

.parse_attribute_list(attr_meta) ⇒ Hash

Parse attribute list to match expected AST structure

Parameters:

  • attr_meta (Hash)

    Attribute metadata from detector

Returns:

  • (Hash)

    Properly formatted attribute_list hash



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/coradoc/asciidoc/parser/block_assembler.rb', line 153

def self.parse_attribute_list(attr_meta)
  return nil unless attr_meta

  # Get the raw content (without brackets)
  content = attr_meta[:content]
  attr_content = content[1...-1] # Remove [ and ]

  # Get attributes array from metadata
  attributes = attr_meta[:attributes]

  # Build attribute_array in expected format
  attribute_array = attributes.map do |attr|
    # Check if it's a named attribute (key=value)
    if attr.include?('=')
      key, value = attr.split('=', 2)
      { named: { named_key: key.strip, named_value: value.strip } }
    else
      # Positional attribute
      { positional: attr.strip }
    end
  end

  {
    attr_content: attr_content,
    attribute_array: attribute_array
  }
end