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

3. Installation

$ gem install canon
$ canon --help

4. Format command

The format command formats files in canonical or pretty-print mode.

4.1. Syntax

canon format FILE [OPTIONS]

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, or yaml (auto-detected from extension if not specified)

-m, --mode MODE

Output mode: pretty (default) or c14n

-i, --indent N

Indentation spaces for pretty mode (default: 2)

--indent-type TYPE

Indentation type: space (default) or tab

-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

XML

.html, .htm

HTML

.json

JSON

.yaml, .yml

YAML

4.5. Examples

Example 1. Pretty-print with default settings
$ canon format input.xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
  <a>1</a>
  <b>2</b>
</root>
Example 2. Canonical mode (compact)
$ canon format input.xml --mode c14n
<root><a>1</a><b>2</b></root>
Example 3. Custom indentation
# 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
Example 4. Specify format explicitly
# Format a .txt file as XML
$ canon format data.txt --format xml
Example 5. Save to file
$ canon format input.xml --output formatted.xml

# Or use shell redirection
$ canon format input.xml > formatted.xml
Example 6. Include XML comments in canonical output
$ canon format doc.xml --mode c14n --with-comments
Example 7. Format different file types
# 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.1. Syntax

canon diff FILE1 FILE2 [OPTIONS]

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, or yaml (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) or semantic. 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, or ignore

--structural-whitespace BEHAVIOR

How to handle whitespace between elements: strict, normalize, or ignore

--attribute-whitespace BEHAVIOR

How to handle whitespace in attribute values: strict, normalize, or ignore (XML/HTML only)

--attribute-order BEHAVIOR

Whether attribute order matters: strict or ignore (XML/HTML only)

--attribute-values BEHAVIOR

How to compare attribute values: strict, normalize, or ignore (XML/HTML only)

--key-order BEHAVIOR

Whether key order matters: strict or ignore (JSON/YAML only)

--comments BEHAVIOR

How to handle comments: strict, normalize, or ignore

--match-profile PROFILE

Use predefined match profile: strict, rendered, spec_friendly, or content_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

Example 8. Basic comparison
# 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
Example 9. Verbose mode with detailed diff
$ canon diff config1.json config2.json --verbose
Visual Diff:
├── settings.debug:
│   ├── - true
│   └── + false
└── version:
    ├── - "1.0.0"
    └── + "2.0.0"
Example 10. XML comparison with by-line mode
$ 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>
Example 11. HTML comparison
$ 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">
Example 12. Using match profiles
# 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
Example 13. Customize match dimensions
# 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
Example 14. Combine profile with dimension overrides
# Use spec_friendly but require strict comments
$ canon diff file1.xml file2.xml \
  --match-profile spec_friendly \
  --comments strict \
  --verbose
Example 15. Customize diff output
# 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
Example 16. Compare different formats
# Compare JSON with YAML (must have same structure)
$ canon diff config.json config.yaml \
  --format1 json \
  --format2 yaml \
  --verbose
Example 17. JSON/YAML comparison examples
# 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
Example 18. Shell integration
# 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

6. Help command

Get help on available commands and options:

# General help
$ canon help

# Command-specific help
$ canon help format
$ canon help diff

# Show version
$ canon --version