merge: track-e group S

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
This commit is contained in:
Umut CAN
2026-09-22 11:10:22 +03:00
co-authored by Claude Opus 5
21 changed files with 5303 additions and 39 deletions
@@ -3351,7 +3351,7 @@ Part of `docs/superpowers/plans/2026-09-16-v1.6-settings-implementation.md`. Its
- Test: `tests/test_standards_presets.py`
**Interfaces:**
- Produces: `PRESETS = {"iso-25": {...17 vars...}, "ansi": {...}}`, `PRESET_VARIABLES` (the 17, spec order), `DIM_VARIABLE_WHITELIST: frozenset` (17 + 16 = 33), `DIM_VARIABLE_RANGES: dict[str, tuple | set]`, `resolve_dimstyle(preset, overrides) -> dict`, `validate_overrides(overrides) -> dict`, `check_dim_value(name, value)`, `describe_preset(name) -> dict`; `TEXT_PRESETS`, `resolve_font(font) -> (font_file, known)`, `validate_textstyle(name, font, height, width_factor, oblique_deg) -> dict`; `MLEADER_PRESETS`, `MLEADER_KEYS`, `resolve_mleaderstyle(preset, overrides) -> dict`.
- Produces: `PRESETS = {"iso-25": {...17 vars...}, "ansi": {...}}`, `PRESET_VARIABLES` (the 17, spec order), `DIM_VARIABLE_WHITELIST: frozenset` (17 + 16 = 33), `DIM_VARIABLE_RANGES: dict[str, tuple | set]`, `resolve_dimstyle(preset, overrides) -> dict`, `validate_overrides(overrides) -> dict`, `check_dim_value(name, value)`, `describe_preset(name) -> dict`; the arrowhead vocabulary (added by the Task 9 review fixes and consumed by Task 10's helpers below): `ARROWHEAD_BLOCKS: frozenset` (AutoCAD's nineteen named built-ins, `_OBLIQUE` spelling, pinned equal to ezdxf's `ARROWS.__acad__`), `canonical_arrowhead(key, value) -> str` (what `check_dim_value` returns for `DIMBLK`/`DIMBLK1`/`DIMBLK2`: `""` for closed filled and its aliases `.`/`CLOSEDFILLED`/`_CLOSEDFILLED`, a built-in in any case with or without its underscore → its block name, anything else a user block name under the symbol-name rule — whether that block *exists* is the backend's check against `doc.blocks`, before any write), `ezdxf_arrowhead(canonical) -> str` (the one translation the headless **writer** needs: `_OBLIQUE` → `OBLIQUE`, user blocks and `""` unchanged — ezdxf raises `DXFValueError: Block "_OBLIQUE" does not exist` at `doc.write` and `DXFUndefinedBlockError` at render if the canonical spelling is stored verbatim), `reported_arrowhead(raw) -> str` (the **read** side, never raises: ezdxf reports `OBLIQUE` in-session and `_OBLIQUE` after a reload, COM reports `_OBLIQUE`; both come back as the canonical name, a foreign name passes through); `TEXT_PRESETS`, `resolve_font(font) -> (font_file, known)`, `validate_textstyle(name, font, height, width_factor, oblique_deg) -> dict`; `MLEADER_PRESETS`, `MLEADER_KEYS`, `resolve_mleaderstyle(preset, overrides) -> dict`.
- Every refusal is `ValueError` (wrong type: `TypeError`) naming the key, and nothing in this package writes anything — the backends call these before they touch a table.
- Groups C and P add `sysvars.py`, `papers.py`, `pdfinfo.py`, `templates.py`, `plot.py` to the same package and import them by path; this `__init__.py` re-exports only group S's names, so those groups never need to edit it.
@@ -3821,7 +3821,9 @@ LINEWEIGHT_CODES: frozenset[int] = frozenset(int(code) for code in _LINEWEIGHT_T
#: * ``("int", low, high)`` — an integer (a float with no fraction is accepted).
#: * ``("nonzero_float", low, high)`` — as ``float`` but ``0`` is refused.
#: * ``("char",)`` — exactly one character.
#: * ``("str",)`` — any string (arrowhead block names; ``""`` is the closed filled arrow).
#: * ``("arrow",)`` — an arrowhead: ``""`` (closed filled), one of ``ARROWHEAD_BLOCKS``
#: given with or without its underscore in any case, or a user block name under the
#: symbol-name rule; ``check_dim_value`` returns ``canonical_arrowhead(key, value)``.
#: * ``("name",)`` — a non-empty DXF symbol-table name.
#: * a ``set`` — one of its members.
DIM_VARIABLE_RANGES: dict[str, tuple | set] = {
@@ -3838,15 +3840,20 @@ DIM_VARIABLE_RANGES: dict[str, tuple | set] = {
"DIMDSEP": ("char",),
"DIMLUNIT": ("int", 1, 6),
"DIMZIN": ("int", 0, 15), # a bitmask
"DIMBLK": ("str",),
"DIMBLK": ("arrow",),
"DIMTXSTY": ("name",),
"DIMLWD": LINEWEIGHT_CODES,
"DIMLWE": LINEWEIGHT_CODES,
"DIMSCALE": ("float", 0.0, 1e6), # 0 means "scale to the viewport"
# tolerances, rounding, fit, colours, arrowheads — the rest of the whitelist
"DIMTOL": {0, 1},
"DIMTP": ("float", 0.0, 1e6),
"DIMTM": ("float", 0.0, 1e6),
# Both signed, as AutoCAD documents them: the displayed lower deviation is
# -DIMTM, so a double-positive fit (ISO 286 p6, +0.035/+0.022) stores
# DIMTM -0.022 and a double-negative one (f7, -0.020/-0.041) stores DIMTP
# -0.020 — exactly what engineering/tolerances.py::build_dim_override emits
# per dimension; a style must be able to hold the same numbers.
"DIMTP": ("float", -1e6, 1e6),
"DIMTM": ("float", -1e6, 1e6),
"DIMTOLJ": ("int", 0, 2),
"DIMTFAC": ("float", 1e-9, 1e6),
"DIMLFAC": ("nonzero_float", -1e6, 1e6),
@@ -3857,8 +3864,8 @@ DIM_VARIABLE_RANGES: dict[str, tuple | set] = {
"DIMCLRE": ("int", 0, 256),
"DIMCLRT": ("int", 0, 256),
"DIMSAH": {0, 1},
"DIMBLK1": ("str",),
"DIMBLK2": ("str",),
"DIMBLK1": ("arrow",),
"DIMBLK2": ("arrow",),
"DIMCEN": ("float", -1e6, 1e6), # negative draws centre lines, 0 none
}
@@ -4224,7 +4231,7 @@ git commit -m "feat(standards): ISO-25 and ANSI dimension, text and leader style
- Test: `tests/test_styles.py`
**Interfaces:**
- Consumes: `resolve_dimstyle`, `validate_overrides`, `PRESET_VARIABLES`, `DIM_VARIABLE_WHITELIST`, `TEXT_PRESETS`, `validate_textstyle`, `MLEADER_KEYS` (Task 9); `sanitize_symbol_name` (`security.py`) — note it raises `ToolError`, not `ValueError`, on an empty or illegal style name, the same refusal the existing block and layer tools give (the skeleton's Global Constraints record this as the one standing exception to the `ValueError`/`TypeError` rule); `_async`/`_require_doc`/`_mark_dirty` (ezdxf), `_run`/`_acad_doc`/`_acad_app`/`_regen`/`deg2rad`/`rad2deg` (COM).
- Consumes: `resolve_dimstyle`, `validate_overrides`, `PRESET_VARIABLES`, `DIM_VARIABLE_WHITELIST`, `ARROWHEAD_BLOCKS`, `ezdxf_arrowhead`, `reported_arrowhead`, `TEXT_PRESETS`, `validate_textstyle`, `MLEADER_KEYS` (Task 9) — `validate_overrides` already returns `DIMBLK`/`DIMBLK1`/`DIMBLK2` in the canonical `_OBLIQUE` spelling, which ActiveX takes verbatim but ezdxf's writer refuses, so the headless helpers translate on write (`ezdxf_arrowhead`), canonicalise on read (`reported_arrowhead`, both engines) and refuse a user block absent from `doc.blocks` before any write; `sanitize_symbol_name` (`security.py`) — note it raises `ToolError`, not `ValueError`, on an empty or illegal style name, the same refusal the existing block and layer tools give (the skeleton's Global Constraints record this as the one standing exception to the `ValueError`/`TypeError` rule); `_async`/`_require_doc`/`_mark_dirty` (ezdxf), `_run`/`_acad_doc`/`_acad_app`/`_regen`/`deg2rad`/`rad2deg` (COM).
- Produces: the nine `StylesContract` methods on both backends, exactly the plan's signatures. Extra keys beyond the plan's row shapes, on both engines: `dimstyle_list` rows carry `values_available: bool`; `dimstyle_create` carries `written: [vars]`; `dimstyle_set_current` / `textstyle_set_current` carry `changed: bool`; `mleaderstyle_create` carries `textstyle_created`. Names are matched case-insensitively (AutoCAD's rule) and reported in the table's own spelling.
- The COM rule, stated once in the code and enforced by the fake: `AcadDimStyle` has `Name` and `CopyFrom` only. Values are written by setting the `DIM*` document variables and `CopyFrom(document)`; making a style current (`ActiveDimStyle`) restores its saved settings and drops unsaved overrides; reading a non-current style's values is impossible, so `dimstyle_list` reports `values` for the current style only. `mleaderstyle_create` stays the `@capability("mleaderstyle")` default on COM (never defined there); `mleaderstyle_list` reads names from the `ACAD_MLEADERSTYLE` dictionary with `values_available: false`.
@@ -4368,6 +4375,46 @@ async def test_refusals_happen_before_anything_is_written(backend):
assert backend._doc.dimstyles.get("ISO-25").dxf.dimdec == 2
async def test_builtin_arrowheads_render_save_and_report_one_spelling(backend, tmp_path):
"""`validate_overrides` hands the canonical `_OBLIQUE`; stored verbatim ezdxf
raises at render and at `doc.write`. The witness is the rendered INSERT and
a save/reopen that reports the same name before and after."""
values = resolve_dimstyle("iso-25", {"DIMBLK": "oblique", "DIMSAH": 1, "DIMBLK1": "_DOT",
"DIMBLK2": "."})
result = await backend.dimstyle_create("ISO-25", values, set_current=True)
assert result["values"]["DIMBLK"] == "_OBLIQUE"
style = backend._doc.dimstyles.get("ISO-25")
assert style.dxf.dimblk == "OBLIQUE" and style.dxf.dimblk1 == "DOT" and style.dxf.dimblk2 == ""
dim = await backend.dimension_linear(0, 0, 20, 0, 10, -10)
block = backend._doc.blocks.get(backend._doc.entitydb.get(dim.handle).dxf.geometry)
assert {e.dxf.name for e in block if e.dxftype() == "INSERT"} == {"_DOT", "_CLOSEDFILLED"}, (
"DIMSAH on: the two separate arrowheads win over DIMBLK"
)
again = await backend.dimstyle_modify("ISO-25", {"DIMBLK": "OBLIQUE", "DIMBLK1": "_dot"})
assert again["changed"] == {}, "re-setting a value to itself is not a change (spec §8.3)"
path = str(tmp_path / "arrows.dxf")
await backend.drawing_save_as(path)
await backend.drawing_open(path)
rows = {r["name"]: r for r in await backend.dimstyle_list()}
assert rows["ISO-25"]["values"]["DIMBLK"] == "_OBLIQUE", "reloaded, the same spelling"
reopened = await backend.dimstyle_modify("ISO-25", {"DIMBLK": "oblique"})
assert reopened["changed"] == {}
async def test_user_arrowhead_block_must_exist_before_anything_is_written(backend):
with pytest.raises(ValueError, match="DIMBLK: block 'MYARROW' does not exist"):
await backend.dimstyle_create("X", resolve_dimstyle("iso-25", {"DIMBLK": "MYARROW"}))
assert not backend._doc.dimstyles.has_entry("X")
await backend.dimstyle_create("ISO-25", resolve_dimstyle("iso-25", None))
with pytest.raises(ValueError, match="DIMBLK1: block 'MYARROW' does not exist"):
await backend.dimstyle_modify("ISO-25", {"DIMSAH": 1, "DIMBLK1": "MYARROW"})
assert not backend._doc.dimstyles.get("ISO-25").dxf.hasattr("dimsah"), "nothing written"
backend._doc.blocks.new("MYARROW").add_line((0, 0), (1, 1))
result = await backend.dimstyle_modify("ISO-25", {"DIMBLK": "myarrow"})
assert result["changed"] == {"DIMBLK": ["", "MYARROW"]}, "the block table's own spelling"
assert backend._doc.dimstyles.get("ISO-25").dxf.dimblk == "MYARROW"
async def test_dimstyle_set_current_reports_previous_and_survives_save_reopen(backend, tmp_path):
await backend.dimstyle_create("ISO-25", resolve_dimstyle("iso-25", None))
result = await backend.dimstyle_set_current("iso-25")
@@ -5019,8 +5066,14 @@ def _dimstyle_schema_default(var: str):
return None if attrib is None else attrib.default
_ARROWHEAD_VARS = ("DIMBLK", "DIMBLK1", "DIMBLK2")
def _dimstyle_value(style, var: str):
"""A style's value for ``var`` in the tool vocabulary (DIMDSEP as the character)."""
"""A style's value for ``var`` in the tool vocabulary (DIMDSEP as the
character, arrowheads in the canonical ``_OBLIQUE`` spelling)."""
from engineering.standards.dimstyles import reported_arrowhead
attr = var.lower()
raw = style.dxf.get(attr) if style.dxf.hasattr(attr) else None
if raw is None:
@@ -5030,6 +5083,12 @@ def _dimstyle_value(style, var: str):
return "," if code == 0 else chr(code)
if var == "DIMTXSTY":
return str(raw) if raw else "Standard"
if var in _ARROWHEAD_VARS:
# Measured: ezdxf holds the writer's ``OBLIQUE`` in-session and the
# block name ``_OBLIQUE`` after a reload. Raw, one style would be
# spelled two ways and re-setting a value to itself would report a
# change (spec §8.3); canonicalised, both reads agree.
return reported_arrowhead(raw)
return raw
@@ -5039,19 +5098,58 @@ def _read_dimstyle_values(style, variables=None) -> dict[str, Any]:
return {var: _dimstyle_value(style, var) for var in (variables or PRESET_VARIABLES)}
def _require_arrowhead_blocks(doc, values: dict[str, Any]) -> None:
"""Refuse a user arrowhead block the drawing does not define — before any write.
A built-in (``ARROWHEAD_BLOCKS``) and closed filled (``""``) need no block:
ezdxf creates the built-in's block on first use. A user block name passes
the data layer (it cannot see the drawing) and, stored, ezdxf raises
``DXFUndefinedBlockError`` at the next dimension render and ``DXFValueError:
Block "MYARROW" does not exist`` at ``doc.write`` — after the create tool
already said ``ok``. ``doc.blocks`` membership is case-insensitive, and a
reload reports the block table's own spelling (measured: ``myarrow`` stored,
``MYARROW`` after reopen), so the name is rewritten in ``values`` to that
spelling here — the same "reported in the table's own spelling" rule the
style names follow, and what keeps a re-set after reopen a non-change.
"""
from engineering.standards.dimstyles import ARROWHEAD_BLOCKS
for var in _ARROWHEAD_VARS:
name = values.get(var)
if not name or name in ARROWHEAD_BLOCKS:
continue
if name not in doc.blocks:
raise ValueError(
f"{var}: block {name!r} does not exist in this drawing; define it first "
"with block_define, or name one of AutoCAD's built-in arrowheads"
)
values[var] = doc.blocks.get(name).name
def _write_dimstyle_values(style, values: dict[str, Any]) -> None:
"""Store typed values (from ``validate_overrides``) on a DIMSTYLE entry.
DIMRND 0 is AutoCAD's "no rounding"; ezdxf applies ``xround(x, 0.0)`` to a
*stored* 0.0 and rounds every dimension to a whole unit, so it is
discarded rather than stored (the `_normalise_dimstyle_rounding` lesson).
Arrowheads arrive in the canonical ``_OBLIQUE`` spelling (what ActiveX
takes verbatim); ezdxf's writer wants ``OBLIQUE`` and raises at
``doc.write`` on the underscore form, so they go through
``ezdxf_arrowhead``. The caller has run ``_require_arrowhead_blocks``.
"""
from engineering.standards.dimstyles import ezdxf_arrowhead
for var, value in values.items():
attr = var.lower()
if var == "DIMRND" and float(value) == 0.0:
style.dxf.discard("dimrnd")
continue
style.dxf.set(attr, ord(value) if var == "DIMDSEP" else value)
if var == "DIMDSEP":
value = ord(value)
elif var in _ARROWHEAD_VARS:
value = ezdxf_arrowhead(value)
style.dxf.set(attr, value)
def _sync_header_to_dimstyle(doc, style) -> None:
@@ -5179,6 +5277,7 @@ Insert immediately before ` # ── corner ops` in `EzdxfBackend` (directly
"use dimstyle_modify to change it"
)
previous = _current_dimstyle_name(doc)
_require_arrowhead_blocks(doc, typed)
txsty, textstyle_created = _ensure_textstyle(
doc, str(typed.get("DIMTXSTY", "Standard")), refusal_key="DIMTXSTY"
)
@@ -5225,6 +5324,7 @@ Insert immediately before ` # ── corner ops` in `EzdxfBackend` (directly
f"DIMTXSTY: text style {typed['DIMTXSTY']!r} does not exist in this drawing; "
"create it first with textstyle_create"
)
_require_arrowhead_blocks(doc, typed)
before = _read_dimstyle_values(style, tuple(typed))
_write_dimstyle_values(style, typed)
after = _read_dimstyle_values(style, tuple(typed))
@@ -5458,7 +5558,14 @@ def _com_dimvar_for_report(var: str, raw: Any) -> Any:
return "," if raw == 0 else chr(raw)
text = str(raw)
return text[:1] if text else ","
if var in ("DIMBLK", "DIMBLK1", "DIMBLK2", "DIMTXSTY"):
if var in ("DIMBLK", "DIMBLK1", "DIMBLK2"):
# AutoCAD reports the block name (``_OBLIQUE``, ``""`` for closed
# filled) — already canonical; the same read-side rule as ezdxf keeps
# the two engines' rows spelled identically.
from engineering.standards.dimstyles import reported_arrowhead
return reported_arrowhead(raw)
if var == "DIMTXSTY":
return str(raw)
return raw
@@ -118,7 +118,7 @@ name.
- `dimstyle_modify(name, overrides)` — `changed` reports only variables that actually moved (the `hatch_edit` rule). Dimensions already using the style are listed in `dimensions_using_style` with `rerender_required: true` on the headless engine: AutoCAD re-renders them on the next regen, but a headless DIMENSION carries its rendered block, so the drawing shows the old style until the dimension is redrawn — stated rather than silent.
- `dimstyle_set_current(name)` — `$DIMSTYLE`; the dimension tools then use it (the existing per-dimension override path stays as is).
- `textstyle_list()`, `textstyle_create(name, font: "isocp.shx"|"isocpeur.ttf"|"arial.ttf"|"romans.shx"|<file>, height=0.0, width_factor=1.0, oblique_deg=0.0, set_current=False)`, `textstyle_set_current(name)` — `$TEXTSTYLE`; a font file that is neither a bundled preset nor present in the engine's font path is written but reported `font_resolved: false` (AutoCAD substitutes at open; the headless renderer falls back), never refused, because DXF only stores the name.
- `mleaderstyle_list()`, `mleaderstyle_create(name, preset: "iso"|"ansi", overrides)` — arrow size, landing gap, text style, text height on ezdxf's `doc.mleader_styles`. ActiveX exposes no MLeaderStyle collection, so the COM engine refuses both with `capability: "mleaderstyle"` (the reason names `leader_create_mleader`'s existing per-leader parameters as the route); `mleaderstyle_list` on COM still reads the names from the `ACAD_MLEADERSTYLE` dictionary.
- `mleaderstyle_list()`, `mleaderstyle_create(name, preset: "iso"|"ansi", overrides)` — arrow size, landing gap, text style, text height, both engines: ezdxf on `doc.mleader_styles`; COM through the `ACAD_MLEADERSTYLE` dictionary, whose items are `IAcadMLeaderStyle` objects (`ArrowSize` / `LandingGap` / `TextHeight` in drawing units, `TextStyle` a name — verified against the AutoCAD 2026 type library), created with `Dictionaries.Item("ACAD_MLEADERSTYLE").AddObject(name, "AcDbMLeaderStyle")` followed by the property writes. ActiveX has no `MLeaderStyles` *collection* property, which is not an engine boundary — no `mleaderstyle` capability key exists.
- `drawing_apply_standard(standard: "iso"|"ansi", layers: bool = True, units: bool = True)` — one call: the dimstyle preset (created and set current), its text style, `drawing_settings` (units mm, decimal linear and angular units, LTSCALE 1, DIMSCALE 1; the decimal separator comes from the preset) and, with `layers`, the `mech` layer set for both standards (ANSI layer naming is company-specific; the set reuses the mech names with ISO 128 lineweights — only styles and the separator differ between the two). Returns, per item, whether it was created or was already present.
## 5. Settings (SECTION 20 shares these; 3 tools + facade growth)
@@ -187,9 +187,10 @@ A state is the layer table snapshot `{layer: {on, frozen, locked, color, linetyp
### 8.1 Capability keys (added to **both** maps)
`mleaderstyle` (COM false), `dwgprops` (ezdxf false: summary fields), `dwt_write`
(ezdxf false), `live_application`, `preferences`, `interactive_prompt` (ezdxf
false). `tests/test_capability_contract.py` enforces both maps.
`dwgprops` (ezdxf false: summary fields), `dwt_write` (ezdxf false),
`live_application`, `preferences`, `interactive_prompt` (ezdxf false).
`tests/test_capability_contract.py` enforces both maps. (`mleaderstyle` was
listed here as COM false; the ActiveX route exists — §4.2 — so there is no key.)
### 8.2 Packs, profiles, discovery
@@ -219,7 +220,9 @@ shop-floor synonyms; the discovery golden set gains ≥ 10 queries for them
(A0 841×1189 … A4 210×297; ANSI A 216×279 … E 864×1118), every catalog
sysvar has type+meaning+engines.
- Dual-engine tests for every tool (ezdxf real; COM fake-ActiveX asserting call
shapes: `DimStyles.Add`, `TextStyles.Add`, `Layout.ConfigName/…`,
shapes: `DimStyles.Add`, `TextStyles.Add`,
`Dictionaries.Item("ACAD_MLEADERSTYLE").AddObject(name, "AcDbMLeaderStyle")`,
`Layout.ConfigName/…`,
`Documents.Item().Activate`, `Dictionaries.Add`+`AddXRecord`, `Views.Add`,
`UserCoordinateSystems.Add`, `Preferences.OpenSave.*`, `SummaryInfo.*`,
`Utility.GetPoint`).
+143 -2
View File
@@ -3,10 +3,10 @@
"schema_version": 1,
"package_version": "1.5.1",
"totals": {
"tools": 166,
"tools": 176,
"resources": 8,
"prompts": 5,
"groups": 20
"groups": 21
},
"groups": {
"analysis": 12,
@@ -24,6 +24,7 @@
"pid": 9,
"premium": 12,
"solids": 5,
"styles": 10,
"system": 7,
"templates": 2,
"transactions": 3,
@@ -450,6 +451,62 @@
"readOnlyHint": false
}
},
{
"name": "dimstyle_create",
"group": "styles",
"cost": "mutate",
"summary": "Create a dimension style from the ISO-25 or ANSI preset, with per-variable overrides.",
"tags": [
"create",
"style"
],
"annotations": {
"title": "Styles: Create Dimension Style",
"readOnlyHint": false
}
},
{
"name": "dimstyle_list",
"group": "styles",
"cost": "read",
"summary": "List dimension styles with their ISO-25/ANSI variables and the current one.",
"tags": [
"query",
"style"
],
"annotations": {
"title": "Styles: List Dimension Styles",
"readOnlyHint": true
}
},
{
"name": "dimstyle_modify",
"group": "styles",
"cost": "mutate",
"summary": "Change DIM* variables on an existing dimension style; reports only what moved.",
"tags": [
"modify",
"style"
],
"annotations": {
"title": "Styles: Modify Dimension Style",
"readOnlyHint": false
}
},
{
"name": "dimstyle_set_current",
"group": "styles",
"cost": "safe",
"summary": "Make a dimension style current so new dimensions use it.",
"tags": [
"modify",
"style"
],
"annotations": {
"title": "Styles: Set Current Dimension Style",
"readOnlyHint": false
}
},
{
"name": "drawing_apply_iso_layers",
"group": "premium",
@@ -464,6 +521,20 @@
"destructiveHint": false
}
},
{
"name": "drawing_apply_standard",
"group": "styles",
"cost": "mutate",
"summary": "Put the drawing on ISO or ANSI in one call: dimstyle, text style, units, mech layers.",
"tags": [
"drawing",
"style"
],
"annotations": {
"title": "Drawing: Apply Drafting Standard",
"readOnlyHint": false
}
},
{
"name": "drawing_audit",
"group": "drawing",
@@ -1717,6 +1788,34 @@
"readOnlyHint": false
}
},
{
"name": "mleaderstyle_create",
"group": "styles",
"cost": "mutate",
"summary": "Create a multileader style from the ISO or ANSI preset, on both engines.",
"tags": [
"create",
"style"
],
"annotations": {
"title": "Styles: Create Multileader Style",
"readOnlyHint": false
}
},
{
"name": "mleaderstyle_list",
"group": "styles",
"cost": "read",
"summary": "List multileader styles: arrow size, landing gap, text style and height.",
"tags": [
"query",
"style"
],
"annotations": {
"title": "Styles: List Multileader Styles",
"readOnlyHint": true
}
},
{
"name": "pid_equipment_list",
"group": "pid",
@@ -2155,6 +2254,48 @@
"destructiveHint": false
}
},
{
"name": "textstyle_create",
"group": "styles",
"cost": "mutate",
"summary": "Create a text style from a bundled font (isocp, isocpeur, arial, romans) or any file.",
"tags": [
"create",
"style"
],
"annotations": {
"title": "Styles: Create Text Style",
"readOnlyHint": false
}
},
{
"name": "textstyle_list",
"group": "styles",
"cost": "read",
"summary": "List text styles: font file, height, width factor, oblique angle.",
"tags": [
"query",
"style"
],
"annotations": {
"title": "Styles: List Text Styles",
"readOnlyHint": true
}
},
{
"name": "textstyle_set_current",
"group": "styles",
"cost": "safe",
"summary": "Make a text style current so new text uses it.",
"tags": [
"modify",
"style"
],
"annotations": {
"title": "Styles: Set Current Text Style",
"readOnlyHint": false
}
},
{
"name": "titleblock_apply_iso_a3",
"group": "engineering",