@mlightcad/mtext-parser 1.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.
- package/README.md +193 -0
- package/dist/example.d.ts +1 -0
- package/dist/example.js +125 -0
- package/dist/parser.d.ts +449 -0
- package/dist/parser.js +1036 -0
- package/dist/parser.test.d.ts +1 -0
- package/dist/parser.test.js +733 -0
- package/package.json +47 -0
package/dist/parser.d.ts
ADDED
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token types used in MText parsing
|
|
3
|
+
*/
|
|
4
|
+
export declare enum TokenType {
|
|
5
|
+
/** No token */
|
|
6
|
+
NONE = 0,
|
|
7
|
+
/** Word token with string data */
|
|
8
|
+
WORD = 1,
|
|
9
|
+
/** Stack token with [numerator, denominator, type] data */
|
|
10
|
+
STACK = 2,
|
|
11
|
+
/** Space token with no data */
|
|
12
|
+
SPACE = 3,
|
|
13
|
+
/** Non-breaking space token with no data */
|
|
14
|
+
NBSP = 4,
|
|
15
|
+
/** Tab token with no data */
|
|
16
|
+
TABULATOR = 5,
|
|
17
|
+
/** New paragraph token with no data */
|
|
18
|
+
NEW_PARAGRAPH = 6,
|
|
19
|
+
/** New column token with no data */
|
|
20
|
+
NEW_COLUMN = 7,
|
|
21
|
+
/** Wrap at dimension line token with no data */
|
|
22
|
+
WRAP_AT_DIMLINE = 8,
|
|
23
|
+
/** Properties changed token with string data (full command) */
|
|
24
|
+
PROPERTIES_CHANGED = 9
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Type for token data based on token type
|
|
28
|
+
*/
|
|
29
|
+
export type TokenData = {
|
|
30
|
+
[TokenType.NONE]: null;
|
|
31
|
+
[TokenType.WORD]: string;
|
|
32
|
+
[TokenType.STACK]: [string, string, string];
|
|
33
|
+
[TokenType.SPACE]: null;
|
|
34
|
+
[TokenType.NBSP]: null;
|
|
35
|
+
[TokenType.TABULATOR]: null;
|
|
36
|
+
[TokenType.NEW_PARAGRAPH]: null;
|
|
37
|
+
[TokenType.NEW_COLUMN]: null;
|
|
38
|
+
[TokenType.WRAP_AT_DIMLINE]: null;
|
|
39
|
+
[TokenType.PROPERTIES_CHANGED]: string;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Line alignment options for MText
|
|
43
|
+
*/
|
|
44
|
+
export declare enum MTextLineAlignment {
|
|
45
|
+
/** Align text to bottom */
|
|
46
|
+
BOTTOM = 0,
|
|
47
|
+
/** Align text to middle */
|
|
48
|
+
MIDDLE = 1,
|
|
49
|
+
/** Align text to top */
|
|
50
|
+
TOP = 2
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Paragraph alignment options for MText
|
|
54
|
+
*/
|
|
55
|
+
export declare enum MTextParagraphAlignment {
|
|
56
|
+
/** Default alignment */
|
|
57
|
+
DEFAULT = 0,
|
|
58
|
+
/** Left alignment */
|
|
59
|
+
LEFT = 1,
|
|
60
|
+
/** Right alignment */
|
|
61
|
+
RIGHT = 2,
|
|
62
|
+
/** Center alignment */
|
|
63
|
+
CENTER = 3,
|
|
64
|
+
/** Justified alignment */
|
|
65
|
+
JUSTIFIED = 4,
|
|
66
|
+
/** Distributed alignment */
|
|
67
|
+
DISTRIBUTED = 5
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Text stroke options for MText
|
|
71
|
+
*/
|
|
72
|
+
export declare enum MTextStroke {
|
|
73
|
+
/** No stroke */
|
|
74
|
+
NONE = 0,
|
|
75
|
+
/** Underline stroke */
|
|
76
|
+
UNDERLINE = 1,
|
|
77
|
+
/** Overline stroke */
|
|
78
|
+
OVERLINE = 2,
|
|
79
|
+
/** Strike-through stroke */
|
|
80
|
+
STRIKE_THROUGH = 4
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* RGB color tuple
|
|
84
|
+
*/
|
|
85
|
+
export type RGB = [number, number, number];
|
|
86
|
+
/**
|
|
87
|
+
* Font face properties
|
|
88
|
+
*/
|
|
89
|
+
export interface FontFace {
|
|
90
|
+
/** Font family name */
|
|
91
|
+
family: string;
|
|
92
|
+
/** Font style (e.g., 'Regular', 'Italic') */
|
|
93
|
+
style: string;
|
|
94
|
+
/** Font weight (e.g., 400 for normal, 700 for bold) */
|
|
95
|
+
weight: number;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Font measurement properties
|
|
99
|
+
*/
|
|
100
|
+
export interface FontMeasurements {
|
|
101
|
+
/** Height of capital letters */
|
|
102
|
+
cap_height: number;
|
|
103
|
+
/** Baseline position */
|
|
104
|
+
baseline: number;
|
|
105
|
+
/** Bottom position */
|
|
106
|
+
bottom: number;
|
|
107
|
+
/** Top position */
|
|
108
|
+
top: number;
|
|
109
|
+
/** Total height of the font */
|
|
110
|
+
total_height: number;
|
|
111
|
+
/**
|
|
112
|
+
* Scale measurements by a factor
|
|
113
|
+
* @param factor - The scaling factor
|
|
114
|
+
* @returns New scaled measurements
|
|
115
|
+
*/
|
|
116
|
+
scale(factor: number): FontMeasurements;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Abstract font interface
|
|
120
|
+
*/
|
|
121
|
+
export interface AbstractFont {
|
|
122
|
+
/**
|
|
123
|
+
* Calculate text width
|
|
124
|
+
* @param text - The text to measure
|
|
125
|
+
* @returns Width of the text
|
|
126
|
+
*/
|
|
127
|
+
text_width(text: string): number;
|
|
128
|
+
/**
|
|
129
|
+
* Get width of a space character
|
|
130
|
+
* @returns Width of a space
|
|
131
|
+
*/
|
|
132
|
+
space_width(): number;
|
|
133
|
+
/** Font measurements */
|
|
134
|
+
measurements: FontMeasurements;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Paragraph properties
|
|
138
|
+
*/
|
|
139
|
+
export interface ParagraphProperties {
|
|
140
|
+
/** Indentation value */
|
|
141
|
+
indent: number;
|
|
142
|
+
/** Left margin value */
|
|
143
|
+
left: number;
|
|
144
|
+
/** Right margin value */
|
|
145
|
+
right: number;
|
|
146
|
+
/** Paragraph alignment */
|
|
147
|
+
align: MTextParagraphAlignment;
|
|
148
|
+
/** Tab stop positions and types */
|
|
149
|
+
tab_stops: (number | string)[];
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Convert RGB tuple to integer color value
|
|
153
|
+
* @param rgb - RGB color tuple
|
|
154
|
+
* @returns Integer color value
|
|
155
|
+
*/
|
|
156
|
+
export declare function rgb2int(rgb: RGB): number;
|
|
157
|
+
/**
|
|
158
|
+
* Convert integer color value to RGB tuple
|
|
159
|
+
* @param value - Integer color value
|
|
160
|
+
* @returns RGB color tuple
|
|
161
|
+
*/
|
|
162
|
+
export declare function int2rgb(value: number): RGB;
|
|
163
|
+
/**
|
|
164
|
+
* DXF stores some special characters using caret notation. This function
|
|
165
|
+
* decodes this notation to normalize the representation of special characters
|
|
166
|
+
* in the string.
|
|
167
|
+
* see: https://en.wikipedia.org/wiki/Caret_notation
|
|
168
|
+
* @param text - Text to decode
|
|
169
|
+
* @returns Decoded text
|
|
170
|
+
*/
|
|
171
|
+
export declare function caretDecode(text: string): string;
|
|
172
|
+
/**
|
|
173
|
+
* Escape DXF line endings
|
|
174
|
+
* @param text - Text to escape
|
|
175
|
+
* @returns Escaped text
|
|
176
|
+
*/
|
|
177
|
+
export declare function escapeDxfLineEndings(text: string): string;
|
|
178
|
+
/**
|
|
179
|
+
* Check if text contains inline formatting codes
|
|
180
|
+
* @param text - Text to check
|
|
181
|
+
* @returns True if text contains formatting codes
|
|
182
|
+
*/
|
|
183
|
+
export declare function hasInlineFormattingCodes(text: string): boolean;
|
|
184
|
+
/**
|
|
185
|
+
* Main parser class for MText content
|
|
186
|
+
*/
|
|
187
|
+
export declare class MTextParser {
|
|
188
|
+
private scanner;
|
|
189
|
+
private ctx;
|
|
190
|
+
private ctxStack;
|
|
191
|
+
private continueStroke;
|
|
192
|
+
private yieldPropertyCommands;
|
|
193
|
+
/**
|
|
194
|
+
* Creates a new MTextParser instance
|
|
195
|
+
* @param content - The MText content to parse
|
|
196
|
+
* @param ctx - Optional initial MText context
|
|
197
|
+
* @param yieldPropertyCommands - Whether to yield property change commands
|
|
198
|
+
*/
|
|
199
|
+
constructor(content: string, ctx?: MTextContext, yieldPropertyCommands?: boolean);
|
|
200
|
+
/**
|
|
201
|
+
* Push current context onto the stack
|
|
202
|
+
*/
|
|
203
|
+
private pushCtx;
|
|
204
|
+
/**
|
|
205
|
+
* Pop context from the stack
|
|
206
|
+
*/
|
|
207
|
+
private popCtx;
|
|
208
|
+
/**
|
|
209
|
+
* Parse stacking expression (numerator/denominator)
|
|
210
|
+
* @returns Tuple of [TokenType.STACK, [numerator, denominator, type]]
|
|
211
|
+
*/
|
|
212
|
+
private parseStacking;
|
|
213
|
+
/**
|
|
214
|
+
* Parse MText properties
|
|
215
|
+
* @param cmd - The property command to parse
|
|
216
|
+
*/
|
|
217
|
+
private parseProperties;
|
|
218
|
+
/**
|
|
219
|
+
* Parse alignment property
|
|
220
|
+
* @param ctx - The context to update
|
|
221
|
+
*/
|
|
222
|
+
private parseAlign;
|
|
223
|
+
/**
|
|
224
|
+
* Parse height property
|
|
225
|
+
* @param ctx - The context to update
|
|
226
|
+
*/
|
|
227
|
+
private parseHeight;
|
|
228
|
+
/**
|
|
229
|
+
* Parse width property
|
|
230
|
+
* @param ctx - The context to update
|
|
231
|
+
*/
|
|
232
|
+
private parseWidth;
|
|
233
|
+
/**
|
|
234
|
+
* Parse character tracking property
|
|
235
|
+
* @param ctx - The context to update
|
|
236
|
+
*/
|
|
237
|
+
private parseCharTracking;
|
|
238
|
+
/**
|
|
239
|
+
* Parse float value or factor
|
|
240
|
+
* @param value - Current value to apply factor to
|
|
241
|
+
* @returns New value
|
|
242
|
+
*/
|
|
243
|
+
private parseFloatValueOrFactor;
|
|
244
|
+
/**
|
|
245
|
+
* Parse oblique angle property
|
|
246
|
+
* @param ctx - The context to update
|
|
247
|
+
*/
|
|
248
|
+
private parseOblique;
|
|
249
|
+
/**
|
|
250
|
+
* Parse ACI color property
|
|
251
|
+
* @param ctx - The context to update
|
|
252
|
+
*/
|
|
253
|
+
private parseAciColor;
|
|
254
|
+
/**
|
|
255
|
+
* Parse RGB color property
|
|
256
|
+
* @param ctx - The context to update
|
|
257
|
+
*/
|
|
258
|
+
private parseRgbColor;
|
|
259
|
+
/**
|
|
260
|
+
* Extract float expression from scanner
|
|
261
|
+
* @param relative - Whether to allow relative values (ending in 'x')
|
|
262
|
+
* @returns Extracted expression
|
|
263
|
+
*/
|
|
264
|
+
private extractFloatExpression;
|
|
265
|
+
/**
|
|
266
|
+
* Extract integer expression from scanner
|
|
267
|
+
* @returns Extracted expression
|
|
268
|
+
*/
|
|
269
|
+
private extractIntExpression;
|
|
270
|
+
/**
|
|
271
|
+
* Extract expression until semicolon or end
|
|
272
|
+
* @param escape - Whether to handle escaped semicolons
|
|
273
|
+
* @returns Extracted expression
|
|
274
|
+
*/
|
|
275
|
+
private extractExpression;
|
|
276
|
+
/**
|
|
277
|
+
* Parse font properties
|
|
278
|
+
* @param ctx - The context to update
|
|
279
|
+
*/
|
|
280
|
+
private parseFontProperties;
|
|
281
|
+
/**
|
|
282
|
+
* Parse paragraph properties from the MText content
|
|
283
|
+
* Handles properties like indentation, alignment, and tab stops
|
|
284
|
+
* @param ctx - The context to update
|
|
285
|
+
*/
|
|
286
|
+
private parseParagraphProperties;
|
|
287
|
+
/**
|
|
288
|
+
* Consume optional terminator (semicolon)
|
|
289
|
+
*/
|
|
290
|
+
private consumeOptionalTerminator;
|
|
291
|
+
/**
|
|
292
|
+
* Parse MText content into tokens
|
|
293
|
+
* @yields MTextToken objects
|
|
294
|
+
*/
|
|
295
|
+
parse(): Generator<MTextToken>;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Text scanner for parsing MText content
|
|
299
|
+
*/
|
|
300
|
+
export declare class TextScanner {
|
|
301
|
+
private text;
|
|
302
|
+
private textLen;
|
|
303
|
+
private _index;
|
|
304
|
+
/**
|
|
305
|
+
* Create a new text scanner
|
|
306
|
+
* @param text - The text to scan
|
|
307
|
+
*/
|
|
308
|
+
constructor(text: string);
|
|
309
|
+
/**
|
|
310
|
+
* Get the current index in the text
|
|
311
|
+
*/
|
|
312
|
+
get currentIndex(): number;
|
|
313
|
+
/**
|
|
314
|
+
* Check if the scanner has reached the end of the text
|
|
315
|
+
*/
|
|
316
|
+
get isEmpty(): boolean;
|
|
317
|
+
/**
|
|
318
|
+
* Check if there is more text to scan
|
|
319
|
+
*/
|
|
320
|
+
get hasData(): boolean;
|
|
321
|
+
/**
|
|
322
|
+
* Get the next character and advance the index
|
|
323
|
+
* @returns The next character, or empty string if at end
|
|
324
|
+
*/
|
|
325
|
+
get(): string;
|
|
326
|
+
/**
|
|
327
|
+
* Advance the index by the specified count
|
|
328
|
+
* @param count - Number of characters to advance
|
|
329
|
+
*/
|
|
330
|
+
consume(count?: number): void;
|
|
331
|
+
/**
|
|
332
|
+
* Look at a character without advancing the index
|
|
333
|
+
* @param offset - Offset from current position
|
|
334
|
+
* @returns The character at the offset position, or empty string if out of bounds
|
|
335
|
+
*/
|
|
336
|
+
peek(offset?: number): string;
|
|
337
|
+
/**
|
|
338
|
+
* Find the next occurrence of a character
|
|
339
|
+
* @param char - The character to find
|
|
340
|
+
* @param escape - Whether to handle escaped characters
|
|
341
|
+
* @returns Index of the character, or -1 if not found
|
|
342
|
+
*/
|
|
343
|
+
find(char: string, escape?: boolean): number;
|
|
344
|
+
/**
|
|
345
|
+
* Get the remaining text from the current position
|
|
346
|
+
*/
|
|
347
|
+
get tail(): string;
|
|
348
|
+
/**
|
|
349
|
+
* Check if the next character is a space
|
|
350
|
+
*/
|
|
351
|
+
isNextSpace(): boolean;
|
|
352
|
+
/**
|
|
353
|
+
* Consume spaces until a non-space character is found
|
|
354
|
+
* @returns Number of spaces consumed
|
|
355
|
+
*/
|
|
356
|
+
consumeSpaces(): number;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* MText context class for managing text formatting state
|
|
360
|
+
*/
|
|
361
|
+
export declare class MTextContext {
|
|
362
|
+
private _stroke;
|
|
363
|
+
/** Whether to continue stroke formatting */
|
|
364
|
+
continueStroke: boolean;
|
|
365
|
+
private _aci;
|
|
366
|
+
/** RGB color value, or null if using ACI */
|
|
367
|
+
rgb: RGB | null;
|
|
368
|
+
/** Line alignment */
|
|
369
|
+
align: MTextLineAlignment;
|
|
370
|
+
/** Font face properties */
|
|
371
|
+
fontFace: FontFace;
|
|
372
|
+
/** Capital letter height */
|
|
373
|
+
capHeight: number;
|
|
374
|
+
/** Character width factor */
|
|
375
|
+
widthFactor: number;
|
|
376
|
+
/** Character tracking factor */
|
|
377
|
+
charTrackingFactor: number;
|
|
378
|
+
/** Oblique angle */
|
|
379
|
+
oblique: number;
|
|
380
|
+
/** Paragraph properties */
|
|
381
|
+
paragraph: ParagraphProperties;
|
|
382
|
+
/**
|
|
383
|
+
* Get the ACI color value
|
|
384
|
+
*/
|
|
385
|
+
get aci(): number;
|
|
386
|
+
/**
|
|
387
|
+
* Set the ACI color value
|
|
388
|
+
* @param value - ACI color value (0-256)
|
|
389
|
+
* @throws Error if value is out of range
|
|
390
|
+
*/
|
|
391
|
+
set aci(value: number);
|
|
392
|
+
/**
|
|
393
|
+
* Get whether text is underlined
|
|
394
|
+
*/
|
|
395
|
+
get underline(): boolean;
|
|
396
|
+
/**
|
|
397
|
+
* Set whether text is underlined
|
|
398
|
+
* @param value - Whether to underline
|
|
399
|
+
*/
|
|
400
|
+
set underline(value: boolean);
|
|
401
|
+
/**
|
|
402
|
+
* Get whether text has strike-through
|
|
403
|
+
*/
|
|
404
|
+
get strikeThrough(): boolean;
|
|
405
|
+
/**
|
|
406
|
+
* Set whether text has strike-through
|
|
407
|
+
* @param value - Whether to strike through
|
|
408
|
+
*/
|
|
409
|
+
set strikeThrough(value: boolean);
|
|
410
|
+
/**
|
|
411
|
+
* Get whether text has overline
|
|
412
|
+
*/
|
|
413
|
+
get overline(): boolean;
|
|
414
|
+
/**
|
|
415
|
+
* Set whether text has overline
|
|
416
|
+
* @param value - Whether to overline
|
|
417
|
+
*/
|
|
418
|
+
set overline(value: boolean);
|
|
419
|
+
/**
|
|
420
|
+
* Check if any stroke formatting is active
|
|
421
|
+
*/
|
|
422
|
+
get hasAnyStroke(): boolean;
|
|
423
|
+
/**
|
|
424
|
+
* Set the state of a stroke type
|
|
425
|
+
* @param stroke - The stroke type to set
|
|
426
|
+
* @param state - Whether to enable or disable the stroke
|
|
427
|
+
*/
|
|
428
|
+
private _setStrokeState;
|
|
429
|
+
/**
|
|
430
|
+
* Create a copy of this context
|
|
431
|
+
* @returns A new context with the same properties
|
|
432
|
+
*/
|
|
433
|
+
copy(): MTextContext;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Token class for MText parsing
|
|
437
|
+
*/
|
|
438
|
+
export declare class MTextToken {
|
|
439
|
+
type: TokenType;
|
|
440
|
+
ctx: MTextContext;
|
|
441
|
+
data: TokenData[TokenType];
|
|
442
|
+
/**
|
|
443
|
+
* Create a new MText token
|
|
444
|
+
* @param type - The token type
|
|
445
|
+
* @param ctx - The text context at this token
|
|
446
|
+
* @param data - Optional token data
|
|
447
|
+
*/
|
|
448
|
+
constructor(type: TokenType, ctx: MTextContext, data: TokenData[TokenType]);
|
|
449
|
+
}
|