1. Scope
This document describes Canon’s command-line interface (CLI). The canon
command provides file formatting and comparison capabilities.
For Ruby API usage, see Ruby API documentation.
For RSpec testing, see RSpec documentation.
2. General
After installing the Canon gem, the canon command becomes available in your
shell. It provides two main commands:
-
canon format- Format files in XML, HTML, JSON, or YAML -
canon diff- Compare files semantically
4. Format command
The format command formats files in canonical or pretty-print mode.
4.2. Output modes
pretty(default)-
Human-readable output with indentation (2 spaces)
c14n-
Canonical form without indentation (compact)
4.3. Options
-f, --format FORMAT-
Specify format:
xml,html,json, oryaml(auto-detected from extension if not specified) -m, --mode MODE-
Output mode:
pretty(default) orc14n -i, --indent N-
Indentation spaces for pretty mode (default: 2)
--indent-type TYPE-
Indentation type:
space(default) ortab -o, --output FILE-
Write output to file instead of stdout
-c, --with-comments-
Include comments in canonical XML output
4.4. Format detection
When --format is not specified, Canon detects the format from file extension:
| File Extension | Detected Format |
|---|---|
|
XML |
|
HTML |
|
JSON |
|
YAML |
4.5. Examples
$ canon format input.xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<a>1</a>
<b>2</b>
</root>
$ canon format input.xml --mode c14n
<root><a>1</a><b>2</b></root>
# 4-space indentation
$ canon format input.xml --mode pretty --indent 4
# Tab indentation
$ canon format input.xml --indent-type tab
# JSON with 4 spaces
$ canon format data.json --indent 4
# Format a .txt file as XML
$ canon format data.txt --format xml
$ canon format input.xml --output formatted.xml
# Or use shell redirection
$ canon format input.xml > formatted.xml
$ canon format doc.xml --mode c14n --with-comments
# HTML files
$ canon format page.html
$ canon format page.html --mode c14n
# JSON files
$ canon format config.json
$ canon format config.json --indent 4
# YAML files
$ canon format data.yaml
5. Diff command
The diff command performs semantic comparison of files.
5.2. Diff modes
Canon supports two diff modes optimized for different use cases:
by-object-
(default for JSON/YAML) Semantic tree-based diff showing structural changes
by-line-
(default for HTML, optional for XML) Line-by-line diff after canonicalization
See Diff modes for details.
5.3. Format options
-f, --format FORMAT-
Format for both files:
xml,html,json, oryaml(auto-detected from extension if not specified) --format1 FORMAT-
Format of first file (when comparing different formats)
--format2 FORMAT-
Format of second file (when comparing different formats)
5.4. Comparison options
-v, --verbose-
Show detailed differences (default: just show if files differ)
--diff-algorithm ALGORITHM-
Diff algorithm to use:
dom(default) orsemantic. DOM uses positional matching, semantic uses tree-based matching with operation detection. --by-line-
Use line-by-line diff for XML (default: by-object mode)
--text-content BEHAVIOR-
How to compare text content:
strict,normalize, orignore --structural-whitespace BEHAVIOR-
How to handle whitespace between elements:
strict,normalize, orignore --attribute-whitespace BEHAVIOR-
How to handle whitespace in attribute values:
strict,normalize, orignore(XML/HTML only) --attribute-order BEHAVIOR-
Whether attribute order matters:
strictorignore(XML/HTML only) --attribute-values BEHAVIOR-
How to compare attribute values:
strict,normalize, orignore(XML/HTML only) --key-order BEHAVIOR-
Whether key order matters:
strictorignore(JSON/YAML only) --comments BEHAVIOR-
How to handle comments:
strict,normalize, orignore --match-profile PROFILE-
Use predefined match profile:
strict,rendered,spec_friendly, orcontent_only
See Match options for detailed dimension reference.
5.5. Output options
--color/--no-color-
Enable/disable colored output (default: enabled)
--context-lines N-
Number of context lines around changes (default: 3)
--diff-grouping-lines N-
Group changes within N lines into blocks
See Diff formatting for details.
5.6. Exit codes
-
0- Files are semantically equivalent -
1- Files are semantically different -
Other - Error occurred
5.7. Examples
# Compare two JSON files
$ canon diff config1.json config2.json
Files are semantically different
# Compare two XML files
$ canon diff file1.xml file2.xml
✅ Files are semantically equivalent
$ canon diff config1.json config2.json --verbose
Visual Diff:
├── settings.debug:
│ ├── - true
│ └── + false
└── version:
├── - "1.0.0"
└── + "2.0.0"
$ canon diff document1.xml document2.xml --by-line --verbose
Line-by-line diff:
4 - | <foreword id="fwd">
4 + | <foreword displayorder="2" id="fwd">
5 | <p>First paragraph</p>
10 + | <p>New content</p>
11 | </clause>
$ canon diff page1.html page2.html --verbose
Line-by-line diff:
4 - | <title>My Page</title>
4 + | <title>My Updated Page</title>
7 - | <div class="header">
7 + | <nav class="header">
# Use spec_friendly profile
$ canon diff file1.xml file2.xml \
--match-profile spec_friendly \
--verbose
# Use rendered profile for HTML
$ canon diff page1.html page2.html \
--match-profile rendered \
--verbose
# Use strict profile (exact matching)
$ canon diff file1.xml file2.xml \
--match-profile strict \
--verbose
# Normalize text content, ignore whitespace
$ canon diff file1.xml file2.xml \
--text-content normalize \
--structural-whitespace ignore \
--verbose
# Ignore comments and attribute order
$ canon diff file1.xml file2.xml \
--comments ignore \
--attribute-order ignore \
--verbose
# Multiple dimension overrides
$ canon diff file1.xml file2.xml \
--text-content normalize \
--structural-whitespace ignore \
--attribute-whitespace normalize \
--comments ignore \
--verbose
# Use spec_friendly but require strict comments
$ canon diff file1.xml file2.xml \
--match-profile spec_friendly \
--comments strict \
--verbose
# Show more context lines
$ canon diff file1.xml file2.xml \
--verbose \
--context-lines 5
# Group nearby changes
$ canon diff file1.xml file2.xml \
--verbose \
--diff-grouping-lines 10
# Disable colors for piping to files
$ canon diff file1.xml file2.xml \
--verbose \
--no-color > diff.txt
# Combine diff options
$ canon diff file1.xml file2.xml \
--verbose \
--context-lines 5 \
--diff-grouping-lines 2 \
--no-color
# Compare JSON with YAML (must have same structure)
$ canon diff config.json config.yaml \
--format1 json \
--format2 yaml \
--verbose
# JSON comparison (uses by-object mode by default)
$ canon diff config1.json config2.json --verbose
# YAML comparison with key order ignored
$ canon diff data1.yaml data2.yaml \
--key-order ignore \
--verbose
# Show 10 context lines for large config files
$ canon diff large-config1.json large-config2.json \
--verbose \
--context-lines 10
# Use in scripts
if canon diff expected.xml actual.xml; then
echo "Files match!"
else
echo "Files differ"
canon diff expected.xml actual.xml --verbose
fi
# Generate diff report
canon diff file1.xml file2.xml --verbose --no-color > diff-report.txt
# Compare with process substitution
canon diff <(curl https://example.com/api/v1) \
<(curl https://example.com/api/v2) \
--format json \
--verbose