├── .eslintrc.js ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── babel.config.json ├── dist └── bundle.js ├── index.html ├── package.json ├── src ├── BlockTypeParsers │ ├── CheckboxTypeParser.js │ ├── CodeTypeParser.js │ ├── DelimiterTypeParser.js │ ├── HeaderTypeParser.js │ ├── ImageTypeParser.js │ ├── ListTypeParser.js │ ├── ParagraphTypeParser.js │ └── QuoteTypeParser.js ├── FileHandler.js ├── MarkdownImporter.js ├── MarkdownParser.js └── index.js ├── webpack.config.js └── yarn.lock /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es6: true, 5 | }, 6 | extends: [ 7 | 'airbnb-base', 8 | ], 9 | globals: { 10 | Atomics: 'readonly', 11 | SharedArrayBuffer: 'readonly', 12 | }, 13 | parserOptions: { 14 | ecmaVersion: 2018, 15 | sourceType: 'module', 16 | }, 17 | rules: { 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [v1.1.0] 4 | 5 | ### Added 6 | 7 | - heading depth support up to level 6 8 | 9 | [v1.1.0]:https://github.com/stejul/editorjs-markdown-parser/tree/v1.1.0 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Stefan Mikic 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

EditorJS Markdown Importer/Exporter

2 | 3 |

4 | A plugin which allows the user to export the EditorJS data to Markdown and import it from Markdown. 5 |

6 | 7 | 8 | ## Table of Contents 9 | 10 | * [About the Project](#about-the-project) 11 | * [Built With](#built-with) 12 | * [Getting Started](#getting-started) 13 | * [Prerequisites](#prerequisites) 14 | * [Installation](#installation) 15 | * [Usage](#usage) 16 | * [Contributing](#contributing) 17 | * [License](#license) 18 | * [Acknowledgements](#acknowledgements) 19 | 20 | 21 | 22 | ## About The Project 23 | 24 | I intend to use the editor which should be exported/imported from Markdown. 25 | 26 | ### Built With 27 | 28 | * [Remark](https://remark.js.org/) 29 | 30 | 31 | ## Getting Started 32 | 33 | To get a local copy up and running follow these simple steps. 34 | 35 | ### Prerequisites 36 | 37 | - yarn 38 | 39 | ### Installation 40 | 41 | 1. Clone the repo 42 | ```sh 43 | git clone https://github.com/stejul/editorjs-markdown-parser 44 | ``` 45 | 2. Install packages 46 | ```sh 47 | yarn 48 | ``` 49 | 50 | ## Usage 51 | 52 | - Load up the bundled file (`dist/bundle.js`) in you document. 53 | - Add the Importer/Exporter to the EditorJS tools. 54 | 55 | ```js 56 | const editor = new EditorJS({ 57 | autofocuse: true, 58 | tools: { 59 | markdownParser: MDParser, 60 | 61 | markdownImporter: MDImporter, 62 | }, 63 | }; 64 | ``` 65 | 66 | ***The Plugin can now be used in the Editor-Toolbar*** 67 | 68 | 69 | ## Contributing 70 | 71 | Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. 72 | 73 | 1. Fork the Project 74 | 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 75 | 3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 76 | 4. Push to the Branch (`git push origin feature/AmazingFeature`) 77 | 5. Open a Pull Request 78 | 79 | 80 | ## License 81 | 82 | Distributed under the MIT License. See `LICENSE` for more information. 83 | 84 | ## Acknowledgements 85 | 86 | * [Lukas Gabsi](https://github.com/gabsii) - Helped me with his JS expertise 87 | -------------------------------------------------------------------------------- /babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /dist/bundle.js: -------------------------------------------------------------------------------- 1 | !function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var r in n)("object"==typeof exports?exports:e)[r]=n[r]}}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=43)}([function(e,t){e.exports=function(e){return e<-2}},function(e,t,n){e.exports=function(e,t,n,i){var o,u=i?i-1:1/0;return function(i){if(r(i))return e.enter(n),o=0,c(i);return t(i)};function c(i){return r(i)&&o++u?0:u+t:t>u?u:t;if(n=n>0?n:0,r.length<1e4)return(o=Array.from(r)).unshift(t,n),[].splice.apply(e,o);i=[].splice.apply(e,[t,n]);for(;c=h||a+1 4 | * 5 | * Copyright (c) 2014-2015, Jon Schlinkert. 6 | * Licensed under the MIT License. 7 | */var r,i="";e.exports=function(e,t){if("string"!=typeof e)throw new TypeError("expected a string");if(1===t)return e;if(2===t)return e+e;var n=e.length*t;if(r!==e||void 0===r)r=e,i="";else if(i.length>=n)return i.substr(0,n);for(;n>i.length&&t>1;)1&t&&(i+=e),t>>=1,e+=e;return i=(i+=e).substr(0,n)}},function(e,t){e.exports=String.fromCharCode},function(e,t,n){t.tokenize=function(e,t,n){return i(e,(function(e){return null===e||r(e)?t(e):n(e)}),"linePrefix")},t.partial=!0;var r=n(0),i=n(1)},function(e,t){e.exports=Object.assign},function(e,t,n){e.exports=function(e,t){var n=e[e.length-1];return n&&n[1].type===t?r(n[2].sliceStream(n[1])):0};var r=n(31)},function(e,t,n){var r=n(4);e.exports=r(/[\dA-Za-z]/)},function(e,t,n){e.exports=function(e,t){var n,i=e.children||[],o=[],u=-1;for(;++u-1,e.enter("labelEnd"),e.enter("labelMarker"),e.consume(t),e.exit("labelMarker"),e.exit("labelEnd"),a)};function a(n){return 40===n?e.attempt(p,t,o?t:s)(n):91===n?e.attempt(h,t,o?e.attempt(d,t,s):s)(n):o?t(n):s(n)}function s(e){return r._balanced=!0,n(e)}},t.resolveTo=function(e,t){var n,r,i,a,s,l,f,p=e.length,h=0;for(;p--;)if(a=e[p][1],s){if("link"===a.type||"labelLink"===a.type&&a._inactive)break;"enter"===e[p][0]&&"labelLink"===a.type&&(a._inactive=!0)}else if(l){if("enter"===e[p][0]&&("labelImage"===a.type||"labelLink"===a.type)&&!a._balanced&&(s=p,"labelLink"!==a.type)){h=2;break}}else"labelEnd"===a.type&&(l=p);return n={type:"labelLink"===e[s][1].type?"link":"image",start:c(e[s][1].start),end:c(e[e.length-1][1].end)},r={type:"label",start:c(e[s][1].start),end:c(e[l][1].end)},i={type:"labelText",start:c(e[s+h+2][1].end),end:c(e[l-2][1].start)},o(f=[["enter",n,t],["enter",r,t]],f.length,0,e.slice(s+1,s+h+3)),o(f,f.length,0,[["enter",i,t]]),o(f,f.length,0,u(t.parser.constructs.insideSpan.null,e.slice(s+h+4,l-3),t)),o(f,f.length,0,[["exit",i,t],e[l-2],e[l-1],["exit",r,t]]),o(f,f.length,0,e.slice(l+1)),o(f,f.length,0,[["exit",n,t]]),o(e,s,e.length,f),e},t.resolveAll=function(e){var t,n=-1;for(;++n1)for(var n=1;n=0;r--){var i=e[r];"."===i?e.splice(r,1):".."===i?(e.splice(r,1),n++):n&&(e.splice(r,1),n--)}if(t)for(;n--;n)e.unshift("..");return e}function r(e,t){if(e.filter)return e.filter(t);for(var n=[],r=0;r=-1&&!i;o--){var u=o>=0?arguments[o]:e.cwd();if("string"!=typeof u)throw new TypeError("Arguments to path.resolve must be strings");u&&(t=u+"/"+t,i="/"===u.charAt(0))}return(i?"/":"")+(t=n(r(t.split("/"),(function(e){return!!e})),!i).join("/"))||"."},t.normalize=function(e){var o=t.isAbsolute(e),u="/"===i(e,-1);return(e=n(r(e.split("/"),(function(e){return!!e})),!o).join("/"))||o||(e="."),e&&u&&(e+="/"),(o?"/":"")+e},t.isAbsolute=function(e){return"/"===e.charAt(0)},t.join=function(){var e=Array.prototype.slice.call(arguments,0);return t.normalize(r(e,(function(e,t){if("string"!=typeof e)throw new TypeError("Arguments to path.join must be strings");return e})).join("/"))},t.relative=function(e,n){function r(e){for(var t=0;t=0&&""===e[n];n--);return t>n?[]:e.slice(t,n-t+1)}e=t.resolve(e).substr(1),n=t.resolve(n).substr(1);for(var i=r(e.split("/")),o=r(n.split("/")),u=Math.min(i.length,o.length),c=u,a=0;a=1;--o)if(47===(t=e.charCodeAt(o))){if(!i){r=o;break}}else i=!1;return-1===r?n?"/":".":n&&1===r?"/":e.slice(0,r)},t.basename=function(e,t){var n=function(e){"string"!=typeof e&&(e+="");var t,n=0,r=-1,i=!0;for(t=e.length-1;t>=0;--t)if(47===e.charCodeAt(t)){if(!i){n=t+1;break}}else-1===r&&(i=!1,r=t+1);return-1===r?"":e.slice(n,r)}(e);return t&&n.substr(-1*t.length)===t&&(n=n.substr(0,n.length-t.length)),n},t.extname=function(e){"string"!=typeof e&&(e+="");for(var t=-1,n=0,r=-1,i=!0,o=0,u=e.length-1;u>=0;--u){var c=e.charCodeAt(u);if(47!==c)-1===r&&(i=!1,r=u+1),46===c?-1===t?t=u:1!==o&&(o=1):-1!==t&&(o=-1);else if(!i){n=u+1;break}}return-1===t||-1===r||0===o||1===o&&t===r-1&&t===n+1?"":e.slice(t,r)};var i="b"==="ab".substr(-1)?function(e,t,n){return e.substr(t,n)}:function(e,t,n){return t<0&&(t=e.length+t),e.substr(t,n)}}).call(this,n(27))},function(e,t){e.exports={}.hasOwnProperty},function(e,t,n){e.exports=function(e){var t,n,c,a,s,l,f,p={},h=-1;for(;++hp?n(o):(e.consume(o),x):41===o?h--?(e.consume(o),x):(e.exit("chunkString"),e.exit(l),e.exit(s),e.exit(u),t(o)):null===o||i(o)?h?n(o):(e.exit("chunkString"),e.exit(l),e.exit(s),e.exit(u),t(o)):r(o)?n(o):(e.consume(o),92===o?g:x)}function g(t){return 40===t||41===t||92===t?(e.consume(t),x):x(t)}};var r=n(33),i=n(3),o=n(0)},function(e,t,n){e.exports=function(e,t,n,o,u,c){var a,s=this,l=0;return function(t){return e.enter(o),e.enter(u),e.consume(t),e.exit(u),e.enter(c),f};function f(i){return null===i||91===i||93===i&&!a||94===i&&!l&&"_hiddenFootnoteSupport"in s.parser.constructs||l>999?n(i):93===i?(e.exit(c),e.enter(u),e.consume(i),e.exit(u),e.exit(o),t):r(i)?(e.enter("lineEnding"),e.consume(i),e.exit("lineEnding"),f):(e.enter("chunkString",{contentType:"string"}),p(i))}function p(t){return null===t||91===t||93===t||r(t)||l++>999?(e.exit("chunkString"),f(t)):(e.consume(t),a=a||!i(t),92===t?h:p)}function h(t){return 91===t||92===t||93===t?(e.consume(t),l++,p):p(t)}};var r=n(0),i=n(2)},function(e,t,n){e.exports=function(e,t){var n;return function u(c){if(r(c))return e.enter("lineEnding"),e.consume(c),e.exit("lineEnding"),n=!0,u;if(i(c))return o(e,u,n?"linePrefix":"lineSuffix")(c);return t(c)}};var r=n(0),i=n(2),o=n(1)},function(e,t,n){e.exports=function(e,t,n,o,u,c){var a;return function(t){return e.enter(o),e.enter(u),e.consume(t),e.exit(u),a=40===t?41:t,s};function s(n){return n===a?(e.enter(u),e.consume(n),e.exit(u),e.exit(o),t):(e.enter(c),l(n))}function l(t){return t===a?(e.exit(c),s(a)):null===t?n(t):r(t)?(e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),i(e,l,"linePrefix")):(e.enter("chunkString",{contentType:"string"}),f(t))}function f(t){return t===a||null===t||r(t)?(e.exit("chunkString"),l(t)):(e.consume(t),92===t?p:f)}function p(t){return t===a||92===t?(e.consume(t),f):f(t)}};var r=n(0),i=n(1)},function(e,t){e.exports=function(){return"\\\n"}},function(e,t){e.exports=function(e,t){return e.value&&!t.options.fences&&!e.lang&&/[^ \r\n]/.test(e.value)&&!/^[\t ]*[\r\n]|[\r\n][\t ]*$/.test(e.value)}},function(e,t,n){e.exports=function(e,t){return t.options.setext&&(!e.depth||e.depth<3)&&r(e)};var r=n(17)},function(e,t,n){e.exports=n(135)},function(e,t,n){"use strict";var r=n(45),i=n(46),o=n(47),u=n(48),c=n(49),a=n(51);e.exports=function e(){var t=[],n=c(),i={},g=!1,k=-1;return y.data=function(e,t){if("string"==typeof e)return 2===arguments.length?(m("data",g),i[e]=t,y):l.call(i,e)&&i[e]||null;if(e)return m("data",g),i=e,y;return i},y.freeze=b,y.attachers=t,y.use=function(e){var n;if(m("use",g),null==e);else if("function"==typeof e)l.apply(null,arguments);else{if("object"!=typeof e)throw new Error("Expected usable value, not `"+e+"`");"length"in e?a(e):r(e)}n&&(i.settings=o(i.settings||{},n));return y;function r(e){a(e.plugins),e.settings&&(n=o(n||{},e.settings))}function c(e){if("function"==typeof e)l(e);else{if("object"!=typeof e)throw new Error("Expected usable value, not `"+e+"`");"length"in e?l.apply(null,e):r(e)}}function a(e){var t,n;if(null==e);else{if("object"!=typeof e||!("length"in e))throw new Error("Expected a list of plugins, not `"+e+"`");for(t=e.length,n=-1;++n 12 | * @license MIT 13 | */ 14 | e.exports=function(e){return null!=e&&null!=e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}},function(e,t,n){"use strict";var r=Object.prototype.hasOwnProperty,i=Object.prototype.toString,o=Object.defineProperty,u=Object.getOwnPropertyDescriptor,c=function(e){return"function"==typeof Array.isArray?Array.isArray(e):"[object Array]"===i.call(e)},a=function(e){if(!e||"[object Object]"!==i.call(e))return!1;var t,n=r.call(e,"constructor"),o=e.constructor&&e.constructor.prototype&&r.call(e.constructor.prototype,"isPrototypeOf");if(e.constructor&&!n&&!o)return!1;for(t in e);return void 0===t||r.call(e,t)},s=function(e,t){o&&"__proto__"===t.name?o(e,t.name,{enumerable:!0,configurable:!0,value:t.newValue,writable:!0}):e[t.name]=t.newValue},l=function(e,t){if("__proto__"===t){if(!r.call(e,t))return;if(u)return u(e,t).value}return e[t]};e.exports=function e(){var t,n,r,i,o,u,f=arguments[0],p=1,h=arguments.length,d=!1;for("boolean"==typeof f&&(d=f,f=arguments[1]||{},p=2),(null==f||"object"!=typeof f&&"function"!=typeof f)&&(f={});p{if("[object Object]"!==Object.prototype.toString.call(e))return!1;const t=Object.getPrototypeOf(e);return null===t||t===Object.prototype}},function(e,t,n){"use strict";var r=n(50);e.exports=o,o.wrap=r;var i=[].slice;function o(){var e=[],t={run:function(){var t=-1,n=i.call(arguments,0,-1),o=arguments[arguments.length-1];if("function"!=typeof o)throw new Error("Expected function as last argument, not "+o);function u(c){var a=e[++t],s=i.call(arguments,0),l=s.slice(1),f=n.length,p=-1;if(c)o(c);else{for(;++pu.length;c&&u.push(i);try{t=e.apply(null,u)}catch(e){if(c&&n)throw e;return i(e)}c||(t&&"function"==typeof t.then?t.then(o,i):t instanceof Error?i(t):o(t))};function i(){n||(n=!0,t.apply(null,arguments))}function o(e){i(null,e)}}},function(e,t,n){"use strict";var r=n(52),i=n(54);e.exports=i;var o=i.prototype;o.message=function(e,t,n){var i=this.path,o=new r(e,t,n);i&&(o.name=i+":"+o.name,o.file=i);return o.fatal=!1,this.messages.push(o),o},o.info=function(){var e=this.message.apply(this,arguments);return e.fatal=null,e},o.fail=function(){var e=this.message.apply(this,arguments);throw e.fatal=!0,e}},function(e,t,n){"use strict";var r=n(53);function i(){}e.exports=u,i.prototype=Error.prototype,u.prototype=new i;var o=u.prototype;function u(e,t,n){var i,o,u;"string"==typeof t&&(n=t,t=null),i=function(e){var t,n=[null,null];"string"==typeof e&&(-1===(t=e.indexOf(":"))?n[1]=e:(n[0]=e.slice(0,t),n[1]=e.slice(t+1)));return n}(n),o=r(t)||"1:1",u={start:{line:null,column:null},end:{line:null,column:null}},t&&t.position&&(t=t.position),t&&(t.start?(u=t,t=t.start):u.start=t),e.stack&&(this.stack=e.stack,e=e.message),this.message=e,this.name=o,this.reason=e,this.line=t?t.line:null,this.column=t?t.column:null,this.location=u,this.source=i[0],this.ruleId=i[1]}o.file="",o.name="",o.reason="",o.message="",o.stack="",o.fatal=null,o.column=null,o.line=null},function(e,t,n){"use strict";var r={}.hasOwnProperty;function i(e){return e&&"object"==typeof e||(e={}),u(e.line)+":"+u(e.column)}function o(e){return e&&"object"==typeof e||(e={}),i(e.start)+"-"+i(e.end)}function u(e){return e&&"number"==typeof e?e:1}e.exports=function(e){if(!e||"object"!=typeof e)return"";if(r.call(e,"position")||r.call(e,"type"))return o(e.position);if(r.call(e,"start")||r.call(e,"end"))return o(e);if(r.call(e,"line")||r.call(e,"column"))return i(e);return""}},function(e,t,n){"use strict";(function(t){var r=n(28),i=n(55),o=n(56);e.exports=s;var u={}.hasOwnProperty,c=s.prototype,a=["history","path","basename","stem","extname","dirname"];function s(e){var n,r,i;if(e){if("string"==typeof e||o(e))e={contents:e};else if("message"in e&&"messages"in e)return e}else e={};if(!(this instanceof s))return new s(e);for(this.data={},this.messages=[],this.history=[],this.cwd=t.cwd(),r=-1,i=a.length;++r 19 | * @license MIT 20 | */ 21 | e.exports=function(e){return null!=e&&null!=e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}},function(e,t,n){"use strict";e.exports=function(e){var t=this;this.Parser=function(n){return r(n,Object.assign({},t.data("settings"),e,{extensions:t.data("micromarkExtensions")||[],mdastExtensions:t.data("fromMarkdownExtensions")||[]}))}};var r=n(58)},function(e,t,n){"use strict";e.exports=n(59)},function(e,t,n){"use strict";e.exports=function(e,t,n){"string"!=typeof t&&(n=t,t=void 0);return function(e){var t=e||{},n=function(e,t){var n=t.length,r=-1;for(;++r13&&n<32||n>126&&n<160||n>55295&&n<57344||n>64975&&n<65008||65535==(65535&n)||65534==(65535&n)||n>1114111)return"�";return r(n)};var r=n(10)},function(e,t,n){e.exports=function(e){var t={defined:[],constructs:s([c].concat(l((e||{}).extensions))),content:n(r),document:n(i),flow:n(o),string:n(u.string),text:n(u.text)};return t;function n(e){return function(n){return a(t,e,n)}}};var r=n(62),i=n(63),o=n(64),u=n(32),c=n(66),a=n(95),s=n(98),l=n(22)},function(e,t,n){t.tokenize=function(e){var t,n=e.attempt(this.parser.constructs.contentInitial,(function(t){if(null===t)return void e.consume(t);return e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),i(e,n,"linePrefix")}),(function(t){return e.enter("paragraph"),o(t)}));return n;function o(n){var r=e.enter("chunkText",{contentType:"text",previous:t});return t&&(t.next=r),t=r,u(n)}function u(t){return null===t?(e.exit("chunkText"),e.exit("paragraph"),void e.consume(t)):r(t)?(e.consume(t),e.exit("chunkText"),o):(e.consume(t),u)}};var r=n(0),i=n(1)},function(e,t,n){t.tokenize=function(e){var t,n,i,a=this,s=[],l=0;return f;function f(t){return lt;)a.containerState=s[o][1],s[o][0].exit.call(a,e);s.length=t}function y(e,r){var i=0;return t={},l;function l(r){return i1&&e[d][1].end.offset-e[d][1].start.offset>1?2:1,s={type:f>1?"strongSequence":"emphasisSequence",start:u(r(e[n][1].end),-f),end:r(e[n][1].end)},l={type:f>1?"strongSequence":"emphasisSequence",start:r(e[d][1].start),end:u(r(e[d][1].start),f)},a={type:f>1?"strongText":"emphasisText",start:r(e[n][1].end),end:r(e[d][1].start)},o={type:f>1?"strong":"emphasis",start:r(s.start),end:r(l.end)},e[n][1].end=r(s.start),e[d][1].start=r(l.end),p=[],e[n][1].end.offset-e[n][1].start.offset&&i(p,p.length,0,[["enter",e[n][1],t],["exit",e[n][1],t]]),i(p,p.length,0,[["enter",o,t],["enter",s,t],["exit",s,t],["enter",a,t]]),i(p,p.length,0,c(t.parser.constructs.insideSpan.null,e.slice(n+1,d),t)),i(p,p.length,0,[["exit",a,t],["enter",l,t],["exit",l,t],["exit",o,t]]),e[d][1].end.offset-e[d][1].start.offset?(h=2,i(p,p.length,0,[["enter",e[d][1],t],["exit",e[d][1],t]])):h=0,i(e,n-1,d-n+3,p),d=n+p.length-h-2;break}d=-1;for(;++do&&"whitespace"===e[i][1].type&&(i-=2);"atxHeadingSequence"===e[i][1].type&&(o===i-1||i-4>o&&"whitespace"===e[i-2][1].type)&&(i-=o+1===i?2:4);i>o&&(n={type:"atxHeadingText",start:e[o][1].start,end:e[i][1].end},r={type:"chunkText",start:e[o][1].start,end:e[i][1].end,contentType:"text"},u(e,o,i-o+1,[["enter",n,t],["enter",r,t],["exit",r,t],["exit",n,t]]));return e};var r=n(0),i=n(3),o=n(2),u=n(5),c=n(1)},function(e,t,n){t.tokenize=function(e,t,n){var c;return function(t){return e.enter("autolink"),e.enter("autolinkMarker"),e.consume(t),e.exit("autolinkMarker"),e.enter("autolinkProtocol"),a};function a(t){return r(t)?(e.consume(t),c=1,s):o(t)?p(t):n(t)}function s(e){return 43===e||45===e||46===e||i(e)?l(e):p(e)}function l(t){return 58===t?(e.consume(t),f):(43===t||45===t||46===t||i(t))&&c++<32?(e.consume(t),l):p(t)}function f(t){return 62===t?(e.exit("autolinkProtocol"),v(t)):32===t||60===t||u(t)?n(t):(e.consume(t),f)}function p(t){return 64===t?(e.consume(t),c=0,h):o(t)?(e.consume(t),p):n(t)}function h(e){return i(e)?d(e):n(e)}function d(t){return 46===t?(e.consume(t),c=0,h):62===t?(e.exit("autolinkProtocol").type="autolinkEmail",v(t)):m(t)}function m(t){return(45===t||i(t))&&c++<63?(e.consume(t),45===t?m:d):n(t)}function v(n){return e.enter("autolinkMarker"),e.consume(n),e.exit("autolinkMarker"),e.exit("autolink"),t}};var r=n(20),i=n(14),o=n(75),u=n(33)},function(e,t,n){var r=n(4);e.exports=r(/[#-'*+\--9=?A-Z^-~]/)},function(e,t,n){t.tokenize=function(e,t,n){var a,l=this,p=o(l.events,"linePrefix");return function(t){if(!(42!==t&&43!==t&&45!==t||l.containerState.marker&&t!==l.containerState.marker))return 42===t||45===t?e.check(c,n,h)(t):h(t);if(i(t)&&(!l.containerState.type||"listOrdered"===l.containerState.type))return function(t){if(l.containerState.type||!l.interrupt||49===t)return l.containerState.type||(l.containerState.type="listOrdered",e.enter(l.containerState.type,{_container:!0})),e.enter("listItemPrefix"),e.enter("listItemValue"),e.consume(t),a=1,l.interrupt?m:d;return n(t)}(t);return n(t)};function h(t){return l.containerState.type||(l.containerState.type="listUnordered",e.enter(l.containerState.type,{_container:!0})),e.enter("listItemPrefix"),v(t)}function d(t){return i(t)&&++a<10?(e.consume(t),d):m(t)}function m(t){return e.exit("listItemValue"),41===t||46===t?v(t):n(t)}function v(t){return l.containerState.marker=l.containerState.marker||t,t===l.containerState.marker?(e.enter("listItemMarker"),e.consume(t),e.exit("listItemMarker"),e.check(s,l.interrupt?n:x,e.attempt({tokenize:f,partial:!0},k,g))):n(t)}function x(e){return l.containerState.initialBlankLine=!0,p++,k(e)}function g(t){return r(t)?(e.enter("listItemPrefixWhitespace"),e.consume(t),e.exit("listItemPrefixWhitespace"),k):n(t)}function k(n){return l.containerState.size=p+u(l.sliceStream(e.exit("listItemPrefix"))),t(n)}},t.continuation={tokenize:function(e,n,i){var o=this;return o.containerState._closeFlow=void 0,e.check(s,(function(e){return o.containerState.furtherBlankLines=o.containerState.furtherBlankLines||o.containerState.initialBlankLine,n(e)}),(function(t){if(o.containerState.furtherBlankLines||!r(t))return o.containerState.furtherBlankLines=o.containerState.initialBlankLine=void 0,u(t);return o.containerState.furtherBlankLines=o.containerState.initialBlankLine=void 0,e.attempt({tokenize:l,partial:!0},n,u)(t)}));function u(r){return o.containerState._closeFlow=!0,o.interrupt=void 0,a(e,e.attempt(t,n,i),"linePrefix",4)(r)}}},t.exit=function(e){e.exit(this.containerState.type)};var r=n(2),i=n(34),o=n(13),u=n(31),c=n(35),a=n(1),s=n(11);function l(e,t,n){var r=this;return a(e,(function(e){return o(r.events,"listItemIndent")===r.containerState.size?t(e):n(e)}),"listItemIndent",r.containerState.size+1)}function f(e,t,n){var i=this;return a(e,(function(e){return r(e)||!o(i.events,"listItemPrefixWhitespace")?n(e):t(e)}),"listItemPrefixWhitespace",5)}},function(e,t,n){t.tokenize=function(e,t,n){var i=this;return function(t){if(62===t)return i.containerState.open||(e.enter("blockQuote",{_container:!0}),i.containerState.open=!0),e.enter("blockQuotePrefix"),e.enter("blockQuoteMarker"),e.consume(t),e.exit("blockQuoteMarker"),o;return n(t)};function o(n){return r(n)?(e.enter("blockQuotePrefixWhitespace"),e.consume(n),e.exit("blockQuotePrefixWhitespace"),e.exit("blockQuotePrefix"),t):(e.exit("blockQuotePrefix"),t(n))}},t.continuation={tokenize:function(e,n,r){return i(e,e.attempt(t,n,r),"linePrefix",4)}},t.exit=function(e){e.exit("blockQuote")};var r=n(2),i=n(1)},function(e,t,n){t.tokenize=function(e,t,n){return function(t){return e.enter("characterEscape"),e.enter("escapeMarker"),e.consume(t),e.exit("escapeMarker"),i};function i(i){return r(i)?(e.enter("characterEscapeValue"),e.consume(i),e.exit("characterEscapeValue"),e.exit("characterEscape"),t):n(i)}};var r=n(79)},function(e,t,n){var r=n(4);e.exports=r(/[!-/:-@[-`{-~]/)},function(e,t,n){t.tokenize=function(e,t,n){var c,a,s=this,l=0;return function(t){return e.enter("characterReference"),e.enter("characterReferenceMarker"),e.consume(t),e.exit("characterReferenceMarker"),f};function f(t){return 35===t?(e.enter("characterReferenceMarkerNumeric"),e.consume(t),e.exit("characterReferenceMarkerNumeric"),p):(e.enter("characterReferenceValue"),c=31,a=i,h(t))}function p(t){return 88===t||120===t?(e.enter("characterReferenceMarkerHexadecimal"),e.consume(t),e.exit("characterReferenceMarkerHexadecimal"),e.enter("characterReferenceValue"),c=6,a=u,h):(e.enter("characterReferenceValue"),c=7,a=o,h(t))}function h(o){var u;return 59===o&&l?(u=e.exit("characterReferenceValue"),a!==i||r(s.sliceSerialize(u))?(e.enter("characterReferenceMarker"),e.consume(o),e.exit("characterReferenceMarker"),e.exit("characterReference"),t):n(o)):a(o)&&l++-1?(f=1,x.interrupt?t(r):D(r)):s.indexOf(d.toLowerCase())>-1?(f=6,47===r?(e.consume(r),E):x.interrupt?t(r):D(r)):(f=7,x.interrupt?n(r):h?A(r):S(r)):45===r||i(r)?(e.consume(r),d+=a(r),F):n(r)}function E(r){return 62===r?(e.consume(r),x.interrupt?t:D):n(r)}function S(t){return c(t)?(e.consume(t),S):_(t)}function A(t){return 47===t?(e.consume(t),_):58===t||95===t||r(t)?(e.consume(t),C):c(t)?(e.consume(t),A):_(t)}function C(t){return 45===t||46===t||58===t||95===t||i(t)?(e.consume(t),C):T(t)}function T(t){return 61===t?(e.consume(t),z):c(t)?(e.consume(t),T):A(t)}function z(t){return null===t||60===t||61===t||62===t||96===t?n(t):34===t||39===t?(e.consume(t),v=t,I):c(t)?(e.consume(t),z):(v=void 0,B(t))}function I(t){return t===v?(e.consume(t),P):null===t||o(t)?n(t):(e.consume(t),I)}function B(t){return null===t||34===t||39===t||60===t||61===t||62===t||96===t||u(t)?T(t):(e.consume(t),B)}function P(e){return 47===e||62===e||c(e)?A(e):n(e)}function _(t){return 62===t?(e.consume(t),M):n(t)}function M(t){return c(t)?(e.consume(t),M):null===t||o(t)?D(t):n(t)}function D(t){return 45===t&&2===f?(e.consume(t),j):60===t&&1===f?(e.consume(t),R):62===t&&4===f?(e.consume(t),Q):63===t&&3===f?(e.consume(t),V):93===t&&5===f?(e.consume(t),H):!o(t)||6!==f&&7!==f?null===t||o(t)?L(t):(e.consume(t),D):e.check(p,Q,L)(t)}function L(t){return e.exit("htmlFlowData"),O(t)}function O(t){return null===t?U(t):o(t)?(e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),O):(e.enter("htmlFlowData"),D(t))}function j(t){return 45===t?(e.consume(t),V):D(t)}function R(t){return 47===t?(e.consume(t),d="",q):D(t)}function q(t){return 62===t&&l.indexOf(d.toLowerCase())>-1?(e.consume(t),Q):r(t)&&d.length<6?(e.consume(t),d+=a(t),q):D(t)}function H(t){return 93===t?(e.consume(t),V):D(t)}function V(t){return 62===t?(e.consume(t),Q):D(t)}function Q(t){return null===t||o(t)?(e.exit("htmlFlowData"),U(t)):(e.consume(t),Q)}function U(n){return e.exit("htmlFlow"),t(n)}},t.resolveTo=function(e){var t=e.length;for(;t--&&("enter"!==e[t][0]||"htmlFlow"!==e[t][1].type););t>1&&"linePrefix"===e[t-2][1].type&&(e[t][1].start=e[t-2][1].start,e[t+1][1].start=e[t-2][1].start,e.splice(t-2,2));return e},t.concrete=!0;var r=n(20),i=n(14),o=n(0),u=n(3),c=n(2),a=n(10),s=n(88),l=n(89),f=n(11),p={tokenize:function(e,t,n){return function(r){return e.exit("htmlFlowData"),e.enter("lineEndingBlank"),e.consume(r),e.exit("lineEndingBlank"),e.attempt(f,t,n)}},partial:!0}},function(e,t){e.exports=["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","section","source","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"]},function(e,t){e.exports=["pre","script","style"]},function(e,t,n){t.tokenize=function(e,t,n){var s,l,f,p;return function(t){return e.enter("htmlText"),e.enter("htmlTextData"),e.consume(t),h};function h(t){return 33===t?(e.consume(t),d):47===t?(e.consume(t),C):63===t?(e.consume(t),S):u(t)?(e.consume(t),I):n(t)}function d(t){return 45===t?(e.consume(t),m):91===t?(e.consume(t),l="CDATA[",f=0,y):u(t)?(e.consume(t),E):n(t)}function m(t){return 45===t?(e.consume(t),v):n(t)}function v(t){return null===t||62===t?n(t):45===t?(e.consume(t),x):g(t)}function x(e){return null===e||62===e?n(e):g(e)}function g(t){return null===t?n(t):45===t?(e.consume(t),k):r(t)?(p=g,j(t)):(e.consume(t),g)}function k(t){return 45===t?(e.consume(t),q):g(t)}function y(t){return t===l.charCodeAt(f++)?(e.consume(t),f===l.length?b:y):n(t)}function b(t){return null===t?n(t):93===t?(e.consume(t),w):(e.consume(t),b)}function w(t){return 93===t?(e.consume(t),F):b(t)}function F(t){return 62===t?q(t):93===t?(e.consume(t),F):b(t)}function E(t){return null===t||62===t?q(t):r(t)?(p=E,j(t)):(e.consume(t),E)}function S(t){return null===t?n(t):63===t?(e.consume(t),A):r(t)?(p=S,j(t)):(e.consume(t),S)}function A(e){return 62===e?q(e):S(e)}function C(t){return u(t)?(e.consume(t),T):n(t)}function T(t){return 45===t||c(t)?(e.consume(t),T):z(t)}function z(t){return r(t)?(p=z,j(t)):o(t)?(e.consume(t),z):q(t)}function I(t){return 45===t||c(t)?(e.consume(t),I):47===t||62===t||i(t)?B(t):n(t)}function B(t){return 47===t?(e.consume(t),q):58===t||95===t||u(t)?(e.consume(t),P):r(t)?(p=B,j(t)):o(t)?(e.consume(t),B):q(t)}function P(t){return 45===t||46===t||58===t||95===t||c(t)?(e.consume(t),P):_(t)}function _(t){return 61===t?(e.consume(t),M):r(t)?(p=_,j(t)):o(t)?(e.consume(t),_):B(t)}function M(t){return null===t||60===t||61===t||62===t||96===t?n(t):34===t||39===t?(e.consume(t),s=t,D):r(t)?(p=M,j(t)):o(t)?(e.consume(t),M):(e.consume(t),s=void 0,O)}function D(t){return t===s?(e.consume(t),L):null===t?n(t):r(t)?(p=D,j(t)):(e.consume(t),D)}function L(e){return 62===e||47===e||i(e)?B(e):n(e)}function O(t){return null===t||34===t||39===t||60===t||61===t||96===t?n(t):62===t||i(t)?B(t):(e.consume(t),O)}function j(t){return e.exit("htmlTextData"),e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),a(e,R,"linePrefix",4)}function R(t){return e.enter("htmlTextData"),p(t)}function q(r){return 62===r?(e.consume(r),e.exit("htmlTextData"),e.exit("htmlText"),t):n(r)}};var r=n(0),i=n(3),o=n(2),u=n(20),c=n(14),a=n(1)},function(e,t,n){t.tokenize=function(e,t,n){var r=this;return function(t){return e.enter("labelImage"),e.enter("labelImageMarker"),e.consume(t),e.exit("labelImageMarker"),i};function i(t){return 91===t?(e.enter("labelMarker"),e.consume(t),e.exit("labelMarker"),e.exit("labelImage"),o):n(t)}function o(e){return 94===e&&"_hiddenFootnoteSupport"in r.parser.constructs?n(e):t(e)}},t.resolveAll=n(21).resolveAll},function(e,t,n){t.tokenize=function(e,t,n){var r=this;return function(t){return e.enter("labelLink"),e.enter("labelMarker"),e.consume(t),e.exit("labelMarker"),e.exit("labelLink"),i};function i(e){return 94===e&&"_hiddenFootnoteSupport"in r.parser.constructs?n(e):t(e)}},t.resolveAll=n(21).resolveAll},function(e,t,n){t.tokenize=function(e,t,n){var i,u,c=this,a=c.events.length;for(;a--;)if("lineEnding"!==c.events[a][1].type&&"linePrefix"!==c.events[a][1].type&&"content"!==c.events[a][1].type){u="paragraph"===c.events[a][1].type;break}return function(t){if(!c.lazy&&(c.interrupt||u))return e.enter("setextHeadingLine"),e.enter("setextHeadingLineSequence"),i=t,s(t);return n(t)};function s(t){return t===i?(e.consume(t),s):(e.exit("setextHeadingLineSequence"),o(e,l,"lineSuffix")(t))}function l(i){return null===i||r(i)?(e.exit("setextHeadingLine"),t(i)):n(i)}},t.resolveTo=function(e,t){var n,r,o,u,c=e.length;for(;c--;)if("enter"===e[c][0]){if("content"===e[c][1].type){n=c;break}"paragraph"===e[c][1].type&&(r=c)}else"content"===e[c][1].type&&e.splice(c,1),o||"definition"!==e[c][1].type||(o=c);u={type:"setextHeading",start:i(e[r][1].start),end:i(e[e.length-1][1].end)},e[r][1].type="setextHeadingText",o?(e.splice(r,0,["enter",u,t]),e.splice(o+1,0,["exit",e[n][1],t]),e[n][1].end=i(e[o][1].end)):e[n][1]=u;return e.push(["exit",u,t]),e};var r=n(0),i=n(7),o=n(1)},function(e,t,n){t.tokenize=function(e,t){return function(n){return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),r(e,t,"linePrefix")}};n(0);var r=n(1)},function(e,t,n){e.exports=function(e,t,n){var f=n?u(n):{line:1,column:1,offset:0},p={},h=[],d=[],m=[],v={consume:function(e){i(e)?(f.line++,f.column=1,f.offset+=-3===e?2:1,A()):-1!==e&&(f.column++,f.offset++);f._bufferIndex<0?f._index++:(f._bufferIndex++,f._bufferIndex===d[f._index].length&&(f._bufferIndex=-1,f._index++));x.previous=e,!0},enter:function(e,t){var n=t||{};return n.type=e,n.start=y(),x.events.push(["enter",n,x]),m.push(n),n},exit:function(e){var t=m.pop();return t.end=y(),x.events.push(["exit",t,x]),t},attempt:E((function(e,t){S(e,t.from)})),check:E(F),interrupt:E(F,{interrupt:!0}),lazy:E(F,{lazy:!0})},x={previous:null,events:[],parser:e,sliceStream:k,sliceSerialize:function(e){return c(k(e))},now:y,defineSkip:function(e){p[e.line]=e.column,A()},write:function(e){if(o(d,d.length,0,e),b(),null!==d[d.length-1])return[];return S(t,0),x.events=s(h,x.events,x),x.events}},g=t.tokenize.call(x,v);t.resolveAll&&h.push(t);return f._index=0,f._bufferIndex=-1,x;function k(e){return a(d,e)}function y(){return u(f)}function b(){for(var e,t;f._index-1&&(n[0]=n[0].slice(i)),u>0&&n.push(e[o].slice(0,u)));return n}},function(e,t,n){e.exports=function(e){var t={},n=-1;for(;++n"+(n?"":" ")+e}},function(e,t,n){e.exports=function(e,t,n){var l,f,p,h,d=u(n),m=e.value||"",v="`"===d?"GraveAccent":"Tilde";o(e,n)?(p=n.enter("codeIndented"),l=c(m,s)):(f=r(d,Math.max(i(m,d)+1,3)),p=n.enter("codeFenced"),l=f,e.lang&&(h=n.enter("codeFencedLang"+v),l+=a(n,e.lang,{before:"`",after:" ",encode:["`"]}),h()),e.lang&&e.meta&&(h=n.enter("codeFencedMeta"+v),l+=" "+a(n,e.meta,{before:" ",after:"\n",encode:["`"]}),h()),l+="\n",m&&(l+=m+"\n"),l+=f);return p(),l};var r=n(9),i=n(108),o=n(41),u=n(109),c=n(23),a=n(6);function s(e,t,n){return(n?"":" ")+e}},function(e,t,n){"use strict";e.exports=function(e,t){var n,r,i=0,o=0;if("string"!=typeof t||1!==t.length)throw new Error("Expected character");e=String(e),r=e.indexOf(t),n=r;for(;-1!==r;)i++,r===n?i>o&&(o=i):i=1,n=r+1,r=e.indexOf(t,n);return o}},function(e,t){e.exports=function(e){var t=e.options.fence||"`";if("`"!==t&&"~"!==t)throw new Error("Cannot serialize code with `"+t+"` for `options.fence`, expected `` ` `` or `~`");return t}},function(e,t,n){e.exports=function(e,t,n){var u=i(n),c='"'===u?"Quote":"Apostrophe",a=n.enter("definition"),s=n.enter("label"),l="["+o(n,r(e),{before:"[",after:"]"})+"]: ";s(),!e.url||/[ \t\r\n]/.test(e.url)?(s=n.enter("destinationLiteral"),l+="<"+o(n,e.url,{before:"<",after:">"})+">"):(s=n.enter("destinationRaw"),l+=o(n,e.url,{before:" ",after:" "}));s(),e.title&&(s=n.enter("title"+c),l+=" "+u+o(n,e.title,{before:u,after:u})+u,s());return a(),l};var r=n(24),i=n(25),o=n(6)},function(e,t,n){e.exports=o,o.peek=function(e,t,n){return n.options.emphasis||"*"};var r=n(112),i=n(8);function o(e,t,n){var o=r(n),u=n.enter("emphasis"),c=i(e,n,{before:o,after:o});return u(),o+c+o}},function(e,t){e.exports=function(e){var t=e.options.emphasis||"*";if("*"!==t&&"_"!==t)throw new Error("Cannot serialize emphasis with `"+t+"` for `options.emphasis`, expected `*`, or `_`");return t}},function(e,t,n){e.exports=function(e,t,n){var u,c,a,s,l=Math.max(Math.min(6,e.depth||1),1);if(i(e,n))return u=n.enter("headingSetext"),c=n.enter("phrasing"),a=o(e,n,{before:"\n",after:"\n"}),c(),u(),a+"\n"+r(1===l?"=":"-",a.length-(Math.max(a.lastIndexOf("\r"),a.lastIndexOf("\n"))+1));s=r("#",l),u=n.enter("headingAtx"),c=n.enter("phrasing"),a=(a=o(e,n,{before:"# ",after:"\n"}))?s+" "+a:s,n.options.closeAtx&&(a+=" "+s);return c(),u(),a};var r=n(9),i=n(42),o=n(8)},function(e,t){e.exports=function(e){return e.value||""}},function(e,t,n){e.exports=o,o.peek=function(){return"!"};var r=n(25),i=n(6);function o(e,t,n){var o=r(n),u='"'===o?"Quote":"Apostrophe",c=n.enter("image"),a=n.enter("label"),s="!["+i(n,e.alt,{before:"[",after:"]"})+"](";return a(),!e.url&&e.title||/[ \t\r\n]/.test(e.url)?(a=n.enter("destinationLiteral"),s+="<"+i(n,e.url,{before:"<",after:">"})+">"):(a=n.enter("destinationRaw"),s+=i(n,e.url,{before:"(",after:e.title?" ":")"})),a(),e.title&&(a=n.enter("title"+u),s+=" "+o+i(n,e.title,{before:o,after:o})+o,a()),s+=")",c(),s}},function(e,t,n){e.exports=o,o.peek=function(){return"!"};var r=n(24),i=n(6);function o(e,t,n){var o,u,c=e.referenceType,a=n.enter("imageReference"),s=n.enter("label"),l=i(n,e.alt,{before:"[",after:"]"}),f="!["+l+"]";return s(),u=n.stack,n.stack=[],s=n.enter("reference"),o=i(n,r(e),{before:"[",after:"]"}),s(),n.stack=u,a(),"full"!==c&&l&&l===o?"shortcut"!==c&&(f+="[]"):f+="["+o+"]",f}},function(e,t){function n(e){for(var t=e.value||"",n="`",r="";new RegExp("(^|[^`])"+n+"([^`]|$)").test(t);)n+="`";return/[^ \r\n]/.test(t)&&(/[ \r\n`]/.test(t.charAt(0))||/[ \r\n`]/.test(t.charAt(t.length-1)))&&(r=" "),n+r+t+r+n}e.exports=n,n.peek=function(){return"`"}},function(e,t,n){e.exports=c,c.peek=function(e){return i(e)?"<":"["};var r=n(25),i=n(119),o=n(8),u=n(6);function c(e,t,n){var c,a,s,l,f=r(n),p='"'===f?"Quote":"Apostrophe";return i(e)?(l=n.stack,n.stack=[],c=n.enter("autolink"),s="<"+o(e,n,{before:"<",after:">"})+">",c(),n.stack=l,s):(c=n.enter("link"),a=n.enter("label"),s="["+o(e,n,{before:"[",after:"]"})+"](",a(),!e.url&&e.title||/[ \t\r\n]/.test(e.url)?(a=n.enter("destinationLiteral"),s+="<"+u(n,e.url,{before:"<",after:">"})+">"):(a=n.enter("destinationRaw"),s+=u(n,e.url,{before:"(",after:e.title?" ":")"})),a(),e.title&&(a=n.enter("title"+p),s+=" "+f+u(n,e.title,{before:f,after:f})+f,a()),s+=")",c(),s)}},function(e,t,n){e.exports=function(e){var t=r(e);return e.url&&!e.title&&(t===e.url||"mailto:"+t===e.url)&&/^[a-z][a-z+.-]+:/i.test(e.url)&&!/[\0- <>\u007F]/.test(e.url)};var r=n(17)},function(e,t,n){e.exports=u,u.peek=function(){return"["};var r=n(24),i=n(8),o=n(6);function u(e,t,n){var u,c,a=e.referenceType,s=n.enter("linkReference"),l=n.enter("label"),f=i(e,n,{before:"[",after:"]"}),p="["+f+"]";return l(),c=n.stack,n.stack=[],l=n.enter("reference"),u=o(n,r(e),{before:"[",after:"]"}),l(),n.stack=c,s(),"full"!==a&&f&&f===u?"shortcut"!==a&&(p+="[]"):p+="["+u+"]",p}},function(e,t,n){e.exports=function(e,t,n){var i=n.enter("list"),o=r(e,n);return i(),o};var r=n(15)},function(e,t,n){e.exports=function(e,t,n){var a,s,l,f=i(n),p=o(n);t&&t.ordered&&(f=(t.start>-1?t.start:1)+(!1===n.options.incrementListMarker?0:t.children.indexOf(e))+".");a=f.length+1,("tab"===p||"mixed"===p&&(t&&t.spread||e.spread))&&(a=4*Math.ceil(a/4));return l=n.enter("listItem"),s=c(u(e,n),(function(e,t,n){if(t)return(n?"":r(" ",a))+e;return(n?f:f+r(" ",a-f.length))+e})),l(),s};var r=n(9),i=n(123),o=n(124),u=n(15),c=n(23)},function(e,t){e.exports=function(e){var t=e.options.bullet||"*";if("*"!==t&&"+"!==t&&"-"!==t)throw new Error("Cannot serialize items with `"+t+"` for `options.bullet`, expected `*`, `+`, or `-`");return t}},function(e,t){e.exports=function(e){var t=e.options.listItemIndent||"tab";if(1===t||"1"===t)return"one";if("tab"!==t&&"one"!==t&&"mixed"!==t)throw new Error("Cannot serialize items with `"+t+"` for `options.listItemIndent`, expected `tab`, `one`, or `mixed`");return t}},function(e,t,n){e.exports=function(e,t,n){var i=n.enter("paragraph"),o=n.enter("phrasing"),u=r(e,n,{before:"\n",after:"\n"});return o(),i(),u};var r=n(8)},function(e,t,n){e.exports=function(e,t,n){return r(e,n)};var r=n(15)},function(e,t,n){e.exports=o,o.peek=function(e,t,n){return n.options.strong||"*"};var r=n(128),i=n(8);function o(e,t,n){var o=r(n),u=n.enter("strong"),c=i(e,n,{before:o,after:o});return u(),o+o+c+o+o}},function(e,t){e.exports=function(e){var t=e.options.strong||"*";if("*"!==t&&"_"!==t)throw new Error("Cannot serialize strong with `"+t+"` for `options.strong`, expected `*`, or `_`");return t}},function(e,t,n){e.exports=function(e,t,n,i){return r(n,e.value,i)};var r=n(6)},function(e,t,n){e.exports=function(e,t,n){var u=r(o(n)+(n.options.ruleSpaces?" ":""),i(n));return n.options.ruleSpaces?u.slice(0,-1):u};var r=n(9),i=n(131),o=n(132)},function(e,t){e.exports=function(e){var t=e.options.ruleRepetition||3;if(t<3)throw new Error("Cannot serialize rules with repetition `"+t+"` for `options.ruleRepetition`, expected `3` or more");return t}},function(e,t){e.exports=function(e){var t=e.options.rule||"*";if("*"!==t&&"-"!==t&&"_"!==t)throw new Error("Cannot serialize rules with `"+t+"` for `options.rule`, expected `*`, `-`, or `_`");return t}},function(e,t){e.exports=[{character:"\t",inConstruct:["codeFencedLangGraveAccent","codeFencedLangTilde"]},{character:"\r",inConstruct:["codeFencedLangGraveAccent","codeFencedLangTilde","codeFencedMetaGraveAccent","codeFencedMetaTilde","destinationLiteral","headingAtx"]},{character:"\n",inConstruct:["codeFencedLangGraveAccent","codeFencedLangTilde","codeFencedMetaGraveAccent","codeFencedMetaTilde","destinationLiteral","headingAtx"]},{character:" ",inConstruct:["codeFencedLangGraveAccent","codeFencedLangTilde"]},{character:"!",after:"\\[",inConstruct:"phrasing"},{character:'"',inConstruct:"titleQuote"},{atBreak:!0,character:"#"},{character:"&",after:"[#A-Za-z]",inConstruct:"phrasing"},{character:"'",inConstruct:"titleApostrophe"},{character:"(",inConstruct:"destinationRaw"},{before:"\\]",character:"(",inConstruct:"phrasing"},{atBreak:!0,before:"\\d+",character:")"},{character:")",inConstruct:"destinationRaw"},{atBreak:!0,character:"*"},{character:"*",inConstruct:"phrasing"},{atBreak:!0,character:"+"},{atBreak:!0,character:"-"},{atBreak:!0,before:"\\d+",character:".",after:"(?:[ \t\r\n]|$)"},{atBreak:!0,character:"<",after:"[!/?A-Za-z]"},{character:"<",after:"[!/?A-Za-z]",inConstruct:"phrasing"},{character:"<",inConstruct:"destinationLiteral"},{atBreak:!0,character:"="},{atBreak:!0,character:">"},{character:">",inConstruct:"destinationLiteral"},{atBreak:!0,character:"["},{character:"[",inConstruct:["phrasing","label","reference"]},{character:"\\",after:"[!-/:-@[-`{-~]"},{character:"\\",after:"[\\r\\n]",inConstruct:"phrasing"},{character:"]",inConstruct:["label","reference"]},{atBreak:!0,character:"_"},{before:"[^A-Za-z]",character:"_",inConstruct:"phrasing"},{character:"_",after:"[^A-Za-z]",inConstruct:"phrasing"},{atBreak:!0,character:"`"},{character:"`",inConstruct:["codeFencedLangGraveAccent","codeFencedMetaGraveAccent","phrasing"]},{atBreak:!0,character:"~"}]},function(e,t,n){e.exports=[function(e,t,n,o){if("list"===t.type&&t.type===e.type&&Boolean(e.ordered)===Boolean(t.ordered)||"code"===t.type&&r(t,o)&&("list"===e.type||e.type===t.type&&r(e,o)))return!1;if("boolean"==typeof n.spread){if("paragraph"===e.type&&(e.type===t.type||"definition"===t.type||"heading"===t.type&&i(t,o)))return;return n.spread?1:0}}];var r=n(41),i=n(42)},function(e,t,n){"use strict";function r(e){switch(e.level){case 1:return"# ".concat(e.text,"\n");case 2:return"## ".concat(e.text,"\n");case 3:return"### ".concat(e.text,"\n");case 4:return"#### ".concat(e.text,"\n");case 5:return"##### ".concat(e.text,"\n");case 6:return"###### ".concat(e.text,"\n")}}function i(e){var t={};switch(e.depth){case 1:return e.children.forEach((function(e){t={data:{level:1,text:e.value},type:"header"}})),t;case 2:return e.children.forEach((function(e){t={data:{level:2,text:e.value},type:"header"}})),t;case 3:return e.children.forEach((function(e){t={data:{level:3,text:e.value},type:"header"}})),t;case 4:return e.children.forEach((function(e){t={data:{level:4,text:e.value},type:"header"}})),t;case 5:return e.children.forEach((function(e){t={data:{level:5,text:e.value},type:"header"}})),t;case 6:return e.children.forEach((function(e){t={data:{level:6,text:e.value},type:"header"}})),t}}function o(e){switch(e.style){case"unordered":return e.items.map((function(e){return"* ".concat(e)}));case"ordered":return e.items.map((function(e,t){return"".concat(t+1," ").concat(e)}))}}function u(e){var t=[];return e.children.forEach((function(e){e.children.forEach((function(e){e.children.forEach((function(e){t.push(e.value)}))}))})),{data:{items:t,style:e.ordered?"ordered":"unordered"},type:"list"}}function c(e){return"![".concat(e.caption,"](").concat(e.url,' "').concat(e.caption,'")').concat("\n")}function a(e){return e.items.map((function(e){return!0===e.checked?"- [x] ".concat(e.text):"- [ ] ".concat(e.text)})).join("\n")}function s(e){return"> ".concat(e.text,"\n")}function l(e){var t={};return e.children.forEach((function(e){e.children.forEach((function(e){"text"===e.type&&(t={data:{alignment:"left",caption:"",text:e.value},type:"quote"})}))})),t}function f(e){return"```\n".concat(e.code,"\n```\n")}function p(e){return{data:{code:e.value},type:"code"}}function h(e,t,n,r,i,o,u){try{var c=e[o](u),a=c.value}catch(e){return void n(e)}c.done?t(a):Promise.resolve(a).then(r,i)}function d(e,t){for(var n=0;n'}}}],n&&d(t.prototype,n),i&&d(t,i),e}(),v=n(26);function x(e,t,n,r,i,o,u){try{var c=e[o](u),a=c.value}catch(e){return void n(e)}c.done?t(a):Promise.resolve(a).then(r,i)}function g(e,t){for(var n=0;n'}}}],n&&g(t.prototype,n),r&&g(t,r),e}()}])})); -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 40 | 41 | 42 | 43 | 44 | 45 |

Editor.js - Markdown Importer/Exporter Plugin

46 |
47 |
48 | 49 |

 50 |     
51 | 52 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "build": "webpack --mode production", 4 | "build:dev": "webpack --mode development --watch", 5 | "dev": "webpack-dev-server" 6 | }, 7 | "devDependencies": { 8 | "@babel/core": "^7.11.4", 9 | "@babel/preset-env": "^7.11.0", 10 | "babel-loader": "^8.1.0", 11 | "eslint": "^7.7.0", 12 | "eslint-config-airbnb-base": "14.2.0", 13 | "eslint-loader": "^4.0.2", 14 | "eslint-plugin-import": "2.22.0", 15 | "webpack": "^4.44.1", 16 | "webpack-cli": "^3.3.12", 17 | "webpack-dev-server": "^3.11.0", 18 | "webpack-merge-and-include-globally": "^2.1.26" 19 | }, 20 | "name": "editorjsMdParser", 21 | "description": "Import from markdown and export editorjs data to markdown", 22 | "version": "1.0.0", 23 | "main": "./dist/bundle.js", 24 | "dependencies": { 25 | "css-loader": "^5.0.0", 26 | "remark": "^13.0.0", 27 | "require": "^2.4.20", 28 | "style-loader": "^2.0.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/BlockTypeParsers/CheckboxTypeParser.js: -------------------------------------------------------------------------------- 1 | export function parseCheckboxToMarkdown(blocks) { 2 | let items = {}; 3 | 4 | items = blocks.items.map((item) => { 5 | if (item.checked === true) { 6 | return `- [x] ${item.text}`; 7 | } 8 | return `- [ ] ${item.text}`; 9 | }); 10 | 11 | return items.join('\n'); 12 | } 13 | -------------------------------------------------------------------------------- /src/BlockTypeParsers/CodeTypeParser.js: -------------------------------------------------------------------------------- 1 | export function parseCodeToMarkdown(blocks) { 2 | return `\`\`\`\n${blocks.code}\n\`\`\`\n`; 3 | } 4 | 5 | export function parseMarkdownToCode(blocks) { 6 | const codeData = { 7 | data: { 8 | code: blocks.value, 9 | }, 10 | type: 'code', 11 | }; 12 | 13 | return codeData; 14 | } 15 | -------------------------------------------------------------------------------- /src/BlockTypeParsers/DelimiterTypeParser.js: -------------------------------------------------------------------------------- 1 | export function parseDelimiterToMarkdown() { 2 | const delimiter = '---'; 3 | 4 | return delimiter.concat('\n'); 5 | } 6 | 7 | export function parseMarkdownToDelimiter() { 8 | let delimiterData = {}; 9 | 10 | delimiterData = { 11 | data: { 12 | items: [], 13 | }, 14 | type: 'delimiter', 15 | }; 16 | 17 | return delimiterData; 18 | } 19 | -------------------------------------------------------------------------------- /src/BlockTypeParsers/HeaderTypeParser.js: -------------------------------------------------------------------------------- 1 | export function parseHeaderToMarkdown(blocks) { 2 | switch (blocks.level) { 3 | case 1: 4 | return `# ${blocks.text}\n`; 5 | case 2: 6 | return `## ${blocks.text}\n`; 7 | case 3: 8 | return `### ${blocks.text}\n`; 9 | case 4: 10 | return `#### ${blocks.text}\n`; 11 | case 5: 12 | return `##### ${blocks.text}\n`; 13 | case 6: 14 | return `###### ${blocks.text}\n`; 15 | default: 16 | break; 17 | } 18 | } 19 | 20 | export function parseMarkdownToHeader(blocks) { 21 | let headerData = {}; 22 | 23 | switch (blocks.depth) { 24 | case 1: 25 | blocks.children.forEach((item) => { 26 | headerData = { 27 | data: { 28 | level: 1, 29 | text: item.value, 30 | }, 31 | type: 'header', 32 | }; 33 | }); 34 | 35 | return headerData; 36 | case 2: 37 | blocks.children.forEach((item) => { 38 | headerData = { 39 | data: { 40 | level: 2, 41 | text: item.value, 42 | }, 43 | type: 'header', 44 | }; 45 | }); 46 | 47 | return headerData; 48 | case 3: 49 | blocks.children.forEach((item) => { 50 | headerData = { 51 | data: { 52 | level: 3, 53 | text: item.value, 54 | }, 55 | type: 'header', 56 | }; 57 | }); 58 | 59 | return headerData; 60 | case 4: 61 | blocks.children.forEach((item) => { 62 | headerData = { 63 | data: { 64 | level: 4, 65 | text: item.value, 66 | }, 67 | type: 'header', 68 | }; 69 | }); 70 | 71 | return headerData; 72 | case 5: 73 | blocks.children.forEach((item) => { 74 | headerData = { 75 | data: { 76 | level: 5, 77 | text: item.value, 78 | }, 79 | type: 'header', 80 | }; 81 | }); 82 | 83 | return headerData; 84 | case 6: 85 | blocks.children.forEach((item) => { 86 | headerData = { 87 | data: { 88 | level: 6, 89 | text: item.value, 90 | }, 91 | type: 'header', 92 | }; 93 | }); 94 | 95 | return headerData; 96 | default: 97 | break; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/BlockTypeParsers/ImageTypeParser.js: -------------------------------------------------------------------------------- 1 | export function parseImageToMarkdown(blocks) { 2 | return `![${blocks.caption}](${blocks.url} "${blocks.caption}")`.concat('\n'); 3 | } 4 | -------------------------------------------------------------------------------- /src/BlockTypeParsers/ListTypeParser.js: -------------------------------------------------------------------------------- 1 | export function parseListToMarkdown(blocks) { 2 | let items = {}; 3 | switch (blocks.style) { 4 | case 'unordered': 5 | items = blocks.items.map((item) => (`* ${item}`)); 6 | 7 | return items; 8 | case 'ordered': 9 | items = blocks.items.map((item, index) => (`${index + 1} ${item}`)); 10 | 11 | return items; 12 | default: 13 | break; 14 | } 15 | } 16 | 17 | export function parseMarkdownToList(blocks) { 18 | let listData = {}; 19 | const itemData = []; 20 | 21 | blocks.children.forEach((items) => { 22 | items.children.forEach((listItem) => { 23 | listItem.children.forEach((listEntry) => { 24 | itemData.push(listEntry.value); 25 | }); 26 | }); 27 | }); 28 | 29 | listData = { 30 | data: { 31 | items: itemData, 32 | style: blocks.ordered ? 'ordered' : 'unordered', 33 | }, 34 | type: 'list', 35 | }; 36 | 37 | return listData; 38 | } 39 | -------------------------------------------------------------------------------- /src/BlockTypeParsers/ParagraphTypeParser.js: -------------------------------------------------------------------------------- 1 | export function parseParagraphToMarkdown(blocks) { 2 | return `${blocks.text}\n`; 3 | } 4 | 5 | export function parseMarkdownToParagraph(blocks) { 6 | let paragraphData = {}; 7 | 8 | if (blocks.type === 'paragraph') { 9 | blocks.children.forEach((item) => { 10 | if (item.type === 'text') { 11 | paragraphData = { 12 | data: { 13 | text: item.value, 14 | }, 15 | type: 'paragraph', 16 | }; 17 | } 18 | if (item.type === 'image') { 19 | paragraphData = { 20 | data: { 21 | caption: item.title, 22 | stretched: false, 23 | url: item.url, 24 | withBackground: false, 25 | withBorder: false, 26 | }, 27 | type: 'image', 28 | }; 29 | } 30 | }); 31 | } 32 | return paragraphData; 33 | } 34 | -------------------------------------------------------------------------------- /src/BlockTypeParsers/QuoteTypeParser.js: -------------------------------------------------------------------------------- 1 | export function parseQuoteToMarkdown(blocks) { 2 | return `> ${blocks.text}\n`; 3 | } 4 | 5 | export function parseMarkdownToQuote(blocks) { 6 | let quoteData = {}; 7 | 8 | blocks.children 9 | .forEach((items) => { 10 | items.children.forEach((listItem) => { 11 | if (listItem.type === 'text') { 12 | quoteData = { 13 | data: { 14 | alignment: 'left', 15 | caption: '', 16 | text: listItem.value, 17 | }, 18 | type: 'quote', 19 | }; 20 | } 21 | }); 22 | }); 23 | 24 | return quoteData; 25 | } 26 | -------------------------------------------------------------------------------- /src/FileHandler.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Function which takes data and creates a markdown file 3 | * @param content of the file 4 | * @param filename 5 | * 6 | */ 7 | export function fileDownloadHandler(content, fileName) { 8 | const file = new File([content], { type: 'text/markdown', endings: 'transparent' }); 9 | const url = URL.createObjectURL(file); 10 | 11 | const element = document.createElement('a'); 12 | document.body.appendChild(element); 13 | element.href = url; 14 | element.download = fileName; 15 | element.click(); 16 | window.URL.revokeObjectURL(url); 17 | document.body.removeChild(element); 18 | } 19 | -------------------------------------------------------------------------------- /src/MarkdownImporter.js: -------------------------------------------------------------------------------- 1 | import * as remark from 'remark'; 2 | import { parseMarkdownToHeader } from './BlockTypeParsers/HeaderTypeParser'; 3 | import { parseMarkdownToParagraph } from './BlockTypeParsers/ParagraphTypeParser'; 4 | import { parseMarkdownToList } from './BlockTypeParsers/ListTypeParser'; 5 | import { parseMarkdownToDelimiter } from './BlockTypeParsers/DelimiterTypeParser'; 6 | import { parseMarkdownToCode } from './BlockTypeParsers/CodeTypeParser'; 7 | import { parseMarkdownToQuote } from './BlockTypeParsers/QuoteTypeParser'; 8 | 9 | export const editorData = []; 10 | 11 | /** 12 | * Markdown Import class 13 | */ 14 | export default class MarkdownImporter { 15 | /** 16 | * creates the Importer plugin 17 | * {editorData, api functions} - necessary to interact with the editor 18 | */ 19 | constructor({ data, api }) { 20 | this.data = data; 21 | this.api = api; 22 | } 23 | 24 | /** 25 | * @return Plugin data such as title and icon 26 | */ 27 | static get toolbox() { 28 | return { 29 | title: 'Import Markdown', 30 | icon: '', 31 | }; 32 | } 33 | 34 | /** 35 | * @return invinsible file upload form 36 | */ 37 | render() { 38 | const doc = document.createElement('input'); 39 | doc.setAttribute('id', 'file-upload'); 40 | doc.setAttribute('type', 'file'); 41 | doc.setAttribute('style', 'display: none'); 42 | doc.setAttribute('name', 'files[]'); 43 | doc.setAttribute('onload', this.parseMarkdown()); 44 | 45 | return doc; 46 | } 47 | 48 | /** 49 | * Function which parses markdown file to JSON which correspons the the editor structure 50 | * @return Parsed markdown in JSON format 51 | */ 52 | async parseMarkdown() { 53 | // empty the array before running the function again 54 | editorData.length = 0; 55 | 56 | const a = {}; 57 | const data = await this.api.saver.save(); 58 | a.content = data.blocks; 59 | 60 | const fileUpload = document.getElementById('file-upload'); 61 | 62 | fileUpload.onchange = (e) => { 63 | const file = e.target.files[0]; 64 | 65 | const reader = new FileReader(); 66 | reader.readAsText(file, 'UTF-8'); 67 | 68 | reader.onload = (readerEvent) => { 69 | const content = readerEvent.target.result; 70 | 71 | const parsedMarkdown = remark().parse(content); 72 | // iterating over the pared remarkjs syntax tree and executing the json parsers 73 | parsedMarkdown.children.forEach((item, index) => { 74 | switch (item.type) { 75 | case 'heading': 76 | return editorData.push(parseMarkdownToHeader(item)); 77 | case 'paragraph': 78 | return editorData.push(parseMarkdownToParagraph(item)); 79 | case 'list': 80 | return editorData.push(parseMarkdownToList(item)); 81 | case 'thematicBreak': 82 | return editorData.push(parseMarkdownToDelimiter()); 83 | case 'code': 84 | return editorData.push(parseMarkdownToCode(item)); 85 | case 'blockquote': 86 | return editorData.push(parseMarkdownToQuote(item)); 87 | default: 88 | break; 89 | } 90 | }); 91 | // clear the editor 92 | this.api.blocks.clear(); 93 | // render the editor with imported markdown data 94 | this.api.blocks.render({ 95 | blocks: editorData.filter((value) => Object.keys(value).length !== 0), // filter through array and remove empty objects 96 | }); 97 | 98 | return remark().parse(content); 99 | }; 100 | }; 101 | 102 | fileUpload.click(); 103 | } 104 | 105 | save() { 106 | return { 107 | message: 'Uploading Markdown', 108 | }; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/MarkdownParser.js: -------------------------------------------------------------------------------- 1 | import { parseHeaderToMarkdown } from './BlockTypeParsers/HeaderTypeParser'; 2 | import { parseParagraphToMarkdown } from './BlockTypeParsers/ParagraphTypeParser'; 3 | import { parseListToMarkdown } from './BlockTypeParsers/ListTypeParser'; 4 | import { parseDelimiterToMarkdown } from './BlockTypeParsers/DelimiterTypeParser'; 5 | import { parseImageToMarkdown } from './BlockTypeParsers/ImageTypeParser'; 6 | import { parseCheckboxToMarkdown } from './BlockTypeParsers/CheckboxTypeParser'; 7 | import { parseQuoteToMarkdown } from './BlockTypeParsers/QuoteTypeParser'; 8 | import { parseCodeToMarkdown } from './BlockTypeParsers/CodeTypeParser'; 9 | import { fileDownloadHandler } from './FileHandler'; 10 | 11 | /** 12 | * Markdown Parsing class 13 | */ 14 | export default class MarkdownParser { 15 | /** 16 | * creates the Parser plugin 17 | * {editorData, api functions} - necessary to interact with the editor 18 | */ 19 | constructor({ data, api }) { 20 | this.data = data; 21 | this.api = api; 22 | } 23 | 24 | /** 25 | * @return Plugin data such as title and icon 26 | */ 27 | static get toolbox() { 28 | return { 29 | title: 'Download Markdown', 30 | icon: '', 31 | }; 32 | } 33 | 34 | /** 35 | * @return empty div and run the export funtion 36 | */ 37 | render() { 38 | const doc = document.createElement('div'); 39 | 40 | this.getContent(); 41 | return doc; 42 | } 43 | 44 | /** 45 | * Function which takes saved editor data and runs the different parsing helper functions 46 | * @return Markdown file download 47 | */ 48 | async getContent() { 49 | const today = new Date(); 50 | const dd = String(today.getDate()).padStart(2, '0'); 51 | const mm = String(today.getMonth() + 1).padStart(2, '0'); // January is 0! 52 | const yyyy = today.getFullYear(); 53 | 54 | const initialData = {}; 55 | const data = await this.api.saver.save(); 56 | 57 | initialData.content = data.blocks; 58 | 59 | const parsedData = initialData.content.map((item) => { 60 | // iterate through editor data and parse the single blocks to markdown syntax 61 | switch (item.type) { 62 | case 'header': 63 | return parseHeaderToMarkdown(item.data); 64 | case 'paragraph': 65 | return parseParagraphToMarkdown(item.data); 66 | case 'list': 67 | return parseListToMarkdown(item.data); 68 | case 'delimiter': 69 | return parseDelimiterToMarkdown(item); 70 | case 'image': 71 | return parseImageToMarkdown(item.data); 72 | case 'quote': 73 | return parseQuoteToMarkdown(item.data); 74 | case 'checkbox': 75 | return parseCheckboxToMarkdown(item.data); 76 | case 'code': 77 | return parseCodeToMarkdown(item.data); 78 | case 'checklist': 79 | return parseCheckboxToMarkdown(item.data); 80 | default: 81 | break; 82 | } 83 | }); 84 | 85 | // take parsed data and create a markdown file 86 | fileDownloadHandler(parsedData.join('\n'), `entry_${dd}-${mm}-${yyyy}.md`); 87 | } 88 | 89 | save() { 90 | return { 91 | message: 'Downloading Markdown', 92 | }; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import MarkdownParser from './MarkdownParser'; 2 | import MarkdownImporter from './MarkdownImporter'; 3 | 4 | export const MDParser = MarkdownParser; 5 | 6 | export const MDImporter = MarkdownImporter; 7 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | entry: { 5 | bundle: [ 6 | path.resolve(__dirname, 'src/index.js'), 7 | ], 8 | }, 9 | module: { 10 | rules: [ 11 | { 12 | test: /\.js$/, 13 | exclude: /node_modules/, 14 | use: [ 15 | { 16 | loader: 'babel-loader', 17 | }, 18 | ], 19 | }, 20 | { 21 | test: /\.css$/, 22 | use: [ 23 | 'style-loader', 24 | 'css-loader', 25 | ], 26 | }, 27 | ], 28 | }, 29 | node: { global: true, fs: 'empty' }, 30 | output: { 31 | path: path.resolve(__dirname, 'dist'), 32 | filename: '[name].js', 33 | libraryTarget: 'umd', 34 | }, 35 | devServer: { 36 | index: 'index.html', 37 | compress: true, 38 | port: 8000, 39 | }, 40 | }; 41 | --------------------------------------------------------------------------------