Class: Ast::Merge::PartialTemplateMergerBase Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/ast/merge/partial_template_merger_base.rb

Overview

This class is abstract.

Subclass and implement parser-specific methods

Base class for merging a partial template into a specific section of a destination document.

Unlike the full SmartMerger which merges entire documents, PartialTemplateMergerBase:

  1. Finds a specific section in the destination (using InjectionPoint)
  2. Replaces/merges only that section with the template
  3. Leaves the rest of the destination unchanged

Ownership boundary:

  • this base class owns the shared structural contract for locating, replacing, and recombining partial content
  • syntax-aware cleanup after recomposition belongs in the relevant family layer or concrete partial merger unless it is truly syntax-agnostic

This is an abstract base class. Subclasses must implement:

  • #create_analysis(content) - Create a FileAnalysis for the given content
  • #create_smart_merger(template, section) - Create a SmartMerger for the section merge
  • #find_section_end(statements, injection_point) - Find where the section ends
  • #node_to_text(node, analysis) - Convert a node to source text

See Also:

  • For markdown implementation

Defined Under Namespace

Classes: Result

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(template:, destination:, anchor:, boundary: nil, preference: :template, add_missing: true, when_missing: :skip, replace_mode: false, signature_generator: nil, node_typing: nil, match_refiner: nil) ⇒ PartialTemplateMergerBase

Initialize a PartialTemplateMergerBase.

Parameters:

  • template (String)

    The template content (the section to merge in)

  • destination (String)

    The destination content

  • anchor (Hash)

    Anchor matcher: { type: :heading, text: /pattern/ }

  • boundary (Hash, nil) (defaults to: nil)

    Boundary matcher (defaults to same type as anchor)

  • preference (Symbol, Hash) (defaults to: :template)

    Which content wins (:template, :destination, or per-type hash)

  • add_missing (Boolean, Proc) (defaults to: true)

    Whether to add template nodes not in destination

  • when_missing (Symbol) (defaults to: :skip)

    What to do if section not found (:skip, :append, :prepend)

  • replace_mode (Boolean) (defaults to: false)

    If true, template replaces section entirely (no merge)

  • signature_generator (Proc, nil) (defaults to: nil)

    Custom signature generator for SmartMerger

  • node_typing (Hash, nil) (defaults to: nil)

    Node typing configuration for per-type preferences

  • match_refiner (Object, nil) (defaults to: nil)

    Match refiner for fuzzy matching (e.g., ContentMatchRefiner)



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/ast/merge/partial_template_merger_base.rb', line 106

def initialize(
  template:,
  destination:,
  anchor:,
  boundary: nil,
  preference: :template,
  add_missing: true,
  when_missing: :skip,
  replace_mode: false,
  signature_generator: nil,
  node_typing: nil,
  match_refiner: nil
)
  @template = template
  @destination = destination
  @anchor = normalize_matcher(anchor)
  @boundary = boundary ? normalize_matcher(boundary) : nil
  @preference = preference
  @add_missing = add_missing
  @when_missing = when_missing
  @replace_mode = replace_mode
  @signature_generator = signature_generator
  @node_typing = node_typing
  @match_refiner = match_refiner
end

Instance Attribute Details

#add_missingBoolean, Proc (readonly)

Returns Whether to add template-only nodes.

Returns:

  • (Boolean, Proc)

    Whether to add template-only nodes



79
80
81
# File 'lib/ast/merge/partial_template_merger_base.rb', line 79

def add_missing
  @add_missing
end

#anchorHash (readonly)

Returns Anchor matcher configuration.

Returns:

  • (Hash)

    Anchor matcher configuration



70
71
72
# File 'lib/ast/merge/partial_template_merger_base.rb', line 70

def anchor
  @anchor
end

#boundaryHash? (readonly)

Returns Boundary matcher configuration.

Returns:

  • (Hash, nil)

    Boundary matcher configuration



73
74
75
# File 'lib/ast/merge/partial_template_merger_base.rb', line 73

def boundary
  @boundary
end

#destinationString (readonly)

Returns The destination content.

Returns:

  • (String)

    The destination content



67
68
69
# File 'lib/ast/merge/partial_template_merger_base.rb', line 67

def destination
  @destination
end

#match_refinerObject? (readonly)

Returns Match refiner for fuzzy matching unmatched nodes.

Returns:

  • (Object, nil)

    Match refiner for fuzzy matching unmatched nodes



91
92
93
# File 'lib/ast/merge/partial_template_merger_base.rb', line 91

def match_refiner
  @match_refiner
end

#node_typingHash? (readonly)

Returns Node typing configuration for per-type preferences.

Returns:

  • (Hash, nil)

    Node typing configuration for per-type preferences



88
89
90
# File 'lib/ast/merge/partial_template_merger_base.rb', line 88

def node_typing
  @node_typing
end

#preferenceSymbol, Hash (readonly)

Returns Merge preference (:template, :destination, or per-type hash).

Returns:

  • (Symbol, Hash)

    Merge preference (:template, :destination, or per-type hash)



76
77
78
# File 'lib/ast/merge/partial_template_merger_base.rb', line 76

def preference
  @preference
end

#signature_generatorProc? (readonly)

Returns Custom signature generator for node matching.

Returns:

  • (Proc, nil)

    Custom signature generator for node matching



85
86
87
# File 'lib/ast/merge/partial_template_merger_base.rb', line 85

def signature_generator
  @signature_generator
end

#templateString (readonly)

Returns The template content (the section to inject).

Returns:

  • (String)

    The template content (the section to inject)



64
65
66
# File 'lib/ast/merge/partial_template_merger_base.rb', line 64

def template
  @template
end

#when_missingSymbol (readonly)

Returns What to do when section not found (:skip, :append, :prepend).

Returns:

  • (Symbol)

    What to do when section not found (:skip, :append, :prepend)



82
83
84
# File 'lib/ast/merge/partial_template_merger_base.rb', line 82

def when_missing
  @when_missing
end

Instance Method Details

#mergeResult

Perform the partial template merge.

Returns:

  • (Result)

    The merge result



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/ast/merge/partial_template_merger_base.rb', line 135

def merge
  # Parse destination and find injection point
  d_analysis = create_analysis(destination)
  d_statements = Navigable::Statement.build_list(navigable_statements_for(d_analysis))

  finder = Navigable::InjectionPointFinder.new(d_statements)
  injection_point = finder.find(
    type: anchor[:type],
    text: anchor[:text],
    position: :replace,
    boundary_type: boundary&.dig(:type),
    boundary_text: boundary&.dig(:text),
    boundary_same_or_shallower: boundary&.dig(:same_or_shallower) || false
  )

  return handle_missing_section(d_analysis) if injection_point.nil?

  # Found the section - now merge
  perform_section_merge(d_analysis, d_statements, injection_point)
end