diff --git a/.eslintrc b/.eslintrc
index faaa1915fc..bd28db39cc 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -23,5 +23,6 @@
"react": {
"version": "detect"
}
- }
+ },
+ "exclude": ["dist", "node_modules"]
}
diff --git a/package-lock.json b/package-lock.json
index 54df709565..f65e883c78 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2783,7 +2783,7 @@
},
"util": {
"version": "0.10.3",
- "resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
"integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
"dev": true,
"requires": {
@@ -3654,6 +3654,11 @@
"resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.3.tgz",
"integrity": "sha512-yB4oYSAa9yLcGyTbB4ItFwHw43QHdH129IJ5R+WvxOkWlyFnR5FAaBNnUq4mcxsTVZGh28bHoeTHMKXH1wZf3w=="
},
+ "character-entities-html4": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.3.tgz",
+ "integrity": "sha512-SwnyZ7jQBCRHELk9zf2CN5AnGEc2nA+uKMZLHvcqhpPprjkYhiLn0DywMHgN5ttFZuITMATbh68M6VIVKwJbcg=="
+ },
"character-entities-legacy": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.3.tgz",
@@ -4865,6 +4870,11 @@
"esutils": "^2.0.2"
}
},
+ "doctype": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/doctype/-/doctype-2.0.3.tgz",
+ "integrity": "sha512-e7TTDW7yJ3kRJIUdp/w2bkOI8QWVxer0lg0kuAYfM0jzquuL5ZJ0GVfUiIA63ec4mfeTz0vffuoM/jEPUb8v+w=="
+ },
"dom-converter": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz",
@@ -5804,14 +5814,6 @@
"resolved": "https://registry.npmjs.org/fastest-stable-stringify/-/fastest-stable-stringify-1.0.1.tgz",
"integrity": "sha1-kSLUBtTJ2YvqZEpraFPVh0uHsCg="
},
- "fault": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.3.tgz",
- "integrity": "sha512-sfFuP4X0hzrbGKjAUNXYvNqsZ5F6ohx/dZ9I0KQud/aiZNwg263r5L9yGB0clvXHCkzXh5W3t7RSHchggYIFmA==",
- "requires": {
- "format": "^0.2.2"
- }
- },
"faye-websocket": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
@@ -6080,11 +6082,6 @@
"mime-types": "^2.1.12"
}
},
- "format": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
- "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs="
- },
"forwarded": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
@@ -6183,8 +6180,7 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"aproba": {
"version": "1.2.0",
@@ -6205,14 +6201,12 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -6227,20 +6221,17 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"core-util-is": {
"version": "1.0.2",
@@ -6357,8 +6348,7 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"ini": {
"version": "1.3.5",
@@ -6370,7 +6360,6 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -6385,7 +6374,6 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -6393,14 +6381,12 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -6419,7 +6405,6 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -6500,8 +6485,7 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"object-assign": {
"version": "4.1.1",
@@ -6513,7 +6497,6 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"wrappy": "1"
}
@@ -6599,8 +6582,7 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -6636,7 +6618,6 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -6656,7 +6637,6 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -6700,14 +6680,12 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
}
}
},
@@ -7064,6 +7042,30 @@
"xtend": "^4.0.1"
}
},
+ "hast-util-to-html": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-6.0.2.tgz",
+ "integrity": "sha512-oiQzGHtjT6ZLhszCY89kCxGCo9O+YuPUHluv36fzp7Hv/E1W4428PgzcQAKlPUzbHAt3ELoPCSrYLWl8fQw7Ag==",
+ "requires": {
+ "ccount": "^1.0.0",
+ "comma-separated-tokens": "^1.0.1",
+ "hast-util-is-element": "^1.0.0",
+ "hast-util-whitespace": "^1.0.0",
+ "html-void-elements": "^1.0.0",
+ "property-information": "^5.2.0",
+ "space-separated-tokens": "^1.0.0",
+ "stringify-entities": "^2.0.0",
+ "unist-util-is": "^3.0.0",
+ "xtend": "^4.0.1"
+ },
+ "dependencies": {
+ "unist-util-is": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz",
+ "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A=="
+ }
+ }
+ },
"hast-util-to-parse5": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-5.1.1.tgz",
@@ -7086,6 +7088,11 @@
"unist-util-find-after": "^2.0.3"
}
},
+ "hast-util-whitespace": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.3.tgz",
+ "integrity": "sha512-AlkYiLTTwPOyxZ8axq2/bCwRUPjIPBfrHkXuCR92B38b3lSdU22R5F/Z4DL6a2kxWpekWq1w6Nj48tWat6GeRA=="
+ },
"hastscript": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/hastscript/-/hastscript-5.1.0.tgz",
@@ -7658,6 +7665,11 @@
"resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.3.tgz",
"integrity": "sha512-eEMa6MKpHFzw38eKm56iNNi6GJ7lf6aLLio7Kr23sJPAECscgRtZvOBYybejWDQ2bM949Y++61PY+udzj5QMLA=="
},
+ "is-alphanumeric": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz",
+ "integrity": "sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ="
+ },
"is-alphanumerical": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.3.tgz",
@@ -8261,8 +8273,7 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"aproba": {
"version": "1.2.0",
@@ -8283,14 +8294,12 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -8305,20 +8314,17 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"core-util-is": {
"version": "1.0.2",
@@ -8435,8 +8441,7 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"ini": {
"version": "1.3.5",
@@ -8448,7 +8453,6 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -8463,7 +8467,6 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -8471,14 +8474,12 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -8497,7 +8498,6 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -8578,8 +8578,7 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"object-assign": {
"version": "4.1.1",
@@ -8591,7 +8590,6 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"wrappy": "1"
}
@@ -8677,8 +8675,7 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -8714,7 +8711,6 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -8734,7 +8730,6 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -8778,14 +8773,12 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
}
}
},
@@ -9400,6 +9393,11 @@
"integrity": "sha512-p0b6mOGKcGa+7nnmKbpzR6qloPbrgLcnio++E+14Vo/XffOGwZtRpUhr8dTH/x2oCMmEoIU0Zwm3ZauhvYD17g==",
"dev": true
},
+ "longest-streak": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.3.tgz",
+ "integrity": "sha512-9lz5IVdpwsKLMzQi0MQ+oD9EA0mIGcWYP7jXMTZVXP8D42PwuAk+M/HBFYQoxt1G5OR8m7aSIgb1UymfWGBWEw=="
+ },
"loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@@ -9491,6 +9489,11 @@
"resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.3.tgz",
"integrity": "sha512-XUi5HJhhV5R74k8/0H2oCbCiYf/u4cO/rX8tnGkRvrqhsr5BRNU6Mg0yt/8UIx1iIS8220BNJsDb7XnILhLepw=="
},
+ "markdown-table": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz",
+ "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q=="
+ },
"md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -9502,6 +9505,37 @@
"safe-buffer": "^5.1.2"
}
},
+ "mdast-util-compact": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.4.tgz",
+ "integrity": "sha512-3YDMQHI5vRiS2uygEFYaqckibpJtKq5Sj2c8JioeOQBU6INpKbdWzfyLqFFnDwEcEnRFIdMsguzs5pC1Jp4Isg==",
+ "requires": {
+ "unist-util-visit": "^1.1.0"
+ },
+ "dependencies": {
+ "unist-util-is": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz",
+ "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A=="
+ },
+ "unist-util-visit": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz",
+ "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==",
+ "requires": {
+ "unist-util-visit-parents": "^2.0.0"
+ }
+ },
+ "unist-util-visit-parents": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz",
+ "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==",
+ "requires": {
+ "unist-util-is": "^3.0.0"
+ }
+ }
+ }
+ },
"mdast-util-definitions": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-1.2.4.tgz",
@@ -9792,7 +9826,7 @@
},
"minimist": {
"version": "0.0.8",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
},
"mississippi": {
@@ -12081,6 +12115,16 @@
}
}
},
+ "rehype-document": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/rehype-document/-/rehype-document-3.2.0.tgz",
+ "integrity": "sha512-TzlPvrIfZLT5w/CuQ+drqCTGoZ/e68nlZfXQH8/PGdauwQGHQ2+WyJ6EUt8tqmKuWR6Xc3gb8oyKtVWtHZGoJA==",
+ "requires": {
+ "doctype": "^2.0.0",
+ "hastscript": "^5.0.0",
+ "unist-builder": "^1.0.1"
+ }
+ },
"rehype-raw": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-4.0.1.tgz",
@@ -12106,21 +12150,21 @@
"hast-util-sanitize": "^2.0.0"
}
},
+ "rehype-stringify": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-6.0.1.tgz",
+ "integrity": "sha512-JfEPRDD4DiG7jet4md7sY07v6ACeb2x+9HWQtRPm2iA6/ic31hCv1SNBUtpolJASxQ/D8gicXiviW4TJKEMPKQ==",
+ "requires": {
+ "hast-util-to-html": "^6.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
"relateurl": {
"version": "0.2.7",
"resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
"integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=",
"dev": true
},
- "remark-frontmatter": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-1.3.2.tgz",
- "integrity": "sha512-2eayxITZ8rezsXdgcXnYB3iLivohm2V/ZT4Ne8uhua6A4pk6GdLE2ZzJnbnINtD1HRLaTdB7RwF9sgUbMptJZA==",
- "requires": {
- "fault": "^1.0.1",
- "xtend": "^4.0.1"
- }
- },
"remark-parse": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-7.0.1.tgz",
@@ -12151,6 +12195,27 @@
"mdast-util-to-hast": "^6.0.0"
}
},
+ "remark-stringify": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-7.0.4.tgz",
+ "integrity": "sha512-qck+8NeA1D0utk1ttKcWAoHRrJxERYQzkHDyn+pF5Z4whX1ug98uCNPPSeFgLSaNERRxnD6oxIug6DzZQth6Pg==",
+ "requires": {
+ "ccount": "^1.0.0",
+ "is-alphanumeric": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-whitespace-character": "^1.0.0",
+ "longest-streak": "^2.0.1",
+ "markdown-escapes": "^1.0.0",
+ "markdown-table": "^1.1.0",
+ "mdast-util-compact": "^1.0.0",
+ "parse-entities": "^1.0.2",
+ "repeat-string": "^1.5.4",
+ "state-toggle": "^1.0.0",
+ "stringify-entities": "^2.0.0",
+ "unherit": "^1.0.4",
+ "xtend": "^4.0.1"
+ }
+ },
"remove-trailing-separator": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
@@ -12440,7 +12505,7 @@
"dependencies": {
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
}
@@ -13236,6 +13301,18 @@
"safe-buffer": "~5.1.0"
}
},
+ "stringify-entities": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-2.0.0.tgz",
+ "integrity": "sha512-fqqhZzXyAM6pGD9lky/GOPq6V4X0SeTAFBl0iXb/BzOegl40gpf/bV3QQP7zULNYvjr6+Dx8SCaDULjVoOru0A==",
+ "requires": {
+ "character-entities-html4": "^1.0.0",
+ "character-entities-legacy": "^1.0.0",
+ "is-alphanumerical": "^1.0.0",
+ "is-decimal": "^1.0.2",
+ "is-hexadecimal": "^1.0.0"
+ }
+ },
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
@@ -13415,7 +13492,7 @@
},
"readable-stream": {
"version": "1.0.33",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz",
"integrity": "sha1-OjYN1mwbHX/UcFOJhg7aHQ9hEmw=",
"requires": {
"core-util-is": "~1.0.0",
diff --git a/package.json b/package.json
index 6cf7d269c4..188cbb514a 100644
--- a/package.json
+++ b/package.json
@@ -119,12 +119,14 @@
"react-dom": "^16.9.0",
"react-i18next": "^11.0.1",
"react-use": "^12.10.0",
+ "rehype-document": "^3.2.0",
"rehype-raw": "^4.0.1",
"rehype-react": "^4.0.1",
"rehype-sanitize": "^3.0.0",
- "remark-frontmatter": "^1.3.2",
+ "rehype-stringify": "^6.0.1",
"remark-parse": "^7.0.1",
"remark-rehype": "^5.0.0",
+ "remark-stringify": "^7.0.4",
"shortid": "^2.2.15",
"styled-components": "^4.3.2",
"typescript": "^3.6.3",
diff --git a/src/components/NotePage/NoteDetail/NoteDetail.tsx b/src/components/NotePage/NoteDetail/NoteDetail.tsx
index 576528db81..2793edcea5 100644
--- a/src/components/NotePage/NoteDetail/NoteDetail.tsx
+++ b/src/components/NotePage/NoteDetail/NoteDetail.tsx
@@ -20,6 +20,7 @@ import {
borderBottom,
borderRight
} from '../../../lib/styled/styleFunctions'
+import ToolbarExportButton from '../../atoms/ToolbarExportButton'
const StyledNoteDetailContainer = styled.div`
${secondaryBackgroundColor}
@@ -347,6 +348,7 @@ export default class NoteDetail extends React.Component<
onKeyDown={this.handleNewTagNameInputKeyDown}
/>
+
{}} path={mdiFormatText} />
) {
}
}
}
-const rehypeCodeMirror = rehypeCodeMirrorAttacher as Plugin<
+
+export const rehypeCodeMirror = rehypeCodeMirrorAttacher as Plugin<
[Partial?]
>
diff --git a/src/components/atoms/ToolbarExportButton.tsx b/src/components/atoms/ToolbarExportButton.tsx
new file mode 100644
index 0000000000..f55ff9d042
--- /dev/null
+++ b/src/components/atoms/ToolbarExportButton.tsx
@@ -0,0 +1,154 @@
+import React, { useCallback } from 'react'
+import styled from '../../lib/styled'
+import { iconColor } from '../../lib/styled/styleFunctions'
+import { useContextMenu, MenuTypes } from '../../lib/contextMenu'
+import { NoteDoc } from '../../lib/db/types'
+import unified from 'unified'
+import remarkParse from 'remark-parse'
+import remarkRehype from 'remark-rehype'
+import remarkStringify from 'remark-stringify'
+import rehypeDocument from 'rehype-document'
+import rehypeRaw from 'rehype-raw'
+import rehypeSanitize from 'rehype-sanitize'
+import rehypeStringify from 'rehype-stringify'
+import { mergeDeepRight } from 'ramda'
+import gh from 'hast-util-sanitize/lib/github.json'
+import { usePreferences } from '../../lib/preferences'
+import { rehypeCodeMirror } from './MarkdownPreviewer'
+import { usePreviewStyle } from '../../lib/preview'
+
+const sanitizeSchema = mergeDeepRight(gh, {
+ attributes: { '*': ['className'] }
+})
+
+const StyledButton = styled.button<{ active: boolean }>`
+ background: transparent;
+ height: 32px;
+ box-sizing: border-box;
+ font-size: 14px;
+ outline: none;
+ border: none;
+ ${iconColor}
+ &:first-child {
+ margin-left: 0;
+ }
+ &:last-child {
+ margin-right: 0;
+ }
+`
+
+interface ToolbarExportButtonProps {
+ note: NoteDoc
+ className?: string
+}
+
+const ToolbarExportButton = ({ className, note }: ToolbarExportButtonProps) => {
+ const { popup } = useContextMenu()
+ const { preferences } = usePreferences()
+ const { previewStyle } = usePreviewStyle()
+
+ const openExportButtonContextMenu = useCallback(
+ (event: React.MouseEvent) => {
+ event.preventDefault()
+ popup(event, [
+ {
+ type: MenuTypes.Normal,
+ label: 'HTML export',
+ onClick: async () => await exportToHtml()
+ },
+ {
+ type: MenuTypes.Normal,
+ label: 'Markdown export',
+ onClick: async () => await exportToMarkdown()
+ }
+ ])
+ },
+ [popup]
+ )
+
+ const downloadFile = (
+ content: string,
+ fileName: string,
+ type: string = 'text/plain'
+ ) => {
+ const anchor = document.createElement('a')
+ anchor.style.display = 'none'
+ document.body.appendChild(anchor)
+ anchor.href = window.URL.createObjectURL(new Blob([content], { type }))
+ anchor.setAttribute('download', fileName)
+ anchor.click()
+ window.URL.revokeObjectURL(anchor.href)
+ document.body.removeChild(anchor)
+ }
+
+ const exportToHtml = async () => {
+ await unified()
+ .use(remarkParse)
+ .use(remarkRehype, { allowDangerousHTML: false })
+ .use(rehypeCodeMirror, {
+ ignoreMissing: true,
+ theme: preferences['markdown.codeBlockTheme']
+ })
+ .use(rehypeRaw)
+ .use(rehypeSanitize, sanitizeSchema)
+ .use(rehypeDocument, {
+ title: note.title,
+ style: previewStyle,
+ meta: { keywords: note.tags.join() }
+ })
+ .use(rehypeStringify)
+ .process(note.content, (err, file) => {
+ if (err != null) {
+ /* TODO: Toast error */
+ console.error(err)
+ return
+ }
+
+ downloadFile(
+ file.toString(),
+ `${note.title.toLowerCase().replace(/\s+/g, '-')}.html`,
+ 'text/html'
+ )
+ return
+ })
+ }
+
+ const exportToMarkdown = async () => {
+ console.log('export markdown')
+ await unified()
+ .use(remarkParse)
+ .use(remarkStringify)
+ .process(note.content, (err, file) => {
+ if (err != null) {
+ /* TODO: Toast error */
+ console.error(err)
+ return
+ }
+ downloadFile(
+ [
+ '---',
+ `title: "${note.title}"`,
+ `tags: "${note.tags.join()}"`,
+ '---',
+ file.toString()
+ ].join('\n'),
+ `${note.title.toLowerCase().replace(/\s+/g, '-')}.md`,
+ 'text/markdown'
+ )
+ return
+ })
+ return
+ }
+
+ return (
+
+ Export
+
+ )
+}
+
+export default ToolbarExportButton
diff --git a/tsconfig-webpack.json b/tsconfig-webpack.json
index f4195027f1..60a3c74b95 100644
--- a/tsconfig-webpack.json
+++ b/tsconfig-webpack.json
@@ -3,5 +3,6 @@
"module": "commonjs",
"target": "es5",
"esModuleInterop": true
- }
+ },
+ "include": ["src/**/*.ts", "src/**/*.tsx", "./typings/**/*.d.ts"]
}
diff --git a/tsconfig.json b/tsconfig.json
index 16041046ad..b9046816e4 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,5 +1,6 @@
{
"include": ["src/**/*.ts", "src/**/*.tsx", "./typings/**/*.d.ts"],
+ "exclude": ["dist", "node_modules"],
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"target": "esnext",
diff --git a/typings/unified.d.ts b/typings/unified.d.ts
index c4164b0d64..af2e04fd17 100644
--- a/typings/unified.d.ts
+++ b/typings/unified.d.ts
@@ -1,7 +1,10 @@
declare module 'remark-rehype'
+declare module 'remark-stringify'
+declare module 'rehype-document'
declare module 'rehype-raw'
declare module 'rehype-sanitize'
declare module 'rehype-react'
+declare module 'rehype-stringify'
declare module 'hast-util-sanitize/lib/github.json'
declare module 'hast-util-to-text'
declare module 'hastscript'