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
@@ -1,4 +1,9 @@
1
- # For technical reasons, if we move to Zeitwerk, this cannot be require_relative.
2
- # See: https://github.com/fxn/zeitwerk#for_gem_extension
3
- # Hook for other libraries to load this library (e.g. via bundler)
4
- require "markdown/merge"
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'markdown/merge'
4
+ require 'version_gem'
5
+ require_relative 'markdown/merge/version'
6
+
7
+ Markdown::Merge::Version.class_eval do
8
+ extend VersionGem::Basic
9
+ end
@@ -1,341 +1,8 @@
1
1
  module Markdown
2
2
  module Merge
3
- VERSION: String
4
-
5
- # Base error class for Markdown::Merge
6
- class Error < Ast::Merge::Error
7
- end
8
-
9
- # Raised when a Markdown file has parsing errors
10
- class ParseError < Ast::Merge::ParseError
11
- def initialize: (?String? message, ?content: String?, ?errors: Array[untyped]) -> void
12
- end
13
-
14
- # Raised when the template file has syntax errors
15
- class TemplateParseError < ParseError
16
- end
17
-
18
- # Raised when the destination file has syntax errors
19
- class DestinationParseError < ParseError
20
- end
21
-
22
- # Debug logging utility for Markdown::Merge operations
23
- module DebugLogger
24
- extend Ast::Merge::DebugLogger
25
-
26
- def self.env_var_name: () -> String
27
- def self.env_var_name=: (String name) -> String
28
- def self.log_prefix: () -> String
29
- def self.log_prefix=: (String prefix) -> String
30
- def self.enabled?: () -> bool
31
- def self.debug: (*untyped args) -> void
32
- def self.info: (*untyped args) -> void
33
- def self.warning: (*untyped args) -> void
34
- def self.time: [T] (String label) { () -> T } -> T
35
- def self.log_node: (untyped node, ?label: String) -> void
36
- end
37
-
38
- # Represents a frozen block of Markdown content
39
- class FreezeNode < Ast::Merge::FreezeNodeBase
40
- def initialize: (
41
- start_line: Integer,
42
- end_line: Integer,
43
- content: String,
44
- start_marker: String,
45
- end_marker: String,
46
- ?nodes: Array[untyped],
47
- ?reason: String?
48
- ) -> void
49
-
50
- def signature: () -> Array[Symbol | String]
51
- def full_text: () -> String
52
- def line_count: () -> Integer
53
- def contains_type?: (Symbol type_symbol) -> bool
54
- def inspect: () -> String
55
- end
56
-
57
- # Base class for file analysis for Markdown files
58
- class FileAnalysisBase
59
- include Ast::Merge::FileAnalyzable
60
-
61
- DEFAULT_FREEZE_TOKEN: String
62
-
63
- attr_reader document: untyped
64
- attr_reader statements: Array[untyped]
65
-
66
- def initialize: (
67
- String source,
68
- ?freeze_token: String,
69
- ?signature_generator: (^(untyped) -> (Array[untyped] | untyped | nil))?,
70
- **untyped parser_options
71
- ) -> void
72
-
73
- # Abstract methods - subclasses must implement
74
- def parse_document: (String source) -> untyped
75
- def next_sibling: (untyped node) -> untyped?
76
-
77
- def valid?: () -> bool
78
- def compute_node_signature: (untyped node) -> Array[untyped]?
79
- def fallthrough_node?: (untyped value) -> bool
80
- def parser_node?: (untyped value) -> bool
81
- def compute_parser_signature: (untyped node) -> Array[untyped]?
82
- def safe_string_content: (untyped node) -> String
83
- def extract_text_content: (untyped node) -> String
84
- def extract_table_header_content: (untyped node) -> String
85
- def source_range: (Integer start_line, Integer end_line) -> String
86
- def count_children: (untyped node) -> Integer
87
-
88
- private
89
-
90
- def extract_and_integrate_all_nodes: () -> Array[untyped]
91
- def collect_top_level_nodes: () -> Array[untyped]
92
- def build_freeze_blocks: (Array[untyped] nodes) -> Array[FreezeNode]
93
- def integrate_freeze_blocks: (Array[untyped] nodes, Array[FreezeNode] freeze_blocks) -> Array[untyped]
94
- end
95
-
96
- # Aligns Markdown block elements between template and destination files
97
- class FileAligner
98
- attr_reader template_analysis: FileAnalysisBase
99
- attr_reader dest_analysis: FileAnalysisBase
100
- attr_reader match_refiner: (^(Array[untyped], Array[untyped], Hash[Symbol, untyped]) -> Array[MatchResult])?
101
-
102
- def initialize: (
103
- FileAnalysisBase template_analysis,
104
- FileAnalysisBase dest_analysis,
105
- ?match_refiner: (^(Array[untyped], Array[untyped], Hash[Symbol, untyped]) -> Array[MatchResult])?
106
- ) -> void
107
-
108
- def align: () -> Array[Hash[Symbol, untyped]]
109
-
110
- private
111
-
112
- def build_signature_map: (Array[untyped] statements, FileAnalysisBase analysis) -> Hash[Array[untyped], Array[Integer]]
113
- end
114
-
115
- # Match result from refiners
116
- class MatchResult
117
- attr_reader template_node: untyped
118
- attr_reader dest_node: untyped
119
- attr_reader score: Float
120
-
121
- def initialize: (
122
- template_node: untyped,
123
- dest_node: untyped,
124
- score: Float
125
- ) -> void
126
- end
127
-
128
- # Resolves conflicts between matching Markdown elements
129
- class ConflictResolver < Ast::Merge::ConflictResolverBase
130
- def initialize: (
131
- preference: Symbol,
132
- template_analysis: FileAnalysisBase,
133
- dest_analysis: FileAnalysisBase
134
- ) -> void
135
-
136
- private
137
-
138
- def resolve_node_pair: (
139
- untyped template_node,
140
- untyped dest_node,
141
- template_index: Integer,
142
- dest_index: Integer
143
- ) -> Hash[Symbol, untyped]
144
-
145
- def content_identical?: (untyped template_node, untyped dest_node) -> bool
146
- def node_to_text: (untyped node, FileAnalysisBase analysis) -> String
147
- end
148
-
149
- # Represents the result of a Markdown merge operation
150
- class MergeResult < Ast::Merge::MergeResultBase
151
- def initialize: (
152
- content: String?,
153
- ?conflicts: Array[Hash[Symbol, untyped]],
154
- ?frozen_blocks: Array[Hash[Symbol, untyped]],
155
- ?stats: Hash[Symbol, untyped]
156
- ) -> void
157
-
158
- def content: () -> String?
159
- def content?: () -> bool
160
- def content_string: () -> String?
161
- def success?: () -> bool
162
- def conflicts?: () -> bool
163
- def has_frozen_blocks?: () -> bool
164
- def nodes_added: () -> Integer
165
- def nodes_removed: () -> Integer
166
- def nodes_modified: () -> Integer
167
- def merge_time_ms: () -> Float?
168
- def frozen_count: () -> Integer
169
- def inspect: () -> String
170
- def to_s: () -> String
171
-
172
- private
173
-
174
- def default_stats: () -> Hash[Symbol, untyped]
175
- end
176
-
177
- # Algorithm for computing match scores between two Markdown tables
178
- class TableMatchAlgorithm
179
- DEFAULT_WEIGHTS: Hash[Symbol, Float]
180
- FIRST_COLUMN_SIMILARITY_THRESHOLD: Float
181
-
182
- attr_reader position_a: Integer?
183
- attr_reader position_b: Integer?
184
- attr_reader total_tables_a: Integer
185
- attr_reader total_tables_b: Integer
186
- attr_reader weights: Hash[Symbol, Float]
187
-
188
- def initialize: (
189
- ?position_a: Integer?,
190
- ?position_b: Integer?,
191
- ?total_tables_a: Integer,
192
- ?total_tables_b: Integer,
193
- ?weights: Hash[Symbol, Float]
194
- ) -> void
195
-
196
- def call: (untyped table_a, untyped table_b) -> Float
197
-
198
- private
199
-
200
- def levenshtein_distance: (String a, String b) -> Integer
201
- def levenshtein_similarity: (String a, String b) -> Float
202
- def extract_rows: (untyped table) -> Array[Array[String]]
203
- def extract_cell_text: (untyped cell) -> String
204
- def compute_header_match: (Array[Array[String]] rows_a, Array[Array[String]] rows_b) -> Float
205
- def compute_first_column_match: (Array[Array[String]] rows_a, Array[Array[String]] rows_b) -> Float
206
- def compute_row_content_match: (Array[Array[String]] rows_a, Array[Array[String]] rows_b) -> Float
207
- def compute_total_cells_match: (Array[Array[String]] rows_a, Array[Array[String]] rows_b) -> Float
208
- def compute_position_score: () -> Float
209
- def weighted_average: (Hash[Symbol, Float] scores) -> Float
210
- end
211
-
212
- # Match refiner for Markdown tables that didn't match by exact signature
213
- class TableMatchRefiner < Ast::Merge::MatchRefinerBase
214
- attr_reader algorithm_options: Hash[Symbol, untyped]
215
-
216
- def initialize: (
217
- ?threshold: Float,
218
- ?algorithm_options: Hash[Symbol, untyped],
219
- **untyped options
220
- ) -> void
221
-
222
- def call: (
223
- Array[untyped] template_nodes,
224
- Array[untyped] dest_nodes,
225
- ?Hash[Symbol, untyped] context
226
- ) -> Array[MatchResult]
227
-
228
- private
229
-
230
- def extract_tables: (Array[untyped] nodes) -> Array[untyped]
231
- def table_node?: (untyped node) -> bool
232
- def compute_table_similarity: (
233
- untyped t_table,
234
- untyped d_table,
235
- Integer t_idx,
236
- Integer d_idx,
237
- Integer total_t,
238
- Integer total_d
239
- ) -> Float
240
- end
241
-
242
- # Merges fenced code blocks using language-specific *-merge gems
243
- class CodeBlockMerger
244
- DEFAULT_MERGERS: Hash[String, ^(String, String, Symbol, **untyped) -> Hash[Symbol, untyped]]
245
-
246
- attr_reader mergers: Hash[String, ^(String, String, Symbol, **untyped) -> Hash[Symbol, untyped]]
247
- attr_reader enabled: bool
248
-
249
- def initialize: (
250
- ?mergers: Hash[String, ^(String, String, Symbol, **untyped) -> Hash[Symbol, untyped]],
251
- ?enabled: bool
252
- ) -> void
253
-
254
- def supports_language?: (String? language) -> bool
255
- def merge_code_blocks: (
256
- untyped template_node,
257
- untyped dest_node,
258
- preference: Symbol,
259
- **untyped opts
260
- ) -> Hash[Symbol, untyped]
261
-
262
- # Class methods for specific mergers
263
- def self.merge_with_prism: (String template, String dest, Symbol preference, **untyped opts) -> Hash[Symbol, untyped]
264
- def self.merge_with_psych: (String template, String dest, Symbol preference, **untyped opts) -> Hash[Symbol, untyped]
265
- def self.merge_with_json: (String template, String dest, Symbol preference, **untyped opts) -> Hash[Symbol, untyped]
266
- def self.merge_with_toml: (String template, String dest, Symbol preference, **untyped opts) -> Hash[Symbol, untyped]
267
-
268
- private
269
-
270
- def extract_language: (untyped node) -> String?
271
- def extract_content: (untyped node) -> String
272
- def rebuild_code_block: (String language, String content, untyped reference_node) -> String
273
- def not_merged: (String reason) -> Hash[Symbol, untyped]
274
- end
275
-
276
- # Builds markdown output from merge operations
277
- class OutputBuilder
278
- @parts: Array[String]
279
- @preserve_formatting: bool
280
-
281
- def initialize: (?preserve_formatting: bool) -> void
282
- def add_node_source: (untyped node, FileAnalysisBase analysis) -> void
283
- def add_link_definition: (LinkDefinitionNode node) -> void
284
- def add_gap_line: (?count: Integer) -> void
285
- def add_raw: (String text) -> void
286
- def to_s: () -> String
287
- def empty?: () -> bool
288
- def clear: () -> void
289
-
290
- private
291
-
292
- def extract_source: (untyped node, FileAnalysisBase analysis) -> String?
293
- def extract_parser_node_source: (untyped node, FileAnalysisBase analysis) -> String?
294
- end
295
-
296
- # Formats link reference definitions for output
297
- module LinkDefinitionFormatter
298
- def self.format: (LinkDefinitionNode node) -> String
299
- def self.format_all: (Array[LinkDefinitionNode] nodes, ?separator: String) -> String
300
- end
301
-
302
- # Base class for smart Markdown file merging
303
- class SmartMergerBase
304
- attr_reader template_analysis: FileAnalysisBase
305
- attr_reader dest_analysis: FileAnalysisBase
306
- attr_reader aligner: FileAligner
307
- attr_reader resolver: ConflictResolver
308
- attr_reader code_block_merger: CodeBlockMerger?
309
-
310
- def initialize: (
311
- String template_content,
312
- String dest_content,
313
- ?signature_generator: (^(untyped) -> (Array[untyped] | untyped | nil))?,
314
- ?preference: Symbol,
315
- ?add_template_only_nodes: bool,
316
- ?inner_merge_code_blocks: (bool | CodeBlockMerger),
317
- ?freeze_token: String,
318
- ?match_refiner: (^(Array[untyped], Array[untyped], Hash[Symbol, untyped]) -> Array[MatchResult])?,
319
- **untyped parser_options
320
- ) -> void
321
-
322
- # Abstract methods - subclasses must implement
323
- def create_file_analysis: (String content, **untyped options) -> FileAnalysisBase
324
- def node_to_source: (untyped node, FileAnalysisBase analysis) -> String
325
-
326
- def template_parse_error_class: () -> Class
327
- def destination_parse_error_class: () -> Class
328
-
329
- def merge: () -> String
330
- def merge_result: () -> MergeResult
331
-
332
- private
333
-
334
- def build_result_content: (Array[Hash[Symbol, untyped]] alignment) -> String
335
- def process_alignment_entry: (Hash[Symbol, untyped] entry) -> String?
336
- def handle_match: (Hash[Symbol, untyped] entry) -> String?
337
- def handle_template_only: (Hash[Symbol, untyped] entry) -> String?
338
- def handle_dest_only: (Hash[Symbol, untyped] entry) -> String?
3
+ module Version
4
+ VERSION: String
339
5
  end
6
+ VERSION: String
340
7
  end
341
8
  end
data.tar.gz.sig CHANGED
Binary file