Python wrapper for svg-matrix — a powerful toolkit for SVG optimization, validation, font embedding, and matrix transformations with arbitrary precision.
This package provides Python access to the full svg-matrix toolkit:
| Tool | Purpose | Use Case |
|---|---|---|
| psvgm | SVG optimization | Reduce file size, clean up code, minify |
| psvg-matrix | Matrix operations | Flatten transforms, convert shapes, analyze |
| psvgfonts | Font management | Embed Google Fonts, extract fonts, subset |
| psvglinter | SVG linting | Validate syntax, find issues, auto-fix |
All commands are prefixed with p to avoid conflicts with the JavaScript versions.
Install globally using uv for command-line access:
# Install the tool globally
uv tool install svg-matrix --python 3.12
# Verify installation
psvgm --version
psvgfonts --versionManage your installation:
uv tool upgrade svg-matrix # Upgrade to latest version
uv tool uninstall svg-matrix # Remove the tool
uv tool list # Show all installed toolsFor use in Python scripts and projects:
pip install svg-matrix
# or with uv:
uv add svg-matrixRequires Bun (recommended) or Node.js:
# Install Bun (faster, recommended)
curl -fsSL https://bun.sh/install | bash
# Or use Node.js from https://nodejs.org/The package will attempt to auto-install Bun if neither runtime is found.
# Optimize an SVG (reduce size, clean up)
psvgm input.svg -o output.svg
# Embed Google Fonts into SVG for offline use
psvgfonts embed --woff2 input.svg -o output.svg
# Validate and auto-fix SVG issues
psvglinter --fix input.svg
# Get SVG information (dimensions, elements, fonts)
psvg-matrix info input.svg
# Show all options for any command
psvgm --help
psvgfonts --helpfrom svg_matrix import validate_svg, optimize_svg, run_svgfonts
# Validate an SVG file
result = validate_svg("icon.svg")
if result["valid"]:
print("✓ SVG is valid!")
else:
for issue in result["issues"]:
print(f"✗ {issue['reason']}")
# Optimize an SVG (reduce file size)
optimize_svg("large.svg", "small.svg", precision=4)
# Embed fonts for offline use
result = run_svgfonts(["embed", "--woff2", "-o", "output.svg", "input.svg"])Optimize SVG files: reduce size, clean up code, remove unnecessary elements.
# Basic optimization
psvgm input.svg -o output.svg
# Set decimal precision (fewer decimals = smaller file)
psvgm input.svg -o output.svg -p 4
# Pretty print (human-readable output)
psvgm input.svg -o output.svg --pretty --indent 2
# Process entire directory recursively
psvgm ./icons/ -f ./optimized/ -r
# Show available plugins
psvgm --show-plugins
# Quiet mode (no output except errors)
psvgm input.svg -o output.svg -qEmbed, extract, and manage fonts in SVG files.
# List fonts used in an SVG
psvgfonts list input.svg
# Embed fonts (downloads from Google Fonts, etc.)
psvgfonts embed input.svg -o output.svg
# Embed with WOFF2 compression (30% smaller)
psvgfonts embed --woff2 input.svg -o output.svg
# Embed only glyphs actually used (smallest size)
psvgfonts embed --woff2 --subset input.svg -o output.svg
# Extract embedded fonts to files
psvgfonts extract --extract-dir ./fonts/ input.svg
# Search for fonts by name
psvgfonts search --query "roboto" --limit 10
# Show font cache statistics
psvgfonts cache
# Clean old cached fonts
psvgfonts cache --cache-action clean --max-age 30Flatten transforms, convert shapes, and analyze SVG structure.
# Get SVG information
psvg-matrix info input.svg
# Flatten all transforms into paths
psvg-matrix flatten input.svg -o output.svg
# Convert shapes (rect, circle, etc.) to paths
psvg-matrix convert input.svg -o output.svg
# Remove Inkscape-specific data
psvg-matrix to-plain input.svg -o output.svg
# Normalize coordinates
psvg-matrix normalize input.svg -o output.svgValidate SVG files and auto-fix common issues.
# Check for issues
psvglinter input.svg
# Auto-fix fixable issues
psvglinter --fix input.svg
# Show only errors (no warnings)
psvglinter --errors-only input.svg
# Process directory
psvglinter ./icons/Check SVG files for issues before processing:
from svg_matrix import validate_svg, validate_svg_async
# Validate a file
result = validate_svg("file.svg")
print(f"Valid: {result['valid']}")
print(f"Issues: {result['issues']}")
# Validate SVG string content
svg_content = '<svg xmlns="http://www.w3.org/2000/svg">...</svg>'
result = validate_svg(svg_content)
# Async validation (for batch processing)
import asyncio
result = await validate_svg_async("file.svg")Reduce SVG file size while preserving visual appearance:
from svg_matrix import optimize_svg, optimize_paths
# Full optimization with options
optimize_svg(
"input.svg",
"output.svg",
precision=6, # Decimal precision (default: 6)
minify=True, # Remove whitespace
remove_comments=True, # Remove XML comments
remove_metadata=True # Remove editor metadata
)
# Path-only optimization (faster, less aggressive)
optimize_paths("input.svg", "output.svg", precision=4)Transform SVG structure and remove editor-specific data:
from svg_matrix import to_plain_svg, flatten, convert_shapes
# Remove Inkscape/Illustrator namespaces and metadata
to_plain_svg("inkscape.svg", "plain.svg")
# Flatten transforms, groups, and clipPaths into paths
flatten(
"complex.svg",
"flat.svg",
flatten_transforms=True, # Bake transforms into coordinates
flatten_groups=True, # Merge nested groups
flatten_clipaths=True # Resolve clipping paths
)
# Convert geometric shapes to <path> elements
convert_shapes("shapes.svg", "paths.svg")Make SVGs self-contained by embedding external fonts:
from svg_matrix import run_svgfonts
# List fonts in an SVG
result = run_svgfonts(["list", "input.svg"])
print(result["stdout"])
# Embed fonts with optimal settings
result = run_svgfonts([
"embed",
"--woff2", # Best compression format
"--subset", # Only include used glyphs
"-o", "output.svg", # Output file
"input.svg" # Input file
])
if result["returncode"] == 0:
print("✓ Fonts embedded successfully!")
else:
print(f"✗ Error: {result['stderr']}")
# Extract embedded fonts to files
result = run_svgfonts([
"extract",
"--extract-dir", "./fonts/",
"input.svg"
])
# Search for fonts by name
result = run_svgfonts(["search", "--query", "open sans", "--limit", "5"])See examples/embed_google_fonts.py for a complete working example.
Run any CLI command programmatically:
from svg_matrix import run_svgm, run_svg_matrix, run_svgfonts, run_svglinter, get_info
# Run svgm with any arguments
result = run_svgm(["input.svg", "-o", "output.svg", "-p", "4"])
print(result["stdout"])
print(result["stderr"])
print(f"Exit code: {result['returncode']}")
# Get structured SVG info
info = get_info("file.svg")
print(f"Width: {info.get('width')}")
print(f"Height: {info.get('height')}")
print(f"Elements: {info.get('elements')}")Convert geometric shapes to SVG path data:
from svg_matrix import (
circle_to_path,
ellipse_to_path,
rect_to_path,
line_to_path,
polygon_to_path,
polyline_to_path
)
# Convert a circle at (100, 100) with radius 50
path_data = circle_to_path(cx=100, cy=100, r=50)
# Returns: "M 100 50 C 127.614... 50 150 72.386... ..."
# Convert a rectangle
path_data = rect_to_path(x=0, y=0, width=100, height=50)
# Convert with rounded corners
path_data = rect_to_path(x=0, y=0, width=100, height=50, rx=10, ry=10)
# Convert a polygon (list of [x, y] points)
points = [[0, 0], [100, 0], [50, 100]]
path_data = polygon_to_path(points)Parse, transform, and serialize SVG path data:
from svg_matrix import (
parse_path,
path_to_string,
path_to_absolute,
path_to_cubics,
transform_path
)
# Parse path string to command list
commands = parse_path("M 0 0 L 100 100 C 50 50 150 150 200 200")
# Returns: [{'command': 'M', 'args': ['0', '0']}, ...]
# Convert relative commands to absolute
absolute_path = path_to_absolute("m 10 10 l 20 20")
# Returns: "M 10 10 L 30 30"
# Convert all commands to cubic Bezier curves
cubic_path = path_to_cubics("M 0 0 L 100 100 Q 50 50 100 0")
# All arcs, lines, quadratics become cubic curves
# Apply transformation matrix to path
from svg_matrix import translate_2d
matrix = translate_2d(50, 100)
transformed = transform_path("M 0 0 L 100 100", matrix)Create and combine 2D transformation matrices:
from svg_matrix import (
translate_2d,
rotate_2d,
scale_2d,
transform_2d,
identity,
multiply_matrices
)
import math
# Create transformation matrices
translate = translate_2d(tx=50, ty=100) # Move by (50, 100)
rotate = rotate_2d(angle=math.pi / 4) # Rotate 45 degrees
scale = scale_2d(sx=2, sy=2) # Scale 2x
# Combine matrices (applied right-to-left: scale, rotate, translate)
combined = multiply_matrices(translate, multiply_matrices(rotate, scale))
# Apply matrix to a point
x, y = transform_2d(combined, 10, 20)
# Create identity matrix
I = identity(3) # 3x3 identity matrixControl decimal precision for arbitrary-precision calculations:
from svg_matrix import set_precision, get_precision, get_kappa
# Get current precision (default: 20 decimal places)
print(f"Current precision: {get_precision()}")
# Set higher precision for scientific applications
set_precision(50)
# Get the kappa constant for circular arc approximation
# (used internally for circle_to_path, etc.)
kappa = get_kappa()
print(f"Kappa: {kappa}") # ~0.5522847498...Process multiple SVG files efficiently:
from pathlib import Path
from svg_matrix import validate_svg, optimize_svg
# Process all SVGs in a directory
svg_dir = Path("./input")
output_dir = Path("./output")
output_dir.mkdir(exist_ok=True)
for svg_file in svg_dir.glob("*.svg"):
# Validate first
result = validate_svg(svg_file)
if result["valid"]:
# Optimize valid files
optimize_svg(svg_file, output_dir / svg_file.name, precision=4)
print(f"✓ Optimized: {svg_file.name}")
else:
# Report issues
print(f"✗ Skipped {svg_file.name}:")
for issue in result["issues"]:
print(f" - {issue['reason']}")The examples/ directory contains working examples:
| File | Description |
|---|---|
embed_google_fonts.py |
Complete workflow for embedding Google Fonts |
google_fonts_sample.svg |
Sample SVG using Google Fonts via @import |
Run the example:
cd examples/
python embed_google_fonts.pyThis package is a lightweight Python wrapper (~20KB) around the @emasoft/svg-matrix npm package.
Architecture:
- Python functions call
bunx(ornpxas fallback) - The npm package handles all SVG processing
- Results are returned as Python dictionaries
Benefits:
- Always uses the latest svg-matrix version from npm
- Full feature parity with the JavaScript library
- Minimal Python dependencies
- Works on Windows, macOS, and Linux
Trade-offs:
- Requires Bun or Node.js runtime
- First run downloads the npm package (~1MB)
- Slightly slower startup than native Python
MIT License — see LICENSE