markdown-merge 1.0.3 → 7.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/LICENSE.md +13 -0
  4. data/README.md +99 -482
  5. data/lib/markdown/merge/backend_support.rb +200 -0
  6. data/lib/markdown/merge/cleanse/block_spacing.rb +18 -23
  7. data/lib/markdown/merge/cleanse/code_fence_spacing.rb +16 -16
  8. data/lib/markdown/merge/cleanse/condensed_link_refs.rb +36 -30
  9. data/lib/markdown/merge/cleanse/list_marker_duplication.rb +66 -0
  10. data/lib/markdown/merge/cleanse/templating_corruption.rb +86 -0
  11. data/lib/markdown/merge/cleanse.rb +5 -3
  12. data/lib/markdown/merge/code_block_match_refiner.rb +111 -0
  13. data/lib/markdown/merge/code_block_merger.rb +489 -47
  14. data/lib/markdown/merge/comment_tracker.rb +42 -0
  15. data/lib/markdown/merge/conflict_resolver.rb +77 -6
  16. data/lib/markdown/merge/debug_logger.rb +2 -2
  17. data/lib/markdown/merge/document_problems.rb +3 -3
  18. data/lib/markdown/merge/file_aligner.rb +433 -133
  19. data/lib/markdown/merge/file_analysis.rb +387 -51
  20. data/lib/markdown/merge/file_analysis_base.rb +188 -51
  21. data/lib/markdown/merge/gap_line_node.rb +14 -8
  22. data/lib/markdown/merge/link_definition_node.rb +5 -5
  23. data/lib/markdown/merge/link_parser.rb +60 -60
  24. data/lib/markdown/merge/link_reference_rehydrator.rb +14 -14
  25. data/lib/markdown/merge/list_match_refiner.rb +98 -0
  26. data/lib/markdown/merge/list_merger.rb +322 -0
  27. data/lib/markdown/merge/markdown_structure.rb +3 -3
  28. data/lib/markdown/merge/merge_result.rb +321 -4
  29. data/lib/markdown/merge/node_type_normalizer.rb +6 -6
  30. data/lib/markdown/merge/output_builder.rb +101 -19
  31. data/lib/markdown/merge/partial_template_merger.rb +248 -27
  32. data/lib/markdown/merge/preservation_support.rb +291 -0
  33. data/lib/markdown/merge/smart_merger.rb +62 -14
  34. data/lib/markdown/merge/smart_merger_base.rb +929 -60
  35. data/lib/markdown/merge/table_match_algorithm.rb +22 -27
  36. data/lib/markdown/merge/table_match_refiner.rb +6 -10
  37. data/lib/markdown/merge/version.rb +5 -4
  38. data/lib/markdown/merge/whitespace_normalizer.rb +25 -33
  39. data/lib/markdown/merge/wrapper_support.rb +194 -0
  40. data/lib/markdown/merge.rb +669 -122
  41. data/lib/markdown-merge.rb +9 -4
  42. data/sig/markdown/merge.rbs +3 -336
  43. data.tar.gz.sig +0 -0
  44. metadata +104 -93
  45. metadata.gz.sig +0 -0
  46. data/CHANGELOG.md +0 -308
  47. data/CITATION.cff +0 -20
  48. data/CODE_OF_CONDUCT.md +0 -134
  49. data/CONTRIBUTING.md +0 -227
  50. data/FUNDING.md +0 -74
  51. data/LICENSE.txt +0 -21
  52. data/REEK +0 -0
  53. data/RUBOCOP.md +0 -71
  54. data/SECURITY.md +0 -21
@@ -59,6 +59,38 @@ module Markdown
59
59
  # @see FileAnalysis
60
60
  # @see SmartMergerBase
61
61
  class SmartMerger < SmartMergerBase
62
+ VALID_BACKENDS = %i[auto commonmarker markly kramdown].freeze
63
+
64
+ class << self
65
+ def default_backend
66
+ :auto
67
+ end
68
+
69
+ def default_freeze_token
70
+ FileAnalysis::DEFAULT_FREEZE_TOKEN
71
+ end
72
+
73
+ def default_inner_merge_code_blocks
74
+ false
75
+ end
76
+
77
+ def default_parser_options
78
+ {}
79
+ end
80
+
81
+ def file_analysis_class
82
+ FileAnalysis
83
+ end
84
+
85
+ def template_parse_error_class
86
+ TemplateParseError
87
+ end
88
+
89
+ def destination_parse_error_class
90
+ DestinationParseError
91
+ end
92
+ end
93
+
62
94
  # @return [Symbol] The backend being used (:commonmarker, :markly)
63
95
  attr_reader :backend
64
96
 
@@ -94,6 +126,11 @@ module Markdown
94
126
  # - `false` (default) - Disable inner-merge (use standard conflict resolution)
95
127
  # - `CodeBlockMerger` instance - Use custom CodeBlockMerger
96
128
  #
129
+ # @param remove_template_missing_nodes [Boolean] Controls whether destination-only
130
+ # structural nodes should be removed instead of preserved. Standalone HTML
131
+ # comment-only fragments, freeze blocks, and link reference definitions remain
132
+ # preserved when enabled.
133
+ #
97
134
  # @param freeze_token [String] Token to use for freeze block markers.
98
135
  # Default: "markdown-merge"
99
136
  # Looks for: <!-- markdown-merge:freeze --> / <!-- markdown-merge:unfreeze -->
@@ -114,18 +151,22 @@ module Markdown
114
151
  def initialize(
115
152
  template_content,
116
153
  dest_content,
117
- backend: :auto,
154
+ backend: self.class.default_backend,
118
155
  signature_generator: nil,
119
156
  preference: :destination,
120
157
  add_template_only_nodes: false,
121
- inner_merge_code_blocks: false,
122
- freeze_token: FileAnalysis::DEFAULT_FREEZE_TOKEN,
158
+ inner_merge_code_blocks: self.class.default_inner_merge_code_blocks,
159
+ inner_merge_lists: false,
160
+ remove_template_missing_nodes: false,
161
+ freeze_token: self.class.default_freeze_token,
123
162
  match_refiner: nil,
124
163
  node_typing: nil,
125
164
  **parser_options
126
165
  )
166
+ validate_backend!(backend)
167
+
127
168
  @requested_backend = backend
128
- @parser_options = parser_options
169
+ @parser_options = self.class.default_parser_options.merge(parser_options)
129
170
 
130
171
  super(
131
172
  template_content,
@@ -134,6 +175,8 @@ module Markdown
134
175
  preference: preference,
135
176
  add_template_only_nodes: add_template_only_nodes,
136
177
  inner_merge_code_blocks: inner_merge_code_blocks,
178
+ inner_merge_lists: inner_merge_lists,
179
+ remove_template_missing_nodes: remove_template_missing_nodes,
137
180
  freeze_token: freeze_token,
138
181
  match_refiner: match_refiner,
139
182
  node_typing: node_typing,
@@ -152,12 +195,12 @@ module Markdown
152
195
  # @param options [Hash] Analysis options
153
196
  # @return [FileAnalysis] File analysis instance
154
197
  def create_file_analysis(content, **opts)
155
- FileAnalysis.new(
198
+ self.class.file_analysis_class.new(
156
199
  content,
157
200
  backend: opts[:backend] || @requested_backend,
158
201
  freeze_token: opts[:freeze_token],
159
202
  signature_generator: opts[:signature_generator],
160
- **@parser_options,
203
+ **@parser_options
161
204
  )
162
205
  end
163
206
 
@@ -165,14 +208,14 @@ module Markdown
165
208
  #
166
209
  # @return [Class] Markdown::Merge::TemplateParseError
167
210
  def template_parse_error_class
168
- TemplateParseError
211
+ self.class.template_parse_error_class
169
212
  end
170
213
 
171
214
  # Returns the DestinationParseError class to use.
172
215
  #
173
216
  # @return [Class] Markdown::Merge::DestinationParseError
174
217
  def destination_parse_error_class
175
- DestinationParseError
218
+ self.class.destination_parse_error_class
176
219
  end
177
220
 
178
221
  # Convert a node to its source text.
@@ -185,14 +228,10 @@ module Markdown
185
228
  # @return [String] Source text
186
229
  def node_to_source(node, analysis)
187
230
  # Check for any FreezeNode type (base class or subclass)
188
- if node.is_a?(Ast::Merge::FreezeNodeBase)
189
- return node.full_text
190
- end
231
+ return node.full_text if node.is_a?(Ast::Merge::FreezeNodeBase)
191
232
 
192
233
  # Handle gap line nodes (created for blank lines and link definitions)
193
- if node.is_a?(LinkDefinitionNode) || node.is_a?(GapLineNode)
194
- return node.content
195
- end
234
+ return node.content if node.is_a?(LinkDefinitionNode) || node.is_a?(GapLineNode)
196
235
 
197
236
  # Unwrap if needed to access source_position
198
237
  raw_node = Ast::Merge::NodeTyping.unwrap(node)
@@ -216,6 +255,15 @@ module Markdown
216
255
  source
217
256
  end
218
257
  end
258
+
259
+ private
260
+
261
+ def validate_backend!(backend)
262
+ normalized_backend = backend.respond_to?(:to_sym) ? backend.to_sym : backend
263
+ return if VALID_BACKENDS.include?(normalized_backend)
264
+
265
+ raise ArgumentError, "Unknown backend: #{backend}"
266
+ end
219
267
  end
220
268
  end
221
269
  end