tsdraft 0.3.0 → 0.4.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/CHANGELOG.md +39 -16
- package/README.md +23 -5
- package/dist/callsite.d.ts +47 -0
- package/dist/callsite.js +82 -0
- package/dist/drawing.d.ts +37 -11
- package/dist/drawing.js +205 -101
- package/dist/index.d.ts +4 -1
- package/dist/index.js +2 -0
- package/dist/json.d.ts +21 -0
- package/dist/json.js +244 -0
- package/dist/layers.d.ts +1 -1
- package/dist/layers.js +2 -3
- package/dist/lint.d.ts +17 -5
- package/dist/lint.js +37 -7
- package/dist/paper.d.ts +33 -0
- package/dist/paper.js +58 -0
- package/dist/rules.d.ts +59 -3
- package/dist/rules.js +79 -3
- package/dist/svg.d.ts +2 -1
- package/dist/svg.js +5 -3
- package/package.json +1 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,44 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
- `fromPaper(length, "in" | "mm", { ratio, units })` turns a length on paper
|
|
6
|
+
into drawing units, to size text, symbols and dashes by how large they plot:
|
|
7
|
+
`fromPaper(3 / 32, "in", { ratio: 96, units: "ft" })` is 0.75. A wrong unit,
|
|
8
|
+
and a length or ratio of 0 or less, are compile errors as literals and thrown
|
|
9
|
+
errors otherwise. A result that would be written as 0, or is 1e100 or more,
|
|
10
|
+
throws.
|
|
11
|
+
- `examples/site-plan.ts` is now the example sheet: a permit-style site plan for
|
|
12
|
+
an ARCH D sheet at 1" = 10', with property lines, setbacks, a building
|
|
13
|
+
footprint, dimensions, labels, site data, notes and a legend. Every text
|
|
14
|
+
height and annotation offset comes from `fromPaper`. Its default export is the drawing.
|
|
15
|
+
- Breaking: a `Drawing` has `format: 0`, its format version, which is separate
|
|
16
|
+
from `dxf`. The builder sets it. A drawing written by hand needs it, and
|
|
17
|
+
`lint` reports one without it under the new rule `format`. Format 0 carries
|
|
18
|
+
no promise of stability.
|
|
19
|
+
- Breaking: `LintRule` gained `format`, `id` and `duplicate-id`. Code that
|
|
20
|
+
switches over every rule, or uses `Record<LintRule, …>`, needs the three.
|
|
21
|
+
- `toJSON(drawing)` writes a drawing as canonical JSON: the same drawing gives
|
|
22
|
+
the same string, whatever order its keys were set in.
|
|
23
|
+
- `fromJSON(json)` reads a drawing from a JSON string or a parsed value. It
|
|
24
|
+
refuses a format version, a field or an entity kind it does not know, naming
|
|
25
|
+
each, then runs `lint`, and throws a `DrawingError`.
|
|
26
|
+
- Entities take an `id` in their options: 1 to 64 letters, digits, `.`, `-` and
|
|
27
|
+
`_`. A malformed id and a second entity with the same id are builder errors
|
|
28
|
+
and `lint` errors, under the new rules `id` and `duplicate-id`. `toSVG` writes
|
|
29
|
+
the id as `data-id`.
|
|
30
|
+
- A `Diagnostic` about an entity carries its `id`, and `call`, the file, line
|
|
31
|
+
and column of the call that drew it, when the drawing was built with
|
|
32
|
+
`createDrawing({ recordCalls: true })`. Setting
|
|
33
|
+
`globalThis.TSDRAFT_RECORD_CALLS = true` before a drawing's code runs turns
|
|
34
|
+
recording on for every builder that does not set the option, which is how a
|
|
35
|
+
tool that runs drawing files asks for it.
|
|
36
|
+
- The builder's `layer`, `linetype` and entity methods now throw a
|
|
37
|
+
`DrawingError` with the same message as before. Its diagnostic has the rule,
|
|
38
|
+
the `id` and the `call` that broke it.
|
|
39
|
+
- [docs/format.md](docs/format.md) describes all of the above.
|
|
4
40
|
|
|
5
|
-
|
|
41
|
+
## 0.3.0
|
|
6
42
|
|
|
7
43
|
- Breaking: `createDrawing()` now targets DXF R2018. Pass `{ dxf: "R12" }` for
|
|
8
44
|
R12, which gets no new features.
|
|
@@ -52,13 +88,10 @@ Every rule below was found by opening tsdraft's output in AutoCAD 2025.
|
|
|
52
88
|
|
|
53
89
|
## 0.2.2
|
|
54
90
|
|
|
55
|
-
Found by opening tsdraft's output in AutoCAD 2025.
|
|
56
|
-
|
|
57
91
|
- Fixed: AutoCAD keeps two layers such as `straße` and `STRASSE` apart, but its
|
|
58
92
|
`AUDIT` reports them as a duplicate name. `lint` now reports the second layer
|
|
59
93
|
as a duplicate, and the builder throws at the `layer()` call. It does so for
|
|
60
|
-
|
|
61
|
-
names:
|
|
94
|
+
these kinds of pair, in either letter case and inside longer names:
|
|
62
95
|
- a letter and the letters it stands for, such as `ß` and `ss`, `æ` and `ae`,
|
|
63
96
|
`œ` and `oe`, `ij` and `ij`, `fi` and `fi`, `dž` and `dž`, and `þ` and `th`;
|
|
64
97
|
- a composed character and its decomposed form, such as `é`;
|
|
@@ -71,13 +104,9 @@ Found by opening tsdraft's output in AutoCAD 2025.
|
|
|
71
104
|
- When an entity names its layer by the other spelling of such a pair, the
|
|
72
105
|
undefined-layer error now says which declared layer AutoCAD does not take it
|
|
73
106
|
for. AutoCAD adds a layer for the entity, and `AUDIT` reports a duplicate name.
|
|
74
|
-
- `pnpm test:cad` checks each kind of pair against AutoCAD, and 600 longer names
|
|
75
|
-
beside respellings of themselves.
|
|
76
107
|
|
|
77
108
|
## 0.2.1
|
|
78
109
|
|
|
79
|
-
Every fix below was found by opening tsdraft's output in AutoCAD 2025.
|
|
80
|
-
|
|
81
110
|
- Fixed: text holding `\U+XXXX` or `\M+NXXXX` came out in AutoCAD as the
|
|
82
111
|
character those escapes stand for, so `\U+00B0` became a degree sign and
|
|
83
112
|
`\U+000A` put a line feed inside a single-line text. Both DXF versions now
|
|
@@ -131,16 +160,11 @@ Every fix below was found by opening tsdraft's output in AutoCAD 2025.
|
|
|
131
160
|
and about a line, polyline or arc that loses its length to rounding.
|
|
132
161
|
- `lint` warns about text that contains `%%`, which AutoCAD stores as written
|
|
133
162
|
but draws as a control code: `%%d` is drawn as a degree sign.
|
|
134
|
-
- `pnpm test:cad` covers each fix above, and checks every character `lint`
|
|
135
|
-
accepts in text and in layer names, and each form of number the writers
|
|
136
|
-
print, against AutoCAD.
|
|
137
163
|
|
|
138
164
|
## 0.2.0
|
|
139
165
|
|
|
140
166
|
0.1.1 was never published, so its changes ship here too.
|
|
141
167
|
|
|
142
|
-
Every fix below comes from opening tsdraft's output in AutoCAD 2025.
|
|
143
|
-
|
|
144
168
|
- `createDrawing({ dxf: "R2018" })` targets AC1032, the DXF version AutoCAD has
|
|
145
169
|
used since 2018. It writes handles, owner links, the standard tables, model
|
|
146
170
|
and paper space blocks, plot styles and `$INSUNITS`. R12 stays the default.
|
|
@@ -169,7 +193,6 @@ Every fix below comes from opening tsdraft's output in AutoCAD 2025.
|
|
|
169
193
|
- Unknown units, and rectangle sizes of 0 or less, are rejected.
|
|
170
194
|
- Breaking: a `Drawing` now has a required `dxf` field, and R12 layer names
|
|
171
195
|
AutoCAD rejects now throw (see above).
|
|
172
|
-
- `pnpm test:cad` runs the output through AutoCAD over ssh.
|
|
173
196
|
- Published from GitHub Actions through npm trusted publishing, with a
|
|
174
197
|
provenance attestation linking the package to its source commit.
|
|
175
198
|
- `tsdraft/package.json` can be imported or resolved.
|
package/README.md
CHANGED
|
@@ -80,6 +80,23 @@ are AutoCAD's own definitions; `d.linetype({ name, pattern })` defines another,
|
|
|
80
80
|
with dashes as positive lengths, gaps as negative ones and dots as 0. A
|
|
81
81
|
lineweight is in millimetres.
|
|
82
82
|
|
|
83
|
+
Text, symbols and dashes are sized by how large they plot. `fromPaper` turns a
|
|
84
|
+
length on paper into drawing units for one scale, given as a plain ratio:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
import { fromPaper } from "tsdraft";
|
|
88
|
+
|
|
89
|
+
const view = { ratio: 120, units: "ft" } as const; // 1" = 10'
|
|
90
|
+
const note = fromPaper(3 / 32, "in", view); // 0.9375 ft
|
|
91
|
+
d.text([0, 0], "PROPERTY LINE", { height: note });
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
A paper unit other than `"in"` or `"mm"`, and a length or a ratio of 0 or less,
|
|
95
|
+
are compile errors as literals and thrown errors otherwise. `fromPaper` also
|
|
96
|
+
throws when the result would be written as 0 or is 1e100 or more.
|
|
97
|
+
[`examples/site-plan.ts`](examples/site-plan.ts) is a whole sheet sized this
|
|
98
|
+
way, and the file to copy to start a drawing.
|
|
99
|
+
|
|
83
100
|
## Status
|
|
84
101
|
|
|
85
102
|
tsdraft is at an early stage. It draws layers, lines, polylines, rectangles,
|
|
@@ -89,8 +106,8 @@ hatches, blocks or paper space layouts. It writes DXF, not DWG. The drawing at
|
|
|
89
106
|
the top builds its dimensions, leaders and stipple from lines and text, so in
|
|
90
107
|
CAD they are plain lines and text, not dimension or hatch objects.
|
|
91
108
|
|
|
92
|
-
The
|
|
93
|
-
|
|
109
|
+
The rules tsdraft checks are AutoCAD's. Other CAD programs may hold a drawing to
|
|
110
|
+
other rules.
|
|
94
111
|
|
|
95
112
|
## Install
|
|
96
113
|
|
|
@@ -152,6 +169,8 @@ lint(drawing, { version: "R12" }); // check a drawing against another version
|
|
|
152
169
|
## Reference
|
|
153
170
|
|
|
154
171
|
- [Rules](docs/rules.md) lists what `lint` refuses and what it warns about.
|
|
172
|
+
- [The Drawing format](docs/format.md) covers format 0, entity ids, `toJSON`
|
|
173
|
+
and `fromJSON`, and what a diagnostic carries.
|
|
155
174
|
- [Layer names](docs/layer-names.md) explains how AutoCAD compares layer and
|
|
156
175
|
linetype names, and lists the pairs `AUDIT` calls duplicates and the
|
|
157
176
|
characters it refuses.
|
|
@@ -170,9 +189,8 @@ pnpm example # writes both examples to examples/out/ as DXF and SVG
|
|
|
170
189
|
pnpm readme:drawing # redraws the pictures in docs/assets/ from the examples
|
|
171
190
|
```
|
|
172
191
|
|
|
173
|
-
[docs/development.md](docs/development.md) covers
|
|
174
|
-
|
|
175
|
-
releasing.
|
|
192
|
+
[docs/development.md](docs/development.md) covers the package smoke test, the
|
|
193
|
+
TypeScript compilers and releasing.
|
|
176
194
|
|
|
177
195
|
## Contributing
|
|
178
196
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** A place in a source file, as the JavaScript engine names it in a stack. */
|
|
2
|
+
export interface CallSite {
|
|
3
|
+
/** A `file://` URL for an ES module in Node, a path for CommonJS, and a URL in a browser. */
|
|
4
|
+
readonly file: string;
|
|
5
|
+
/** Counted from 1. */
|
|
6
|
+
readonly line: number;
|
|
7
|
+
/** Counted from 1. */
|
|
8
|
+
readonly column: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A stack that the engine has captured and formats when `stack` is first read. `whole` is true
|
|
12
|
+
* for a stack that starts inside tsdraft, and false for one cut down to the caller's frame.
|
|
13
|
+
*/
|
|
14
|
+
export interface HeldCall {
|
|
15
|
+
readonly stack?: unknown;
|
|
16
|
+
readonly whole: boolean;
|
|
17
|
+
}
|
|
18
|
+
type Method = (...args: never[]) => unknown;
|
|
19
|
+
/**
|
|
20
|
+
* Captures the call of the builder method `method` that is running now, to be read later, or
|
|
21
|
+
* returns undefined where the engine gives no stack. It must be called from the builder's file.
|
|
22
|
+
*
|
|
23
|
+
* With `Error.captureStackTrace` the engine leaves out every frame down to `method`, so only the
|
|
24
|
+
* caller's frame is captured. Without it, the whole stack of a new error is kept.
|
|
25
|
+
*/
|
|
26
|
+
export declare function holdCall(method: Method): HeldCall | undefined;
|
|
27
|
+
/** The location a held call names, or undefined when its stack has none. */
|
|
28
|
+
export declare function readCall(held: HeldCall | undefined): CallSite | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* The caller's frame in a whole stack captured by `holdCall`: the first frame in neither of
|
|
31
|
+
* tsdraft's two files on it, which are those of the first frame, `holdCall`'s own, and of the
|
|
32
|
+
* second, the builder's. Frames are told apart by file and not counted, because an engine may
|
|
33
|
+
* leave a frame out. When the caller's code is in one file with tsdraft, as in a bundle, no
|
|
34
|
+
* frame qualifies and there is no location, which is better than a line inside tsdraft.
|
|
35
|
+
*/
|
|
36
|
+
export declare function callerInStack(stack: string): CallSite | undefined;
|
|
37
|
+
/** Keeps the calls that drew `entities`, one for each entity in order. */
|
|
38
|
+
export declare function recordCalls(entities: readonly object[], calls: readonly (HeldCall | undefined)[]): void;
|
|
39
|
+
/** The call that drew the entity at `index` of `entities`, when the builder recorded it. */
|
|
40
|
+
export declare function callOf(entities: readonly object[], index: number): CallSite | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* The location of each frame of a stack, innermost first. V8 writes a frame as
|
|
43
|
+
* `at name (file:1:2)` or `at file:1:2`, and Firefox and Safari as `name@file:1:2`. A line that
|
|
44
|
+
* is no frame, such as the error's message, is left out.
|
|
45
|
+
*/
|
|
46
|
+
export declare function parseStack(stack: string): CallSite[];
|
|
47
|
+
export {};
|
package/dist/callsite.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// Where in the caller's code a builder method was called. The location comes from the engine's
|
|
2
|
+
// stack, so it holds a path of the machine the drawing was built on. It is kept beside the
|
|
3
|
+
// drawing, never in it.
|
|
4
|
+
/** The calls that drew a drawing's entities, by its `entities` array and each entity's index. */
|
|
5
|
+
const recorded = new WeakMap();
|
|
6
|
+
/**
|
|
7
|
+
* Captures the call of the builder method `method` that is running now, to be read later, or
|
|
8
|
+
* returns undefined where the engine gives no stack. It must be called from the builder's file.
|
|
9
|
+
*
|
|
10
|
+
* With `Error.captureStackTrace` the engine leaves out every frame down to `method`, so only the
|
|
11
|
+
* caller's frame is captured. Without it, the whole stack of a new error is kept.
|
|
12
|
+
*/
|
|
13
|
+
export function holdCall(method) {
|
|
14
|
+
const errors = Error;
|
|
15
|
+
try {
|
|
16
|
+
if (typeof errors.captureStackTrace !== "function") {
|
|
17
|
+
return { stack: new Error().stack, whole: true };
|
|
18
|
+
}
|
|
19
|
+
const held = { whole: false };
|
|
20
|
+
const limit = errors.stackTraceLimit;
|
|
21
|
+
const limited = typeof limit === "number";
|
|
22
|
+
if (limited)
|
|
23
|
+
errors.stackTraceLimit = 1;
|
|
24
|
+
try {
|
|
25
|
+
errors.captureStackTrace(held, method);
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
if (limited)
|
|
29
|
+
errors.stackTraceLimit = limit;
|
|
30
|
+
}
|
|
31
|
+
return held;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** The location a held call names, or undefined when its stack has none. */
|
|
38
|
+
export function readCall(held) {
|
|
39
|
+
if (!held)
|
|
40
|
+
return undefined;
|
|
41
|
+
try {
|
|
42
|
+
const stack = held.stack;
|
|
43
|
+
if (typeof stack !== "string")
|
|
44
|
+
return undefined;
|
|
45
|
+
return held.whole ? callerInStack(stack) : parseStack(stack)[0];
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The caller's frame in a whole stack captured by `holdCall`: the first frame in neither of
|
|
53
|
+
* tsdraft's two files on it, which are those of the first frame, `holdCall`'s own, and of the
|
|
54
|
+
* second, the builder's. Frames are told apart by file and not counted, because an engine may
|
|
55
|
+
* leave a frame out. When the caller's code is in one file with tsdraft, as in a bundle, no
|
|
56
|
+
* frame qualifies and there is no location, which is better than a line inside tsdraft.
|
|
57
|
+
*/
|
|
58
|
+
export function callerInStack(stack) {
|
|
59
|
+
const [capture, builder, ...rest] = parseStack(stack);
|
|
60
|
+
return rest.find((frame) => frame.file !== capture?.file && frame.file !== builder?.file);
|
|
61
|
+
}
|
|
62
|
+
/** Keeps the calls that drew `entities`, one for each entity in order. */
|
|
63
|
+
export function recordCalls(entities, calls) {
|
|
64
|
+
recorded.set(entities, calls);
|
|
65
|
+
}
|
|
66
|
+
/** The call that drew the entity at `index` of `entities`, when the builder recorded it. */
|
|
67
|
+
export function callOf(entities, index) {
|
|
68
|
+
return readCall(recorded.get(entities)?.[index]);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The location of each frame of a stack, innermost first. V8 writes a frame as
|
|
72
|
+
* `at name (file:1:2)` or `at file:1:2`, and Firefox and Safari as `name@file:1:2`. A line that
|
|
73
|
+
* is no frame, such as the error's message, is left out.
|
|
74
|
+
*/
|
|
75
|
+
export function parseStack(stack) {
|
|
76
|
+
return stack.split("\n").flatMap((line) => {
|
|
77
|
+
const frame = /^\s*at .*?\((.+):(\d+):(\d+)\)$/.exec(line) ??
|
|
78
|
+
/^\s*at (.+):(\d+):(\d+)$/.exec(line) ??
|
|
79
|
+
/^[^@]*@(.+):(\d+):(\d+)$/.exec(line);
|
|
80
|
+
return frame ? [{ file: frame[1], line: Number(frame[2]), column: Number(frame[3]) }] : [];
|
|
81
|
+
});
|
|
82
|
+
}
|
package/dist/drawing.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Description, type FrozenCurrent, type LayerLinetypeName, type LineweightMm, type LineweightOf, type LinetypeName, type NewLinetypeName, type Pattern, type R12EntityStyle, type R12LayerStates, type R12Lineweights, type R12Linetypes, type LayerColor, type LayerName, type Positive } from "./rules.ts";
|
|
1
|
+
import { type Description, type EntityId, type FrozenCurrent, type LayerLinetypeName, type LineweightMm, type LineweightOf, type LinetypeName, type NewLinetypeName, type Pattern, type R12EntityStyle, type R12LayerStates, type R12Lineweights, type R12Linetypes, type LayerColor, type LayerName, type Positive } from "./rules.ts";
|
|
2
2
|
/** A model-space point, in drawing units. Y points up, as in CAD. */
|
|
3
3
|
export type Point = readonly [x: number, y: number];
|
|
4
4
|
/**
|
|
@@ -51,6 +51,12 @@ export interface Layer {
|
|
|
51
51
|
readonly plot?: boolean;
|
|
52
52
|
}
|
|
53
53
|
interface EntityBase {
|
|
54
|
+
/**
|
|
55
|
+
* A name for this entity that stays the same when the drawing's code changes around it: 1 to
|
|
56
|
+
* 64 letters A to Z or a to z, digits, `.`, `-` and `_`. No two entities of a drawing share
|
|
57
|
+
* one, whatever its case.
|
|
58
|
+
*/
|
|
59
|
+
readonly id?: string;
|
|
54
60
|
readonly layer: string;
|
|
55
61
|
/** A linetype of the drawing, `"Continuous"`, `"ByBlock"` or `"ByLayer"`, the default. */
|
|
56
62
|
readonly linetype?: string;
|
|
@@ -91,6 +97,11 @@ export interface Text extends EntityBase {
|
|
|
91
97
|
}
|
|
92
98
|
export type Entity = Line | Polyline | Circle | Arc | Text;
|
|
93
99
|
export interface Drawing {
|
|
100
|
+
/**
|
|
101
|
+
* The version of the `Drawing` format, which is separate from the DXF version in `dxf`.
|
|
102
|
+
* Format 0 carries no promise of stability: a later tsdraft may change it without reading it.
|
|
103
|
+
*/
|
|
104
|
+
readonly format: 0;
|
|
94
105
|
readonly units: Units;
|
|
95
106
|
/** The DXF version the drawing is written for. `toDXF` uses it unless told otherwise. */
|
|
96
107
|
readonly dxf: DxfVersion;
|
|
@@ -108,6 +119,13 @@ export interface DrawingOptions<V extends DxfVersion = DxfVersion, S extends num
|
|
|
108
119
|
readonly dxf?: V;
|
|
109
120
|
/** The global linetype scale, which multiplies every linetype's pattern. Defaults to 1. */
|
|
110
121
|
readonly linetypeScale?: V extends "R12" ? 1 | R12Linetypes : Positive<S>;
|
|
122
|
+
/**
|
|
123
|
+
* Whether to record the call that draws each entity, so that a `lint` diagnostic names it in
|
|
124
|
+
* `call`. It more than doubles the time the builder takes. Defaults to `false`, or to `true` when
|
|
125
|
+
* `globalThis.TSDRAFT_RECORD_CALLS` is `true`, which a tool that runs drawing files sets
|
|
126
|
+
* before it runs them.
|
|
127
|
+
*/
|
|
128
|
+
readonly recordCalls?: boolean;
|
|
111
129
|
}
|
|
112
130
|
/** A linetype to define: a `Linetype`, whose description may be left out. */
|
|
113
131
|
export interface LinetypeDefinition<N extends string = string, P extends readonly number[] = readonly number[], D extends string = string> {
|
|
@@ -170,12 +188,18 @@ export interface LayerOptions<C extends number = number, W extends number = numb
|
|
|
170
188
|
readonly plot?: V extends "R12" ? true | R12LayerStates : boolean;
|
|
171
189
|
}
|
|
172
190
|
/**
|
|
173
|
-
* The linetype and lineweight
|
|
191
|
+
* The id an entity may have, and the linetype and lineweight it may have of its own. Both
|
|
192
|
+
* default to ByLayer.
|
|
174
193
|
*
|
|
175
194
|
* @typeParam L - The linetype as written, a name or a definition. A definition's literal mistakes
|
|
176
195
|
* are compile errors.
|
|
177
196
|
*/
|
|
178
|
-
export interface EntityOptions<V extends DxfVersion = "R2018", T extends string = string, W extends number = number, L extends LinetypeValue = LinetypeDefinition> {
|
|
197
|
+
export interface EntityOptions<V extends DxfVersion = "R2018", T extends string = string, W extends number = number, L extends LinetypeValue = LinetypeDefinition, I extends string = string> {
|
|
198
|
+
/**
|
|
199
|
+
* A name for the entity that no other entity of the drawing has: 1 to 64 letters A to Z or a
|
|
200
|
+
* to z, digits, `.`, `-` and `_`. Diagnostics and `toSVG` carry it.
|
|
201
|
+
*/
|
|
202
|
+
readonly id?: EntityId<I>;
|
|
179
203
|
/** A linetype of the drawing, `"Continuous"`, `"ByBlock"` or `"ByLayer"`. R2018 only. */
|
|
180
204
|
readonly linetype?: V extends "R12" ? R12LinetypeChoice<T, L, "bylayer", R12EntityStyle> : LinetypeChoice<T, L>;
|
|
181
205
|
/** In millimetres, or `"ByLayer"`, `"ByBlock"` or `"Default"`. R2018 only. */
|
|
@@ -187,7 +211,7 @@ export interface EntityOptions<V extends DxfVersion = "R2018", T extends string
|
|
|
187
211
|
* @typeParam L - The linetype as written, a name or a definition. A definition's literal mistakes
|
|
188
212
|
* are compile errors.
|
|
189
213
|
*/
|
|
190
|
-
export interface TextOptions<H extends number = number, V extends DxfVersion = "R2018", T extends string = string, W extends number = number, L extends LinetypeValue = LinetypeDefinition> extends EntityOptions<V, T, W, L> {
|
|
214
|
+
export interface TextOptions<H extends number = number, V extends DxfVersion = "R2018", T extends string = string, W extends number = number, L extends LinetypeValue = LinetypeDefinition, I extends string = string> extends EntityOptions<V, T, W, L, I> {
|
|
191
215
|
readonly height?: Positive<H>;
|
|
192
216
|
/** Degrees counterclockwise. */
|
|
193
217
|
readonly rotation?: number;
|
|
@@ -198,7 +222,9 @@ export interface TextOptions<H extends number = number, V extends DxfVersion = "
|
|
|
198
222
|
*
|
|
199
223
|
* Mistakes written as literals, such as a layer name the DXF version does not
|
|
200
224
|
* allow or a negative radius, are compile errors. The same checks run again
|
|
201
|
-
* when the code runs, for values the compiler cannot see
|
|
225
|
+
* when the code runs, for values the compiler cannot see: `layer`, `linetype`
|
|
226
|
+
* and the entity methods then throw a `DrawingError` whose diagnostic has the
|
|
227
|
+
* rule, the entity's `id` and the `call` that broke it.
|
|
202
228
|
*/
|
|
203
229
|
export declare class DrawingBuilder<V extends DxfVersion = "R2018", S extends number = number> {
|
|
204
230
|
#private;
|
|
@@ -218,11 +244,11 @@ export declare class DrawingBuilder<V extends DxfVersion = "R2018", S extends nu
|
|
|
218
244
|
* Options left out keep the values the layer has.
|
|
219
245
|
*/
|
|
220
246
|
layer<N extends string, C extends number = number, W extends number = number, T extends string = string, const L extends LinetypeValue = LinetypeDefinition>(name: LayerName<N, V>, options?: LayerOptions<C, W, T, V, N, L>, draw?: () => void): this;
|
|
221
|
-
line<T extends string = string, W extends number = number, const L extends LinetypeValue = LinetypeDefinition>(from: Point, to: Point, options?: EntityOptions<V, T, W, L>): this;
|
|
222
|
-
polyline<T extends string = string, W extends number = number, const L extends LinetypeValue = LinetypeDefinition>(points: readonly Point[], closed?: boolean, options?: EntityOptions<V, T, W, L>): this;
|
|
247
|
+
line<T extends string = string, W extends number = number, const L extends LinetypeValue = LinetypeDefinition, I extends string = string>(from: Point, to: Point, options?: EntityOptions<V, T, W, L, I>): this;
|
|
248
|
+
polyline<T extends string = string, W extends number = number, const L extends LinetypeValue = LinetypeDefinition, I extends string = string>(points: readonly Point[], closed?: boolean, options?: EntityOptions<V, T, W, L, I>): this;
|
|
223
249
|
/** Closed rectangle from its lower-left corner. */
|
|
224
|
-
rect<W extends number, H extends number, T extends string = string, LW extends number = number, const L extends LinetypeValue = LinetypeDefinition>(corner: Point, width: Positive<W>, height: Positive<H>, options?: EntityOptions<V, T, LW, L>): this;
|
|
225
|
-
circle<R extends number, T extends string = string, W extends number = number, const L extends LinetypeValue = LinetypeDefinition>(center: Point, radius: Positive<R>, options?: EntityOptions<V, T, W, L>): this;
|
|
250
|
+
rect<W extends number, H extends number, T extends string = string, LW extends number = number, const L extends LinetypeValue = LinetypeDefinition, I extends string = string>(corner: Point, width: Positive<W>, height: Positive<H>, options?: EntityOptions<V, T, LW, L, I>): this;
|
|
251
|
+
circle<R extends number, T extends string = string, W extends number = number, const L extends LinetypeValue = LinetypeDefinition, I extends string = string>(center: Point, radius: Positive<R>, options?: EntityOptions<V, T, W, L, I>): this;
|
|
226
252
|
/**
|
|
227
253
|
* Arc from `startAngle` counterclockwise to `endAngle`. Angles are stored
|
|
228
254
|
* from 0 up to 360, so -90 becomes 270, because AutoCAD's AUDIT rejects
|
|
@@ -232,8 +258,8 @@ export declare class DrawingBuilder<V extends DxfVersion = "R2018", S extends nu
|
|
|
232
258
|
* full turn would be written with equal angles, which AutoCAD holds as an
|
|
233
259
|
* arc of no length, so it throws: draw a circle instead.
|
|
234
260
|
*/
|
|
235
|
-
arc<R extends number, T extends string = string, W extends number = number, const L extends LinetypeValue = LinetypeDefinition>(center: Point, radius: Positive<R>, startAngle: number, endAngle: number, options?: EntityOptions<V, T, W, L>): this;
|
|
236
|
-
text<H extends number = number, T extends string = string, W extends number = number, const L extends LinetypeValue = LinetypeDefinition>(at: Point, value: string, options?: TextOptions<H, V, T, W, L>): this;
|
|
261
|
+
arc<R extends number, T extends string = string, W extends number = number, const L extends LinetypeValue = LinetypeDefinition, I extends string = string>(center: Point, radius: Positive<R>, startAngle: number, endAngle: number, options?: EntityOptions<V, T, W, L, I>): this;
|
|
262
|
+
text<H extends number = number, T extends string = string, W extends number = number, const L extends LinetypeValue = LinetypeDefinition, I extends string = string>(at: Point, value: string, options?: TextOptions<H, V, T, W, L, I>): this;
|
|
237
263
|
build(): Drawing;
|
|
238
264
|
}
|
|
239
265
|
export declare function createDrawing<V extends DxfVersion = "R2018", S extends number = number>(options?: DrawingOptions<V, S>): DrawingBuilder<V>;
|