Skip to main content

Pure-Python cross-platform parser for Vexy Lines .lines vector art files

Project description

vexy-lines-py

Parse Vexy Lines .lines vector art files in pure Python — no app, no macOS, no heavy dependencies.

Install

pip install vexy-lines-py

Python 3.11+. Runtime dependency: loguru only.

Quick start

from vexy_lines import parse, GroupInfo, LayerInfo

doc = parse("artwork.lines")
print(doc.caption, doc.dpi)          # "My Art"  300
print(doc.props.width_mm, "x", doc.props.height_mm, "mm")

# Walk the layer tree
for node in doc.groups:
    if isinstance(node, GroupInfo):
        for child in node.children:
            if isinstance(child, LayerInfo):
                for fill in child.fills:
                    p = fill.params
                    print(p.fill_type, p.color, f"interval={p.interval}")
                    # "linear"  "#1a2b3c"  interval=2.5
                    for image_filter in fill.image_filters:
                        print(image_filter.name, image_filter.params)
                        # "brightness" {"value": 25.0}

# Embedded source image (JPEG)
if doc.source_image_data:
    open("source.jpg", "wb").write(doc.source_image_data)

# Embedded preview image (PNG)
if doc.preview_image_data:
    open("preview.png", "wb").write(doc.preview_image_data)

Convenience wrappers for image extraction:

from vexy_lines import extract_source_image, extract_preview_image

extract_source_image("artwork.lines", "source.jpg")
extract_preview_image("artwork.lines", "preview.png")

API

Read-only parser. This package parses .lines files but does not support creating or writing them. For creating and manipulating .lines documents, use vexy-lines-apy with the MCP API.

parse(path) -> LinesDocument

Parse a .lines file and return a fully populated LinesDocument.

  • FileNotFoundError — path does not exist
  • xml.etree.ElementTree.ParseError — file is not valid XML

parse_string(xml_text) -> LinesDocument

Parse a .lines XML string (in-memory) and return a LinesDocument. Useful when the XML content is already loaded or received from another source.

  • xml.etree.ElementTree.ParseError — string is not valid XML

extract_source_image(path, output) -> Path

Parse and save the embedded JPEG source image to output. Raises ValueError if no source image is present.

extract_preview_image(path, output) -> Path

Parse and save the embedded PNG preview to output. Raises ValueError if no preview is present.

Editing .lines files

Three helpers edit a .lines file while preserving everything else (fill parameters, masks, mesh, document settings) byte-for-byte. Each writes to output_path (pass the same path as the input to edit in place).

replace_source_image(lines_path, new_image_path, output_path, *, target_size=None) -> Path

Swap the embedded JPEG source image, reusing a .lines file's fill style with new content. Requires pillow. Raises FileNotFoundError if an input is missing, ValueError if there is no <SourcePict>.

rename_objects(lines_path, output_path, renames) -> int

Rewrite the caption of groups, layers, and/or fills. renames maps object_id (from GroupInfo/LayerInfo/FillNode) to a new caption; returns the number actually changed (a caption already equal to its target is not counted). Only canonical definitions are touched — href reference elements have no object_id.

set_visibility(lines_path, output_path, visible) -> int

Set the visible="0"/"1" attribute (absent = visible) per object_id; returns the number changed. Toggling visibility live over the app's MCP API does not change what the app exports, but baking the attribute into a copy and re-opening it does — this is how the AI-rename feature renders one fill in isolation.

from vexy_lines import rename_objects, set_visibility

rename_objects("artwork.lines", "artwork.lines", {1: "Background", 10: "Sky lines"})
set_visibility("artwork.lines", "fill_10_only.lines", {10: True, 11: False, 12: False})

Both raise FileNotFoundError if lines_path is missing.

Types

Type Key attributes
LinesDocument caption, version, dpi, props, groups, source_image_data, preview_image_data
DocumentProps width_mm, height_mm, dpi, thickness_min/max, interval_min/max
GroupInfo caption, object_id, expanded, `children: list[GroupInfo
LayerInfo caption, object_id, visible, mask, fills: list[FillNode], grid_edges
FillNode xml_tag, caption, params: FillParams, image_filters: list[ImageFilterEntry], object_id
FillParams fill_type, color, interval, angle, thickness, smoothness, uplimit, downlimit, multiplier, dispersion, shear, raw
ImageFilterEntry type_id, name, params, raw
MaskInfo mask_type, invert, tolerance

FillParams.raw holds every original XML attribute, including algorithm-specific keys not promoted to named fields.

FillNode.image_filters holds the ordered source-image filter chain saved inside a fill's <image_filters> child. Known filters are named brightness, contrast, blur, sharpen, levels, shadows_highlights, invert, remove_background, color, and gradient; unknown future filter IDs are preserved as unknown_<id> with their raw attributes.

Colors are normalised to #RRGGBB (opaque) or #RRGGBBAA. The raw Vexy Lines #AARRGGBB encoding is converted automatically.

Fill types

11 fill algorithms are recognised in FillParams.fill_type:

Value Algorithm XML Tag
linear Parallel straight lines LinearStrokesTmpl
wave Sine-wave strokes SigmoidStrokesTmpl
circular Concentric circles CircleStrokesTmpl
radial Lines radiating from a centre point RadialStrokesTmpl
spiral Archimedean spirals SpiralStrokesTmpl
scribble Random scribble-style strokes ScribbleStrokesTmpl
halftone Halftone dot/line patterns HalftoneStrokesTmpl
handmade Sketch-style handmade strokes FreeCurveStrokesTmpl
fractals Fractal / Peano space-filling strokes PeanoStrokesTmpl
trace Strokes following image contours TracedAreaTmpl
source_strokes Strokes derived from the source image SourceStrokes

FreeCurveStrokesTmpl with attribute type_conv="9" is resolved to trace at parse time (otherwise handmade).

The mapping from XML tags to these names is available as FILL_TAG_MAP. The full set of recognised tags is FILL_TAGS.

Full documentation

Read the docs for the complete API reference, file format specification, and more examples.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vexy_lines_py-1.0.35.tar.gz (11.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vexy_lines_py-1.0.35-py3-none-any.whl (22.5 kB view details)

Uploaded Python 3

File details

Details for the file vexy_lines_py-1.0.35.tar.gz.

File metadata

  • Download URL: vexy_lines_py-1.0.35.tar.gz
  • Upload date:
  • Size: 11.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for vexy_lines_py-1.0.35.tar.gz
Algorithm Hash digest
SHA256 3e8a7ec583af355f6b3b165087818b0b0b15e274f375f1c443a5de4ff550593e
MD5 281a821ddb5cd54f469d37899884df0a
BLAKE2b-256 cd0094fa0b1b80c69e023752145703a24359203c34249b88486d725482cf8db2

See more details on using hashes here.

File details

Details for the file vexy_lines_py-1.0.35-py3-none-any.whl.

File metadata

  • Download URL: vexy_lines_py-1.0.35-py3-none-any.whl
  • Upload date:
  • Size: 22.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for vexy_lines_py-1.0.35-py3-none-any.whl
Algorithm Hash digest
SHA256 eee4b903c3b7bbd52c8d5a41d710057b8a87e22941d6770b6b0346b555ee5351
MD5 68926e81d10e6932f01fc2579ce76a37
BLAKE2b-256 b4f85d5827161b36b7770979fde55245aa591e568a303b648692d37c4d4796bc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page