@schemd/core 0.1.1 → 0.1.2

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.
package/README.md CHANGED
@@ -1,119 +1,60 @@
1
1
  # @schemd/core
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/@schemd/core.svg?style=flat-square)](https://www.npmjs.com/package/@schemd/core)
4
- [![CI status](https://github.com/Sirneij/schemd/actions/workflows/ci.yml/badge.svg?style=flat-square)](https://github.com/Sirneij/schemd/actions/workflows/ci.yml)
5
- [![license](https://img.shields.io/npm/l/@schemd/core.svg?style=flat-square)](https://github.com/Sirneij/schemd/blob/main/LICENSE)
3
+ Write schematics and UML as text. Get accessible, deterministic SVG.
6
4
 
7
- Write engineering diagrams as text and compile them to accessible inline SVG.
8
-
9
- Schemd supports electrical components, logic gates, quantum gates, and general system diagrams. It runs on the server or during a build, so the browser only receives SVG—no diagram runtime, DOM, or layout engine.
10
-
11
- ## Why Schemd?
12
-
13
- - Small, readable text format
14
- - Deterministic SVG output with fixed dimensions
15
- - Straight, curved, and obstacle-aware orthogonal connections
16
- - Accessible titles and descriptions
17
- - No runtime dependencies
5
+ Schemd has no runtime dependencies, browser layout pass, or DOM requirement. It works on a server or during a build.
18
6
 
19
7
  ## Install
20
8
 
21
- Schemd requires Node.js 24 or newer. Install `marked` if you want to use Markdown fences.
22
-
23
9
  ```sh
24
- npm install @schemd/core marked
10
+ npm install @schemd/core
25
11
  ```
26
12
 
27
- ## Use with Markdown
13
+ Node.js 24+ is required. Install `marked` too if you use Markdown fences.
14
+
15
+ ## Quick start
28
16
 
29
17
  ```ts
30
- import { Marked } from "marked";
31
- import { schematicMarkedExtension } from "@schemd/core";
18
+ import { parseSchematic, parseSchematicFence, renderSchematic } from "@schemd/core";
32
19
 
33
- const markdown = new Marked();
34
- markdown.use(schematicMarkedExtension());
20
+ const fence = parseSchematicFence(
21
+ 'schemd bounds="640x260" title="Sensor input"',
22
+ )!;
35
23
 
36
- const html = await markdown.parse(`
37
- \`\`\`schemd bounds="640x260" title="Sensor input"
24
+ const diagram = parseSchematic(`
38
25
  port:VIN "Input" at (60, 130) #blue
39
26
  resistor:R1 "10 k\\Omega" at (220, 130) #amber
40
27
  capacitor:C1 "100 nF" at (400, 130) #cyan
41
28
 
42
29
  VIN.out -> R1.in #blue [ortho]
43
30
  R1.out -> C1.in #amber [ortho]
44
- \`\`\`
45
- `);
46
- ```
47
-
48
- ## Use the compiler directly
49
-
50
- ```ts
51
- import {
52
- parseSchematic,
53
- parseSchematicFence,
54
- renderSchematic,
55
- } from "@schemd/core";
56
-
57
- const fence = parseSchematicFence(
58
- 'schemd bounds="640x260" title="Sensor input"',
59
- );
31
+ `, fence);
60
32
 
61
- if (!fence) throw new Error("Expected a schemd fence");
62
-
63
- const diagram = parseSchematic(
64
- `port:VIN "Input" at (60, 130) #blue
65
- resistor:R1 "10 k\\Omega" at (220, 130) #amber
66
- VIN.out -> R1.in #blue [ortho]`,
67
- fence,
68
- );
69
-
70
- const svg = renderSchematic(diagram, fence);
33
+ const html = renderSchematic(diagram, fence);
71
34
  ```
72
35
 
73
- ## The language
74
-
75
- A diagram has component declarations and connections:
36
+ The DSL is intentionally small:
76
37
 
77
38
  ```text
78
39
  kind:ID "label" at (x, y) color [options]
79
40
  ID.port -> ID.port color [line|bezier|ortho]
80
41
  ```
81
42
 
82
- Available components include resistors, capacitors, inductors, diodes, transistors, grounds, ports, logic gates, quantum gates, and configurable IC blocks.
43
+ It includes electrical parts, analog devices, logic and quantum gates, configurable ICs, math labels, collision-aware routing, and wire bridges.
83
44
 
84
- Use `line`, `bezier`, or `ortho` to choose a connection style. Arrow and dot markers are also supported:
45
+ UML nodes and relations use the same syntax:
85
46
 
86
47
  ```text
87
- U1.out -> U2.in #emerald [ortho marker-end=arrow]
88
- ```
89
-
90
- See the [full documentation](https://johnowolabiidogun.dev/tools/schemd/docs/overview) for component ports, options, colors, math labels, and framework integrations.
91
-
92
- ## Output modes
48
+ class:User "User" at (160, 120) #slate [attributes="- id: UUID" operations="+ save(): void"]
49
+ class:Admin "Admin" at (460, 120) #blue
93
50
 
94
- | Mode | Use it for |
95
- | --- | --- |
96
- | `default` | Small, static SVG |
97
- | `embedded-css` | Built-in styles and responsive visuals |
98
- | `full` | Interactive diagrams with node and wire metadata |
99
-
100
- Pass a mode to `renderSchematic` or `schematicMarkedExtension`:
101
-
102
- ```ts
103
- const svg = renderSchematic(diagram, { ...fence, mode: "embedded-css" });
51
+ Admin.left -> User.right #blue [ortho generalization]
104
52
  ```
105
53
 
106
- ## Security
54
+ Class, actor, use-case, state, lifeline, note, package, initial, and final nodes are built in. Relations include association, dependency, generalization, realization, aggregation, composition, message, transition, include, and extend.
107
55
 
108
- Schemd validates input, escapes labels, limits diagram size, and returns bounded SVG. Compile diagrams on a trusted server or build system, then send the generated SVG to the browser. Do not treat arbitrary HTML as Schemd output.
56
+ Use `mode: "embedded-css"` for built-in styling or `mode: "full"` for interaction metadata. The default output stays compact and static.
109
57
 
110
- ## Development
111
-
112
- ```sh
113
- npm install
114
- npm run check
115
- npm test
116
- npm run build
117
- ```
58
+ For Markdown, use `schematicMarkedExtension()` from the main package or the `@schemd/core/marked` subpath.
118
59
 
119
- Schemd is available under the [MIT License](https://github.com/Sirneij/schemd/blob/main/LICENSE).
60
+ [Documentation](https://johnowolabiidogun.dev/tools/schemd/docs/overview) · [Issues](https://github.com/Sirneij/schemd/issues) · [MIT](https://github.com/Sirneij/schemd/blob/main/LICENSE)
package/dist/index.d.ts CHANGED
@@ -10,7 +10,7 @@
10
10
  export { parseSchematic, parseSchematicColor, parseSchematicFence } from './parser.js';
11
11
  export { renderSchematic } from './renderer.js';
12
12
  export { schematicMarkedExtension } from './marked-extension.js';
13
- export { mathLabelGlyphLength, mathLabelText, parseMathLabel, renderMathLabelTspans, type MathLabelSegment, type MathLabelSegmentKind } from './math-label.js';
14
- export { MAX_SCHEMATIC_COMPONENTS, MAX_SCHEMATIC_CONNECTIONS, MAX_SCHEMATIC_SOURCE_CHARACTERS, MAX_SCHEMATIC_SVG_OUTPUT_BYTES, SCHEMATIC_LIMITS } from './limits.js';
15
- export { classicalGateHeight, componentObstacleRectangle, componentRectangle, componentTextAnchors, distributedCoordinate, enumerateComponentPorts, positionIcPin, PORT_HOTSPOT_RADIUS, resolvePortPoint, routeConnections, routeConnection, SCHEMATIC_BRIDGE_RADIUS, SCHEMATIC_OBSTACLE_CLEARANCE, validateDocumentGeometry, type RoutedConnection, type ComponentTextAnchors, type ComponentPort, type IcPinSide, type SchematicRectangle } from './layout.js';
16
- export { ANALOG_KINDS, COMPONENT_KINDS, CLASSICAL_GATE_KINDS, DIODE_TYPES, GROUND_STYLES, PASSIVE_KINDS, QUANTUM_GATE_KINDS, SCHEMATIC_SIGNAL_MARKERS, SEMANTIC_COLORS, TRANSISTOR_TYPES, SCHEMD_OUTPUT_MODES, SchematicSyntaxError, type AnalogKind, type CompileSchematicOptions, type ClassicalGateComponent, type ClassicalGateKind, type ComponentKind, type DiodeComponent, type DiodeType, type GroundComponent, type GroundStyle, type IcComponent, type IntegratedCircuitComponent, type IntegratedCircuitPins, type PassiveComponent, type PassiveKind, type PortComponent, type SemanticColor, type SchematicBounds, type SchematicComponent, type SchematicConnection, type SchematicColor, type SchematicDocument, type SchematicEndpoint, type SchematicFence, type SchematicSignalMarker, type SchematicMarkedOptions, type SchematicPoint, type SchemdOutputMode, type TransistorComponent, type TransistorType, type QuantumGateComponent, type QuantumGateKind } from './types.js';
13
+ export { mathLabelGlyphLength, mathLabelTextWidth, mathLabelText, parseMathLabel, renderMathLabelTspans, type MathLabelSegment, type MathLabelSegmentKind } from './math-label.js';
14
+ export { MAX_SCHEMATIC_COMPONENTS, MAX_SCHEMATIC_CONNECTIONS, MAX_SCHEMATIC_WIRE_CROSSINGS, MAX_SCHEMATIC_SOURCE_CHARACTERS, MAX_SCHEMATIC_SVG_OUTPUT_BYTES, SCHEMATIC_LIMITS } from './limits.js';
15
+ export { classicalGateHeight, componentObstacleRectangle, componentRectangle, componentTextAnchors, distributedCoordinate, enumerateComponentPorts, positionIcPin, PORT_HOTSPOT_RADIUS, resolvePortPoint, resolvePortGeometry, routeConnections, routeConnection, SCHEMATIC_BRIDGE_RADIUS, SCHEMATIC_OBSTACLE_CLEARANCE, validateDocumentGeometry, type RoutedConnection, type ComponentTextAnchors, type ComponentPort, type IcPinSide, type SchematicRectangle } from './layout.js';
16
+ export { ANALOG_KINDS, COMPONENT_KINDS, CLASSICAL_GATE_KINDS, DIODE_TYPES, GROUND_STYLES, PASSIVE_KINDS, QUANTUM_GATE_KINDS, SCHEMATIC_SIGNAL_MARKERS, SEMANTIC_COLORS, TRANSISTOR_TYPES, UML_COMPONENT_KINDS, UML_RELATION_KINDS, SCHEMD_OUTPUT_MODES, SchematicSyntaxError, type AnalogKind, type CompileSchematicOptions, type ClassicalGateComponent, type ClassicalGateKind, type ComponentKind, type DiodeComponent, type DiodeType, type GroundComponent, type GroundStyle, type IcComponent, type IntegratedCircuitComponent, type IntegratedCircuitPins, type PassiveComponent, type PassiveKind, type PortComponent, type SemanticColor, type SchematicBounds, type SchematicComponent, type SchematicConnection, type SchematicColor, type SchematicDocument, type SchematicEndpoint, type SchematicFence, type SchematicSignalMarker, type SchematicMarkedOptions, type SchematicPoint, type SchemdOutputMode, type TransistorComponent, type TransistorType, type QuantumGateComponent, type QuantumGateKind, type SchematicRelationKind, type UmlActorComponent, type UmlClassComponent, type UmlComponent, type UmlComponentKind, type UmlPseudostateComponent, type UmlRelationKind, type UmlSizedComponent, type UmlStateComponent } from './types.js';
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  export { parseSchematic, parseSchematicColor, parseSchematicFence } from './parser.js';
2
2
  export { renderSchematic } from './renderer.js';
3
3
  export { schematicMarkedExtension } from './marked-extension.js';
4
- export { mathLabelGlyphLength, mathLabelText, parseMathLabel, renderMathLabelTspans } from './math-label.js';
5
- export { MAX_SCHEMATIC_COMPONENTS, MAX_SCHEMATIC_CONNECTIONS, MAX_SCHEMATIC_SOURCE_CHARACTERS, MAX_SCHEMATIC_SVG_OUTPUT_BYTES, SCHEMATIC_LIMITS } from './limits.js';
6
- export { classicalGateHeight, componentObstacleRectangle, componentRectangle, componentTextAnchors, distributedCoordinate, enumerateComponentPorts, positionIcPin, PORT_HOTSPOT_RADIUS, resolvePortPoint, routeConnections, routeConnection, SCHEMATIC_BRIDGE_RADIUS, SCHEMATIC_OBSTACLE_CLEARANCE, validateDocumentGeometry } from './layout.js';
7
- export { ANALOG_KINDS, COMPONENT_KINDS, CLASSICAL_GATE_KINDS, DIODE_TYPES, GROUND_STYLES, PASSIVE_KINDS, QUANTUM_GATE_KINDS, SCHEMATIC_SIGNAL_MARKERS, SEMANTIC_COLORS, TRANSISTOR_TYPES, SCHEMD_OUTPUT_MODES, SchematicSyntaxError } from './types.js';
4
+ export { mathLabelGlyphLength, mathLabelTextWidth, mathLabelText, parseMathLabel, renderMathLabelTspans } from './math-label.js';
5
+ export { MAX_SCHEMATIC_COMPONENTS, MAX_SCHEMATIC_CONNECTIONS, MAX_SCHEMATIC_WIRE_CROSSINGS, MAX_SCHEMATIC_SOURCE_CHARACTERS, MAX_SCHEMATIC_SVG_OUTPUT_BYTES, SCHEMATIC_LIMITS } from './limits.js';
6
+ export { classicalGateHeight, componentObstacleRectangle, componentRectangle, componentTextAnchors, distributedCoordinate, enumerateComponentPorts, positionIcPin, PORT_HOTSPOT_RADIUS, resolvePortPoint, resolvePortGeometry, routeConnections, routeConnection, SCHEMATIC_BRIDGE_RADIUS, SCHEMATIC_OBSTACLE_CLEARANCE, validateDocumentGeometry } from './layout.js';
7
+ export { ANALOG_KINDS, COMPONENT_KINDS, CLASSICAL_GATE_KINDS, DIODE_TYPES, GROUND_STYLES, PASSIVE_KINDS, QUANTUM_GATE_KINDS, SCHEMATIC_SIGNAL_MARKERS, SEMANTIC_COLORS, TRANSISTOR_TYPES, UML_COMPONENT_KINDS, UML_RELATION_KINDS, SCHEMD_OUTPUT_MODES, SchematicSyntaxError } from './types.js';
package/dist/layout.d.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * @packageDocumentation
10
10
  */
11
- import { type ClassicalGateComponent, type IntegratedCircuitComponent, type SchematicComponent, type SchematicConnection, type SchematicDocument, type SchematicFence, type SchematicPoint } from './types.js';
11
+ import { type ClassicalGateComponent, type IntegratedCircuitComponent, type SchematicBounds, type SchematicComponent, type SchematicConnection, type SchematicDocument, type SchematicFence, type SchematicPoint } from './types.js';
12
12
  /** Axis-aligned rectangle expressed in absolute schematic coordinates. */
13
13
  export interface SchematicRectangle {
14
14
  /** Inclusive left extent. */
@@ -22,6 +22,8 @@ export interface SchematicRectangle {
22
22
  }
23
23
  /** Render-ready connection path and the points used for bounds validation. */
24
24
  export interface RoutedConnection {
25
+ /** Original routing strategy; crossing passes must never infer it from control points. */
26
+ readonly curve: SchematicConnection['curve'];
25
27
  /** Compact SVG path-data string. */
26
28
  d: string;
27
29
  /** At least two absolute points spanning endpoints, controls, corners, and bridge extrema. */
@@ -44,6 +46,8 @@ export interface ComponentPort {
44
46
  readonly id: string;
45
47
  /** Absolute center of the physical terminal. */
46
48
  readonly point: SchematicPoint;
49
+ /** Unit outward normal used to leave the owning component without crossing its body. */
50
+ readonly normal: SchematicPoint;
47
51
  }
48
52
  /** One edge of a polymorphic integrated-circuit body. */
49
53
  export type IcPinSide = 'left' | 'right' | 'top' | 'bottom';
@@ -88,6 +92,11 @@ export declare function positionIcPin(component: IntegratedCircuitComponent, sid
88
92
  * @throws {Error} When called with an endpoint the semantic parser did not validate.
89
93
  */
90
94
  export declare function resolvePortPoint(component: SchematicComponent, port: string): SchematicPoint;
95
+ /** Resolve a port coordinate together with the direction a route must initially travel. */
96
+ export declare function resolvePortGeometry(component: SchematicComponent, port: string): {
97
+ readonly point: SchematicPoint;
98
+ readonly normal: SchematicPoint;
99
+ };
91
100
  /**
92
101
  * Enumerate each physical terminal exactly once. Alias spellings deliberately resolve through
93
102
  * `resolvePortPoint` but do not create duplicate interactive targets.
@@ -110,9 +119,10 @@ export declare function componentObstacleRectangle(component: SchematicComponent
110
119
  *
111
120
  * @param connection - Validated directed connection.
112
121
  * @param components - Complete component map used for endpoint and obstacle lookup.
122
+ * @param bounds - Optional intrinsic routing bounds.
113
123
  * @returns SVG path data plus control/corner points for later bounds checks.
114
124
  */
115
- export declare function routeConnection(connection: SchematicConnection, components: ReadonlyMap<string, SchematicComponent>): RoutedConnection;
125
+ export declare function routeConnection(connection: SchematicConnection, components: ReadonlyMap<string, SchematicComponent>, bounds?: SchematicBounds): RoutedConnection;
116
126
  /**
117
127
  * Route connections in source order and bridge only the later trace at a true crossing.
118
128
  *
@@ -123,7 +133,7 @@ export declare function routeConnection(connection: SchematicConnection, compone
123
133
  * @param components - Complete component map.
124
134
  * @returns Routes in the same order, with crossings applied to later orthogonal traces.
125
135
  */
126
- export declare function routeConnections(connections: readonly SchematicConnection[], components: ReadonlyMap<string, SchematicComponent>): readonly RoutedConnection[];
136
+ export declare function routeConnections(connections: readonly SchematicConnection[], components: ReadonlyMap<string, SchematicComponent>, bounds?: SchematicBounds): readonly RoutedConnection[];
127
137
  /**
128
138
  * Calculate external designator and label fitting metrics.
129
139
  *
@@ -148,4 +158,4 @@ export declare function componentRectangle(component: SchematicComponent): Schem
148
158
  * @param fence - Intrinsic canvas contract.
149
159
  * @throws {SchematicSyntaxError} At the originating component or connection line.
150
160
  */
151
- export declare function validateDocumentGeometry(document: SchematicDocument, fence: SchematicFence): void;
161
+ export declare function validateDocumentGeometry(document: SchematicDocument, fence: SchematicFence, routedConnections?: readonly RoutedConnection[]): void;