Skip to main content

ezjww

ezjww reads Jw_cad drawings, creates JWW files and converts drawings to DXF. Its Rust core is available through Python and TypeScript/WebAssembly.

  • Read JWW files, JWS registered symbols, and a limited binary JWC profile.
  • Create new version-700 JWW drawings with basic geometry and text (Python/TypeScript/Rust).
  • Read and write the images embedded in version-700 files (^@BM placements).
  • Inspect source records, headers, layers, and parsing diagnostics.
  • Query converted geometry, calculate bounds, and audit drawings.
  • Export ASCII DXF (AC1015 or AC1024) and render PNG/PDF previews.
  • Convert individual files or directories from the command line.

This checkout prepares 0.5.0, adding SXF color/line tables, solids, ellipses, dimensions, blocks and convenience APIs to the writer introduced in 0.4.0. Build from source until 0.5.0 is published.

JWS reading is available in this source checkout. See the JWS guide for supported versions, coordinates and image limits.

Installation

Python 3.9 or later:

pip install ezjww

For previews, install the optional Matplotlib dependency:

pip install "ezjww[plot]"

For Node.js, see the TypeScript package:

npm install ezjww

To build the Python package from source, install a Rust toolchain, then run:

git clone https://github.com/monozukuri-ai/ezjww.git
cd ezjww
pip install .

Python quick start

readfile detects JWW, JWC or JWS from the file contents. Replace drawing.jww with your input path; the same API accepts supported .jwc and .jws files.

import ezjww

drawing = ezjww.readfile("drawing.jww")
print(drawing.source_format, drawing.header)
print(drawing.stats())
print(drawing.bbox())

lines = drawing.modelspace().query("LINE")
health = drawing.audit()
for diagnostic in health["diagnostics"]:
    print(diagnostic["code"], diagnostic["details"])

drawing.save_dxf("drawing.dxf", target_version="AC1024")

Use read_cad_document when you need the original records. Its return value identifies the format and contains the corresponding source document:

import ezjww

cad = ezjww.read_cad_document("drawing.jwc")
source = cad["document"]
print(cad["format"], source["entity_counts"])

# JWC DXF geometry defaults to paper millimeters. Select model millimeters
# to apply each entity's layer-group scale.
model = ezjww.readfile("drawing.jwc", jwc_coordinates="model_millimeters")
model.save_dxf("drawing-model.dxf")
print(model.report()["jwc_conversion_report"]["notices"])

The JWW-specific read_document and read_header keep their original meanings. Use read_jwc_document and read_jwc_header for JWC-specific reads. See the API reference for format detection, coordinate options, errors, and conversion metadata.

Create a JWW drawing

Build this revision from source to use the creation API:

import ezjww

drawing = ezjww.new(paper_size=3, memo="平面図\r\n")  # A3, version 700
msp = drawing.modelspace()
msp.add_line((0, 0), (100, 0), jwwattribs={"pen_color": 3})
msp.add_circle((20, 20), 5)
msp.add_arc((40, 20), 5, start_angle=350, sweep_angle=30)  # degrees, CCW
msp.add_point((60, 20))
msp.add_text("日本語", (0, -10), (9, -10))  # explicit baseline endpoints

drawing.options["layer_groups"][0]["name"] = "平面図"
drawing.saveas("created.jww")
drawing.save_dxf("created.dxf", target_version="AC1024")

Coordinates are paper millimeters, with the origin at the paper center and +Y up. Edit drawing.options and the native entity dictionaries returned by add_*. See JWW writing for supported attributes, validation and native application limits.

API migration: new() / Drawing.new() now create writable JWW drawings. The former empty DXF view is available as new_dxf() / Drawing.new_dxf(). Replace drawing.saveas("out.dxf", ...) with drawing.save_dxf("out.dxf", ...). saveas() writes JWW for new drawings; lossless existing-file editing is outside this release's scope. readfile(...).save_dxf(...) remains the DXF conversion workflow.

Queries and previews

import ezjww

drawing = ezjww.readfile("drawing.jww")
entities = drawing.modelspace().query('LINE POINT[layer=="#lv4", color==5]')
flat = drawing.to_dxf(explode_inserts=True, max_block_nesting=32)

drawing.plot(save_path="drawing.png")  # requires ezjww[plot]
drawing.plot(save_path="drawing.pdf")

DXF TEXT records include a width factor (group 41). For JWW, it is estimated from the stored endpoint span and half/full-width character cells. Actual glyph advances depend on the selected font; this is not an exact fit for every font substitution. JWC retains its existing width/height ratio.

Line type settings

A JWW file also records the line width of each pen color (header["pens"]: screen dots, printer width per pen with its unit, "hundredth_mm" or "dot" at printer_dpi). An entity whose pen_width is 0 prints at its pen color's width, so this table is the line width of most drawings. The writer takes the same table as options["pens"].

A JWW file records how each of its line types is drawn. read_header and read_document report them as header["line_types"] (None for files older than version 3.00):

import ezjww

line_types = ezjww.read_header("drawing.jww")["line_types"]
for item in line_types["standard"]:          # line types 2-9
    print(item["number"], item["runs"], item["segments_mm"])
for item in line_types["sxf"] or []:         # line types 30-62 (version 4.20+)
    print(item["number"], item["name"], item["segments_mm"])
  • standard (2-9: dashed 1-3, chain 1-2, double-dot chain 1-2, construction line) and double_length (16-19) carry the bit pattern, its unit_dots, the screen pitch and the printer_pitch. runs is the pattern as dash and gap lengths in bits, starting with the longest dash, and segments_mm the lengths it prints at: one bit is printer_pitch / 32 mm.
  • random (11-15) carries the amplitude and pitch of the hand-drawn line types.
  • sxf (30-62) carries the SXF-compatible line types with their name and the segments_mm stored in the file. Numbers 47-62 are user-defined.

Entities refer to a line type by pen_style.

DXF line types

The DXF conversion names each Jw_cad line type and defines the ones a drawing uses in the LTYPE table, with the dash pattern the file records (the Jw_cad defaults for files older than version 3.00):

Jw_cad line type DXF linetype
1, SXF 31 CONTINUOUS
2-4 (dashed 1-3) JWW_DASHED1-JWW_DASHED3
5-6 (chain 1-2) JWW_DASHDOT1, JWW_DASHDOT2
7-8 (double-dot chain 1-2) JWW_DIVIDE1, JWW_DIVIDE2
9 (construction line) JWW_CONSTRUCTION
16-19 (double length) JWW_DASHDOT_X2, JWW_DIVIDE_X2, JWW_DASHED_X2, JWW_DASHED_X4
32-45 (SXF predefined) SXF_DASHED, SXF_CHAIN, ...
47-62 (SXF user-defined) SXF_USER_17-SXF_USER_32
11-15 (random lines), undefined numbers BYLAYER

Pattern lengths are millimetres on paper, like the coordinates of a JWW drawing, so the DXF needs no linetype scale. A line type whose pattern the user turned solid has an empty pattern. Jw_cad does not print construction lines (line type 9); they are converted like any other line, on the linetype JWW_CONSTRUCTION, so that a reader can leave them out.

import ezjww

document = ezjww.read_dxf_document("drawing.jww")
for line_type in document["line_types"]:
    print(line_type["name"], line_type["description"], line_type["pattern"])

pattern uses the DXF convention: positive is a dash, negative a gap. JWC drawings keep the fixed linetypes of that format.

Use text_em_scale when a target renderer draws a larger em box per unit of DXF text height. It must be positive and finite; the default is 1.0. This divides the exported text height (group 40). A value such as 1.364 is an example that must be measured for the renderer and font, not a universal correction.

scaled = drawing.to_dxf(text_em_scale=1.364)
ezjww.write_dxf("drawing.jww", "drawing.dxf", text_em_scale=1.364)
drawing.plot(text_em_scale=1.364, save_path="drawing.png")

Previews apply the width factor to glyphs before rotation and recover the source em height from text_em_scale. They use the locally available font, so they may differ from an external DXF viewer. Audit, bounding-box and statistics queries retain their existing defaults.

Block expansion supports nested JWW INSERTs; max_block_nesting must be at least

  1. Statistics and bounding boxes include hidden entities. TEXT bounds use the insertion point, so they are not bounds of the rendered glyphs.

Command line

The Python package installs the ezjww command. Each single-file command below accepts JWW and supported JWC input.

ezjww info drawing.jww --json
ezjww audit drawing.jwc --json
ezjww bbox drawing.jwc --jwc-coordinates model_millimeters --json
ezjww stats drawing.jww --json
ezjww report drawing.jwc --json
ezjww to-dxf drawing.jwc -o drawing.dxf --report json
ezjww to-dxf drawing.jww -o drawing.dxf --text-em-scale 1.364
ezjww to-dxf-dir drawings -o dxf --recursive
ezjww plot drawing.jwc -o drawing.png

Use ezjww --help or ezjww <command> --help for options. Audit/report commands support --fail-on-issues for automation. Rendering requires ezjww[plot].

Directory conversion finds .jww, .jwc and .jws case-insensitively and preserves subdirectories. If inputs would share an output name (for example, a.jww and a.jwc), it exits with code 2 before writing any converted files.

Compatibility

JWW parsing supports CP932 and Unicode strings, block definitions, and structured diagnostics. Some damaged JWW entity lists can be read partially; inspect diagnostics before relying on the result.

ANSI strings (BYTE length + bytes) are CP932 by default. Jw_cad running under Wine with a UTF-8 locale writes them as UTF-8; the reader detects that per file (every non-ASCII ANSI string is well-formed UTF-8, with at least three multi-byte sequences or one CP932 decoding anomaly), reads the file again as UTF-8, reports TEXT_ENCODING_DETECTED and sets the document's text_encoding ("cp932" or "utf-8", also Drawing.text_encoding). A CP932 string can be well-formed UTF-8 by coincidence only in narrow byte patterns (for example メー = D2 B0), so a file with a single such string stays CP932. Font names and the SXF line type and extended color names are copied by Jw_cad from its own CP932 string table even under Wine, so they neither count as evidence nor switch with the file: in a UTF-8 file they are read as UTF-8 only when well-formed, otherwise as CP932. Unicode strings (FF FE FF, UTF-16LE) are never affected.

JWC support covers the fixed2421_basic_v1 and fixed2389_basic_v1 document profiles (two header layouts sharing one record layout). It includes lines, circles, circular and elliptical arcs, rotated ellipses, CP932 text, points, and auxiliary points. Settings and attribute bits outside ezjww's reference corpus are retained and reported as JWC_* diagnostics; structurally inconsistent or malformed JWC files raise an error instead of returning a partial document. Compatibility with every JWC generation is not established.

JWC output uses millimeters, with the sheet center as the origin and +Y pointing up. Palette, dash lengths, and fonts use documented conversion defaults; exact source fonts and character spacing are not reproduced. The source format version is unknown and returned as None in Python or null in TypeScript.

Documentation

License

MIT

Metadata

Release files for ezjww 0.7.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ezjww 0.7.5
File Size Uploaded Provenance
ezjww-0.7.5.tar.gz 2.9 MB Without provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for ezjww 0.7.5
File
ezjww-0.7.5-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details
ezjww-0.7.5-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.9 abi3 Linux glibc 2.17+ x86-64 Details
ezjww-0.7.5-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.9 abi3 Linux glibc 2.17+ ARM64 Details
ezjww-0.7.5-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl CPython 3.9 abi3 macOS 10.12+ x86-64, macOS 11.0+ ARM64, macOS 10.12+ universal2 (ARM64, x86-64) Details

Total release size: 7.5 MB

Release files / ezjww-0.7.5.tar.gz

Download URL ezjww-0.7.5.tar.gz
Size 2.9 MB
Tags Source
SHA-256 checksum
How to use checksums
2eac45f5b4636985600f42ea730995ed64722304105f1319b741c49ef1855a91
BLAKE2b-256 checksum
How to use checksums
b0dc642c87d77d9d908fdec7973a0b086874d5e477bfbb26acd9c58a0a30c4ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / ezjww-0.7.5-cp39-abi3-win_amd64.whl

Download URL ezjww-0.7.5-cp39-abi3-win_amd64.whl
Size 823.6 kB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
83d73a2835d4946f703301901d8adf9da832aa4c020ec18e8144236b7ea2f420
BLAKE2b-256 checksum
How to use checksums
6c463d63cbeb58e19ae20c2359d5d0db7376592876d43939812bd1bcfdaf749e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / ezjww-0.7.5-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL ezjww-0.7.5-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 994.7 kB
Tags CPython 3.9 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
440360d0d3807d5a74d141a360ddecfe28af2865635fde9d8f078f1e2a3eaa0c
BLAKE2b-256 checksum
How to use checksums
cac0447de86df811b47b3be31f755cf71e0cbd25f984b833b1e927b6d44312fb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / ezjww-0.7.5-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL ezjww-0.7.5-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 972.6 kB
Tags CPython 3.9 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
885de6ab7219a6ae9bcb759862faceb3be5cda4ba98f02a23447879366540cf0
BLAKE2b-256 checksum
How to use checksums
f527d9ba571b5efe402cf2c53e56a47b61faed057691daf116d4325d7c620564
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / ezjww-0.7.5-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl

Download URL ezjww-0.7.5-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Size 1.8 MB
Tags CPython 3.9 abi3 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
3993e699dd77deeb313dfc905854c3519c287bd658e6a03093c38e83858f540d
BLAKE2b-256 checksum
How to use checksums
582050db9f3c6ba2f353a178d62e5f24f719eb0e092a1ba786772898c8588da9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for ezjww 0.7.5

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page