diff --git a/src/cdl_parser/constants.py b/src/cdl_parser/constants.py index 6d66c1b..415eaec 100644 --- a/src/cdl_parser/constants.py +++ b/src/cdl_parser/constants.py @@ -139,15 +139,29 @@ FEATURE_NAMES: set[str] = { # Growth features - "phantom", "sector", "zoning", "skeletal", "dendritic", + "phantom", + "sector", + "zoning", + "skeletal", + "dendritic", # Surface features - "striation", "trigon", "etch_pit", "growth_hillock", + "striation", + "trigon", + "etch_pit", + "growth_hillock", # Inclusion features - "inclusion", "needle", "silk", "fluid", "bubble", + "inclusion", + "needle", + "silk", + "fluid", + "bubble", # Color features - "colour", "colour_zone", "pleochroism", + "colour", + "colour_zone", + "pleochroism", # Other - "lamellar", "banding", + "lamellar", + "banding", } # ============================================================================= @@ -155,6 +169,12 @@ # ============================================================================= PHENOMENON_TYPES: set[str] = { - "asterism", "chatoyancy", "adularescence", "labradorescence", - "play_of_color", "colour_change", "aventurescence", "iridescence", + "asterism", + "chatoyancy", + "adularescence", + "labradorescence", + "play_of_color", + "colour_change", + "aventurescence", + "iridescence", } diff --git a/src/cdl_parser/models.py b/src/cdl_parser/models.py index 05533e2..c0fc221 100644 --- a/src/cdl_parser/models.py +++ b/src/cdl_parser/models.py @@ -246,20 +246,18 @@ def _form_node_to_dict(node: FormNode) -> dict[str, Any]: "scale": node.scale, "name": node.name, "label": node.label, - "features": [ - {"name": feat.name, "values": feat.values} - for feat in node.features - ] if node.features else None, + "features": [{"name": feat.name, "values": feat.values} for feat in node.features] + if node.features + else None, } elif isinstance(node, FormGroup): return { "type": "group", "forms": [_form_node_to_dict(f) for f in node.forms], "label": node.label, - "features": [ - {"name": feat.name, "values": feat.values} - for feat in node.features - ] if node.features else None, + "features": [{"name": feat.name, "values": feat.values} for feat in node.features] + if node.features + else None, } return {} @@ -346,10 +344,9 @@ def to_dict(self) -> dict[str, Any]: "scale": f.scale, "name": f.name, "label": f.label, - "features": [ - {"name": feat.name, "values": feat.values} - for feat in f.features - ] if f.features else None, + "features": [{"name": feat.name, "values": feat.values} for feat in f.features] + if f.features + else None, } for f in self.flat_forms() ], @@ -373,7 +370,9 @@ def to_dict(self) -> dict[str, Any]: "definitions": [ {"name": d.name, "body": [_form_node_to_dict(f) for f in d.body]} for d in self.definitions - ] if self.definitions else None, + ] + if self.definitions + else None, } @@ -386,10 +385,15 @@ def _flatten_node( merged = list(parent_features) if node.features: merged.extend(node.features) - return [CrystalForm( - miller=node.miller, scale=node.scale, - name=node.name, features=merged, label=node.label, - )] + return [ + CrystalForm( + miller=node.miller, + scale=node.scale, + name=node.name, + features=merged, + label=node.label, + ) + ] return [node] elif isinstance(node, FormGroup): combined_features = list(parent_features) if parent_features else [] diff --git a/src/cdl_parser/parser.py b/src/cdl_parser/parser.py index c7c935c..61a8672 100644 --- a/src/cdl_parser/parser.py +++ b/src/cdl_parser/parser.py @@ -70,6 +70,7 @@ def strip_comments(text: str) -> tuple[str, list[str]]: return text, doc_comments + # ============================================================================= # Token Types # ============================================================================= @@ -433,7 +434,10 @@ def parse(self) -> CrystalDescription: phenomenon = None if self._current().type == TokenType.PIPE: self._advance() # consume | - if self._current().type == TokenType.IDENTIFIER and self._current().value.lower() == "phenomenon": + if ( + self._current().type == TokenType.IDENTIFIER + and self._current().value.lower() == "phenomenon" + ): phenomenon = self._parse_phenomenon() return CrystalDescription( @@ -792,7 +796,11 @@ def _parse_phenomenon(self) -> PhenomenonSpec: else: # Bare identifier value params[key] = True - elif self._current().type in (TokenType.INTEGER, TokenType.FLOAT, TokenType.POINT_GROUP): + elif self._current().type in ( + TokenType.INTEGER, + TokenType.FLOAT, + TokenType.POINT_GROUP, + ): val = self._parse_feature_value() params["value"] = val diff --git a/tests/test_parser.py b/tests/test_parser.py index 39924ca..b380d2d 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -572,11 +572,7 @@ def test_multiple_doc_comments(self): def test_mixed_comments(self): """Mix of line, block, and doc comments.""" - cdl = ( - "#! Mineral: Quartz\n" - "# A line comment\n" - "/* block */ trigonal[-3m]:{10-10} # inline" - ) + cdl = "#! Mineral: Quartz\n# A line comment\n/* block */ trigonal[-3m]:{10-10} # inline" desc = parse_cdl(cdl) assert desc.system == "trigonal" assert desc.doc_comments == ["Mineral: Quartz"] @@ -1101,6 +1097,7 @@ class TestVersion: def test_version_1_3(self): """Version is 1.3.0.""" import cdl_parser + assert cdl_parser.__version__ == "1.3.0"