Skip to content

reznakt/svglab

Repository files navigation

GitHub Actions Workflow Status GitHub License PyPI - Version PyPI - Python Version Maintenance Dependency status GitHub repo size LOC


svglab

A manipulation and optimization library for Scalable Vector Graphics


Table of Contents

About The Project

Features

  • SVG parsing, manipulation, and writing
  • Support for all SVG 1.1 elements and attributes
  • Support for special XML elements (CDATA, comments, text)
  • Attributes are parsed into native Python types for easy manipulation
  • Highly configurable formatting options:
    • indentation level
    • maximum precision for floating-point numbers
    • color mode (rgb, rgba, hsl, hex, named)
    • relative/absolute path commands
    • scientific notation for small/large numbers
    • and many more...
  • Strong type safety:
    • one class per distinct SVG element
    • typed attributes
    • runtime validation thanks to pydantic
  • Support for all beautifulsoup4 parsers (e.g., html.parser, lxml, html5lib)
---
title: Element hierarchy
---

graph TD
  Element:::abc --> TextElement
  Element --> Tag

  Tag:::abc --> PairedTag

  PairedTag:::abc --> G
  PairedTag --> Svg
  PairedTag --> etc1[...]

  Tag --> Rect
  Tag --> Circle
  Tag --> etc2[...]

  TextElement:::abc --> RawText
  TextElement --> Comment
  TextElement --> CData

  etc1:::etc
  etc2:::etc

  classDef abc stroke:white,stroke-width:2px;
  classDef etc stroke:gray,stroke-width:2px;
  classDef default stroke:orange,stroke-width:2px;
Loading

(back to top)

Getting Started

Prerequisites

Installation

From PyPi:

pip install svglab

From source:

# Via HTTPS
pip install git+/~https://github.com/reznakt/svglab.git

# Via SSH
pip install git+ssh://git@github.com/reznakt/svglab.git

(back to top)

Usage

from svglab import (
    CData,
    Comment,
    G,
    Path,
    Polyline,
    RawText,
    Rect,
    parse_svg,
)
from svglab.attrparse import Color, D, Length, Point, SkewX, Translate
from svglab.serialize import Formatter, set_formatter


# Configure custom formatting options
set_formatter(Formatter(indent=4, max_precision=2, color_mode="rgb"))


# Parse an existing SVG file
svg = parse_svg(
    """
    <svg xmlns="http://www.w3.org/2000/svg">
      <g>
          <rect
            id="background"
            width="100cm"
            height="100%"
            transform="rotate(45)"
            stroke="red"
          />
          <rect color="hsl(0, 100%, 100%)"/>
          <!-- This is a comment -->
          <![CDATA[.background { fill: blue; }]]>
          Hello SVG!
          <path d="M 10,10 L 100,100 Q 100,100 50,50 Z"/>
          <polygon points="0,0 100,0 100,100 0,100"/>
      </g>
    </svg>
"""
)

print(svg)

# Create an element programmatically
group = G().add_children(
    Rect(
        width=Length(15, "px"),
        height=Length(20),
        transform=[SkewX(45.123), Translate(10, 20)],
        color=Color("#ff0000"),
    ),
    Comment("This is a comment"),
    CData(".background { fill: blue; }"),
    RawText("Hello SVG!"),
    Path(
        d=D()
        .move_to(Point(10, 10))
        .line_to(Point(100, 100))
        .quadratic_bezier_to(Point(100, 100), Point(50, 50))
        .move_to(Point(50, 50))
        .cubic_bezier_to(
            Point(100, 100), Point(100, 100), Point(10, 10)
        )
        .arc_to(
            Point(50, 50), 90, Point(100, 100), large=True, sweep=False
        )
        .close()
    ),
    Polyline(
        points=[
            Point(0, 0),
            Point(100, 0),
            Point(100, 100),
            Point(0, 100),
        ],
        stroke_linecap="square",
        opacity=0.5,
    ),
)

# Add the element to the SVG
svg.add_child(group)

# Manipulate attributes
print(svg.xmlns)  # http://www.w3.org/2000/svg
svg.x = Length(10, "px")

# Save to a file
svg.save("output.svg")

# Search the element tree
print(svg.find(G).find(Rect).width)
print(*svg.find_all(Rect), sep="\n")

(back to top)

Development

Setup

# Install dependencies
poetry install

# Activate the virtual environment
poetry shell

# Optional: Install pre-commit hooks
pre-commit install

Common tasks

# Run tests
poe test

# Run type checker
poe typecheck

# Run linter
poe lint

# Fix linting errors
poe lint-fix

# Run formatter
poe format

# Fix formatting errors
poe format-fix

(back to top)

License

This software is distributed under the MIT License. See LICENSE for more information.

(back to top)