@graphty/graph-io 0.3.42 → 0.3.44
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/dist/chunks/approximations-3Q4TsdTh.js +40 -0
- package/dist/chunks/approximations-3Q4TsdTh.js.map +1 -0
- package/dist/chunks/block-JQiwViEt.js +2777 -0
- package/dist/chunks/block-JQiwViEt.js.map +1 -0
- package/dist/chunks/{choose-DvpbdRuz.js → choose-BemygfH8.js} +3 -2
- package/dist/chunks/{choose-DvpbdRuz.js.map → choose-BemygfH8.js.map} +1 -1
- package/dist/chunks/{constants-fT3E8JYY.js → constants-BFUR_CtU.js} +6 -2
- package/dist/chunks/constants-BFUR_CtU.js.map +1 -0
- package/dist/chunks/convert-BcQ8_jMo.js +59 -0
- package/dist/chunks/convert-BcQ8_jMo.js.map +1 -0
- package/dist/chunks/emit-DCwFLts5.js +3456 -0
- package/dist/chunks/emit-DCwFLts5.js.map +1 -0
- package/dist/chunks/{escape-B62ZGM_a.js → escape-B1rMftd9.js} +43 -20
- package/dist/chunks/escape-B1rMftd9.js.map +1 -0
- package/dist/chunks/{export-rKLeGQMo.js → export-D7IGzTG4.js} +196 -792
- package/dist/chunks/export-D7IGzTG4.js.map +1 -0
- package/dist/chunks/{exporter-BWwEuOPT.js → exporter-BtnqYuuj.js} +22 -12
- package/dist/chunks/exporter-BtnqYuuj.js.map +1 -0
- package/dist/chunks/{exporter-yLxKBvLE.js → exporter-ChPyhBOv.js} +4 -3
- package/dist/chunks/{exporter-yLxKBvLE.js.map → exporter-ChPyhBOv.js.map} +1 -1
- package/dist/chunks/{exporter-8hLNemFk.js → exporter-KEPxYUXD.js} +133 -74
- package/dist/chunks/exporter-KEPxYUXD.js.map +1 -0
- package/dist/chunks/{exporter-CpRyHZ3H.js → exporter-quPUCBiC.js} +1807 -288
- package/dist/chunks/exporter-quPUCBiC.js.map +1 -0
- package/dist/chunks/format-GDmO6m6Q.js +676 -0
- package/dist/chunks/format-GDmO6m6Q.js.map +1 -0
- package/dist/chunks/generic-BL06jrJf.js +1347 -0
- package/dist/chunks/generic-BL06jrJf.js.map +1 -0
- package/dist/chunks/{importer-WrGRZb0N.js → importer-B7r2owVf.js} +449 -102
- package/dist/chunks/importer-B7r2owVf.js.map +1 -0
- package/dist/chunks/{importer-Ht7LNg8L.js → importer-BFmOP96W.js} +116 -296
- package/dist/chunks/importer-BFmOP96W.js.map +1 -0
- package/dist/chunks/{importer-BbNb7eNg.js → importer-C2nzGhdV.js} +1390 -129
- package/dist/chunks/importer-C2nzGhdV.js.map +1 -0
- package/dist/chunks/{importer-Dz7tI8Sa.js → importer-CbX2_rNF.js} +617 -115
- package/dist/chunks/importer-CbX2_rNF.js.map +1 -0
- package/dist/chunks/{importer-D794XUTe.js → importer-CdzeN6X4.js} +31 -8
- package/dist/chunks/importer-CdzeN6X4.js.map +1 -0
- package/dist/chunks/{importer-xZ-3suY1.js → importer-ChKNC_GN.js} +791 -135
- package/dist/chunks/importer-ChKNC_GN.js.map +1 -0
- package/dist/chunks/{importer-C98dpSH4.js → importer-dwoYpSqb.js} +141 -82
- package/dist/chunks/importer-dwoYpSqb.js.map +1 -0
- package/dist/chunks/index-B9fdNpTA.js +4310 -0
- package/dist/chunks/index-B9fdNpTA.js.map +1 -0
- package/dist/chunks/{json-elements-DKSqpNW1.js → json-elements-C4FwgnH5.js} +123 -32
- package/dist/chunks/json-elements-C4FwgnH5.js.map +1 -0
- package/dist/chunks/lexicon-B-knUi-l.js +508 -0
- package/dist/chunks/lexicon-B-knUi-l.js.map +1 -0
- package/dist/chunks/{ontology-export-CtRXjg_i.js → ontology-export-BSpbY5FL.js} +3 -2
- package/dist/chunks/{ontology-export-CtRXjg_i.js.map → ontology-export-BSpbY5FL.js.map} +1 -1
- package/dist/chunks/{records-Cu4bxYOm.js → records-Nwz_rbNt.js} +2 -2
- package/dist/chunks/{records-Cu4bxYOm.js.map → records-Nwz_rbNt.js.map} +1 -1
- package/dist/chunks/styles-Brt9JMfs.js +690 -0
- package/dist/chunks/styles-Brt9JMfs.js.map +1 -0
- package/dist/chunks/styles-_N-C8S-U.js +2102 -0
- package/dist/chunks/styles-_N-C8S-U.js.map +1 -0
- package/dist/chunks/styles-yed-DAfcIkf7.js +842 -0
- package/dist/chunks/styles-yed-DAfcIkf7.js.map +1 -0
- package/dist/chunks/{text-DHOJXnED.js → text-CgzMqHQb.js} +2 -2
- package/dist/chunks/{text-DHOJXnED.js.map → text-CgzMqHQb.js.map} +1 -1
- package/dist/chunks/units-XMZFIFe1.js +19 -0
- package/dist/chunks/units-XMZFIFe1.js.map +1 -0
- package/dist/csv.js +5 -4
- package/dist/csv.js.map +1 -1
- package/dist/cx.js +1 -1
- package/dist/cx2.js +2 -2
- package/dist/cys.js +1 -1
- package/dist/dot.js +5 -2
- package/dist/dot.js.map +1 -1
- package/dist/gexf.js +295 -414
- package/dist/gexf.js.map +1 -1
- package/dist/gml.js +8 -3031
- package/dist/gml.js.map +1 -1
- package/dist/graph-io.js +354 -240
- package/dist/graph-io.js.map +1 -1
- package/dist/graphml.js +4 -2
- package/dist/graphml.js.map +1 -1
- package/dist/json.js +1 -1
- package/dist/neo4j.js +4 -3
- package/dist/neo4j.js.map +1 -1
- package/dist/obo.js +1 -1
- package/dist/pajek.js +4 -2
- package/dist/positions.d.ts +1 -0
- package/dist/positions.js +427 -0
- package/dist/positions.js.map +1 -0
- package/dist/src/common/codes.d.ts +6 -0
- package/dist/src/common/codes.d.ts.map +1 -1
- package/dist/src/common/codes.js +6 -0
- package/dist/src/common/codes.js.map +1 -1
- package/dist/src/common/escape.d.ts.map +1 -1
- package/dist/src/common/escape.js +4 -2
- package/dist/src/common/escape.js.map +1 -1
- package/dist/src/common/export.d.ts +10 -0
- package/dist/src/common/export.d.ts.map +1 -1
- package/dist/src/common/export.js +123 -100
- package/dist/src/common/export.js.map +1 -1
- package/dist/src/common/input.d.ts.map +1 -1
- package/dist/src/common/input.js +8 -1
- package/dist/src/common/input.js.map +1 -1
- package/dist/src/common/json-elements.d.ts +12 -9
- package/dist/src/common/json-elements.d.ts.map +1 -1
- package/dist/src/common/json-elements.js +160 -37
- package/dist/src/common/json-elements.js.map +1 -1
- package/dist/src/common/notes.d.ts +42 -0
- package/dist/src/common/notes.d.ts.map +1 -0
- package/dist/src/common/notes.js +72 -0
- package/dist/src/common/notes.js.map +1 -0
- package/dist/src/common/report.d.ts +18 -0
- package/dist/src/common/report.d.ts.map +1 -1
- package/dist/src/common/report.js +36 -1
- package/dist/src/common/report.js.map +1 -1
- package/dist/src/common/units.d.ts +24 -0
- package/dist/src/common/units.d.ts.map +1 -0
- package/dist/src/common/units.js +26 -0
- package/dist/src/common/units.js.map +1 -0
- package/dist/src/common/xml.d.ts +18 -0
- package/dist/src/common/xml.d.ts.map +1 -1
- package/dist/src/common/xml.js +42 -5
- package/dist/src/common/xml.js.map +1 -1
- package/dist/src/formats/cx/exporter.d.ts +6 -0
- package/dist/src/formats/cx/exporter.d.ts.map +1 -1
- package/dist/src/formats/cx/exporter.js +71 -8
- package/dist/src/formats/cx/exporter.js.map +1 -1
- package/dist/src/formats/cx/importer.d.ts +5 -2
- package/dist/src/formats/cx/importer.d.ts.map +1 -1
- package/dist/src/formats/cx/importer.js +102 -72
- package/dist/src/formats/cx/importer.js.map +1 -1
- package/dist/src/formats/cx/styles.d.ts +102 -0
- package/dist/src/formats/cx/styles.d.ts.map +1 -0
- package/dist/src/formats/cx/styles.js +225 -0
- package/dist/src/formats/cx/styles.js.map +1 -0
- package/dist/src/formats/cx2/exporter.d.ts +5 -0
- package/dist/src/formats/cx2/exporter.d.ts.map +1 -1
- package/dist/src/formats/cx2/exporter.js +181 -71
- package/dist/src/formats/cx2/exporter.js.map +1 -1
- package/dist/src/formats/cx2/importer.d.ts +4 -1
- package/dist/src/formats/cx2/importer.d.ts.map +1 -1
- package/dist/src/formats/cx2/importer.js +19 -1
- package/dist/src/formats/cx2/importer.js.map +1 -1
- package/dist/src/formats/cx2/styles.d.ts +18 -0
- package/dist/src/formats/cx2/styles.d.ts.map +1 -0
- package/dist/src/formats/cx2/styles.js +24 -0
- package/dist/src/formats/cx2/styles.js.map +1 -0
- package/dist/src/formats/cys/constants.d.ts +2 -0
- package/dist/src/formats/cys/constants.d.ts.map +1 -1
- package/dist/src/formats/cys/constants.js +2 -0
- package/dist/src/formats/cys/constants.js.map +1 -1
- package/dist/src/formats/cys/exporter.d.ts +6 -2
- package/dist/src/formats/cys/exporter.d.ts.map +1 -1
- package/dist/src/formats/cys/exporter.js +215 -53
- package/dist/src/formats/cys/exporter.js.map +1 -1
- package/dist/src/formats/cys/importer.d.ts +2 -1
- package/dist/src/formats/cys/importer.d.ts.map +1 -1
- package/dist/src/formats/cys/importer.js +119 -6
- package/dist/src/formats/cys/importer.js.map +1 -1
- package/dist/src/formats/cys/session.d.ts +2 -0
- package/dist/src/formats/cys/session.d.ts.map +1 -1
- package/dist/src/formats/cys/session.js +5 -0
- package/dist/src/formats/cys/session.js.map +1 -1
- package/dist/src/formats/cys/styles.d.ts +38 -0
- package/dist/src/formats/cys/styles.d.ts.map +1 -0
- package/dist/src/formats/cys/styles.js +213 -0
- package/dist/src/formats/cys/styles.js.map +1 -0
- package/dist/src/formats/cys/tables.d.ts +8 -3
- package/dist/src/formats/cys/tables.d.ts.map +1 -1
- package/dist/src/formats/cys/tables.js +88 -34
- package/dist/src/formats/cys/tables.js.map +1 -1
- package/dist/src/formats/dot/exporter.d.ts +2 -0
- package/dist/src/formats/dot/exporter.d.ts.map +1 -1
- package/dist/src/formats/dot/exporter.js +195 -81
- package/dist/src/formats/dot/exporter.js.map +1 -1
- package/dist/src/formats/dot/importer.d.ts.map +1 -1
- package/dist/src/formats/dot/importer.js +100 -20
- package/dist/src/formats/dot/importer.js.map +1 -1
- package/dist/src/formats/dot/index.d.ts +1 -0
- package/dist/src/formats/dot/index.d.ts.map +1 -1
- package/dist/src/formats/dot/index.js +1 -0
- package/dist/src/formats/dot/index.js.map +1 -1
- package/dist/src/formats/dot/positions.d.ts +14 -0
- package/dist/src/formats/dot/positions.d.ts.map +1 -0
- package/dist/src/formats/dot/positions.js +70 -0
- package/dist/src/formats/dot/positions.js.map +1 -0
- package/dist/src/formats/dot/styles.d.ts +82 -0
- package/dist/src/formats/dot/styles.d.ts.map +1 -0
- package/dist/src/formats/dot/styles.js +1484 -0
- package/dist/src/formats/dot/styles.js.map +1 -0
- package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
- package/dist/src/formats/gexf/exporter.js +23 -7
- package/dist/src/formats/gexf/exporter.js.map +1 -1
- package/dist/src/formats/gexf/importer.d.ts +8 -1
- package/dist/src/formats/gexf/importer.d.ts.map +1 -1
- package/dist/src/formats/gexf/importer.js +251 -131
- package/dist/src/formats/gexf/importer.js.map +1 -1
- package/dist/src/formats/gexf/index.d.ts +8 -0
- package/dist/src/formats/gexf/index.d.ts.map +1 -1
- package/dist/src/formats/gexf/index.js +10 -2
- package/dist/src/formats/gexf/index.js.map +1 -1
- package/dist/src/formats/gexf/schema.d.ts +5 -0
- package/dist/src/formats/gexf/schema.d.ts.map +1 -1
- package/dist/src/formats/gexf/schema.js +5 -0
- package/dist/src/formats/gexf/schema.js.map +1 -1
- package/dist/src/formats/gexf/styles.d.ts +74 -0
- package/dist/src/formats/gexf/styles.d.ts.map +1 -0
- package/dist/src/formats/gexf/styles.js +604 -0
- package/dist/src/formats/gexf/styles.js.map +1 -0
- package/dist/src/formats/gml/exporter.d.ts +1 -5
- package/dist/src/formats/gml/exporter.d.ts.map +1 -1
- package/dist/src/formats/gml/exporter.js +19 -8
- package/dist/src/formats/gml/exporter.js.map +1 -1
- package/dist/src/formats/gml/importer.d.ts.map +1 -1
- package/dist/src/formats/gml/importer.js +4 -0
- package/dist/src/formats/gml/importer.js.map +1 -1
- package/dist/src/formats/gml/index.d.ts +2 -1
- package/dist/src/formats/gml/index.d.ts.map +1 -1
- package/dist/src/formats/gml/index.js +2 -1
- package/dist/src/formats/gml/index.js.map +1 -1
- package/dist/src/formats/gml/positions.d.ts +14 -0
- package/dist/src/formats/gml/positions.d.ts.map +1 -0
- package/dist/src/formats/gml/positions.js +46 -0
- package/dist/src/formats/gml/positions.js.map +1 -0
- package/dist/src/formats/gml/styles.d.ts +59 -0
- package/dist/src/formats/gml/styles.d.ts.map +1 -0
- package/dist/src/formats/gml/styles.js +1056 -0
- package/dist/src/formats/gml/styles.js.map +1 -0
- package/dist/src/formats/gml/syntax.d.ts +11 -0
- package/dist/src/formats/gml/syntax.d.ts.map +1 -1
- package/dist/src/formats/gml/syntax.js +151 -62
- package/dist/src/formats/gml/syntax.js.map +1 -1
- package/dist/src/formats/graphml/constants.d.ts +4 -0
- package/dist/src/formats/graphml/constants.d.ts.map +1 -1
- package/dist/src/formats/graphml/constants.js +5 -1
- package/dist/src/formats/graphml/constants.js.map +1 -1
- package/dist/src/formats/graphml/exporter.d.ts.map +1 -1
- package/dist/src/formats/graphml/exporter.js +133 -65
- package/dist/src/formats/graphml/exporter.js.map +1 -1
- package/dist/src/formats/graphml/importer.d.ts +4 -1
- package/dist/src/formats/graphml/importer.d.ts.map +1 -1
- package/dist/src/formats/graphml/importer.js +100 -44
- package/dist/src/formats/graphml/importer.js.map +1 -1
- package/dist/src/formats/graphml/index.d.ts +1 -0
- package/dist/src/formats/graphml/index.d.ts.map +1 -1
- package/dist/src/formats/graphml/index.js +1 -0
- package/dist/src/formats/graphml/index.js.map +1 -1
- package/dist/src/formats/graphml/styles-plain.d.ts +19 -0
- package/dist/src/formats/graphml/styles-plain.d.ts.map +1 -0
- package/dist/src/formats/graphml/styles-plain.js +187 -0
- package/dist/src/formats/graphml/styles-plain.js.map +1 -0
- package/dist/src/formats/graphml/styles-yed.d.ts +179 -0
- package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -0
- package/dist/src/formats/graphml/styles-yed.js +1086 -0
- package/dist/src/formats/graphml/styles-yed.js.map +1 -0
- package/dist/src/formats/graphml/styles-yfiles3.d.ts +19 -0
- package/dist/src/formats/graphml/styles-yfiles3.d.ts.map +1 -0
- package/dist/src/formats/graphml/styles-yfiles3.js +508 -0
- package/dist/src/formats/graphml/styles-yfiles3.js.map +1 -0
- package/dist/src/formats/graphml/tree.d.ts.map +1 -1
- package/dist/src/formats/graphml/tree.js +34 -19
- package/dist/src/formats/graphml/tree.js.map +1 -1
- package/dist/src/formats/graphml/yfiles.d.ts +16 -2
- package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
- package/dist/src/formats/graphml/yfiles.js +83 -12
- package/dist/src/formats/graphml/yfiles.js.map +1 -1
- package/dist/src/formats/json/exporter.d.ts +5 -0
- package/dist/src/formats/json/exporter.d.ts.map +1 -1
- package/dist/src/formats/json/exporter.js +68 -25
- package/dist/src/formats/json/exporter.js.map +1 -1
- package/dist/src/formats/json/importer.d.ts +22 -3
- package/dist/src/formats/json/importer.d.ts.map +1 -1
- package/dist/src/formats/json/importer.js +441 -265
- package/dist/src/formats/json/importer.js.map +1 -1
- package/dist/src/formats/json/positions.d.ts +16 -0
- package/dist/src/formats/json/positions.d.ts.map +1 -0
- package/dist/src/formats/json/positions.js +44 -0
- package/dist/src/formats/json/positions.js.map +1 -0
- package/dist/src/formats/json/styles.d.ts +102 -0
- package/dist/src/formats/json/styles.d.ts.map +1 -0
- package/dist/src/formats/json/styles.js +1753 -0
- package/dist/src/formats/json/styles.js.map +1 -0
- package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
- package/dist/src/formats/neo4j/exporter.js +2 -1
- package/dist/src/formats/neo4j/exporter.js.map +1 -1
- package/dist/src/formats/pajek/exporter.d.ts +2 -0
- package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
- package/dist/src/formats/pajek/exporter.js +142 -76
- package/dist/src/formats/pajek/exporter.js.map +1 -1
- package/dist/src/formats/pajek/importer.d.ts +4 -0
- package/dist/src/formats/pajek/importer.d.ts.map +1 -1
- package/dist/src/formats/pajek/importer.js +60 -6
- package/dist/src/formats/pajek/importer.js.map +1 -1
- package/dist/src/formats/pajek/index.d.ts +2 -0
- package/dist/src/formats/pajek/index.d.ts.map +1 -1
- package/dist/src/formats/pajek/index.js +2 -0
- package/dist/src/formats/pajek/index.js.map +1 -1
- package/dist/src/formats/pajek/styles.d.ts +50 -0
- package/dist/src/formats/pajek/styles.d.ts.map +1 -0
- package/dist/src/formats/pajek/styles.js +569 -0
- package/dist/src/formats/pajek/styles.js.map +1 -0
- package/dist/src/formats/pajek/syntax.d.ts +6 -0
- package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
- package/dist/src/formats/pajek/syntax.js +6 -0
- package/dist/src/formats/pajek/syntax.js.map +1 -1
- package/dist/src/formats/xgmml/columns.d.ts.map +1 -1
- package/dist/src/formats/xgmml/columns.js +34 -9
- package/dist/src/formats/xgmml/columns.js.map +1 -1
- package/dist/src/formats/xgmml/constants.d.ts +2 -0
- package/dist/src/formats/xgmml/constants.d.ts.map +1 -1
- package/dist/src/formats/xgmml/constants.js +3 -1
- package/dist/src/formats/xgmml/constants.js.map +1 -1
- package/dist/src/formats/xgmml/document.d.ts +12 -8
- package/dist/src/formats/xgmml/document.d.ts.map +1 -1
- package/dist/src/formats/xgmml/document.js +56 -13
- package/dist/src/formats/xgmml/document.js.map +1 -1
- package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
- package/dist/src/formats/xgmml/emit.js +12 -6
- package/dist/src/formats/xgmml/emit.js.map +1 -1
- package/dist/src/formats/xgmml/exporter.d.ts +3 -1
- package/dist/src/formats/xgmml/exporter.d.ts.map +1 -1
- package/dist/src/formats/xgmml/exporter.js +22 -9
- package/dist/src/formats/xgmml/exporter.js.map +1 -1
- package/dist/src/formats/xgmml/importer.d.ts +2 -1
- package/dist/src/formats/xgmml/importer.d.ts.map +1 -1
- package/dist/src/formats/xgmml/importer.js +31 -24
- package/dist/src/formats/xgmml/importer.js.map +1 -1
- package/dist/src/formats/xgmml/styles.d.ts +104 -0
- package/dist/src/formats/xgmml/styles.d.ts.map +1 -0
- package/dist/src/formats/xgmml/styles.js +310 -0
- package/dist/src/formats/xgmml/styles.js.map +1 -0
- package/dist/src/index.d.ts +9 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -7
- package/dist/src/index.js.map +1 -1
- package/dist/src/positions/codes.d.ts +31 -0
- package/dist/src/positions/codes.d.ts.map +1 -0
- package/dist/src/positions/codes.js +26 -0
- package/dist/src/positions/codes.js.map +1 -0
- package/dist/src/positions/convert.d.ts +58 -0
- package/dist/src/positions/convert.d.ts.map +1 -0
- package/dist/src/positions/convert.js +107 -0
- package/dist/src/positions/convert.js.map +1 -0
- package/dist/src/positions/extract.d.ts +27 -0
- package/dist/src/positions/extract.d.ts.map +1 -0
- package/dist/src/positions/extract.js +526 -0
- package/dist/src/positions/extract.js.map +1 -0
- package/dist/src/positions/index.d.ts +10 -0
- package/dist/src/positions/index.d.ts.map +1 -0
- package/dist/src/positions/index.js +9 -0
- package/dist/src/positions/index.js.map +1 -0
- package/dist/src/positions/types.d.ts +208 -0
- package/dist/src/positions/types.d.ts.map +1 -0
- package/dist/src/positions/types.js +10 -0
- package/dist/src/positions/types.js.map +1 -0
- package/dist/src/registry.d.ts +30 -0
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js +130 -9
- package/dist/src/registry.js.map +1 -1
- package/dist/src/styles/annotations.d.ts +132 -0
- package/dist/src/styles/annotations.d.ts.map +1 -0
- package/dist/src/styles/annotations.js +320 -0
- package/dist/src/styles/annotations.js.map +1 -0
- package/dist/src/styles/budget.d.ts +45 -0
- package/dist/src/styles/budget.d.ts.map +1 -0
- package/dist/src/styles/budget.js +58 -0
- package/dist/src/styles/budget.js.map +1 -0
- package/dist/src/styles/canon/bends.d.ts +32 -0
- package/dist/src/styles/canon/bends.d.ts.map +1 -0
- package/dist/src/styles/canon/bends.js +74 -0
- package/dist/src/styles/canon/bends.js.map +1 -0
- package/dist/src/styles/canon/color-tables.d.ts +22 -0
- package/dist/src/styles/canon/color-tables.d.ts.map +1 -0
- package/dist/src/styles/canon/color-tables.js +369 -0
- package/dist/src/styles/canon/color-tables.js.map +1 -0
- package/dist/src/styles/canon/color.d.ts +66 -0
- package/dist/src/styles/canon/color.d.ts.map +1 -0
- package/dist/src/styles/canon/color.js +548 -0
- package/dist/src/styles/canon/color.js.map +1 -0
- package/dist/src/styles/canon/enums.d.ts +25 -0
- package/dist/src/styles/canon/enums.d.ts.map +1 -0
- package/dist/src/styles/canon/enums.js +187 -0
- package/dist/src/styles/canon/enums.js.map +1 -0
- package/dist/src/styles/canon/graphviz.d.ts +48 -0
- package/dist/src/styles/canon/graphviz.d.ts.map +1 -0
- package/dist/src/styles/canon/graphviz.js +160 -0
- package/dist/src/styles/canon/graphviz.js.map +1 -0
- package/dist/src/styles/canon/index.d.ts +13 -0
- package/dist/src/styles/canon/index.d.ts.map +1 -0
- package/dist/src/styles/canon/index.js +13 -0
- package/dist/src/styles/canon/index.js.map +1 -0
- package/dist/src/styles/canon/number.d.ts +59 -0
- package/dist/src/styles/canon/number.d.ts.map +1 -0
- package/dist/src/styles/canon/number.js +142 -0
- package/dist/src/styles/canon/number.js.map +1 -0
- package/dist/src/styles/canon/site.d.ts +51 -0
- package/dist/src/styles/canon/site.d.ts.map +1 -0
- package/dist/src/styles/canon/site.js +63 -0
- package/dist/src/styles/canon/site.js.map +1 -0
- package/dist/src/styles/canon/text.d.ts +61 -0
- package/dist/src/styles/canon/text.d.ts.map +1 -0
- package/dist/src/styles/canon/text.js +199 -0
- package/dist/src/styles/canon/text.js.map +1 -0
- package/dist/src/styles/codes.d.ts +95 -0
- package/dist/src/styles/codes.d.ts.map +1 -0
- package/dist/src/styles/codes.js +97 -0
- package/dist/src/styles/codes.js.map +1 -0
- package/dist/src/styles/cyjs/cascade.d.ts +134 -0
- package/dist/src/styles/cyjs/cascade.d.ts.map +1 -0
- package/dist/src/styles/cyjs/cascade.js +2252 -0
- package/dist/src/styles/cyjs/cascade.js.map +1 -0
- package/dist/src/styles/cyjs/defaults-table.d.ts +25 -0
- package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -0
- package/dist/src/styles/cyjs/defaults-table.js +76 -0
- package/dist/src/styles/cyjs/defaults-table.js.map +1 -0
- package/dist/src/styles/cyjs/emit.d.ts +82 -0
- package/dist/src/styles/cyjs/emit.d.ts.map +1 -0
- package/dist/src/styles/cyjs/emit.js +790 -0
- package/dist/src/styles/cyjs/emit.js.map +1 -0
- package/dist/src/styles/cyjs/index.d.ts +13 -0
- package/dist/src/styles/cyjs/index.d.ts.map +1 -0
- package/dist/src/styles/cyjs/index.js +13 -0
- package/dist/src/styles/cyjs/index.js.map +1 -0
- package/dist/src/styles/cyjs/live.d.ts +46 -0
- package/dist/src/styles/cyjs/live.d.ts.map +1 -0
- package/dist/src/styles/cyjs/live.js +108 -0
- package/dist/src/styles/cyjs/live.js.map +1 -0
- package/dist/src/styles/cyjs/mappers.d.ts +147 -0
- package/dist/src/styles/cyjs/mappers.d.ts.map +1 -0
- package/dist/src/styles/cyjs/mappers.js +744 -0
- package/dist/src/styles/cyjs/mappers.js.map +1 -0
- package/dist/src/styles/cyjs/selector.d.ts +113 -0
- package/dist/src/styles/cyjs/selector.d.ts.map +1 -0
- package/dist/src/styles/cyjs/selector.js +611 -0
- package/dist/src/styles/cyjs/selector.js.map +1 -0
- package/dist/src/styles/cyjs/stylesheet-text.d.ts +37 -0
- package/dist/src/styles/cyjs/stylesheet-text.d.ts.map +1 -0
- package/dist/src/styles/cyjs/stylesheet-text.js +181 -0
- package/dist/src/styles/cyjs/stylesheet-text.js.map +1 -0
- package/dist/src/styles/cytoscape/emit.d.ts +125 -0
- package/dist/src/styles/cytoscape/emit.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/emit.js +1025 -0
- package/dist/src/styles/cytoscape/emit.js.map +1 -0
- package/dist/src/styles/cytoscape/index.d.ts +10 -0
- package/dist/src/styles/cytoscape/index.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/index.js +10 -0
- package/dist/src/styles/cytoscape/index.js.map +1 -0
- package/dist/src/styles/cytoscape/lexicon.d.ts +49 -0
- package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/lexicon.js +603 -0
- package/dist/src/styles/cytoscape/lexicon.js.map +1 -0
- package/dist/src/styles/cytoscape/mappings.d.ts +171 -0
- package/dist/src/styles/cytoscape/mappings.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/mappings.js +460 -0
- package/dist/src/styles/cytoscape/mappings.js.map +1 -0
- package/dist/src/styles/cytoscape/resolve.d.ts +137 -0
- package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/resolve.js +381 -0
- package/dist/src/styles/cytoscape/resolve.js.map +1 -0
- package/dist/src/styles/cytoscape/translate.d.ts +50 -0
- package/dist/src/styles/cytoscape/translate.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/translate.js +156 -0
- package/dist/src/styles/cytoscape/translate.js.map +1 -0
- package/dist/src/styles/defaults.d.ts +90 -0
- package/dist/src/styles/defaults.d.ts.map +1 -0
- package/dist/src/styles/defaults.js +414 -0
- package/dist/src/styles/defaults.js.map +1 -0
- package/dist/src/styles/index.d.ts +15 -0
- package/dist/src/styles/index.d.ts.map +1 -0
- package/dist/src/styles/index.js +14 -0
- package/dist/src/styles/index.js.map +1 -0
- package/dist/src/styles/internal.d.ts +17 -0
- package/dist/src/styles/internal.d.ts.map +1 -0
- package/dist/src/styles/internal.js +16 -0
- package/dist/src/styles/internal.js.map +1 -0
- package/dist/src/styles/io/approximations.d.ts +24 -0
- package/dist/src/styles/io/approximations.d.ts.map +1 -0
- package/dist/src/styles/io/approximations.js +51 -0
- package/dist/src/styles/io/approximations.js.map +1 -0
- package/dist/src/styles/io/block.d.ts +166 -0
- package/dist/src/styles/io/block.d.ts.map +1 -0
- package/dist/src/styles/io/block.js +930 -0
- package/dist/src/styles/io/block.js.map +1 -0
- package/dist/src/styles/io/generic.d.ts +88 -0
- package/dist/src/styles/io/generic.d.ts.map +1 -0
- package/dist/src/styles/io/generic.js +516 -0
- package/dist/src/styles/io/generic.js.map +1 -0
- package/dist/src/styles/io/index.d.ts +8 -0
- package/dist/src/styles/io/index.d.ts.map +1 -0
- package/dist/src/styles/io/index.js +7 -0
- package/dist/src/styles/io/index.js.map +1 -0
- package/dist/src/styles/io/writer.d.ts +80 -0
- package/dist/src/styles/io/writer.d.ts.map +1 -0
- package/dist/src/styles/io/writer.js +596 -0
- package/dist/src/styles/io/writer.js.map +1 -0
- package/dist/src/styles/notes.d.ts +47 -0
- package/dist/src/styles/notes.d.ts.map +1 -0
- package/dist/src/styles/notes.js +140 -0
- package/dist/src/styles/notes.js.map +1 -0
- package/dist/src/styles/plan/classes.d.ts +31 -0
- package/dist/src/styles/plan/classes.d.ts.map +1 -0
- package/dist/src/styles/plan/classes.js +139 -0
- package/dist/src/styles/plan/classes.js.map +1 -0
- package/dist/src/styles/plan/continuous.d.ts +32 -0
- package/dist/src/styles/plan/continuous.d.ts.map +1 -0
- package/dist/src/styles/plan/continuous.js +165 -0
- package/dist/src/styles/plan/continuous.js.map +1 -0
- package/dist/src/styles/plan/discrete.d.ts +39 -0
- package/dist/src/styles/plan/discrete.d.ts.map +1 -0
- package/dist/src/styles/plan/discrete.js +127 -0
- package/dist/src/styles/plan/discrete.js.map +1 -0
- package/dist/src/styles/plan/families.d.ts +31 -0
- package/dist/src/styles/plan/families.d.ts.map +1 -0
- package/dist/src/styles/plan/families.js +95 -0
- package/dist/src/styles/plan/families.js.map +1 -0
- package/dist/src/styles/plan/features.d.ts +58 -0
- package/dist/src/styles/plan/features.d.ts.map +1 -0
- package/dist/src/styles/plan/features.js +185 -0
- package/dist/src/styles/plan/features.js.map +1 -0
- package/dist/src/styles/plan/index.d.ts +7 -0
- package/dist/src/styles/plan/index.d.ts.map +1 -0
- package/dist/src/styles/plan/index.js +7 -0
- package/dist/src/styles/plan/index.js.map +1 -0
- package/dist/src/styles/plan/plan.d.ts +71 -0
- package/dist/src/styles/plan/plan.d.ts.map +1 -0
- package/dist/src/styles/plan/plan.js +893 -0
- package/dist/src/styles/plan/plan.js.map +1 -0
- package/dist/src/styles/plan/resolve.d.ts +137 -0
- package/dist/src/styles/plan/resolve.d.ts.map +1 -0
- package/dist/src/styles/plan/resolve.js +587 -0
- package/dist/src/styles/plan/resolve.js.map +1 -0
- package/dist/src/styles/types.d.ts +702 -0
- package/dist/src/styles/types.d.ts.map +1 -0
- package/dist/src/styles/types.js +10 -0
- package/dist/src/styles/types.js.map +1 -0
- package/dist/src/styles/vocabulary.d.ts +41 -0
- package/dist/src/styles/vocabulary.d.ts.map +1 -0
- package/dist/src/styles/vocabulary.js +140 -0
- package/dist/src/styles/vocabulary.js.map +1 -0
- package/dist/src/types.d.ts +64 -1
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/styles.d.ts +1 -0
- package/dist/styles.js +322 -0
- package/dist/styles.js.map +1 -0
- package/dist/xgmml.js +5 -4
- package/dist/xgmml.js.map +1 -1
- package/package.json +13 -2
- package/src/common/codes.ts +7 -0
- package/src/common/escape.ts +5 -2
- package/src/common/export.ts +179 -140
- package/src/common/input.ts +8 -4
- package/src/common/json-elements.ts +169 -38
- package/src/common/notes.ts +94 -0
- package/src/common/report.ts +41 -1
- package/src/common/units.ts +42 -0
- package/src/common/xml.ts +45 -5
- package/src/formats/cx/exporter.ts +95 -11
- package/src/formats/cx/importer.ts +126 -90
- package/src/formats/cx/styles.ts +304 -0
- package/src/formats/cx2/exporter.ts +234 -77
- package/src/formats/cx2/importer.ts +19 -1
- package/src/formats/cx2/styles.ts +29 -0
- package/src/formats/cys/constants.ts +3 -0
- package/src/formats/cys/exporter.ts +246 -60
- package/src/formats/cys/importer.ts +125 -9
- package/src/formats/cys/session.ts +6 -0
- package/src/formats/cys/styles.ts +254 -0
- package/src/formats/cys/tables.ts +117 -48
- package/src/formats/dot/exporter.ts +262 -126
- package/src/formats/dot/importer.ts +111 -20
- package/src/formats/dot/index.ts +1 -0
- package/src/formats/dot/positions.ts +77 -0
- package/src/formats/dot/styles.ts +1741 -0
- package/src/formats/gexf/exporter.ts +30 -13
- package/src/formats/gexf/importer.ts +308 -158
- package/src/formats/gexf/index.ts +10 -0
- package/src/formats/gexf/schema.ts +5 -0
- package/src/formats/gexf/styles.ts +719 -0
- package/src/formats/gml/exporter.ts +33 -14
- package/src/formats/gml/importer.ts +4 -0
- package/src/formats/gml/index.ts +2 -1
- package/src/formats/gml/positions.ts +52 -0
- package/src/formats/gml/styles.ts +1248 -0
- package/src/formats/gml/syntax.ts +173 -62
- package/src/formats/graphml/constants.ts +5 -0
- package/src/formats/graphml/exporter.ts +163 -71
- package/src/formats/graphml/importer.ts +119 -45
- package/src/formats/graphml/index.ts +1 -0
- package/src/formats/graphml/styles-plain.ts +236 -0
- package/src/formats/graphml/styles-yed.ts +1221 -0
- package/src/formats/graphml/styles-yfiles3.ts +573 -0
- package/src/formats/graphml/tree.ts +36 -20
- package/src/formats/graphml/yfiles.ts +89 -13
- package/src/formats/json/exporter.ts +76 -26
- package/src/formats/json/importer.ts +543 -323
- package/src/formats/json/positions.ts +50 -0
- package/src/formats/json/styles.ts +2082 -0
- package/src/formats/neo4j/exporter.ts +2 -1
- package/src/formats/pajek/exporter.ts +195 -106
- package/src/formats/pajek/importer.ts +78 -9
- package/src/formats/pajek/index.ts +2 -0
- package/src/formats/pajek/styles.ts +685 -0
- package/src/formats/pajek/syntax.ts +7 -0
- package/src/formats/xgmml/columns.ts +39 -9
- package/src/formats/xgmml/constants.ts +3 -0
- package/src/formats/xgmml/document.ts +54 -12
- package/src/formats/xgmml/emit.ts +11 -6
- package/src/formats/xgmml/exporter.ts +32 -13
- package/src/formats/xgmml/importer.ts +43 -29
- package/src/formats/xgmml/styles.ts +400 -0
- package/src/index.ts +16 -0
- package/src/positions/codes.ts +32 -0
- package/src/positions/convert.ts +123 -0
- package/src/positions/extract.ts +619 -0
- package/src/positions/index.ts +23 -0
- package/src/positions/types.ts +221 -0
- package/src/registry.ts +179 -8
- package/src/styles/annotations.ts +478 -0
- package/src/styles/budget.ts +60 -0
- package/src/styles/canon/bends.ts +84 -0
- package/src/styles/canon/color-tables.ts +386 -0
- package/src/styles/canon/color.ts +624 -0
- package/src/styles/canon/enums.ts +211 -0
- package/src/styles/canon/graphviz.ts +189 -0
- package/src/styles/canon/index.ts +13 -0
- package/src/styles/canon/number.ts +152 -0
- package/src/styles/canon/site.ts +87 -0
- package/src/styles/canon/text.ts +221 -0
- package/src/styles/codes.ts +104 -0
- package/src/styles/cyjs/cascade.ts +2670 -0
- package/src/styles/cyjs/defaults-table.ts +82 -0
- package/src/styles/cyjs/emit.ts +951 -0
- package/src/styles/cyjs/index.ts +37 -0
- package/src/styles/cyjs/live.ts +147 -0
- package/src/styles/cyjs/mappers.ts +879 -0
- package/src/styles/cyjs/selector.ts +778 -0
- package/src/styles/cyjs/stylesheet-text.ts +214 -0
- package/src/styles/cytoscape/emit.ts +1264 -0
- package/src/styles/cytoscape/index.ts +40 -0
- package/src/styles/cytoscape/lexicon.ts +656 -0
- package/src/styles/cytoscape/mappings.ts +603 -0
- package/src/styles/cytoscape/resolve.ts +521 -0
- package/src/styles/cytoscape/translate.ts +237 -0
- package/src/styles/defaults.ts +504 -0
- package/src/styles/index.ts +57 -0
- package/src/styles/internal.ts +17 -0
- package/src/styles/io/approximations.ts +47 -0
- package/src/styles/io/block.ts +1138 -0
- package/src/styles/io/generic.ts +687 -0
- package/src/styles/io/index.ts +18 -0
- package/src/styles/io/writer.ts +745 -0
- package/src/styles/notes.ts +165 -0
- package/src/styles/plan/classes.ts +166 -0
- package/src/styles/plan/continuous.ts +218 -0
- package/src/styles/plan/discrete.ts +165 -0
- package/src/styles/plan/families.ts +115 -0
- package/src/styles/plan/features.ts +234 -0
- package/src/styles/plan/index.ts +7 -0
- package/src/styles/plan/plan.ts +1129 -0
- package/src/styles/plan/resolve.ts +685 -0
- package/src/styles/types.ts +814 -0
- package/src/styles/vocabulary.ts +172 -0
- package/src/types.ts +76 -1
- package/dist/chunks/constants-fT3E8JYY.js.map +0 -1
- package/dist/chunks/escape-B62ZGM_a.js.map +0 -1
- package/dist/chunks/export-rKLeGQMo.js.map +0 -1
- package/dist/chunks/exporter-8hLNemFk.js.map +0 -1
- package/dist/chunks/exporter-BWwEuOPT.js.map +0 -1
- package/dist/chunks/exporter-CpRyHZ3H.js.map +0 -1
- package/dist/chunks/importer-BbNb7eNg.js.map +0 -1
- package/dist/chunks/importer-C98dpSH4.js.map +0 -1
- package/dist/chunks/importer-D794XUTe.js.map +0 -1
- package/dist/chunks/importer-Dz7tI8Sa.js.map +0 -1
- package/dist/chunks/importer-Ht7LNg8L.js.map +0 -1
- package/dist/chunks/importer-WrGRZb0N.js.map +0 -1
- package/dist/chunks/importer-xZ-3suY1.js.map +0 -1
- package/dist/chunks/json-elements-DKSqpNW1.js.map +0 -1
|
@@ -154,6 +154,12 @@ export class GmlTokens {
|
|
|
154
154
|
/** The number of tokens. */
|
|
155
155
|
count = 0;
|
|
156
156
|
|
|
157
|
+
/**
|
|
158
|
+
* Whether a backslash escapes the next character inside a string (`\"`, `\\`): set for files OGDF wrote, whose
|
|
159
|
+
* writer escapes quotes that way. Plain GML has no escape mechanism.
|
|
160
|
+
*/
|
|
161
|
+
backslashEscapes = false;
|
|
162
|
+
|
|
157
163
|
/** Called by stringOf() with each named entity it cannot decode and the token's line, when set. */
|
|
158
164
|
onUnknownEntity: ((entity: string, line: number) => void) | null = null;
|
|
159
165
|
|
|
@@ -209,6 +215,9 @@ export class GmlTokens {
|
|
|
209
215
|
// a line break inside a string is part of it, as LF whatever the file's line ends
|
|
210
216
|
text = text.replaceAll(/\r\n?/g, "\n");
|
|
211
217
|
}
|
|
218
|
+
if (this.backslashEscapes && text.includes("\\")) {
|
|
219
|
+
text = text.replaceAll(/\\([\s\S])/g, "$1");
|
|
220
|
+
}
|
|
212
221
|
if (!text.includes("&")) {
|
|
213
222
|
return text;
|
|
214
223
|
}
|
|
@@ -279,67 +288,144 @@ export class GmlTokens {
|
|
|
279
288
|
*/
|
|
280
289
|
export function tokenizeGml(text: string): GmlTokens {
|
|
281
290
|
const tokens = new GmlTokens(text, Math.max(1024, text.length >>> 3));
|
|
282
|
-
|
|
291
|
+
tokens.backslashEscapes = writtenByOgdf(text);
|
|
292
|
+
const lex: GmlLex = { text, tokens, i: 0, line: 1, spanningLine: 0 };
|
|
293
|
+
while (lex.i < text.length) {
|
|
294
|
+
const c = text.codePointAt(lex.i) ?? 0;
|
|
295
|
+
if (c === 34) {
|
|
296
|
+
lexString(lex);
|
|
297
|
+
} else if (c === 91 || c === 93) {
|
|
298
|
+
tokens.push(c === 91 ? TOKEN_OPEN : TOKEN_CLOSE, lex.i, lex.i + 1, lex.line);
|
|
299
|
+
lex.i++;
|
|
300
|
+
} else if (!skipSpace(lex, c)) {
|
|
301
|
+
lexBare(lex);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
validateStructure(tokens);
|
|
305
|
+
return tokens;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/** Where tokenizeGml() is. */
|
|
309
|
+
interface GmlLex {
|
|
310
|
+
readonly text: string;
|
|
311
|
+
readonly tokens: GmlTokens;
|
|
312
|
+
/** The offset of the next character. */
|
|
313
|
+
i: number;
|
|
314
|
+
/** The line of the next character. */
|
|
315
|
+
line: number;
|
|
316
|
+
/** The opening line of the first string that spans lines: where a missing quote most likely is; 0 for none. */
|
|
317
|
+
spanningLine: number;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Skips one line break, space or comment.
|
|
322
|
+
* @param lex - the lexer
|
|
323
|
+
* @param c - the char code at the offset
|
|
324
|
+
* @returns false when the character starts a token
|
|
325
|
+
*/
|
|
326
|
+
function skipSpace(lex: GmlLex, c: number): boolean {
|
|
327
|
+
const { text } = lex;
|
|
328
|
+
if (c === 10 || c === 13) {
|
|
329
|
+
lex.line++;
|
|
330
|
+
lex.i++;
|
|
331
|
+
if (c === 13 && lex.i < text.length && text.codePointAt(lex.i) === 10) {
|
|
332
|
+
lex.i++;
|
|
333
|
+
}
|
|
334
|
+
} else if (c === 32 || c === 9 || c === 11 || c === 12 || c === 0xfeff) {
|
|
335
|
+
// a BOM left inside by concatenated files is whitespace; the shared text check reports it
|
|
336
|
+
lex.i++;
|
|
337
|
+
} else if (c === 35) {
|
|
338
|
+
lex.i = endOfLine(text, lex.i);
|
|
339
|
+
} else {
|
|
340
|
+
return false;
|
|
341
|
+
}
|
|
342
|
+
return true;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Lexes a string starting at the offset (its opening quote).
|
|
347
|
+
* @param lex - the lexer
|
|
348
|
+
*/
|
|
349
|
+
function lexString(lex: GmlLex): void {
|
|
350
|
+
const { text, tokens, i } = lex;
|
|
351
|
+
const close = tokens.backslashEscapes ? escapedClose(text, i + 1) : text.indexOf('"', i + 1);
|
|
352
|
+
if (close < 0) {
|
|
353
|
+
const hint =
|
|
354
|
+
lex.spanningLine === 0
|
|
355
|
+
? ""
|
|
356
|
+
: `; the string opened at line ${lex.spanningLine} spans lines, so a quote may be missing there`;
|
|
357
|
+
throw new GmlSyntaxError(SYNTAX_STRING_CODE, `unclosed string opened at line ${lex.line}${hint}`, lex.line);
|
|
358
|
+
}
|
|
359
|
+
tokens.push(TOKEN_STRING, i + 1, close, lex.line);
|
|
360
|
+
const opened = lex.line;
|
|
361
|
+
for (let k = i + 1; k < close; k++) {
|
|
362
|
+
const d = text.codePointAt(k);
|
|
363
|
+
if (d === 10 || (d === 13 && text.codePointAt(k + 1) !== 10)) {
|
|
364
|
+
lex.line++;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
if (lex.line !== opened && lex.spanningLine === 0) {
|
|
368
|
+
lex.spanningLine = opened;
|
|
369
|
+
}
|
|
370
|
+
lex.i = close + 1;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Lexes a bare token (a key, a number) starting at the offset.
|
|
375
|
+
* @param lex - the lexer
|
|
376
|
+
*/
|
|
377
|
+
function lexBare(lex: GmlLex): void {
|
|
378
|
+
const { text, i } = lex;
|
|
379
|
+
let j = i + 1;
|
|
380
|
+
while (j < text.length && !isDelimiter(text.codePointAt(j) ?? 0)) {
|
|
381
|
+
j++;
|
|
382
|
+
}
|
|
383
|
+
lex.tokens.push(classifyBare(text, i, j, lex.line), i, j, lex.line);
|
|
384
|
+
lex.i = j;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Whether OGDF wrote the file: its first key is `Creator "ogdf::..."`, after any whitespace and
|
|
389
|
+
* comment lines. A plain scan, so a banner of `#` characters costs time linear in its length.
|
|
390
|
+
* @param text - the GML text
|
|
391
|
+
* @returns true when the file opens with an OGDF creator line
|
|
392
|
+
*/
|
|
393
|
+
function writtenByOgdf(text: string): boolean {
|
|
394
|
+
const end = Math.min(text.length, 512);
|
|
283
395
|
let i = 0;
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
if (c === 10) {
|
|
290
|
-
line++;
|
|
291
|
-
i++;
|
|
292
|
-
} else if (c === 13) {
|
|
293
|
-
line++;
|
|
294
|
-
i++;
|
|
295
|
-
if (i < n && text.charCodeAt(i) === 10) {
|
|
396
|
+
while (i < end) {
|
|
397
|
+
const c = text.codePointAt(i);
|
|
398
|
+
if (c === 35) {
|
|
399
|
+
// '#': a comment runs to the next line break
|
|
400
|
+
while (i < end && text.codePointAt(i) !== 10 && text.codePointAt(i) !== 13) {
|
|
296
401
|
i++;
|
|
297
402
|
}
|
|
298
|
-
} else if (c === 32 || c === 9 || c ===
|
|
299
|
-
i++;
|
|
300
|
-
} else if (c === 0xfeff) {
|
|
301
|
-
// a BOM left inside by concatenated files is whitespace; the shared text check reports it
|
|
403
|
+
} else if (c === 32 || c === 9 || c === 10 || c === 13 || c === 12 || c === 11) {
|
|
302
404
|
i++;
|
|
303
|
-
} else if (c === 35) {
|
|
304
|
-
i = endOfLine(text, i);
|
|
305
|
-
} else if (c === 91) {
|
|
306
|
-
tokens.push(TOKEN_OPEN, i, i + 1, line);
|
|
307
|
-
i++;
|
|
308
|
-
} else if (c === 93) {
|
|
309
|
-
tokens.push(TOKEN_CLOSE, i, i + 1, line);
|
|
310
|
-
i++;
|
|
311
|
-
} else if (c === 34) {
|
|
312
|
-
const close = text.indexOf('"', i + 1);
|
|
313
|
-
if (close < 0) {
|
|
314
|
-
const hint =
|
|
315
|
-
spanningLine === 0
|
|
316
|
-
? ""
|
|
317
|
-
: `; the string opened at line ${spanningLine} spans lines, so a quote may be missing there`;
|
|
318
|
-
throw new GmlSyntaxError(SYNTAX_STRING_CODE, `unclosed string opened at line ${line}${hint}`, line);
|
|
319
|
-
}
|
|
320
|
-
tokens.push(TOKEN_STRING, i + 1, close, line);
|
|
321
|
-
const opened = line;
|
|
322
|
-
for (let k = i + 1; k < close; k++) {
|
|
323
|
-
const d = text.codePointAt(k);
|
|
324
|
-
if (d === 10 || (d === 13 && text.codePointAt(k + 1) !== 10)) {
|
|
325
|
-
line++;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
if (line !== opened && spanningLine === 0) {
|
|
329
|
-
spanningLine = opened;
|
|
330
|
-
}
|
|
331
|
-
i = close + 1;
|
|
332
405
|
} else {
|
|
333
|
-
|
|
334
|
-
while (j < n && !isDelimiter(text.charCodeAt(j))) {
|
|
335
|
-
j++;
|
|
336
|
-
}
|
|
337
|
-
tokens.push(classifyBare(text, i, j, line), i, j, line);
|
|
338
|
-
i = j;
|
|
406
|
+
break;
|
|
339
407
|
}
|
|
340
408
|
}
|
|
341
|
-
|
|
342
|
-
|
|
409
|
+
return /^Creator\s+"ogdf::/.test(text.slice(i, i + 64));
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* The offset of the quote closing a string whose backslashes escape the next character, or -1.
|
|
414
|
+
* @param text - the text
|
|
415
|
+
* @param from - the offset after the opening quote
|
|
416
|
+
* @returns the offset of the closing quote
|
|
417
|
+
*/
|
|
418
|
+
function escapedClose(text: string, from: number): number {
|
|
419
|
+
let k = from;
|
|
420
|
+
while (k < text.length) {
|
|
421
|
+
const c = text.codePointAt(k);
|
|
422
|
+
if (c === 34) {
|
|
423
|
+
return k;
|
|
424
|
+
}
|
|
425
|
+
// a backslash escapes the next character
|
|
426
|
+
k += c === 92 ? 2 : 1;
|
|
427
|
+
}
|
|
428
|
+
return -1;
|
|
343
429
|
}
|
|
344
430
|
|
|
345
431
|
/**
|
|
@@ -447,15 +533,8 @@ function validateStructure(tokens: GmlTokens): void {
|
|
|
447
533
|
tokens.line[i],
|
|
448
534
|
);
|
|
449
535
|
}
|
|
450
|
-
|
|
451
|
-
if (vk === TOKEN_OPEN) {
|
|
536
|
+
if (checkValue(tokens, i) === TOKEN_OPEN) {
|
|
452
537
|
stack.push(value);
|
|
453
|
-
} else if (vk === TOKEN_CLOSE || (vk === TOKEN_WORD && !NON_FINITE_WORD.test(tokens.textOf(value)))) {
|
|
454
|
-
throw new GmlSyntaxError(
|
|
455
|
-
SYNTAX_STRUCTURE_CODE,
|
|
456
|
-
`expected a value for key "${tokens.textOf(i)}" at line ${tokens.line[i]}, found ${describeToken(tokens, value)}`,
|
|
457
|
-
tokens.line[value],
|
|
458
|
-
);
|
|
459
538
|
}
|
|
460
539
|
i = value + 1;
|
|
461
540
|
}
|
|
@@ -470,6 +549,31 @@ function validateStructure(tokens: GmlTokens): void {
|
|
|
470
549
|
tokens.match = match;
|
|
471
550
|
}
|
|
472
551
|
|
|
552
|
+
/**
|
|
553
|
+
* Checks the value of a key: a number, a string, `INF` / `NAN` or an opening bracket. Gephi writes its name
|
|
554
|
+
* unquoted (`Creator Gephi`): the word is read as the string it means.
|
|
555
|
+
* @param tokens - the lexed tokens
|
|
556
|
+
* @param key - the key's token index (its value follows it)
|
|
557
|
+
* @returns the value's kind
|
|
558
|
+
*/
|
|
559
|
+
function checkValue(tokens: GmlTokens, key: number): TokenKind {
|
|
560
|
+
const { kind } = tokens;
|
|
561
|
+
const value = key + 1;
|
|
562
|
+
const word = kind[value] === TOKEN_WORD && !NON_FINITE_WORD.test(tokens.textOf(value));
|
|
563
|
+
if (word && tokens.textOf(key) === "Creator") {
|
|
564
|
+
kind[value] = TOKEN_STRING;
|
|
565
|
+
return TOKEN_STRING;
|
|
566
|
+
}
|
|
567
|
+
if (kind[value] === TOKEN_CLOSE || word) {
|
|
568
|
+
throw new GmlSyntaxError(
|
|
569
|
+
SYNTAX_STRUCTURE_CODE,
|
|
570
|
+
`expected a value for key "${tokens.textOf(key)}" at line ${tokens.line[key]}, found ${describeToken(tokens, value)}`,
|
|
571
|
+
tokens.line[value],
|
|
572
|
+
);
|
|
573
|
+
}
|
|
574
|
+
return kind[value] as TokenKind;
|
|
575
|
+
}
|
|
576
|
+
|
|
473
577
|
/**
|
|
474
578
|
* A short description of a token for messages.
|
|
475
579
|
* @param tokens - the tokens
|
|
@@ -528,6 +632,13 @@ export function isGmlKey(text: string): boolean {
|
|
|
528
632
|
return STRICT_KEY_TEXT.test(text);
|
|
529
633
|
}
|
|
530
634
|
|
|
635
|
+
/**
|
|
636
|
+
* Keys rewritten under sanitizeKeys "mangle", or a data column renamed because its key would read back as one of
|
|
637
|
+
* graphty's style values.
|
|
638
|
+
* @category Issue and loss codes
|
|
639
|
+
*/
|
|
640
|
+
export const KEY_MANGLED_CODE = "W_GML_KEY_MANGLED";
|
|
641
|
+
|
|
531
642
|
/**
|
|
532
643
|
* Rewrite a text as a GML key: every character outside `[0-9A-Za-z_]` becomes `_` and a leading
|
|
533
644
|
* non-letter is prefixed with `x` (the exporter's `sanitizeKeys: "mangle"`).
|
|
@@ -45,6 +45,7 @@ import {
|
|
|
45
45
|
UNKNOWN_ENCODING_CODE,
|
|
46
46
|
UNKNOWN_PARENT_CODE,
|
|
47
47
|
UNKNOWN_XML_ATTRIBUTE_CODE,
|
|
48
|
+
XML_NESTING_CODE,
|
|
48
49
|
XML_SYNTAX_CODE,
|
|
49
50
|
} from "../../common/codes.js";
|
|
50
51
|
|
|
@@ -190,6 +191,8 @@ export const GRAPHML_ISSUE = Object.freeze({
|
|
|
190
191
|
COLUMN_TYPE: COLUMN_TYPE_CODE,
|
|
191
192
|
/** The input is not well-formed XML. The import stops. */
|
|
192
193
|
XML_SYNTAX: XML_SYNTAX_CODE,
|
|
194
|
+
/** Elements are nested more than 100,000 deep. The import stops. */
|
|
195
|
+
XML_NESTING: XML_NESTING_CODE,
|
|
193
196
|
/** The input is not valid UTF-8. The import stops. */
|
|
194
197
|
INVALID_UTF8: INVALID_UTF8_CODE,
|
|
195
198
|
/**
|
|
@@ -245,6 +248,8 @@ export const GRAPHML_ISSUE = Object.freeze({
|
|
|
245
248
|
HYPEREDGE_DATA_DROPPED: "W_GRAPHML_HYPEREDGE_DATA_DROPPED",
|
|
246
249
|
/** Nested elements in the `<data>` of a typed (non-yfiles) key. */
|
|
247
250
|
DATA_NESTED: "E_GRAPHML_DATA_NESTED",
|
|
251
|
+
/** Nested elements in the `<data>` of an untyped key; they are kept as their XML text. */
|
|
252
|
+
DATA_STRUCTURED: "W_GRAPHML_DATA_STRUCTURED",
|
|
248
253
|
/** A `<node>` declared twice. */
|
|
249
254
|
DUPLICATE_NODE: DUPLICATE_NODE_CODE,
|
|
250
255
|
/** An edge id already used by another edge. */
|
|
@@ -37,6 +37,7 @@ import { agree, plural } from "../../common/plural.js";
|
|
|
37
37
|
import { type ExplicitWeights, explicitWeights } from "../../common/weights.js";
|
|
38
38
|
import { encodeChunks, joinText } from "../../common/writer.js";
|
|
39
39
|
import { xmlIllegalTextNotes } from "../../common/xml.js";
|
|
40
|
+
import type { ExporterStyleOptions } from "../../styles/io/writer.js";
|
|
40
41
|
import { type CommonExportOptions, type ExportCapabilities, type GraphExporter, type LossNote } from "../../types.js";
|
|
41
42
|
import {
|
|
42
43
|
EDGE_ID_COLUMN,
|
|
@@ -56,9 +57,13 @@ import {
|
|
|
56
57
|
XSI_NAMESPACE,
|
|
57
58
|
YFILES_NAMESPACE,
|
|
58
59
|
} from "./constants.js";
|
|
60
|
+
import { GRAPHML_STYLE_CAPABILITIES, graphmlStyledExport } from "./styles-yed.js";
|
|
59
61
|
import { treeProblem, writeXmlTree } from "./tree.js";
|
|
60
62
|
import { isGraphicsColumn, staleGraphicsRows } from "./yfiles.js";
|
|
61
63
|
|
|
64
|
+
/** What the writer takes: the format's options, the common ones and the styles. */
|
|
65
|
+
type GraphmlWriteOptions = GraphmlExportOptions & CommonExportOptions & ExporterStyleOptions;
|
|
66
|
+
|
|
62
67
|
/**
|
|
63
68
|
* The format-specific options of the GraphML exporter.
|
|
64
69
|
* @category Built-in formats
|
|
@@ -236,6 +241,8 @@ interface Plan {
|
|
|
236
241
|
readonly hierarchy: Hierarchy;
|
|
237
242
|
readonly meta: GraphmlMeta | null;
|
|
238
243
|
readonly needsOriginalIdKey: boolean;
|
|
244
|
+
/** Styles are written: the `y` prefix is yEd's namespace, whatever the file the graph came from bound it to. */
|
|
245
|
+
readonly yedGraphics?: boolean;
|
|
239
246
|
}
|
|
240
247
|
|
|
241
248
|
/** The resolved format-specific options. */
|
|
@@ -301,9 +308,15 @@ function graphmlMetaOf(snapshot: GraphSnapshot): GraphmlMeta | null {
|
|
|
301
308
|
* @param snapshot - the snapshot
|
|
302
309
|
* @param options - the resolved common options
|
|
303
310
|
* @param format - the resolved format options
|
|
311
|
+
* @param keyOrdered - write each element's data in the order of the keys (styled exports)
|
|
304
312
|
* @returns the plan
|
|
305
313
|
*/
|
|
306
|
-
function planExport(
|
|
314
|
+
function planExport(
|
|
315
|
+
snapshot: GraphSnapshot,
|
|
316
|
+
options: ResolvedExportOptions,
|
|
317
|
+
format: FormatOptions,
|
|
318
|
+
keyOrdered = false,
|
|
319
|
+
): Plan {
|
|
307
320
|
// the generic json note is replaced by planTable()'s (yfiles trees are kept, other json is
|
|
308
321
|
// text); columns mapped from a yfiles tree are never written: planTable() notes the ones
|
|
309
322
|
// that no longer match their tree, the rest lose nothing
|
|
@@ -325,6 +338,16 @@ function planExport(snapshot: GraphSnapshot, options: ResolvedExportOptions, for
|
|
|
325
338
|
const nodeColumns = planTable(snapshot.nodes, "node", notes, note);
|
|
326
339
|
const edgeColumns = planTable(snapshot.edges, "edge", notes, note);
|
|
327
340
|
const keys = planKeys([...graphColumns, ...nodeColumns, ...edgeColumns], keyIds);
|
|
341
|
+
if (keyOrdered) {
|
|
342
|
+
// an element's data in the order of its keys, as a re-import orders its columns, so that exporting what a
|
|
343
|
+
// styled export reads back gives the same bytes. ponytail: styled exports only, so an export without
|
|
344
|
+
// styles keeps its bytes; extend it to every export when that change is wanted on its own.
|
|
345
|
+
const keyOrder = new Map(keys.map((k, i) => [k.id, i]));
|
|
346
|
+
const byKey = (a: ColumnPlan, b: ColumnPlan): number =>
|
|
347
|
+
(keyOrder.get(a.keyId) ?? 0) - (keyOrder.get(b.keyId) ?? 0);
|
|
348
|
+
nodeColumns.sort(byKey);
|
|
349
|
+
edgeColumns.sort(byKey);
|
|
350
|
+
}
|
|
328
351
|
reservedNameNotes(nodeColumns, RESERVED_NODE_NAMES, note);
|
|
329
352
|
reservedNameNotes(edgeColumns, RESERVED_EDGE_NAMES, note);
|
|
330
353
|
const weight = planWeight(snapshot, edgeColumns, keyIds, keys, note);
|
|
@@ -1193,7 +1216,9 @@ function keyElement(key: KeyPlan, indent: string): string {
|
|
|
1193
1216
|
text += ` attr.type="${escapeXmlAttribute(key.attrType)}"`;
|
|
1194
1217
|
}
|
|
1195
1218
|
if (key.yfilesType !== null) {
|
|
1196
|
-
|
|
1219
|
+
// a yFiles 3 key is identified by its attr.uri, which the importer keeps as the column's type
|
|
1220
|
+
const uri = key.yfilesType.includes("://");
|
|
1221
|
+
text += ` ${uri ? "y:attr.uri" : "yfiles.type"}="${escapeXmlAttribute(key.yfilesType)}"`;
|
|
1197
1222
|
}
|
|
1198
1223
|
const { column } = key;
|
|
1199
1224
|
const desc = column?.meta.extra.desc;
|
|
@@ -1274,25 +1299,7 @@ function* writeGraphml(snapshot: GraphSnapshot, plan: Plan): Generator<string, v
|
|
|
1274
1299
|
const step = plan.pretty ? " " : "";
|
|
1275
1300
|
|
|
1276
1301
|
yield '<?xml version="1.0" encoding="UTF-8"?>\n';
|
|
1277
|
-
|
|
1278
|
-
const namespaces: Record<string, string> = { ...plan.meta?.namespaces };
|
|
1279
|
-
if (
|
|
1280
|
-
(plan.nodeColumns.some((c) => c.yfiles) ||
|
|
1281
|
-
plan.edgeColumns.some((c) => c.yfiles) ||
|
|
1282
|
-
plan.graphColumns.some((c) => c.yfiles)) &&
|
|
1283
|
-
!Object.values(namespaces).includes(YFILES_NAMESPACE)
|
|
1284
|
-
) {
|
|
1285
|
-
namespaces.y = YFILES_NAMESPACE;
|
|
1286
|
-
}
|
|
1287
|
-
if (!Object.values(namespaces).includes(XSI_NAMESPACE)) {
|
|
1288
|
-
namespaces.xsi = XSI_NAMESPACE;
|
|
1289
|
-
}
|
|
1290
|
-
for (const [prefix, uri] of Object.entries(namespaces)) {
|
|
1291
|
-
root += ` xmlns:${prefix}="${escapeXmlAttribute(uri)}"`;
|
|
1292
|
-
}
|
|
1293
|
-
const xsiPrefix = Object.entries(namespaces).find(([, uri]) => uri === XSI_NAMESPACE)?.[0] ?? "xsi";
|
|
1294
|
-
root += ` ${xsiPrefix}:schemaLocation="${SCHEMA_LOCATION}">\n`;
|
|
1295
|
-
yield root;
|
|
1302
|
+
yield rootElement(plan);
|
|
1296
1303
|
|
|
1297
1304
|
for (const key of plan.keys) {
|
|
1298
1305
|
yield keyElement(key, i1);
|
|
@@ -1329,54 +1336,116 @@ function* writeGraphml(snapshot: GraphSnapshot, plan: Plan): Generator<string, v
|
|
|
1329
1336
|
|
|
1330
1337
|
// edges: primaries only, in index order
|
|
1331
1338
|
const list = snapshot.edgeList();
|
|
1332
|
-
const { folding } = plan;
|
|
1333
1339
|
for (let e = 0; e < snapshot.edgeCount; e++) {
|
|
1334
|
-
if (folding.folded(e)) {
|
|
1335
|
-
|
|
1340
|
+
if (!plan.folding.folded(e)) {
|
|
1341
|
+
const start = edgeStartTag(snapshot, plan, e, String(ids.idAt(list.src[e])), String(ids.idAt(list.dst[e])));
|
|
1342
|
+
yield edgeElement(plan, e, edgeIds[e], start, [i2, i3]);
|
|
1336
1343
|
}
|
|
1337
|
-
const parts: string[] = [`\n${i2}<edge`];
|
|
1338
|
-
const id = edgeIds[e];
|
|
1339
|
-
if (id !== null) {
|
|
1340
|
-
parts.push(` id="${escapeXmlAttribute(id)}"`);
|
|
1341
|
-
}
|
|
1342
|
-
parts.push(
|
|
1343
|
-
` source="${escapeXmlAttribute(String(ids.idAt(list.src[e])))}" target="${escapeXmlAttribute(String(ids.idAt(list.dst[e])))}"`,
|
|
1344
|
-
);
|
|
1345
|
-
const directed = snapshot.directed && isDirectedEdge(folding, e);
|
|
1346
|
-
if (directed !== (plan.edgedefault === "directed")) {
|
|
1347
|
-
parts.push(` directed="${directed ? "true" : "false"}"`);
|
|
1348
|
-
}
|
|
1349
|
-
const sourcePort = portText(plan.sourcePortColumn, e);
|
|
1350
|
-
if (sourcePort !== null) {
|
|
1351
|
-
parts.push(` sourceport="${escapeXmlAttribute(sourcePort)}"`);
|
|
1352
|
-
}
|
|
1353
|
-
const targetPort = portText(plan.targetPortColumn, e);
|
|
1354
|
-
if (targetPort !== null) {
|
|
1355
|
-
parts.push(` targetport="${escapeXmlAttribute(targetPort)}"`);
|
|
1356
|
-
}
|
|
1357
|
-
const open = parts.length;
|
|
1358
|
-
if (plan.weight !== null) {
|
|
1359
|
-
const { keyId, attrType } = plan.weight;
|
|
1360
|
-
const weight = plan.weight.weights.text(e, attrType === "int" || attrType === "long");
|
|
1361
|
-
if (weight !== null) {
|
|
1362
|
-
parts.push(`\n${i3}<data key="${keyId}">${escapeXmlText(weight)}</data>`);
|
|
1363
|
-
}
|
|
1364
|
-
}
|
|
1365
|
-
for (const column of plan.edgeColumns) {
|
|
1366
|
-
writeData(column, e, i3, parts);
|
|
1367
|
-
}
|
|
1368
|
-
if (parts.length === open) {
|
|
1369
|
-
parts.push("/>");
|
|
1370
|
-
} else {
|
|
1371
|
-
parts.splice(open, 0, ">");
|
|
1372
|
-
parts.push(`\n${i2}</edge>`);
|
|
1373
|
-
}
|
|
1374
|
-
yield parts.join("");
|
|
1375
1344
|
}
|
|
1376
1345
|
|
|
1377
1346
|
yield `\n${i1}</graph>\n</graphml>\n`;
|
|
1378
1347
|
}
|
|
1379
1348
|
|
|
1349
|
+
/**
|
|
1350
|
+
* The opening `<graphml>` tag with its namespaces: the kept ones, yFiles' where graphics or yFiles columns are written,
|
|
1351
|
+
* and XML Schema's for the schema location.
|
|
1352
|
+
* @param plan - the plan
|
|
1353
|
+
* @returns the tag
|
|
1354
|
+
*/
|
|
1355
|
+
function rootElement(plan: Plan): string {
|
|
1356
|
+
const namespaces: Record<string, string> = { ...plan.meta?.namespaces };
|
|
1357
|
+
const yfilesColumns =
|
|
1358
|
+
plan.nodeColumns.some((c) => c.yfiles) ||
|
|
1359
|
+
plan.edgeColumns.some((c) => c.yfiles) ||
|
|
1360
|
+
plan.graphColumns.some((c) => c.yfiles);
|
|
1361
|
+
if (
|
|
1362
|
+
plan.yedGraphics === true ||
|
|
1363
|
+
(yfilesColumns &&
|
|
1364
|
+
!Object.values(namespaces).includes(YFILES_NAMESPACE) &&
|
|
1365
|
+
// a yFiles 3 file binds `y` to its own namespace, which its kept trees are written in
|
|
1366
|
+
namespaces.y === undefined)
|
|
1367
|
+
) {
|
|
1368
|
+
namespaces.y = YFILES_NAMESPACE;
|
|
1369
|
+
}
|
|
1370
|
+
if (!Object.values(namespaces).includes(XSI_NAMESPACE)) {
|
|
1371
|
+
namespaces.xsi = XSI_NAMESPACE;
|
|
1372
|
+
}
|
|
1373
|
+
let root = `<graphml xmlns="${GRAPHML_NAMESPACE}"`;
|
|
1374
|
+
for (const [prefix, uri] of Object.entries(namespaces)) {
|
|
1375
|
+
root += ` xmlns:${prefix}="${escapeXmlAttribute(uri)}"`;
|
|
1376
|
+
}
|
|
1377
|
+
const xsiPrefix = Object.entries(namespaces).find(([, uri]) => uri === XSI_NAMESPACE)?.[0] ?? "xsi";
|
|
1378
|
+
return `${root} ${xsiPrefix}:schemaLocation="${SCHEMA_LOCATION}">\n`;
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
/**
|
|
1382
|
+
* An edge's attributes after `<edge`: its source and target, a `directed` that differs from the default, its ports.
|
|
1383
|
+
* @param snapshot - the snapshot
|
|
1384
|
+
* @param plan - the plan
|
|
1385
|
+
* @param e - the edge
|
|
1386
|
+
* @param source - the source's written id
|
|
1387
|
+
* @param target - the target's written id
|
|
1388
|
+
* @returns the attribute text
|
|
1389
|
+
*/
|
|
1390
|
+
function edgeStartTag(snapshot: GraphSnapshot, plan: Plan, e: number, source: string, target: string): string {
|
|
1391
|
+
let text = ` source="${escapeXmlAttribute(source)}" target="${escapeXmlAttribute(target)}"`;
|
|
1392
|
+
const directed = snapshot.directed && isDirectedEdge(plan.folding, e);
|
|
1393
|
+
if (directed !== (plan.edgedefault === "directed")) {
|
|
1394
|
+
text += ` directed="${directed ? "true" : "false"}"`;
|
|
1395
|
+
}
|
|
1396
|
+
const sourcePort = portText(plan.sourcePortColumn, e);
|
|
1397
|
+
if (sourcePort !== null) {
|
|
1398
|
+
text += ` sourceport="${escapeXmlAttribute(sourcePort)}"`;
|
|
1399
|
+
}
|
|
1400
|
+
const targetPort = portText(plan.targetPortColumn, e);
|
|
1401
|
+
if (targetPort !== null) {
|
|
1402
|
+
text += ` targetport="${escapeXmlAttribute(targetPort)}"`;
|
|
1403
|
+
}
|
|
1404
|
+
return text;
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
/**
|
|
1408
|
+
* One `<edge>` element with its weight and data.
|
|
1409
|
+
* @param plan - the plan
|
|
1410
|
+
* @param e - the edge
|
|
1411
|
+
* @param id - its written id, or null
|
|
1412
|
+
* @param start - its attributes after the id
|
|
1413
|
+
* @param indents - the edge's indentation and its data's
|
|
1414
|
+
* @returns the element text
|
|
1415
|
+
*/
|
|
1416
|
+
function edgeElement(
|
|
1417
|
+
plan: Plan,
|
|
1418
|
+
e: number,
|
|
1419
|
+
id: string | null,
|
|
1420
|
+
start: string,
|
|
1421
|
+
indents: readonly [string, string],
|
|
1422
|
+
): string {
|
|
1423
|
+
const [i2, i3] = indents;
|
|
1424
|
+
const parts: string[] = [`\n${i2}<edge`];
|
|
1425
|
+
if (id !== null) {
|
|
1426
|
+
parts.push(` id="${escapeXmlAttribute(id)}"`);
|
|
1427
|
+
}
|
|
1428
|
+
parts.push(start);
|
|
1429
|
+
const open = parts.length;
|
|
1430
|
+
if (plan.weight !== null) {
|
|
1431
|
+
const { keyId, attrType } = plan.weight;
|
|
1432
|
+
const weight = plan.weight.weights.text(e, attrType === "int" || attrType === "long");
|
|
1433
|
+
if (weight !== null) {
|
|
1434
|
+
parts.push(`\n${i3}<data key="${keyId}">${escapeXmlText(weight)}</data>`);
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
for (const column of plan.edgeColumns) {
|
|
1438
|
+
writeData(column, e, i3, parts);
|
|
1439
|
+
}
|
|
1440
|
+
if (parts.length === open) {
|
|
1441
|
+
parts.push("/>");
|
|
1442
|
+
} else {
|
|
1443
|
+
parts.splice(open, 0, ">");
|
|
1444
|
+
parts.push(`\n${i2}</edge>`);
|
|
1445
|
+
}
|
|
1446
|
+
return parts.join("");
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1380
1449
|
/**
|
|
1381
1450
|
* The text of a port reference cell.
|
|
1382
1451
|
* @param column - the sourcePort / targetPort column, or null
|
|
@@ -1497,15 +1566,16 @@ export const graphmlExporter: GraphExporter<GraphmlExportOptions> = Object.freez
|
|
|
1497
1566
|
format: FORMAT,
|
|
1498
1567
|
options: Object.freeze(["edgedefault", "pretty"]),
|
|
1499
1568
|
capabilities: CAPABILITIES,
|
|
1569
|
+
styles: Object.freeze({ capabilities: GRAPHML_STYLE_CAPABILITIES }),
|
|
1500
1570
|
/**
|
|
1501
1571
|
* Pre-flight: every loss the export would incur.
|
|
1502
1572
|
* @param snapshot - the snapshot
|
|
1503
1573
|
* @param options - format-specific and common options
|
|
1504
1574
|
* @returns the notes
|
|
1505
1575
|
*/
|
|
1506
|
-
check(snapshot: GraphSnapshot, options?:
|
|
1507
|
-
const plan =
|
|
1508
|
-
return Object.freeze(plan.notes);
|
|
1576
|
+
check(snapshot: GraphSnapshot, options?: GraphmlWriteOptions): readonly LossNote[] {
|
|
1577
|
+
const { plan, styled } = prepare(snapshot, options);
|
|
1578
|
+
return Object.freeze([...plan.notes, ...(styled?.notes ?? [])]);
|
|
1509
1579
|
},
|
|
1510
1580
|
/**
|
|
1511
1581
|
* Write the document as UTF-8 chunks.
|
|
@@ -1513,9 +1583,9 @@ export const graphmlExporter: GraphExporter<GraphmlExportOptions> = Object.freez
|
|
|
1513
1583
|
* @param options - format-specific and common options
|
|
1514
1584
|
* @returns the chunks
|
|
1515
1585
|
*/
|
|
1516
|
-
export(snapshot: GraphSnapshot, options?:
|
|
1517
|
-
const plan =
|
|
1518
|
-
return encodeChunks(writeGraphml(
|
|
1586
|
+
export(snapshot: GraphSnapshot, options?: GraphmlWriteOptions): AsyncIterable<Uint8Array> {
|
|
1587
|
+
const { plan, written } = prepare(snapshot, options);
|
|
1588
|
+
return encodeChunks(writeGraphml(written, plan));
|
|
1519
1589
|
},
|
|
1520
1590
|
/**
|
|
1521
1591
|
* Write the document as one string.
|
|
@@ -1523,8 +1593,30 @@ export const graphmlExporter: GraphExporter<GraphmlExportOptions> = Object.freez
|
|
|
1523
1593
|
* @param options - format-specific and common options
|
|
1524
1594
|
* @returns the document
|
|
1525
1595
|
*/
|
|
1526
|
-
exportToString(snapshot: GraphSnapshot, options?:
|
|
1527
|
-
const plan =
|
|
1528
|
-
return joinText(writeGraphml(
|
|
1596
|
+
exportToString(snapshot: GraphSnapshot, options?: GraphmlWriteOptions): Promise<string> {
|
|
1597
|
+
const { plan, written } = prepare(snapshot, options);
|
|
1598
|
+
return joinText(writeGraphml(written, plan));
|
|
1529
1599
|
},
|
|
1530
1600
|
});
|
|
1601
|
+
|
|
1602
|
+
/**
|
|
1603
|
+
* The plan of an export, with styles: the graph to write with yEd graphics in place of its yFiles columns.
|
|
1604
|
+
* @param snapshot - the snapshot
|
|
1605
|
+
* @param options - format-specific and common options
|
|
1606
|
+
* @returns the plan, the graph to write and the styled export (null without styles)
|
|
1607
|
+
*/
|
|
1608
|
+
function prepare(
|
|
1609
|
+
snapshot: GraphSnapshot,
|
|
1610
|
+
options: GraphmlWriteOptions | undefined,
|
|
1611
|
+
): { plan: Plan; written: GraphSnapshot; styled: ReturnType<typeof graphmlStyledExport> } {
|
|
1612
|
+
const styled = graphmlStyledExport(snapshot, options?.styles);
|
|
1613
|
+
const written = styled?.snapshot ?? snapshot;
|
|
1614
|
+
const plan = planExport(written, resolveExportOptions(options), resolveFormatOptions(options), styled !== null);
|
|
1615
|
+
if (styled === null) {
|
|
1616
|
+
return { plan, written, styled };
|
|
1617
|
+
}
|
|
1618
|
+
// the yEd graphics carry each node's position in its y:Geometry, so the position column is not lost
|
|
1619
|
+
const position = written.nodes.byRole("position")?.meta.name;
|
|
1620
|
+
const notes = plan.notes.filter((n) => n.code !== LOSS.POSITIONS || n.column !== position);
|
|
1621
|
+
return { plan: { ...plan, notes, yedGraphics: true }, written, styled };
|
|
1622
|
+
}
|