Skip to content

Commit

Permalink
Fix handling of top level schematic lib symbols
Browse files Browse the repository at this point in the history
  • Loading branch information
Frzoen committed Feb 26, 2024
1 parent e1abab3 commit 1a5ae30
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/kiutils/schematic.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

from kiutils.items.common import Image, PageSettings, TitleBlock
from kiutils.items.schitems import *
from kiutils.symbol import Symbol
from kiutils.symbol import Symbol, SchematicLibSymbol
from kiutils.utils import sexpr
from kiutils.misc.config import KIUTILS_CREATE_NEW_GENERATOR_STR, KIUTILS_CREATE_NEW_VERSION_STR

Expand All @@ -48,7 +48,7 @@ class Schematic():
titleBlock: Optional[TitleBlock] = None
"""The ``titleBlock`` token defines author, date, revision, company and comments of the schematic"""

libSymbols: List[Symbol] = field(default_factory=list)
libSymbols: List[SchematicLibSymbol] = field(default_factory=list)
"""The ``libSymbols`` token defines a list of symbols that are used in the schematic"""

schematicSymbols: List[SchematicSymbol] = field(default_factory=list)
Expand Down Expand Up @@ -143,7 +143,7 @@ def from_sexpr(cls, exp: list) -> Schematic:
if item[0] == 'title_block': object.titleBlock = TitleBlock().from_sexpr(item)
if item[0] == 'lib_symbols':
for symbol in item[1:]:
object.libSymbols.append(Symbol().from_sexpr(symbol))
object.libSymbols.append(SchematicLibSymbol().from_sexpr(symbol))
if item[0] == 'junction': object.junctions.append(Junction().from_sexpr(item))
if item[0] == 'no_connect': object.noConnects.append(NoConnect().from_sexpr(item))
if item[0] == 'bus_entry': object.busEntries.append(BusEntry().from_sexpr(item))
Expand Down
76 changes: 76 additions & 0 deletions src/kiutils/symbol.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,82 @@ def to_sexpr(self, indent: int = 2, newline: bool = True) -> str:
expression += f'{indents}){endline}'
return expression

@dataclass
class SchematicLibSymbol(Symbol):
"""The ``symbol`` token defines a symbol or sub-unit of a parent symbol. There can be zero or more
``symbol`` tokens in a symbol library file.
Documentation:
https://dev-docs.kicad.org/en/file-formats/sexpr-intro/index.html#_symbols
"""

"""Each symbol must have """
@property
def libId(self) -> str:
"""The ``lib_id`` token defines a unique "LIBRARY_ID" for each top level symbol in the
library or a unique "UNIT_ID" for each unit embedded in a parent symbol. Library identifiers
are only valid it top level symbols and unit identifiers are on valid as unit symbols inside
a parent symbol.
The following conventions apply:
- "LIBRARY_ID" (top-level symbol): ``[<libraryNickname>:]<entryName>`` (the library
nickname part is optional here)
In ``kiutils``, the ``lib_id`` token is a combination of ``libraryNickname``, ``entryName``,
``unitId`` and ``styleId`` tokens. Setting the ``lib_id`` token will update all those tokens
accordingly.
Returns:
- If the ``libraryNickname`` is set: ``<libraryNickname>:<entryName>``
- If the ``libraryNickname`` is ``None``: ``<entryName>``
depending if these tokens are set.
"""
if (self.unitId is not None and self.styleId is not None):
unit_style_ids = f"_{self.unitId}_{self.styleId}"
else:
unit_style_ids = ""

if self.libraryNickname:
return f'{self.libraryNickname}:{self.entryName}'
else:
return f'{self.entryName}{unit_style_ids}'

@libId.setter
def libId(self, symbol_id: str):
"""Sets the ``lib_id`` token and parses its contents into the ``libraryNickname``,
``entryName`` and ``styleId`` token.
See self.libId property description for more information.
Args:
- symbol_id (str): The symbol id in the following format: ``<libraryNickname>:<entryName>``
or only ``<entryName>``, depending on if the symbol
is a top-level symbol or a child symbol
Raises:
- Exception: If the given ID is neither a top-level nor a child symbol
"""
# Try to parse the given ID
parse_symbol_id = re.match(r"^(.+?):(.+?)$", symbol_id)
if parse_symbol_id:
# The symbol is a top-level symbol with a library nickname
self.libraryNickname = parse_symbol_id.group(1)
self.entryName = parse_symbol_id.group(2)
self.unitId = None
self.styleId = None
else:
# The symbol is a top-level symbol without a library nickname
self.libraryNickname = None
self.entryName = symbol_id
self.unitId = None
self.styleId = None

# Update units id to match parent id
for unit in self.units:
unit.entryName = self.entryName



@dataclass
class SymbolLib():
"""A symbol library defines the common format of ``.kicad_sym`` files. A symbol library may contain
Expand Down

0 comments on commit 1a5ae30

Please sign in to comment.