@@ -731,7 +731,14 @@ export class DimensionStyle {
731731 }
732732}
733733
734- type FootprintDrawings = FpLine | FpCircle | FpArc | FpPoly | FpRect | FpText ;
734+ type FootprintDrawings =
735+ | FpLine
736+ | FpCircle
737+ | FpArc
738+ | FpPoly
739+ | FpRect
740+ | FpText
741+ | SymbolProperty ;
735742
736743export class Footprint {
737744 at : At ;
@@ -776,7 +783,7 @@ export class Footprint {
776783 allow_solder_mask_bridges : false ,
777784 allow_missing_courtyard : false ,
778785 } ;
779- properties : Record < string , string > = { } ;
786+ properties : Record < string , SymbolProperty > = { } ;
780787 drawings : FootprintDrawings [ ] = [ ] ;
781788 pads : Pad [ ] = [ ] ;
782789 #pads_by_number = new Map < string , Pad > ( ) ;
@@ -826,7 +833,7 @@ export class Footprint {
826833 P . atom ( "allow_solder_mask_bridges" ) ,
827834 P . atom ( "allow_missing_courtyard" ) ,
828835 ) ,
829- P . dict ( "properties" , "property" , T . string ) ,
836+ P . dict ( "properties" , "property" , T . item ( SymbolProperty , this ) ) ,
830837 P . collection ( "drawings" , "fp_line" , T . item ( FpLine , this ) ) ,
831838 P . collection ( "drawings" , "fp_circle" , T . item ( FpCircle , this ) ) ,
832839 P . collection ( "drawings" , "fp_arc" , T . item ( FpArc , this ) ) ,
@@ -860,13 +867,13 @@ export class Footprint {
860867 // KiCad correctly parses both definitions
861868 // (fp_text reference XXXX) and (property "Reference" "XXXX")
862869 // https://dev-docs.kicad.org/en/file-formats/sexpr-intro/index.html#_symbol_properties
863- for ( const [ prop_name , prop_value ] of Object . entries ( this . properties ) ) {
870+ for ( const [ prop_name , prop ] of Object . entries ( this . properties ) ) {
864871 if ( this . reference === undefined && prop_name == "Reference" ) {
865- this . reference = prop_value ;
872+ this . reference = prop . value ;
866873 }
867874
868875 if ( this . value === undefined && prop_name == "Value" ) {
869- this . value = prop_value ;
876+ this . value = prop . value ;
870877 }
871878 }
872879 }
@@ -879,6 +886,10 @@ export class Footprint {
879886 yield * this . drawings ?? [ ] ;
880887 yield * this . zones ?? [ ] ;
881888 yield * this . pads . values ( ) ?? [ ] ;
889+
890+ yield * Object . values ( this . properties ) . filter (
891+ ( prop ) => prop . has_symbol_prop ,
892+ ) ;
882893 }
883894
884895 resolve_text_var ( name : string ) : string | undefined {
@@ -914,7 +925,7 @@ export class Footprint {
914925 }
915926
916927 if ( this . properties [ name ] !== undefined ) {
917- return this . properties [ name ] ! ;
928+ return this . properties [ name ] ! . value ;
918929 }
919930
920931 return this . parent . resolve_text_var ( name ) ;
@@ -949,7 +960,7 @@ export class Footprint {
949960 ) . rotate_self ( Angle . deg_to_rad ( this . at . rotation ) ) ;
950961
951962 for ( const item of this . drawings ) {
952- if ( item instanceof FpText ) {
963+ if ( item instanceof FpText || item instanceof SymbolProperty ) {
953964 continue ;
954965 }
955966
@@ -963,6 +974,63 @@ export class Footprint {
963974 }
964975}
965976
977+ export class SymbolProperty {
978+ has_symbol_prop : boolean ;
979+
980+ // generic properties
981+ // https://dev-docs.kicad.org/en/file-formats/sexpr-intro/index.html#_properties
982+ value : string ;
983+
984+ // symbol properties
985+ // https://dev-docs.kicad.org/en/file-formats/sexpr-intro/index.html#_symbol_properties
986+ id : number = 0 ;
987+ unlocked = false ;
988+ hide = false ;
989+ at : At = new At ( ) ;
990+ effects : Effects = new Effects ( ) ;
991+ layer : string = "F.SilkS" ;
992+ uuid ?: string ;
993+
994+ constructor (
995+ expr : Parseable ,
996+ public parent : Footprint ,
997+ ) {
998+ // for some reasons, I cannot get kicad_version here
999+ // const is_newer = parent.parent.version >= 20240108;
1000+ const is_newer = expr instanceof Array && expr . length > 3 ;
1001+
1002+ if ( is_newer ) {
1003+ this . has_symbol_prop = true ;
1004+ // parsed as 'symbol_property' node
1005+ Object . assign (
1006+ this ,
1007+ parse_expr (
1008+ expr ,
1009+ P . positional ( "value" , T . string ) ,
1010+ P . pair ( "id" , T . number ) ,
1011+ P . item ( "at" , At ) ,
1012+ P . pair ( "layer" , T . string ) ,
1013+ P . pair ( "uuid" , T . string ) ,
1014+ P . atom ( "unlocked" ) ,
1015+ P . atom ( "hide" ) ,
1016+ P . item ( "effects" , Effects ) ,
1017+ ) ,
1018+ ) ;
1019+ } else {
1020+ this . has_symbol_prop = false ;
1021+ // parsed as 'property' node
1022+ Object . assign (
1023+ this ,
1024+ parse_expr ( expr , P . positional ( "value" , T . string ) ) ,
1025+ ) ;
1026+ }
1027+ }
1028+
1029+ get shown_text ( ) {
1030+ return expand_text_vars ( this . value , this . parent ) ;
1031+ }
1032+ }
1033+
9661034class GraphicItem {
9671035 parent ?: Footprint ;
9681036 layer : string ;
0 commit comments