Class: Markdown::Merge::SmartMerger
- Inherits:
-
SmartMergerBase
- Object
- SmartMergerBase
- Markdown::Merge::SmartMerger
- Defined in:
- lib/markdown/merge/smart_merger.rb
Overview
Orchestrates the smart merge process for Markdown files using tree_haver backends.
Extends SmartMergerBase with backend-agnostic parsing via tree_haver. Supports both Commonmarker and Markly backends.
Uses FileAnalysis, FileAligner, ConflictResolver, and MergeResult to merge two Markdown files intelligently. Freeze blocks marked with HTML comments are preserved exactly as-is.
SmartMerger 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)
Constant Summary collapse
- VALID_BACKENDS =
%i[auto commonmarker markly kramdown].freeze
Instance Attribute Summary collapse
-
#backend ⇒ Symbol
readonly
The backend being used (:commonmarker, :markly).
Attributes inherited from SmartMergerBase
#aligner, #code_block_merger, #corruption_handling, #dest_analysis, #node_typing, #resolution_mode, #resolver, #runtime_session, #template_analysis, #unresolved_policy
Class Method Summary collapse
- .default_backend ⇒ Object
- .default_freeze_token ⇒ Object
- .default_inner_merge_code_blocks ⇒ Object
- .default_parser_options ⇒ Object
- .destination_parse_error_class ⇒ Object
- .file_analysis_class ⇒ Object
- .template_parse_error_class ⇒ Object
Instance Method Summary collapse
-
#create_file_analysis(content, **opts) ⇒ FileAnalysis
Create a FileAnalysis instance for parsing.
-
#destination_parse_error_class ⇒ Class
Returns the DestinationParseError class to use.
-
#initialize(template_content, dest_content, backend: self.class.default_backend, signature_generator: nil, preference: :destination, add_template_only_nodes: false, inner_merge_code_blocks: self.class.default_inner_merge_code_blocks, inner_merge_lists: false, remove_template_missing_nodes: false, freeze_token: self.class.default_freeze_token, match_refiner: nil, node_typing: nil, **parser_options) ⇒ SmartMerger
constructor
Creates a new SmartMerger for intelligent Markdown file merging.
-
#node_to_source(node, analysis) ⇒ String
Convert a node to its source text.
-
#template_parse_error_class ⇒ Class
Returns the TemplateParseError class to use.
Methods inherited from SmartMergerBase
#default_match_refiner, #merge, #merge_result, #merge_with_debug, #stats
Constructor Details
#initialize(template_content, dest_content, backend: self.class.default_backend, signature_generator: nil, preference: :destination, add_template_only_nodes: false, inner_merge_code_blocks: self.class.default_inner_merge_code_blocks, inner_merge_lists: false, remove_template_missing_nodes: false, freeze_token: self.class.default_freeze_token, match_refiner: nil, node_typing: nil, **parser_options) ⇒ SmartMerger
Creates a new SmartMerger for intelligent Markdown file merging.
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 |
# File 'lib/markdown/merge/smart_merger.rb', line 151 def initialize( template_content, dest_content, backend: self.class.default_backend, signature_generator: nil, preference: :destination, add_template_only_nodes: false, inner_merge_code_blocks: self.class.default_inner_merge_code_blocks, inner_merge_lists: false, remove_template_missing_nodes: false, freeze_token: self.class.default_freeze_token, match_refiner: nil, node_typing: nil, ** ) validate_backend!(backend) @requested_backend = backend @parser_options = self.class..merge() super( template_content, dest_content, signature_generator: signature_generator, preference: preference, add_template_only_nodes: add_template_only_nodes, inner_merge_code_blocks: inner_merge_code_blocks, inner_merge_lists: inner_merge_lists, remove_template_missing_nodes: remove_template_missing_nodes, freeze_token: freeze_token, match_refiner: match_refiner, node_typing: node_typing, # Pass through for FileAnalysis backend: backend, **, ) # Capture the resolved backend from template analysis @backend = @template_analysis.backend end |
Instance Attribute Details
#backend ⇒ Symbol (readonly)
Returns The backend being used (:commonmarker, :markly).
95 96 97 |
# File 'lib/markdown/merge/smart_merger.rb', line 95 def backend @backend end |
Class Method Details
.default_backend ⇒ Object
65 66 67 |
# File 'lib/markdown/merge/smart_merger.rb', line 65 def default_backend :auto end |
.default_freeze_token ⇒ Object
69 70 71 |
# File 'lib/markdown/merge/smart_merger.rb', line 69 def default_freeze_token FileAnalysis::DEFAULT_FREEZE_TOKEN end |
.default_inner_merge_code_blocks ⇒ Object
73 74 75 |
# File 'lib/markdown/merge/smart_merger.rb', line 73 def default_inner_merge_code_blocks false end |
.default_parser_options ⇒ Object
77 78 79 |
# File 'lib/markdown/merge/smart_merger.rb', line 77 def {} end |
.destination_parse_error_class ⇒ Object
89 90 91 |
# File 'lib/markdown/merge/smart_merger.rb', line 89 def destination_parse_error_class DestinationParseError end |
.file_analysis_class ⇒ Object
81 82 83 |
# File 'lib/markdown/merge/smart_merger.rb', line 81 def file_analysis_class FileAnalysis end |
.template_parse_error_class ⇒ Object
85 86 87 |
# File 'lib/markdown/merge/smart_merger.rb', line 85 def template_parse_error_class TemplateParseError end |
Instance Method Details
#create_file_analysis(content, **opts) ⇒ FileAnalysis
Create a FileAnalysis instance for parsing.
197 198 199 200 201 202 203 204 205 |
# File 'lib/markdown/merge/smart_merger.rb', line 197 def create_file_analysis(content, **opts) self.class.file_analysis_class.new( content, backend: opts[:backend] || @requested_backend, freeze_token: opts[:freeze_token], signature_generator: opts[:signature_generator], **@parser_options ) end |
#destination_parse_error_class ⇒ Class
Returns the DestinationParseError class to use.
217 218 219 |
# File 'lib/markdown/merge/smart_merger.rb', line 217 def destination_parse_error_class self.class.destination_parse_error_class end |
#node_to_source(node, analysis) ⇒ String
Convert a node to its source text.
Handles wrapped nodes from NodeTypeNormalizer, gap line nodes, and link definition nodes created during gap detection.
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/markdown/merge/smart_merger.rb', line 229 def node_to_source(node, analysis) # Check for any FreezeNode type (base class or subclass) return node.full_text if node.is_a?(Ast::Merge::FreezeNodeBase) # Handle gap line nodes (created for blank lines and link definitions) return node.content if node.is_a?(LinkDefinitionNode) || node.is_a?(GapLineNode) # Unwrap if needed to access source_position raw_node = Ast::Merge::NodeTyping.unwrap(node) pos = raw_node.source_position start_line = pos&.dig(:start_line) end_line = pos&.dig(:end_line) # Fall back to to_commonmark if no position info return raw_node.to_commonmark unless start_line && end_line # Get source from line range source = analysis.source_range(start_line, end_line) # Handle Markly's buggy position reporting for :html nodes # where end_line < start_line results in empty source_range. # Fall back to to_commonmark in that case. if source.empty? && raw_node.respond_to?(:to_commonmark) raw_node.to_commonmark.chomp else source end end |
#template_parse_error_class ⇒ Class
Returns the TemplateParseError class to use.
210 211 212 |
# File 'lib/markdown/merge/smart_merger.rb', line 210 def template_parse_error_class self.class.template_parse_error_class end |