Hand roll a SSR markdown parser for reveal
This commit is contained in:
parent
e5c6d7f1e8
commit
bc8c817e92
14
package.json
14
package.json
|
@ -12,18 +12,23 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/mdx": "^0.18.3",
|
"@astrojs/mdx": "^0.18.3",
|
||||||
"@astrojs/svelte": "^2.1.0",
|
"@astrojs/svelte": "^2.1.0",
|
||||||
"astro": "^2.2.1",
|
"astro": "^2.2.2",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"leaflet": "^1.9.3",
|
"leaflet": "^1.9.3",
|
||||||
"leaflet.markercluster": "^1.5.3",
|
"leaflet.markercluster": "^1.5.3",
|
||||||
"lunr": "^2.3.9",
|
"lunr": "^2.3.9",
|
||||||
"marked": "^4.3.0",
|
|
||||||
"rehype-katex": "^6.0.2",
|
"rehype-katex": "^6.0.2",
|
||||||
|
"rehype-raw": "^6.1.1",
|
||||||
|
"rehype-stringify": "^9.0.3",
|
||||||
"remark-emoji": "^3.1.1",
|
"remark-emoji": "^3.1.1",
|
||||||
|
"remark-gfm": "^3.0.1",
|
||||||
"remark-math": "^5.1.1",
|
"remark-math": "^5.1.1",
|
||||||
|
"remark-parse": "^10.0.1",
|
||||||
|
"remark-rehype": "^10.1.0",
|
||||||
"reveal.js": "^4.4.0",
|
"reveal.js": "^4.4.0",
|
||||||
"sass": "^1.61.0",
|
"sass": "^1.62.0",
|
||||||
"svelte": "^3.58.0",
|
"svelte": "^3.58.0",
|
||||||
|
"unified": "^10.1.2",
|
||||||
"unist-util-visit": "^4.1.2"
|
"unist-util-visit": "^4.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -32,6 +37,7 @@
|
||||||
"@types/leaflet.markercluster": "^1.5.1",
|
"@types/leaflet.markercluster": "^1.5.1",
|
||||||
"@types/lunr": "^2.3.4",
|
"@types/lunr": "^2.3.4",
|
||||||
"@types/marked": "^4.0.8",
|
"@types/marked": "^4.0.8",
|
||||||
"@types/reveal.js": "^4.4.2"
|
"@types/reveal.js": "^4.4.2",
|
||||||
|
"@types/unist": "^2.0.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,13 +3,13 @@ lockfileVersion: '6.0'
|
||||||
dependencies:
|
dependencies:
|
||||||
'@astrojs/mdx':
|
'@astrojs/mdx':
|
||||||
specifier: ^0.18.3
|
specifier: ^0.18.3
|
||||||
version: 0.18.3(astro@2.2.1)(rollup@3.20.2)
|
version: 0.18.3(astro@2.2.2)(rollup@3.20.2)
|
||||||
'@astrojs/svelte':
|
'@astrojs/svelte':
|
||||||
specifier: ^2.1.0
|
specifier: ^2.1.0
|
||||||
version: 2.1.0(astro@2.2.1)(svelte@3.58.0)(typescript@4.9.5)(vite@4.2.1)
|
version: 2.1.0(astro@2.2.2)(svelte@3.58.0)(typescript@4.9.5)(vite@4.2.1)
|
||||||
astro:
|
astro:
|
||||||
specifier: ^2.2.1
|
specifier: ^2.2.2
|
||||||
version: 2.2.1(sass@1.61.0)
|
version: 2.2.2(sass@1.62.0)
|
||||||
dayjs:
|
dayjs:
|
||||||
specifier: ^1.11.7
|
specifier: ^1.11.7
|
||||||
version: 1.11.7
|
version: 1.11.7
|
||||||
|
@ -22,27 +22,42 @@ dependencies:
|
||||||
lunr:
|
lunr:
|
||||||
specifier: ^2.3.9
|
specifier: ^2.3.9
|
||||||
version: 2.3.9
|
version: 2.3.9
|
||||||
marked:
|
|
||||||
specifier: ^4.3.0
|
|
||||||
version: 4.3.0
|
|
||||||
rehype-katex:
|
rehype-katex:
|
||||||
specifier: ^6.0.2
|
specifier: ^6.0.2
|
||||||
version: 6.0.2
|
version: 6.0.2
|
||||||
|
rehype-raw:
|
||||||
|
specifier: ^6.1.1
|
||||||
|
version: 6.1.1
|
||||||
|
rehype-stringify:
|
||||||
|
specifier: ^9.0.3
|
||||||
|
version: 9.0.3
|
||||||
remark-emoji:
|
remark-emoji:
|
||||||
specifier: ^3.1.1
|
specifier: ^3.1.1
|
||||||
version: 3.1.1
|
version: 3.1.1
|
||||||
|
remark-gfm:
|
||||||
|
specifier: ^3.0.1
|
||||||
|
version: 3.0.1
|
||||||
remark-math:
|
remark-math:
|
||||||
specifier: ^5.1.1
|
specifier: ^5.1.1
|
||||||
version: 5.1.1
|
version: 5.1.1
|
||||||
|
remark-parse:
|
||||||
|
specifier: ^10.0.1
|
||||||
|
version: 10.0.1
|
||||||
|
remark-rehype:
|
||||||
|
specifier: ^10.1.0
|
||||||
|
version: 10.1.0
|
||||||
reveal.js:
|
reveal.js:
|
||||||
specifier: ^4.4.0
|
specifier: ^4.4.0
|
||||||
version: 4.4.0
|
version: 4.4.0
|
||||||
sass:
|
sass:
|
||||||
specifier: ^1.61.0
|
specifier: ^1.62.0
|
||||||
version: 1.61.0
|
version: 1.62.0
|
||||||
svelte:
|
svelte:
|
||||||
specifier: ^3.58.0
|
specifier: ^3.58.0
|
||||||
version: 3.58.0
|
version: 3.58.0
|
||||||
|
unified:
|
||||||
|
specifier: ^10.1.2
|
||||||
|
version: 10.1.2
|
||||||
unist-util-visit:
|
unist-util-visit:
|
||||||
specifier: ^4.1.2
|
specifier: ^4.1.2
|
||||||
version: 4.1.2
|
version: 4.1.2
|
||||||
|
@ -66,6 +81,9 @@ devDependencies:
|
||||||
'@types/reveal.js':
|
'@types/reveal.js':
|
||||||
specifier: ^4.4.2
|
specifier: ^4.4.2
|
||||||
version: 4.4.2
|
version: 4.4.2
|
||||||
|
'@types/unist':
|
||||||
|
specifier: ^2.0.6
|
||||||
|
version: 2.0.6
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
|
@ -103,13 +121,13 @@ packages:
|
||||||
vscode-uri: 3.0.7
|
vscode-uri: 3.0.7
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@astrojs/markdown-remark@2.1.3(astro@2.2.1):
|
/@astrojs/markdown-remark@2.1.3(astro@2.2.2):
|
||||||
resolution: {integrity: sha512-Di8Qbit9p7L7eqKklAJmiW9nVD+XMsNHpaNzCLduWjOonDu9fVgEzdjeDrTVCDtgrvkfhpAekuNXrp5+w4F91g==}
|
resolution: {integrity: sha512-Di8Qbit9p7L7eqKklAJmiW9nVD+XMsNHpaNzCLduWjOonDu9fVgEzdjeDrTVCDtgrvkfhpAekuNXrp5+w4F91g==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
astro: ^2.2.0
|
astro: ^2.2.0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@astrojs/prism': 2.1.1
|
'@astrojs/prism': 2.1.1
|
||||||
astro: 2.2.1(sass@1.61.0)
|
astro: 2.2.2(sass@1.62.0)
|
||||||
github-slugger: 1.5.0
|
github-slugger: 1.5.0
|
||||||
import-meta-resolve: 2.2.2
|
import-meta-resolve: 2.2.2
|
||||||
rehype-raw: 6.1.1
|
rehype-raw: 6.1.1
|
||||||
|
@ -126,11 +144,11 @@ packages:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@astrojs/mdx@0.18.3(astro@2.2.1)(rollup@3.20.2):
|
/@astrojs/mdx@0.18.3(astro@2.2.2)(rollup@3.20.2):
|
||||||
resolution: {integrity: sha512-fFkzYthnFqxmdp6IesvzU6FDHdAGo9bf4dbMOPCREcBfEhATqSpT9gjK/HdJ5s1MfZI8jjYeSC3yzhmNlq62qA==}
|
resolution: {integrity: sha512-fFkzYthnFqxmdp6IesvzU6FDHdAGo9bf4dbMOPCREcBfEhATqSpT9gjK/HdJ5s1MfZI8jjYeSC3yzhmNlq62qA==}
|
||||||
engines: {node: '>=16.12.0'}
|
engines: {node: '>=16.12.0'}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@astrojs/markdown-remark': 2.1.3(astro@2.2.1)
|
'@astrojs/markdown-remark': 2.1.3(astro@2.2.2)
|
||||||
'@astrojs/prism': 2.1.1
|
'@astrojs/prism': 2.1.1
|
||||||
'@mdx-js/mdx': 2.3.0
|
'@mdx-js/mdx': 2.3.0
|
||||||
'@mdx-js/rollup': 2.3.0(rollup@3.20.2)
|
'@mdx-js/rollup': 2.3.0(rollup@3.20.2)
|
||||||
|
@ -160,7 +178,7 @@ packages:
|
||||||
prismjs: 1.29.0
|
prismjs: 1.29.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@astrojs/svelte@2.1.0(astro@2.2.1)(svelte@3.58.0)(typescript@4.9.5)(vite@4.2.1):
|
/@astrojs/svelte@2.1.0(astro@2.2.2)(svelte@3.58.0)(typescript@4.9.5)(vite@4.2.1):
|
||||||
resolution: {integrity: sha512-upfkscrNuZbQvqVB5EG38FPJCgHCxO/LOJLAap75rO/++c1T7ztbVru4uSYVBRJkzTDuH3TS52T8kFTVgHXx/g==}
|
resolution: {integrity: sha512-upfkscrNuZbQvqVB5EG38FPJCgHCxO/LOJLAap75rO/++c1T7ztbVru4uSYVBRJkzTDuH3TS52T8kFTVgHXx/g==}
|
||||||
engines: {node: '>=16.12.0'}
|
engines: {node: '>=16.12.0'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -168,7 +186,7 @@ packages:
|
||||||
svelte: ^3.54.0
|
svelte: ^3.54.0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@sveltejs/vite-plugin-svelte': 2.0.4(svelte@3.58.0)(vite@4.2.1)
|
'@sveltejs/vite-plugin-svelte': 2.0.4(svelte@3.58.0)(vite@4.2.1)
|
||||||
astro: 2.2.1(sass@1.61.0)
|
astro: 2.2.2(sass@1.62.0)
|
||||||
svelte: 3.58.0
|
svelte: 3.58.0
|
||||||
svelte2tsx: 0.5.23(svelte@3.58.0)(typescript@4.9.5)
|
svelte2tsx: 0.5.23(svelte@3.58.0)(typescript@4.9.5)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
@ -795,7 +813,7 @@ packages:
|
||||||
magic-string: 0.30.0
|
magic-string: 0.30.0
|
||||||
svelte: 3.58.0
|
svelte: 3.58.0
|
||||||
svelte-hmr: 0.15.1(svelte@3.58.0)
|
svelte-hmr: 0.15.1(svelte@3.58.0)
|
||||||
vite: 4.2.1(sass@1.61.0)
|
vite: 4.2.1(sass@1.62.0)
|
||||||
vitefu: 0.2.4(vite@4.2.1)
|
vitefu: 0.2.4(vite@4.2.1)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
@ -927,7 +945,6 @@ packages:
|
||||||
|
|
||||||
/@types/unist@2.0.6:
|
/@types/unist@2.0.6:
|
||||||
resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==}
|
resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==}
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@types/yargs-parser@21.0.0:
|
/@types/yargs-parser@21.0.0:
|
||||||
resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==}
|
resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==}
|
||||||
|
@ -1023,8 +1040,8 @@ packages:
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/astro@2.2.1(sass@1.61.0):
|
/astro@2.2.2(sass@1.62.0):
|
||||||
resolution: {integrity: sha512-yYPRzh3su38bi3VBCKmYAUBkQSaFQMKFsu8JAVDzFRoGLbskJ/6JkDX2abSB9/iRug8GAKaH/FWxXOTzIsSQ7Q==}
|
resolution: {integrity: sha512-RmV/UiOW3losWRbR8CeFDFDtjBOdFdBTEccXF9sT/ZxLz7T9SglevtOHgKwTSRPgUM9c0LteFDFcHDY3OYBgDg==}
|
||||||
engines: {node: '>=16.12.0', npm: '>=6.14.0'}
|
engines: {node: '>=16.12.0', npm: '>=6.14.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -1035,7 +1052,7 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@astrojs/compiler': 1.3.1
|
'@astrojs/compiler': 1.3.1
|
||||||
'@astrojs/language-server': 0.28.3
|
'@astrojs/language-server': 0.28.3
|
||||||
'@astrojs/markdown-remark': 2.1.3(astro@2.2.1)
|
'@astrojs/markdown-remark': 2.1.3(astro@2.2.2)
|
||||||
'@astrojs/telemetry': 2.1.0
|
'@astrojs/telemetry': 2.1.0
|
||||||
'@astrojs/webapi': 2.1.0
|
'@astrojs/webapi': 2.1.0
|
||||||
'@babel/core': 7.21.4
|
'@babel/core': 7.21.4
|
||||||
|
@ -1071,7 +1088,7 @@ packages:
|
||||||
preferred-pm: 3.0.3
|
preferred-pm: 3.0.3
|
||||||
prompts: 2.4.2
|
prompts: 2.4.2
|
||||||
rehype: 12.0.1
|
rehype: 12.0.1
|
||||||
semver: 7.3.8
|
semver: 7.4.0
|
||||||
server-destroy: 1.0.1
|
server-destroy: 1.0.1
|
||||||
shiki: 0.11.1
|
shiki: 0.11.1
|
||||||
slash: 4.0.0
|
slash: 4.0.0
|
||||||
|
@ -1082,7 +1099,7 @@ packages:
|
||||||
typescript: 5.0.4
|
typescript: 5.0.4
|
||||||
unist-util-visit: 4.1.2
|
unist-util-visit: 4.1.2
|
||||||
vfile: 5.3.7
|
vfile: 5.3.7
|
||||||
vite: 4.2.1(sass@1.61.0)
|
vite: 4.2.1(sass@1.62.0)
|
||||||
vitefu: 0.2.4(vite@4.2.1)
|
vitefu: 0.2.4(vite@4.2.1)
|
||||||
yargs-parser: 21.1.1
|
yargs-parser: 21.1.1
|
||||||
zod: 3.21.4
|
zod: 3.21.4
|
||||||
|
@ -1144,7 +1161,7 @@ packages:
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
caniuse-lite: 1.0.30001477
|
caniuse-lite: 1.0.30001477
|
||||||
electron-to-chromium: 1.4.356
|
electron-to-chromium: 1.4.359
|
||||||
node-releases: 2.0.10
|
node-releases: 2.0.10
|
||||||
update-browserslist-db: 1.0.10(browserslist@4.21.5)
|
update-browserslist-db: 1.0.10(browserslist@4.21.5)
|
||||||
dev: false
|
dev: false
|
||||||
|
@ -1382,8 +1399,8 @@ packages:
|
||||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/electron-to-chromium@1.4.356:
|
/electron-to-chromium@1.4.359:
|
||||||
resolution: {integrity: sha512-nEftV1dRX3omlxAj42FwqRZT0i4xd2dIg39sog/CnCJeCcL1TRd2Uh0i9Oebgv8Ou0vzTPw++xc+Z20jzS2B6A==}
|
resolution: {integrity: sha512-OoVcngKCIuNXtZnsYoqlCvr0Cf3NIPzDIgwUfI9bdTFjXCrr79lI0kwQstLPZ7WhCezLlGksZk/BFAzoXC7GDw==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/emmet@2.4.2:
|
/emmet@2.4.2:
|
||||||
|
@ -1846,8 +1863,8 @@ packages:
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/is-core-module@2.11.0:
|
/is-core-module@2.12.0:
|
||||||
resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==}
|
resolution: {integrity: sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
has: 1.0.3
|
has: 1.0.3
|
||||||
dev: false
|
dev: false
|
||||||
|
@ -2102,12 +2119,6 @@ packages:
|
||||||
resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==}
|
resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/marked@4.3.0:
|
|
||||||
resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==}
|
|
||||||
engines: {node: '>= 12'}
|
|
||||||
hasBin: true
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/mdast-util-definitions@5.1.2:
|
/mdast-util-definitions@5.1.2:
|
||||||
resolution: {integrity: sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==}
|
resolution: {integrity: sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -3098,7 +3109,7 @@ packages:
|
||||||
resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==}
|
resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
is-core-module: 2.11.0
|
is-core-module: 2.12.0
|
||||||
path-parse: 1.0.7
|
path-parse: 1.0.7
|
||||||
supports-preserve-symlinks-flag: 1.0.0
|
supports-preserve-symlinks-flag: 1.0.0
|
||||||
dev: false
|
dev: false
|
||||||
|
@ -3190,8 +3201,8 @@ packages:
|
||||||
suf-log: 2.5.3
|
suf-log: 2.5.3
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/sass@1.61.0:
|
/sass@1.62.0:
|
||||||
resolution: {integrity: sha512-PDsN7BrVkNZK2+dj/dpKQAWZavbAQ87IXqVvw2+oEYI+GwlTWkvbQtL7F2cCNbMqJEYKPh1EcjSxsnqIb/kyaQ==}
|
resolution: {integrity: sha512-Q4USplo4pLYgCi+XlipZCWUQz5pkg/ruSSgJ0WRDSb/+3z9tXUOkQ7QPYn4XrhZKYAK4HlpaQecRwKLJX6+DBg==}
|
||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -3213,8 +3224,8 @@ packages:
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/semver@7.3.8:
|
/semver@7.4.0:
|
||||||
resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==}
|
resolution: {integrity: sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -3642,7 +3653,7 @@ packages:
|
||||||
vfile-message: 3.1.4
|
vfile-message: 3.1.4
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/vite@4.2.1(sass@1.61.0):
|
/vite@4.2.1(sass@1.62.0):
|
||||||
resolution: {integrity: sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==}
|
resolution: {integrity: sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==}
|
||||||
engines: {node: ^14.18.0 || >=16.0.0}
|
engines: {node: ^14.18.0 || >=16.0.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
@ -3671,7 +3682,7 @@ packages:
|
||||||
postcss: 8.4.21
|
postcss: 8.4.21
|
||||||
resolve: 1.22.2
|
resolve: 1.22.2
|
||||||
rollup: 3.20.2
|
rollup: 3.20.2
|
||||||
sass: 1.61.0
|
sass: 1.62.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.2
|
||||||
dev: false
|
dev: false
|
||||||
|
@ -3684,7 +3695,7 @@ packages:
|
||||||
vite:
|
vite:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
vite: 4.2.1(sass@1.61.0)
|
vite: 4.2.1(sass@1.62.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/vscode-css-languageservice@6.2.4:
|
/vscode-css-languageservice@6.2.4:
|
||||||
|
|
|
@ -1,478 +0,0 @@
|
||||||
/* Copyright (C) 2011-2023 Hakim El Hattab, http://hakim.se, and reveal.js contributors
|
|
||||||
* License: MIT (https://github.com/hakimel/reveal.js/blob/master/LICENSE)
|
|
||||||
*
|
|
||||||
* The reveal.js markdown plugin. Handles parsing of
|
|
||||||
* markdown inside of presentations as well as loading
|
|
||||||
* of external markdown documents.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
import { marked } from 'marked';
|
|
||||||
|
|
||||||
const DEFAULT_SLIDE_SEPARATOR = '\r?\n---\r?\n',
|
|
||||||
DEFAULT_NOTES_SEPARATOR = 'notes?:',
|
|
||||||
DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$',
|
|
||||||
DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\S.+?)$';
|
|
||||||
|
|
||||||
const SCRIPT_END_PLACEHOLDER = '__SCRIPT_END__';
|
|
||||||
|
|
||||||
const CODE_LINE_NUMBER_REGEX = /\[([\s\d,|-]*)\]/;
|
|
||||||
|
|
||||||
const HTML_ESCAPE_MAP = {
|
|
||||||
'&': '&',
|
|
||||||
'<': '<',
|
|
||||||
'>': '>',
|
|
||||||
'"': '"',
|
|
||||||
"'": '''
|
|
||||||
};
|
|
||||||
|
|
||||||
const Plugin = () => {
|
|
||||||
|
|
||||||
// The reveal.js instance this plugin is attached to
|
|
||||||
let deck;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the markdown contents of a slide section
|
|
||||||
* element. Normalizes leading tabs/whitespace.
|
|
||||||
*/
|
|
||||||
function getMarkdownFromSlide( section ) {
|
|
||||||
|
|
||||||
// look for a <script> or <textarea data-template> wrapper
|
|
||||||
var template = section.querySelector( '[data-template]' ) || section.querySelector( 'script' );
|
|
||||||
|
|
||||||
// strip leading whitespace so it isn't evaluated as code
|
|
||||||
var text = ( template || section ).textContent;
|
|
||||||
|
|
||||||
// restore script end tags
|
|
||||||
text = text.replace( new RegExp( SCRIPT_END_PLACEHOLDER, 'g' ), '</script>' );
|
|
||||||
|
|
||||||
var leadingWs = text.match( /^\n?(\s*)/ )[1].length,
|
|
||||||
leadingTabs = text.match( /^\n?(\t*)/ )[1].length;
|
|
||||||
|
|
||||||
if( leadingTabs > 0 ) {
|
|
||||||
text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}(.*)','g'), function(m, p1) { return '\n' + p1 ; } );
|
|
||||||
}
|
|
||||||
else if( leadingWs > 1 ) {
|
|
||||||
text = text.replace( new RegExp('\\n? {' + leadingWs + '}(.*)', 'g'), function(m, p1) { return '\n' + p1 ; } );
|
|
||||||
}
|
|
||||||
|
|
||||||
return text;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a markdown slide section element, this will
|
|
||||||
* return all arguments that aren't related to markdown
|
|
||||||
* parsing. Used to forward any other user-defined arguments
|
|
||||||
* to the output markdown slide.
|
|
||||||
*/
|
|
||||||
function getForwardedAttributes( section ) {
|
|
||||||
|
|
||||||
var attributes = section.attributes;
|
|
||||||
var result = [];
|
|
||||||
|
|
||||||
for( var i = 0, len = attributes.length; i < len; i++ ) {
|
|
||||||
var name = attributes[i].name,
|
|
||||||
value = attributes[i].value;
|
|
||||||
|
|
||||||
// disregard attributes that are used for markdown loading/parsing
|
|
||||||
if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue;
|
|
||||||
|
|
||||||
if( value ) {
|
|
||||||
result.push( name + '="' + value + '"' );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result.push( name );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.join( ' ' );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inspects the given options and fills out default
|
|
||||||
* values for what's not defined.
|
|
||||||
*/
|
|
||||||
function getSlidifyOptions( options ) {
|
|
||||||
|
|
||||||
options = options || {};
|
|
||||||
options.separator = options.separator || DEFAULT_SLIDE_SEPARATOR;
|
|
||||||
options.notesSeparator = options.notesSeparator || DEFAULT_NOTES_SEPARATOR;
|
|
||||||
options.attributes = options.attributes || '';
|
|
||||||
|
|
||||||
return options;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function for constructing a markdown slide.
|
|
||||||
*/
|
|
||||||
function createMarkdownSlide( content, options ) {
|
|
||||||
|
|
||||||
options = getSlidifyOptions( options );
|
|
||||||
|
|
||||||
var notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
|
|
||||||
|
|
||||||
if( notesMatch.length === 2 ) {
|
|
||||||
content = notesMatch[0] + '<aside class="notes">' + marked(notesMatch[1].trim()) + '</aside>';
|
|
||||||
}
|
|
||||||
|
|
||||||
// prevent script end tags in the content from interfering
|
|
||||||
// with parsing
|
|
||||||
content = content.replace( /<\/script>/g, SCRIPT_END_PLACEHOLDER );
|
|
||||||
|
|
||||||
return '<script type="text/template">' + content + '</script>';
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses a data string into multiple slides based
|
|
||||||
* on the passed in separator arguments.
|
|
||||||
*/
|
|
||||||
function slidify( markdown, options ) {
|
|
||||||
|
|
||||||
options = getSlidifyOptions( options );
|
|
||||||
|
|
||||||
var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
|
|
||||||
horizontalSeparatorRegex = new RegExp( options.separator );
|
|
||||||
|
|
||||||
var matches,
|
|
||||||
lastIndex = 0,
|
|
||||||
isHorizontal,
|
|
||||||
wasHorizontal = true,
|
|
||||||
content,
|
|
||||||
sectionStack = [];
|
|
||||||
|
|
||||||
// iterate until all blocks between separators are stacked up
|
|
||||||
while( matches = separatorRegex.exec( markdown ) ) {
|
|
||||||
var notes = null;
|
|
||||||
|
|
||||||
// determine direction (horizontal by default)
|
|
||||||
isHorizontal = horizontalSeparatorRegex.test( matches[0] );
|
|
||||||
|
|
||||||
if( !isHorizontal && wasHorizontal ) {
|
|
||||||
// create vertical stack
|
|
||||||
sectionStack.push( [] );
|
|
||||||
}
|
|
||||||
|
|
||||||
// pluck slide content from markdown input
|
|
||||||
content = markdown.substring( lastIndex, matches.index );
|
|
||||||
|
|
||||||
if( isHorizontal && wasHorizontal ) {
|
|
||||||
// add to horizontal stack
|
|
||||||
sectionStack.push( content );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// add to vertical stack
|
|
||||||
sectionStack[sectionStack.length-1].push( content );
|
|
||||||
}
|
|
||||||
|
|
||||||
lastIndex = separatorRegex.lastIndex;
|
|
||||||
wasHorizontal = isHorizontal;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the remaining slide
|
|
||||||
( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) );
|
|
||||||
|
|
||||||
var markdownSections = '';
|
|
||||||
|
|
||||||
// flatten the hierarchical stack, and insert <section data-markdown> tags
|
|
||||||
for( var i = 0, len = sectionStack.length; i < len; i++ ) {
|
|
||||||
// vertical
|
|
||||||
if( sectionStack[i] instanceof Array ) {
|
|
||||||
markdownSections += '<section '+ options.attributes +'>';
|
|
||||||
|
|
||||||
sectionStack[i].forEach( function( child ) {
|
|
||||||
markdownSections += '<section data-markdown>' + createMarkdownSlide( child, options ) + '</section>';
|
|
||||||
} );
|
|
||||||
|
|
||||||
markdownSections += '</section>';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
markdownSections += '<section '+ options.attributes +' data-markdown>' + createMarkdownSlide( sectionStack[i], options ) + '</section>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return markdownSections;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses any current data-markdown slides, splits
|
|
||||||
* multi-slide markdown into separate sections and
|
|
||||||
* handles loading of external markdown.
|
|
||||||
*/
|
|
||||||
function processSlides( scope ) {
|
|
||||||
|
|
||||||
return new Promise( function( resolve ) {
|
|
||||||
|
|
||||||
var externalPromises = [];
|
|
||||||
|
|
||||||
[].slice.call( scope.querySelectorAll( 'section[data-markdown]:not([data-markdown-parsed])') ).forEach( function( section, i ) {
|
|
||||||
|
|
||||||
if( section.getAttribute( 'data-markdown' ).length ) {
|
|
||||||
|
|
||||||
externalPromises.push( loadExternalMarkdown( section ).then(
|
|
||||||
|
|
||||||
// Finished loading external file
|
|
||||||
function( xhr, url ) {
|
|
||||||
section.outerHTML = slidify( xhr.responseText, {
|
|
||||||
separator: section.getAttribute( 'data-separator' ),
|
|
||||||
verticalSeparator: section.getAttribute( 'data-separator-vertical' ),
|
|
||||||
notesSeparator: section.getAttribute( 'data-separator-notes' ),
|
|
||||||
attributes: getForwardedAttributes( section )
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// Failed to load markdown
|
|
||||||
function( xhr, url ) {
|
|
||||||
section.outerHTML = '<section data-state="alert">' +
|
|
||||||
'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' +
|
|
||||||
'Check your browser\'s JavaScript console for more details.' +
|
|
||||||
'<p>Remember that you need to serve the presentation HTML from a HTTP server.</p>' +
|
|
||||||
'</section>';
|
|
||||||
}
|
|
||||||
|
|
||||||
) );
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
section.outerHTML = slidify( getMarkdownFromSlide( section ), {
|
|
||||||
separator: section.getAttribute( 'data-separator' ),
|
|
||||||
verticalSeparator: section.getAttribute( 'data-separator-vertical' ),
|
|
||||||
notesSeparator: section.getAttribute( 'data-separator-notes' ),
|
|
||||||
attributes: getForwardedAttributes( section )
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
Promise.all( externalPromises ).then( resolve );
|
|
||||||
|
|
||||||
} );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadExternalMarkdown( section ) {
|
|
||||||
|
|
||||||
return new Promise( function( resolve, reject ) {
|
|
||||||
|
|
||||||
var xhr = new XMLHttpRequest(),
|
|
||||||
url = section.getAttribute( 'data-markdown' );
|
|
||||||
|
|
||||||
var datacharset = section.getAttribute( 'data-charset' );
|
|
||||||
|
|
||||||
// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
|
|
||||||
if( datacharset != null && datacharset != '' ) {
|
|
||||||
xhr.overrideMimeType( 'text/html; charset=' + datacharset );
|
|
||||||
}
|
|
||||||
|
|
||||||
xhr.onreadystatechange = function( section, xhr ) {
|
|
||||||
if( xhr.readyState === 4 ) {
|
|
||||||
// file protocol yields status code 0 (useful for local debug, mobile applications etc.)
|
|
||||||
if ( ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 0 ) {
|
|
||||||
|
|
||||||
resolve( xhr, url );
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
reject( xhr, url );
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.bind( this, section, xhr );
|
|
||||||
|
|
||||||
xhr.open( 'GET', url, true );
|
|
||||||
|
|
||||||
try {
|
|
||||||
xhr.send();
|
|
||||||
}
|
|
||||||
catch ( e ) {
|
|
||||||
console.warn( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e );
|
|
||||||
resolve( xhr, url );
|
|
||||||
}
|
|
||||||
|
|
||||||
} );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a node value has the attributes pattern.
|
|
||||||
* If yes, extract it and add that value as one or several attributes
|
|
||||||
* to the target element.
|
|
||||||
*
|
|
||||||
* You need Cache Killer on Chrome to see the effect on any FOM transformation
|
|
||||||
* directly on refresh (F5)
|
|
||||||
* http://stackoverflow.com/questions/5690269/disabling-chrome-cache-for-website-development/7000899#answer-11786277
|
|
||||||
*/
|
|
||||||
function addAttributeInElement( node, elementTarget, separator ) {
|
|
||||||
|
|
||||||
var mardownClassesInElementsRegex = new RegExp( separator, 'mg' );
|
|
||||||
var mardownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"]+?)\"|(data-[^\"= ]+?)(?=[\" ])", 'mg' );
|
|
||||||
var nodeValue = node.nodeValue;
|
|
||||||
var matches,
|
|
||||||
matchesClass;
|
|
||||||
if( matches = mardownClassesInElementsRegex.exec( nodeValue ) ) {
|
|
||||||
|
|
||||||
var classes = matches[1];
|
|
||||||
nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( mardownClassesInElementsRegex.lastIndex );
|
|
||||||
node.nodeValue = nodeValue;
|
|
||||||
while( matchesClass = mardownClassRegex.exec( classes ) ) {
|
|
||||||
if( matchesClass[2] ) {
|
|
||||||
elementTarget.setAttribute( matchesClass[1], matchesClass[2] );
|
|
||||||
} else {
|
|
||||||
elementTarget.setAttribute( matchesClass[3], "" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add attributes to the parent element of a text node,
|
|
||||||
* or the element of an attribute node.
|
|
||||||
*/
|
|
||||||
function addAttributes( section, element, previousElement, separatorElementAttributes, separatorSectionAttributes ) {
|
|
||||||
|
|
||||||
if ( element != null && element.childNodes != undefined && element.childNodes.length > 0 ) {
|
|
||||||
var previousParentElement = element;
|
|
||||||
for( var i = 0; i < element.childNodes.length; i++ ) {
|
|
||||||
var childElement = element.childNodes[i];
|
|
||||||
if ( i > 0 ) {
|
|
||||||
var j = i - 1;
|
|
||||||
while ( j >= 0 ) {
|
|
||||||
var aPreviousChildElement = element.childNodes[j];
|
|
||||||
if ( typeof aPreviousChildElement.setAttribute == 'function' && aPreviousChildElement.tagName != "BR" ) {
|
|
||||||
previousParentElement = aPreviousChildElement;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
j = j - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var parentSection = section;
|
|
||||||
if( childElement.nodeName == "section" ) {
|
|
||||||
parentSection = childElement ;
|
|
||||||
previousParentElement = childElement ;
|
|
||||||
}
|
|
||||||
if ( typeof childElement.setAttribute == 'function' || childElement.nodeType == Node.COMMENT_NODE ) {
|
|
||||||
addAttributes( parentSection, childElement, previousParentElement, separatorElementAttributes, separatorSectionAttributes );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( element.nodeType == Node.COMMENT_NODE ) {
|
|
||||||
if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) == false ) {
|
|
||||||
addAttributeInElement( element, section, separatorSectionAttributes );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts any current data-markdown slides in the
|
|
||||||
* DOM to HTML.
|
|
||||||
*/
|
|
||||||
function convertSlides() {
|
|
||||||
|
|
||||||
var sections = deck.getRevealElement().querySelectorAll( '[data-markdown]:not([data-markdown-parsed])');
|
|
||||||
|
|
||||||
[].slice.call( sections ).forEach( function( section ) {
|
|
||||||
|
|
||||||
section.setAttribute( 'data-markdown-parsed', true )
|
|
||||||
|
|
||||||
var notes = section.querySelector( 'aside.notes' );
|
|
||||||
var markdown = getMarkdownFromSlide( section );
|
|
||||||
|
|
||||||
section.innerHTML = marked( markdown );
|
|
||||||
addAttributes( section, section, null, section.getAttribute( 'data-element-attributes' ) ||
|
|
||||||
section.parentNode.getAttribute( 'data-element-attributes' ) ||
|
|
||||||
DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR,
|
|
||||||
section.getAttribute( 'data-attributes' ) ||
|
|
||||||
section.parentNode.getAttribute( 'data-attributes' ) ||
|
|
||||||
DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR);
|
|
||||||
|
|
||||||
// If there were notes, we need to re-add them after
|
|
||||||
// having overwritten the section's HTML
|
|
||||||
if( notes ) {
|
|
||||||
section.appendChild( notes );
|
|
||||||
}
|
|
||||||
|
|
||||||
} );
|
|
||||||
|
|
||||||
return Promise.resolve();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function escapeForHTML( input ) {
|
|
||||||
|
|
||||||
return input.replace( /([&<>'"])/g, char => HTML_ESCAPE_MAP[char] );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: 'markdown',
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts processing and converting Markdown within the
|
|
||||||
* current reveal.js deck.
|
|
||||||
*/
|
|
||||||
init: function( reveal ) {
|
|
||||||
|
|
||||||
deck = reveal;
|
|
||||||
|
|
||||||
let { renderer, animateLists, ...markedOptions } = deck.getConfig().markdown || {};
|
|
||||||
|
|
||||||
if( !renderer ) {
|
|
||||||
renderer = new marked.Renderer();
|
|
||||||
|
|
||||||
renderer.code = ( code, language ) => {
|
|
||||||
|
|
||||||
// Off by default
|
|
||||||
let lineNumbers = '';
|
|
||||||
|
|
||||||
// Users can opt in to show line numbers and highlight
|
|
||||||
// specific lines.
|
|
||||||
// ```javascript [] show line numbers
|
|
||||||
// ```javascript [1,4-8] highlights lines 1 and 4-8
|
|
||||||
if( CODE_LINE_NUMBER_REGEX.test( language ) ) {
|
|
||||||
lineNumbers = language.match( CODE_LINE_NUMBER_REGEX )[1].trim();
|
|
||||||
lineNumbers = `data-line-numbers="${lineNumbers}"`;
|
|
||||||
language = language.replace( CODE_LINE_NUMBER_REGEX, '' ).trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Escape before this gets injected into the DOM to
|
|
||||||
// avoid having the HTML parser alter our code before
|
|
||||||
// highlight.js is able to read it
|
|
||||||
code = escapeForHTML( code );
|
|
||||||
|
|
||||||
return `<pre><code ${lineNumbers} class="${language}">${code}</code></pre>`;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if( animateLists === true ) {
|
|
||||||
renderer.listitem = text => `<li class="fragment">${text}</li>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
marked.setOptions( {
|
|
||||||
renderer,
|
|
||||||
...markedOptions
|
|
||||||
} );
|
|
||||||
|
|
||||||
return processSlides( deck.getRevealElement() ).then( convertSlides );
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
// TODO: Do these belong in the API?
|
|
||||||
processSlides: processSlides,
|
|
||||||
convertSlides: convertSlides,
|
|
||||||
slidify: slidify,
|
|
||||||
marked: marked
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Plugin;
|
|
70
src/assets/reveal-ssr/markdown.ts
Normal file
70
src/assets/reveal-ssr/markdown.ts
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
import type { Node, Parent } from 'unist';
|
||||||
|
import { unified } from "unified";
|
||||||
|
import remarkParse from "remark-parse";
|
||||||
|
import remarkGfm from 'remark-gfm';
|
||||||
|
import remarkRehype from "remark-rehype";
|
||||||
|
import rehypeRaw from "rehype-raw";
|
||||||
|
import rehypeStringify from "rehype-stringify";
|
||||||
|
import { visit } from "unist-util-visit";
|
||||||
|
|
||||||
|
|
||||||
|
interface CodeNode extends Node {
|
||||||
|
type: 'code';
|
||||||
|
lang?: string;
|
||||||
|
meta?: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ESCAPED_CHARS: {[key: string]: string} = {
|
||||||
|
'&': '&',
|
||||||
|
'<': '<',
|
||||||
|
'>': '>',
|
||||||
|
'"': '"',
|
||||||
|
"'": '''
|
||||||
|
};
|
||||||
|
|
||||||
|
const REGEX_HL_LINES = /\[([\s\d,|-]*)\]/;
|
||||||
|
function transformCode(node: CodeNode, index: number, parent: Parent) {
|
||||||
|
if (!node.meta || !REGEX_HL_LINES.test(node.meta)) return;
|
||||||
|
|
||||||
|
const langtag = node.lang ? ` class="${node.lang}" ` : ''
|
||||||
|
const numbers = node.meta.match(REGEX_HL_LINES)![1];
|
||||||
|
const escaped = node.value.replace(/[&<>"']/g, match => ESCAPED_CHARS[match] || '');
|
||||||
|
parent.children[index] = {
|
||||||
|
type: 'html',
|
||||||
|
value: `<pre><code data-line-numbers="${numbers}"${langtag}>${escaped}</code></pre>`,
|
||||||
|
} as any;
|
||||||
|
}
|
||||||
|
|
||||||
|
function codePassthrough() {
|
||||||
|
return (tree: Node, _: any) => {
|
||||||
|
visit(tree, 'code', transformCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const compiler = unified()
|
||||||
|
.use(remarkParse)
|
||||||
|
.use(remarkGfm)
|
||||||
|
.use(codePassthrough)
|
||||||
|
.use(remarkRehype, {allowDangerousHtml: true})
|
||||||
|
.use(rehypeRaw)
|
||||||
|
.use(rehypeStringify);
|
||||||
|
|
||||||
|
|
||||||
|
const SPLIT_H = /\n-----\n/;
|
||||||
|
const SPLIT_V = /\n---\n/;
|
||||||
|
|
||||||
|
|
||||||
|
function wrapSection(content: string): string {
|
||||||
|
return `<section>${content}</section>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function compile(text: string): string {
|
||||||
|
return text
|
||||||
|
.split(SPLIT_H)
|
||||||
|
.map(stacks => stacks.split(SPLIT_V).map(slide => String(compiler.processSync(slide))))
|
||||||
|
.map(stack => (stack.length > 1)
|
||||||
|
? wrapSection(stack.map(wrapSection).join(''))
|
||||||
|
: wrapSection(stack[0]))
|
||||||
|
.join('');
|
||||||
|
}
|
|
@ -1,19 +1,24 @@
|
||||||
|
import type { Node, Parent } from 'unist';
|
||||||
import { visit } from "unist-util-visit";
|
import { visit } from "unist-util-visit";
|
||||||
import type { Node } from "unist-util-visit/lib";
|
|
||||||
|
|
||||||
|
|
||||||
|
interface RubyNode extends Node {
|
||||||
|
type: 'html';
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
const regex = /\{.+?\}\(.+?\)/g;
|
const regex = /\{.+?\}\(.+?\)/g;
|
||||||
const group = /^\{(.+?)\}\((.+?)\)$/;
|
const group = /^\{(.+?)\}\((.+?)\)$/;
|
||||||
const template = "<ruby>$1<rp>(</rp><rt>$2</rt><rp>)</rp></ruby>";
|
const template = "<ruby>$1<rp>(</rp><rt>$2</rt><rp>)</rp></ruby>";
|
||||||
|
|
||||||
function toRuby(ruby: string) {
|
function toRuby(ruby: string): RubyNode {
|
||||||
return ({
|
return {
|
||||||
type: "html",
|
type: "html",
|
||||||
value: ruby.replace(group, template),
|
value: ruby.replace(group, template),
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function transformRuby(node: { value: string }, index: number, parent: any) {
|
function transformRuby(node: {value: string}, index: number, parent: Parent) {
|
||||||
if (!regex.test(node.value)) return;
|
if (!regex.test(node.value)) return;
|
||||||
|
|
||||||
const text = node.value.split(regex).map(value => ({ type: "text", value}));
|
const text = node.value.split(regex).map(value => ({ type: "text", value}));
|
||||||
|
|
|
@ -4,6 +4,7 @@ import 'reveal.js/dist/theme/black.css';
|
||||||
import 'reveal.js/plugin/highlight/monokai.css';
|
import 'reveal.js/plugin/highlight/monokai.css';
|
||||||
import Base from '../../layouts/Base.astro';
|
import Base from '../../layouts/Base.astro';
|
||||||
import { getCollection } from 'astro:content';
|
import { getCollection } from 'astro:content';
|
||||||
|
import { compile } from '../../assets/reveal-ssr/markdown';
|
||||||
|
|
||||||
|
|
||||||
export async function getStaticPaths () {
|
export async function getStaticPaths () {
|
||||||
|
@ -16,20 +17,17 @@ const { entry } = Astro.props;
|
||||||
|
|
||||||
<Base>
|
<Base>
|
||||||
<div class="reveal">
|
<div class="reveal">
|
||||||
<div class="slides">
|
<div class="slides" set:html={compile(entry.body)}></div>
|
||||||
<section data-markdown data-separator="^\n-----\n$" data-separator-vertical="^\n---\n$">
|
|
||||||
<textarea data-template>{entry.body}</textarea>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
import Reveal from 'reveal.js';
|
import Reveal from 'reveal.js';
|
||||||
import Markdown from '../../assets/reveal-md';
|
|
||||||
import Highlight from 'reveal.js/plugin/highlight/highlight';
|
import Highlight from 'reveal.js/plugin/highlight/highlight';
|
||||||
|
|
||||||
Reveal.initialize({
|
Reveal.initialize({
|
||||||
hash: true,
|
hash: true,
|
||||||
plugins: [Markdown, Highlight]
|
plugins: [
|
||||||
|
Highlight,
|
||||||
|
]
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue