canon 0.1.6 → 0.1.7

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 (136) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +163 -67
  3. data/README.adoc +400 -7
  4. data/docs/Gemfile +9 -0
  5. data/docs/INDEX.adoc +99 -182
  6. data/docs/_config.yml +100 -0
  7. data/docs/advanced/diff-classification.adoc +547 -0
  8. data/docs/advanced/diff-pipeline.adoc +358 -0
  9. data/docs/advanced/index.adoc +214 -0
  10. data/docs/advanced/semantic-diff-report.adoc +390 -0
  11. data/docs/{VERBOSE.adoc → advanced/verbose-mode-architecture.adoc} +51 -53
  12. data/docs/features/diff-formatting/algorithm-specific-output.adoc +533 -0
  13. data/docs/{CHARACTER_VISUALIZATION.adoc → features/diff-formatting/character-visualization.adoc} +23 -62
  14. data/docs/features/diff-formatting/colors-and-symbols.adoc +606 -0
  15. data/docs/features/diff-formatting/context-and-grouping.adoc +490 -0
  16. data/docs/features/diff-formatting/display-filtering.adoc +472 -0
  17. data/docs/features/diff-formatting/index.adoc +140 -0
  18. data/docs/features/environment-configuration/index.adoc +327 -0
  19. data/docs/features/environment-configuration/override-system.adoc +436 -0
  20. data/docs/features/environment-configuration/size-limits.adoc +273 -0
  21. data/docs/features/index.adoc +173 -0
  22. data/docs/features/input-validation/index.adoc +521 -0
  23. data/docs/features/match-options/algorithm-specific-behavior.adoc +365 -0
  24. data/docs/features/match-options/html-policies.adoc +312 -0
  25. data/docs/features/match-options/index.adoc +621 -0
  26. data/docs/getting-started/index.adoc +83 -0
  27. data/docs/getting-started/quick-start.adoc +76 -0
  28. data/docs/guides/choosing-configuration.adoc +689 -0
  29. data/docs/guides/index.adoc +181 -0
  30. data/docs/{CLI.adoc → interfaces/cli/index.adoc} +18 -13
  31. data/docs/interfaces/index.adoc +101 -0
  32. data/docs/{RSPEC.adoc → interfaces/rspec/index.adoc} +242 -31
  33. data/docs/{RUBY_API.adoc → interfaces/ruby-api/index.adoc} +118 -16
  34. data/docs/lychee.toml +65 -0
  35. data/docs/reference/cli-options.adoc +418 -0
  36. data/docs/reference/environment-variables.adoc +375 -0
  37. data/docs/reference/index.adoc +204 -0
  38. data/docs/reference/options-across-interfaces.adoc +417 -0
  39. data/docs/understanding/algorithms/dom-diff.adoc +389 -0
  40. data/docs/understanding/algorithms/index.adoc +314 -0
  41. data/docs/understanding/algorithms/semantic-tree-diff.adoc +533 -0
  42. data/docs/understanding/architecture.adoc +447 -0
  43. data/docs/understanding/comparison-pipeline.adoc +317 -0
  44. data/docs/understanding/formats/html.adoc +380 -0
  45. data/docs/understanding/formats/index.adoc +261 -0
  46. data/docs/understanding/formats/json.adoc +390 -0
  47. data/docs/understanding/formats/xml.adoc +366 -0
  48. data/docs/understanding/formats/yaml.adoc +504 -0
  49. data/docs/understanding/index.adoc +130 -0
  50. data/lib/canon/cli.rb +42 -1
  51. data/lib/canon/commands/diff_command.rb +108 -23
  52. data/lib/canon/comparison/compare_profile.rb +101 -0
  53. data/lib/canon/comparison/comparison_result.rb +41 -2
  54. data/lib/canon/comparison/html_comparator.rb +292 -71
  55. data/lib/canon/comparison/html_compare_profile.rb +117 -0
  56. data/lib/canon/comparison/match_options.rb +42 -4
  57. data/lib/canon/comparison/strategies/base_match_strategy.rb +99 -0
  58. data/lib/canon/comparison/strategies/match_strategy_factory.rb +74 -0
  59. data/lib/canon/comparison/strategies/semantic_tree_match_strategy.rb +220 -0
  60. data/lib/canon/comparison/xml_comparator.rb +695 -91
  61. data/lib/canon/comparison.rb +207 -2
  62. data/lib/canon/config/env_provider.rb +71 -0
  63. data/lib/canon/config/env_schema.rb +58 -0
  64. data/lib/canon/config/override_resolver.rb +55 -0
  65. data/lib/canon/config/type_converter.rb +59 -0
  66. data/lib/canon/config.rb +158 -29
  67. data/lib/canon/data_model.rb +29 -0
  68. data/lib/canon/diff/diff_classifier.rb +74 -14
  69. data/lib/canon/diff/diff_context_builder.rb +41 -0
  70. data/lib/canon/diff/diff_line.rb +18 -2
  71. data/lib/canon/diff/diff_node.rb +18 -3
  72. data/lib/canon/diff/diff_node_mapper.rb +71 -12
  73. data/lib/canon/diff/formatting_detector.rb +53 -0
  74. data/lib/canon/diff_formatter/by_line/base_formatter.rb +60 -5
  75. data/lib/canon/diff_formatter/by_line/html_formatter.rb +68 -16
  76. data/lib/canon/diff_formatter/by_line/json_formatter.rb +0 -37
  77. data/lib/canon/diff_formatter/by_line/simple_formatter.rb +0 -42
  78. data/lib/canon/diff_formatter/by_line/xml_formatter.rb +116 -31
  79. data/lib/canon/diff_formatter/by_line/yaml_formatter.rb +0 -37
  80. data/lib/canon/diff_formatter/by_object/base_formatter.rb +126 -19
  81. data/lib/canon/diff_formatter/by_object/xml_formatter.rb +30 -1
  82. data/lib/canon/diff_formatter/debug_output.rb +7 -1
  83. data/lib/canon/diff_formatter/diff_detail_formatter.rb +674 -57
  84. data/lib/canon/diff_formatter/legend.rb +42 -0
  85. data/lib/canon/diff_formatter.rb +78 -9
  86. data/lib/canon/errors.rb +56 -0
  87. data/lib/canon/formatters/html_formatter_base.rb +35 -1
  88. data/lib/canon/formatters/json_formatter.rb +3 -0
  89. data/lib/canon/formatters/yaml_formatter.rb +3 -0
  90. data/lib/canon/html/data_model.rb +229 -0
  91. data/lib/canon/html.rb +9 -0
  92. data/lib/canon/options/cli_generator.rb +70 -0
  93. data/lib/canon/options/registry.rb +234 -0
  94. data/lib/canon/rspec_matchers.rb +34 -13
  95. data/lib/canon/tree_diff/adapters/html_adapter.rb +316 -0
  96. data/lib/canon/tree_diff/adapters/json_adapter.rb +204 -0
  97. data/lib/canon/tree_diff/adapters/xml_adapter.rb +285 -0
  98. data/lib/canon/tree_diff/adapters/yaml_adapter.rb +213 -0
  99. data/lib/canon/tree_diff/core/attribute_comparator.rb +84 -0
  100. data/lib/canon/tree_diff/core/matching.rb +241 -0
  101. data/lib/canon/tree_diff/core/node_signature.rb +164 -0
  102. data/lib/canon/tree_diff/core/node_weight.rb +135 -0
  103. data/lib/canon/tree_diff/core/tree_node.rb +450 -0
  104. data/lib/canon/tree_diff/matchers/hash_matcher.rb +258 -0
  105. data/lib/canon/tree_diff/matchers/similarity_matcher.rb +168 -0
  106. data/lib/canon/tree_diff/matchers/structural_propagator.rb +242 -0
  107. data/lib/canon/tree_diff/matchers/universal_matcher.rb +220 -0
  108. data/lib/canon/tree_diff/operation_converter.rb +631 -0
  109. data/lib/canon/tree_diff/operations/operation.rb +92 -0
  110. data/lib/canon/tree_diff/operations/operation_detector.rb +626 -0
  111. data/lib/canon/tree_diff/tree_diff_integrator.rb +140 -0
  112. data/lib/canon/tree_diff.rb +33 -0
  113. data/lib/canon/validators/json_validator.rb +3 -1
  114. data/lib/canon/validators/yaml_validator.rb +3 -1
  115. data/lib/canon/version.rb +1 -1
  116. data/lib/canon/xml/data_model.rb +22 -23
  117. data/lib/canon/xml/element_matcher.rb +128 -20
  118. data/lib/canon/xml/namespace_helper.rb +110 -0
  119. data/lib/canon.rb +3 -0
  120. metadata +81 -23
  121. data/_config.yml +0 -116
  122. data/docs/ADVANCED_TOPICS.adoc +0 -20
  123. data/docs/BASIC_USAGE.adoc +0 -16
  124. data/docs/CUSTOMIZING_BEHAVIOR.adoc +0 -19
  125. data/docs/DIFF_ARCHITECTURE.adoc +0 -435
  126. data/docs/DIFF_FORMATTING.adoc +0 -540
  127. data/docs/FORMATS.adoc +0 -447
  128. data/docs/INPUT_VALIDATION.adoc +0 -477
  129. data/docs/MATCH_ARCHITECTURE.adoc +0 -463
  130. data/docs/MATCH_OPTIONS.adoc +0 -719
  131. data/docs/MODES.adoc +0 -432
  132. data/docs/NORMATIVE_INFORMATIVE_DIFFS.adoc +0 -219
  133. data/docs/OPTIONS.adoc +0 -1387
  134. data/docs/PREPROCESSING.adoc +0 -491
  135. data/docs/SEMANTIC_DIFF_REPORT.adoc +0 -528
  136. data/docs/UNDERSTANDING_CANON.adoc +0 -17
@@ -0,0 +1,490 @@
1
+ ---
2
+ layout: default
3
+ title: Context and Grouping
4
+ parent: Diff Formatting
5
+ grand_parent: Features
6
+ nav_order: 6
7
+ ---
8
+
9
+ :toc:
10
+ :toclevels: 3
11
+
12
+ == Purpose
13
+
14
+ Context lines and diff grouping control how much unchanged content is shown around changes in line-by-line diffs. These features help you understand the location and scope of changes while keeping output readable.
15
+
16
+ NOTE: Context and grouping apply only to **by-line diff mode**. By-object mode shows only changed elements without context lines.
17
+
18
+ == Context Lines
19
+
20
+ Context lines are unchanged lines displayed before and after each change to show where modifications occur in the file.
21
+
22
+ === Default Behavior
23
+
24
+ By default, Canon shows **3 context lines** before and after each change:
25
+
26
+ .Default context example
27
+ [example]
28
+ ====
29
+ [source]
30
+ ----
31
+ 5| 5 | <section> # Context line
32
+ 6| 6 | <title>Intro</title> # Context line
33
+ 7| 7 | <p>Welcome</p> # Context line
34
+ 8| -| <p>Old text</p> # Deleted line (change)
35
+ | 8+| <p>New text</p> # Added line (change)
36
+ 9| 9 | <p>Goodbye</p> # Context line
37
+ 10| 10 | <p>End</p> # Context line
38
+ 11| 11 | </section> # Context line
39
+ ----
40
+
41
+ Three unchanged lines are shown before and after the change.
42
+ ====
43
+
44
+ === Configuring Context Lines
45
+
46
+ Control the number of context lines with the `context_lines` option:
47
+
48
+ .CLI
49
+ [example]
50
+ ====
51
+ [source,bash]
52
+ ----
53
+ # Show 5 context lines
54
+ canon diff file1.xml file2.xml --context-lines 5
55
+
56
+ # Show no context (changes only)
57
+ canon diff file1.xml file2.xml --context-lines 0
58
+
59
+ # Show 10 context lines
60
+ canon diff file1.xml file2.xml --context-lines 10
61
+ ----
62
+ ====
63
+
64
+ .Ruby API
65
+ [example]
66
+ ====
67
+ [source,ruby]
68
+ ----
69
+ # Show 5 context lines
70
+ Canon.compare(file1, file2,
71
+ format: :xml,
72
+ context_lines: 5
73
+ )
74
+
75
+ # Show no context
76
+ Canon.compare(file1, file2,
77
+ format: :xml,
78
+ context_lines: 0
79
+ )
80
+ ----
81
+ ====
82
+
83
+ .RSpec
84
+ [example]
85
+ ====
86
+ [source,ruby]
87
+ ----
88
+ RSpec.configure do |config|
89
+ # Show more context in local development
90
+ config.canon.xml.diff.context_lines = 5
91
+ end
92
+ ----
93
+ ====
94
+
95
+ .Environment Variable
96
+ [example]
97
+ ====
98
+ [source,bash]
99
+ ----
100
+ # Set default context lines globally
101
+ export CANON_CONTEXT_LINES=5
102
+ ----
103
+ ====
104
+
105
+ === Zero Context Lines
106
+
107
+ Setting `context_lines: 0` shows only changed lines without any surrounding context:
108
+
109
+ .No context example
110
+ [example]
111
+ ====
112
+ [source]
113
+ ----
114
+ 8| -| <p>Old text</p> # Only the deletion
115
+ | 8+| <p>New text</p> # Only the addition
116
+ ----
117
+
118
+ This is useful when:
119
+
120
+ * Changes are self-explanatory
121
+ * You want minimal output
122
+ * File structure is already known
123
+ ====
124
+
125
+ === Large Context Values
126
+
127
+ Larger context values show more surrounding content:
128
+
129
+ .Large context example (context_lines: 10)
130
+ [example]
131
+ ====
132
+ [source]
133
+ ----
134
+ 1| 1 | <root>
135
+ 2| 2 | <header>
136
+ 3| 3 | <title>Document</title>
137
+ 4| 4 | </header>
138
+ 5| 5 | <body>
139
+ 6| 6 | <section>
140
+ 7| 7 | <h1>Title</h1>
141
+ 8| 8 | <p>Para 1</p>
142
+ 9| 9 | <p>Para 2</p>
143
+ 10| 10 | <p>Para 3</p>
144
+ 11| -| <p>Old</p> # The change
145
+ | 11+| <p>New</p>
146
+ 12| 12 | <p>Para 4</p>
147
+ 13| 13 | <p>Para 5</p>
148
+ 14| 14 | <p>Para 6</p>
149
+ 15| 15 | </section>
150
+ 16| 16 | </body>
151
+ 17| 17 | </root>
152
+ ----
153
+
154
+ Ten lines of context before and after the change.
155
+ ====
156
+
157
+ == Diff Grouping
158
+
159
+ Diff grouping controls whether nearby changes are shown as separate blocks or merged into a single continuous block.
160
+
161
+ === Default Behavior
162
+
163
+ By default, Canon uses **10 lines** as the grouping threshold. Changes within 10 lines of each other are shown in the same context block:
164
+
165
+ .Grouped changes (within 10 lines)
166
+ [example]
167
+ ====
168
+ [source]
169
+ ----
170
+ 5| 5 | <section>
171
+ 6| 6 | <p>Text 1</p>
172
+ 7| -| <p>Old A</p> # First change
173
+ | 7+| <p>New A</p>
174
+ 8| 8 | <p>Text 2</p>
175
+ 9| 9 | <p>Text 3</p>
176
+ 10| 10 | <p>Text 4</p>
177
+ 11| 11 | <p>Text 5</p>
178
+ 12| -| <p>Old B</p> # Second change (within 10 lines)
179
+ | 12+| <p>New B</p>
180
+ 13| 13 | <p>Text 6</p>
181
+ 14| 14 | </section>
182
+ ----
183
+
184
+ Both changes appear in one continuous block because they're only 4 lines apart.
185
+ ====
186
+
187
+ === Separate Blocks
188
+
189
+ When changes are far apart (more than grouping threshold), they appear as separate blocks:
190
+
191
+ .Separate blocks (beyond 10 lines apart)
192
+ [example]
193
+ ====
194
+ [source]
195
+ ----
196
+ 5| 5 | <section>
197
+ 6| 6 | <p>Text 1</p>
198
+ 7| -| <p>Old A</p> # First change
199
+ | 7+| <p>New A</p>
200
+ 8| 8 | <p>Text 2</p>
201
+ 9| 9 | <p>Text 3</p>
202
+ 10| 10 | </section>
203
+
204
+ ... (lines 11-25 omitted) # Gap indicator
205
+
206
+ 26| 26 | <section>
207
+ 27| 27 | <p>Text N</p>
208
+ 28| -| <p>Old B</p> # Second change (far from first)
209
+ | 28+| <p>New B</p>
210
+ 29| 29 | <p>Text M</p>
211
+ 30| 30 | </section>
212
+ ----
213
+
214
+ The two changes appear as separate blocks with a gap indicator between them.
215
+ ====
216
+
217
+ === Configuring Grouping
218
+
219
+ Control grouping behavior with the `diff_grouping_lines` option:
220
+
221
+ .CLI
222
+ [example]
223
+ ====
224
+ [source,bash]
225
+ ----
226
+ # Group changes within 5 lines
227
+ canon diff file1.xml file2.xml --diff-grouping-lines 5
228
+
229
+ # Group changes within 20 lines
230
+ canon diff file1.xml file2.xml --diff-grouping-lines 20
231
+
232
+ # Never group (each change in its own block)
233
+ canon diff file1.xml file2.xml --diff-grouping-lines 0
234
+ ----
235
+ ====
236
+
237
+ .Ruby API
238
+ [example]
239
+ ====
240
+ [source,ruby]
241
+ ----
242
+ # Tight grouping (5 lines)
243
+ Canon.compare(file1, file2,
244
+ format: :xml,
245
+ diff_grouping_lines: 5
246
+ )
247
+
248
+ # Loose grouping (20 lines)
249
+ Canon.compare(file1, file2,
250
+ format: :xml,
251
+ diff_grouping_lines: 20
252
+ )
253
+ ----
254
+ ====
255
+
256
+ .RSpec
257
+ [example]
258
+ ====
259
+ [source,ruby]
260
+ ----
261
+ RSpec.configure do |config|
262
+ # Tighter grouping for specs
263
+ config.canon.xml.diff.grouping_lines = 5
264
+ end
265
+ ----
266
+ ====
267
+
268
+ .Environment Variable
269
+ [example]
270
+ ====
271
+ [source,bash]
272
+ ----
273
+ # Set default grouping globally
274
+ export CANON_GROUPING_LINES=15
275
+ ----
276
+ ====
277
+
278
+ == Interaction Between Context and Grouping
279
+
280
+ Context lines and grouping work together to determine diff block boundaries:
281
+
282
+ === Example: Tight Context, Loose Grouping
283
+
284
+ .context_lines: 1, diff_grouping_lines: 20
285
+ [example]
286
+ ====
287
+ [source]
288
+ ----
289
+ 6| 6 | <p>Text 1</p> # 1 line context before
290
+ 7| -| <p>Old A</p>
291
+ | 7+| <p>New A</p>
292
+ 8| 8 | <p>Text 2</p> # 1 line context after
293
+ 9| 9 | <p>Text 3</p> # Continues because next change within 20 lines
294
+ 10| 10 | <p>Text 4</p>
295
+ 11| 11 | <p>Text 5</p>
296
+ 12| -| <p>Old B</p>
297
+ | 12+| <p>New B</p>
298
+ 13| 13 | <p>Text 6</p> # 1 line context after
299
+ ----
300
+
301
+ Minimal context but changes stay grouped.
302
+ ====
303
+
304
+ === Example: Wide Context, Tight Grouping
305
+
306
+ .context_lines: 5, diff_grouping_lines: 3
307
+ [example]
308
+ ====
309
+ [source]
310
+ ----
311
+ # First change block
312
+ 2| 2 | <root>
313
+ 3| 3 | <section>
314
+ 4| 4 | <p>A</p>
315
+ 5| 5 | <p>B</p>
316
+ 6| 6 | <p>C</p>
317
+ 7| -| <p>Old A</p>
318
+ | 7+| <p>New A</p>
319
+ 8| 8 | <p>D</p>
320
+ 9| 9 | <p>E</p>
321
+ 10| 10 | <p>F</p>
322
+ 11| 11 | <p>G</p>
323
+ 12| 12 | <p>H</p>
324
+
325
+ ... (lines 13-17 omitted)
326
+
327
+ # Second change block (separated by > 3 lines)
328
+ 13| 13 | <p>I</p>
329
+ 14| 14 | <p>J</p>
330
+ 15| 15 | <p>K</p>
331
+ 16| 16 | <p>L</p>
332
+ 17| 17 | <p>M</p>
333
+ 18| -| <p>Old B</p>
334
+ | 18+| <p>New B</p>
335
+ 19| 19 | <p>N</p>
336
+ 20| 20 | <p>O</p>
337
+ 21| 21 | <p>P</p>
338
+ 22| 22 | <p>Q</p>
339
+ 23| 23 | </section>
340
+ ----
341
+
342
+ Wide context but changes in separate blocks due to tight grouping.
343
+ ====
344
+
345
+ == Use Cases
346
+
347
+ === Debugging: Wide Context
348
+
349
+ When debugging unexpected test failures, use wide context to see surrounding structure:
350
+
351
+ [source,bash]
352
+ ----
353
+ canon diff expected.xml actual.xml \
354
+ --context-lines 10 \
355
+ --diff-grouping-lines 20
356
+ ----
357
+
358
+ === CI/CD: Minimal Output
359
+
360
+ In CI environments, minimize output for faster log scanning:
361
+
362
+ [source,bash]
363
+ ----
364
+ export CANON_CONTEXT_LINES=1
365
+ export CANON_GROUPING_LINES=5
366
+ ----
367
+
368
+ === Documentation: Complete Context
369
+
370
+ When documenting changes, show complete sections:
371
+
372
+ [source,ruby]
373
+ ----
374
+ Canon.compare(old_doc, new_doc,
375
+ format: :xml,
376
+ context_lines: 15,
377
+ diff_grouping_lines: 30
378
+ )
379
+ ----
380
+
381
+ === Code Review: Balanced View
382
+
383
+ For code reviews, balance readability and completeness:
384
+
385
+ [source,ruby]
386
+ ----
387
+ RSpec.configure do |config|
388
+ config.canon.xml.diff.context_lines = 5
389
+ config.canon.xml.diff.grouping_lines = 10
390
+ end
391
+ ----
392
+
393
+ == Performance Considerations
394
+
395
+ === Large Files
396
+
397
+ With large files and many changes:
398
+
399
+ * **Smaller context**: Reduces output size, faster to scan
400
+ * **Tighter grouping**: More separate blocks, easier to locate specific changes
401
+ * **Larger context**: Better understanding, but more verbose
402
+
403
+ .Recommended for large files
404
+ [example]
405
+ ====
406
+ [source,bash]
407
+ ----
408
+ # Keep output manageable
409
+ canon diff large1.xml large2.xml \
410
+ --context-lines 2 \
411
+ --diff-grouping-lines 5
412
+ ----
413
+ ====
414
+
415
+ === Many Small Changes
416
+
417
+ When files have numerous small scattered changes:
418
+
419
+ * **Smaller context**: Avoids repetitive output
420
+ * **Tighter grouping**: Keeps unrelated changes separate
421
+ * **Larger grouping**: May merge everything into one block
422
+
423
+ .Recommended for scattered changes
424
+ [example]
425
+ ====
426
+ [source,bash]
427
+ ----
428
+ # Separate unrelated changes
429
+ canon diff file1.xml file2.xml \
430
+ --context-lines 1 \
431
+ --diff-grouping-lines 3
432
+ ----
433
+ ====
434
+
435
+ == Gap Indicators
436
+
437
+ When changes are far apart, Canon shows gap indicators:
438
+
439
+ [source]
440
+ ----
441
+ 10| 10 | <p>End of first section</p>
442
+
443
+ ... (lines 11-45 omitted)
444
+
445
+ 46| 46 | <p>Start of next section</p>
446
+ ----
447
+
448
+ The gap indicator shows:
449
+ * How many lines were skipped
450
+ * That there are no changes in the skipped region
451
+
452
+ == Troubleshooting
453
+
454
+ === Too Much Output
455
+
456
+ **Problem**: Diff output is overwhelming.
457
+
458
+ **Solutions**:
459
+ * Reduce `context_lines` (try 1 or 2)
460
+ * Reduce `diff_grouping_lines` (try 5 or less)
461
+ * Use `show_diffs: :normative` to hide informative changes
462
+
463
+ === Not Enough Context
464
+
465
+ **Problem**: Can't understand where changes occur.
466
+
467
+ **Solutions**:
468
+ * Increase `context_lines` (try 7-10)
469
+ * Increase `diff_grouping_lines` (try 15-20)
470
+ * Check file structure separately
471
+
472
+ === Changes Grouped Incorrectly
473
+
474
+ **Problem**: Unrelated changes appear together.
475
+
476
+ **Solution**:
477
+ * Decrease `diff_grouping_lines` to separate them
478
+
479
+ **Problem**: Related changes appear in separate blocks.
480
+
481
+ **Solution**:
482
+ * Increase `diff_grouping_lines` to group them together
483
+
484
+ == See Also
485
+
486
+ * link:colors-and-symbols.html[Colors and Symbols] - Color scheme and visual markers
487
+ * link:character-visualization.html[Character Visualization] - Whitespace visualization
488
+ * link:algorithm-specific-output.html[Algorithm-Specific Output] - Diff format variations
489
+ * link:../../interfaces/cli/index.html[CLI Interface] - Command-line usage
490
+ * link:../../reference/cli-options.html[CLI Options Reference] - Complete option list