Class: Markdown::Merge::SmartMergerBase Abstract
- Inherits:
-
Object
- Object
- Markdown::Merge::SmartMergerBase
- Defined in:
- lib/markdown/merge/smart_merger_base.rb
Overview
Subclass and implement parser-specific methods
Base class for smart Markdown file merging.
Orchestrates the smart merge process for Markdown files using FileAnalysisBase, FileAligner, ConflictResolver, and MergeResult to merge two Markdown files intelligently. Freeze blocks marked with HTML comments are preserved exactly as-is.
Subclasses must implement:
-
#create_file_analysis(content, **options) - Create parser-specific FileAnalysis
-
#node_to_source(node, analysis) - Convert a node to source text
SmartMergerBase provides flexible configuration for different merge scenarios:
-
Preserve destination customizations (default)
-
Apply template updates
-
Add new sections from template
-
Inner-merge fenced code blocks using language-specific mergers (optional)
Direct Known Subclasses
Instance Attribute Summary collapse
-
#aligner ⇒ FileAligner
readonly
Aligner for finding matches and differences.
-
#code_block_merger ⇒ CodeBlockMerger?
readonly
Merger for fenced code blocks.
-
#dest_analysis ⇒ FileAnalysisBase
readonly
Analysis of the destination file.
-
#node_typing ⇒ Hash{Symbol,String => #call}?
readonly
Node typing configuration.
-
#resolver ⇒ ConflictResolver
readonly
Resolver for handling conflicting content.
-
#template_analysis ⇒ FileAnalysisBase
readonly
Analysis of the template file.
Instance Method Summary collapse
-
#create_file_analysis(content, **options) ⇒ FileAnalysisBase
abstract
Create a FileAnalysis instance for the given content.
-
#destination_parse_error_class ⇒ Class
Returns the DestinationParseError class to use.
-
#initialize(template_content, dest_content, signature_generator: nil, preference: :destination, add_template_only_nodes: false, inner_merge_code_blocks: false, freeze_token: FileAnalysisBase::DEFAULT_FREEZE_TOKEN, match_refiner: nil, node_typing: nil, normalize_whitespace: false, rehydrate_link_references: false, **parser_options) ⇒ SmartMergerBase
constructor
Creates a new SmartMerger for intelligent Markdown file merging.
-
#merge ⇒ String
Perform the merge operation and return the merged content as a string.
-
#merge_result ⇒ MergeResult
Perform the merge operation and return the full MergeResult object.
-
#stats ⇒ Hash
Get merge statistics (convenience method).
-
#template_parse_error_class ⇒ Class
Returns the TemplateParseError class to use.
Constructor Details
#initialize(template_content, dest_content, signature_generator: nil, preference: :destination, add_template_only_nodes: false, inner_merge_code_blocks: false, freeze_token: FileAnalysisBase::DEFAULT_FREEZE_TOKEN, match_refiner: nil, node_typing: nil, normalize_whitespace: false, rehydrate_link_references: false, **parser_options) ⇒ SmartMergerBase
Creates a new SmartMerger for intelligent Markdown file merging.
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 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 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/markdown/merge/smart_merger_base.rb', line 135 def initialize( template_content, dest_content, signature_generator: nil, preference: :destination, add_template_only_nodes: false, inner_merge_code_blocks: false, freeze_token: FileAnalysisBase::DEFAULT_FREEZE_TOKEN, match_refiner: nil, node_typing: nil, normalize_whitespace: false, rehydrate_link_references: false, ** ) @preference = preference @add_template_only_nodes = add_template_only_nodes @match_refiner = match_refiner @node_typing = node_typing @normalize_whitespace = normalize_whitespace @rehydrate_link_references = rehydrate_link_references # Validate node_typing if provided Ast::Merge::NodeTyping.validate!(node_typing) if node_typing # Set up code block merger @code_block_merger = case inner_merge_code_blocks when true CodeBlockMerger.new when false nil when CodeBlockMerger inner_merge_code_blocks else raise ArgumentError, "inner_merge_code_blocks must be true, false, or a CodeBlockMerger instance" end # Parse template begin @template_analysis = create_file_analysis( template_content, freeze_token: freeze_token, signature_generator: signature_generator, **, ) rescue StandardError => e raise template_parse_error_class.new(errors: [e]) end # Parse destination begin @dest_analysis = create_file_analysis( dest_content, freeze_token: freeze_token, signature_generator: signature_generator, **, ) rescue StandardError => e raise destination_parse_error_class.new(errors: [e]) end @aligner = FileAligner.new(@template_analysis, @dest_analysis, match_refiner: @match_refiner) @resolver = ConflictResolver.new( preference: @preference, template_analysis: @template_analysis, dest_analysis: @dest_analysis, ) end |
Instance Attribute Details
#aligner ⇒ FileAligner (readonly)
Returns Aligner for finding matches and differences.
51 52 53 |
# File 'lib/markdown/merge/smart_merger_base.rb', line 51 def aligner @aligner end |
#code_block_merger ⇒ CodeBlockMerger? (readonly)
Returns Merger for fenced code blocks.
57 58 59 |
# File 'lib/markdown/merge/smart_merger_base.rb', line 57 def code_block_merger @code_block_merger end |
#dest_analysis ⇒ FileAnalysisBase (readonly)
Returns Analysis of the destination file.
48 49 50 |
# File 'lib/markdown/merge/smart_merger_base.rb', line 48 def dest_analysis @dest_analysis end |
#node_typing ⇒ Hash{Symbol,String => #call}? (readonly)
Returns Node typing configuration.
60 61 62 |
# File 'lib/markdown/merge/smart_merger_base.rb', line 60 def node_typing @node_typing end |
#resolver ⇒ ConflictResolver (readonly)
Returns Resolver for handling conflicting content.
54 55 56 |
# File 'lib/markdown/merge/smart_merger_base.rb', line 54 def resolver @resolver end |
#template_analysis ⇒ FileAnalysisBase (readonly)
Returns Analysis of the template file.
45 46 47 |
# File 'lib/markdown/merge/smart_merger_base.rb', line 45 def template_analysis @template_analysis end |
Instance Method Details
#create_file_analysis(content, **options) ⇒ FileAnalysisBase
Subclasses must implement this method
Create a FileAnalysis instance for the given content.
209 210 211 |
# File 'lib/markdown/merge/smart_merger_base.rb', line 209 def create_file_analysis(content, **) raise NotImplementedError, "#{self.class} must implement #create_file_analysis" end |
#destination_parse_error_class ⇒ Class
Returns the DestinationParseError class to use.
Subclasses should override to return their parser-specific error class.
227 228 229 |
# File 'lib/markdown/merge/smart_merger_base.rb', line 227 def destination_parse_error_class DestinationParseError end |
#merge ⇒ String
Perform the merge operation and return the merged content as a string.
234 235 236 |
# File 'lib/markdown/merge/smart_merger_base.rb', line 234 def merge merge_result.content end |
#merge_result ⇒ MergeResult
Perform the merge operation and return the full MergeResult object.
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 |
# File 'lib/markdown/merge/smart_merger_base.rb', line 241 def merge_result return @merge_result if @merge_result @merge_result = DebugLogger.time("SmartMergerBase#merge") do alignment = DebugLogger.time("SmartMergerBase#align") do @aligner.align end DebugLogger.debug("Alignment complete", { total_entries: alignment.size, matches: alignment.count { |e| e[:type] == :match }, template_only: alignment.count { |e| e[:type] == :template_only }, dest_only: alignment.count { |e| e[:type] == :dest_only }, }) # Process alignment using OutputBuilder builder, stats, frozen_blocks, conflicts = DebugLogger.time("SmartMergerBase#process") do process_alignment(alignment) end # Get content from OutputBuilder content = builder.to_s # Collect problems from post-processing problems = DocumentProblems.new # Apply post-processing transformations content, problems = apply_post_processing(content, problems) # Get final content from OutputBuilder MergeResult.new( content: content, conflicts: conflicts, frozen_blocks: frozen_blocks, stats: stats, problems: problems, ) end end |
#stats ⇒ Hash
Get merge statistics (convenience method).
284 285 286 |
# File 'lib/markdown/merge/smart_merger_base.rb', line 284 def stats merge_result.stats end |
#template_parse_error_class ⇒ Class
Returns the TemplateParseError class to use.
Subclasses should override to return their parser-specific error class.
218 219 220 |
# File 'lib/markdown/merge/smart_merger_base.rb', line 218 def template_parse_error_class TemplateParseError end |