Class: Markdown::Merge::PartialTemplateMerger

Inherits:
Ast::Merge::PartialTemplateMergerBase
  • Object
show all
Includes:
PreservationSupport
Defined in:
lib/markdown/merge/partial_template_merger.rb

Overview

Markdown-specific implementation of PartialTemplateMerger.

Merges a partial template into a specific section of a destination markdown document. This class extends the parser-agnostic base with markdown-specific logic for:

  • Heading-level-aware section boundaries
  • Source-based text extraction to preserve link references and table formatting
  • Backend-specific parser initialization (Markly, Commonmarker)

Examples:

Basic usage

merger = Markdown::Merge::PartialTemplateMerger.new(
  template: template_content,
  destination: destination_content,
  anchor: { type: :heading, text: /Gem Family/ },
  backend: :markly
)
result = merger.merge
puts result.content

With boundary

merger = Markdown::Merge::PartialTemplateMerger.new(
  template: template_content,
  destination: destination_content,
  anchor: { type: :heading, text: /Installation/ },
  boundary: { type: :heading },  # Stop at next heading
  backend: :markly
)

Constant Summary collapse

Result =

Re-export Result class from base for convenience

Ast::Merge::PartialTemplateMergerBase::Result

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(template:, destination:, anchor:, boundary: nil, backend: self.class.default_backend, preference: :template, add_missing: true, when_missing: :skip, replace_mode: false, signature_generator: nil, node_typing: nil, match_refiner: nil, normalize_whitespace: false, rehydrate_link_references: false) ⇒ PartialTemplateMerger

Initialize a markdown PartialTemplateMerger.

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)

  • backend (Symbol) (defaults to: self.class.default_backend)

    Backend to use (:markly, :commonmarker)

  • 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)

  • normalize_whitespace (Boolean) (defaults to: false)

    If true, collapse excessive blank lines. Default: false

  • rehydrate_link_references (Boolean) (defaults to: false)

    If true, convert inline links to reference style. Default: false



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/markdown/merge/partial_template_merger.rb', line 71

def initialize(
  template:,
  destination:,
  anchor:,
  boundary: nil,
  backend: self.class.default_backend,
  preference: :template,
  add_missing: true,
  when_missing: :skip,
  replace_mode: false,
  signature_generator: nil,
  node_typing: nil,
  match_refiner: nil,
  normalize_whitespace: false,
  rehydrate_link_references: false
)
  validate_backend!(backend)
  @backend = backend
  @normalize_whitespace = normalize_whitespace
  @rehydrate_link_references = rehydrate_link_references
  super(
    template: template,
    destination: destination,
    anchor: anchor,
    boundary: boundary,
    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

#backendSymbol (readonly)

Returns Backend to use (:markly, :commonmarker).

Returns:

  • (Symbol)

    Backend to use (:markly, :commonmarker)



53
54
55
# File 'lib/markdown/merge/partial_template_merger.rb', line 53

def backend
  @backend
end

Class Method Details

.default_backendObject



39
40
41
# File 'lib/markdown/merge/partial_template_merger.rb', line 39

def default_backend
  :markly
end

.file_analysis_classObject



43
44
45
# File 'lib/markdown/merge/partial_template_merger.rb', line 43

def file_analysis_class
  FileAnalysis
end

.smart_merger_classObject



47
48
49
# File 'lib/markdown/merge/partial_template_merger.rb', line 47

def smart_merger_class
  SmartMerger
end

Instance Method Details

#mergeResult

Perform the partial template merge with post-processing.

Returns:

  • (Result)

    The merge result



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/markdown/merge/partial_template_merger.rb', line 109

def merge
  result = super

  # Apply post-processing if enabled
  if result.changed && (@normalize_whitespace || @rehydrate_link_references)
    content = result.content
    problems = DocumentProblems.new

    if @normalize_whitespace
      normalizer = WhitespaceNormalizer.new(content)
      content = normalizer.normalize
      problems.merge!(normalizer.problems)
    end

    if @rehydrate_link_references
      rehydrator = LinkReferenceRehydrator.new(content)
      content = rehydrator.rehydrate
      problems.merge!(rehydrator.problems)
    end

    # Return new result with transformed content and problems
    Result.new(
      content: content,
      has_section: result.has_section,
      changed: result.changed,
      stats: result.stats.merge(problems: problems.all),
      injection_point: result.injection_point,
      message: result.message
    )
  else
    result
  end
end