tools/epro2/std: add Pro 2.x JSON path — Liangshan + Taishan SCH now exportable
The downstream colleague's "encrypted_external" / "string old format"
projects were Pro 2.x, not Pro 3.x EPRO2. Pro 2.x ships each doc as a
JSON file whose `dataStr` is a plaintext op-stream — one JSON array per
line, e.g. `["COMPONENT","e1","",0,0,0,0,{},0]`. Different wire format
from EPRO2's binary tilde/pipe streams; same Std envelope works for
output.
- tools/epro2/std/pro2_writer.py: parses dataStr line-by-line, keys
objects by id (position 1 for most ops, OPTYPE for singletons),
extracts BBox by walking known coord positions per OPTYPE, derives
layers from LAYER ops directly (Pro 2.x almost matches Std layer
string format already). PCB blobs that are encrypted-external
(`dataStrId` URL + `iv` + `key`, no inline dataStr — Taishan PCB)
return None so the CLI skips with a message instead of stubbing.
- tools/epro2/std/__main__.py: auto-detect via manifest's
editor_version. "2.x" → Pro 2.x writer; otherwise the existing
EPRO2 replay path. CLI surface and output layout unchanged.
- docs/sources/epro2_to_std_mapping.md: adds a Pro 2.x section.
Adapter dispatches on `head.epro_format`: absent / "epro2" gets
dict-shaped objects values, "pro2" gets array-shaped values
(`[OPTYPE, arg1, ...]`). Lists the Pro 2.x-specific OPTYPEs
(FONTSTYLE / LINESTYLE / CONNECT / OBJ / REGION / DIMENSION /
STRING / TEARDROP) the EPRO2 vocabulary doesn't have.
Smoke (re-running --all on all 5 Pro projects): 191 → 222 JSON files.
Liangshan adds 3 (2 SCH + inline 5357-object PCB). Taishan adds 28
(SCH only — PCB skipped, encrypted-external; source/<uuid>.json still
keeps the dataStrId/iv/key for a later fetch+decrypt pass).
84 → 86 unit tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# EPRO2 OPTYPE → EasyEDA Std shape verb mapping
|
||||
# EPRO2 / Pro 2.x OPTYPE → EasyEDA Std shape verb mapping
|
||||
|
||||
For downstream adapters that consume `tools/epro2/std/`'s Option-2 output
|
||||
(raw `objects: {id: payload}` dict in the `dataStr` field) and need to
|
||||
@@ -225,6 +225,43 @@ choose to skip silently or emit best-effort placeholders:
|
||||
| STRING (PCB) | `TEXT` | Board-level text; field order distinct from PCB TEXT-in-LIB |
|
||||
| BUS / BE (SCH) | `BUS` / `BE` | Bus + bus entry — no EPRO2 sample in our corpus |
|
||||
|
||||
## Pro 2.x source format
|
||||
|
||||
Pro 2.x projects (lceda Pro editor 2.x — Liangshan Pi, Taishan Pi RK3566
|
||||
in our corpus) use a **different on-disk format** than Pro 3.x EPRO2,
|
||||
even though both come out of the same crawler. Detection: the
|
||||
`source/manifest.json` file has `"editor_version": "2.x.x"`. Our
|
||||
exporter auto-detects this and emits the same Std envelope, but with two
|
||||
key differences the adapter must branch on:
|
||||
|
||||
- `result.dataStr.head.epro_format = "pro2"` (vs absent / `"epro2"` for
|
||||
Pro 3.x). This is the canonical dispatch field.
|
||||
- `result.dataStr.objects` values are **JSON arrays**, not the
|
||||
`{"_type": ..., **fields}` dicts EPRO2 produces. The first array
|
||||
element is the OPTYPE (`["COMPONENT", "e1", "", 0, 0, 90, ...]`).
|
||||
|
||||
Pro 2.x op vocabulary overlaps EPRO2 but adds editor-specific helpers:
|
||||
`FONTSTYLE` / `LINESTYLE` (referenced by id from text/stroke ops),
|
||||
`CONNECT` (sch wire-end to pin binding), `OBJ` (group container),
|
||||
`REGION` (sch background fills), `DIMENSION` (sch annotation),
|
||||
`STRING` (PCB board-level text — distinct from PCB `TEXT`),
|
||||
`TEARDROP` (cosmetic fillets at via/pad).
|
||||
|
||||
Field positions per OPTYPE follow the public EasyEDA Pro 2.x spec
|
||||
(versioned via the leading `["DOCTYPE","SCH","1.1"]` / `["DOCTYPE",
|
||||
"PCB","1.4"]` op). Our writer doesn't translate them — adapter
|
||||
dispatches by `arr[0]` (OPTYPE) and walks the rest by index.
|
||||
|
||||
### Encrypted-external PCB blobs
|
||||
|
||||
Some Pro 2.x PCB docs (and a handful of resource docs) replace the
|
||||
inline `dataStr` field with `{"dataStrId": "https://modules.lceda.cn/...",
|
||||
"iv": "...", "key": "..."}` — the actual op-stream lives at the URL,
|
||||
AES-decrypted with the iv+key. **Our exporter skips these**; the
|
||||
`source/<uuid>.json` files still hold the dataStrId/iv/key so a future
|
||||
fetch+decrypt pass can recover them. Taishan PCB is the example in our
|
||||
corpus.
|
||||
|
||||
## Provenance fields the adapter can rely on
|
||||
|
||||
In addition to `objects`, our writer always emits:
|
||||
|
||||
Reference in New Issue
Block a user