dxf-json 0.0.21 → 0.0.22
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/package.json +5 -2
- package/.github/FUNDING.yml +0 -1
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -38
- package/.github/ISSUE_TEMPLATE/custom.md +0 -10
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
- package/.github/pull_request_template.md +0 -23
- package/.github/workflows/npm-publish.yml +0 -55
- package/.swcrc +0 -8
- package/jest.config.js +0 -20
- package/src/consts/block.ts +0 -22
- package/src/consts/color.ts +0 -6
- package/src/consts/config.ts +0 -2
- package/src/consts/dimension.ts +0 -69
- package/src/consts/hatch.ts +0 -52
- package/src/consts/header.ts +0 -10
- package/src/consts/index.ts +0 -9
- package/src/consts/lineweight.ts +0 -5
- package/src/consts/measurement.ts +0 -4
- package/src/consts/obscuredLineTypes.ts +0 -21
- package/src/consts/scene.ts +0 -2
- package/src/consts/viewport.ts +0 -62
- package/src/index.ts +0 -3
- package/src/parser/AutoCadColorIndex.ts +0 -265
- package/src/parser/DxfArrayScanner.ts +0 -161
- package/src/parser/DxfParser.ts +0 -109
- package/src/parser/ParseHelpers.ts +0 -124
- package/src/parser/blocks/blocks.test.ts +0 -97
- package/src/parser/blocks/index.ts +0 -88
- package/src/parser/blocks/types.ts +0 -15
- package/src/parser/entities/arc/index.ts +0 -2
- package/src/parser/entities/arc/parser.ts +0 -67
- package/src/parser/entities/arc/types.ts +0 -13
- package/src/parser/entities/attdef/consts.ts +0 -12
- package/src/parser/entities/attdef/index.ts +0 -3
- package/src/parser/entities/attdef/parser.ts +0 -119
- package/src/parser/entities/attdef/types.ts +0 -19
- package/src/parser/entities/attribute/consts.ts +0 -6
- package/src/parser/entities/attribute/index.ts +0 -3
- package/src/parser/entities/attribute/parser.ts +0 -198
- package/src/parser/entities/attribute/types.ts +0 -31
- package/src/parser/entities/circle/index.ts +0 -2
- package/src/parser/entities/circle/parser.ts +0 -58
- package/src/parser/entities/circle/types.ts +0 -11
- package/src/parser/entities/dimension/common.ts +0 -98
- package/src/parser/entities/dimension/index.ts +0 -24
- package/src/parser/entities/dimension/types.ts +0 -65
- package/src/parser/entities/ellipse/index.ts +0 -2
- package/src/parser/entities/ellipse/parser.ts +0 -66
- package/src/parser/entities/ellipse/types.ts +0 -13
- package/src/parser/entities/entities.test.ts +0 -86
- package/src/parser/entities/hatch/boundaryPathData/edge.ts +0 -190
- package/src/parser/entities/hatch/boundaryPathData/index.ts +0 -27
- package/src/parser/entities/hatch/boundaryPathData/polyline.ts +0 -43
- package/src/parser/entities/hatch/boundaryPathData/shared.ts +0 -16
- package/src/parser/entities/hatch/index.ts +0 -189
- package/src/parser/entities/hatch/patternData.ts +0 -57
- package/src/parser/entities/hatch/types/boundaryPath.ts +0 -72
- package/src/parser/entities/hatch/types/definitionLine.ts +0 -14
- package/src/parser/entities/hatch/types/hatch.ts +0 -47
- package/src/parser/entities/hatch/types/index.ts +0 -3
- package/src/parser/entities/index.ts +0 -87
- package/src/parser/entities/insert/index.ts +0 -2
- package/src/parser/entities/insert/parser.ts +0 -106
- package/src/parser/entities/insert/types.ts +0 -19
- package/src/parser/entities/leader/consts.ts +0 -6
- package/src/parser/entities/leader/index.ts +0 -3
- package/src/parser/entities/leader/parser.ts +0 -119
- package/src/parser/entities/leader/types.ts +0 -24
- package/src/parser/entities/line/index.ts +0 -2
- package/src/parser/entities/line/parser.ts +0 -55
- package/src/parser/entities/line/types.ts +0 -11
- package/src/parser/entities/lwpolyline/consts.ts +0 -4
- package/src/parser/entities/lwpolyline/index.ts +0 -3
- package/src/parser/entities/lwpolyline/parser.ts +0 -122
- package/src/parser/entities/lwpolyline/types.ts +0 -21
- package/src/parser/entities/mtext/consts.ts +0 -5
- package/src/parser/entities/mtext/index.ts +0 -3
- package/src/parser/entities/mtext/parser.ts +0 -195
- package/src/parser/entities/mtext/types.ts +0 -34
- package/src/parser/entities/point/index.ts +0 -2
- package/src/parser/entities/point/parser.ts +0 -60
- package/src/parser/entities/point/types.ts +0 -10
- package/src/parser/entities/polyline/consts.ts +0 -17
- package/src/parser/entities/polyline/index.ts +0 -3
- package/src/parser/entities/polyline/parser.ts +0 -126
- package/src/parser/entities/polyline/types.ts +0 -20
- package/src/parser/entities/section/index.ts +0 -2
- package/src/parser/entities/section/parser.ts +0 -104
- package/src/parser/entities/section/types.ts +0 -20
- package/src/parser/entities/shared.ts +0 -166
- package/src/parser/entities/solid/index.ts +0 -2
- package/src/parser/entities/solid/parser.ts +0 -56
- package/src/parser/entities/solid/types.ts +0 -10
- package/src/parser/entities/spline/consts.ts +0 -8
- package/src/parser/entities/spline/index.ts +0 -3
- package/src/parser/entities/spline/parser.ts +0 -121
- package/src/parser/entities/spline/types.ts +0 -22
- package/src/parser/entities/text/consts.ts +0 -21
- package/src/parser/entities/text/index.ts +0 -3
- package/src/parser/entities/text/parser.ts +0 -117
- package/src/parser/entities/text/types.ts +0 -21
- package/src/parser/entities/vertex/consts.ts +0 -10
- package/src/parser/entities/vertex/index.ts +0 -3
- package/src/parser/entities/vertex/parser.ts +0 -90
- package/src/parser/entities/vertex/types.ts +0 -17
- package/src/parser/entities/viewport/index.ts +0 -178
- package/src/parser/entities/viewport/types.ts +0 -58
- package/src/parser/filterDummyBlocks.ts +0 -49
- package/src/parser/header/index.ts +0 -30
- package/src/parser/objects/common.ts +0 -55
- package/src/parser/objects/dictionary.ts +0 -61
- package/src/parser/objects/index.ts +0 -45
- package/src/parser/objects/layout.ts +0 -136
- package/src/parser/objects/plotSettings.ts +0 -231
- package/src/parser/objects/treefy.ts +0 -53
- package/src/parser/objects/types.ts +0 -17
- package/src/parser/shared/index.ts +0 -21
- package/src/parser/shared/parsePoint.ts +0 -37
- package/src/parser/shared/parserGenerator.test.ts +0 -164
- package/src/parser/shared/parserGenerator.ts +0 -180
- package/src/parser/shared/xdata/index.ts +0 -3
- package/src/parser/shared/xdata/interpreter.test.ts +0 -85
- package/src/parser/shared/xdata/interpreter.ts +0 -65
- package/src/parser/shared/xdata/parser.test.ts +0 -66
- package/src/parser/shared/xdata/parser.ts +0 -140
- package/src/parser/shared/xdata/types.ts +0 -22
- package/src/parser/tables/blockRecord/index.ts +0 -2
- package/src/parser/tables/blockRecord/parser.ts +0 -49
- package/src/parser/tables/blockRecord/types.ts +0 -11
- package/src/parser/tables/dimStyle/consts.ts +0 -428
- package/src/parser/tables/dimStyle/index.ts +0 -3
- package/src/parser/tables/dimStyle/parser.ts +0 -37
- package/src/parser/tables/dimStyle/types.ts +0 -164
- package/src/parser/tables/index.ts +0 -2
- package/src/parser/tables/layer/index.ts +0 -2
- package/src/parser/tables/layer/parser.ts +0 -58
- package/src/parser/tables/layer/types.ts +0 -14
- package/src/parser/tables/ltype/consts.ts +0 -6
- package/src/parser/tables/ltype/index.ts +0 -3
- package/src/parser/tables/ltype/parser.ts +0 -110
- package/src/parser/tables/ltype/types.ts +0 -23
- package/src/parser/tables/parser.ts +0 -100
- package/src/parser/tables/shared.ts +0 -32
- package/src/parser/tables/style/index.ts +0 -2
- package/src/parser/tables/style/parser.ts +0 -70
- package/src/parser/tables/style/types.ts +0 -15
- package/src/parser/tables/types.ts +0 -15
- package/src/parser/tables/vport/index.ts +0 -2
- package/src/parser/tables/vport/parser.ts +0 -205
- package/src/parser/tables/vport/types.ts +0 -48
- package/src/parser/types.ts +0 -30
- package/src/types/color.ts +0 -5
- package/src/types/dxfHeader.ts +0 -21
- package/src/types/entity.ts +0 -7
- package/src/types/index.ts +0 -30
- package/src/utils/binarySearch.ts +0 -20
- package/src/utils/disjointSet.ts +0 -52
- package/src/utils/flooding.ts +0 -37
- package/src/utils/functional.ts +0 -124
- package/src/utils/graph.ts +0 -53
- package/src/utils/index.ts +0 -102
- package/src/utils/queue.ts +0 -77
- package/src/utils/triangle.ts +0 -28
- package/tsconfig.json +0 -37
- package/webpack.config.js +0 -53
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
import { isMatched } from '.';
|
|
2
|
-
import type DxfArrayScanner from '../DxfArrayScanner';
|
|
3
|
-
import { ScannerGroup } from '../DxfArrayScanner';
|
|
4
|
-
import { parsePoint } from './parsePoint';
|
|
5
|
-
|
|
6
|
-
export const Abort = Symbol();
|
|
7
|
-
|
|
8
|
-
// Snippet은 스트림에서 code를 읽었을 때 적절한 원자 파서를
|
|
9
|
-
// 대응해 주는 역할을 한다.
|
|
10
|
-
// Snippet은 스택에 쌓이며, 여러 Snippet이 동일한 code를
|
|
11
|
-
// 소비할 수 있을 때, 가장 위에 쌓인 Snippet이 우선순위를 갖는다.
|
|
12
|
-
export interface DXFParserSnippet {
|
|
13
|
-
code: number | number[]; // 복수의 코드를 다 한 곳으로 몰아넣기
|
|
14
|
-
name?: string; // 파싱한 값을 넣을 오브젝트 속성 명, 없으면 등록 안하고 패스함
|
|
15
|
-
|
|
16
|
-
// 추가로 더 읽어야 할 때만 scanner 사용하고, 새 값은 읽어놓지 말 것
|
|
17
|
-
// 반환되는 값이 entity[name]에 대입되므로 특별한 경우엔 entity 건들지 말고
|
|
18
|
-
// 사용할 경우, 최종값이 반환되도록 잘 건드릴 것
|
|
19
|
-
// 만약 Abort 심볼이 반환될 경우 값에 대입하지 않고 읽은 것을 한 칸 되돌리고
|
|
20
|
-
// 종료함
|
|
21
|
-
parser?(curr: ScannerGroup, scanner: DxfArrayScanner, entity: any): any;
|
|
22
|
-
isMultiple?: boolean; // code가 여러 번 들어올 수 있는 경우, true로 표기
|
|
23
|
-
|
|
24
|
-
// https://github.com/connect-for-you/cadview-front/issues/41
|
|
25
|
-
// 이 스니펫을 기점으로 맥락을 바꿈
|
|
26
|
-
pushContext?: boolean;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// 만약 파서가 어떤 유의미한 snippet도 찾지 못한 경우 전진하지 말고 false 반환
|
|
30
|
-
// 만약 파서가 유의미한 snippet을 찾아서 사용한 경우 반드시 한 칸 전진시키고 true 반환
|
|
31
|
-
// 즉 새로운 애를 하나는 무조건 읽어놓음
|
|
32
|
-
export type DXFParser = (
|
|
33
|
-
curr: ScannerGroup,
|
|
34
|
-
scanner: DxfArrayScanner,
|
|
35
|
-
target: any,
|
|
36
|
-
) => boolean;
|
|
37
|
-
|
|
38
|
-
export function createParser(
|
|
39
|
-
snippets: DXFParserSnippet[],
|
|
40
|
-
defaultObject?: any,
|
|
41
|
-
): DXFParser {
|
|
42
|
-
return (curr, scanner, target) => {
|
|
43
|
-
const snippetMaps = createSnippetMaps(snippets);
|
|
44
|
-
let isReadOnce = false;
|
|
45
|
-
let contextIndex = snippetMaps.length - 1;
|
|
46
|
-
|
|
47
|
-
while (!isMatched(curr, 0, 'EOF')) {
|
|
48
|
-
const snippetMap = findSnippetMap(
|
|
49
|
-
snippetMaps,
|
|
50
|
-
curr.code,
|
|
51
|
-
contextIndex,
|
|
52
|
-
);
|
|
53
|
-
const snippet = snippetMap?.[curr.code].at(-1);
|
|
54
|
-
|
|
55
|
-
if (!snippetMap || !snippet) {
|
|
56
|
-
scanner.rewind();
|
|
57
|
-
break;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (!snippet.isMultiple) {
|
|
61
|
-
snippetMap[curr.code].pop();
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const { name, parser, isMultiple } = snippet;
|
|
65
|
-
const parsedValue = parser?.(curr, scanner, target);
|
|
66
|
-
|
|
67
|
-
if (parsedValue === Abort) {
|
|
68
|
-
scanner.rewind();
|
|
69
|
-
break;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (name) {
|
|
73
|
-
const [leaf, fieldName] = getObjectByPath(target, name);
|
|
74
|
-
|
|
75
|
-
if (isMultiple) {
|
|
76
|
-
// prototype으로 디폴트값 넣어준 경우 nullish coalescing으로 해결 안됨
|
|
77
|
-
// @ts-ignore
|
|
78
|
-
if (!Object.hasOwn(leaf, fieldName)) {
|
|
79
|
-
leaf[fieldName] = [];
|
|
80
|
-
}
|
|
81
|
-
leaf[fieldName].push(parsedValue);
|
|
82
|
-
} else {
|
|
83
|
-
leaf[fieldName] = parsedValue;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (snippet.pushContext) {
|
|
88
|
-
contextIndex -= 1;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
isReadOnce = true;
|
|
92
|
-
curr = scanner.next();
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
if (defaultObject) {
|
|
96
|
-
Object.setPrototypeOf(target, defaultObject);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return isReadOnce;
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function createSnippetMaps(snippets: DXFParserSnippet[]) {
|
|
104
|
-
return snippets.reduce(
|
|
105
|
-
(acc, snippet) => {
|
|
106
|
-
if (snippet.pushContext) {
|
|
107
|
-
acc.push({});
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const context = acc[acc.length - 1];
|
|
111
|
-
const codes =
|
|
112
|
-
typeof snippet.code === 'number'
|
|
113
|
-
? [snippet.code]
|
|
114
|
-
: snippet.code;
|
|
115
|
-
|
|
116
|
-
for (const code of codes) {
|
|
117
|
-
const bin = (context[code] ??= []);
|
|
118
|
-
|
|
119
|
-
if (snippet.isMultiple && bin.length) {
|
|
120
|
-
console.warn(
|
|
121
|
-
`Snippet ${bin.at(-1)!.name
|
|
122
|
-
} for code(${code}) is shadowed by ${snippet.name}`,
|
|
123
|
-
);
|
|
124
|
-
}
|
|
125
|
-
bin.push(snippet);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return acc;
|
|
129
|
-
},
|
|
130
|
-
[{}] as Record<number, DXFParserSnippet[]>[],
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
function findSnippetMap(
|
|
135
|
-
snippetMaps: Record<number, DXFParserSnippet[]>[],
|
|
136
|
-
code: number,
|
|
137
|
-
contextIndex: number,
|
|
138
|
-
) {
|
|
139
|
-
return snippetMaps.find(
|
|
140
|
-
(map, index) => index >= contextIndex && map[code]?.length,
|
|
141
|
-
);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* path를 .으로 나누고, 그 서브패스의 값을 설정할 수 있게 함.
|
|
146
|
-
* 값이 없으면 알아서 만듦
|
|
147
|
-
*
|
|
148
|
-
* ex) a.b -> target[a]를 반환하여 b를 대입할 수 있게 함
|
|
149
|
-
* a.b.c -> target[a][b]를 반환하여 c를 대입할 수 있게 함
|
|
150
|
-
*
|
|
151
|
-
* @param target .으로 구분된 경로
|
|
152
|
-
* @param path
|
|
153
|
-
* @return [finalTargetObject, name]
|
|
154
|
-
*/
|
|
155
|
-
function getObjectByPath(target: any, path: string) {
|
|
156
|
-
const fragments = path.split('.');
|
|
157
|
-
|
|
158
|
-
let currentTarget = target;
|
|
159
|
-
for (let depth = 0; depth < fragments.length - 1; ++depth) {
|
|
160
|
-
const currentName = fragments[depth];
|
|
161
|
-
// @ts-ignore
|
|
162
|
-
if (!Object.hasOwn(currentTarget, currentName)) {
|
|
163
|
-
currentTarget[currentName] = {};
|
|
164
|
-
}
|
|
165
|
-
currentTarget = currentTarget[currentName];
|
|
166
|
-
}
|
|
167
|
-
return [currentTarget, fragments.at(-1)!];
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
export function Identity({ value }: ScannerGroup) {
|
|
171
|
-
return value;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
export function PointParser(_: any, scanner: DxfArrayScanner) {
|
|
175
|
-
return parsePoint(scanner);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
export function ToBoolean({ value }: ScannerGroup) {
|
|
179
|
-
return !!value;
|
|
180
|
-
}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { createXDataControlInterpreter } from './interpreter';
|
|
2
|
-
|
|
3
|
-
describe('xdata:interpreter', () => {
|
|
4
|
-
it('xdata 엔트리들이 name-value 쌍이면 객체에 snippet대로 풀어서 반환한다', () => {
|
|
5
|
-
const interpreter = createXDataControlInterpreter([
|
|
6
|
-
{
|
|
7
|
-
code: 40,
|
|
8
|
-
name: '$DIMSCALE',
|
|
9
|
-
},
|
|
10
|
-
{
|
|
11
|
-
code: 172,
|
|
12
|
-
name: 'dim-line-forced',
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
code: 175,
|
|
16
|
-
name: 'dim-line-inside',
|
|
17
|
-
},
|
|
18
|
-
]);
|
|
19
|
-
|
|
20
|
-
const result = interpreter([
|
|
21
|
-
{
|
|
22
|
-
value: 40,
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
value: 2.0,
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
value: 175,
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
value: 0,
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
value: 172,
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
value: 1,
|
|
38
|
-
},
|
|
39
|
-
]);
|
|
40
|
-
// @ts-ignore
|
|
41
|
-
expect(result['$DIMSCALE']).toBe(2.0);
|
|
42
|
-
// @ts-ignore
|
|
43
|
-
expect(result['dim-line-forced']).toBe(1);
|
|
44
|
-
// @ts-ignore
|
|
45
|
-
expect(result['dim-line-inside']).toBe(0);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('snippet에 없는 쌍은 무시한다.', () => {
|
|
49
|
-
const interpreter = createXDataControlInterpreter([
|
|
50
|
-
{
|
|
51
|
-
code: 40,
|
|
52
|
-
name: '$DIMSCALE',
|
|
53
|
-
type: 'real',
|
|
54
|
-
},
|
|
55
|
-
]);
|
|
56
|
-
|
|
57
|
-
const result = interpreter([
|
|
58
|
-
{
|
|
59
|
-
value: 175,
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
value: 0,
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
value: 40,
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
value: 2.0,
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
value: 172,
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
value: 1,
|
|
75
|
-
},
|
|
76
|
-
]);
|
|
77
|
-
|
|
78
|
-
// @ts-ignore
|
|
79
|
-
expect(result['$DIMSCALE']).toBe(2.0);
|
|
80
|
-
// @ts-ignore
|
|
81
|
-
expect(result['dim-line-forced']).toBe(undefined);
|
|
82
|
-
// @ts-ignore
|
|
83
|
-
expect(result['dim-line-inside']).toBe(undefined);
|
|
84
|
-
});
|
|
85
|
-
});
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import type { XData, XDataEntry } from './types';
|
|
2
|
-
|
|
3
|
-
export type XDataInterpreterSnippet<Name extends string> = {
|
|
4
|
-
code: number;
|
|
5
|
-
name: Name;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
type PackPairType<Snippets> = Snippets extends readonly [infer X, ...infer R]
|
|
9
|
-
? X extends XDataInterpreterSnippet<infer N>
|
|
10
|
-
? { [key in N]?: any } & PackPairType<R>
|
|
11
|
-
: PackPairType<R>
|
|
12
|
-
: {};
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* xdata가 code-value의 연속인 경우에 사용 가능
|
|
16
|
-
* ex) DSTYLE
|
|
17
|
-
*/
|
|
18
|
-
export function createXDataControlInterpreter<
|
|
19
|
-
T extends readonly XDataInterpreterSnippet<string>[],
|
|
20
|
-
>(snippets: T) {
|
|
21
|
-
return (entries: XDataEntry[]): PackPairType<T> => {
|
|
22
|
-
const result = {} as PackPairType<T>;
|
|
23
|
-
|
|
24
|
-
for (let i = 0; i < entries.length; i += 2) {
|
|
25
|
-
const snippet = snippets.find(
|
|
26
|
-
({ code }) => code === entries[i].value,
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
if (!snippet) continue;
|
|
30
|
-
// @ts-ignore
|
|
31
|
-
result[snippet.name] = entries[i + 1]?.value;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return result;
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
interface CreateXDataCatcherParams {
|
|
39
|
-
appName?: string;
|
|
40
|
-
catcher(entry: XDataEntry): boolean;
|
|
41
|
-
escaper?(entry: XDataEntry, count: number): boolean; // 몇 번째인지. 1부터 셈.
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function createXDataCatcher({
|
|
45
|
-
appName = 'ACAD',
|
|
46
|
-
catcher,
|
|
47
|
-
escaper,
|
|
48
|
-
}: CreateXDataCatcherParams) {
|
|
49
|
-
return function* (xdata?: XData) {
|
|
50
|
-
if (xdata?.appName !== appName) return;
|
|
51
|
-
|
|
52
|
-
let isCatchable = false;
|
|
53
|
-
let startIndex = -1;
|
|
54
|
-
for (const [index, entry] of xdata.value.entries()) {
|
|
55
|
-
if (isCatchable) {
|
|
56
|
-
yield entry;
|
|
57
|
-
|
|
58
|
-
if (escaper?.(entry, index - startIndex)) return;
|
|
59
|
-
} else if (catcher(entry)) {
|
|
60
|
-
isCatchable = true;
|
|
61
|
-
startIndex = index;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import DxfArrayScanner from '../../DxfArrayScanner';
|
|
2
|
-
import { parseXData } from './parser';
|
|
3
|
-
|
|
4
|
-
describe('xdata:parser', () => {
|
|
5
|
-
it('xdata entry를 순차적으로 파싱하여 배열로 반환해야 한다', () => {
|
|
6
|
-
const scanner = new DxfArrayScanner(
|
|
7
|
-
`1001
|
|
8
|
-
ACAD
|
|
9
|
-
1000
|
|
10
|
-
DSTYLE
|
|
11
|
-
1070
|
|
12
|
-
171
|
|
13
|
-
`.split('\n'),
|
|
14
|
-
);
|
|
15
|
-
const curr = scanner.next();
|
|
16
|
-
const result = parseXData(curr, scanner);
|
|
17
|
-
|
|
18
|
-
expect(result.appName).toBe('ACAD');
|
|
19
|
-
expect(result.value.length).toBe(2);
|
|
20
|
-
expect(result.value[0].value).toBe('DSTYLE');
|
|
21
|
-
expect(result.value[1].value).toBe(171);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('중첩된 xdata entry를 중첩된 배열로 반환해야 한다.', () => {
|
|
25
|
-
const scanner = new DxfArrayScanner(
|
|
26
|
-
`1001
|
|
27
|
-
ACAD
|
|
28
|
-
1000
|
|
29
|
-
a
|
|
30
|
-
1002
|
|
31
|
-
{
|
|
32
|
-
1000
|
|
33
|
-
b
|
|
34
|
-
1000
|
|
35
|
-
c
|
|
36
|
-
1002
|
|
37
|
-
}
|
|
38
|
-
1000
|
|
39
|
-
d
|
|
40
|
-
`.split('\n'),
|
|
41
|
-
);
|
|
42
|
-
const curr = scanner.next();
|
|
43
|
-
const result = parseXData(curr, scanner);
|
|
44
|
-
|
|
45
|
-
expect(result.value).toMatchObject([
|
|
46
|
-
{
|
|
47
|
-
type: 'string',
|
|
48
|
-
value: 'a',
|
|
49
|
-
},
|
|
50
|
-
[
|
|
51
|
-
{
|
|
52
|
-
type: 'string',
|
|
53
|
-
value: 'b',
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
type: 'string',
|
|
57
|
-
value: 'c',
|
|
58
|
-
},
|
|
59
|
-
],
|
|
60
|
-
{
|
|
61
|
-
type: 'string',
|
|
62
|
-
value: 'd',
|
|
63
|
-
},
|
|
64
|
-
]);
|
|
65
|
-
});
|
|
66
|
-
});
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { isMatched } from '..';
|
|
2
|
-
import type { ScannerGroup } from '../../DxfArrayScanner';
|
|
3
|
-
import type DxfArrayScanner from '../../DxfArrayScanner';
|
|
4
|
-
import { parsePoint } from '../parsePoint';
|
|
5
|
-
import { DXFParserSnippet } from '../parserGenerator';
|
|
6
|
-
import type { XData, XDataEntry } from './types';
|
|
7
|
-
|
|
8
|
-
export const XDataParserSnippets: DXFParserSnippet[] = [
|
|
9
|
-
{
|
|
10
|
-
code: 1001,
|
|
11
|
-
name: 'xdata',
|
|
12
|
-
parser: parseXData,
|
|
13
|
-
},
|
|
14
|
-
];
|
|
15
|
-
|
|
16
|
-
export function parseXData(curr: ScannerGroup, scanner: DxfArrayScanner) {
|
|
17
|
-
if (!isMatched(curr, 1001)) {
|
|
18
|
-
throw new Error('XData must starts with code 1001');
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const xdata: XData = {
|
|
22
|
-
appName: curr.value,
|
|
23
|
-
value: [] as XDataEntry[],
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
curr = scanner.next();
|
|
27
|
-
|
|
28
|
-
const stack = [xdata.value] as any[][];
|
|
29
|
-
|
|
30
|
-
while (!isMatched(curr, 0, 'EOF') && curr.code >= 1000) {
|
|
31
|
-
const top = stack.at(-1)!;
|
|
32
|
-
|
|
33
|
-
switch (curr.code) {
|
|
34
|
-
case 1002:
|
|
35
|
-
if (curr.value === '{') {
|
|
36
|
-
stack.push([]);
|
|
37
|
-
} else {
|
|
38
|
-
stack.pop();
|
|
39
|
-
stack.at(-1)?.push(top);
|
|
40
|
-
}
|
|
41
|
-
break;
|
|
42
|
-
case 1000: // string
|
|
43
|
-
case 1004: // hex string
|
|
44
|
-
case 1040: // real
|
|
45
|
-
case 1070: // integer
|
|
46
|
-
case 1071: // long
|
|
47
|
-
top.push({
|
|
48
|
-
type: getType(curr.code),
|
|
49
|
-
value: curr.value,
|
|
50
|
-
});
|
|
51
|
-
break;
|
|
52
|
-
case 1003:
|
|
53
|
-
top.push({
|
|
54
|
-
name: 'layer',
|
|
55
|
-
type: getType(curr.code),
|
|
56
|
-
value: curr.value,
|
|
57
|
-
});
|
|
58
|
-
break;
|
|
59
|
-
case 1005:
|
|
60
|
-
top.push({
|
|
61
|
-
name: 'handle',
|
|
62
|
-
type: getType(curr.code),
|
|
63
|
-
value: curr.value,
|
|
64
|
-
});
|
|
65
|
-
break;
|
|
66
|
-
case 1010: // just 3 reals
|
|
67
|
-
top.push({
|
|
68
|
-
type: getType(curr.code),
|
|
69
|
-
value: parsePoint(scanner),
|
|
70
|
-
});
|
|
71
|
-
break;
|
|
72
|
-
case 1011:
|
|
73
|
-
top.push({
|
|
74
|
-
name: 'worldSpacePosition',
|
|
75
|
-
type: getType(curr.code),
|
|
76
|
-
value: parsePoint(scanner),
|
|
77
|
-
});
|
|
78
|
-
break;
|
|
79
|
-
case 1012:
|
|
80
|
-
top.push({
|
|
81
|
-
name: 'worldSpaceDisplacement',
|
|
82
|
-
type: getType(curr.code),
|
|
83
|
-
value: parsePoint(scanner),
|
|
84
|
-
});
|
|
85
|
-
break;
|
|
86
|
-
case 1013:
|
|
87
|
-
top.push({
|
|
88
|
-
name: 'worldSpaceDirection',
|
|
89
|
-
type: getType(curr.code),
|
|
90
|
-
value: parsePoint(scanner),
|
|
91
|
-
});
|
|
92
|
-
break;
|
|
93
|
-
case 1041:
|
|
94
|
-
top.push({
|
|
95
|
-
name: 'distance',
|
|
96
|
-
type: getType(curr.code),
|
|
97
|
-
value: curr.value,
|
|
98
|
-
});
|
|
99
|
-
break;
|
|
100
|
-
case 1042:
|
|
101
|
-
top.push({
|
|
102
|
-
name: 'scale',
|
|
103
|
-
type: getType(curr.code),
|
|
104
|
-
value: curr.value,
|
|
105
|
-
});
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
curr = scanner.next();
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
scanner.rewind();
|
|
113
|
-
return xdata;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function getType(code: number) {
|
|
117
|
-
switch (code) {
|
|
118
|
-
case 1000:
|
|
119
|
-
case 1003:
|
|
120
|
-
case 1005:
|
|
121
|
-
return 'string';
|
|
122
|
-
case 1004:
|
|
123
|
-
return 'hex';
|
|
124
|
-
case 1040:
|
|
125
|
-
case 1041:
|
|
126
|
-
case 1042:
|
|
127
|
-
return 'real';
|
|
128
|
-
case 1070:
|
|
129
|
-
return 'integer';
|
|
130
|
-
case 1071:
|
|
131
|
-
return 'long';
|
|
132
|
-
case 1010:
|
|
133
|
-
case 1011:
|
|
134
|
-
case 1012:
|
|
135
|
-
case 1013:
|
|
136
|
-
return 'point';
|
|
137
|
-
default:
|
|
138
|
-
return '';
|
|
139
|
-
}
|
|
140
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { Point3D } from '../../../types';
|
|
2
|
-
|
|
3
|
-
/*
|
|
4
|
-
https://help.autodesk.com/view/OARX/2023/ENU/?guid=GUID-A2A628B0-3699-4740-A215-C560E7242F63
|
|
5
|
-
|
|
6
|
-
확장 데이터는 LISP 언어 형식으로 작성되는데, 대충 재귀적인 배열 구조라고 생각하면 된다.
|
|
7
|
-
이 구조는 AutoCAD 혹은 서드파티가 알아서 정의하고 쓰므로 신경꺼도 좋다.
|
|
8
|
-
(ex: [1, 2, 'babo', [3], 3.14, [[]]])
|
|
9
|
-
|
|
10
|
-
각 깊이는 1002번 코드의 {로 시작하여 }로 끝난다.
|
|
11
|
-
이 값들은 DXF 일반 코드와 다르게 이름이 있기도 하고 없기도 하여, 아래와 같은 자료 구조로 저장한다.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
export interface XData {
|
|
15
|
-
appName: string;
|
|
16
|
-
value: XDataEntry[];
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface XDataEntry {
|
|
20
|
-
name?: string;
|
|
21
|
-
value: XDataEntry[] | number | string | Point3D;
|
|
22
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createParser,
|
|
3
|
-
DXFParserSnippet,
|
|
4
|
-
Identity,
|
|
5
|
-
} from '../../shared/parserGenerator';
|
|
6
|
-
import { CommonTableEntryParserSnippets } from '../shared';
|
|
7
|
-
|
|
8
|
-
const BlockRecordTableParserSnippets: DXFParserSnippet[] = [
|
|
9
|
-
{
|
|
10
|
-
code: 310,
|
|
11
|
-
name: 'bmpPreview',
|
|
12
|
-
parser: Identity,
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
code: 281,
|
|
16
|
-
name: 'scalability',
|
|
17
|
-
parser: Identity,
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
code: 280,
|
|
21
|
-
name: 'explodability',
|
|
22
|
-
parser: Identity,
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
code: 70,
|
|
26
|
-
name: 'insertionUnits',
|
|
27
|
-
parser: Identity,
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
code: 340,
|
|
31
|
-
name: 'layoutObjects',
|
|
32
|
-
parser: Identity,
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
code: 2,
|
|
36
|
-
name: 'name',
|
|
37
|
-
parser: Identity,
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
code: 100,
|
|
41
|
-
name: 'subclassMarker',
|
|
42
|
-
parser: Identity,
|
|
43
|
-
},
|
|
44
|
-
...CommonTableEntryParserSnippets,
|
|
45
|
-
];
|
|
46
|
-
|
|
47
|
-
export const parseBlockRecordTable = createParser(
|
|
48
|
-
BlockRecordTableParserSnippets,
|
|
49
|
-
);
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { CommonDxfTableEntry } from '../types';
|
|
2
|
-
|
|
3
|
-
export interface BlockRecordTableEntry extends CommonDxfTableEntry {
|
|
4
|
-
subclassMarker: 'AcDbBlockTableRecord';
|
|
5
|
-
name: string;
|
|
6
|
-
layoutObjects: string;
|
|
7
|
-
insertionUnits: number;
|
|
8
|
-
explodability: number;
|
|
9
|
-
scalability: number;
|
|
10
|
-
bmpPreview: string;
|
|
11
|
-
}
|