kicad-sch-api 0.4.0__py3-none-any.whl → 0.4.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of kicad-sch-api might be problematic. Click here for more details.
- kicad_sch_api/__init__.py +2 -2
- kicad_sch_api/cli/__init__.py +45 -0
- kicad_sch_api/cli/base.py +302 -0
- kicad_sch_api/cli/bom.py +164 -0
- kicad_sch_api/cli/erc.py +229 -0
- kicad_sch_api/cli/export_docs.py +289 -0
- kicad_sch_api/cli/netlist.py +94 -0
- kicad_sch_api/cli/types.py +43 -0
- kicad_sch_api/core/collections/__init__.py +5 -0
- kicad_sch_api/core/collections/base.py +248 -0
- kicad_sch_api/core/component_bounds.py +5 -0
- kicad_sch_api/core/components.py +142 -47
- kicad_sch_api/core/config.py +85 -3
- kicad_sch_api/core/factories/__init__.py +5 -0
- kicad_sch_api/core/factories/element_factory.py +276 -0
- kicad_sch_api/core/formatter.py +22 -5
- kicad_sch_api/core/junctions.py +26 -75
- kicad_sch_api/core/labels.py +28 -52
- kicad_sch_api/core/managers/file_io.py +3 -2
- kicad_sch_api/core/managers/metadata.py +6 -5
- kicad_sch_api/core/managers/validation.py +3 -2
- kicad_sch_api/core/managers/wire.py +7 -1
- kicad_sch_api/core/nets.py +38 -43
- kicad_sch_api/core/no_connects.py +29 -53
- kicad_sch_api/core/parser.py +75 -1765
- kicad_sch_api/core/schematic.py +211 -148
- kicad_sch_api/core/texts.py +28 -55
- kicad_sch_api/core/types.py +59 -18
- kicad_sch_api/core/wires.py +27 -75
- kicad_sch_api/parsers/elements/__init__.py +22 -0
- kicad_sch_api/parsers/elements/graphics_parser.py +564 -0
- kicad_sch_api/parsers/elements/label_parser.py +194 -0
- kicad_sch_api/parsers/elements/library_parser.py +165 -0
- kicad_sch_api/parsers/elements/metadata_parser.py +58 -0
- kicad_sch_api/parsers/elements/sheet_parser.py +352 -0
- kicad_sch_api/parsers/elements/symbol_parser.py +313 -0
- kicad_sch_api/parsers/elements/text_parser.py +250 -0
- kicad_sch_api/parsers/elements/wire_parser.py +242 -0
- kicad_sch_api/parsers/utils.py +80 -0
- kicad_sch_api/validation/__init__.py +25 -0
- kicad_sch_api/validation/erc.py +171 -0
- kicad_sch_api/validation/erc_models.py +203 -0
- kicad_sch_api/validation/pin_matrix.py +243 -0
- kicad_sch_api/validation/validators.py +391 -0
- {kicad_sch_api-0.4.0.dist-info → kicad_sch_api-0.4.2.dist-info}/METADATA +17 -9
- kicad_sch_api-0.4.2.dist-info/RECORD +87 -0
- kicad_sch_api/core/manhattan_routing.py +0 -430
- kicad_sch_api/core/simple_manhattan.py +0 -228
- kicad_sch_api/core/wire_routing.py +0 -380
- kicad_sch_api/parsers/label_parser.py +0 -254
- kicad_sch_api/parsers/symbol_parser.py +0 -222
- kicad_sch_api/parsers/wire_parser.py +0 -99
- kicad_sch_api-0.4.0.dist-info/RECORD +0 -67
- {kicad_sch_api-0.4.0.dist-info → kicad_sch_api-0.4.2.dist-info}/WHEEL +0 -0
- {kicad_sch_api-0.4.0.dist-info → kicad_sch_api-0.4.2.dist-info}/entry_points.txt +0 -0
- {kicad_sch_api-0.4.0.dist-info → kicad_sch_api-0.4.2.dist-info}/licenses/LICENSE +0 -0
- {kicad_sch_api-0.4.0.dist-info → kicad_sch_api-0.4.2.dist-info}/top_level.txt +0 -0
kicad_sch_api/core/types.py
CHANGED
|
@@ -18,14 +18,14 @@ class Point:
|
|
|
18
18
|
x: float
|
|
19
19
|
y: float
|
|
20
20
|
|
|
21
|
-
def __post_init__(self):
|
|
21
|
+
def __post_init__(self) -> None:
|
|
22
22
|
# Ensure coordinates are float
|
|
23
23
|
object.__setattr__(self, "x", float(self.x))
|
|
24
24
|
object.__setattr__(self, "y", float(self.y))
|
|
25
25
|
|
|
26
26
|
def distance_to(self, other: "Point") -> float:
|
|
27
27
|
"""Calculate distance to another point."""
|
|
28
|
-
return ((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5
|
|
28
|
+
return float(((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5)
|
|
29
29
|
|
|
30
30
|
def offset(self, dx: float, dy: float) -> "Point":
|
|
31
31
|
"""Create new point offset by dx, dy."""
|
|
@@ -35,6 +35,43 @@ class Point:
|
|
|
35
35
|
return f"({self.x:.3f}, {self.y:.3f})"
|
|
36
36
|
|
|
37
37
|
|
|
38
|
+
def point_from_dict_or_tuple(
|
|
39
|
+
position: Union[Point, Dict[str, float], Tuple[float, float], List[float], Any]
|
|
40
|
+
) -> Point:
|
|
41
|
+
"""
|
|
42
|
+
Convert various position formats to a Point object.
|
|
43
|
+
|
|
44
|
+
Supports multiple input formats for maximum flexibility:
|
|
45
|
+
- Point: Returns as-is
|
|
46
|
+
- Dict with 'x' and 'y' keys: Extracts and creates Point
|
|
47
|
+
- Tuple/List with 2 elements: Creates Point from coordinates
|
|
48
|
+
- Other: Returns as-is (assumes it's already a Point-like object)
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
position: Position in any supported format
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
Point object
|
|
55
|
+
|
|
56
|
+
Example:
|
|
57
|
+
>>> point_from_dict_or_tuple({"x": 10, "y": 20})
|
|
58
|
+
Point(x=10.0, y=20.0)
|
|
59
|
+
>>> point_from_dict_or_tuple((10, 20))
|
|
60
|
+
Point(x=10.0, y=20.0)
|
|
61
|
+
>>> point_from_dict_or_tuple(Point(10, 20))
|
|
62
|
+
Point(x=10.0, y=20.0)
|
|
63
|
+
"""
|
|
64
|
+
if isinstance(position, Point):
|
|
65
|
+
return position
|
|
66
|
+
elif isinstance(position, dict):
|
|
67
|
+
return Point(position.get("x", 0), position.get("y", 0))
|
|
68
|
+
elif isinstance(position, (list, tuple)) and len(position) >= 2:
|
|
69
|
+
return Point(position[0], position[1])
|
|
70
|
+
else:
|
|
71
|
+
# Assume it's already a Point-like object or will be handled by caller
|
|
72
|
+
return position
|
|
73
|
+
|
|
74
|
+
|
|
38
75
|
@dataclass(frozen=True)
|
|
39
76
|
class Rectangle:
|
|
40
77
|
"""Rectangle defined by two corner points."""
|
|
@@ -110,7 +147,7 @@ class SchematicPin:
|
|
|
110
147
|
length: float = 2.54 # Standard pin length in mm
|
|
111
148
|
rotation: float = 0.0 # Rotation in degrees
|
|
112
149
|
|
|
113
|
-
def __post_init__(self):
|
|
150
|
+
def __post_init__(self) -> None:
|
|
114
151
|
# Ensure types are correct
|
|
115
152
|
self.pin_type = PinType(self.pin_type) if isinstance(self.pin_type, str) else self.pin_type
|
|
116
153
|
self.pin_shape = (
|
|
@@ -135,7 +172,7 @@ class SchematicSymbol:
|
|
|
135
172
|
on_board: bool = True
|
|
136
173
|
unit: int = 1
|
|
137
174
|
|
|
138
|
-
def __post_init__(self):
|
|
175
|
+
def __post_init__(self) -> None:
|
|
139
176
|
# Generate UUID if not provided
|
|
140
177
|
if not self.uuid:
|
|
141
178
|
self.uuid = str(uuid4())
|
|
@@ -163,6 +200,10 @@ class SchematicSymbol:
|
|
|
163
200
|
if not pin:
|
|
164
201
|
return None
|
|
165
202
|
# TODO: Apply rotation and symbol position transformation
|
|
203
|
+
# NOTE: Currently assumes 0° rotation. For rotated components, pin positions
|
|
204
|
+
# would need to be transformed using rotation matrix before adding to component position.
|
|
205
|
+
# This affects pin-to-pin wiring accuracy for rotated components.
|
|
206
|
+
# Priority: MEDIUM - Would improve wiring accuracy for rotated components
|
|
166
207
|
return Point(self.position.x + pin.position.x, self.position.y + pin.position.y)
|
|
167
208
|
|
|
168
209
|
|
|
@@ -183,7 +224,7 @@ class Wire:
|
|
|
183
224
|
stroke_width: float = 0.0
|
|
184
225
|
stroke_type: str = "default"
|
|
185
226
|
|
|
186
|
-
def __post_init__(self):
|
|
227
|
+
def __post_init__(self) -> None:
|
|
187
228
|
if not self.uuid:
|
|
188
229
|
self.uuid = str(uuid4())
|
|
189
230
|
|
|
@@ -196,7 +237,7 @@ class Wire:
|
|
|
196
237
|
raise ValueError("Wire must have at least 2 points")
|
|
197
238
|
|
|
198
239
|
@classmethod
|
|
199
|
-
def from_start_end(cls, uuid: str, start: Point, end: Point, **kwargs) -> "Wire":
|
|
240
|
+
def from_start_end(cls, uuid: str, start: Point, end: Point, **kwargs: Any) -> "Wire":
|
|
200
241
|
"""Create wire from start and end points (convenience method)."""
|
|
201
242
|
return cls(uuid=uuid, points=[start, end], **kwargs)
|
|
202
243
|
|
|
@@ -244,7 +285,7 @@ class Junction:
|
|
|
244
285
|
diameter: float = 0 # KiCAD default diameter
|
|
245
286
|
color: Tuple[int, int, int, int] = (0, 0, 0, 0) # RGBA color
|
|
246
287
|
|
|
247
|
-
def __post_init__(self):
|
|
288
|
+
def __post_init__(self) -> None:
|
|
248
289
|
if not self.uuid:
|
|
249
290
|
self.uuid = str(uuid4())
|
|
250
291
|
|
|
@@ -280,7 +321,7 @@ class Label:
|
|
|
280
321
|
size: float = 1.27
|
|
281
322
|
shape: Optional[HierarchicalLabelShape] = None # Only for hierarchical labels
|
|
282
323
|
|
|
283
|
-
def __post_init__(self):
|
|
324
|
+
def __post_init__(self) -> None:
|
|
284
325
|
if not self.uuid:
|
|
285
326
|
self.uuid = str(uuid4())
|
|
286
327
|
|
|
@@ -305,7 +346,7 @@ class Text:
|
|
|
305
346
|
size: float = 1.27
|
|
306
347
|
exclude_from_sim: bool = False
|
|
307
348
|
|
|
308
|
-
def __post_init__(self):
|
|
349
|
+
def __post_init__(self) -> None:
|
|
309
350
|
if not self.uuid:
|
|
310
351
|
self.uuid = str(uuid4())
|
|
311
352
|
|
|
@@ -333,7 +374,7 @@ class TextBox:
|
|
|
333
374
|
justify_vertical: str = "top"
|
|
334
375
|
exclude_from_sim: bool = False
|
|
335
376
|
|
|
336
|
-
def __post_init__(self):
|
|
377
|
+
def __post_init__(self) -> None:
|
|
337
378
|
if not self.uuid:
|
|
338
379
|
self.uuid = str(uuid4())
|
|
339
380
|
|
|
@@ -349,7 +390,7 @@ class SchematicRectangle:
|
|
|
349
390
|
stroke_type: str = "default"
|
|
350
391
|
fill_type: str = "none"
|
|
351
392
|
|
|
352
|
-
def __post_init__(self):
|
|
393
|
+
def __post_init__(self) -> None:
|
|
353
394
|
if not self.uuid:
|
|
354
395
|
self.uuid = str(uuid4())
|
|
355
396
|
|
|
@@ -378,7 +419,7 @@ class Image:
|
|
|
378
419
|
data: str # Base64-encoded image data
|
|
379
420
|
scale: float = 1.0
|
|
380
421
|
|
|
381
|
-
def __post_init__(self):
|
|
422
|
+
def __post_init__(self) -> None:
|
|
382
423
|
if not self.uuid:
|
|
383
424
|
self.uuid = str(uuid4())
|
|
384
425
|
|
|
@@ -390,7 +431,7 @@ class NoConnect:
|
|
|
390
431
|
uuid: str
|
|
391
432
|
position: Point
|
|
392
433
|
|
|
393
|
-
def __post_init__(self):
|
|
434
|
+
def __post_init__(self) -> None:
|
|
394
435
|
if not self.uuid:
|
|
395
436
|
self.uuid = str(uuid4())
|
|
396
437
|
|
|
@@ -404,13 +445,13 @@ class Net:
|
|
|
404
445
|
wires: List[str] = field(default_factory=list) # Wire UUIDs
|
|
405
446
|
labels: List[str] = field(default_factory=list) # Label UUIDs
|
|
406
447
|
|
|
407
|
-
def add_connection(self, reference: str, pin: str):
|
|
448
|
+
def add_connection(self, reference: str, pin: str) -> None:
|
|
408
449
|
"""Add component pin to net."""
|
|
409
450
|
connection = (reference, pin)
|
|
410
451
|
if connection not in self.components:
|
|
411
452
|
self.components.append(connection)
|
|
412
453
|
|
|
413
|
-
def remove_connection(self, reference: str, pin: str):
|
|
454
|
+
def remove_connection(self, reference: str, pin: str) -> None:
|
|
414
455
|
"""Remove component pin from net."""
|
|
415
456
|
connection = (reference, pin)
|
|
416
457
|
if connection in self.components:
|
|
@@ -436,7 +477,7 @@ class Sheet:
|
|
|
436
477
|
stroke_type: str = "solid"
|
|
437
478
|
fill_color: Tuple[float, float, float, float] = (0, 0, 0, 0.0)
|
|
438
479
|
|
|
439
|
-
def __post_init__(self):
|
|
480
|
+
def __post_init__(self) -> None:
|
|
440
481
|
if not self.uuid:
|
|
441
482
|
self.uuid = str(uuid4())
|
|
442
483
|
|
|
@@ -451,7 +492,7 @@ class SheetPin:
|
|
|
451
492
|
pin_type: PinType = PinType.BIDIRECTIONAL
|
|
452
493
|
size: float = 1.27
|
|
453
494
|
|
|
454
|
-
def __post_init__(self):
|
|
495
|
+
def __post_init__(self) -> None:
|
|
455
496
|
if not self.uuid:
|
|
456
497
|
self.uuid = str(uuid4())
|
|
457
498
|
|
|
@@ -494,7 +535,7 @@ class Schematic:
|
|
|
494
535
|
rectangles: List[SchematicRectangle] = field(default_factory=list)
|
|
495
536
|
lib_symbols: Dict[str, Any] = field(default_factory=dict)
|
|
496
537
|
|
|
497
|
-
def __post_init__(self):
|
|
538
|
+
def __post_init__(self) -> None:
|
|
498
539
|
if not self.uuid:
|
|
499
540
|
self.uuid = str(uuid4())
|
|
500
541
|
|
kicad_sch_api/core/wires.py
CHANGED
|
@@ -9,56 +9,36 @@ import logging
|
|
|
9
9
|
import uuid as uuid_module
|
|
10
10
|
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
11
11
|
|
|
12
|
+
from .collections import BaseCollection
|
|
12
13
|
from .types import Point, Wire, WireType
|
|
13
14
|
|
|
14
15
|
logger = logging.getLogger(__name__)
|
|
15
16
|
|
|
16
17
|
|
|
17
|
-
class WireCollection:
|
|
18
|
+
class WireCollection(BaseCollection[Wire]):
|
|
18
19
|
"""
|
|
19
20
|
Professional wire collection with enhanced management features.
|
|
20
21
|
|
|
22
|
+
Inherits from BaseCollection for standard operations and adds wire-specific
|
|
23
|
+
functionality.
|
|
24
|
+
|
|
21
25
|
Features:
|
|
22
|
-
- Fast UUID-based lookup and indexing
|
|
23
|
-
- Bulk operations for performance
|
|
26
|
+
- Fast UUID-based lookup and indexing (inherited)
|
|
27
|
+
- Bulk operations for performance (inherited)
|
|
24
28
|
- Multi-point wire support
|
|
25
29
|
- Validation and conflict detection
|
|
26
30
|
- Junction management integration
|
|
31
|
+
- Wire geometry queries (horizontal, vertical, by-point)
|
|
27
32
|
"""
|
|
28
33
|
|
|
29
|
-
def __init__(self, wires: Optional[List[Wire]] = None):
|
|
34
|
+
def __init__(self, wires: Optional[List[Wire]] = None) -> None:
|
|
30
35
|
"""
|
|
31
36
|
Initialize wire collection.
|
|
32
37
|
|
|
33
38
|
Args:
|
|
34
39
|
wires: Initial list of wires
|
|
35
40
|
"""
|
|
36
|
-
|
|
37
|
-
self._uuid_index: Dict[str, int] = {}
|
|
38
|
-
self._modified = False
|
|
39
|
-
|
|
40
|
-
# Build UUID index
|
|
41
|
-
self._rebuild_index()
|
|
42
|
-
|
|
43
|
-
logger.debug(f"WireCollection initialized with {len(self._wires)} wires")
|
|
44
|
-
|
|
45
|
-
def _rebuild_index(self):
|
|
46
|
-
"""Rebuild UUID index for fast lookups."""
|
|
47
|
-
self._uuid_index = {wire.uuid: i for i, wire in enumerate(self._wires)}
|
|
48
|
-
|
|
49
|
-
def __len__(self) -> int:
|
|
50
|
-
"""Number of wires in collection."""
|
|
51
|
-
return len(self._wires)
|
|
52
|
-
|
|
53
|
-
def __iter__(self):
|
|
54
|
-
"""Iterate over wires."""
|
|
55
|
-
return iter(self._wires)
|
|
56
|
-
|
|
57
|
-
def __getitem__(self, uuid: str) -> Wire:
|
|
58
|
-
"""Get wire by UUID."""
|
|
59
|
-
if uuid not in self._uuid_index:
|
|
60
|
-
raise KeyError(f"Wire with UUID '{uuid}' not found")
|
|
61
|
-
return self._wires[self._uuid_index[uuid]]
|
|
41
|
+
super().__init__(wires, collection_name="wires")
|
|
62
42
|
|
|
63
43
|
def add(
|
|
64
44
|
self,
|
|
@@ -114,37 +94,14 @@ class WireCollection:
|
|
|
114
94
|
# Create wire
|
|
115
95
|
wire = Wire(uuid=uuid, points=wire_points, wire_type=wire_type, stroke_width=stroke_width)
|
|
116
96
|
|
|
117
|
-
# Add to collection
|
|
118
|
-
self.
|
|
119
|
-
self._uuid_index[uuid] = len(self._wires) - 1
|
|
120
|
-
self._modified = True
|
|
97
|
+
# Add to collection using base class method
|
|
98
|
+
self._add_item(wire)
|
|
121
99
|
|
|
122
100
|
logger.debug(f"Added wire: {len(wire_points)} points, UUID={uuid}")
|
|
123
101
|
return uuid
|
|
124
102
|
|
|
125
|
-
def remove(self, uuid: str) -> bool:
|
|
126
|
-
"""
|
|
127
|
-
Remove wire by UUID.
|
|
128
|
-
|
|
129
|
-
Args:
|
|
130
|
-
uuid: Wire UUID to remove
|
|
131
|
-
|
|
132
|
-
Returns:
|
|
133
|
-
True if wire was removed, False if not found
|
|
134
|
-
"""
|
|
135
|
-
if uuid not in self._uuid_index:
|
|
136
|
-
return False
|
|
137
|
-
|
|
138
|
-
index = self._uuid_index[uuid]
|
|
139
|
-
del self._wires[index]
|
|
140
|
-
self._rebuild_index()
|
|
141
|
-
self._modified = True
|
|
142
|
-
|
|
143
|
-
logger.debug(f"Removed wire: {uuid}")
|
|
144
|
-
return True
|
|
145
|
-
|
|
146
103
|
def get_by_point(
|
|
147
|
-
self, point: Union[Point, Tuple[float, float]], tolerance: float = None
|
|
104
|
+
self, point: Union[Point, Tuple[float, float]], tolerance: Optional[float] = None
|
|
148
105
|
) -> List[Wire]:
|
|
149
106
|
"""
|
|
150
107
|
Find wires that pass through or near a point.
|
|
@@ -164,7 +121,7 @@ class WireCollection:
|
|
|
164
121
|
point = Point(point[0], point[1])
|
|
165
122
|
|
|
166
123
|
matching_wires = []
|
|
167
|
-
for wire in self.
|
|
124
|
+
for wire in self._items:
|
|
168
125
|
# Check if any wire point is close
|
|
169
126
|
for wire_point in wire.points:
|
|
170
127
|
if wire_point.distance_to(point) <= tolerance:
|
|
@@ -213,40 +170,35 @@ class WireCollection:
|
|
|
213
170
|
|
|
214
171
|
def get_horizontal_wires(self) -> List[Wire]:
|
|
215
172
|
"""Get all horizontal wires."""
|
|
216
|
-
return [wire for wire in self.
|
|
173
|
+
return [wire for wire in self._items if wire.is_horizontal()]
|
|
217
174
|
|
|
218
175
|
def get_vertical_wires(self) -> List[Wire]:
|
|
219
176
|
"""Get all vertical wires."""
|
|
220
|
-
return [wire for wire in self.
|
|
177
|
+
return [wire for wire in self._items if wire.is_vertical()]
|
|
221
178
|
|
|
222
179
|
def get_statistics(self) -> Dict[str, Any]:
|
|
223
|
-
"""Get wire collection statistics."""
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
180
|
+
"""Get wire collection statistics (extends base statistics)."""
|
|
181
|
+
base_stats = super().get_statistics()
|
|
182
|
+
total_length = sum(wire.length for wire in self._items)
|
|
183
|
+
simple_wires = sum(1 for wire in self._items if wire.is_simple())
|
|
184
|
+
multi_point_wires = len(self._items) - simple_wires
|
|
227
185
|
|
|
228
186
|
return {
|
|
229
|
-
|
|
187
|
+
**base_stats,
|
|
188
|
+
"total_wires": len(self._items),
|
|
230
189
|
"simple_wires": simple_wires,
|
|
231
190
|
"multi_point_wires": multi_point_wires,
|
|
232
191
|
"total_length": total_length,
|
|
233
|
-
"avg_length": total_length / len(self.
|
|
192
|
+
"avg_length": total_length / len(self._items) if self._items else 0,
|
|
234
193
|
"horizontal_wires": len(self.get_horizontal_wires()),
|
|
235
194
|
"vertical_wires": len(self.get_vertical_wires()),
|
|
236
195
|
}
|
|
237
196
|
|
|
238
|
-
def clear(self):
|
|
239
|
-
"""Remove all wires from collection."""
|
|
240
|
-
self._wires.clear()
|
|
241
|
-
self._uuid_index.clear()
|
|
242
|
-
self._modified = True
|
|
243
|
-
logger.debug("Cleared all wires")
|
|
244
|
-
|
|
245
197
|
@property
|
|
246
198
|
def modified(self) -> bool:
|
|
247
199
|
"""Check if collection has been modified."""
|
|
248
|
-
return self.
|
|
200
|
+
return self.is_modified()
|
|
249
201
|
|
|
250
|
-
def mark_saved(self):
|
|
202
|
+
def mark_saved(self) -> None:
|
|
251
203
|
"""Mark collection as saved (reset modified flag)."""
|
|
252
|
-
self.
|
|
204
|
+
self.reset_modified_flag()
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Element-specific parsers for KiCAD schematic elements.
|
|
3
|
+
|
|
4
|
+
This module contains specialized parsers for different schematic element types,
|
|
5
|
+
extracted from the monolithic parser.py for better maintainability.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .graphics_parser import GraphicsParser
|
|
9
|
+
|
|
10
|
+
# Additional element parsers will be imported here as they are created
|
|
11
|
+
# from .wire_parser import WireParser
|
|
12
|
+
# from .label_parser import LabelParser
|
|
13
|
+
# from .text_parser import TextParser
|
|
14
|
+
# from .sheet_parser import SheetParser
|
|
15
|
+
# from .library_parser import LibraryParser
|
|
16
|
+
# from .symbol_parser import SymbolParser
|
|
17
|
+
# from .metadata_parser import MetadataParser
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"GraphicsParser",
|
|
21
|
+
# Will be populated as parsers are added
|
|
22
|
+
]
|