planscript 1.2.0 → 2.0.0

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.
@@ -39,6 +39,13 @@ export interface DefaultsDeclaration extends ASTNode {
39
39
  doorWidth?: number;
40
40
  windowWidth?: number;
41
41
  }
42
+ export type CardinalDirection = 'north' | 'south' | 'east' | 'west';
43
+ export type Hemisphere = 'north' | 'south';
44
+ export interface SiteDeclaration extends ASTNode {
45
+ type: 'SiteDeclaration';
46
+ street: CardinalDirection;
47
+ hemisphere?: Hemisphere;
48
+ }
42
49
  export interface FootprintPolygon extends ASTNode {
43
50
  type: 'FootprintPolygon';
44
51
  points: Point[];
@@ -70,24 +77,49 @@ export interface RoomRectCenterSize extends ASTNode {
70
77
  }
71
78
  export interface RoomRectSizeOnly extends ASTNode {
72
79
  type: 'RoomRectSizeOnly';
73
- size: Point;
80
+ size: SizeValue;
81
+ }
82
+ export type DimensionValue = number | 'auto';
83
+ export interface SizeValue {
84
+ x: DimensionValue;
85
+ y: DimensionValue;
74
86
  }
75
- export type RoomGeometry = RoomPolygon | RoomRectDiagonal | RoomRectAtSize | RoomRectCenterSize | RoomRectSizeOnly;
87
+ export interface RoomFill extends ASTNode {
88
+ type: 'RoomFill';
89
+ between: [string, string];
90
+ width?: number;
91
+ height?: number;
92
+ }
93
+ export type RoomGeometry = RoomPolygon | RoomRectDiagonal | RoomRectAtSize | RoomRectCenterSize | RoomRectSizeOnly | RoomFill;
76
94
  export type RelativeDirection = 'north_of' | 'south_of' | 'east_of' | 'west_of';
77
95
  export type AlignmentType = 'top' | 'bottom' | 'left' | 'right' | 'center';
96
+ export type AlignEdge = 'top' | 'bottom' | 'left' | 'right';
78
97
  export interface AttachDirective extends ASTNode {
79
98
  type: 'AttachDirective';
80
99
  direction: RelativeDirection;
81
100
  target: string;
82
101
  }
83
- export interface AlignDirective extends ASTNode {
102
+ export interface AlignDirectiveSimple extends ASTNode {
84
103
  type: 'AlignDirective';
85
104
  alignment: AlignmentType;
86
105
  }
106
+ export interface AlignDirectiveExplicit extends ASTNode {
107
+ type: 'AlignDirective';
108
+ myEdge: AlignEdge;
109
+ withRoom: string;
110
+ withEdge: AlignEdge;
111
+ }
112
+ export type AlignDirective = AlignDirectiveSimple | AlignDirectiveExplicit;
87
113
  export interface GapDirective extends ASTNode {
88
114
  type: 'GapDirective';
89
115
  distance: number;
90
116
  }
117
+ export interface ExtendDirective extends ASTNode {
118
+ type: 'ExtendDirective';
119
+ axis: 'x' | 'y';
120
+ from: EdgeReference;
121
+ to: EdgeReference;
122
+ }
91
123
  export interface SpanX extends ASTNode {
92
124
  type: 'SpanX';
93
125
  from: EdgeReference;
@@ -115,6 +147,7 @@ export interface RoomDefinition extends ASTNode {
115
147
  attach?: AttachDirective;
116
148
  align?: AlignDirective;
117
149
  gap?: GapDirective;
150
+ extend?: ExtendDirective;
118
151
  }
119
152
  export type OpeningType = 'door' | 'window';
120
153
  export type SwingDirection = string;
@@ -127,7 +160,7 @@ export interface PositionPercentage {
127
160
  value: number;
128
161
  }
129
162
  export type Position = PositionAbsolute | PositionPercentage;
130
- export interface DoorOpening extends ASTNode {
163
+ export interface DoorOpeningBetween extends ASTNode {
131
164
  type: 'DoorOpening';
132
165
  name: string;
133
166
  between: [string, string];
@@ -136,6 +169,16 @@ export interface DoorOpening extends ASTNode {
136
169
  width: number;
137
170
  swing?: SwingDirection;
138
171
  }
172
+ export interface DoorOpeningEdge extends ASTNode {
173
+ type: 'DoorOpening';
174
+ name: string;
175
+ room: string;
176
+ edge: EdgeSide;
177
+ at: Position;
178
+ width: number;
179
+ swing?: SwingDirection;
180
+ }
181
+ export type DoorOpening = DoorOpeningBetween | DoorOpeningEdge;
139
182
  export type EdgeSide = 'north' | 'south' | 'east' | 'west';
140
183
  export interface WindowOpening extends ASTNode {
141
184
  type: 'WindowOpening';
@@ -173,12 +216,58 @@ export interface AssertionMinRoomArea extends ASTNode {
173
216
  export interface AssertionRoomsConnected extends ASTNode {
174
217
  type: 'AssertionRoomsConnected';
175
218
  }
176
- export type Assertion = AssertionInsideFootprint | AssertionNoOverlap | AssertionOpeningsOnWalls | AssertionMinRoomArea | AssertionRoomsConnected;
219
+ export type OrientationTarget = 'morning_sun' | 'afternoon_sun' | 'street' | CardinalDirection;
220
+ export interface AssertionOrientationHasWindow extends ASTNode {
221
+ type: 'AssertionOrientationHasWindow';
222
+ room: string;
223
+ target: OrientationTarget;
224
+ }
225
+ export interface AssertionOrientationNearStreet extends ASTNode {
226
+ type: 'AssertionOrientationNearStreet';
227
+ room: string;
228
+ }
229
+ export interface AssertionOrientationAwayFromStreet extends ASTNode {
230
+ type: 'AssertionOrientationAwayFromStreet';
231
+ room: string;
232
+ }
233
+ export interface AssertionOrientationGardenView extends ASTNode {
234
+ type: 'AssertionOrientationGardenView';
235
+ room: string;
236
+ }
237
+ export type OrientationAssertion = AssertionOrientationHasWindow | AssertionOrientationNearStreet | AssertionOrientationAwayFromStreet | AssertionOrientationGardenView;
238
+ export type Assertion = AssertionInsideFootprint | AssertionNoOverlap | AssertionOpeningsOnWalls | AssertionMinRoomArea | AssertionRoomsConnected | OrientationAssertion;
239
+ export interface ZoneDefinition extends ASTNode {
240
+ type: 'ZoneDefinition';
241
+ name: string;
242
+ label?: string;
243
+ rooms: RoomDefinition[];
244
+ attach?: AttachDirective;
245
+ align?: AlignDirective;
246
+ gap?: GapDirective;
247
+ }
248
+ export type CourtyardGeometry = CourtyardRect | CourtyardPolygon;
249
+ export interface CourtyardRect extends ASTNode {
250
+ type: 'CourtyardRect';
251
+ p1: Point;
252
+ p2: Point;
253
+ }
254
+ export interface CourtyardPolygon extends ASTNode {
255
+ type: 'CourtyardPolygon';
256
+ points: Point[];
257
+ }
258
+ export interface CourtyardDefinition extends ASTNode {
259
+ type: 'CourtyardDefinition';
260
+ name: string;
261
+ label?: string;
262
+ geometry: CourtyardGeometry;
263
+ }
177
264
  export interface PlanDefinition extends ASTNode {
178
265
  type: 'PlanDefinition';
179
266
  name: string;
180
267
  footprint: Footprint;
268
+ zones: ZoneDefinition[];
181
269
  rooms: RoomDefinition[];
270
+ courtyards: CourtyardDefinition[];
182
271
  openings: Opening[];
183
272
  wallOverrides: WallThicknessOverride[];
184
273
  assertions: Assertion[];
@@ -190,6 +279,7 @@ export interface Program extends ASTNode {
190
279
  axis?: AxisDeclaration;
191
280
  grid?: GridDeclaration;
192
281
  defaults?: DefaultsDeclaration;
282
+ site?: SiteDeclaration;
193
283
  plan: PlanDefinition;
194
284
  }
195
285
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ast/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ast/types.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { readFileSync, writeFileSync } from 'fs';
3
+ import { resolve } from 'path';
3
4
  import { compile } from './compiler.js';
4
5
  const args = process.argv.slice(2);
5
6
  if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
@@ -24,7 +25,28 @@ Examples:
24
25
  `);
25
26
  process.exit(0);
26
27
  }
28
+ /**
29
+ * Format error in a way that editors can parse for click-to-navigate.
30
+ * Standard format: file:line:column: error: message
31
+ */
32
+ function formatError(file, error) {
33
+ const parts = [];
34
+ // file:line:column (clickable in most editors/terminals)
35
+ if (error.location) {
36
+ parts.push(`${file}:${error.location.line}:${error.location.column}`);
37
+ }
38
+ else {
39
+ parts.push(file);
40
+ }
41
+ // error type with code
42
+ const errorType = error.code ? `error[${error.code}]` : 'error';
43
+ parts.push(errorType);
44
+ // message
45
+ parts.push(error.message);
46
+ return parts.join(': ');
47
+ }
27
48
  const inputFile = args[0];
49
+ const absoluteInputFile = resolve(inputFile);
28
50
  let svgOutput;
29
51
  let jsonOutput;
30
52
  let emitSVG = true;
@@ -62,12 +84,12 @@ try {
62
84
  jsonOptions: { pretty: true },
63
85
  });
64
86
  if (!result.success) {
65
- console.error('Compilation failed:');
87
+ console.error('');
66
88
  for (const error of result.errors) {
67
- const location = error.location ? ` at line ${error.location.line}:${error.location.column}` : '';
68
- const code = error.code ? ` [${error.code}]` : '';
69
- console.error(` ${error.phase}${code}${location}: ${error.message}`);
89
+ console.error(formatError(absoluteInputFile, error));
70
90
  }
91
+ console.error('');
92
+ console.error(`Compilation failed with ${result.errors.length} error(s).`);
71
93
  process.exit(1);
72
94
  }
73
95
  console.log('Compilation successful!');
@@ -90,10 +112,10 @@ try {
90
112
  }
91
113
  catch (e) {
92
114
  if (e instanceof Error) {
93
- console.error(`Error: ${e.message}`);
115
+ console.error(`${absoluteInputFile}: error: ${e.message}`);
94
116
  }
95
117
  else {
96
- console.error('Unknown error occurred');
118
+ console.error(`${absoluteInputFile}: error: Unknown error occurred`);
97
119
  }
98
120
  process.exit(1);
99
121
  }
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,9 @@ export interface SVGExportOptions {
13
13
  roomFillColor?: string;
14
14
  roomStrokeColor?: string;
15
15
  roomStrokeWidth?: number;
16
+ courtyardFillColor?: string;
17
+ courtyardStrokeColor?: string;
18
+ courtyardStrokeWidth?: number;
16
19
  doorColor?: string;
17
20
  windowColor?: string;
18
21
  footprintColor?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"svg.d.ts","sourceRoot":"","sources":["../../src/exporters/svg.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAwD,MAAM,sBAAsB,CAAC;AAM7G,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAu3BD,wBAAgB,SAAS,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAqCtF"}
1
+ {"version":3,"file":"svg.d.ts","sourceRoot":"","sources":["../../src/exporters/svg.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAA2E,MAAM,sBAAsB,CAAC;AAMhI,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAwkCD,wBAAgB,SAAS,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAwCtF"}
@@ -12,6 +12,9 @@ const defaultOptions = {
12
12
  roomFillColor: '#ecf0f1',
13
13
  roomStrokeColor: '#bdc3c7',
14
14
  roomStrokeWidth: 1,
15
+ courtyardFillColor: '#d5f5e3', // Light green for open spaces
16
+ courtyardStrokeColor: '#27ae60', // Darker green stroke
17
+ courtyardStrokeWidth: 2,
15
18
  doorColor: '#e74c3c',
16
19
  windowColor: '#3498db',
17
20
  footprintColor: '#7f8c8d',
@@ -87,6 +90,131 @@ function calculatePolygonCenter(points) {
87
90
  const y = points.reduce((sum, p) => sum + p.y, 0) / points.length;
88
91
  return { x, y };
89
92
  }
93
+ /**
94
+ * Test if a point is inside a polygon using ray casting algorithm.
95
+ */
96
+ function isPointInPolygon(point, polygon) {
97
+ const { x, y } = point;
98
+ let inside = false;
99
+ for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
100
+ const xi = polygon[i].x, yi = polygon[i].y;
101
+ const xj = polygon[j].x, yj = polygon[j].y;
102
+ if (((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi)) {
103
+ inside = !inside;
104
+ }
105
+ }
106
+ return inside;
107
+ }
108
+ /**
109
+ * Calculate the distance from a point to a line segment.
110
+ */
111
+ function pointToSegmentDistance(point, p1, p2) {
112
+ const dx = p2.x - p1.x;
113
+ const dy = p2.y - p1.y;
114
+ const lengthSquared = dx * dx + dy * dy;
115
+ if (lengthSquared === 0) {
116
+ // Segment is a point
117
+ return Math.sqrt((point.x - p1.x) ** 2 + (point.y - p1.y) ** 2);
118
+ }
119
+ // Project point onto line, clamped to segment
120
+ let t = ((point.x - p1.x) * dx + (point.y - p1.y) * dy) / lengthSquared;
121
+ t = Math.max(0, Math.min(1, t));
122
+ const projX = p1.x + t * dx;
123
+ const projY = p1.y + t * dy;
124
+ return Math.sqrt((point.x - projX) ** 2 + (point.y - projY) ** 2);
125
+ }
126
+ /**
127
+ * Calculate minimum distance from a point to the polygon boundary.
128
+ */
129
+ function pointToPolygonDistance(point, polygon) {
130
+ let minDist = Infinity;
131
+ for (let i = 0; i < polygon.length; i++) {
132
+ const p1 = polygon[i];
133
+ const p2 = polygon[(i + 1) % polygon.length];
134
+ const dist = pointToSegmentDistance(point, p1, p2);
135
+ minDist = Math.min(minDist, dist);
136
+ }
137
+ return minDist;
138
+ }
139
+ /**
140
+ * Find the visual center of a polygon using a "pole of inaccessibility" algorithm.
141
+ * This finds the point inside the polygon that is furthest from any edge.
142
+ * Uses an iterative grid-based approach for better accuracy.
143
+ */
144
+ function findVisualCenter(points) {
145
+ // Calculate bounding box
146
+ const xs = points.map(p => p.x);
147
+ const ys = points.map(p => p.y);
148
+ const minX = Math.min(...xs);
149
+ const maxX = Math.max(...xs);
150
+ const minY = Math.min(...ys);
151
+ const maxY = Math.max(...ys);
152
+ const width = maxX - minX;
153
+ const height = maxY - minY;
154
+ // Start with centroid as fallback
155
+ const centroid = calculatePolygonCenter(points);
156
+ // If centroid is inside, use iterative refinement
157
+ // Otherwise, find a point inside first
158
+ let bestPoint = centroid;
159
+ let bestDistance = isPointInPolygon(centroid, points)
160
+ ? pointToPolygonDistance(centroid, points)
161
+ : -Infinity;
162
+ // Initial grid search
163
+ const gridSize = 10;
164
+ const cellWidth = width / gridSize;
165
+ const cellHeight = height / gridSize;
166
+ for (let i = 0; i <= gridSize; i++) {
167
+ for (let j = 0; j <= gridSize; j++) {
168
+ const testPoint = {
169
+ x: minX + i * cellWidth,
170
+ y: minY + j * cellHeight
171
+ };
172
+ if (isPointInPolygon(testPoint, points)) {
173
+ const dist = pointToPolygonDistance(testPoint, points);
174
+ if (dist > bestDistance) {
175
+ bestDistance = dist;
176
+ bestPoint = testPoint;
177
+ }
178
+ }
179
+ }
180
+ }
181
+ // Refinement: search around best point with smaller grid
182
+ const refineRadius = Math.max(cellWidth, cellHeight);
183
+ const refineSteps = 5;
184
+ for (let iteration = 0; iteration < 3; iteration++) {
185
+ const searchRadius = refineRadius / Math.pow(2, iteration);
186
+ const step = searchRadius / refineSteps;
187
+ for (let dx = -refineSteps; dx <= refineSteps; dx++) {
188
+ for (let dy = -refineSteps; dy <= refineSteps; dy++) {
189
+ const testPoint = {
190
+ x: bestPoint.x + dx * step,
191
+ y: bestPoint.y + dy * step
192
+ };
193
+ if (isPointInPolygon(testPoint, points)) {
194
+ const dist = pointToPolygonDistance(testPoint, points);
195
+ if (dist > bestDistance) {
196
+ bestDistance = dist;
197
+ bestPoint = testPoint;
198
+ }
199
+ }
200
+ }
201
+ }
202
+ }
203
+ return bestPoint;
204
+ }
205
+ /**
206
+ * Get the best label position for a polygon.
207
+ * Uses centroid for convex polygons, visual center for concave ones.
208
+ */
209
+ function getLabelPosition(points) {
210
+ const centroid = calculatePolygonCenter(points);
211
+ // If centroid is inside the polygon, it's good enough for most cases
212
+ if (isPointInPolygon(centroid, points)) {
213
+ return centroid;
214
+ }
215
+ // For concave polygons where centroid is outside, find the visual center
216
+ return findVisualCenter(points);
217
+ }
90
218
  function calculatePolygonBounds(points) {
91
219
  const xs = points.map(p => p.x);
92
220
  const ys = points.map(p => p.y);
@@ -113,14 +241,26 @@ function generateRoomsSVG(rooms, t, opts) {
113
241
  }
114
242
  return elements.join('\n ');
115
243
  }
116
- function generateLabelsSVG(rooms, t, opts) {
244
+ function generateCourtyardsSVG(courtyards, t, opts) {
245
+ const elements = [];
246
+ for (const courtyard of courtyards) {
247
+ const points = transformPolygon(courtyard.polygon.points, t);
248
+ const path = pointsToPath(points);
249
+ // Courtyard fill with distinct styling
250
+ elements.push(`<path d="${path}" fill="${opts.courtyardFillColor}" stroke="${opts.courtyardStrokeColor}" ` +
251
+ `stroke-width="${opts.courtyardStrokeWidth}" stroke-dasharray="4,2" />`);
252
+ }
253
+ return elements.join('\n ');
254
+ }
255
+ function generateLabelsSVG(rooms, courtyards, t, opts) {
117
256
  if (!opts.showLabels)
118
257
  return '';
119
258
  const elements = [];
259
+ // Room labels
120
260
  for (const room of rooms) {
121
261
  if (!room.label)
122
262
  continue;
123
- const worldCenter = calculatePolygonCenter(room.polygon.points);
263
+ const worldCenter = getLabelPosition(room.polygon.points);
124
264
  const screenCenter = transformPoint(worldCenter, t);
125
265
  // Calculate room size in screen coordinates to adapt font size
126
266
  const worldBounds = calculatePolygonBounds(room.polygon.points);
@@ -149,6 +289,34 @@ function generateLabelsSVG(rooms, t, opts) {
149
289
  `text-anchor="middle" dominant-baseline="middle" font-family="Arial, sans-serif">` +
150
290
  `${escapeXml(label)}</text>`);
151
291
  }
292
+ // Courtyard labels
293
+ for (const courtyard of courtyards) {
294
+ if (!courtyard.label)
295
+ continue;
296
+ const worldCenter = getLabelPosition(courtyard.polygon.points);
297
+ const screenCenter = transformPoint(worldCenter, t);
298
+ // Calculate courtyard size in screen coordinates to adapt font size
299
+ const worldBounds = calculatePolygonBounds(courtyard.polygon.points);
300
+ const screenWidth = worldBounds.width * t.scale;
301
+ const screenHeight = worldBounds.height * t.scale;
302
+ const label = courtyard.label;
303
+ const baseFontSize = opts.labelFontSize;
304
+ const estimatedTextWidth = 0.6 * baseFontSize * label.length;
305
+ const maxTextWidth = screenWidth * 0.85;
306
+ const maxTextHeight = screenHeight * 0.4;
307
+ let fontSize = baseFontSize;
308
+ if (estimatedTextWidth > maxTextWidth) {
309
+ fontSize = Math.floor((maxTextWidth / label.length) / 0.6);
310
+ }
311
+ fontSize = Math.min(fontSize, maxTextHeight);
312
+ fontSize = Math.max(fontSize, 6);
313
+ fontSize = Math.min(fontSize, baseFontSize);
314
+ // Use courtyard stroke color for label to match the style
315
+ elements.push(`<text x="${screenCenter.x.toFixed(2)}" y="${screenCenter.y.toFixed(2)}" ` +
316
+ `font-size="${fontSize}" fill="${opts.courtyardStrokeColor}" ` +
317
+ `text-anchor="middle" dominant-baseline="middle" font-family="Arial, sans-serif" font-style="italic">` +
318
+ `${escapeXml(label)}</text>`);
319
+ }
152
320
  return elements.join('\n ');
153
321
  }
154
322
  function generateWallsSVG(walls, t, opts) {
@@ -667,6 +835,9 @@ export function exportSVG(geometry, options = {}) {
667
835
  <!-- Rooms -->
668
836
  ${generateRoomsSVG(geometry.rooms, transform, opts)}
669
837
 
838
+ <!-- Courtyards -->
839
+ ${generateCourtyardsSVG(geometry.courtyards, transform, opts)}
840
+
670
841
  <!-- Walls -->
671
842
  ${generateWallsSVG(geometry.walls, transform, opts)}
672
843
 
@@ -674,7 +845,7 @@ export function exportSVG(geometry, options = {}) {
674
845
  ${generateOpeningsSVG(geometry.openings, geometry.walls, transform, opts)}
675
846
 
676
847
  <!-- Labels -->
677
- ${generateLabelsSVG(geometry.rooms, transform, opts)}
848
+ ${generateLabelsSVG(geometry.rooms, geometry.courtyards, transform, opts)}
678
849
 
679
850
  <!-- Dimensions -->
680
851
  ${dimensionsSVG}