diff --git a/.env b/.env new file mode 100644 index 0000000..06f95df --- /dev/null +++ b/.env @@ -0,0 +1 @@ +HEADLESS_REACTION_SVG=true diff --git a/README.md b/README.md index c649ebc..ff2c452 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,10 @@ navigate to into reaction-svg-composer and execute npm link yarn compile ``` +### Development - ali 14.02.2024 +set .env (HEADLESS_REACTION_SVG=true) in root directory +run following: node .\example\index.js + ## Acknowledgments diff --git a/example/index.js b/example/index.js new file mode 100644 index 0000000..6c32cb3 --- /dev/null +++ b/example/index.js @@ -0,0 +1,238 @@ + +import * as dotenv from "dotenv"; +dotenv.config(); // Load environment variables before anything else +import fs from "fs"; +import { JSDOM } from "jsdom"; +import { ReactionRenderer } from "../lib/esm/index.js"; + +// Set up a virtual DOM +const dom = new JSDOM(``, { + pretendToBeVisual: true, +}); +global.window = dom.window; +global.document = dom.window.document; +global.DOMParser = dom.window.DOMParser; +global.XMLSerializer = dom.window.XMLSerializer; +global.HTMLElement = dom.window.HTMLElement; +global.Node = dom.window.Node; + + +async function generateReactionSVG() { + try { + + // Initialize the ReactionRenderer + // const renderer = new ReactionRenderer(); + + const fileData = { + "displayMatrix": { + "multistep": false, + "condition": true, + "temperature": true, + "duration": true, + "solvent": true, + "elementMargin": 20, + "svg_type": "ketcher1", + "samples": { + "19": { + "coefficient": true, + "yield_equivalent": true, + "molecule_sum_formula": true, + "sample_name": false, + "sample_short_label": true, + "sample_external_label": false, + "molecule_name": true, + "sample_index": false, + "svg": true + }, + "20": { + "coefficient": true, + "yield_equivalent": true, + "molecule_sum_formula": true, + "sample_name": false, + "sample_short_label": true, + "sample_external_label": false, + "molecule_name": true, + "sample_index": false, + "svg": true + }, + "21": { + "coefficient": true, + "yield_equivalent": true, + "molecule_sum_formula": true, + "sample_name": false, + "sample_short_label": true, + "sample_external_label": false, + "molecule_name": true, + "sample_index": false, + "svg": true + }, + "22": { + "coefficient": true, + "yield_equivalent": true, + "molecule_sum_formula": true, + "sample_name": false, + "sample_short_label": true, + "sample_external_label": false, + "molecule_name": true, + "sample_index": false, + "svg": true + }, + "23": { + "coefficient": true, + "yield_equivalent": true, + "molecule_sum_formula": true, + "sample_name": false, + "sample_short_label": true, + "sample_external_label": false, + "molecule_name": true, + "sample_index": false, + "svg": true + }, + "24": { + "coefficient": true, + "yield_equivalent": true, + "molecule_sum_formula": true, + "sample_name": false, + "sample_short_label": true, + "sample_external_label": false, + "molecule_name": true, + "sample_index": false, + "svg": true + } + } + }, + "reactionArray": [ + { + "sample_id": 19, + "position": 0, + "step": 1, + "type": "ReactionsStartingMaterialSample", + "sample_short_label": "CU1-19", + "sample_index": "0", + "sample_external_label": "CU1-Wyatt", + "sample_name": "If I Forget Thee Jerusalem", + "sum_formula": null, + "svgs": { + "ketcher1": "\n \n \n \n I\n \n \n Cl\n \n \n \n \n \n\n" + }, + "equivalent": null, + "coefficient": 1 + }, + { + "sample_id": 20, + "position": 0, + "step": 1, + "type": "ReactionsStartingMaterialSample", + "sample_short_label": "CU1-20", + "sample_index": "0", + "sample_external_label": "CU1-Tula", + "sample_name": "Time To Murder And Create", + "sum_formula": null, + "svgs": { + "ketcher1": "\n \n \n \n C\n \n \n H\n \n \n 3\n \n \n O\n \n \n \n \n \n C\n \n \n H\n \n \n 3\n \n \n O\n \n \n C\n \n \n H\n \n \n 3\n \n \n O\n \n \n \n \n \n C\n \n \n H\n \n \n 3\n \n \n O\n \n \n Mn\n \n \n 2+\n \n \n O\n \n \n H\n \n \n 2\n \n \n O\n \n \n H\n \n \n 2\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "equivalent": 0.0016557297067639597, + "coefficient": 1 + }, + { + "sample_id": 21, + "position": 0, + "step": 1, + "type": "ReactionsReactantSample", + "sample_short_label": "New Reactant", + "sample_index": "0", + "sample_external_label": "CU1-Mikki", + "sample_name": "Mr Standfast", + "sum_formula": null, + "svgs": { + "ketcher1": "\n \n \n \n Ir\n \n \n Cl\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "equivalent": 0.004222523970004419, + "coefficient": 1 + }, + { + "sample_id": 22, + "position": 0, + "step": 1, + "type": "ReactionsReactantSample", + "sample_short_label": "New Reactant", + "sample_index": "0", + "sample_external_label": "CU1-Jeremy", + "sample_name": "Dulce et Decorum Est", + "sum_formula": null, + "svgs": { + "ketcher1": "\n \n \n \n Rh\n \n \n Cl\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "equivalent": 0.4998516253605817, + "coefficient": 1 + }, + { + "sample_id": 24, + "position": 0, + "step": 1, + "type": "ReactionsProductSample", + "sample_short_label": "CU1-24", + "sample_index": "0", + "sample_external_label": "CU1-Wilhelmina", + "sample_name": "It's a Battlefield", + "sum_formula": null, + "svgs": { + "ketcher1": "\n \n \n \n C\n \n \n H\n \n \n 3\n \n \n N\n \n \n C\n \n \n H\n \n \n 3\n \n \n O\n \n \n \n \n \n \n\n" + }, + "equivalent": 0, + "coefficient": 1 + }, + { + "sample_id": 23, + "position": 0, + "step": 1, + "type": "ReactionsProductSample", + "sample_short_label": "CU1-23", + "sample_index": "0", + "sample_external_label": "CU1-Jamel", + "sample_name": "Frequent Hearses", + "sum_formula": null, + "svgs": { + "ketcher1": "\n \n \n \n O\n \n \n S\n \n \n O\n \n \n \n \n \n O\n \n \n \n \n \n O\n \n \n Cu\n \n \n 2+\n \n \n \n \n \n \n\n" + }, + "equivalent": null, + "coefficient": 1 + }, + { + "type": "condition", + "step": 1, + "value": "Françoise Sagan" + }, + { + "type": "duration", + "step": 1, + "value": "" + }, + { + "type": "temperature", + "step": 1, + "value": { + "data": [ + + ], + "userText": "", + "valueUnit": "°C" + } + } + ] + } + // Generate the SVG output + const svgOutput = new ReactionRenderer(fileData.displayMatrix, fileData.reactionArray) + const re = svgOutput.renderReaction(); + + console.log(re) + // Save the generated SVG to a file + // fs.writeFileSync("reaction.svg", svgOutput); + // console.log("✅ SVG Reaction Image saved as 'reaction.svg'"); + } catch (error) { + console.error("❌ Error generating SVG reaction:", error); + } +} + +// Run the function +generateReactionSVG(); diff --git a/example/test2.json b/example/test2.json new file mode 100644 index 0000000..ede6589 --- /dev/null +++ b/example/test2.json @@ -0,0 +1,198 @@ +{ + "displayMatrix": { + "multistep": false, + "condition": true, + "temperature": true, + "duration": true, + "solvent": true, + "elementMargin": 20, + "svg_type": "ketcher1", + "samples": { + "19": { + "coefficient": true, + "yield_equivalent": true, + "molecule_sum_formula": true, + "sample_name": false, + "sample_short_label": true, + "sample_external_label": false, + "molecule_name": true, + "sample_index": false, + "svg": true + }, + "20": { + "coefficient": true, + "yield_equivalent": true, + "molecule_sum_formula": true, + "sample_name": false, + "sample_short_label": true, + "sample_external_label": false, + "molecule_name": true, + "sample_index": false, + "svg": true + }, + "21": { + "coefficient": true, + "yield_equivalent": true, + "molecule_sum_formula": true, + "sample_name": false, + "sample_short_label": true, + "sample_external_label": false, + "molecule_name": true, + "sample_index": false, + "svg": true + }, + "22": { + "coefficient": true, + "yield_equivalent": true, + "molecule_sum_formula": true, + "sample_name": false, + "sample_short_label": true, + "sample_external_label": false, + "molecule_name": true, + "sample_index": false, + "svg": true + }, + "23": { + "coefficient": true, + "yield_equivalent": true, + "molecule_sum_formula": true, + "sample_name": false, + "sample_short_label": true, + "sample_external_label": false, + "molecule_name": true, + "sample_index": false, + "svg": true + }, + "24": { + "coefficient": true, + "yield_equivalent": true, + "molecule_sum_formula": true, + "sample_name": false, + "sample_short_label": true, + "sample_external_label": false, + "molecule_name": true, + "sample_index": false, + "svg": true + } + } + }, + "reactionArray": [ + { + "sample_id": 19, + "position": 0, + "step": 1, + "type": "ReactionsStartingMaterialSample", + "sample_short_label": "CU1-19", + "sample_index": "0", + "sample_external_label": "CU1-Wyatt", + "sample_name": "If I Forget Thee Jerusalem", + "sum_formula": null, + "svgs": { + "ketcher1": "\n \n \n \n I\n \n \n Cl\n \n \n \n \n \n\n" + }, + "equivalent": null, + "coefficient": 1 + }, + { + "sample_id": 20, + "position": 0, + "step": 1, + "type": "ReactionsStartingMaterialSample", + "sample_short_label": "CU1-20", + "sample_index": "0", + "sample_external_label": "CU1-Tula", + "sample_name": "Time To Murder And Create", + "sum_formula": null, + "svgs": { + "ketcher1": "\n \n \n \n C\n \n \n H\n \n \n 3\n \n \n O\n \n \n \n \n \n C\n \n \n H\n \n \n 3\n \n \n O\n \n \n C\n \n \n H\n \n \n 3\n \n \n O\n \n \n \n \n \n C\n \n \n H\n \n \n 3\n \n \n O\n \n \n Mn\n \n \n 2+\n \n \n O\n \n \n H\n \n \n 2\n \n \n O\n \n \n H\n \n \n 2\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "equivalent": 0.0016557297067639597, + "coefficient": 1 + }, + { + "sample_id": 21, + "position": 0, + "step": 1, + "type": "ReactionsReactantSample", + "sample_short_label": "New Reactant", + "sample_index": "0", + "sample_external_label": "CU1-Mikki", + "sample_name": "Mr Standfast", + "sum_formula": null, + "svgs": { + "ketcher1": "\n \n \n \n Ir\n \n \n Cl\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "equivalent": 0.004222523970004419, + "coefficient": 1 + }, + { + "sample_id": 22, + "position": 0, + "step": 1, + "type": "ReactionsReactantSample", + "sample_short_label": "New Reactant", + "sample_index": "0", + "sample_external_label": "CU1-Jeremy", + "sample_name": "Dulce et Decorum Est", + "sum_formula": null, + "svgs": { + "ketcher1": "\n \n \n \n Rh\n \n \n Cl\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "equivalent": 0.4998516253605817, + "coefficient": 1 + }, + { + "sample_id": 24, + "position": 0, + "step": 1, + "type": "ReactionsProductSample", + "sample_short_label": "CU1-24", + "sample_index": "0", + "sample_external_label": "CU1-Wilhelmina", + "sample_name": "It's a Battlefield", + "sum_formula": null, + "svgs": { + "ketcher1": "\n \n \n \n C\n \n \n H\n \n \n 3\n \n \n N\n \n \n C\n \n \n H\n \n \n 3\n \n \n O\n \n \n \n \n \n \n\n" + }, + "equivalent": 0, + "coefficient": 1 + }, + { + "sample_id": 23, + "position": 0, + "step": 1, + "type": "ReactionsProductSample", + "sample_short_label": "CU1-23", + "sample_index": "0", + "sample_external_label": "CU1-Jamel", + "sample_name": "Frequent Hearses", + "sum_formula": null, + "svgs": { + "ketcher1": "\n \n \n \n O\n \n \n S\n \n \n O\n \n \n \n \n \n O\n \n \n \n \n \n O\n \n \n Cu\n \n \n 2+\n \n \n \n \n \n \n\n" + }, + "equivalent": null, + "coefficient": 1 + }, + { + "type": "condition", + "step": 1, + "value": "Françoise Sagan" + }, + { + "type": "duration", + "step": 1, + "value": "" + }, + { + "type": "temperature", + "step": 1, + "value": { + "data": [ + + ], + "userText": "", + "valueUnit": "°C" + } + } + ] +} \ No newline at end of file diff --git a/package.json b/package.json index a87b21c..31a6f32 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "@types/jest": "^29.5.3", "@typescript-eslint/eslint-plugin": "^6.4.0", "@typescript-eslint/parser": "^6.4.0", + "cross-env": "^7.0.3", "eslint": "^8.47.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.1.0", @@ -28,16 +29,17 @@ "typescript": "^5.1.6" }, "scripts": { - "compile": "yarn run tscEs && yarn run tscCommon", + "compile": "yarn run tscEs && yarn run tscCommon && yarn run test", "tscEs": "tsc -p tsconfig.esm.json", "tscCommon": "tsc -p tsconfig.cjs.json", "lint": "eslint --fix", "start": "node --experimental-json-modules lib/esm/index.js", - "test": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" HEADLESS_REACTION_SVG=true jest", + "test": "cross-env NODE_OPTIONS=--experimental-vm-modules HEADLESS_REACTION_SVG=true jest", "prepare": "yarn run tscEs && yarn run tscCommon" }, "dependencies": { "@svgdotjs/svg.js": "^3.2.0", + "dotenv": "^16.4.7", "svgdom": "^0.1.14" }, "exports": { diff --git a/yarn.lock b/yarn.lock index dbfdfe8..3580698 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1551,7 +1551,14 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-env@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== + dependencies: + cross-spawn "^7.0.1" + +cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.6" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== @@ -1729,6 +1736,11 @@ domexception@^4.0.0: dependencies: webidl-conversions "^7.0.0" +dotenv@^16.4.7: + version "16.4.7" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.7.tgz#0e20c5b82950140aa99be360a8a5f52335f53c26" + integrity sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ== + electron-to-chromium@^1.4.284: version "1.4.288" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.288.tgz#bbce00eb03c1819fe3d0d0d861374b76c53f7507"