canon 0.1.5 → 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,606 @@
1
+ ---
2
+ layout: default
3
+ title: Colors and Symbols
4
+ parent: Diff Formatting
5
+ grand_parent: Features
6
+ nav_order: 5
7
+ ---
8
+
9
+ :toc:
10
+ :toclevels: 3
11
+
12
+ == Purpose
13
+
14
+ Canon uses a carefully designed color scheme and symbol system to communicate
15
+ the nature and severity of differences in document comparisons.
16
+
17
+ == Diff classification
18
+
19
+ Canon classifies differences into three distinct categories, each with unique
20
+ visual markers and directional colors.
21
+
22
+ [cols="1,1,1,3",options="header"]
23
+ |===
24
+ | Type | Marker | Color | Meaning
25
+
26
+ h| Formatting-only
27
+ | `[` (removed) +
28
+ `]` (added)
29
+ | Dark gray (removed) +
30
+ Light gray (added)
31
+ | Purely cosmetic differences with no semantic meaning. +
32
+ Only whitespace, line breaks, or indentation differ. +
33
+ Content is semantically identical.
34
+
35
+ h| Informative
36
+ | `<` (removed) +
37
+ `>` (added)
38
+ | Blue (removed) +
39
+ Cyan (added)
40
+ | Differences that don't affect current match results. +
41
+ May become normative with different match option settings. +
42
+ Provides context about ignored differences.
43
+
44
+ h| Normative
45
+ | `-` (removed) +
46
+ `+` (added)
47
+ | Red (removed) +
48
+ Green (added)
49
+ | Semantic differences that affect match results. +
50
+ Requires developer attention. +
51
+ Represents actual content changes.
52
+ |===
53
+
54
+ === Classification hierarchy
55
+
56
+ The classification follows a strict hierarchy:
57
+
58
+ ----
59
+ formatting < informative < normative
60
+ ----
61
+
62
+ A difference is classified using the highest applicable category:
63
+
64
+ normative:: the differences leads to semantic changes that are considered normative
65
+ informative:: the differences leads to semantic changes that are considered informative
66
+ formatting-only:: the differences do not cause any semantic difference
67
+
68
+ == Formatting-only detection
69
+
70
+ Formatting-only differences are detected through aggressive normalization:
71
+
72
+ . Collapse all whitespace (spaces, tabs, newlines) to single space
73
+ . Strip leading and trailing whitespace
74
+ . Compare normalized content
75
+
76
+ If the normalized content is identical, the difference is classified as formatting-only.
77
+
78
+ .Example: Formatting-Only Difference
79
+ ====
80
+ [source]
81
+ ----
82
+ 5| 5[ | <p class="section-break"><br clear="all" class="section"></p>
83
+ | 5] | <p class="section-break"><br clear="all" class="section"><div class="WordSection2">
84
+ 6| 6] | <div class="WordSection2">
85
+ ----
86
+
87
+ These lines differ only in how content is split across lines. The semantic content (when
88
+ whitespace is normalized) is identical, so they show as formatting-only with `[` (dark gray) for
89
+ removed and `]` (light gray) for added lines.
90
+ ====
91
+
92
+ == Color Coding
93
+
94
+ === By Difference Type
95
+
96
+ ==== Formatting-Only (Gray Tones)
97
+
98
+ Formatting-only changes use directional gray tones to indicate low visual priority:
99
+
100
+ * **Dark gray** (`[`): Formatting-only removal
101
+ * **Light gray** (`]`): Formatting-only addition
102
+ * Purely cosmetic
103
+ * Safe to ignore
104
+ * No semantic impact
105
+
106
+ ==== Informative (Blue Tones)
107
+
108
+ Informative changes use blue tones to indicate medium visual priority:
109
+
110
+ * **Blue** (`<`): Informative removal
111
+ * **Cyan** (`>`): Informative addition
112
+ * Context-dependent
113
+ * Currently ignored
114
+ * May matter with different settings
115
+
116
+ ==== Normative (Red/Green)
117
+
118
+ Normative changes use red/green for high visual priority:
119
+
120
+ * **Red** (`-`): Content removed (normative difference)
121
+ * **Green** (`+`): Content added (normative difference)
122
+ * Requires attention
123
+ * Affects comparison result
124
+
125
+ == Symbol Meanings
126
+
127
+ === Line-Level Markers
128
+
129
+ ==== Formatting Markers (Gray)
130
+
131
+ * `[` - Line removed (formatting-only difference, dark gray)
132
+ * `]` - Line added (formatting-only difference, light gray)
133
+
134
+ ==== Informative Markers (Blue)
135
+
136
+ * `<` - Line removed (informative difference, blue)
137
+ * `>` - Line added (informative difference, cyan)
138
+
139
+ ==== Normative Markers (Red/Green)
140
+
141
+ * `-` - Line removed (normative difference, red)
142
+ * `+` - Line added (normative difference, green)
143
+
144
+ ==== Context Marker
145
+
146
+ * ` ` (space) - Unchanged line (context)
147
+
148
+ === Line Numbers
149
+
150
+ Line numbers are displayed in yellow with pipe separators:
151
+
152
+ ```
153
+ 123| 45+ | content here
154
+ ^^^^ ^^
155
+ old new
156
+ line line
157
+ ```
158
+
159
+ * Left number: Line number in original file
160
+ * Right number: Line number in modified file
161
+ * Empty space (` `) when line doesn't exist in that file
162
+
163
+ == Visual Examples
164
+
165
+ === Formatting-Only Change (Gray Tones)
166
+
167
+ [source]
168
+ ----
169
+ 5| 5[ | <p>Content that spans (dark gray)
170
+ | 5] | <p>Content that spans multiple lines</p> (light gray)
171
+ 6| 6] | multiple lines</p> (light gray)
172
+ ----
173
+
174
+ === Informative Change (Blue Tones)
175
+
176
+ [source]
177
+ ----
178
+ 10| 10< | <div class="test"> (blue)
179
+ | 10> | <div class="test"> (cyan)
180
+ ----
181
+
182
+ === Normative Change (Red/Green)
183
+
184
+ [source]
185
+ ----
186
+ 15| 15- | <title>Old Title</title> (red)
187
+ | 15+ | <title>New Title</title> (green)
188
+ ----
189
+
190
+ === Mixed Context
191
+
192
+ [source]
193
+ ----
194
+ 20| 20 | <body>
195
+ 21| 21[ | <p>Hello</p> (dark gray)
196
+ | 21] | <p>Hello</p><span>World</span> (light gray)
197
+ 22| 22] | <span>World</span> (light gray)
198
+ 23| 23- | <footer>2023</footer> (red)
199
+ | 23+ | <footer>2024</footer> (green)
200
+ 24| 24 | </body>
201
+ ----
202
+
203
+ This example shows:
204
+
205
+ * Line 20, 24: Unchanged context (space marker)
206
+ * Lines 21-22: Formatting-only change (`[` dark gray, `]` light gray)
207
+ * Line 23: Normative change (`-` red, `+` green)
208
+
209
+ == Configuration
210
+
211
+ Colors can be disabled for terminal compatibility:
212
+
213
+ [source,ruby]
214
+ ----
215
+ result = Canon.compare(doc1, doc2, format: :xml, use_color: false)
216
+ ----
217
+
218
+ When colors are disabled:
219
+
220
+ * Markers remain (` [ ] < > - +`)
221
+ * All text appears in terminal default color
222
+ * Line numbers and pipes remain visible
223
+
224
+
225
+
226
+
227
+ === Tree Diff Symbols
228
+
229
+ In by-object diff mode, box-drawing characters create a visual tree structure:
230
+
231
+ [cols="1,3"]
232
+ |===
233
+ |Symbol |Meaning
234
+
235
+ |`├──`
236
+ |Tree branch (child element)
237
+
238
+ |`└──`
239
+ |Last tree branch (last child)
240
+
241
+ |`│`
242
+ |Tree continuation (vertical line)
243
+
244
+ |`-`
245
+ |Deletion marker (red)
246
+
247
+ |`+`
248
+ |Addition marker (green)
249
+
250
+ |`~`
251
+ |Change marker (yellow)
252
+ |===
253
+
254
+ .Example: Tree structure with symbols
255
+ [example]
256
+ ====
257
+ [source]
258
+ ----
259
+ root
260
+ ├── - item: "Old value" # Deleted (red -)
261
+ ├── + item: "New value" # Added (green +)
262
+ └── ~ title # Modified (yellow ~)
263
+ ├── - "Old Title" # Old value
264
+ └── + "New Title" # New value
265
+ ----
266
+ ====
267
+
268
+ == Character Visualization Symbols
269
+
270
+ When `use_color: true`, Canon visualizes invisible characters using Unicode symbols. See link:character-visualization.html[Character Visualization] for the complete mapping.
271
+
272
+ Common examples:
273
+
274
+ [cols="2,1,2"]
275
+ |===
276
+ |Character |Symbol |Unicode
277
+
278
+ |Regular space
279
+ |`░`
280
+ |U+2591 (Light Shade)
281
+
282
+ |Tab
283
+ |`⇥`
284
+ |U+21E5 (Rightwards Arrow to Bar)
285
+
286
+ |Non-breaking space
287
+ |`␣`
288
+ |U+2423 (Open Box)
289
+
290
+ |Line feed
291
+ |`↵`
292
+ |U+21B5 (Downwards Arrow with Corner Leftwards)
293
+
294
+ |Zero-width space
295
+ |`→`
296
+ |U+2192 (Rightwards Arrow)
297
+ |===
298
+
299
+ == Namespace Rendering
300
+
301
+ === Namespace Display Format
302
+
303
+ Canon makes namespace information explicit in diff output, particularly when comparing XML elements and attributes:
304
+
305
+ [cols="2,3"]
306
+ |===
307
+ |Namespace State |Display Format
308
+
309
+ |Empty namespace
310
+ |`ns:[{blank}]`
311
+
312
+ |Populated namespace
313
+ |`ns:[http://example.com]`
314
+ |===
315
+
316
+ .Example: Namespace display in diff output
317
+ [example]
318
+ ====
319
+ [source]
320
+ ----
321
+ # Element with no namespace
322
+ - <element ns:[{blank}]>content</element>
323
+
324
+ # Element with namespace
325
+ + <element ns:[http://example.com]>content</element>
326
+ ----
327
+ ====
328
+
329
+ === Namespace Mismatch Classification
330
+
331
+ When elements or attributes differ, Canon classifies the mismatch type:
332
+
333
+ [cols="2,3"]
334
+ |===
335
+ |Mismatch Type |Message Format
336
+
337
+ |Same namespace, different name
338
+ |`mismatched element name: 'oldname' vs 'newname' (ns:[http://example.com])`
339
+
340
+ |Different namespace, same name
341
+ |`mismatched element namespace: 'element' (ns:[{blank}] vs ns:[http://example.com])`
342
+
343
+ |Both name and namespace differ
344
+ |`mismatched element name and namespace: 'old' (ns:[uri1]) vs 'new' (ns:[uri2])`
345
+ |===
346
+
347
+ .Example: Namespace mismatch messages
348
+ [example]
349
+ ====
350
+ [source]
351
+ ----
352
+ # Name differs, same namespace
353
+ mismatched element name: 'item' vs 'product' (ns:[http://shop.com])
354
+
355
+ # Namespace differs, same name
356
+ mismatched element namespace: 'element' (ns:[{blank}] vs ns:[http://example.com])
357
+ ----
358
+ ====
359
+
360
+ === Attribute Namespace Rendering
361
+
362
+ The same namespace rendering applies to attributes:
363
+
364
+ .Example: Attribute namespace in diffs
365
+ [example]
366
+ ====
367
+ [source]
368
+ ----
369
+ # Attribute with no namespace
370
+ - <element attr="value" ns:[{blank}]/>
371
+
372
+ # Attribute with namespace
373
+ + <element ns:attr="value" ns:[http://ns.com]/>
374
+
375
+ # Mismatch message
376
+ mismatched attribute namespace: 'id' (ns:[{blank}] vs ns:[http://example.com])
377
+ ----
378
+ ====
379
+
380
+ == Header and Metadata Colors
381
+
382
+ [cols="2,2,3"]
383
+ |===
384
+ |Element |Color |Purpose
385
+
386
+ |Section headers
387
+ |Cyan + Bold
388
+ |"Visual Diff:", "Line-by-line diff:", etc.
389
+
390
+ |Algorithm name
391
+ |Cyan + Bold
392
+ |"Algorithm: SEMANTIC TREE DIFF", "Algorithm: DOM DIFF"
393
+
394
+ |Success messages
395
+ |Green + Bold
396
+ |"✅ Files are semantically equivalent"
397
+
398
+ |Separators
399
+ |Cyan + Bold
400
+ |"━━━━" (Unicode box drawing)
401
+
402
+ |Legend headers
403
+ |Cyan + Bold
404
+ |"Character Visualization Legend:"
405
+
406
+ |Category names
407
+ |Yellow + Bold
408
+ |"Common Whitespace:", "Unicode Spaces:", etc.
409
+ |===
410
+
411
+ == Normative vs Informative Classification
412
+
413
+ The color distinction between normative and informative diffs is crucial:
414
+
415
+ === Normative Diffs (Red/Green)
416
+
417
+ **Definition**: Differences that cause files to be non-equivalent based on the current match configuration.
418
+
419
+ **When shown**:
420
+ * Match dimension is set to `:strict` or `:normalize`
421
+ * The difference persists even after applying normalization
422
+
423
+ .Example: Normative attribute difference
424
+ [example]
425
+ ====
426
+ [source]
427
+ ----
428
+ # With attribute_order: :strict
429
+ 5| -| <item id="a" name="foo"/> # Red (normative)
430
+ | 6+| <item name="foo" id="a"/> # Green (normative)
431
+ ----
432
+
433
+ The attribute order difference is normative because `attribute_order: :strict` treats it as significant.
434
+ ====
435
+
436
+ === Informative Diffs (Cyan)
437
+
438
+ **Definition**: Differences that don't affect file equivalence based on the current match configuration.
439
+
440
+ **When shown**:
441
+ * Match dimension is set to `:ignore` or `:normalize` handled the difference
442
+ * The difference exists but is ignored for equivalence purposes
443
+ * Shown with `show_diffs: :all` or `show_diffs: :informative`
444
+
445
+ .Example: Informative whitespace difference
446
+ [example]
447
+ ====
448
+ [source]
449
+ ----
450
+ # With structural_whitespace: :ignore
451
+ 5| ~~ | <item> # Cyan (informative)
452
+ | ~~ | <name>Widget</name> # Extra indentation ignored
453
+ ----
454
+
455
+ The whitespace difference is informative because `structural_whitespace: :ignore` means it doesn't affect equivalence.
456
+ ====
457
+
458
+ == Color Control
459
+
460
+ === Enabling/Disabling Colors
461
+
462
+ Colors are controlled by the `use_color` option:
463
+
464
+ .CLI
465
+ [example]
466
+ ====
467
+ [source,bash]
468
+ ----
469
+ # Enable colors (default)
470
+ canon diff file1.xml file2.xml --color
471
+
472
+ # Disable colors
473
+ canon diff file1.xml file2.xml --no-color
474
+ ----
475
+ ====
476
+
477
+ .Ruby API
478
+ [example]
479
+ ====
480
+ [source,ruby]
481
+ ----
482
+ # Enable colors
483
+ Canon.compare(file1, file2, format: :xml, color: true)
484
+
485
+ # Disable colors
486
+ Canon.compare(file1, file2, format: :xml, color: false)
487
+ ----
488
+ ====
489
+
490
+ .RSpec
491
+ [example]
492
+ ====
493
+ [source,ruby]
494
+ ----
495
+ RSpec.configure do |config|
496
+ # Enable for local, disable for CI
497
+ config.canon.xml.diff.use_color = !ENV['CI']
498
+ end
499
+ ----
500
+ ====
501
+
502
+ === Environment Variable
503
+
504
+ [source,bash]
505
+ ----
506
+ # Disable colors globally
507
+ export CANON_USE_COLOR=false
508
+
509
+ # Enable colors globally
510
+ export CANON_USE_COLOR=true
511
+ ----
512
+
513
+
514
+ == Diff Type Display Options
515
+
516
+ Control which types of diffs to show using the `show_diffs` option:
517
+
518
+ [cols="2,3"]
519
+ |===
520
+ |Option |What's Shown
521
+
522
+ |`:all` (default)
523
+ |Both normative and informative diffs
524
+
525
+ |`:normative`
526
+ |Only normative diffs (red/green)
527
+
528
+ |`:informative`
529
+ |Only informative diffs (cyan)
530
+ |===
531
+
532
+ .Example: Show only normative diffs
533
+ [example]
534
+ ====
535
+ [source,bash]
536
+ ----
537
+ # CLI - only show differences that affect equivalence
538
+ canon diff file1.xml file2.xml --show-diffs normative
539
+ ----
540
+
541
+ [source,ruby]
542
+ ----
543
+ # Ruby API
544
+ Canon.compare(file1, file2,
545
+ format: :xml,
546
+ show_diffs: :normative
547
+ )
548
+ ----
549
+ ====
550
+
551
+ == Visual Examples
552
+
553
+ === Complete Diff with All Colors
554
+
555
+ .Full-color diff example
556
+ [example]
557
+ ====
558
+ [source]
559
+ ----
560
+ Algorithm: SEMANTIC TREE DIFF # Cyan + Bold
561
+
562
+ Visual Diff: # Cyan + Bold
563
+ root
564
+ ├── ~ attributes # Yellow (normative)
565
+ │ ├── - id: "old" # Red (normative deletion)
566
+ │ └── + id: "new" # Green (normative addition)
567
+ ├── ~~ whitespace # Cyan (informative)
568
+ │ └── ~~ extra spaces # Cyan (informative)
569
+ └── + element # Green (normative addition)
570
+ └── value: "new"
571
+
572
+ Line-by-line diff (XML mode): # Cyan + Bold
573
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ # Cyan
574
+
575
+ 1| 1 | <root> # Default (context)
576
+ 2| -| <item░id="old"/> # Red (normative deletion)
577
+ | 2+| <item░id="new"/> # Green (normative addition)
578
+ 3| ~~ | <p>Text</p> # Cyan (informative)
579
+ | ~~ | <p>░░Text</p> # Cyan (extra spaces, informative)
580
+ ----
581
+ ====
582
+
583
+ == Colorblind-Friendly Features
584
+
585
+ While Canon uses colors, it also provides symbols that work without color:
586
+
587
+ * **Symbols** (`-`, `+`, `~`) distinguish change types
588
+ * **Line numbers** show correspondence
589
+ * **Tree structure** shows hierarchy
590
+ * **Text labels** describe differences
591
+
592
+ The combination ensures diffs are readable even without color perception.
593
+
594
+
595
+ == Related Features
596
+
597
+ * link:display-filtering.adoc[Display Filtering] - Control which diff types to show
598
+ * link:context-and-grouping.adoc[Context and Grouping] - Control surrounding context
599
+ * link:../match-options/index.adoc[Match Options] - Configure what's considered normative vs informative
600
+
601
+ == See Also
602
+
603
+ * link:character-visualization.html[Character Visualization] - Detailed whitespace visualization
604
+ * link:algorithm-specific-output.html[Algorithm-Specific Output] - Diff format variations
605
+ * link:context-and-grouping.html[Context and Grouping] - Controlling diff context
606
+ * link:../index.html[Diff Formatting] - Overview of formatting features