@linkiez/dxf-renew 7.0.0 → 7.2.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.
Files changed (252) hide show
  1. package/.eslintrc.json +1 -16
  2. package/.github/instructions/code-patterns.instructions.md +1 -1
  3. package/.github/instructions/exdxf.instruction.md +161 -0
  4. package/.github/instructions/tdd.instructions.md +271 -0
  5. package/.yarn/install-state.gz +0 -0
  6. package/ARCHITECTURE.md +163 -0
  7. package/CHANGELOG.md +39 -0
  8. package/CONTRIBUTING.md +16 -14
  9. package/README.md +113 -16
  10. package/{PLAN.md → ROADMAP.md} +244 -102
  11. package/dist/dxf.js +2212 -454
  12. package/docs/EZDXF_REFERENCE_SITEMAP.md +55 -0
  13. package/docs/FIXTURE_VALIDATION_EZDXF.md +62 -0
  14. package/lib/Helper.cjs +6 -2
  15. package/lib/Helper.cjs.map +3 -3
  16. package/lib/Helper.js +6 -2
  17. package/lib/Helper.js.map +2 -2
  18. package/lib/denormalise.cjs +131 -91
  19. package/lib/denormalise.cjs.map +2 -2
  20. package/lib/denormalise.js +131 -91
  21. package/lib/denormalise.js.map +2 -2
  22. package/lib/dimensionToSVG.cjs +318 -53
  23. package/lib/dimensionToSVG.cjs.map +3 -3
  24. package/lib/dimensionToSVG.js +316 -52
  25. package/lib/dimensionToSVG.js.map +2 -2
  26. package/lib/entityToPolyline.cjs +95 -0
  27. package/lib/entityToPolyline.cjs.map +3 -3
  28. package/lib/entityToPolyline.js +95 -0
  29. package/lib/entityToPolyline.js.map +2 -2
  30. package/lib/handlers/entities.cjs +111 -27
  31. package/lib/handlers/entities.cjs.map +3 -3
  32. package/lib/handlers/entities.js +111 -27
  33. package/lib/handlers/entities.js.map +3 -3
  34. package/lib/handlers/entity/dgnUnderlay.cjs +106 -0
  35. package/lib/handlers/entity/dgnUnderlay.cjs.map +7 -0
  36. package/lib/handlers/entity/dgnUnderlay.js +71 -0
  37. package/lib/handlers/entity/dgnUnderlay.js.map +7 -0
  38. package/lib/handlers/entity/dimension.cjs +24 -0
  39. package/lib/handlers/entity/dimension.cjs.map +2 -2
  40. package/lib/handlers/entity/dimension.js +24 -0
  41. package/lib/handlers/entity/dimension.js.map +2 -2
  42. package/lib/handlers/entity/dwfUnderlay.cjs +106 -0
  43. package/lib/handlers/entity/dwfUnderlay.cjs.map +7 -0
  44. package/lib/handlers/entity/dwfUnderlay.js +71 -0
  45. package/lib/handlers/entity/dwfUnderlay.js.map +7 -0
  46. package/lib/handlers/entity/image.cjs +123 -0
  47. package/lib/handlers/entity/image.cjs.map +7 -0
  48. package/lib/handlers/entity/image.js +88 -0
  49. package/lib/handlers/entity/image.js.map +7 -0
  50. package/lib/handlers/entity/leader.cjs +148 -0
  51. package/lib/handlers/entity/leader.cjs.map +7 -0
  52. package/lib/handlers/entity/leader.js +113 -0
  53. package/lib/handlers/entity/leader.js.map +7 -0
  54. package/lib/handlers/entity/mleader.cjs +69 -0
  55. package/lib/handlers/entity/mleader.cjs.map +7 -0
  56. package/lib/handlers/entity/mleader.js +34 -0
  57. package/lib/handlers/entity/mleader.js.map +7 -0
  58. package/lib/handlers/entity/mline.cjs +91 -0
  59. package/lib/handlers/entity/mline.cjs.map +7 -0
  60. package/lib/handlers/entity/mline.js +56 -0
  61. package/lib/handlers/entity/mline.js.map +7 -0
  62. package/lib/handlers/entity/oleframe.cjs +98 -0
  63. package/lib/handlers/entity/oleframe.cjs.map +7 -0
  64. package/lib/handlers/entity/oleframe.js +63 -0
  65. package/lib/handlers/entity/oleframe.js.map +7 -0
  66. package/lib/handlers/entity/pdfUnderlay.cjs +106 -0
  67. package/lib/handlers/entity/pdfUnderlay.cjs.map +7 -0
  68. package/lib/handlers/entity/pdfUnderlay.js +71 -0
  69. package/lib/handlers/entity/pdfUnderlay.js.map +7 -0
  70. package/lib/handlers/entity/ray.cjs +81 -0
  71. package/lib/handlers/entity/ray.cjs.map +7 -0
  72. package/lib/handlers/entity/ray.js +46 -0
  73. package/lib/handlers/entity/ray.js.map +7 -0
  74. package/lib/handlers/entity/region.cjs +67 -0
  75. package/lib/handlers/entity/region.cjs.map +7 -0
  76. package/lib/handlers/entity/region.js +32 -0
  77. package/lib/handlers/entity/region.js.map +7 -0
  78. package/lib/handlers/entity/shape.cjs +95 -0
  79. package/lib/handlers/entity/shape.cjs.map +7 -0
  80. package/lib/handlers/entity/shape.js +60 -0
  81. package/lib/handlers/entity/shape.js.map +7 -0
  82. package/lib/handlers/entity/table.cjs +71 -0
  83. package/lib/handlers/entity/table.cjs.map +7 -0
  84. package/lib/handlers/entity/table.js +36 -0
  85. package/lib/handlers/entity/table.js.map +7 -0
  86. package/lib/handlers/entity/tolerance.cjs +90 -0
  87. package/lib/handlers/entity/tolerance.cjs.map +7 -0
  88. package/lib/handlers/entity/tolerance.js +55 -0
  89. package/lib/handlers/entity/tolerance.js.map +7 -0
  90. package/lib/handlers/entity/trace.cjs +101 -0
  91. package/lib/handlers/entity/trace.cjs.map +7 -0
  92. package/lib/handlers/entity/trace.js +66 -0
  93. package/lib/handlers/entity/trace.js.map +7 -0
  94. package/lib/handlers/entity/wipeout.cjs +122 -0
  95. package/lib/handlers/entity/wipeout.cjs.map +7 -0
  96. package/lib/handlers/entity/wipeout.js +87 -0
  97. package/lib/handlers/entity/wipeout.js.map +7 -0
  98. package/lib/handlers/entity/xline.cjs +81 -0
  99. package/lib/handlers/entity/xline.cjs.map +7 -0
  100. package/lib/handlers/entity/xline.js +46 -0
  101. package/lib/handlers/entity/xline.js.map +7 -0
  102. package/lib/handlers/objects.cjs +299 -136
  103. package/lib/handlers/objects.cjs.map +2 -2
  104. package/lib/handlers/objects.js +299 -136
  105. package/lib/handlers/objects.js.map +2 -2
  106. package/lib/handlers/tables.cjs +96 -17
  107. package/lib/handlers/tables.cjs.map +2 -2
  108. package/lib/handlers/tables.js +96 -17
  109. package/lib/handlers/tables.js.map +2 -2
  110. package/lib/index.cjs +5 -2
  111. package/lib/index.cjs.map +3 -3
  112. package/lib/index.js +18 -16
  113. package/lib/index.js.map +3 -3
  114. package/lib/toJson.cjs +29 -0
  115. package/lib/toJson.cjs.map +7 -0
  116. package/lib/toJson.js +9 -0
  117. package/lib/toJson.js.map +7 -0
  118. package/lib/toSVG.cjs +105 -11
  119. package/lib/toSVG.cjs.map +3 -3
  120. package/lib/toSVG.js +106 -12
  121. package/lib/toSVG.js.map +2 -2
  122. package/lib/types/dimension-entity.cjs.map +1 -1
  123. package/lib/types/entity.cjs.map +1 -1
  124. package/lib/types/helper.cjs.map +1 -1
  125. package/lib/types/image-entity.cjs +17 -0
  126. package/lib/types/image-entity.cjs.map +7 -0
  127. package/lib/types/image-entity.js +1 -0
  128. package/lib/types/image-entity.js.map +7 -0
  129. package/lib/types/index.cjs +28 -0
  130. package/lib/types/index.cjs.map +2 -2
  131. package/lib/types/index.js +14 -0
  132. package/lib/types/index.js.map +2 -2
  133. package/lib/types/leader-entity.cjs +17 -0
  134. package/lib/types/leader-entity.cjs.map +7 -0
  135. package/lib/types/leader-entity.js +1 -0
  136. package/lib/types/leader-entity.js.map +7 -0
  137. package/lib/types/mleader-entity.cjs +17 -0
  138. package/lib/types/mleader-entity.cjs.map +7 -0
  139. package/lib/types/mleader-entity.js +1 -0
  140. package/lib/types/mleader-entity.js.map +7 -0
  141. package/lib/types/mline-entity.cjs +17 -0
  142. package/lib/types/mline-entity.cjs.map +7 -0
  143. package/lib/types/mline-entity.js +1 -0
  144. package/lib/types/mline-entity.js.map +7 -0
  145. package/lib/types/oleframe-entity.cjs +17 -0
  146. package/lib/types/oleframe-entity.cjs.map +7 -0
  147. package/lib/types/oleframe-entity.js +1 -0
  148. package/lib/types/oleframe-entity.js.map +7 -0
  149. package/lib/types/options.cjs.map +1 -1
  150. package/lib/types/ray-entity.cjs +17 -0
  151. package/lib/types/ray-entity.cjs.map +7 -0
  152. package/lib/types/ray-entity.js +1 -0
  153. package/lib/types/ray-entity.js.map +7 -0
  154. package/lib/types/region-entity.cjs +17 -0
  155. package/lib/types/region-entity.cjs.map +7 -0
  156. package/lib/types/region-entity.js +1 -0
  157. package/lib/types/region-entity.js.map +7 -0
  158. package/lib/types/shape-entity.cjs +17 -0
  159. package/lib/types/shape-entity.cjs.map +7 -0
  160. package/lib/types/shape-entity.js +1 -0
  161. package/lib/types/shape-entity.js.map +7 -0
  162. package/lib/types/table-entity.cjs +17 -0
  163. package/lib/types/table-entity.cjs.map +7 -0
  164. package/lib/types/table-entity.js +1 -0
  165. package/lib/types/table-entity.js.map +7 -0
  166. package/lib/types/tables.cjs.map +1 -1
  167. package/lib/types/tolerance-entity.cjs +17 -0
  168. package/lib/types/tolerance-entity.cjs.map +7 -0
  169. package/lib/types/tolerance-entity.js +1 -0
  170. package/lib/types/tolerance-entity.js.map +7 -0
  171. package/lib/types/trace-entity.cjs +17 -0
  172. package/lib/types/trace-entity.cjs.map +7 -0
  173. package/lib/types/trace-entity.js +1 -0
  174. package/lib/types/trace-entity.js.map +7 -0
  175. package/lib/types/underlay-entity.cjs +17 -0
  176. package/lib/types/underlay-entity.cjs.map +7 -0
  177. package/lib/types/underlay-entity.js +1 -0
  178. package/lib/types/underlay-entity.js.map +7 -0
  179. package/lib/types/wipeout-entity.cjs +17 -0
  180. package/lib/types/wipeout-entity.cjs.map +7 -0
  181. package/lib/types/wipeout-entity.js +1 -0
  182. package/lib/types/wipeout-entity.js.map +7 -0
  183. package/lib/types/xline-entity.cjs +17 -0
  184. package/lib/types/xline-entity.cjs.map +7 -0
  185. package/lib/types/xline-entity.js +1 -0
  186. package/lib/types/xline-entity.js.map +7 -0
  187. package/lib/util/escapeXmlText.cjs +27 -0
  188. package/lib/util/escapeXmlText.cjs.map +7 -0
  189. package/lib/util/escapeXmlText.js +7 -0
  190. package/lib/util/escapeXmlText.js.map +7 -0
  191. package/package.json +9 -18
  192. package/playwright.config.cjs +20 -0
  193. package/src/Helper.ts +8 -3
  194. package/src/denormalise.ts +182 -116
  195. package/src/dimensionToSVG.ts +466 -54
  196. package/src/entityToPolyline.ts +124 -2
  197. package/src/handlers/entities.ts +129 -34
  198. package/src/handlers/entity/dgnUnderlay.ts +94 -0
  199. package/src/handlers/entity/dimension.ts +27 -1
  200. package/src/handlers/entity/dwfUnderlay.ts +94 -0
  201. package/src/handlers/entity/image.ts +118 -0
  202. package/src/handlers/entity/leader.ts +153 -0
  203. package/src/handlers/entity/mleader.ts +46 -0
  204. package/src/handlers/entity/mline.ts +74 -0
  205. package/src/handlers/entity/oleframe.ts +62 -0
  206. package/src/handlers/entity/pdfUnderlay.ts +94 -0
  207. package/src/handlers/entity/ray.ts +52 -0
  208. package/src/handlers/entity/region.ts +42 -0
  209. package/src/handlers/entity/shape.ts +73 -0
  210. package/src/handlers/entity/table.ts +49 -0
  211. package/src/handlers/entity/tolerance.ts +75 -0
  212. package/src/handlers/entity/trace.ts +72 -0
  213. package/src/handlers/entity/wipeout.ts +114 -0
  214. package/src/handlers/entity/xline.ts +52 -0
  215. package/src/handlers/objects.ts +379 -139
  216. package/src/handlers/tables.ts +134 -21
  217. package/src/index.ts +9 -18
  218. package/src/toJson.ts +8 -0
  219. package/src/toSVG.ts +143 -10
  220. package/src/types/dimension-entity.ts +11 -0
  221. package/src/types/entity.ts +30 -0
  222. package/src/types/helper.ts +2 -1
  223. package/src/types/image-entity.ts +35 -0
  224. package/src/types/index.ts +14 -0
  225. package/src/types/leader-entity.ts +40 -0
  226. package/src/types/mleader-entity.ts +8 -0
  227. package/src/types/mline-entity.ts +12 -0
  228. package/src/types/oleframe-entity.ts +40 -0
  229. package/src/types/options.ts +48 -0
  230. package/src/types/ray-entity.ts +12 -0
  231. package/src/types/region-entity.ts +11 -0
  232. package/src/types/shape-entity.ts +19 -0
  233. package/src/types/table-entity.ts +14 -0
  234. package/src/types/tables.ts +160 -0
  235. package/src/types/tolerance-entity.ts +20 -0
  236. package/src/types/trace-entity.ts +14 -0
  237. package/src/types/underlay-entity.ts +35 -0
  238. package/src/types/wipeout-entity.ts +20 -0
  239. package/src/types/xline-entity.ts +12 -0
  240. package/src/util/escapeXmlText.ts +10 -0
  241. package/tools/browser_test_server.cjs +87 -0
  242. package/tools/ezdxf_generate_dimensions_all_types.py +246 -0
  243. package/tools/ezdxf_generate_dimensions_angular_3p.py +59 -0
  244. package/tools/ezdxf_generate_dimensions_large_scale.py +87 -0
  245. package/tools/ezdxf_regenerate_problem_fixtures.py +184 -0
  246. package/tools/ezdxf_validate_fixtures.py +165 -0
  247. package/docs/DIMENSION_SUMMARY.md +0 -248
  248. package/docs/DIMENSION_SUMMARY.pt-BR.md +0 -248
  249. package/docs/IMPLEMENTED-2D-ENTITIES.md +0 -54
  250. package/docs/IMPLEMENTED-2D-ENTITIES.pt-BR.md +0 -54
  251. package/docs/TEXT-MTEXT-DIMENSION-SUPPORT.md +0 -241
  252. package/docs/TEXT-MTEXT-DIMENSION-SUPPORT.pt-BR.md +0 -169
@@ -1,4 +1,16 @@
1
- import type { DXFTuple, DimStyleInternal, LTypeElement, LTypeInternal, LayerInternal, StyleInternal, VPortInternal } from '../types'
1
+ import type {
2
+ AppIdInternal,
3
+ BlockRecordInternal,
4
+ DXFTuple,
5
+ DimStyleInternal,
6
+ LTypeElement,
7
+ LTypeInternal,
8
+ LayerInternal,
9
+ StyleInternal,
10
+ UcsInternal,
11
+ VPortInternal,
12
+ ViewInternal,
13
+ } from '../types'
2
14
 
3
15
  import logger from '../util/logger'
4
16
 
@@ -6,7 +18,7 @@ const ltypeHandler = (tuples: DXFTuple[]): LTypeInternal => {
6
18
  let element: LTypeElement | undefined
7
19
  let offset: { x: string | number; y: string | number } | undefined
8
20
  return tuples.reduce(
9
- (layer, tuple) => {
21
+ (layer, tuple) => { // NOSONAR
10
22
  const type = tuple[0]
11
23
  const value = tuple[1]
12
24
  // https://documentation.help/AutoCAD-DXF/WS1a9193826455f5ff18cb41610ec0a2e719-7a4f.htm
@@ -172,7 +184,7 @@ const vPortHandler = (tuples: DXFTuple[]): VPortInternal => {
172
184
  (vport, tuple) => {
173
185
  const type = tuple[0]
174
186
  const value = tuple[1]
175
- switch (type) {
187
+ switch (type) { // NOSONAR
176
188
  case 2:
177
189
  vport.name = value
178
190
  break
@@ -287,12 +299,100 @@ const vPortHandler = (tuples: DXFTuple[]): VPortInternal => {
287
299
  )
288
300
  }
289
301
 
302
+ const appIdHandler = (tuples: DXFTuple[]): AppIdInternal => {
303
+ return tuples.reduce(
304
+ (appId, tuple) => {
305
+ const type = tuple[0]
306
+ const value = tuple[1]
307
+
308
+ switch (type) {
309
+ case 2:
310
+ appId.name = value
311
+ break
312
+ case 70:
313
+ appId.flags = value
314
+ break
315
+ default:
316
+ }
317
+
318
+ return appId
319
+ },
320
+ { type: 'APPID' } as AppIdInternal,
321
+ )
322
+ }
323
+
324
+ const blockRecordHandler = (tuples: DXFTuple[]): BlockRecordInternal => {
325
+ return tuples.reduce(
326
+ (blockRecord, tuple) => {
327
+ const type = tuple[0]
328
+ const value = tuple[1]
329
+
330
+ switch (type) {
331
+ case 2:
332
+ blockRecord.name = value
333
+ break
334
+ case 70:
335
+ blockRecord.flags = value
336
+ break
337
+ default:
338
+ }
339
+
340
+ return blockRecord
341
+ },
342
+ { type: 'BLOCK_RECORD' } as BlockRecordInternal,
343
+ )
344
+ }
345
+
346
+ const ucsHandler = (tuples: DXFTuple[]): UcsInternal => {
347
+ return tuples.reduce(
348
+ (ucs, tuple) => {
349
+ const type = tuple[0]
350
+ const value = tuple[1]
351
+
352
+ switch (type) {
353
+ case 2:
354
+ ucs.name = value
355
+ break
356
+ case 70:
357
+ ucs.flags = value
358
+ break
359
+ default:
360
+ }
361
+
362
+ return ucs
363
+ },
364
+ { type: 'UCS' } as UcsInternal,
365
+ )
366
+ }
367
+
368
+ const viewHandler = (tuples: DXFTuple[]): ViewInternal => {
369
+ return tuples.reduce(
370
+ (view, tuple) => {
371
+ const type = tuple[0]
372
+ const value = tuple[1]
373
+
374
+ switch (type) {
375
+ case 2:
376
+ view.name = value
377
+ break
378
+ case 70:
379
+ view.flags = value
380
+ break
381
+ default:
382
+ }
383
+
384
+ return view
385
+ },
386
+ { type: 'VIEW' } as ViewInternal,
387
+ )
388
+ }
389
+
290
390
  const dimStyleHandler = (tuples: DXFTuple[]): DimStyleInternal => {
291
391
  return tuples.reduce(
292
392
  (dimStyle, tuple) => {
293
393
  const type = tuple[0]
294
394
  const value = tuple[1]
295
- switch (type) {
395
+ switch (type) { // NOSONAR
296
396
  case 2:
297
397
  dimStyle.name = value
298
398
  break
@@ -508,7 +608,18 @@ const dimStyleHandler = (tuples: DXFTuple[]): DimStyleInternal => {
508
608
  const tableHandler = (
509
609
  tuples: DXFTuple[],
510
610
  tableType: string,
511
- handler: (tuples: DXFTuple[]) => LTypeInternal | LayerInternal | StyleInternal | VPortInternal | DimStyleInternal,
611
+ handler: (
612
+ tuples: DXFTuple[],
613
+ ) =>
614
+ | LTypeInternal
615
+ | LayerInternal
616
+ | StyleInternal
617
+ | VPortInternal
618
+ | DimStyleInternal
619
+ | AppIdInternal
620
+ | BlockRecordInternal
621
+ | UcsInternal
622
+ | ViewInternal,
512
623
  ): Record<string, any> => {
513
624
  const tableRowsTuples: DXFTuple[][] = []
514
625
 
@@ -552,30 +663,32 @@ export default function parseTables(tuples: DXFTuple[]) {
552
663
  }
553
664
  }
554
665
 
555
- let stylesTuples: DXFTuple[] = []
556
- let layersTuples: DXFTuple[] = []
557
- let vPortTuples: DXFTuple[] = []
558
- let ltypeTuples: DXFTuple[] = []
559
- let dimStyleTuples: DXFTuple[] = []
666
+ const groupsByName: Record<string, DXFTuple[]> = {}
560
667
  for (const group of tableGroups) {
561
- if (group[0]?.[1] === 'STYLE') {
562
- stylesTuples = group
563
- } else if (group[0]?.[1] === 'LTYPE') {
564
- ltypeTuples = group
565
- } else if (group[0]?.[1] === 'LAYER') {
566
- layersTuples = group
567
- } else if (group[0]?.[1] === 'VPORT') {
568
- vPortTuples = group
569
- } else if (group[0]?.[1] === 'DIMSTYLE') {
570
- dimStyleTuples = group
571
- }
668
+ const name = String(group[0]?.[1] ?? '')
669
+ if (!name) continue
670
+ groupsByName[name] = group
572
671
  }
573
672
 
673
+ const stylesTuples = groupsByName.STYLE ?? []
674
+ const layersTuples = groupsByName.LAYER ?? []
675
+ const vPortTuples = groupsByName.VPORT ?? []
676
+ const ltypeTuples = groupsByName.LTYPE ?? []
677
+ const dimStyleTuples = groupsByName.DIMSTYLE ?? []
678
+ const appIdTuples = groupsByName.APPID ?? []
679
+ const blockRecordTuples = groupsByName.BLOCK_RECORD ?? []
680
+ const ucsTuples = groupsByName.UCS ?? []
681
+ const viewTuples = groupsByName.VIEW ?? []
682
+
574
683
  return {
575
684
  layers: tableHandler(layersTuples, 'LAYER', layerHandler),
576
685
  styles: tableHandler(stylesTuples, 'STYLE', styleHandler),
577
686
  vports: tableHandler(vPortTuples, 'VPORT', vPortHandler),
578
687
  ltypes: tableHandler(ltypeTuples, 'LTYPE', ltypeHandler),
579
688
  dimStyles: tableHandler(dimStyleTuples, 'DIMSTYLE', dimStyleHandler),
689
+ appids: tableHandler(appIdTuples, 'APPID', appIdHandler),
690
+ blockRecords: tableHandler(blockRecordTuples, 'BLOCK_RECORD', blockRecordHandler),
691
+ ucs: tableHandler(ucsTuples, 'UCS', ucsHandler),
692
+ views: tableHandler(viewTuples, 'VIEW', viewHandler),
580
693
  }
581
694
  }
package/src/index.ts CHANGED
@@ -1,19 +1,10 @@
1
- import config from './config'
2
- import parseString from './parseString'
3
- import denormalise from './denormalise'
4
- import groupEntitiesByLayer from './groupEntitiesByLayer'
5
- import toPolylines from './toPolylines'
6
- import toSVG from './toSVG'
7
- import colors from './util/colors'
8
- import Helper from './Helper'
1
+ export { default as config } from './config'
2
+ export { default as denormalise } from './denormalise'
3
+ export { default as groupEntitiesByLayer } from './groupEntitiesByLayer'
4
+ export { default as Helper } from './Helper'
5
+ export { default as parseString } from './parseString'
6
+ export { default as toJson } from './toJson'
7
+ export { default as toPolylines } from './toPolylines'
8
+ export { default as toSVG } from './toSVG'
9
+ export { default as colors } from './util/colors'
9
10
 
10
- export {
11
- config,
12
- parseString,
13
- denormalise,
14
- groupEntitiesByLayer,
15
- toPolylines,
16
- toSVG,
17
- colors,
18
- Helper,
19
- }
package/src/toJson.ts ADDED
@@ -0,0 +1,8 @@
1
+ import type { ParsedDXF, ToJsonOptions } from './types'
2
+
3
+ export default function toJson(parsed: ParsedDXF, options: ToJsonOptions = {}): string {
4
+ const shouldPrettyPrint = options.pretty === true
5
+ const indentation = shouldPrettyPrint ? (options.space ?? 2) : undefined
6
+
7
+ return JSON.stringify(parsed, null, indentation)
8
+ }
package/src/toSVG.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import { Box2 } from 'vecks'
2
2
 
3
3
  import denormalise from './denormalise'
4
- import dimensionToSVG from './dimensionToSVG'
4
+ import dimensionToSVG, { getDimensionGeometryBBox } from './dimensionToSVG'
5
5
  import entityToPolyline from './entityToPolyline'
6
6
  import getRGBForEntity from './getRGBForEntity'
7
+ import escapeXmlText from './util/escapeXmlText'
7
8
  import logger from './util/logger'
8
9
  import rgbToColorAttribute from './util/rgbToColorAttribute'
9
10
  import rotate from './util/rotate'
@@ -16,10 +17,14 @@ import type {
16
17
  DimensionEntity,
17
18
  EllipseEntity,
18
19
  Entity,
20
+ LeaderEntity,
19
21
  MTextEntity,
20
22
  ParsedDXF,
23
+ ShapeEntity,
21
24
  SplineEntity,
22
25
  TextEntity,
26
+ ToleranceEntity,
27
+ ToSVGOptions,
23
28
  } from './types'
24
29
  import type { BoundsAndElement } from './types/svg'
25
30
 
@@ -90,6 +95,26 @@ const lwpolyline = (entity: Entity): BoundsAndElement => {
90
95
  )
91
96
  }
92
97
 
98
+ const leader = (entity: LeaderEntity): BoundsAndElement | null => {
99
+ if (!entity.vertices || entity.vertices.length < 2) return null
100
+
101
+ const bbox0 = entity.vertices.reduce(
102
+ (acc, p) => acc.expandByPoint({ x: p.x, y: p.y }),
103
+ new Box2(),
104
+ )
105
+ const d = entity.vertices.reduce((acc, p, i) => {
106
+ acc += i === 0 ? 'M' : 'L'
107
+ acc += p.x + ',' + p.y
108
+ return acc
109
+ }, '')
110
+
111
+ return transformBoundingBoxAndElement(
112
+ bbox0,
113
+ `<path d="${d}" />`,
114
+ entity.transforms ?? [],
115
+ )
116
+ }
117
+
93
118
 
94
119
  /**
95
120
  * Create a <circle /> element for the CIRCLE entity.
@@ -311,7 +336,7 @@ const text = (entity: TextEntity): BoundsAndElement => {
311
336
  .expandByPoint({ x: x + textWidth, y: y + height })
312
337
 
313
338
  const rotationDegrees = (rotation * 180) / Math.PI
314
- const element0 = `<text x="${x}" y="${y}" font-size="${height}" transform="rotate(${-rotationDegrees} ${x} ${y}) scale(1,-1) translate(0 ${-2 * y})">${content}</text>`
339
+ const element0 = `<text x="${x}" y="${y}" font-size="${height}" transform="rotate(${-rotationDegrees} ${x} ${y}) scale(1,-1) translate(0 ${-2 * y})">${escapeXmlText(content)}</text>`
315
340
 
316
341
  const { bbox, element } = addFlipXIfApplicable(entity, {
317
342
  bbox: bbox0,
@@ -340,8 +365,62 @@ const mtext = (entity: MTextEntity): BoundsAndElement => {
340
365
  ? Math.atan2(entity.xAxisY, entity.xAxisX)
341
366
  : 0
342
367
  const rotationDegrees = (rotation * 180) / Math.PI
368
+ const element0 = `<text x="${x}" y="${y}" font-size="${height}" transform="rotate(${-rotationDegrees} ${x} ${y}) scale(1,-1) translate(0 ${-2 * y})">${escapeXmlText(content)}</text>`
369
+
370
+ const { bbox, element } = addFlipXIfApplicable(entity, {
371
+ bbox: bbox0,
372
+ element: element0,
373
+ })
374
+ return transformBoundingBoxAndElement(bbox, element, entity.transforms ?? [])
375
+ }
376
+
377
+ /**
378
+ * Minimal <text /> fallback for TOLERANCE entities.
379
+ * DXF uses special control codes; we preserve the raw string.
380
+ */
381
+ const tolerance = (entity: ToleranceEntity): BoundsAndElement => {
382
+ const x = entity.insertionPoint?.x ?? 0
383
+ const y = entity.insertionPoint?.y ?? 0
384
+ const height = 1
385
+ const content = entity.text ?? ''
386
+
387
+ const rotation = entity.xAxisDirection
388
+ ? Math.atan2(entity.xAxisDirection.y, entity.xAxisDirection.x)
389
+ : 0
390
+ const rotationDegrees = (rotation * 180) / Math.PI
391
+
392
+ const textWidth = content.length * height * 0.6
393
+ const bbox0 = new Box2()
394
+ .expandByPoint({ x, y })
395
+ .expandByPoint({ x: x + textWidth, y: y + height })
396
+
397
+ const element0 = `<text x="${x}" y="${y}" font-size="${height}" transform="rotate(${-rotationDegrees} ${x} ${y}) scale(1,-1) translate(0 ${-2 * y})">${escapeXmlText(content)}</text>`
398
+
399
+ const { bbox, element } = addFlipXIfApplicable(entity, {
400
+ bbox: bbox0,
401
+ element: element0,
402
+ })
403
+ return transformBoundingBoxAndElement(bbox, element, entity.transforms ?? [])
404
+ }
405
+
406
+ /**
407
+ * Minimal <text /> fallback for SHAPE entities.
408
+ * Rendering SHX-based shapes is out of scope; we render the name as text.
409
+ */
410
+ const shape = (entity: ShapeEntity): BoundsAndElement => {
411
+ const x = entity.insertionPoint?.x ?? 0
412
+ const y = entity.insertionPoint?.y ?? 0
413
+ const height = entity.size ?? 1
414
+ const rotation = entity.rotation ?? 0
415
+ const content = entity.name ?? ''
416
+
417
+ const textWidth = content.length * height * 0.6
418
+ const bbox0 = new Box2()
419
+ .expandByPoint({ x, y })
420
+ .expandByPoint({ x: x + textWidth, y: y + height })
343
421
 
344
- const element0 = `<text x="${x}" y="${y}" font-size="${height}" transform="rotate(${-rotationDegrees} ${x} ${y}) scale(1,-1) translate(0 ${-2 * y})">${content}</text>`
422
+ const rotationDegrees = (rotation * 180) / Math.PI
423
+ const element0 = `<text x="${x}" y="${y}" font-size="${height}" transform="rotate(${-rotationDegrees} ${x} ${y}) scale(1,-1) translate(0 ${-2 * y})">${escapeXmlText(content)}</text>`
345
424
 
346
425
  const { bbox, element } = addFlipXIfApplicable(entity, {
347
426
  bbox: bbox0,
@@ -356,8 +435,10 @@ const mtext = (entity: MTextEntity): BoundsAndElement => {
356
435
  const dimension = (
357
436
  entity: DimensionEntity,
358
437
  dimStyle?: any,
438
+ options?: ToSVGOptions,
439
+ viewport?: { width: number; height: number },
359
440
  ): BoundsAndElement => {
360
- const result = dimensionToSVG(entity, dimStyle)
441
+ const result = dimensionToSVG(entity, dimStyle, options, viewport)
361
442
  return transformBoundingBoxAndElement(
362
443
  result.bbox,
363
444
  result.element,
@@ -410,6 +491,8 @@ const bezier = (entity: SplineEntity): BoundsAndElement => {
410
491
  const entityToBoundsAndElement = (
411
492
  entity: Entity,
412
493
  dimStyles?: { [name: string]: any },
494
+ options?: ToSVGOptions,
495
+ viewport?: { width: number; height: number },
413
496
  ): BoundsAndElement | null => {
414
497
  switch (entity.type) {
415
498
  case 'CIRCLE':
@@ -430,7 +513,7 @@ const entityToBoundsAndElement = (
430
513
  const dimStyle = styleName && dimStyles
431
514
  ? dimStyles[styleName]
432
515
  : undefined
433
- return dimension(dimEntity, dimStyle)
516
+ return dimension(dimEntity, dimStyle, options, viewport)
434
517
  }
435
518
  case 'SPLINE': {
436
519
  const splineEntity = entity as SplineEntity
@@ -448,28 +531,75 @@ const entityToBoundsAndElement = (
448
531
  }
449
532
  }
450
533
  case 'LINE':
534
+ case 'RAY':
535
+ case 'XLINE':
451
536
  case 'POLYLINE': {
452
537
  return polyline(entity)
453
538
  }
539
+ case 'SOLID':
540
+ case 'TRACE': {
541
+ return polyline(entity)
542
+ }
454
543
  case 'LWPOLYLINE': {
455
544
  return lwpolyline(entity)
456
545
  }
546
+ case 'WIPEOUT': {
547
+ return polyline(entity)
548
+ }
549
+ case 'LEADER': {
550
+ return leader(entity as LeaderEntity)
551
+ }
552
+ case 'TOLERANCE': {
553
+ return tolerance(entity as ToleranceEntity)
554
+ }
555
+ case 'SHAPE': {
556
+ return shape(entity as ShapeEntity)
557
+ }
457
558
  default:
458
559
  logger.warn('entity type not supported in SVG rendering:', entity.type)
459
560
  return null
460
561
  }
461
562
  }
462
563
 
463
- export default function toSVG(parsed: ParsedDXF): string {
564
+ export default function toSVG(parsed: ParsedDXF, options: ToSVGOptions = {}): string {
464
565
  const entities = denormalise(parsed)
465
566
  const dimStyles = parsed.tables.dimStyles
567
+
568
+ const geometryBBox = entities.reduce((acc: Box2, entity: Entity): Box2 => {
569
+ if (entity.type === 'DIMENSION') {
570
+ const bbox = getDimensionGeometryBBox(entity as DimensionEntity)
571
+ if (bbox.valid) {
572
+ acc.expandByPoint(bbox.min)
573
+ acc.expandByPoint(bbox.max)
574
+ }
575
+ return acc
576
+ }
577
+
578
+ const boundsAndElement = entityToBoundsAndElement(entity, dimStyles, options)
579
+ if (boundsAndElement?.bbox.valid) {
580
+ acc.expandByPoint(boundsAndElement.bbox.min)
581
+ acc.expandByPoint(boundsAndElement.bbox.max)
582
+ }
583
+ return acc
584
+ }, new Box2())
585
+
586
+ const viewport = geometryBBox.valid
587
+ ? {
588
+ width: geometryBBox.max.x - geometryBBox.min.x,
589
+ height: geometryBBox.max.y - geometryBBox.min.y,
590
+ }
591
+ : {
592
+ width: 0,
593
+ height: 0,
594
+ }
595
+
466
596
  const { bbox, elements } = entities.reduce(
467
597
  (
468
598
  acc: { bbox: Box2; elements: string[] },
469
599
  entity: Entity,
470
600
  ): { bbox: Box2; elements: string[] } => {
471
601
  const rgb = getRGBForEntity(parsed.tables.layers, entity)
472
- const boundsAndElement = entityToBoundsAndElement(entity, dimStyles)
602
+ const boundsAndElement = entityToBoundsAndElement(entity, dimStyles, options, viewport)
473
603
  // Ignore entities that don't produce SVG elements or have unsupported types
474
604
  if (boundsAndElement) {
475
605
  const { bbox, element } = boundsAndElement
@@ -478,9 +608,12 @@ export default function toSVG(parsed: ParsedDXF): string {
478
608
  acc.bbox.expandByPoint(bbox.min)
479
609
  acc.bbox.expandByPoint(bbox.max)
480
610
  }
481
- acc.elements.push(
482
- `<g stroke="${rgbToColorAttribute(rgb)}">${element}</g>`,
483
- )
611
+ const color = rgbToColorAttribute(rgb)
612
+ if (entity.type === 'SOLID' || entity.type === 'TRACE') {
613
+ acc.elements.push(`<g fill="${color}" stroke="none">${element}</g>`)
614
+ } else {
615
+ acc.elements.push(`<g stroke="${color}">${element}</g>`)
616
+ }
484
617
  }
485
618
  return acc
486
619
  },
@@ -7,6 +7,17 @@ export interface DimensionEntity extends BaseEntity {
7
7
  type: 'DIMENSION'
8
8
  block?: string
9
9
  start: Point3D
10
+ /**
11
+ * Angular vertex for DIMENSION type 5 (Angular 3-point).
12
+ * This is parsed from group codes 15/25/35.
13
+ */
14
+ angleVertex?: Point3D
15
+
16
+ /**
17
+ * Angular arc location point for DIMENSION angular types.
18
+ * This is parsed from group codes 16/26/36 (OCS in the DXF reference).
19
+ */
20
+ arcPoint?: Point3D
10
21
  measureStart: Point3D
11
22
  measureEnd: Point3D
12
23
  textMidpoint: Point3D
@@ -6,14 +6,28 @@ import type { CircleEntity } from './circle-entity'
6
6
  import type { DimensionEntity } from './dimension-entity'
7
7
  import type { EllipseEntity } from './ellipse-entity'
8
8
  import type { HatchEntity } from './hatch-entity'
9
+ import type { ImageEntity } from './image-entity'
9
10
  import type { InsertEntity } from './insert-entity'
11
+ import type { LeaderEntity } from './leader-entity'
10
12
  import type { LineEntity } from './line-entity'
13
+ import type { MLeaderEntity } from './mleader-entity'
14
+ import type { MLineEntity } from './mline-entity'
11
15
  import type { MTextEntity } from './mtext-entity'
16
+ import type { OleFrameEntity } from './oleframe-entity'
12
17
  import type { PointEntity } from './point-entity'
13
18
  import type { PolylineEntity } from './polyline-entity'
19
+ import type { RayEntity } from './ray-entity'
20
+ import type { RegionEntity } from './region-entity'
21
+ import type { ShapeEntity } from './shape-entity'
14
22
  import type { SolidEntity } from './solid-entity'
15
23
  import type { SplineEntity } from './spline-entity'
24
+ import type { TableEntity } from './table-entity'
16
25
  import type { TextEntity } from './text-entity'
26
+ import type { ToleranceEntity } from './tolerance-entity'
27
+ import type { TraceEntity } from './trace-entity'
28
+ import type { DgnUnderlayEntity, DwfUnderlayEntity, PdfUnderlayEntity } from './underlay-entity'
29
+ import type { WipeoutEntity } from './wipeout-entity'
30
+ import type { XLineEntity } from './xline-entity'
17
31
 
18
32
  export type Entity =
19
33
  | LineEntity
@@ -25,8 +39,24 @@ export type Entity =
25
39
  | PointEntity
26
40
  | PolylineEntity
27
41
  | SplineEntity
42
+ | TableEntity
28
43
  | DimensionEntity
29
44
  | SolidEntity
45
+ | TraceEntity
30
46
  | InsertEntity
47
+ | ImageEntity
48
+ | LeaderEntity
49
+ | MLineEntity
50
+ | MLeaderEntity
51
+ | ToleranceEntity
52
+ | DwfUnderlayEntity
53
+ | DgnUnderlayEntity
54
+ | PdfUnderlayEntity
31
55
  | HatchEntity
32
56
  | BaseEntity
57
+ | OleFrameEntity
58
+ | RayEntity
59
+ | RegionEntity
60
+ | ShapeEntity
61
+ | WipeoutEntity
62
+ | XLineEntity
@@ -2,11 +2,12 @@
2
2
 
3
3
  import type { ParsedDXF } from './dxf'
4
4
  import type { Entity } from './entity'
5
- import type { ToPolylinesOptions, ToSVGOptions } from './options'
5
+ import type { ToJsonOptions, ToPolylinesOptions, ToSVGOptions } from './options'
6
6
 
7
7
  export interface HelperInterface {
8
8
  parsed: ParsedDXF
9
9
  denormalised: Entity[]
10
10
  toSVG(options?: ToSVGOptions): string
11
+ toJson(options?: ToJsonOptions): string
11
12
  toPolylines(options?: ToPolylinesOptions): any[]
12
13
  }
@@ -0,0 +1,35 @@
1
+ // IMAGE entity type
2
+
3
+ import type { BaseEntity } from './base-entity'
4
+ import type { Point3D } from './common'
5
+
6
+ export interface ImageEntity extends BaseEntity {
7
+ type: 'IMAGE'
8
+
9
+ insertionPoint: Point3D
10
+ uVector: Point3D
11
+ vVector: Point3D
12
+
13
+ /** Image size in pixels. */
14
+ pixelSizeX: number
15
+ pixelSizeY: number
16
+
17
+ /** Hard reference to IMAGEDEF object. */
18
+ imageDefHandle?: string
19
+
20
+ /** Hard reference to IMAGEDEF_REACTOR object. */
21
+ imageDefReactorHandle?: string
22
+
23
+ /** Image display properties bitmask. */
24
+ displayProperties?: number
25
+
26
+ /** Clipping state: 0 = Off; 1 = On. */
27
+ clippingState?: number
28
+
29
+ brightness?: number
30
+ contrast?: number
31
+ fade?: number
32
+
33
+ /** DXF class version. */
34
+ classVersion?: number
35
+ }
@@ -12,16 +12,30 @@ export * from './circle-entity'
12
12
  export * from './dimension-entity'
13
13
  export * from './ellipse-entity'
14
14
  export * from './hatch-entity'
15
+ export * from './image-entity'
15
16
  export * from './insert-entity'
17
+ export * from './leader-entity'
16
18
  export * from './line-entity'
19
+ export * from './mleader-entity'
20
+ export * from './mline-entity'
17
21
  export * from './mtext-entity'
18
22
  export * from './ole2frame-entity'
23
+ export * from './oleframe-entity'
19
24
  export * from './point-entity'
20
25
  export * from './polyline-entity'
26
+ export * from './ray-entity'
27
+ export * from './region-entity'
28
+ export * from './shape-entity'
21
29
  export * from './solid-entity'
22
30
  export * from './spline-entity'
31
+ export * from './table-entity'
23
32
  export * from './text-entity'
33
+ export * from './tolerance-entity'
34
+ export * from './trace-entity'
35
+ export * from './underlay-entity'
24
36
  export * from './viewport-entity'
37
+ export * from './wipeout-entity'
38
+ export * from './xline-entity'
25
39
 
26
40
  // Union type
27
41
  export * from './entity'
@@ -0,0 +1,40 @@
1
+ // LEADER entity type
2
+
3
+ import type { BaseEntity } from './base-entity'
4
+ import type { Point3D } from './common'
5
+
6
+ export interface LeaderEntity extends BaseEntity {
7
+ type: 'LEADER'
8
+
9
+ /** Leader vertices, in drawing coordinates. */
10
+ vertices: Point3D[]
11
+
12
+ /** Dimension style name. */
13
+ dimensionStyleName?: string
14
+
15
+ /** Arrowhead flag: 0 = Disabled; 1 = Enabled. */
16
+ arrowheadFlag?: number
17
+
18
+ /** Leader path type: 0 = Straight line segments; 1 = Spline. */
19
+ pathType?: number
20
+
21
+ /** Leader creation flag: 0 = text; 1 = tolerance; 2 = insert; 3 = none. */
22
+ creationFlag?: number
23
+
24
+ hooklineDirectionFlag?: number
25
+ hooklineFlag?: number
26
+
27
+ textHeight?: number
28
+ textWidth?: number
29
+
30
+ /** Color to use if leader's DIMCLR D = BYBLOCK. */
31
+ color?: number
32
+
33
+ /** Hard reference to associated annotation entity. */
34
+ annotationHandle?: string
35
+
36
+ normal?: Point3D
37
+ horizontalDirection?: Point3D
38
+ blockOffset?: Point3D
39
+ annotationOffset?: Point3D
40
+ }