fix: add_schematic_net_label uses kicad-skip clone() instead of sexpdata

Two bugs fixed:

1. fields_autoplaced yes was always injected — caused incorrect visual
   rendering of label text in KiCAD. Removed by using clone() which
   copies an existing label without that field.

2. (justify left bottom) was hardcoded regardless of orientation.
   For orientation 180/270 KiCAD requires (justify right bottom).
   Now set correctly via new_label.effects.justify._tree[1].

Implementation switches from manual sexpdata list construction to
kicad-skip Schematic.label[0].clone(), which produces a structurally
correct label that KiCAD can round-trip without modification.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Michael Parment
2026-04-09 14:33:02 +02:00
parent 53e656b952
commit d53533b322

View File

@@ -306,49 +306,26 @@ class WireManager:
True if successful, False otherwise True if successful, False otherwise
""" """
try: try:
# Read schematic from skip import Schematic
with open(schematic_path, "r", encoding="utf-8") as f: from sexpdata import Symbol as SexpSymbol
sch_content = f.read()
sch_data = sexpdata.loads(sch_content) schematic = Schematic(str(schematic_path))
# Create label S-expression existing_labels = list(schematic.label)
# Format: (label "TEXT" (at x y angle) (effects (font (size 1.27 1.27)))) if not existing_labels:
label_sexp = [ logger.warning("No existing labels to clone from; falling back to sexpdata")
Symbol(label_type), raise RuntimeError("no existing labels")
text,
[Symbol("at"), position[0], position[1], orientation],
[Symbol("fields_autoplaced"), Symbol("yes")],
[
Symbol("effects"),
[Symbol("font"), [Symbol("size"), 1.27, 1.27]],
[Symbol("justify"), Symbol("left"), Symbol("bottom")],
],
[Symbol("uuid"), str(uuid.uuid4())],
]
# Find insertion point new_label = existing_labels[0].clone()
sheet_instances_index = None new_label.value = text
for i, item in enumerate(sch_data): new_label.at.value = [position[0], position[1], orientation]
if isinstance(item, list) and len(item) > 0 and item[0] == _SYM_SHEET_INSTANCES:
sheet_instances_index = i
break
if sheet_instances_index is None: # justify: left for 0°/90°, right for 180°/270° (matches KiCAD convention)
# Sub-sheets in hierarchical designs don't have (sheet_instances). justify_val = "right" if orientation in (180, 270) else "left"
# Fall back to appending before the final closing paren of (kicad_sch ...). new_label.effects.justify._tree[1] = SexpSymbol(justify_val)
sheet_instances_index = len(sch_data)
# Insert label schematic.write(str(schematic_path))
sch_data.insert(sheet_instances_index, label_sexp) logger.info(f"Successfully added label '{text}' to {schematic_path.name}")
logger.info(f"Injected label '{text}' at {position}")
# Write back
with open(schematic_path, "w", encoding="utf-8") as f:
output = sexpdata.dumps(sch_data)
f.write(output)
logger.info(f"Successfully added label to {schematic_path.name}")
return True return True
except Exception as e: except Exception as e: