@lowlighter/markdown 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -0
- package/deno.jsonc +119 -0
- package/deno.lock +2777 -0
- package/mod.mjs +1 -0
- package/mod.ts +2 -0
- package/mod_test.ts +1 -0
- package/package.json +42 -0
- package/plugins/anchors.mjs +1 -0
- package/plugins/anchors.ts +21 -0
- package/plugins/anchors_test.ts +8 -0
- package/plugins/directives.mjs +1 -0
- package/plugins/directives.ts +112 -0
- package/plugins/directives_test.ts +13 -0
- package/plugins/emojis.mjs +1 -0
- package/plugins/emojis.ts +20 -0
- package/plugins/emojis_test.ts +8 -0
- package/plugins/frontmatter.mjs +1 -0
- package/plugins/frontmatter.ts +43 -0
- package/plugins/frontmatter_test.ts +18 -0
- package/plugins/gfm.mjs +1 -0
- package/plugins/gfm.ts +14 -0
- package/plugins/gfm_test.ts +28 -0
- package/plugins/highlighting.mjs +1 -0
- package/plugins/highlighting.ts +24 -0
- package/plugins/highlighting_test.ts +8 -0
- package/plugins/linebreaks.mjs +1 -0
- package/plugins/linebreaks.ts +21 -0
- package/plugins/linebreaks_test.ts +8 -0
- package/plugins/markers.mjs +1 -0
- package/plugins/markers.ts +25 -0
- package/plugins/markers_test.ts +13 -0
- package/plugins/math.ts +25 -0
- package/plugins/math_test.ts +8 -0
- package/plugins/mermaid.ts +41 -0
- package/plugins/mermaid_test.ts +8 -0
- package/plugins/ruby.mjs +1 -0
- package/plugins/ruby.ts +20 -0
- package/plugins/ruby_test.ts +8 -0
- package/plugins/sanitize.mjs +1 -0
- package/plugins/sanitize.ts +26 -0
- package/plugins/sanitize_test.ts +15 -0
- package/plugins/uncomments.mjs +1 -0
- package/plugins/uncomments.ts +20 -0
- package/plugins/uncomments_test.ts +8 -0
- package/plugins/wikilinks.mjs +1 -0
- package/plugins/wikilinks.ts +40 -0
- package/plugins/wikilinks_test.ts +14 -0
- package/renderer.mjs +1 -0
- package/renderer.ts +124 -0
- package/renderer_test.ts +14 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { expect, test } from "@libs/testing"
|
|
2
|
+
import { Renderer } from "../renderer.ts"
|
|
3
|
+
import plugin from "./highlighting.ts"
|
|
4
|
+
|
|
5
|
+
test("deno")("Plugin.highlighting renders syntax highlighted code blocks", async () => {
|
|
6
|
+
const markdown = new Renderer({ plugins: [plugin] })
|
|
7
|
+
await expect(markdown.render("```ts\nconst foo = 'bar'\n```")).resolves.toMatch(/<pre><code class=".*language-ts">[\s\S]+<\/code><\/pre>/)
|
|
8
|
+
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var n=function(r){if(null==r)return e;if("function"==typeof r)return t(r);if("object"==typeof r)return Array.isArray(r)?function(e){const r=[];let o=-1;for(;++o<e.length;)r[o]=n(e[o]);return t(i);function i(...n){let t=-1;for(;++t<r.length;)if(r[t].apply(this,n))return!0;return!1}}(r):function(n){const e=n;return t(r);function r(t){const r=t;let o;for(o in n)if(r[o]!==e[o])return!1;return!0}}(r);if("string"==typeof r)return function(n){return t(e);function e(t){return t&&t.type===n}}(r);throw new Error("Expected function, string, or object as test")};function t(n){return function(t,e,r){return Boolean(function(n){return null!==n&&"object"==typeof n&&"type"in n}(t)&&n.call(this,t,"number"==typeof e?e:void 0,r||void 0))}}function e(){return!0}var r=[],o=!0,i=!1,u="skip";function f(t,e,f,c){let l;"function"==typeof e&&"function"!=typeof f?(c=f,f=e):l=e;const s=n(l),p=c?-1:1;!function n(t,l,a){const y=t&&"object"==typeof t?t:{};if("string"==typeof y.type){const n="string"==typeof y.tagName?y.tagName:"string"==typeof y.name?y.name:void 0;Object.defineProperty(d,"name",{value:"node ("+t.type+(n?"<"+n+">":"")+")"})}return d;function d(){let y,d,h,g=r;if((!e||s(t,l,a[a.length-1]||void 0))&&(g=function(n){if(Array.isArray(n))return n;if("number"==typeof n)return[o,n];return null==n?r:[n]}(f(t,a)),g[0]===i))return g;if("children"in t&&t.children){const e=t;if(e.children&&g[0]!==u)for(d=(c?e.children.length:-1)+p,h=a.concat(e);d>-1&&d<e.children.length;){const t=e.children[d];if(y=n(t,d,h)(),y[0]===i)return y;d="number"==typeof y[1]?y[1]:d+p}}return g}}(t,void 0,[])()}function c(t,e,r){const o=n((r||{}).ignore||[]),i=function(n){const t=[];if(!Array.isArray(n))throw new TypeError("Expected find and replace tuple or list of tuples");const e=!n[0]||Array.isArray(n[0])?n:[n];let r=-1;for(;++r<e.length;){const n=e[r];t.push([l(n[0]),s(n[1])])}return t}(e);let u=-1;for(;++u<i.length;)f(t,"text",c);function c(n,t){let e,r=-1;for(;++r<t.length;){const n=t[r],i=e?e.children:void 0;if(o(n,i?i.indexOf(n):void 0,e))return;e=n}if(e)return function(n,t){const e=t[t.length-1],r=i[u][0],o=i[u][1];let f=0;const c=e.children.indexOf(n);let l=!1,s=[];r.lastIndex=0;let p=r.exec(n.value);for(;p;){const e=p.index,i={index:p.index,input:p.input,stack:[...t,n]};let u=o(...p,i);if("string"==typeof u&&(u=u.length>0?{type:"text",value:u}:void 0),!1===u?r.lastIndex=e+1:(f!==e&&s.push({type:"text",value:n.value.slice(f,e)}),Array.isArray(u)?s.push(...u):u&&s.push(u),f=e+p[0].length,l=!0),!r.global)break;p=r.exec(n.value)}l?(f<n.value.length&&s.push({type:"text",value:n.value.slice(f)}),e.children.splice(c,1,...s)):s=[n];return c+s.length}(n,t)}}function l(n){return"string"==typeof n?new RegExp(function(n){if("string"!=typeof n)throw new TypeError("Expected a string");return n.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d")}(n),"g"):n}function s(n){return"function"==typeof n?n:function(){return n}}function p(){return{type:"break"}}function a(){return function(n){!function(n){c(n,[/\r?\n|\r/g,p])}(n)}}var y={remark:n=>n.use(a)};export{y as default};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Imports
|
|
2
|
+
import type { Plugin } from "../renderer.ts"
|
|
3
|
+
import remarkBreaks from "remark-breaks"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Force line-breaks to be hard-breaks.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```md
|
|
10
|
+
* foo
|
|
11
|
+
* bar
|
|
12
|
+
* ```
|
|
13
|
+
* ```html
|
|
14
|
+
* <p>foo<br>bar</p>
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export default {
|
|
18
|
+
remark(processor) {
|
|
19
|
+
return processor.use(remarkBreaks)
|
|
20
|
+
},
|
|
21
|
+
} as Plugin
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { expect, test } from "@libs/testing"
|
|
2
|
+
import { Renderer } from "../renderer.ts"
|
|
3
|
+
import plugin from "./linebreaks.ts"
|
|
4
|
+
|
|
5
|
+
test("deno")("Plugin.linebreaks renders hard linebreaks", async () => {
|
|
6
|
+
const markdown = new Renderer({ plugins: [plugin] })
|
|
7
|
+
await expect(markdown.render("foo\nbar")).resolves.toMatch(/foo<br>\nbar/)
|
|
8
|
+
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=function(n){if(null==n)return t;if("function"==typeof n)return r(n);if("object"==typeof n)return Array.isArray(n)?function(t){const n=[];let i=-1;for(;++i<t.length;)n[i]=e(t[i]);return r(o);function o(...e){let r=-1;for(;++r<n.length;)if(n[r].apply(this,e))return!0;return!1}}(n):function(e){const t=e;return r(n);function n(r){const n=r;let i;for(i in e)if(n[i]!==t[i])return!1;return!0}}(n);if("string"==typeof n)return function(e){return r(t);function t(r){return r&&r.type===e}}(n);throw new Error("Expected function, string, or object as test")};function r(e){return function(r,t,n){return Boolean(function(e){return null!==e&&"object"==typeof e&&"type"in e}(r)&&e.call(this,r,"number"==typeof t?t:void 0,n||void 0))}}function t(){return!0}var n=[],i=!0,o=!1,c="skip";function s(r,t,s,l){let a;"function"==typeof t&&"function"!=typeof s?(l=s,s=t):a=t;const f=e(a),u=l?-1:1;!function e(r,a,d){const h=r&&"object"==typeof r?r:{};if("string"==typeof h.type){const e="string"==typeof h.tagName?h.tagName:"string"==typeof h.name?h.name:void 0;Object.defineProperty(p,"name",{value:"node ("+r.type+(e?"<"+e+">":"")+")"})}return p;function p(){let h,p,m,y=n;if((!t||f(r,a,d[d.length-1]||void 0))&&(y=function(e){if(Array.isArray(e))return e;if("number"==typeof e)return[i,e];return null==e?n:[e]}(s(r,d)),y[0]===o))return y;if("children"in r&&r.children){const t=r;if(t.children&&y[0]!==c)for(p=(l?t.children.length:-1)+u,m=d.concat(t);p>-1&&p<t.children.length;){const r=t.children[p];if(h=e(r,p,m)(),h[0]===o)return h;p="number"==typeof h[1]?h[1]:p+u}}return y}}(r,void 0,[])()}function l(e,r,t,n){let i,o,c;"function"==typeof r&&"function"!=typeof t?(o=void 0,c=r,i=t):(o=r,c=t,i=n),s(e,o,(function(e,r){const t=r[r.length-1],n=t?t.children.indexOf(e):void 0;return c(e,n,t)}),i)}function a(e,r,t){const n={type:String(e)};return null!=t||"string"!=typeof r&&!Array.isArray(r)?Object.assign(n,r):t=r,Array.isArray(t)?n.children=t:null!=t&&(n.value=String(t)),n}var f={a:"amber",b:"blue",c:"cyan",d:"brown",e:"espresso",f:"fuchsia",g:"green",h:"hotpink",i:"indigo",j:"jade",k:"kiwi",l:"lime",m:"magenta",n:"navyblue",o:"orange",p:"purple",q:"pink",r:"red",s:"silver",t:"teal",u:"umber",v:"violet",w:"white",x:"gray",y:"yellow",z:"black"},u={dictionary:f,markerTagName:"mark",markerClassName:"flexible-marker",actionForEmptyContent:"mark"},d=/=([a-z]?)=(?![\s=])([\s\S]*?)(?<![\s=])==/,h=/=([a-z]?)=(?![\s=])([\s\S]*?)(?<![\s=])==/g,p=/=([a-z]?)=(?![\s]|=+\s)/,m=/=([a-z]?)=(?![\s]|=+\s)/g,y=/(?<!\s|\s=|\s==|\s===|\s====)==/,g=/(?<!\s|\s=|\s==|\s===|\s====)==/g,x=/=([a-z]?)=\s*==/,v=/=([a-z]?)=\s*==/g;var b=r=>{const t=Object.assign({},u,r);r?.dictionary&&Object.keys(r.dictionary).length&&(t.dictionary=Object.assign({},f,r.dictionary));const n=(e,r)=>{let n;const i=e?t.dictionary[e]:void 0,o="string"==typeof t.markerTagName?t.markerTagName:t.markerTagName(i),c="function"==typeof t.markerClassName?t.markerClassName(i):[t.markerClassName,!e&&`${t.markerClassName}-default`,i&&`${t.markerClassName}-${i}`,!r.length&&`${t.markerClassName}-empty`].filter((e=>!!e));return t.markerProperties&&(n=t.markerProperties(i),Object.entries(n).forEach((([e,r])=>{("string"==typeof r&&""===r||Array.isArray(r)&&0===r.length)&&n&&(n[e]=void 0),"className"===e&&delete n?.className}))),{type:"mark",children:r,data:{hName:o,hProperties:{className:c,...n&&{...n}}}}},o=function(e,r,t){if(!t||void 0===r)return;if(!d.test(e.value))return;const i=[],o=e.value;let c="",s=0,l=0;const f=Array.from(o.matchAll(h));for(let e=0;e<f.length;e++){const r=f[e],[t,u,d]=r,h=r.index,p=t.length,m=s+l;if(s=h,l=p,h>m){const e=a("text",o.substring(m,h));i.push(e)}const y=n(u,[{type:"text",value:d.trim()}]);i.push(y),c=o.slice(h+p)}if(c){const e=a("text",c);i.push(e)}i.length&&t.children.splice(r,1,...i)},s=function(r,t,i){if(!i||void 0===t)return;if(!p.test(r.value))return;const o=r,c=function(r,t,n){const i=e(n);if(!r||!r.type||!r.children)throw new Error("Expected parent node");if("number"==typeof t){if(t<0||t===Number.POSITIVE_INFINITY)throw new Error("Expected positive finite number as index")}else if((t=r.children.indexOf(t))<0)throw new Error("Expected child node or index");for(;++t<r.children.length;)if(i(r.children[t],t,r))return r.children[t]}(i,o,(function(e){return"text"===e.type&&y.test(e.value)}));if(!c)return;const s=function(r,t,n){const i=e(n),o=[];let c=-1;if(!r||!r.type||!r.children)throw new Error("Expected parent node");if("number"==typeof t){if(t<0||t===Number.POSITIVE_INFINITY)throw new Error("Expected positive finite number as index")}else if((t=r.children.indexOf(t))<0)throw new Error("Expected child node or index");for(t>r.children.length&&(t=r.children.length);++c<t;)i(r.children[c],c,r)&&o.push(r.children[c]);return o}(i,o),l=function(r,t,n,i,o){const c=e(i),s=[];if(!r||!r.type||!r.children)throw new Error("Expected parent node");if("number"==typeof t){if(t<0||t===Number.POSITIVE_INFINITY)throw new Error("Expected positive finite number as index for start")}else if((t=r.children.indexOf(t))<0)throw new Error("Expected child node or index for start");if("number"==typeof n){if(n<0||n===Number.POSITIVE_INFINITY)throw new Error("Expected positive finite number as index for end")}else if((n=r.children.indexOf(n))<0)throw new Error("Expected child node or index for end");if("include"===o?.behaviour)for(;t<=n;)c(r.children[t],t,r)&&s.push(r.children[t]),t++;else for(;++t<n;)c(r.children[t],t,r)&&s.push(r.children[t]);return s}(i,o,c),f=function(r,t,n){const i=e(n),o=[];if(!r||!r.type||!r.children)throw new Error("Expected parent node");if("number"==typeof t){if(t<0||t===Number.POSITIVE_INFINITY)throw new Error("Expected positive finite number as index")}else if((t=r.children.indexOf(t))<0)throw new Error("Expected child node or index");for(;++t<r.children.length;)i(r.children[t],t,r)&&o.push(r.children[t]);return o}(i,c),u=o.value,d=Array.from(u.matchAll(m))[0],[h,x]=d,v=h.length,b=d.index;if(b>0){const e=a("text",u.substring(0,b));s.push(e)}if(u.length>b+v){const e=a("text",u.slice(b+v));l.unshift(e)}const E=c.value,w=Array.from(E.matchAll(g))[0],[N]=w,k=N.length,I=w.index;if(I>0){const e=a("text",E.substring(0,I));l.push(e)}if(E.length>I+k){const e=a("text",E.slice(I+k));f.unshift(e)}const A=n(x,l);return i.children=[...s,A,...f],t},b=function(e,r,o){if(!o||void 0===r)return;if(!x.test(e.value))return;if("remove"===t.actionForEmptyContent)return e.value=e.value.replaceAll(v,""),""===e.value.trim()?[c,r]:i;const s=[],l=e.value;let f="",u=0,d=0;const h=Array.from(l.matchAll(v));for(let e=0;e<h.length;e++){const r=h[e],[t,i]=r,o=r.index,c=t.length,p=u+d;if(u=o,d=c,o>p){const e=a("text",l.substring(p,o));s.push(e)}const m=n(i,[]);s.push(m),f=l.slice(o+c)}if(f){const e=a("text",f);s.push(e)}s.length&&o.children.splice(r,1,...s)};return e=>{if(l(e,"text",o),l(e,"text",s),"keep"!==t.actionForEmptyContent&&l(e,"text",b),t.equalityOperator){const r=new RegExp(t.equalityOperator,"gi");l(e,"text",(e=>{e.value=e.value.replaceAll(r,"==")}))}}},E=Object.fromEntries([..."abcdefghijklmnopqrstuvwxyz"].map((e=>[e,e]))),w={remark:e=>e.use(b,{dictionary:E,markerClassName:()=>[],markerProperties:e=>e?{[e]:!0}:{}})};export{w as default};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Imports
|
|
2
|
+
import type { Plugin } from "../renderer.ts"
|
|
3
|
+
import remarkFlexibleMarkers from "remark-flexible-markers"
|
|
4
|
+
|
|
5
|
+
/** Marker attributes */
|
|
6
|
+
const dictionary = Object.fromEntries([..."abcdefghijklmnopqrstuvwxyz"].map((letter) => [letter, letter]))
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Add support for markers.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```md
|
|
13
|
+
* ==foo==
|
|
14
|
+
* =r=bar=
|
|
15
|
+
* ```
|
|
16
|
+
* ```html
|
|
17
|
+
* <p><mark>foo</mark></p>
|
|
18
|
+
* <p><mark r>bar</mark></p>
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export default {
|
|
22
|
+
remark(processor) {
|
|
23
|
+
return processor.use(remarkFlexibleMarkers, { dictionary, markerClassName: () => [], markerProperties: (letter) => (letter ? { [letter]: true } : {}) })
|
|
24
|
+
},
|
|
25
|
+
} as Plugin
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { expect, test } from "@libs/testing"
|
|
2
|
+
import { Renderer } from "../renderer.ts"
|
|
3
|
+
import plugin from "./markers.ts"
|
|
4
|
+
|
|
5
|
+
test("deno")("Plugin.markers renders markers", async () => {
|
|
6
|
+
const markdown = new Renderer({ plugins: [plugin] })
|
|
7
|
+
await expect(markdown.render("==foo==")).resolves.toMatch(/<mark class="">foo<\/mark>/)
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
test("deno")("Plugin.markers renders colored markers", async () => {
|
|
11
|
+
const markdown = new Renderer({ plugins: [plugin] })
|
|
12
|
+
await expect(markdown.render("=r=foo==")).resolves.toMatch(/<mark class="" r="">foo<\/mark>/)
|
|
13
|
+
})
|
package/plugins/math.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Imports
|
|
2
|
+
import type { Plugin } from "../renderer.ts"
|
|
3
|
+
import remarkMath from "remark-math"
|
|
4
|
+
import rehypeMathjax from "rehype-mathjax"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Add support for math.
|
|
8
|
+
*
|
|
9
|
+
* {@link https://www.mathjax.org | See MathJax documentation for more information}.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```md
|
|
13
|
+
* $$
|
|
14
|
+
* \frac{1}{2}
|
|
15
|
+
* $$
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export default {
|
|
19
|
+
remark(processor) {
|
|
20
|
+
return processor.use(remarkMath)
|
|
21
|
+
},
|
|
22
|
+
rehype(processor) {
|
|
23
|
+
return processor.use(rehypeMathjax)
|
|
24
|
+
},
|
|
25
|
+
} as Plugin
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { expect, test } from "@libs/testing"
|
|
2
|
+
import { Renderer } from "../renderer.ts"
|
|
3
|
+
import plugin from "./math.ts"
|
|
4
|
+
|
|
5
|
+
test("deno")("Plugin.math renders math expressions", async () => {
|
|
6
|
+
const markdown = new Renderer({ plugins: [plugin] })
|
|
7
|
+
await expect(markdown.render("$$\\pi$$")).resolves.toMatch(/mjx-container class="MathJax"/)
|
|
8
|
+
})
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Imports
|
|
2
|
+
import type { Plugin } from "../renderer.ts"
|
|
3
|
+
import rehypeMermaid from "rehype-mermaid"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Add support for Mermaid diagrams.
|
|
7
|
+
*
|
|
8
|
+
* {@link https://mermaid-js.github.io/mermaid/ | See Mermaid documentation for more information}.
|
|
9
|
+
*
|
|
10
|
+
* > [!WARNING]
|
|
11
|
+
* > This plugin requires playwright browser to be installed.
|
|
12
|
+
* >
|
|
13
|
+
* > You can install it by running the following command:
|
|
14
|
+
* > ```sh
|
|
15
|
+
* > npx playwright-core install --with-deps chromium
|
|
16
|
+
* > ```
|
|
17
|
+
*
|
|
18
|
+
* > [!WARNING]
|
|
19
|
+
* > This plugin requires the following permission in Deno:
|
|
20
|
+
* > - read
|
|
21
|
+
* > - env
|
|
22
|
+
* > - sys
|
|
23
|
+
* > - write: <TMP>
|
|
24
|
+
* > - run: <location to playwright browser executable>
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ````md
|
|
28
|
+
* ```mermaid
|
|
29
|
+
* graph TD;
|
|
30
|
+
* A-->B;
|
|
31
|
+
* A-->C;
|
|
32
|
+
* B-->D;
|
|
33
|
+
* C-->D;
|
|
34
|
+
* ```
|
|
35
|
+
* ````
|
|
36
|
+
*/
|
|
37
|
+
export default {
|
|
38
|
+
rehype(processor) {
|
|
39
|
+
return processor.use(rehypeMermaid, { strategy: "inline-svg", launchOptions: { headless: true, args: ["--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage", "--disable-accelerated-2d-canvas", "--no-zygote", "--disable-gpu"] } })
|
|
40
|
+
},
|
|
41
|
+
} as Plugin
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { expect, test } from "@libs/testing"
|
|
2
|
+
import { Renderer } from "../renderer.ts"
|
|
3
|
+
import plugin from "./mermaid.ts"
|
|
4
|
+
|
|
5
|
+
test.skip("deno")("Plugin.mermaid renders mermaid diagrams", async () => {
|
|
6
|
+
const markdown = new Renderer({ plugins: [plugin] })
|
|
7
|
+
await expect(markdown.render("```mermaid\ngraph TD;\nA-->A;\n```")).resolves.toMatch(/foo<br>\nbar/)
|
|
8
|
+
}, { permissions: { read: true, env: true, sys: true, write: "inherit", run: "inherit" } })
|
package/plugins/ruby.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e,r,t,n=Object.create,s=Object.defineProperty,o=Object.getOwnPropertyDescriptor,a=Object.getOwnPropertyNames,i=Object.getPrototypeOf,u=Object.prototype.hasOwnProperty,c=(e=>"undefined"!=typeof require?require:"undefined"!=typeof Proxy?new Proxy(e,{get:(e,r)=>("undefined"!=typeof require?require:e)[r]}):e)((function(e){if("undefined"!=typeof require)return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')})),l=(e,r)=>function(){return r||(0,e[a(e)[0]])((r={exports:{}}).exports,r),r.exports},d=l({"node_modules/.deno/remark-ruby@0.4.0/node_modules/remark-ruby/lib/from-markdown.js"(e,r){var t=/\[[^\]]+\]/;function n(e){let r=e;const n=[];let s=t.exec(r);if(!s)return r;for(;s;)0!==s.index&&n.push(r.substr(0,s.index)),n.push(s[0].substr(1,s[0].length-2)),r=r.substr(s[0].length+s.index),s=t.exec(r);return n.length<=1?n[0]:n}r.exports=function(e){return{enter:{ruby(e){this.enter({type:"ruby",base:null,text:null,children:[],data:{hName:"ruby",hChildren:[]}},e)},rubyText(){this.stack.push({type:"fragment",children:[]})},rubyPronunciation(){this.stack.push({type:"fragment",children:[]})}},exit:{ruby(r){const t=this.stack[this.stack.length-1],n=t.base,s=t.text;let o;o="string"==typeof n?[{type:"text",value:n}]:n.map((e=>({type:"element",children:[{type:"text",value:e}],tagName:"rb"})));const a=[].concat(s).map((e=>({type:"element",children:[{type:"text",value:e}],tagName:"rt"})));t.data.hChildren=[o,{type:"element",children:[{type:"text",value:e[0]}],tagName:"rp"},a,{type:"element",children:[{type:"text",value:e[e.length-1]}],tagName:"rp"}].reduce(((e,r)=>e.concat(r)),[]),this.exit(r)},rubyText(){const e=n(this.resume());this.stack[this.stack.length-1].base=e},rubyPronunciation(){const e=n(this.resume());this.stack[this.stack.length-1].text=e}}}}}}),p=l({"node_modules/.deno/remark-ruby@0.4.0/node_modules/remark-ruby/lib/to-markdown.js"(e,r){function t(e){return"string"==typeof e?e:e.map((e=>`[${e}]`)).join("")}function n(e){return`{${t(e.base)}}^(${t(e.text)})`}n.peek=function(){return"{"},r.exports={unsafe:[{character:"{",inConstruct:"phrasing"}],handlers:{ruby:n}}}}),m=l({"node_modules/.deno/micromark@2.11.4/node_modules/micromark/dist/character/codes.js"(e,r){r.exports={carriageReturn:-5,lineFeed:-4,carriageReturnLineFeed:-3,horizontalTab:-2,virtualSpace:-1,eof:null,nul:0,soh:1,stx:2,etx:3,eot:4,enq:5,ack:6,bel:7,bs:8,ht:9,lf:10,vt:11,ff:12,cr:13,so:14,si:15,dle:16,dc1:17,dc2:18,dc3:19,dc4:20,nak:21,syn:22,etb:23,can:24,em:25,sub:26,esc:27,fs:28,gs:29,rs:30,us:31,space:32,exclamationMark:33,quotationMark:34,numberSign:35,dollarSign:36,percentSign:37,ampersand:38,apostrophe:39,leftParenthesis:40,rightParenthesis:41,asterisk:42,plusSign:43,comma:44,dash:45,dot:46,slash:47,digit0:48,digit1:49,digit2:50,digit3:51,digit4:52,digit5:53,digit6:54,digit7:55,digit8:56,digit9:57,colon:58,semicolon:59,lessThan:60,equalsTo:61,greaterThan:62,questionMark:63,atSign:64,uppercaseA:65,uppercaseB:66,uppercaseC:67,uppercaseD:68,uppercaseE:69,uppercaseF:70,uppercaseG:71,uppercaseH:72,uppercaseI:73,uppercaseJ:74,uppercaseK:75,uppercaseL:76,uppercaseM:77,uppercaseN:78,uppercaseO:79,uppercaseP:80,uppercaseQ:81,uppercaseR:82,uppercaseS:83,uppercaseT:84,uppercaseU:85,uppercaseV:86,uppercaseW:87,uppercaseX:88,uppercaseY:89,uppercaseZ:90,leftSquareBracket:91,backslash:92,rightSquareBracket:93,caret:94,underscore:95,graveAccent:96,lowercaseA:97,lowercaseB:98,lowercaseC:99,lowercaseD:100,lowercaseE:101,lowercaseF:102,lowercaseG:103,lowercaseH:104,lowercaseI:105,lowercaseJ:106,lowercaseK:107,lowercaseL:108,lowercaseM:109,lowercaseN:110,lowercaseO:111,lowercaseP:112,lowercaseQ:113,lowercaseR:114,lowercaseS:115,lowercaseT:116,lowercaseU:117,lowercaseV:118,lowercaseW:119,lowercaseX:120,lowercaseY:121,lowercaseZ:122,leftCurlyBrace:123,verticalBar:124,rightCurlyBrace:125,tilde:126,del:127,byteOrderMarker:65279,replacementCharacter:65533}}}),y=l({"node_modules/.deno/micromark@2.11.4/node_modules/micromark/dist/character/markdown-line-ending.js"(e,r){r.exports=function(e){return e<-2}}}),h=l({"node_modules/.deno/micromark@2.11.4/node_modules/micromark/dist/character/markdown-space.js"(e,r){r.exports=function(e){return-2===e||-1===e||32===e}}}),f=l({"node_modules/.deno/micromark@2.11.4/node_modules/micromark/dist/constant/splice.js"(e,r){var t=[].splice;r.exports=t}}),b=l({"node_modules/.deno/micromark@2.11.4/node_modules/micromark/dist/util/chunked-splice.js"(e,r){var t=f();r.exports=function(e,r,n,s){var o,a=e.length,i=0;if(r=r<0?-r>a?0:a+r:r>a?a:r,n=n>0?n:0,s.length<1e4)(o=Array.from(s)).unshift(r,n),t.apply(e,o);else for(n&&t.apply(e,[r,n]);i<s.length;)(o=s.slice(i,i+1e4)).unshift(r,0),t.apply(e,o),i+=1e4,r+=1e4}}}),k=l({"node_modules/.deno/micromark@2.11.4/node_modules/micromark/dist/util/chunked-push.js"(e,r){var t=b();r.exports=function(e,r){return e.length?(t(e,e.length,0,r),e):r}}}),g=l({"node_modules/.deno/micromark@2.11.4/node_modules/micromark/dist/util/normalize-identifier.js"(e,r){r.exports=function(e){return e.replace(/[\t\n\r ]+/g," ").replace(/^ | $/g,"").toLowerCase().toUpperCase()}}}),x=l({"node_modules/.deno/micromark@2.11.4/node_modules/micromark/dist/util/resolve-all.js"(e,r){r.exports=function(e,r,t){for(var n,s=[],o=-1;++o<e.length;)(n=e[o].resolveAll)&&s.indexOf(n)<0&&(r=n(r,t),s.push(n));return r}}}),_=l({"node_modules/.deno/micromark@2.11.4/node_modules/micromark/dist/constant/assign.js"(e,r){var t=Object.assign;r.exports=t}}),w=l({"node_modules/.deno/micromark@2.11.4/node_modules/micromark/dist/util/shallow.js"(e,r){var t=_();r.exports=function(e){return t({},e)}}}),v=l({"node_modules/.deno/remark-ruby@0.4.0/node_modules/remark-ruby/lib/tokenize/ruby-end.js"(e,r){var t=c("assert"),n=m(),s=y(),o=h(),a=k(),i=b(),u=g(),l=x(),d=w(),p={tokenize:function(e,r,a){let i,u=0;return function(r){return t(r===n.leftParenthesis,"expected left paren"),e.enter("rubyPronunciation"),e.enter("rubyPronunciationMarker"),e.consume(r),e.exit("rubyPronunciationMarker"),c};function c(t){return t===n.rightParenthesis?function(t){if(t===n.rightParenthesis)return e.enter("rubyPronunciationMarker"),e.consume(t),e.exit("rubyPronunciationMarker"),e.exit("rubyPronunciation"),r;return a(t)}(t):s(t)?(e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),c):(e.enter("chunkString",{contentType:"string"}),l(t))}function l(r){return r===n.eof||r===n.leftParenthesis||r===n.rightParenthesis||s(r)||u++>999?(e.exit("chunkString"),c(r)):(e.consume(r),i=i||!o(r),r===n.backslash?d:l)}function d(r){return r===n.leftParenthesis||r===n.backslash||r===n.rightParenthesis?(e.consume(r),u++,l):l(r)}}};r.exports={tokenize:function(e,r,s){const o=this;let a,i,c=o.events.length;for(;c--;)if("rubyStart"===o.events[c][1].type&&!o.events[c][1]._balanced){[,a]=o.events[c];break}return function(r){if(t(r===n.rightCurlyBrace,"expected `}`"),!a)return s(r);return a._inactive?m(r):(i=o.parser.defined.indexOf(u(o.sliceSerialize({start:a.end,end:o.now()})))>-1,e.enter("rubyEnd"),e.enter("rubyMarker"),e.consume(r),e.exit("rubyMarker"),e.exit("rubyEnd"),l)};function l(r){return r!==n.caret?s(r):(e.consume(r),d)}function d(t){return t===n.leftParenthesis?e.attempt(p,r,i?r:m)(t):i?r(t):m(t)}function m(e){return a._balanced=!0,s(e)}},resolveTo:function(e,r){let t,n,s,o,u=e.length;for(;u--;)if([,t]=e[u],n){if("ruby"===t.type||"rubyStart"===t.type&&t._inactive)break;"enter"===e[u][0]&&"rubyStart"===t.type&&(t._inactive=!0)}else s?"enter"!==e[u][0]||"rubyStart"!==t.type||t._balanced||(n=u):"rubyEnd"===t.type&&(s=u);const c={type:"ruby",start:d(e[n][1].start),end:d(e[e.length-1][1].end)},p={type:"rubyLabel",start:d(e[n][1].start),end:d(e[s][1].end)},m={type:"rubyText",start:d(e[n+2][1].end),end:d(e[s-2][1].start)};return o=[["enter",c,r],["enter",p,r]],o=a(o,e.slice(n+1,n+3)),o=a(o,[["enter",m,r]]),o=a(o,l(r.parser.constructs.insideSpan.null,e.slice(n+4,s-3),r)),o=a(o,[["exit",m,r],e[s-2],e[s-1],["exit",p,r]]),o=a(o,e.slice(s+1)),o=a(o,[["exit",c,r]]),i(e,n,e.length,o),e},resolveAll:function(e){let r,t=-1;for(;++t<e.length;)[,r]=e[t],r._used||"rubyStart"!==r.type&&"rubyEnd"!==r.type||(e.splice(t+1,2),r.type="data",t++);return e}}}}),P=l({"node_modules/.deno/remark-ruby@0.4.0/node_modules/remark-ruby/lib/tokenize/ruby-start.js"(e,r){var t=c("assert"),n=v();r.exports={tokenize:function(e,r){return function(n){return t(123===n,"expected `{`"),e.enter("rubyStart"),e.enter("rubyMarker"),e.consume(n),e.exit("rubyMarker"),e.exit("rubyStart"),r(n)}},resolveAll:n.resolveAll}}}),j=l({"node_modules/.deno/remark-ruby@0.4.0/node_modules/remark-ruby/lib/index.js"(e,r){var t=d(),n=p(),s=v(),o=P();r.exports=function(e){const r=this.data(),a=e&&e.parenthesis?e.parenthesis:"()";function i(e,t){r[e]?r[e].push(t):r[e]=[t]}i("micromarkExtensions",{text:{123:o,125:s},insideSpan:{null:o}}),i("fromMarkdownExtensions",t(a)),i("toMarkdownExtensions",n)}}}),S=l({"node_modules/.deno/remark-ruby@0.4.0/node_modules/remark-ruby/index.js"(e,r){r.exports=j()}}),M=(e=S(),t=null!=e?n(i(e)):{},((e,r,t,n)=>{if(r&&"object"==typeof r||"function"==typeof r)for(let i of a(r))u.call(e,i)||i===t||s(e,i,{get:()=>r[i],enumerable:!(n=o(r,i))||n.enumerable});return e})(!r&&e&&e.__esModule?t:s(t,"default",{value:e,enumerable:!0}),e)),O={remark:e=>e.use(M.default)};export{O as default};
|
package/plugins/ruby.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Imports
|
|
2
|
+
import type { Plugin } from "../renderer.ts"
|
|
3
|
+
import remarkRuby from "remark-ruby"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Add support for {@link https://developer.mozilla.org/docs/Web/HTML/Element/ruby | ruby} text.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```md
|
|
10
|
+
* {漢字}^(kanji)
|
|
11
|
+
* ```
|
|
12
|
+
* ```html
|
|
13
|
+
* <ruby>漢字<rp>(</rp><rt>kanji</rt><rp>)</rp></ruby>
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export default {
|
|
17
|
+
remark(processor) {
|
|
18
|
+
return processor.use(remarkRuby)
|
|
19
|
+
},
|
|
20
|
+
} as Plugin
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { expect, test } from "@libs/testing"
|
|
2
|
+
import { Renderer } from "../renderer.ts"
|
|
3
|
+
import plugin from "./ruby.ts"
|
|
4
|
+
|
|
5
|
+
test("deno")("Plugin.ruby renders ruby content", async () => {
|
|
6
|
+
const markdown = new Renderer({ plugins: [plugin] })
|
|
7
|
+
await expect(markdown.render("{foo}^(bar)")).resolves.toMatch(/<ruby>foo<rp>\(<\/rp><rt>bar<\/rt><rp>\)<\/rp><\/ruby>/)
|
|
8
|
+
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e="object"==typeof self?self:globalThis,t=t=>((t,r)=>{const n=(e,r)=>(t.set(r,e),e),s=o=>{if(t.has(o))return t.get(o);const[c,a]=r[o];switch(c){case 0:case-1:return n(a,o);case 1:{const e=n([],o);for(const t of a)e.push(s(t));return e}case 2:{const e=n({},o);for(const[t,r]of a)e[s(t)]=s(r);return e}case 3:return n(new Date(a),o);case 4:{const{source:e,flags:t}=a;return n(new RegExp(e,t),o)}case 5:{const e=n(new Map,o);for(const[t,r]of a)e.set(s(t),s(r));return e}case 6:{const e=n(new Set,o);for(const t of a)e.add(s(t));return e}case 7:{const{name:t,message:r}=a;return n(new e[t](r),o)}case 8:return n(BigInt(a),o);case"BigInt":return n(Object(BigInt(a)),o)}return n(new e[c](a),o)};return s})(new Map,t)(0),r="",{toString:n}={},{keys:s}=Object,o=e=>{const t=typeof e;if("object"!==t||!e)return[0,t];const s=n.call(e).slice(8,-1);switch(s){case"Array":return[1,r];case"Object":return[2,r];case"Date":return[3,r];case"RegExp":return[4,r];case"Map":return[5,r];case"Set":return[6,r]}return s.includes("Array")?[1,s]:s.includes("Error")?[7,s]:[2,s]},c=([e,t])=>0===e&&("function"===t||"symbol"===t),a=(e,{json:t,lossy:r}={})=>{const n=[];return((e,t,r,n)=>{const a=(e,t)=>{const s=n.push(e)-1;return r.set(t,s),s},i=n=>{if(r.has(n))return r.get(n);let[l,u]=o(n);switch(l){case 0:{let t=n;switch(u){case"bigint":l=8,t=n.toString();break;case"function":case"symbol":if(e)throw new TypeError("unable to serialize "+u);t=null;break;case"undefined":return a([-1],n)}return a([l,t],n)}case 1:{if(u)return a([u,[...n]],n);const e=[],t=a([l,e],n);for(const t of n)e.push(i(t));return t}case 2:{if(u)switch(u){case"BigInt":return a([u,n.toString()],n);case"Boolean":case"Number":case"String":return a([u,n.valueOf()],n)}if(t&&"toJSON"in n)return i(n.toJSON());const r=[],f=a([l,r],n);for(const t of s(n))!e&&c(o(n[t]))||r.push([i(t),i(n[t])]);return f}case 3:return a([l,n.toISOString()],n);case 4:{const{source:e,flags:t}=n;return a([l,{source:e,flags:t}],n)}case 5:{const t=[],r=a([l,t],n);for(const[r,s]of n)(e||!c(o(r))&&!c(o(s)))&&t.push([i(r),i(s)]);return r}case 6:{const t=[],r=a([l,t],n);for(const r of n)!e&&c(o(r))||t.push(i(r));return r}}const{message:f}=n;return a([l,{name:u,message:f}],n)};return i})(!(t||r),!!t,new Map,n)(e),n},i="function"==typeof structuredClone?(e,r)=>r&&("json"in r||"lossy"in r)?t(a(e,r)):structuredClone(e):(e,r)=>t(a(e,r)),l=f("end"),u=f("start");function f(e){return function(t){const r=t&&t.position&&t.position[e]||{};if("number"==typeof r.line&&r.line>0&&"number"==typeof r.column&&r.column>0)return{line:r.line,column:r.column,offset:"number"==typeof r.offset&&r.offset>-1?r.offset:void 0}}}var p=["ariaDescribedBy","ariaLabel","ariaLabelledBy"],h={ancestors:{tbody:["table"],td:["table"],th:["table"],thead:["table"],tfoot:["table"],tr:["table"]},attributes:{a:[...p,"dataFootnoteBackref","dataFootnoteRef",["className","data-footnote-backref"],"href"],blockquote:["cite"],code:[["className",/^language-./]],del:["cite"],div:["itemScope","itemType"],dl:[...p],h2:[["className","sr-only"]],img:[...p,"longDesc","src"],input:[["disabled",!0],["type","checkbox"]],ins:["cite"],li:[["className","task-list-item"]],ol:[...p,["className","contains-task-list"]],q:["cite"],section:["dataFootnotes",["className","footnotes"]],source:["srcSet"],summary:[...p],table:[...p],ul:[...p,["className","contains-task-list"]],"*":["abbr","accept","acceptCharset","accessKey","action","align","alt","axis","border","cellPadding","cellSpacing","char","charOff","charSet","checked","clear","colSpan","color","cols","compact","coords","dateTime","dir","encType","frame","hSpace","headers","height","hrefLang","htmlFor","id","isMap","itemProp","label","lang","maxLength","media","method","multiple","name","noHref","noShade","noWrap","open","prompt","readOnly","rev","rowSpan","rows","rules","scope","selected","shape","size","span","start","summary","tabIndex","title","useMap","vAlign","value","width"]},clobber:["ariaDescribedBy","ariaLabelledBy","id","name"],clobberPrefix:"user-content-",protocols:{cite:["http","https"],href:["http","https","irc","ircs","mailto","xmpp"],longDesc:["http","https"],src:["http","https"]},required:{input:{disabled:!0,type:"checkbox"}},strip:["script"],tagNames:["a","b","blockquote","br","code","dd","del","details","div","dl","dt","em","h1","h2","h3","h4","h5","h6","hr","i","img","input","ins","kbd","li","ol","p","picture","pre","q","rp","rt","ruby","s","samp","section","source","span","strike","strong","sub","summary","sup","table","tbody","td","tfoot","th","thead","tr","tt","ul","var"]},d={}.hasOwnProperty;function m(e,t){if(t&&"object"==typeof t){const r=t;switch("string"==typeof r.type?r.type:""){case"comment":return function(e,t){if(e.schema.allowComments){const e="string"==typeof t.value?t.value:"",r=e.indexOf("--\x3e"),n={type:"comment",value:r<0?e:e.slice(0,r)};return k(n,t),n}}(e,r);case"doctype":return function(e,t){if(e.schema.allowDoctypes){const e={type:"doctype"};return k(e,t),e}}(e,r);case"element":return function(e,t){const r="string"==typeof t.tagName?t.tagName:"";e.stack.push(r);const n=b(e,t.children),s=function(e,t){const r=e.stack[e.stack.length-1],n=e.schema.attributes,s=e.schema.required,o=n&&d.call(n,r)?n[r]:void 0,c=n&&d.call(n,"*")?n["*"]:void 0,a=t&&"object"==typeof t?t:{},i={};let l;for(l in a)if(d.call(a,l)){const t=a[l];let r=y(e,w(o,l),l,t);null==r&&(r=y(e,w(c,l),l,t)),null!=r&&(i[l]=r)}if(s&&d.call(s,r)){const e=s[r];for(l in e)d.call(e,l)&&!d.call(i,l)&&(i[l]=e[l])}return i}(e,t.properties);e.stack.pop();let o=!1;if(r&&"*"!==r&&(!e.schema.tagNames||e.schema.tagNames.includes(r))&&(o=!0,e.schema.ancestors&&d.call(e.schema.ancestors,r))){const t=e.schema.ancestors[r];let n=-1;for(o=!1;++n<t.length;)e.stack.includes(t[n])&&(o=!0)}if(!o)return e.schema.strip&&!e.schema.strip.includes(r)?n:void 0;const c={type:"element",tagName:r,properties:s,children:n};return k(c,t),c}(e,r);case"root":return function(e,t){const r=b(e,t.children),n={type:"root",children:r};return k(n,t),n}(e,r);case"text":return function(e,t){const r="string"==typeof t.value?t.value:"",n={type:"text",value:r};return k(n,t),n}(0,r)}}}function b(e,t){const r=[];if(Array.isArray(t)){const n=t;let s=-1;for(;++s<n.length;){const t=m(e,n[s]);t&&(Array.isArray(t)?r.push(...t):r.push(t))}}return r}function y(e,t,r,n){return t?Array.isArray(n)?function(e,t,r,n){let s=-1;const o=[];for(;++s<n.length;){const c=g(e,t,r,n[s]);"number"!=typeof c&&"string"!=typeof c||o.push(c)}return o}(e,t,r,n):g(e,t,r,n):void 0}function g(e,t,r,n){if(("boolean"==typeof n||"number"==typeof n||"string"==typeof n)&&function(e,t,r){const n=e.schema.protocols&&d.call(e.schema.protocols,t)?e.schema.protocols[t]:void 0;if(!n||0===n.length)return!0;const s=String(r),o=s.indexOf(":"),c=s.indexOf("?"),a=s.indexOf("#"),i=s.indexOf("/");if(o<0||i>-1&&o>i||c>-1&&o>c||a>-1&&o>a)return!0;let l=-1;for(;++l<n.length;){const e=n[l];if(o===e.length&&s.slice(0,e.length)===e)return!0}return!1}(e,r,n)){if("object"==typeof t&&t.length>1){let e=!1,r=0;for(;++r<t.length;){const s=t[r];if(s&&"object"==typeof s&&"flags"in s){if(s.test(String(n))){e=!0;break}}else if(s===n){e=!0;break}}if(!e)return}return e.schema.clobber&&e.schema.clobberPrefix&&e.schema.clobber.includes(r)?e.schema.clobberPrefix+n:n}}function k(e,t){const r=function(e){const t=u(e),r=l(e);if(t&&r)return{start:t,end:r}}(t);t.data&&(e.data=i(t.data)),r&&(e.position=r)}function w(e,t){let r,n=-1;if(e)for(;++n<e.length;){const s=e[n],o="string"==typeof s?s:s[0];if(o===t)return s;"data*"===o&&(r=s)}if(t.length>4&&"data"===t.slice(0,4).toLowerCase())return r}function v(e){return function(t){const r=function(e,t){let r={type:"root",children:[]};const n=m({schema:t?{...h,...t}:h,stack:[]},e);return n&&(Array.isArray(n)?1===n.length?r=n[0]:r.children=n:r=n),r}(t,e);return r}}var x=S();function S(e=h){return{rehype:t=>t.use(v,e)}}export{S as create,x as default,h as schema};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Imports
|
|
2
|
+
import type { Plugin } from "../renderer.ts"
|
|
3
|
+
import rehypeSanitize, { defaultSchema as defaults } from "rehype-sanitize"
|
|
4
|
+
export { defaults as schema }
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Sanitize HTML.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```md
|
|
11
|
+
* <script>alert('foo')</script>
|
|
12
|
+
* ```
|
|
13
|
+
* ```html
|
|
14
|
+
* <p></p>
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export default create() as Plugin
|
|
18
|
+
|
|
19
|
+
/** Create a new HTML sanitization plugin. */
|
|
20
|
+
export function create(schema = defaults): Plugin {
|
|
21
|
+
return {
|
|
22
|
+
rehype(processor) {
|
|
23
|
+
return processor.use(rehypeSanitize, schema)
|
|
24
|
+
},
|
|
25
|
+
} as Plugin
|
|
26
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { expect, test } from "@libs/testing"
|
|
2
|
+
import { Renderer } from "../renderer.ts"
|
|
3
|
+
import plugin, { create, schema } from "./sanitize.ts"
|
|
4
|
+
|
|
5
|
+
test("deno")("Plugin.sanitize renders sanitized output", async () => {
|
|
6
|
+
const markdown = new Renderer({ plugins: [plugin] })
|
|
7
|
+
await expect(markdown.render("foo <script>console.log('hello')</script> bar")).not.resolves.toContain("<script>")
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
test("deno")("Plugin.sanitize exposes a way to create custom sanitization", async () => {
|
|
11
|
+
const a = new Renderer({ plugins: [create({ ...schema, attributes: { span: [] } })] })
|
|
12
|
+
await expect(a.render("<span foo></span>")).resolves.not.toContain("foo")
|
|
13
|
+
const b = new Renderer({ plugins: [create({ ...schema, attributes: { span: ["foo"] } })] })
|
|
14
|
+
await expect(b.render("<span foo></span>")).resolves.toContain("foo")
|
|
15
|
+
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e,t,n=Object.create,r=Object.defineProperty,o=Object.getOwnPropertyDescriptor,u=Object.getOwnPropertyNames,f=Object.getPrototypeOf,i=Object.prototype.hasOwnProperty,c=(e={"node_modules/.deno/html-comment-regex@1.1.2/node_modules/html-comment-regex/index.js"(e,t){t.exports=/<!--([\s\S]*?)-->/g}},function(){return t||(0,e[u(e)[0]])((t={exports:{}}).exports,t),t.exports}),l=function(e){if(null==e)return p;if("string"==typeof e)return function(e){return a(t);function t(t){return t&&t.type===e}}(e);if("object"==typeof e)return Array.isArray(e)?function(e){const t=[];let n=-1;for(;++n<e.length;)t[n]=l(e[n]);return a(r);function r(...e){let n=-1;for(;++n<t.length;)if(t[n].call(this,...e))return!0;return!1}}(e):function(e){return a(t);function t(t){let n;for(n in e)if(t[n]!==e[n])return!1;return!0}}(e);if("function"==typeof e)return a(e);throw new Error("Expected function, string, or object as test")};function a(e){return function(t,...n){return Boolean(t&&"object"==typeof t&&"type"in t&&Boolean(e.call(this,t,...n)))}}function p(){return!0}var s=!0,y=!1,d="skip",m=function(e,t,n,r){"function"==typeof t&&"function"!=typeof n&&(r=n,n=t,t=null);const o=l(t),u=r?-1:1;!function e(f,i,c){const l=f&&"object"==typeof f?f:{};if("string"==typeof l.type){const e="string"==typeof l.tagName?l.tagName:"string"==typeof l.name?l.name:void 0;Object.defineProperty(a,"name",{value:"node ("+f.type+(e?"<"+e+">":"")+")"})}return a;function a(){let l,a,p,m=[];if((!t||o(f,i,c[c.length-1]||null))&&(m=function(e){if(Array.isArray(e))return e;if("number"==typeof e)return[s,e];return[e]}(n(f,c)),m[0]===y))return m;if(f.children&&m[0]!==d)for(a=(r?f.children.length:-1)+u,p=c.concat(f);a>-1&&a<f.children.length;){if(l=e(f.children[a],a,p)(),l[0]===y)return l;a="number"==typeof l[1]?l[1]:a+u}return m}}(e,void 0,[])()};var g=function(e,t,n,r){"function"==typeof t&&"function"!=typeof n&&(r=n,n=t,t=null),m(e,t,(function(e,t){const r=t[t.length-1];return n(e,r?r.children.indexOf(e):null,r)}),r)},h=((e,t,c)=>(c=null!=e?n(f(e)):{},((e,t,n,f)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of u(t))i.call(e,c)||c===n||r(e,c,{get:()=>t[c],enumerable:!(f=o(t,c))||f.enumerable});return e})(!t&&e&&e.__esModule?c:r(c,"default",{value:e,enumerable:!0}),e)))(c(),1),b=(e,t)=>{const n=(e,t,n)=>{if(e.value.match(h.default))return n.children.splice(t,1),[d,t]};g(e,"html",n),g(e,"jsx",n)};var j=function(){return b},O={remark:e=>e.use(j)};export{O as default};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Imports
|
|
2
|
+
import type { Plugin } from "../renderer.ts"
|
|
3
|
+
import remarkRemoveComments from "remark-remove-comments"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Remove HTML comments.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```md
|
|
10
|
+
* <!-- foo -->
|
|
11
|
+
* ```
|
|
12
|
+
* ```html
|
|
13
|
+
* <p></p>
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export default {
|
|
17
|
+
remark(processor) {
|
|
18
|
+
return processor.use(remarkRemoveComments)
|
|
19
|
+
},
|
|
20
|
+
} as Plugin
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { expect, test } from "@libs/testing"
|
|
2
|
+
import { Renderer } from "../renderer.ts"
|
|
3
|
+
import plugin from "./uncomments.ts"
|
|
4
|
+
|
|
5
|
+
test("deno")("Plugin.uncomments renders without any comments", async () => {
|
|
6
|
+
const markdown = new Renderer({ plugins: [plugin] })
|
|
7
|
+
await expect(markdown.render("foo<!-- baz -->bar")).resolves.toMatch(/foobar/)
|
|
8
|
+
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e={d:(r,t)=>{for(var i in t)e.o(t,i)&&!e.o(r,i)&&Object.defineProperty(r,i,{enumerable:!0,get:t[i]})},o:(e,r)=>Object.prototype.hasOwnProperty.call(e,r)},r={};e.d(r,{Z:()=>p,$:()=>k});var t={horizontalTab:-2,virtualSpace:-1,nul:0,eof:null,space:32};function i(e){return e<t.nul||e===t.space}function n(e){return e<t.horizontalTab}var a={553:e=>{e.exports=function(e){var r,t;return e._compiled||(r=e.before?"(?:"+e.before+")":"",t=e.after?"(?:"+e.after+")":"",e.atBreak&&(r="[\\r\\n][\\t ]*"+r),e._compiled=new RegExp((r?"("+r+")":"")+(/[|\\{}()[\]^$+*?.-]/.test(e.character)?"\\":"")+e.character+(t||""),"g")),e._compiled}},112:e=>{function r(e,r,t){var i;if(!r)return t;for("string"==typeof r&&(r=[r]),i=-1;++i<r.length;)if(-1!==e.indexOf(r[i]))return!0;return!1}e.exports=function(e,t){return r(e,t.inConstruct,!0)&&!r(e,t.notInConstruct)}},113:(e,r,t)=>{e.exports=function(e,r,t){for(var s,l,u,c,f,k,p,h,d=(t.before||"")+(r||"")+(t.after||""),x=[],w=[],v={},g=-1;++g<e.unsafe.length;)if(c=e.unsafe[g],n(e.stack,c))for(f=i(c);k=f.exec(d);)s="before"in c||c.atBreak,l="after"in c,u=k.index+(s?k[1].length:0),-1===x.indexOf(u)?(x.push(u),v[u]={before:s,after:l}):(v[u].before&&!s&&(v[u].before=!1),v[u].after&&!l&&(v[u].after=!1));for(x.sort(a),p=t.before?t.before.length:0,h=d.length-(t.after?t.after.length:0),g=-1;++g<x.length;)(u=x[g])<p||u>=h||u+1<h&&x[g+1]===u+1&&v[u].after&&!v[u+1].before&&!v[u+1].after||(p!==u&&w.push(o(d.slice(p,u),"\\")),p=u,!/[!-/:-@[-`{-~]/.test(d.charAt(u))||t.encode&&-1!==t.encode.indexOf(d.charAt(u))?(w.push("&#x"+d.charCodeAt(u).toString(16).toUpperCase()+";"),p++):w.push("\\"));return w.push(o(d.slice(p,h),t.after)),w.join("")};var i=t(553),n=t(112);function a(e,r){return e-r}function o(e,r){for(var t,i=/\\(?=[!-/:-@[-`{-~])/g,n=[],a=[],o=-1,s=0,l=e+r;t=i.exec(l);)n.push(t.index);for(;++o<n.length;)s!==n[o]&&a.push(e.slice(s,n[o])),a.push("\\"),s=n[o];return a.push(e.slice(s)),a.join("")}}},o={};function s(e){var r=o[e];if(void 0!==r)return r.exports;var t=o[e]={exports:{}};return a[e](t,t.exports,s),t.exports}s.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return s.d(r,{a:r}),r},s.d=(e,r)=>{for(var t in r)s.o(r,t)&&!s.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},s.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r);var l={};(()=>{function e(e={}){const r=e.permalinks||[],t=e.pageResolver||(e=>[e.replace(/ /g,"_").toLowerCase()]),i=e.newClassName||"new",n=e.wikiLinkClassName||"internal",a=e.hrefTemplate||(e=>`#/page/${e}`);let o;function s(e){return e[e.length-1]}return{enter:{wikiLink:function(e){o={type:"wikiLink",value:null,data:{alias:null,permalink:null,exists:null}},this.enter(o,e)}},exit:{wikiLinkTarget:function(e){const r=this.sliceSerialize(e);s(this.stack).value=r},wikiLinkAlias:function(e){const r=this.sliceSerialize(e);s(this.stack).data.alias=r},wikiLink:function(e){this.exit(e);const s=o,l=t(s.value),u=l.find((e=>-1!==r.indexOf(e))),c=void 0!==u;let f;f=c?u:l[0]||"";let k=s.value;s.data.alias&&(k=s.data.alias);let p=n;c||(p+=" "+i),s.data.alias=k,s.data.permalink=f,s.data.exists=c,s.data.hName="a",s.data.hProperties={className:p,href:a(f)},s.data.hChildren=[{type:"text",value:k}]}}}}s.d(l,{V:()=>e,x:()=>i});var r=s(113),t=s.n(r);function i(e={}){const r=e.aliasDivider||":";return{unsafe:[{character:"[",inConstruct:["phrasing","label","reference"]},{character:"]",inConstruct:["label","reference"]}],handlers:{wikiLink:function(e,i,n){const a=n.enter("wikiLink"),o=t()(n,e.value,{before:"[",after:"]"}),s=t()(n,e.data.alias,{before:"[",after:"]"});let l;return l=s!==o?`[[${o}${r}${s}]]`:`[[${o}]]`,a(),l}}}}})();var u=l.V,c=l.x,f=!1;function k(e={}){const r=this.data();function a(e,t){r[e]?r[e].push(t):r[e]=[t]}!f&&(this.Parser&&this.Parser.prototype&&this.Parser.prototype.blockTokenizers||this.Compiler&&this.Compiler.prototype&&this.Compiler.prototype.visitors)&&(f=!0,console.warn("[remark-wiki-link] Warning: please upgrade to remark 13 to use this plugin")),a("micromarkExtensions",function(){var e=(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}).aliasDivider||":",r="]]";return{text:{91:{tokenize:function(a,o,s){var l,u,c=0,f=0,k=0;return function(e){return e!=="[[".charCodeAt(f)?s(e):(a.enter("wikiLink"),a.enter("wikiLinkMarker"),p(e))};function p(e){return 2===f?(a.exit("wikiLinkMarker"),n(r=e)||r===t.eof?s(r):(a.enter("wikiLinkData"),a.enter("wikiLinkTarget"),h(r))):e!=="[[".charCodeAt(f)?s(e):(a.consume(e),f++,p);var r}function h(o){return o===e.charCodeAt(c)?l?(a.exit("wikiLinkTarget"),a.enter("wikiLinkAliasMarker"),d(o)):s(o):o===r.charCodeAt(k)?l?(a.exit("wikiLinkTarget"),a.exit("wikiLinkData"),a.enter("wikiLinkMarker"),w(o)):s(o):n(o)||o===t.eof?s(o):(i(o)||(l=!0),a.consume(o),h)}function d(r){return c===e.length?(a.exit("wikiLinkAliasMarker"),a.enter("wikiLinkAlias"),x(r)):r!==e.charCodeAt(c)?s(r):(a.consume(r),c++,d)}function x(e){return e===r.charCodeAt(k)?u?(a.exit("wikiLinkAlias"),a.exit("wikiLinkData"),a.enter("wikiLinkMarker"),w(e)):s(e):n(e)||e===t.eof?s(e):(i(e)||(u=!0),a.consume(e),x)}function w(e){return 2===k?(a.exit("wikiLinkMarker"),a.exit("wikiLink"),o(e)):e!==r.charCodeAt(k)?s(e):(a.consume(e),k++,w)}}}}}}(e)),a("fromMarkdownExtensions",u(e)),a("toMarkdownExtensions",c(e))}var p=k,h=r.Z,d=x();function x({slugify:e=e=>{return[(r=e,r.trim().normalize("NFD").replaceAll(/[^a-zA-Z0-9\s-]/g,"").replaceAll(/\s+|-+/g,"-").replaceAll(/^-+|-+$/g,"").toLowerCase())];var r},resolve:r=e=>`/pages/${e}`,existing:t}={}){return{rehype:i=>i.use(h,{pageResolver:e,hrefTemplate:r,permalinks:t,wikiLinkClassName:"wikilink"})}}export{x as create,d as default};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Imports
|
|
2
|
+
import type { Plugin } from "../renderer.ts"
|
|
3
|
+
import { slugify as slug } from "@std/text/slugify"
|
|
4
|
+
import remarkWikilinks from "remark-wiki-link"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Add support for wiki links.
|
|
8
|
+
*
|
|
9
|
+
* Use the `existing` option to provide a list of existing permalinks.
|
|
10
|
+
* Any link not present in the list will posses the `new` class.
|
|
11
|
+
*
|
|
12
|
+
* Use the `slugify` option to indicate which possible slugs are possible for a given reference.
|
|
13
|
+
* All generated slugs are automatically added to the list of existing permalinks if at least one them is present.
|
|
14
|
+
*
|
|
15
|
+
* Use the `resolve` option to indicate how to resolve a link to a URL.
|
|
16
|
+
*
|
|
17
|
+
* All links generated by this plugin will have the `wikilink` class.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```md
|
|
21
|
+
* [[foo]]
|
|
22
|
+
* ```
|
|
23
|
+
* ```html
|
|
24
|
+
* <a href="/pages/foo" class="wikilink">foo</a>
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export default create() as Plugin
|
|
28
|
+
|
|
29
|
+
/** Create a new wiki links plugin. */
|
|
30
|
+
export function create({
|
|
31
|
+
slugify = (name) => [slug(name)],
|
|
32
|
+
resolve = (link) => `/pages/${link}`,
|
|
33
|
+
existing,
|
|
34
|
+
} = {} as { slugify?: (name: string) => string[]; resolve?: (link: string) => string; existing?: string[] }): Plugin {
|
|
35
|
+
return {
|
|
36
|
+
rehype(processor) {
|
|
37
|
+
return processor.use(remarkWikilinks, { pageResolver: slugify, hrefTemplate: resolve, permalinks: existing, wikiLinkClassName: "wikilink" })
|
|
38
|
+
},
|
|
39
|
+
} as Plugin
|
|
40
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { expect, test } from "@libs/testing"
|
|
2
|
+
import { Renderer } from "../renderer.ts"
|
|
3
|
+
import plugin, { create } from "./wikilinks.ts"
|
|
4
|
+
|
|
5
|
+
test("deno")("Plugin.wikilinks renders wiki links format", async () => {
|
|
6
|
+
const markdown = new Renderer({ plugins: [plugin] })
|
|
7
|
+
await expect(markdown.render("[[Foo Bar]]")).resolves.toMatch(/<a class=".*wikilink.*" href="\/pages\/foo-bar">Foo Bar<\/a>/)
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
test("deno")("Plugin.wikilinks exposes a way to create custom formatting", async () => {
|
|
11
|
+
const markdown = new Renderer({ plugins: [create({ existing: ["foo"] })] })
|
|
12
|
+
await expect(markdown.render("[[foo]]")).resolves.toMatch(/<a class="wikilink".*>foo<\/a>/)
|
|
13
|
+
await expect(markdown.render("[[bar]]")).resolves.toMatch(/<a class="wikilink new".*>bar<\/a>/)
|
|
14
|
+
})
|