Class: Markdown::Merge::OutputBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/markdown/merge/output_builder.rb

Overview

Builds markdown output from merge operations.

Handles markdown-specific concerns like:

  • Extracting source from original nodes
  • Reconstructing consumed link reference definitions
  • Preserving gap lines (blank line spacing)
  • Automatic structural spacing (blank lines between tables, headings, etc.)
  • Assembling final merged content

Unlike Emitter classes used in JSON/YAML/etc, OutputBuilder focuses on
source preservation and reconstruction rather than generation from scratch.

Examples:

Basic usage

builder = OutputBuilder.new
builder.add_node_source(node, analysis)
builder.add_link_definition(link_def_node)
builder.add_gap_line(count: 2)
content = builder.to_s

Instance Method Summary collapse

Constructor Details

#initialize(preserve_formatting: true, auto_spacing: true) ⇒ OutputBuilder

Initialize a new OutputBuilder

Parameters:

  • preserve_formatting (Boolean) (defaults to: true)

    Whether to preserve original formatting

  • auto_spacing (Boolean) (defaults to: true)

    Whether to automatically insert blank lines between structural elements



28
29
30
31
32
33
# File 'lib/markdown/merge/output_builder.rb', line 28

def initialize(preserve_formatting: true, auto_spacing: true)
  @parts = []
  @preserve_formatting = preserve_formatting
  @auto_spacing = auto_spacing
  @last_node_type = nil  # Track previous node type for spacing decisions
end

Instance Method Details

#add_gap_line(count: 1) ⇒ Object

Add gap lines (blank line preservation)

Parameters:

  • count (Integer) (defaults to: 1)

    Number of blank lines to add



83
84
85
# File 'lib/markdown/merge/output_builder.rb', line 83

def add_gap_line(count: 1)
  @parts << ("\n" * count) if count > 0
end

Add a reconstructed link definition

Parameters:



75
76
77
78
# File 'lib/markdown/merge/output_builder.rb', line 75

def add_link_definition(node)
  formatted = LinkDefinitionFormatter.format(node)
  @parts << formatted if formatted && !formatted.empty?
end

#add_node_source(node, analysis) ⇒ Object

Add a node’s source content

Automatically inserts structural blank lines when transitioning between
certain node types (tables, headings, code blocks, etc.) if auto_spacing is enabled.

Parameters:

  • node (Object)

    Node to add (can be parser node, FreezeNode, LinkDefinitionNode, etc.)

  • analysis (FileAnalysisBase)

    Analysis for accessing source



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/markdown/merge/output_builder.rb', line 42

def add_node_source(node, analysis)
  # Determine node type for spacing decisions
  current_type = MarkdownStructure.node_type(node)

  # Auto-spacing logic:
  # - Skip for gap_line and freeze_block (they handle their own spacing)
  # - Skip if last node was a gap_line (we already have spacing)
  # - Otherwise, check MarkdownStructure.needs_blank_between? which handles
  #   contiguous types (like link_definitions that shouldn't have blanks between them)
  unless [:gap_line, :freeze_block].include?(current_type) ||
      @last_node_type == :gap_line
    if @auto_spacing && @last_node_type && current_type
      if MarkdownStructure.needs_blank_between?(@last_node_type, current_type)
        # Only add spacing if we don't already have adequate blank lines
        # Check the last part to see if it already ends with blank line(s)
        unless @parts.empty? || @parts.last&.end_with?("\n\n")
          add_gap_line(count: 1)
        end
      end
    end
  end

  content = extract_source(node, analysis)
  if content && !content.empty?
    @parts << content
    # Update last node type (track all node types for proper spacing)
    @last_node_type = current_type
  end
end

#add_raw(text) ⇒ Object

Add raw text content

Parameters:

  • text (String)

    Raw text to add



90
91
92
# File 'lib/markdown/merge/output_builder.rb', line 90

def add_raw(text)
  @parts << text if text && !text.empty?
end

#clearObject

Clear all content



109
110
111
# File 'lib/markdown/merge/output_builder.rb', line 109

def clear
  @parts.clear
end

#empty?Boolean

Check if builder has any content

Returns:

  • (Boolean)


104
105
106
# File 'lib/markdown/merge/output_builder.rb', line 104

def empty?
  @parts.empty?
end

#to_sString

Get final content

Returns:

  • (String)

    Assembled markdown content



97
98
99
# File 'lib/markdown/merge/output_builder.rb', line 97

def to_s
  @parts.join
end