markdown-merge 1.0.2 → 7.0.0

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 (46) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/markdown/merge/version.rb +3 -4
  4. data/lib/markdown/merge.rb +538 -137
  5. data/lib/markdown-merge.rb +3 -4
  6. data.tar.gz.sig +0 -0
  7. metadata +28 -283
  8. metadata.gz.sig +0 -0
  9. data/CHANGELOG.md +0 -283
  10. data/CITATION.cff +0 -20
  11. data/CODE_OF_CONDUCT.md +0 -134
  12. data/CONTRIBUTING.md +0 -227
  13. data/FUNDING.md +0 -74
  14. data/LICENSE.txt +0 -21
  15. data/README.md +0 -1090
  16. data/REEK +0 -0
  17. data/RUBOCOP.md +0 -71
  18. data/SECURITY.md +0 -21
  19. data/lib/markdown/merge/cleanse/block_spacing.rb +0 -253
  20. data/lib/markdown/merge/cleanse/code_fence_spacing.rb +0 -294
  21. data/lib/markdown/merge/cleanse/condensed_link_refs.rb +0 -405
  22. data/lib/markdown/merge/cleanse.rb +0 -42
  23. data/lib/markdown/merge/code_block_merger.rb +0 -300
  24. data/lib/markdown/merge/conflict_resolver.rb +0 -128
  25. data/lib/markdown/merge/debug_logger.rb +0 -26
  26. data/lib/markdown/merge/document_problems.rb +0 -190
  27. data/lib/markdown/merge/file_aligner.rb +0 -196
  28. data/lib/markdown/merge/file_analysis.rb +0 -353
  29. data/lib/markdown/merge/file_analysis_base.rb +0 -629
  30. data/lib/markdown/merge/freeze_node.rb +0 -93
  31. data/lib/markdown/merge/gap_line_node.rb +0 -136
  32. data/lib/markdown/merge/link_definition_formatter.rb +0 -49
  33. data/lib/markdown/merge/link_definition_node.rb +0 -157
  34. data/lib/markdown/merge/link_parser.rb +0 -421
  35. data/lib/markdown/merge/link_reference_rehydrator.rb +0 -320
  36. data/lib/markdown/merge/markdown_structure.rb +0 -123
  37. data/lib/markdown/merge/merge_result.rb +0 -166
  38. data/lib/markdown/merge/node_type_normalizer.rb +0 -126
  39. data/lib/markdown/merge/output_builder.rb +0 -166
  40. data/lib/markdown/merge/partial_template_merger.rb +0 -334
  41. data/lib/markdown/merge/smart_merger.rb +0 -221
  42. data/lib/markdown/merge/smart_merger_base.rb +0 -621
  43. data/lib/markdown/merge/table_match_algorithm.rb +0 -504
  44. data/lib/markdown/merge/table_match_refiner.rb +0 -136
  45. data/lib/markdown/merge/whitespace_normalizer.rb +0 -251
  46. data/sig/markdown/merge.rbs +0 -341
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: markdown-merge
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 7.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
8
- bindir: exe
8
+ bindir: bin
9
9
  cert_chain:
10
10
  - |
11
11
  -----BEGIN CERTIFICATE-----
@@ -37,329 +37,74 @@ cert_chain:
37
37
  -----END CERTIFICATE-----
38
38
  date: 1980-01-02 00:00:00.000000000 Z
39
39
  dependencies:
40
- - !ruby/object:Gem::Dependency
41
- name: parslet
42
- requirement: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - "~>"
45
- - !ruby/object:Gem::Version
46
- version: '2.0'
47
- type: :runtime
48
- prerelease: false
49
- version_requirements: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - "~>"
52
- - !ruby/object:Gem::Version
53
- version: '2.0'
54
- - !ruby/object:Gem::Dependency
55
- name: tree_haver
56
- requirement: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - "~>"
59
- - !ruby/object:Gem::Version
60
- version: '5.0'
61
- - - ">="
62
- - !ruby/object:Gem::Version
63
- version: 5.0.3
64
- type: :runtime
65
- prerelease: false
66
- version_requirements: !ruby/object:Gem::Requirement
67
- requirements:
68
- - - "~>"
69
- - !ruby/object:Gem::Version
70
- version: '5.0'
71
- - - ">="
72
- - !ruby/object:Gem::Version
73
- version: 5.0.3
74
40
  - !ruby/object:Gem::Dependency
75
41
  name: ast-merge
76
42
  requirement: !ruby/object:Gem::Requirement
77
43
  requirements:
78
- - - "~>"
44
+ - - '='
79
45
  - !ruby/object:Gem::Version
80
- version: '4.0'
81
- - - ">="
82
- - !ruby/object:Gem::Version
83
- version: 4.0.5
46
+ version: 7.0.0
84
47
  type: :runtime
85
48
  prerelease: false
86
49
  version_requirements: !ruby/object:Gem::Requirement
87
50
  requirements:
88
- - - "~>"
89
- - !ruby/object:Gem::Version
90
- version: '4.0'
91
- - - ">="
51
+ - - '='
92
52
  - !ruby/object:Gem::Version
93
- version: 4.0.5
53
+ version: 7.0.0
94
54
  - !ruby/object:Gem::Dependency
95
- name: version_gem
55
+ name: tree_haver
96
56
  requirement: !ruby/object:Gem::Requirement
97
57
  requirements:
98
- - - "~>"
58
+ - - '='
99
59
  - !ruby/object:Gem::Version
100
- version: '1.1'
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: 1.1.9
60
+ version: 7.0.0
104
61
  type: :runtime
105
62
  prerelease: false
106
63
  version_requirements: !ruby/object:Gem::Requirement
107
64
  requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: '1.1'
111
- - - ">="
112
- - !ruby/object:Gem::Version
113
- version: 1.1.9
114
- - !ruby/object:Gem::Dependency
115
- name: kettle-dev
116
- requirement: !ruby/object:Gem::Requirement
117
- requirements:
118
- - - "~>"
119
- - !ruby/object:Gem::Version
120
- version: '1.1'
121
- type: :development
122
- prerelease: false
123
- version_requirements: !ruby/object:Gem::Requirement
124
- requirements:
125
- - - "~>"
126
- - !ruby/object:Gem::Version
127
- version: '1.1'
128
- - !ruby/object:Gem::Dependency
129
- name: bundler-audit
130
- requirement: !ruby/object:Gem::Requirement
131
- requirements:
132
- - - "~>"
133
- - !ruby/object:Gem::Version
134
- version: 0.9.2
135
- type: :development
136
- prerelease: false
137
- version_requirements: !ruby/object:Gem::Requirement
138
- requirements:
139
- - - "~>"
140
- - !ruby/object:Gem::Version
141
- version: 0.9.2
142
- - !ruby/object:Gem::Dependency
143
- name: rake
144
- requirement: !ruby/object:Gem::Requirement
145
- requirements:
146
- - - "~>"
147
- - !ruby/object:Gem::Version
148
- version: '13.0'
149
- type: :development
150
- prerelease: false
151
- version_requirements: !ruby/object:Gem::Requirement
152
- requirements:
153
- - - "~>"
154
- - !ruby/object:Gem::Version
155
- version: '13.0'
156
- - !ruby/object:Gem::Dependency
157
- name: require_bench
158
- requirement: !ruby/object:Gem::Requirement
159
- requirements:
160
- - - "~>"
161
- - !ruby/object:Gem::Version
162
- version: '1.0'
163
- - - ">="
164
- - !ruby/object:Gem::Version
165
- version: 1.0.4
166
- type: :development
167
- prerelease: false
168
- version_requirements: !ruby/object:Gem::Requirement
169
- requirements:
170
- - - "~>"
171
- - !ruby/object:Gem::Version
172
- version: '1.0'
173
- - - ">="
174
- - !ruby/object:Gem::Version
175
- version: 1.0.4
176
- - !ruby/object:Gem::Dependency
177
- name: appraisal2
178
- requirement: !ruby/object:Gem::Requirement
179
- requirements:
180
- - - "~>"
181
- - !ruby/object:Gem::Version
182
- version: '3.0'
183
- type: :development
184
- prerelease: false
185
- version_requirements: !ruby/object:Gem::Requirement
186
- requirements:
187
- - - "~>"
188
- - !ruby/object:Gem::Version
189
- version: '3.0'
190
- - !ruby/object:Gem::Dependency
191
- name: kettle-test
192
- requirement: !ruby/object:Gem::Requirement
193
- requirements:
194
- - - "~>"
195
- - !ruby/object:Gem::Version
196
- version: '1.0'
197
- - - ">="
198
- - !ruby/object:Gem::Version
199
- version: 1.0.6
200
- type: :development
201
- prerelease: false
202
- version_requirements: !ruby/object:Gem::Requirement
203
- requirements:
204
- - - "~>"
205
- - !ruby/object:Gem::Version
206
- version: '1.0'
207
- - - ">="
208
- - !ruby/object:Gem::Version
209
- version: 1.0.6
210
- - !ruby/object:Gem::Dependency
211
- name: ruby-progressbar
212
- requirement: !ruby/object:Gem::Requirement
213
- requirements:
214
- - - "~>"
215
- - !ruby/object:Gem::Version
216
- version: '1.13'
217
- type: :development
218
- prerelease: false
219
- version_requirements: !ruby/object:Gem::Requirement
220
- requirements:
221
- - - "~>"
222
- - !ruby/object:Gem::Version
223
- version: '1.13'
224
- - !ruby/object:Gem::Dependency
225
- name: stone_checksums
226
- requirement: !ruby/object:Gem::Requirement
227
- requirements:
228
- - - "~>"
229
- - !ruby/object:Gem::Version
230
- version: '1.0'
231
- - - ">="
232
- - !ruby/object:Gem::Version
233
- version: 1.0.2
234
- type: :development
235
- prerelease: false
236
- version_requirements: !ruby/object:Gem::Requirement
237
- requirements:
238
- - - "~>"
239
- - !ruby/object:Gem::Version
240
- version: '1.0'
241
- - - ">="
242
- - !ruby/object:Gem::Version
243
- version: 1.0.2
244
- - !ruby/object:Gem::Dependency
245
- name: gitmoji-regex
246
- requirement: !ruby/object:Gem::Requirement
247
- requirements:
248
- - - "~>"
249
- - !ruby/object:Gem::Version
250
- version: '1.0'
251
- - - ">="
252
- - !ruby/object:Gem::Version
253
- version: 1.0.3
254
- type: :development
255
- prerelease: false
256
- version_requirements: !ruby/object:Gem::Requirement
257
- requirements:
258
- - - "~>"
259
- - !ruby/object:Gem::Version
260
- version: '1.0'
261
- - - ">="
65
+ - - '='
262
66
  - !ruby/object:Gem::Version
263
- version: 1.0.3
264
- description: "☯️ Ast::Merge-based structure for merging Markdown files with tools
265
- like markly-merge and commonmarker-merge"
67
+ version: 7.0.0
68
+ description: Portable Markdown owner analysis and matching behavior for Structured
69
+ Merge.
266
70
  email:
267
- - floss@galtzo.com
71
+ - info@structuredmerge.org
268
72
  executables: []
269
73
  extensions: []
270
- extra_rdoc_files:
271
- - CHANGELOG.md
272
- - CITATION.cff
273
- - CODE_OF_CONDUCT.md
274
- - CONTRIBUTING.md
275
- - FUNDING.md
276
- - LICENSE.txt
277
- - README.md
278
- - REEK
279
- - RUBOCOP.md
280
- - SECURITY.md
74
+ extra_rdoc_files: []
281
75
  files:
282
- - CHANGELOG.md
283
- - CITATION.cff
284
- - CODE_OF_CONDUCT.md
285
- - CONTRIBUTING.md
286
- - FUNDING.md
287
- - LICENSE.txt
288
- - README.md
289
- - REEK
290
- - RUBOCOP.md
291
- - SECURITY.md
292
76
  - lib/markdown-merge.rb
293
77
  - lib/markdown/merge.rb
294
- - lib/markdown/merge/cleanse.rb
295
- - lib/markdown/merge/cleanse/block_spacing.rb
296
- - lib/markdown/merge/cleanse/code_fence_spacing.rb
297
- - lib/markdown/merge/cleanse/condensed_link_refs.rb
298
- - lib/markdown/merge/code_block_merger.rb
299
- - lib/markdown/merge/conflict_resolver.rb
300
- - lib/markdown/merge/debug_logger.rb
301
- - lib/markdown/merge/document_problems.rb
302
- - lib/markdown/merge/file_aligner.rb
303
- - lib/markdown/merge/file_analysis.rb
304
- - lib/markdown/merge/file_analysis_base.rb
305
- - lib/markdown/merge/freeze_node.rb
306
- - lib/markdown/merge/gap_line_node.rb
307
- - lib/markdown/merge/link_definition_formatter.rb
308
- - lib/markdown/merge/link_definition_node.rb
309
- - lib/markdown/merge/link_parser.rb
310
- - lib/markdown/merge/link_reference_rehydrator.rb
311
- - lib/markdown/merge/markdown_structure.rb
312
- - lib/markdown/merge/merge_result.rb
313
- - lib/markdown/merge/node_type_normalizer.rb
314
- - lib/markdown/merge/output_builder.rb
315
- - lib/markdown/merge/partial_template_merger.rb
316
- - lib/markdown/merge/smart_merger.rb
317
- - lib/markdown/merge/smart_merger_base.rb
318
- - lib/markdown/merge/table_match_algorithm.rb
319
- - lib/markdown/merge/table_match_refiner.rb
320
78
  - lib/markdown/merge/version.rb
321
- - lib/markdown/merge/whitespace_normalizer.rb
322
- - sig/markdown/merge.rbs
323
- homepage: https://github.com/kettle-rb/markdown-merge
79
+ homepage: https://github.com/structuredmerge/structuredmerge-ruby
324
80
  licenses:
325
- - MIT
81
+ - AGPL-3.0-only
82
+ - PolyForm-Small-Business-1.0.0
326
83
  metadata:
327
- homepage_uri: https://markdown-merge.galtzo.com/
328
- source_code_uri: https://github.com/kettle-rb/markdown-merge/tree/v1.0.2
329
- changelog_uri: https://github.com/kettle-rb/markdown-merge/blob/v1.0.2/CHANGELOG.md
330
- bug_tracker_uri: https://github.com/kettle-rb/markdown-merge/issues
331
- documentation_uri: https://www.rubydoc.info/gems/markdown-merge/1.0.2
84
+ homepage_uri: https://structuredmerge.org
85
+ source_code_uri: https://github.com/structuredmerge/structuredmerge-ruby/tree/v7.0.0
86
+ changelog_uri: https://github.com/structuredmerge/structuredmerge-ruby/blob/v7.0.0/CHANGELOG.md
87
+ bug_tracker_uri: https://github.com/structuredmerge/structuredmerge-ruby/issues
88
+ documentation_uri: https://www.rubydoc.info/gems/markdown-merge/7.0.0
332
89
  funding_uri: https://github.com/sponsors/pboling
333
- wiki_uri: https://github.com/kettle-rb/markdown-merge/wiki
334
- news_uri: https://www.railsbling.com/tags/markdown-merge
90
+ wiki_uri: https://github.com/structuredmerge/structuredmerge-ruby/wiki
335
91
  discord_uri: https://discord.gg/3qme4XHNKN
336
92
  rubygems_mfa_required: 'true'
337
- rdoc_options:
338
- - "--title"
339
- - markdown-merge - ☯️ Ast::Merge-based structure for building Markdown merging tools
340
- like markly-merge and commonmarker-merge
341
- - "--main"
342
- - README.md
343
- - "--exclude"
344
- - "^sig/"
345
- - "--line-numbers"
346
- - "--inline-source"
347
- - "--quiet"
93
+ rdoc_options: []
348
94
  require_paths:
349
95
  - lib
350
96
  required_ruby_version: !ruby/object:Gem::Requirement
351
97
  requirements:
352
98
  - - ">="
353
99
  - !ruby/object:Gem::Version
354
- version: 3.2.0
100
+ version: 4.0.0
355
101
  required_rubygems_version: !ruby/object:Gem::Requirement
356
102
  requirements:
357
103
  - - ">="
358
104
  - !ruby/object:Gem::Version
359
105
  version: '0'
360
106
  requirements: []
361
- rubygems_version: 4.0.5
107
+ rubygems_version: 4.0.10
362
108
  specification_version: 4
363
- summary: "☯️ Ast::Merge-based structure for building Markdown merging tools like markly-merge
364
- and commonmarker-merge"
109
+ summary: Structured Merge Markdown analysis and matching for Ruby
365
110
  test_files: []
metadata.gz.sig CHANGED
Binary file
data/CHANGELOG.md DELETED
@@ -1,283 +0,0 @@
1
- # Changelog
2
-
3
- [![SemVer 2.0.0][📌semver-img]][📌semver] [![Keep-A-Changelog 1.0.0][📗keep-changelog-img]][📗keep-changelog]
4
-
5
- All notable changes to this project will be documented in this file.
6
-
7
- The format is based on [Keep a Changelog][📗keep-changelog],
8
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
9
- and [yes][📌major-versions-not-sacred], platform and engine support are part of the [public API][📌semver-breaking].
10
- Please file a bug if you notice a violation of semantic versioning.
11
-
12
- [📌semver]: https://semver.org/spec/v2.0.0.html
13
- [📌semver-img]: https://img.shields.io/badge/semver-2.0.0-FFDD67.svg?style=flat
14
- [📌semver-breaking]: https://github.com/semver/semver/issues/716#issuecomment-869336139
15
- [📌major-versions-not-sacred]: https://tom.preston-werner.com/2022/05/23/major-version-numbers-are-not-sacred.html
16
- [📗keep-changelog]: https://keepachangelog.com/en/1.0.0/
17
- [📗keep-changelog-img]: https://img.shields.io/badge/keep--a--changelog-1.0.0-FFDD67.svg?style=flat
18
-
19
- ## [Unreleased]
20
-
21
- ### Added
22
-
23
- ### Changed
24
-
25
- ### Deprecated
26
-
27
- ### Removed
28
-
29
- ### Fixed
30
-
31
- ### Security
32
-
33
- ## [1.0.2] - 2026-02-01
34
-
35
- - TAG: [v1.0.2][1.0.2t]
36
- - COVERAGE: 93.12% -- 1611/1730 lines in 25 files
37
- - BRANCH COVERAGE: 81.52% -- 525/644 branches in 25 files
38
- - 96.92% documented
39
-
40
- ### Added
41
-
42
- - More tests
43
-
44
- ### Changed
45
-
46
- - Documentation cleanup
47
- - Upgrade to [ast-merge v4.0.5](https://github.com/kettle-rb/ast-merge/releases/tag/v4.0.5)
48
- - Upgrade to [tree_haver v5.0.3](https://github.com/kettle-rb/tree_haver/releases/tag/v5.0.3)
49
-
50
- ## [1.0.1] - 2026-01-20
51
-
52
- - TAG: [v1.0.1][1.0.1t]
53
- - COVERAGE: 93.12% -- 1611/1730 lines in 25 files
54
- - BRANCH COVERAGE: 81.52% -- 525/644 branches in 25 files
55
- - 96.92% documented
56
-
57
- ### Changed
58
-
59
- - Upgrade to [ast-merge v4.0.3](https://github.com/kettle-rb/ast-merge/releases/tag/v4.0.3)
60
-
61
- ## [1.0.0] - 2026-01-19
62
-
63
- - TAG: [v1.0.0][1.0.0t]
64
- - COVERAGE: 91.43% -- 1803/1972 lines in 29 files
65
- - BRANCH COVERAGE: 79.10% -- 579/732 branches in 29 files
66
- - 96.92% documented
67
-
68
- ### Added
69
-
70
- - **Cleanse Module**: New namespace for document cleansing/repair utilities
71
- - `Cleanse::CondensedLinkRefs` - Fixes condensed link reference definitions caused by previous merge bugs
72
- - Parslet-based PEG parser (linear-time, ReDoS-safe) for detecting and expanding `[label]: url[label2]: url2` → separate lines
73
- - Detects two corruption patterns: (1) multiple definitions on same line, (2) content before definition without newline
74
- - Methods: `#condensed?`, `#expand`, `#definitions`, `#count`
75
- - `Cleanse::CodeFenceSpacing` - Fixes malformed code fence language tags
76
- - Fixes ` ``` console` → ` ```console` (removes space between backticks and language)
77
- - Parslet-based PEG parser (linear-time, ReDoS-safe) for detecting code blocks and their info strings
78
- - Supports any indentation level (handles code blocks nested in lists)
79
- - Methods: `#malformed?`, `#malformed_count`, `#code_blocks`, `#fix`
80
- - `Cleanse::BlockSpacing` - Fixes missing blank lines between block elements
81
- - Detects and fixes missing blank lines after thematic breaks (`---`)
82
- - Detects and fixes missing blank lines between list items and headings
83
- - Detects and fixes missing blank lines between markdown and HTML blocks
84
- - Detects and fixes missing blank lines before HTML when preceded by markdown
85
- - Special handling for markdown container closing tags (e.g., `</details>`) - adds blank lines before them even when inside HTML blocks, since their content may be markdown
86
- - Methods: `#malformed?`, `#issue_count`, `#issues`, `#fix`
87
- - **Security Note**: `CondensedLinkRefs` and `CodeFenceSpacing` use PEG parsers instead of regex to eliminate ReDoS vulnerabilities. Both process untrusted Markdown input safely in O(n) time.
88
- - **LinkParser tree-based nesting detection**:
89
- - `#find_all_link_constructs(content)` - Returns tree structure with `:children` for nested items
90
- - `#build_link_tree(links, images)` - Detects containment and builds parent-child relationships
91
- - `#flatten_leaf_first(items)` - Flattens tree in post-order (children before parents) for safe replacement
92
- - Properly handles linked images like `[![alt](img-url)](link-url)` as parent link with child image
93
- - **`bin/fix_readme_formatting`**: Updated to include `BlockSpacing` cleanse fix
94
- - Now fixes missing blank lines between block elements (thematic breaks, lists, headings, HTML)
95
- - Runs as Phase 1c after CondensedLinkRefs and CodeFenceSpacing
96
- - **MergeGemRegistry Integration**: Registers with `Ast::Merge::RSpec::MergeGemRegistry`
97
- - Enables automatic RSpec dependency tag support
98
- - Registers as category `:markdown` with `skip_instantiation: true` (requires backend)
99
- - **TestableNode-based spec helpers**: New helper methods using `TreeHaver::RSpec::TestableNode`
100
- for creating real node instances in tests instead of fragile mocks
101
- - `create_test_node(type, text:, start_line:, ...)` - Create any node type
102
- - `create_test_table_node(rows:, text:)` - Create table nodes
103
- - `create_test_row_node(cells:, start_line:)` - Create table row nodes
104
- - `create_test_cell_node(content:, start_line:)` - Create table cell nodes
105
- - `create_test_paragraph_node(content:, start_line:)` - Create paragraph nodes
106
- - `create_test_heading_node(level:, content:, start_line:)` - Create heading nodes
107
- - `create_test_code_block_node(content:, language:, start_line:)` - Create code block nodes
108
- - `create_test_list_node(items:, ordered:, start_line:)` - Create list nodes
109
- - `create_test_block_quote_node(content:, start_line:)` - Create block quote nodes
110
- - `create_test_thematic_break_node(start_line:)` - Create thematic break nodes
111
- - `create_test_html_block_node(content:, start_line:)` - Create HTML block nodes
112
- - **LinkParser**: New Parslet-based PEG parser for markdown link structures
113
- - Properly handles emoji in labels (e.g., `[🖼️galtzo-discord]`)
114
- - Handles multi-byte UTF-8 characters without regex limitations
115
- - Handles nested brackets (for linked images like `[![alt][ref]](url)`)
116
- - Parses link reference definitions: `[label]: url` and `[label]: url "title"`
117
- - Parses inline links: `[text](url)` and `[text](url "title")`
118
- - Parses inline images: `![alt](url)` and `![alt](url "title")`
119
- - Methods: `#parse_definitions`, `#parse_definition_line`, `#find_inline_links`, `#find_inline_images`, `#build_url_to_label_map`
120
- - **DocumentProblems**: New class for tracking document issues found during merge
121
- - Categories: `:duplicate_link_definition`, `:excessive_whitespace`, `:link_has_title`, `:image_has_title`, `:link_ref_spacing`
122
- - Severity levels: `:info`, `:warning`, `:error`
123
- - Methods: `#add`, `#by_category`, `#by_severity`, `#warnings`, `#errors`, `#infos`, `#merge!`, `#summary_by_category`, `#summary_by_severity`
124
- - Accessible via `MergeResult#problems` after merge
125
- - **WhitespaceNormalizer**: New class for normalizing excessive whitespace
126
- - Supports multiple normalization modes:
127
- - `:basic` (or `true`) - Collapse excessive blank lines (3+ → 2)
128
- - `:link_refs` - Basic + remove blank lines between consecutive link reference definitions
129
- - `:strict` - All normalizations (same as :link_refs currently)
130
- - Class method: `WhitespaceNormalizer.normalize(content, mode: :basic)`
131
- - Instance usage tracks problems for introspection
132
- - New `:link_ref_spacing` problem category for tracking removed blank lines between link refs
133
- - **LinkReferenceRehydrator**: New class for converting inline links to reference style
134
- - Converts inline links `[text](url)` to `[text][label]` when matching definition exists
135
- - Converts inline images `![alt](url)` to `![alt][label]` when matching definition exists
136
- - Skips links/images with titles (would lose title information)
137
- - Tracks duplicate definitions and title conflicts in problems
138
- - Prefers shortest label when multiple labels point to same URL
139
- - **SmartMergerBase options**:
140
- - `normalize_whitespace: false | true | :basic | :link_refs | :strict` - whitespace normalization mode
141
- - `rehydrate_link_references: false` - convert inline links to reference style
142
- - **PartialTemplateMerger options**:
143
- - `normalize_whitespace: false | true | :basic | :link_refs | :strict` - whitespace normalization mode
144
- - `rehydrate_link_references: false` - convert inline links to reference style
145
- - **MergeResult#problems**: Access `DocumentProblems` instance for introspection
146
- - **OutputBuilder**: New class for building markdown output from merge operations
147
- - Consolidates all output assembly logic in one place
148
- - Handles node source extraction, link definition reconstruction, gap lines
149
- - Replaces manual string concatenation with clean builder pattern
150
- - Public methods: `add_node_source`, `add_link_definition`, `add_gap_line`, `add_raw`, `to_s`, `empty?`, `clear`
151
- - **LinkDefinitionFormatter**: New module for formatting link reference definitions
152
- - Reconstructs link definitions that parsers consume during parsing
153
- - Methods: `format(node)`, `format_all(nodes)`
154
- - **Position-based signature generator for PartialTemplateMerger**:
155
- - Tables (and other elements) at the same relative position in their sections now match
156
- - Fixes the "duplicate tables" bug where tables with different column structures weren't merged
157
- - Template table replaces destination table when both are at the same position within the section
158
- - Position counters reset for each document, ensuring template and destination tables match
159
- - **PartialTemplateMerger**: Markdown-specific implementation for partial template merging
160
- - Extends `Ast::Merge::PartialTemplateMergerBase` with markdown-specific logic
161
- - Heading-level-aware section boundaries (finds next heading of same or higher level)
162
- - Source-based text extraction via `analysis.source_range` to preserve:
163
- - Link reference definitions (no conversion to inline links)
164
- - Table column padding/alignment
165
- - Original formatting exactly as written
166
- - Supports both Markly and Commonmarker backends via tree_haver
167
- - **SmartMergerBase**: `add_template_only_nodes` now accepts a callable filter
168
- - Boolean `true`/`false` still works as before (add all or none)
169
- - Callable (Proc/Lambda) receives `(node, entry)` and returns truthy to add the node
170
- - Enables selective addition of template-only nodes based on signature, type, or content
171
- - Useful for partial template merging where only specific template nodes should be added
172
-
173
- ### Changed
174
-
175
- - Upgrade to [ast-merge v4.0.2](https://github.com/kettle-rb/ast-merge/releases/tag/v4.0.2)
176
- - Upgrade to [tree_haver v5.0.2](https://github.com/kettle-rb/tree_haver/releases/tag/v5.0.2)
177
- - **WhitespaceNormalizer refactored to use LinkParser**
178
- - Removed `LINK_REF_PATTERN` regex constant
179
- - Now uses `LinkParser#parse_definition_line` for link definition detection
180
- - Supports all link definition formats that LinkParser handles:
181
- - Angle-bracketed URLs: `[label]: <url>`
182
- - Emoji in labels: `[🎨logo]: url`
183
- - Definitions with titles in any quote style
184
- - Completely regex-free implementation
185
- - **LinkDefinitionNode**: Now uses `LinkParser` (Parslet-based) instead of regex for parsing
186
- - Properly handles emoji in labels (e.g., `[🖼️galtzo-discord]`)
187
- - More robust parsing of multi-byte UTF-8 characters
188
- - **LinkReferenceRehydrator**: Rewritten to use `LinkParser` (Parslet-based) for all parsing
189
- - Uses `LinkParser#parse_definitions` to parse link reference definitions
190
- - Uses `LinkParser#find_inline_links` and `#find_inline_images` to find inline constructs
191
- - Properly handles linked images (e.g., `[![alt][ref]](url)`)
192
- - Properly handles emoji in link text and URLs
193
- - No regex used - all parsing via PEG grammar
194
- - **PartialTemplateMerger#find_section_end**: For headings, now always uses heading-level-aware logic, ignoring tree-depth-based boundary from `InjectionPointFinder`
195
- - Fixes duplicate H4 section bug where nested headings (e.g., H4 inside H3) were incorrectly treated as section boundaries
196
- - In Markdown, all headings are siblings at the same tree depth regardless of level (H2, H3, H4), so tree depth cannot determine section boundaries
197
- - Heading level semantics require comparing actual heading level numbers (H3 < H4 means H4 is nested)
198
- - **SmartMergerBase**: Refactored to use OutputBuilder throughout
199
- - `process_alignment` now returns OutputBuilder instead of array
200
- - New methods: `process_match_to_builder`, `process_template_only_to_builder`, `process_dest_only_to_builder`
201
- - Old methods deprecated but kept for compatibility
202
- - Inner merge for code blocks now uses `try_inner_merge_code_block_to_builder`
203
- - **OutputBuilder**: Enhanced node extraction to handle `source_position` method
204
- - Supports nodes with `source_position` hash
205
- - Falls back to `to_commonmark` if position unavailable
206
- - Handles FreezeNode, LinkDefinitionNode, GapLineNode, and parser nodes
207
- - **FileAnalysisBase**: Added `@errors` instance variable and `errors` attr_reader
208
- - `valid?` now checks both `@errors.empty?` and `!@document.nil?`
209
- - Consistent with bash-merge, json-merge, jsonc-merge, and toml-merge patterns
210
- - **FileAnalysis error handling**: Now rescues `TreeHaver::Error` in `parse_document`
211
- - `TreeHaver::Error` inherits from `Exception`, not `StandardError`
212
- - `TreeHaver::NotAvailable` is a subclass of `TreeHaver::Error`, so it's also caught
213
- - Stores error in `@errors` and returns nil, so `valid?` returns false
214
- - `SmartMergerBase#parse_and_analyze` then raises the appropriate parse error
215
- - **Dependency tags**: Refactored to use shared `TreeHaver::RSpec::DependencyTags` from tree_haver gem
216
- - All dependency detection is now centralized in tree_haver
217
- - Use `require "tree_haver/rspec"` for shared RSpec configuration
218
- - `MarkdownMergeDependencies` is now an alias to `TreeHaver::RSpec::DependencyTags`
219
- - Enables `MARKDOWN_MERGE_DEBUG=1` for dependency summary output
220
- - Inner-merge dependencies (`:toml_merge`, `:json_merge`, `:prism_merge`, `:psych_merge`) now available
221
- - **CodeBlockMerger**: Refactored class methods to remove redundant error handling
222
- - Removed duplicate `rescue` blocks from `merge_with_prism`, `merge_with_psych`, `merge_with_json`, `merge_with_toml`
223
- - Error handling is now consolidated in `merge_code_blocks` instance method
224
- - Class methods now raise exceptions which are caught by `merge_code_blocks`
225
- - Updated specs to test through `merge_code_blocks` (the intended API) instead of class methods directly
226
-
227
- ### Fixed
228
-
229
- - **CondensedLinkRefs false positive**: Fixed bug where reference-style links followed by colon
230
- (e.g., `**[Floss-Funding.dev][🖇floss-funding.dev]:**`) were incorrectly detected as condensed
231
- link reference definitions
232
- - The pattern `][label]:` was matching, but this is a reference link with punctuation, not a link def
233
- - Now requires URL-like content after `]:` to confirm it's a real link def
234
- - Supports both full URLs (`https://...`) and relative paths (`CONTRIBUTING.md`, `LICENSE.txt`)
235
- - The relative path pattern matches `UPPERCASE.ext` format common in repo files
236
- - Prevents incorrect newline insertion inside markdown links
237
- - **LinkReferenceRehydrator content corruption**: Fixed critical bug where rehydrating linked images
238
- like `[![alt](img-url)](link-url)` would corrupt document content
239
- - The parser was finding both the outer link and inner image as separate items
240
- - Replacing both overlapping items corrupted the content, losing significant portions of documents
241
- - Now uses tree-based approach: builds parent-child relationships for nested constructs
242
- - Processes replacements recursively: children are processed first, then parent text is updated
243
- to include child replacements before parent is processed
244
- - Single pass now handles all nested structures (no more multi-pass workaround needed)
245
- - Test fixture showed 68 lines lost (1023 → 955) before fix, now preserves all content
246
- - **OutputBuilder**: Fixed link definitions being concatenated without newlines
247
- - `extract_source` for `LinkDefinitionNode` now includes trailing newline
248
- - Link definitions are now properly output on separate lines
249
- - **OutputBuilder**: Fixed auto-spacing to properly handle link_definition transitions
250
- - Removed `link_definition` from the skip list for auto-spacing
251
- - Now correctly adds blank lines when transitioning FROM link_definition TO other content (e.g., headings)
252
- - `MarkdownStructure.needs_blank_between?` now handles contiguous types properly
253
- - **MarkdownStructure**: Added support for contiguous node types
254
- - New `CONTIGUOUS_TYPES` constant for node types that should not have blank lines between consecutive instances
255
- - `link_definition` is now a contiguous type - consecutive link definitions won't have blank lines inserted
256
- - Added `link_definition` to `NEEDS_BLANK_AFTER` - link definition blocks get blank line after when followed by other content
257
- - New `contiguous_type?` method to check if a type is contiguous
258
- - `needs_blank_between?` now returns `false` for consecutive nodes of the same contiguous type
259
- - **PartialTemplateMerger#node_to_text**: Fixed double blank line bug
260
- - `source_range` already adds trailing newlines, so adding another `"\n"` caused double blank lines
261
- - Removed the extra `+ "\n"` that was causing excessive blank lines in merged output
262
- - **Lint cleanup**: Fixed RSpec/ReceiveMessages cops by combining multiple `receive` stubs
263
- - **Style fixes**: Fixed Style/ClassMethodsDefinitions in `LinkDefinitionNode` using `class << self`
264
- - **Layout fixes**: Removed extra blank lines in `mock_helpers.rb`
265
- - **Freeze block detection**: Fixed `find_freeze_markers` to handle both raw parser types
266
- (`:html`) and TreeHaver normalized types (`"html_block"`, `:html_block`). Previously,
267
- freeze markers were not detected when using TreeHaver backends because the node type
268
- check only looked for `:html`.
269
- - **Freeze marker content extraction**: Now uses a three-tier fallback for extracting
270
- HTML comment content:
271
- 1. `string_content` (raw Markly/Commonmarker nodes)
272
- 2. `to_commonmark` on the wrapper node
273
- 3. `inner_node.to_commonmark` (TreeHaver Commonmarker wrapper)
274
- This fixes freeze block detection for Commonmarker where the TreeHaver wrapper's
275
- content methods return empty but the inner node has the actual content.
276
-
277
- [Unreleased]: https://github.com/kettle-rb/markdown-merge/compare/v1.0.2...HEAD
278
- [1.0.2]: https://github.com/kettle-rb/markdown-merge/compare/v1.0.1...v1.0.2
279
- [1.0.2t]: https://github.com/kettle-rb/markdown-merge/releases/tag/v1.0.2
280
- [1.0.1]: https://github.com/kettle-rb/markdown-merge/compare/v1.0.0...v1.0.1
281
- [1.0.1t]: https://github.com/kettle-rb/markdown-merge/releases/tag/v1.0.1
282
- [1.0.0]: https://github.com/kettle-rb/markdown-merge/compare/76f2230840b236dd10fdd7baf322c082762dddb0...v1.0.0
283
- [1.0.0t]: https://github.com/kettle-rb/markdown-merge/tags/v1.0.0
data/CITATION.cff DELETED
@@ -1,20 +0,0 @@
1
- cff-version: 1.2.0
2
- title: markdown-merge
3
- message: >-
4
- If you use this work and you want to cite it,
5
- then you can use the metadata from this file.
6
- type: software
7
- authors:
8
- - given-names: Peter Hurn
9
- family-names: Boling
10
- email: peter@railsbling.com
11
- affiliation: railsbling.com
12
- orcid: 'https://orcid.org/0009-0008-8519-441X'
13
- identifiers:
14
- - type: url
15
- value: 'https://github.com/kettle-rb/markdown-merge'
16
- description: markdown-merge
17
- repository-code: 'https://github.com/kettle-rb/markdown-merge'
18
- abstract: >-
19
- markdown-merge
20
- license: See license file