├── .eslintignore ├── .gitignore ├── docs └── images │ └── example-01.png ├── keymaps └── markdown-flowchart.json ├── styles └── markdown-flowchart.less ├── prettier.config.js ├── .babelrc ├── .eslintrc.yml ├── README-mobile.md ├── package.json ├── LICENSE.md ├── README.md ├── src └── index.js └── lib └── index.js /.eslintignore: -------------------------------------------------------------------------------- 1 | lib 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | npm-debug.log 3 | node_modules 4 | -------------------------------------------------------------------------------- /docs/images/example-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inkdropapp/inkdrop-flowchart/HEAD/docs/images/example-01.png -------------------------------------------------------------------------------- /keymaps/markdown-flowchart.json: -------------------------------------------------------------------------------- 1 | { 2 | "body": { 3 | "ctrl-alt-o": "markdown-flowchart:toggle" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /styles/markdown-flowchart.less: -------------------------------------------------------------------------------- 1 | .markdown-flowchart { 2 | white-space: normal; 3 | } 4 | 5 | .mde-preview.print .markdown-flowchart svg { 6 | max-width: 100%; 7 | } 8 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | const options = { 2 | arrowParens: "avoid", 3 | singleQuote: true, 4 | bracketSpacing: true, 5 | endOfLine: "lf", 6 | semi: false, 7 | tabWidth: 2, 8 | trailingComma: "none", 9 | }; 10 | 11 | module.exports = options; 12 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "targets": { "electron": "16.2.8" }, 7 | "useBuiltIns": "usage", 8 | "debug": false, 9 | "corejs": 3 10 | } 11 | ], 12 | "@babel/preset-react" 13 | ], 14 | "plugins": ["@babel/plugin-proposal-class-properties"] 15 | } 16 | -------------------------------------------------------------------------------- /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | root: true 2 | plugins: 3 | - react 4 | extends: 5 | - plugin:react/recommended 6 | - prettier 7 | parser: "@babel/eslint-parser" 8 | env: {} 9 | rules: 10 | no-useless-escape: 0 11 | prefer-const: 2 12 | no-unused-vars: 13 | - 2 14 | - argsIgnorePattern: ^_ 15 | varsIgnorePattern: ^_ 16 | react/prop-types: 0 17 | -------------------------------------------------------------------------------- /README-mobile.md: -------------------------------------------------------------------------------- 1 | It adds a support for drawing flowchart using [flowchart.js](http://flowchart.js.org/) in Markdown code block. 2 | 3 | ## Usage 4 | 5 | ```flowchart 6 | st=>start: Start:>http://www.google.com[blank] 7 | e=>end:>http://www.google.com 8 | op1=>operation: My Operation 9 | sub1=>subroutine: My Subroutine 10 | cond=>condition: Yes 11 | or No?:>http://www.google.com 12 | io=>inputoutput: catch something... 13 | 14 | st->op1->cond 15 | cond(yes)->io->e 16 | cond(no)->sub1(right)->op1 17 | ``` 18 | 19 | It will be rendered as: 20 | 21 | ![](https://github.com/inkdropapp/inkdrop-flowchart/raw/master/docs/images/example-01.png) 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flowchart", 3 | "main": "./lib/index", 4 | "version": "1.0.4", 5 | "description": "Enables flowchart support within Markdown", 6 | "keywords": [], 7 | "repository": "https://github.com/inkdropapp/inkdrop-flowchart", 8 | "license": "MIT", 9 | "scripts": { 10 | "build": "babel src/ -d lib/", 11 | "dev": "babel src/ -s -d lib/ --watch" 12 | }, 13 | "engines": { 14 | "inkdrop": "^4.x" 15 | }, 16 | "dependencies": { 17 | "flowchart.js": "^1.13.0" 18 | }, 19 | "devDependencies": { 20 | "@babel/cli": "^7.19.3", 21 | "@babel/core": "^7.20.2", 22 | "@babel/eslint-parser": "^7.19.1", 23 | "@babel/plugin-proposal-class-properties": "^7.18.6", 24 | "@babel/preset-env": "^7.20.2", 25 | "@babel/preset-react": "^7.18.6", 26 | "eslint": "^8.28.0", 27 | "eslint-config-prettier": "^8.5.0", 28 | "eslint-plugin-react": "^7.31.11", 29 | "prettier": "^2.8.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flowchart 2 | 3 | A plugin for drawing flowchart using [flowchart.js](http://flowchart.js.org/) in Markdown code block. 4 | 5 | ## Install 6 | 7 | ```shell 8 | ipm install flowchart 9 | ``` 10 | 11 | ## Usage 12 | 13 | ```flowchart 14 | st=>start: Start:>http://www.google.com[blank] 15 | e=>end:>http://www.google.com 16 | op1=>operation: My Operation 17 | sub1=>subroutine: My Subroutine 18 | cond=>condition: Yes 19 | or No?:>http://www.google.com 20 | io=>inputoutput: catch something... 21 | 22 | st->op1->cond 23 | cond(yes)->io->e 24 | cond(no)->sub1(right)->op1 25 | ``` 26 | 27 | It will be rendered as: 28 | 29 | ![](https://github.com/inkdropapp/inkdrop-flowchart/raw/master/docs/images/example-01.png) 30 | 31 | ## Changelog 32 | 33 | ### 1.0.3 34 | 35 | - fix(export): arrows don't appear in exported documents (Thanks [James](https://forum.inkdrop.app/t/arrows-on-flowchart-dont-make-it-to-pdf/1498)) 36 | 37 | ### 1.0.0 38 | 39 | - feat(\*): Support Inkdrop v4 40 | 41 | ### 0.2.0 42 | 43 | - feat(print): Scale flowchart up to 100% in width for printing (Thanks @zainul) 44 | 45 | ### 0.1.4 46 | 47 | - Show user-friendly error message 48 | 49 | ### 0.1.3 50 | 51 | - Use ranspiled js instead of ES6 52 | 53 | ### 0.1.2 54 | 55 | - Remove unused menu 56 | 57 | ### 0.1.1 58 | 59 | - Support Inkdrop v3.1.1 60 | 61 | ### 0.1.0 - First Release 62 | 63 | - Every feature added 64 | - Every bug fixed 65 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import flowchart from 'flowchart.js' 3 | import { markdownRenderer } from 'inkdrop' 4 | 5 | class Flowchart extends React.Component { 6 | componentDidMount() { 7 | this.renderDiagram() 8 | } 9 | componentDidUpdate() { 10 | this.renderDiagram() 11 | } 12 | render() { 13 | return
(this.canvas = el)} /> 14 | } 15 | renderDiagram() { 16 | try { 17 | const code = this.props.children[0] 18 | const diagram = flowchart.parse(code) 19 | this.canvas.innerHTML = '' 20 | diagram.drawSVG(this.canvas) 21 | this.duplicateMarkers() 22 | } catch (error) { 23 | this.canvas.innerHTML = ` 24 | 25 |
Failed to render flowchart. Please check if the syntax is correct.
26 |

${error.message}

27 |

How to write flowchart

28 |
29 | ` 30 | } 31 | } 32 | duplicateMarkers() { 33 | const { canvas } = this 34 | const markerDefs = document.querySelectorAll( 35 | '.markdown-flowchart path[id^=raphael-marker]' 36 | ) 37 | for (const marker of markerDefs) { 38 | if (!canvas.querySelector(`path#${marker.id}`)) { 39 | const clonedMarker = marker.cloneNode() 40 | const defs = canvas.querySelector('defs') 41 | if (defs) { 42 | defs.appendChild(clonedMarker) 43 | } 44 | } 45 | } 46 | } 47 | } 48 | 49 | module.exports = { 50 | activate() { 51 | if (markdownRenderer) { 52 | markdownRenderer.remarkCodeComponents.flowchart = Flowchart 53 | } 54 | }, 55 | 56 | deactivate() { 57 | if (markdownRenderer) { 58 | markdownRenderer.remarkCodeComponents.flowchart = null 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var React = _interopRequireWildcard(require("react")); 4 | var _flowchart = _interopRequireDefault(require("flowchart.js")); 5 | var _inkdrop = require("inkdrop"); 6 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 7 | function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } 8 | function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } 9 | class Flowchart extends React.Component { 10 | componentDidMount() { 11 | this.renderDiagram(); 12 | } 13 | componentDidUpdate() { 14 | this.renderDiagram(); 15 | } 16 | render() { 17 | return /*#__PURE__*/React.createElement("div", { 18 | className: "markdown-flowchart", 19 | ref: el => this.canvas = el 20 | }); 21 | } 22 | renderDiagram() { 23 | try { 24 | const code = this.props.children[0]; 25 | const diagram = _flowchart.default.parse(code); 26 | this.canvas.innerHTML = ''; 27 | diagram.drawSVG(this.canvas); 28 | this.duplicateMarkers(); 29 | } catch (error) { 30 | this.canvas.innerHTML = ` 31 | 32 |
Failed to render flowchart. Please check if the syntax is correct.
33 |

${error.message}

34 |

How to write flowchart

35 |
36 | `; 37 | } 38 | } 39 | duplicateMarkers() { 40 | const { 41 | canvas 42 | } = this; 43 | const markerDefs = document.querySelectorAll('.markdown-flowchart path[id^=raphael-marker]'); 44 | for (const marker of markerDefs) { 45 | if (!canvas.querySelector(`path#${marker.id}`)) { 46 | const clonedMarker = marker.cloneNode(); 47 | const defs = canvas.querySelector('defs'); 48 | if (defs) { 49 | defs.appendChild(clonedMarker); 50 | } 51 | } 52 | } 53 | } 54 | } 55 | module.exports = { 56 | activate() { 57 | if (_inkdrop.markdownRenderer) { 58 | _inkdrop.markdownRenderer.remarkCodeComponents.flowchart = Flowchart; 59 | } 60 | }, 61 | deactivate() { 62 | if (_inkdrop.markdownRenderer) { 63 | _inkdrop.markdownRenderer.remarkCodeComponents.flowchart = null; 64 | } 65 | } 66 | }; --------------------------------------------------------------------------------