kicadts 0.0.2 → 0.0.4

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.
Files changed (195) hide show
  1. package/dist/index.d.ts +4466 -0
  2. package/dist/index.js +14253 -0
  3. package/package.json +5 -2
  4. package/.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc +0 -111
  5. package/.github/workflows/bun-formatcheck.yml +0 -26
  6. package/.github/workflows/bun-pver-release.yml +0 -70
  7. package/.github/workflows/bun-test.yml +0 -32
  8. package/.github/workflows/bun-typecheck.yml +0 -26
  9. package/.vscode/settings.json +0 -16
  10. package/AGENTS.md +0 -31
  11. package/TODO.md +0 -46
  12. package/biome.json +0 -93
  13. package/bunfig.toml +0 -5
  14. package/lib/index.ts +0 -1
  15. package/lib/sexpr/base-classes/SxClass.ts +0 -164
  16. package/lib/sexpr/base-classes/SxPrimitiveBoolean.ts +0 -35
  17. package/lib/sexpr/base-classes/SxPrimitiveNumber.ts +0 -26
  18. package/lib/sexpr/base-classes/SxPrimitiveString.ts +0 -26
  19. package/lib/sexpr/classes/At.ts +0 -53
  20. package/lib/sexpr/classes/Bus.ts +0 -103
  21. package/lib/sexpr/classes/BusEntry.ts +0 -169
  22. package/lib/sexpr/classes/Color.ts +0 -29
  23. package/lib/sexpr/classes/Dnp.ts +0 -8
  24. package/lib/sexpr/classes/EmbeddedFonts.ts +0 -68
  25. package/lib/sexpr/classes/ExcludeFromSim.ts +0 -8
  26. package/lib/sexpr/classes/FieldsAutoplaced.ts +0 -8
  27. package/lib/sexpr/classes/Footprint.ts +0 -849
  28. package/lib/sexpr/classes/FootprintAttr.ts +0 -104
  29. package/lib/sexpr/classes/FootprintAutoplaceCost180.ts +0 -9
  30. package/lib/sexpr/classes/FootprintAutoplaceCost90.ts +0 -9
  31. package/lib/sexpr/classes/FootprintClearance.ts +0 -9
  32. package/lib/sexpr/classes/FootprintDescr.ts +0 -44
  33. package/lib/sexpr/classes/FootprintLocked.ts +0 -32
  34. package/lib/sexpr/classes/FootprintModel.ts +0 -142
  35. package/lib/sexpr/classes/FootprintNetTiePadGroups.ts +0 -52
  36. package/lib/sexpr/classes/FootprintPad.ts +0 -857
  37. package/lib/sexpr/classes/FootprintPath.ts +0 -44
  38. package/lib/sexpr/classes/FootprintPlaced.ts +0 -32
  39. package/lib/sexpr/classes/FootprintPrivateLayers.ts +0 -56
  40. package/lib/sexpr/classes/FootprintSheetfile.ts +0 -44
  41. package/lib/sexpr/classes/FootprintSheetname.ts +0 -44
  42. package/lib/sexpr/classes/FootprintSolderMaskMargin.ts +0 -9
  43. package/lib/sexpr/classes/FootprintSolderPasteMargin.ts +0 -9
  44. package/lib/sexpr/classes/FootprintSolderPasteRatio.ts +0 -9
  45. package/lib/sexpr/classes/FootprintTags.ts +0 -44
  46. package/lib/sexpr/classes/FootprintTedit.ts +0 -21
  47. package/lib/sexpr/classes/FootprintThermalGap.ts +0 -9
  48. package/lib/sexpr/classes/FootprintThermalWidth.ts +0 -9
  49. package/lib/sexpr/classes/FootprintZoneConnect.ts +0 -9
  50. package/lib/sexpr/classes/FpArc.ts +0 -312
  51. package/lib/sexpr/classes/FpCircle.ts +0 -314
  52. package/lib/sexpr/classes/FpLine.ts +0 -316
  53. package/lib/sexpr/classes/FpPoly.ts +0 -286
  54. package/lib/sexpr/classes/FpPolyFill.ts +0 -48
  55. package/lib/sexpr/classes/FpPolyLocked.ts +0 -40
  56. package/lib/sexpr/classes/FpRect.ts +0 -314
  57. package/lib/sexpr/classes/FpText.ts +0 -375
  58. package/lib/sexpr/classes/FpTextBox.ts +0 -450
  59. package/lib/sexpr/classes/GrLine.ts +0 -264
  60. package/lib/sexpr/classes/GrLineAngle.ts +0 -32
  61. package/lib/sexpr/classes/GrLineEnd.ts +0 -61
  62. package/lib/sexpr/classes/GrLineLocked.ts +0 -40
  63. package/lib/sexpr/classes/GrLineStart.ts +0 -61
  64. package/lib/sexpr/classes/GrText.ts +0 -228
  65. package/lib/sexpr/classes/Image.ts +0 -283
  66. package/lib/sexpr/classes/InBom.ts +0 -8
  67. package/lib/sexpr/classes/Junction.ts +0 -166
  68. package/lib/sexpr/classes/KicadPcb.ts +0 -361
  69. package/lib/sexpr/classes/KicadSch.ts +0 -397
  70. package/lib/sexpr/classes/KicadSchGenerator.ts +0 -32
  71. package/lib/sexpr/classes/KicadSchGeneratorVersion.ts +0 -30
  72. package/lib/sexpr/classes/KicadSchVersion.ts +0 -22
  73. package/lib/sexpr/classes/Label.ts +0 -176
  74. package/lib/sexpr/classes/Layer.ts +0 -51
  75. package/lib/sexpr/classes/Layers.ts +0 -47
  76. package/lib/sexpr/classes/LibSymbols.ts +0 -61
  77. package/lib/sexpr/classes/NoConnect.ts +0 -90
  78. package/lib/sexpr/classes/OnBoard.ts +0 -8
  79. package/lib/sexpr/classes/PadChamfer.ts +0 -50
  80. package/lib/sexpr/classes/PadChamferRatio.ts +0 -9
  81. package/lib/sexpr/classes/PadClearance.ts +0 -9
  82. package/lib/sexpr/classes/PadDieLength.ts +0 -9
  83. package/lib/sexpr/classes/PadDrill.ts +0 -145
  84. package/lib/sexpr/classes/PadDrillOffset.ts +0 -54
  85. package/lib/sexpr/classes/PadLayers.ts +0 -71
  86. package/lib/sexpr/classes/PadNet.ts +0 -56
  87. package/lib/sexpr/classes/PadOptions.ts +0 -181
  88. package/lib/sexpr/classes/PadPinFunction.ts +0 -9
  89. package/lib/sexpr/classes/PadPinType.ts +0 -9
  90. package/lib/sexpr/classes/PadPrimitiveGrArc.ts +0 -272
  91. package/lib/sexpr/classes/PadPrimitiveGrCircle.ts +0 -298
  92. package/lib/sexpr/classes/PadPrimitiveGrLine.ts +0 -126
  93. package/lib/sexpr/classes/PadPrimitives.ts +0 -291
  94. package/lib/sexpr/classes/PadRectDelta.ts +0 -57
  95. package/lib/sexpr/classes/PadRoundrectRratio.ts +0 -9
  96. package/lib/sexpr/classes/PadSize.ts +0 -69
  97. package/lib/sexpr/classes/PadSolderMaskMargin.ts +0 -9
  98. package/lib/sexpr/classes/PadSolderPasteMargin.ts +0 -9
  99. package/lib/sexpr/classes/PadSolderPasteMarginRatio.ts +0 -9
  100. package/lib/sexpr/classes/PadTeardrops.ts +0 -210
  101. package/lib/sexpr/classes/PadThermalBridgeAngle.ts +0 -9
  102. package/lib/sexpr/classes/PadThermalGap.ts +0 -9
  103. package/lib/sexpr/classes/PadThermalWidth.ts +0 -9
  104. package/lib/sexpr/classes/PadZoneConnect.ts +0 -9
  105. package/lib/sexpr/classes/Paper.ts +0 -119
  106. package/lib/sexpr/classes/PcbGeneral.ts +0 -82
  107. package/lib/sexpr/classes/PcbGeneralLegacyTeardrops.ts +0 -44
  108. package/lib/sexpr/classes/PcbGeneralThickness.ts +0 -9
  109. package/lib/sexpr/classes/PcbGenerator.ts +0 -16
  110. package/lib/sexpr/classes/PcbGeneratorVersion.ts +0 -16
  111. package/lib/sexpr/classes/PcbLayerDefinition.ts +0 -106
  112. package/lib/sexpr/classes/PcbLayers.ts +0 -34
  113. package/lib/sexpr/classes/PcbNet.ts +0 -56
  114. package/lib/sexpr/classes/PcbVersion.ts +0 -9
  115. package/lib/sexpr/classes/Property.ts +0 -301
  116. package/lib/sexpr/classes/PropertyHide.ts +0 -9
  117. package/lib/sexpr/classes/PropertyUnlocked.ts +0 -9
  118. package/lib/sexpr/classes/Pts.ts +0 -67
  119. package/lib/sexpr/classes/RenderCache.ts +0 -221
  120. package/lib/sexpr/classes/SchematicText.ts +0 -171
  121. package/lib/sexpr/classes/Segment.ts +0 -243
  122. package/lib/sexpr/classes/SegmentEnd.ts +0 -59
  123. package/lib/sexpr/classes/SegmentLocked.ts +0 -33
  124. package/lib/sexpr/classes/SegmentNet.ts +0 -64
  125. package/lib/sexpr/classes/SegmentStart.ts +0 -59
  126. package/lib/sexpr/classes/Setup/PcbPlotParams.ts +0 -689
  127. package/lib/sexpr/classes/Setup/PcbPlotParamsBase.ts +0 -9
  128. package/lib/sexpr/classes/Setup/PcbPlotParamsNumericProperties.ts +0 -105
  129. package/lib/sexpr/classes/Setup/PcbPlotParamsStringPropertiesA.ts +0 -104
  130. package/lib/sexpr/classes/Setup/PcbPlotParamsStringPropertiesB.ts +0 -105
  131. package/lib/sexpr/classes/Setup/Setup.ts +0 -574
  132. package/lib/sexpr/classes/Setup/SetupPropertyTypes.ts +0 -119
  133. package/lib/sexpr/classes/Setup/Stackup.ts +0 -135
  134. package/lib/sexpr/classes/Setup/StackupLayer.ts +0 -233
  135. package/lib/sexpr/classes/Setup/StackupLayerProperties.ts +0 -80
  136. package/lib/sexpr/classes/Setup/StackupProperties.ts +0 -40
  137. package/lib/sexpr/classes/Setup/base.ts +0 -165
  138. package/lib/sexpr/classes/Setup/index.ts +0 -14
  139. package/lib/sexpr/classes/Setup/setupMultiValueProperties.ts +0 -53
  140. package/lib/sexpr/classes/Setup/setupNumericProperties.ts +0 -151
  141. package/lib/sexpr/classes/Setup/setupPropertyHandlers.ts +0 -90
  142. package/lib/sexpr/classes/Setup/setupStringProperties.ts +0 -75
  143. package/lib/sexpr/classes/Sheet.ts +0 -287
  144. package/lib/sexpr/classes/SheetFill.ts +0 -44
  145. package/lib/sexpr/classes/SheetInstances.ts +0 -168
  146. package/lib/sexpr/classes/SheetInstancesRoot.ts +0 -165
  147. package/lib/sexpr/classes/SheetPin.ts +0 -125
  148. package/lib/sexpr/classes/SheetProperty.ts +0 -115
  149. package/lib/sexpr/classes/SheetSize.ts +0 -44
  150. package/lib/sexpr/classes/Stroke.ts +0 -58
  151. package/lib/sexpr/classes/StrokeType.ts +0 -34
  152. package/lib/sexpr/classes/Symbol.ts +0 -1666
  153. package/lib/sexpr/classes/TextEffects.ts +0 -461
  154. package/lib/sexpr/classes/TitleBlock.ts +0 -369
  155. package/lib/sexpr/classes/Unit.ts +0 -28
  156. package/lib/sexpr/classes/Uuid.ts +0 -8
  157. package/lib/sexpr/classes/Via.ts +0 -363
  158. package/lib/sexpr/classes/ViaNet.ts +0 -60
  159. package/lib/sexpr/classes/Width.ts +0 -8
  160. package/lib/sexpr/classes/Wire.ts +0 -111
  161. package/lib/sexpr/classes/Xy.ts +0 -33
  162. package/lib/sexpr/classes/Zone.ts +0 -39
  163. package/lib/sexpr/index.ts +0 -130
  164. package/lib/sexpr/parseKicadSexpr.ts +0 -5
  165. package/lib/sexpr/parseToPrimitiveSExpr.ts +0 -245
  166. package/lib/sexpr/utils/indentLines.ts +0 -3
  167. package/lib/sexpr/utils/parseYesNo.ts +0 -12
  168. package/lib/sexpr/utils/quoteSExprString.ts +0 -8
  169. package/lib/sexpr/utils/strokeFromArgs.ts +0 -18
  170. package/lib/sexpr/utils/toNumberValue.ts +0 -13
  171. package/lib/sexpr/utils/toStringValue.ts +0 -11
  172. package/scripts/download-references.ts +0 -68
  173. package/tests/fixtures/expectEqualPrimitiveSExpr.ts +0 -199
  174. package/tests/fixtures/png-matcher.ts +0 -109
  175. package/tests/fixtures/preload.ts +0 -1
  176. package/tests/sexpr/KicadPcbDemos.test.ts +0 -48
  177. package/tests/sexpr/KicadSchDemos.test.ts +0 -49
  178. package/tests/sexpr/classes/Footprint.test.ts +0 -277
  179. package/tests/sexpr/classes/FootprintPad.test.ts +0 -78
  180. package/tests/sexpr/classes/FpArc.test.ts +0 -45
  181. package/tests/sexpr/classes/FpCircle.test.ts +0 -39
  182. package/tests/sexpr/classes/FpPoly.test.ts +0 -43
  183. package/tests/sexpr/classes/FpRect.test.ts +0 -40
  184. package/tests/sexpr/classes/FpTextBox.test.ts +0 -84
  185. package/tests/sexpr/classes/Image.test.ts +0 -58
  186. package/tests/sexpr/classes/KicadSch.test.ts +0 -95
  187. package/tests/sexpr/classes/Paper.test.ts +0 -30
  188. package/tests/sexpr/classes/Property.test.ts +0 -48
  189. package/tests/sexpr/classes/Setup.test.ts +0 -188
  190. package/tests/sexpr/classes/Sheet.test.ts +0 -107
  191. package/tests/sexpr/classes/Stroke.test.ts +0 -15
  192. package/tests/sexpr/classes/Symbol.test.ts +0 -96
  193. package/tests/sexpr/classes/TextEffects.test.ts +0 -56
  194. package/tests/sexpr/classes/TitleBlock.test.ts +0 -40
  195. package/tsconfig.json +0 -35
@@ -1,130 +0,0 @@
1
- export * from "./base-classes/SxClass"
2
- export * from "./classes/Stroke"
3
- export * from "./classes/Width"
4
- export * from "./classes/Unit"
5
- export * from "./classes/InBom"
6
- export * from "./classes/OnBoard"
7
- export * from "./classes/StrokeType"
8
- export * from "./classes/Color"
9
- export * from "./classes/Pts"
10
- export * from "./classes/At"
11
- export * from "./classes/Xy"
12
- export * from "./classes/TextEffects"
13
- export * from "./classes/TitleBlock"
14
- export * from "./classes/Paper"
15
- export * from "./classes/Image"
16
- export * from "./classes/RenderCache"
17
- export * from "./classes/Uuid"
18
- export * from "./classes/KicadSchGenerator"
19
- export * from "./classes/KicadSchVersion"
20
- export * from "./classes/KicadSchGeneratorVersion"
21
- export * from "./classes/LibSymbols"
22
- export * from "./classes/Wire"
23
- export * from "./classes/Bus"
24
- export * from "./classes/Junction"
25
- export * from "./classes/NoConnect"
26
- export * from "./classes/BusEntry"
27
- export * from "./classes/Label"
28
- export * from "./classes/SchematicText"
29
- export * from "./classes/KicadSch"
30
- export * from "./classes/Property"
31
- export * from "./classes/PropertyUnlocked"
32
- export * from "./classes/PropertyHide"
33
- export * from "./classes/Footprint"
34
- export * from "./classes/FootprintLocked"
35
- export * from "./classes/FootprintPlaced"
36
- export * from "./classes/FootprintTedit"
37
- export * from "./classes/FootprintDescr"
38
- export * from "./classes/FootprintTags"
39
- export * from "./classes/FootprintSheetname"
40
- export * from "./classes/FootprintSheetfile"
41
- export * from "./classes/FootprintPath"
42
- export * from "./classes/FootprintAutoplaceCost90"
43
- export * from "./classes/FootprintAutoplaceCost180"
44
- export * from "./classes/FootprintSolderMaskMargin"
45
- export * from "./classes/FootprintSolderPasteMargin"
46
- export * from "./classes/FootprintSolderPasteRatio"
47
- export * from "./classes/FootprintClearance"
48
- export * from "./classes/FootprintZoneConnect"
49
- export * from "./classes/FootprintThermalWidth"
50
- export * from "./classes/FootprintThermalGap"
51
- export * from "./classes/FootprintAttr"
52
- export * from "./classes/FootprintPrivateLayers"
53
- export * from "./classes/FootprintNetTiePadGroups"
54
- export * from "./classes/GrLine"
55
- export * from "./classes/GrLineStart"
56
- export * from "./classes/GrLineEnd"
57
- export * from "./classes/GrLineAngle"
58
- export * from "./classes/GrLineLocked"
59
- export * from "./classes/GrText"
60
- export * from "./classes/Segment"
61
- export * from "./classes/SegmentStart"
62
- export * from "./classes/SegmentEnd"
63
- export * from "./classes/SegmentNet"
64
- export * from "./classes/SegmentLocked"
65
- export * from "./classes/Zone"
66
- export * from "./classes/EmbeddedFonts"
67
- export * from "./classes/Layers"
68
- export * from "./classes/Layer"
69
- export * from "./classes/FpText"
70
- export * from "./classes/FpTextBox"
71
- export * from "./classes/FpLine"
72
- export * from "./classes/FpRect"
73
- export * from "./classes/FpCircle"
74
- export * from "./classes/FpArc"
75
- export * from "./classes/FpPoly"
76
- export * from "./classes/FpPolyFill"
77
- export * from "./classes/FpPolyLocked"
78
- export * from "./classes/FootprintPad"
79
- export * from "./classes/FootprintModel"
80
- export * from "./classes/PadSize"
81
- export * from "./classes/PadDrill"
82
- export * from "./classes/PadDrillOffset"
83
- export * from "./classes/PadLayers"
84
- export * from "./classes/PadRoundrectRratio"
85
- export * from "./classes/PadRectDelta"
86
- export * from "./classes/PadChamferRatio"
87
- export * from "./classes/PadChamfer"
88
- export * from "./classes/PadNet"
89
- export * from "./classes/PadPinFunction"
90
- export * from "./classes/PadPinType"
91
- export * from "./classes/PadDieLength"
92
- export * from "./classes/PadSolderMaskMargin"
93
- export * from "./classes/PadSolderPasteMargin"
94
- export * from "./classes/PadSolderPasteMarginRatio"
95
- export * from "./classes/PadClearance"
96
- export * from "./classes/PadZoneConnect"
97
- export * from "./classes/PadThermalWidth"
98
- export * from "./classes/PadThermalGap"
99
- export * from "./classes/PadThermalBridgeAngle"
100
- export * from "./classes/PadOptions"
101
- export * from "./classes/PadPrimitives"
102
- export * from "./classes/PadPrimitiveGrLine"
103
- export * from "./classes/PadPrimitiveGrArc"
104
- export * from "./classes/PadPrimitiveGrCircle"
105
- export * from "./classes/PadTeardrops"
106
- export * from "./classes/Symbol"
107
- export * from "./classes/Sheet"
108
- export * from "./classes/SheetPin"
109
- export * from "./classes/SheetProperty"
110
- export * from "./classes/SheetInstances"
111
- export * from "./classes/SheetInstancesRoot"
112
- export * from "./classes/SheetFill"
113
- export * from "./classes/SheetSize"
114
- export * from "./classes/FieldsAutoplaced"
115
- export * from "./classes/ExcludeFromSim"
116
- export * from "./classes/Dnp"
117
- export * from "./classes/Setup"
118
- export * from "./classes/PcbGeneral"
119
- export * from "./classes/PcbGeneralThickness"
120
- export * from "./classes/PcbGeneralLegacyTeardrops"
121
- export * from "./classes/PcbLayers"
122
- export * from "./classes/PcbLayerDefinition"
123
- export * from "./classes/PcbNet"
124
- export * from "./classes/PcbVersion"
125
- export * from "./classes/PcbGenerator"
126
- export * from "./classes/PcbGeneratorVersion"
127
- export * from "./classes/KicadPcb"
128
- export * from "./classes/Via"
129
- export * from "./classes/ViaNet"
130
- export * from "./parseKicadSexpr"
@@ -1,5 +0,0 @@
1
- import { SxClass } from "./base-classes/SxClass"
2
-
3
- export const parseKicadSexpr = (sexpr: string) => {
4
- return SxClass.parse(sexpr)
5
- }
@@ -1,245 +0,0 @@
1
- // s_expr_parser.ts
2
- export type PrimitiveSExpr =
3
- | string // symbols and string literals (distinct via `type` guard if you want)
4
- | number
5
- | boolean
6
- | null
7
- | PrimitiveSExpr[] // lists
8
-
9
- type Token =
10
- | { type: "lparen" }
11
- | { type: "rparen" }
12
- | { type: "number"; value: number }
13
- | { type: "string"; value: string }
14
- | { type: "boolean"; value: boolean }
15
- | { type: "nil" }
16
- | { type: "symbol"; value: string }
17
-
18
- export function tokenize(input: string): Token[] {
19
- const tokens: Token[] = []
20
- let i = 0
21
-
22
- const isWhitespace = (ch: string) => /\s/.test(ch)
23
- const isSymbolInitial = (ch: string) => /[^\s()"]/u.test(ch) // anything except ws, parens, quote
24
- const peek = () => (i < input.length ? input[i]! : undefined)
25
- const advance = () => {
26
- if (i >= input.length) {
27
- throw new SyntaxError("Unexpected end of input")
28
- }
29
- return input[i++]!
30
- }
31
-
32
- while (i < input.length) {
33
- const ch = peek()
34
- if (ch === undefined) {
35
- break
36
- }
37
- const current: string = ch
38
-
39
- // Skip whitespace
40
- if (isWhitespace(current)) {
41
- i++
42
- continue
43
- }
44
-
45
- // Comments ;...<EOL>
46
- if (current === ";") {
47
- while (i < input.length && input[i] !== "\n") i++
48
- continue
49
- }
50
-
51
- if (current === "(") {
52
- tokens.push({ type: "lparen" })
53
- i++
54
- continue
55
- }
56
- if (current === ")") {
57
- tokens.push({ type: "rparen" })
58
- i++
59
- continue
60
- }
61
-
62
- // String literal
63
- if (current === '"') {
64
- i++ // skip opening quote
65
- let out = ""
66
- while (i < input.length) {
67
- const c = advance()
68
- if (c === '"') break
69
- if (c === "\\") {
70
- if (i >= input.length)
71
- throw new SyntaxError("Unterminated escape in string")
72
- const e = advance()
73
- switch (e) {
74
- case "n":
75
- out += "\n"
76
- break
77
- case "r":
78
- out += "\r"
79
- break
80
- case "t":
81
- out += "\t"
82
- break
83
- case '"':
84
- out += '"'
85
- break
86
- case "\\":
87
- out += "\\"
88
- break
89
- default:
90
- out += e
91
- break // unknown escapes: keep raw
92
- }
93
- } else {
94
- out += c
95
- }
96
- }
97
- if (input[i - 1] !== '"')
98
- throw new SyntaxError("Unterminated string literal")
99
- tokens.push({ type: "string", value: out })
100
- continue
101
- }
102
-
103
- // Number or symbol
104
- if (
105
- isSymbolInitial(current) ||
106
- current === "-" ||
107
- current === "+" ||
108
- current === "."
109
- ) {
110
- // read a maximal token until delimiter
111
- let start = i
112
- while (i < input.length) {
113
- const nextChar = input[i]!
114
- if (
115
- isWhitespace(nextChar) ||
116
- nextChar === "(" ||
117
- nextChar === ")" ||
118
- nextChar === '"'
119
- ) {
120
- break
121
- }
122
- i++
123
- }
124
- const raw = input.slice(start, i)
125
-
126
- // Booleans
127
- if (raw === "#t") {
128
- tokens.push({ type: "boolean", value: true })
129
- continue
130
- }
131
- if (raw === "#f") {
132
- tokens.push({ type: "boolean", value: false })
133
- continue
134
- }
135
-
136
- // nil
137
- if (raw === "nil") {
138
- tokens.push({ type: "nil" })
139
- continue
140
- }
141
-
142
- // Numbers (int/float), allow leading +/-, decimals, exponent
143
- if (/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?$/u.test(raw)) {
144
- tokens.push({ type: "number", value: Number(raw) })
145
- } else {
146
- tokens.push({ type: "symbol", value: raw })
147
- }
148
- continue
149
- }
150
-
151
- throw new SyntaxError(`Unexpected character: ${JSON.stringify(ch)} at ${i}`)
152
- }
153
-
154
- return tokens
155
- }
156
-
157
- export function parseToPrimitiveSExpr(input: string): PrimitiveSExpr[] {
158
- const toks = tokenize(input)
159
- let idx = 0
160
-
161
- const peekToken = () => (idx < toks.length ? toks[idx]! : undefined)
162
- const advanceToken = () => {
163
- if (idx >= toks.length) {
164
- throw new SyntaxError("Unexpected end of input")
165
- }
166
- return toks[idx++]!
167
- }
168
-
169
- function readForm(): PrimitiveSExpr {
170
- const t = advanceToken()
171
-
172
- switch (t.type) {
173
- case "lparen": {
174
- const list: PrimitiveSExpr[] = []
175
- while (true) {
176
- const next = peekToken()
177
- if (!next) {
178
- throw new SyntaxError("Unmatched '('")
179
- }
180
- if (next.type === "rparen") break
181
- list.push(readForm())
182
- }
183
- advanceToken() // consume rparen
184
- return list
185
- }
186
- case "rparen":
187
- throw new SyntaxError("Unmatched ')'")
188
- case "number":
189
- return t.value
190
- case "string":
191
- return t.value
192
- case "boolean":
193
- return t.value
194
- case "nil":
195
- return null
196
- case "symbol":
197
- return t.value // represent symbols as strings
198
- }
199
- }
200
-
201
- const forms: PrimitiveSExpr[] = []
202
- while (peekToken()) forms.push(readForm())
203
- return forms
204
- }
205
-
206
- /* -------------------------
207
- Tiny helper utilities
208
- --------------------------*/
209
-
210
- export function printSExpr(x: PrimitiveSExpr): string {
211
- if (x === null) return "nil"
212
- if (typeof x === "boolean") return x ? "#t" : "#f"
213
- if (typeof x === "number") return Number.isFinite(x) ? String(x) : "nan"
214
- if (typeof x === "string") {
215
- // naive: treat as symbol if it looks like a symbol; otherwise quote
216
- if (/^[^\s()"]+$/u.test(x) && x !== "nil" && x !== "#t" && x !== "#f")
217
- return x
218
- return `"${x.replace(/["\\\n\r\t]/g, (m) =>
219
- m === '"'
220
- ? '\\"'
221
- : m === "\\"
222
- ? "\\\\"
223
- : m === "\n"
224
- ? "\\n"
225
- : m === "\r"
226
- ? "\\r"
227
- : "\\t",
228
- )}"`
229
- }
230
- if (Array.isArray(x)) {
231
- return `(${x.map(printSExpr).join(" ")})`
232
- }
233
-
234
- throw new Error(`Unsupported S-expression value: ${JSON.stringify(x)}`)
235
- }
236
-
237
- // Quick example:
238
- // const program = `
239
- // ; define square
240
- // (define (square x) (* x x))
241
- // (list 1 2.5 "hi" #t nil foo-bar)
242
- // `;
243
- // const ast = parseSExpr(program);
244
- // console.log(JSON.stringify(ast, null, 2));
245
- // console.log(ast.map(printSExpr).join("\n"));
@@ -1,3 +0,0 @@
1
- export const indentLines = (value: string, indent = " "): string[] => {
2
- return value.split("\n").map((line) => `${indent}${line}`)
3
- }
@@ -1,12 +0,0 @@
1
- import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
2
- import { toStringValue } from "./toStringValue"
3
-
4
- export const parseYesNo = (
5
- value: PrimitiveSExpr | undefined,
6
- ): boolean | undefined => {
7
- const str = toStringValue(value)
8
- if (!str) return undefined
9
- if (str === "yes" || str === "true") return true
10
- if (str === "no" || str === "false") return false
11
- return undefined
12
- }
@@ -1,8 +0,0 @@
1
- export const quoteSExprString = (value: string): string => {
2
- return `"${value
3
- .replace(/\\/g, "\\\\")
4
- .replace(/"/g, '\\"')
5
- .replace(/\n/g, "\\n")
6
- .replace(/\r/g, "\\r")
7
- .replace(/\t/g, "\\t")}"`
8
- }
@@ -1,18 +0,0 @@
1
- import { SxClass } from "../base-classes/SxClass"
2
- import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
3
- import { Stroke } from "../classes/Stroke"
4
-
5
- export const strokeFromArgs = (args: PrimitiveSExpr[]): Stroke | undefined => {
6
- try {
7
- const parsed = SxClass.parsePrimitiveSexpr([
8
- "stroke",
9
- ...args,
10
- ] as PrimitiveSExpr)
11
- if (parsed instanceof Stroke) {
12
- return parsed
13
- }
14
- } catch {
15
- // Ignore parse errors and defer to caller
16
- }
17
- return undefined
18
- }
@@ -1,13 +0,0 @@
1
- import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
2
-
3
- export const toNumberValue = (
4
- value: PrimitiveSExpr | undefined,
5
- ): number | undefined => {
6
- if (value === undefined) return undefined
7
- if (typeof value === "number") return value
8
- if (typeof value === "string") {
9
- const parsed = Number(value)
10
- return Number.isNaN(parsed) ? undefined : parsed
11
- }
12
- return undefined
13
- }
@@ -1,11 +0,0 @@
1
- import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
2
-
3
- export const toStringValue = (
4
- value: PrimitiveSExpr | undefined,
5
- ): string | undefined => {
6
- if (value === undefined) return undefined
7
- if (typeof value === "string") return value
8
- if (typeof value === "number" || typeof value === "boolean")
9
- return String(value)
10
- return undefined
11
- }
@@ -1,68 +0,0 @@
1
- import { mkdir, writeFile } from "node:fs/promises"
2
- import { resolve, dirname } from "node:path"
3
- import { fileURLToPath } from "node:url"
4
-
5
- type ReferenceSpec = {
6
- readonly url: string
7
- readonly filename: string
8
- }
9
-
10
- const references: ReferenceSpec[] = [
11
- {
12
- url: "https://gitlab.com/kicad/services/kicad-dev-docs/-/raw/master/content/file-formats/sexpr-intro/_index.en.adoc",
13
- filename: "SEXPR_MAIN.adoc",
14
- },
15
- {
16
- url: "https://gitlab.com/kicad/services/kicad-dev-docs/-/raw/master/content/file-formats/sexpr-schematic/_index.en.adoc",
17
- filename: "SCHEMATIC_SEXPR.adoc",
18
- },
19
- {
20
- url: "https://gitlab.com/kicad/services/kicad-dev-docs/-/raw/master/content/file-formats/sexpr-pcb/_index.en.adoc",
21
- filename: "PCB_SEXPR.adoc",
22
- },
23
- {
24
- url: "https://gitlab.com/kicad/services/kicad-dev-docs/-/raw/master/content/file-formats/sexpr-footprint/_index.en.adoc",
25
- filename: "FOOTPRINT_SEXPR.adoc",
26
- },
27
- {
28
- url: "https://gitlab.com/kicad/services/kicad-dev-docs/-/raw/master/content/file-formats/sexpr-symbol-lib/_index.en.adoc",
29
- filename: "SCH_SYM_SEXPR.adoc",
30
- },
31
- ]
32
-
33
- const __dirname = dirname(fileURLToPath(import.meta.url))
34
- const repoRoot = resolve(__dirname, "..")
35
- const referencesDir = resolve(repoRoot, "references")
36
-
37
- async function fetchReference(reference: ReferenceSpec): Promise<void> {
38
- const response = await fetch(reference.url)
39
-
40
- if (!response.ok) {
41
- throw new Error(
42
- `${reference.url} (${response.status} ${response.statusText})`,
43
- )
44
- }
45
-
46
- const content = await response.text()
47
- const targetPath = resolve(referencesDir, reference.filename)
48
-
49
- await writeFile(targetPath, content, "utf8")
50
- console.log(`Saved ${reference.filename}`)
51
- }
52
-
53
- async function main(): Promise<void> {
54
- await mkdir(referencesDir, { recursive: true })
55
-
56
- await Promise.all(
57
- references.map(async (reference) => {
58
- try {
59
- await fetchReference(reference)
60
- } catch (error) {
61
- console.error(`Failed to download ${reference.filename}:`, error)
62
- process.exitCode = 1
63
- }
64
- }),
65
- )
66
- }
67
-
68
- await main()