@p-buddy/parkdown 0.0.28 → 0.0.32
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 +63 -33
- package/dist/cli.js +1 -1
- package/dist/index.js +497 -333
- package/dist/index.umd.cjs +13 -13
- package/package.json +53 -50
- package/src/cli.ts +33 -0
- package/src/index.ts +45 -0
package/dist/index.umd.cjs
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
(function(
|
|
2
|
-
`),
|
|
3
|
-
`}},
|
|
1
|
+
(function(d,m){typeof exports=="object"&&typeof module<"u"?m(exports,require("node:fs"),require("node:path"),require("node:url"),require("unified"),require("remark-parse"),require("unist-util-visit"),require("ts-dedent")):typeof define=="function"&&define.amd?define(["exports","node:fs","node:path","node:url","unified","remark-parse","unist-util-visit","ts-dedent"],m):(d=typeof globalThis<"u"?globalThis:d||self,m(d.index={},d.node_fs,d.node_path,d.node_url,d.unified,d.remarkParse,d.unistUtilVisit,d.tsDedent))})(this,(function(d,m,g,be,Ce,Ee,Se,ke){"use strict";var ht=Object.defineProperty;var ft=(d,m,g)=>m in d?ht(d,m,{enumerable:!0,configurable:!0,writable:!0,value:g}):d[m]=g;var _=(d,m,g)=>ft(d,typeof m!="symbol"?m+"":m,g);const w=(e,t)=>e.position.start.offset-t.position.start.offset;w.reverse=(e,t)=>w(t,e);const L=e=>e.position!==void 0&&e.position.start.offset!==void 0&&e.position.end.offset!==void 0,xe=Ce.unified().use(Ee),U={md:e=>xe.parse(e)},j=(e,t)=>{const n=[];return Se.visit(e,(i,s,o)=>{if(i.type!=="root"){if(t&&i.type!==t)return;if(L(i)){const r=((o==null?void 0:o.children.length)??0)-1;n.push({...i,siblingIndex:s,siblingCount:r})}}}),n},Ne=e=>e.children.length===0,J=(e,t,...n)=>{if(n.length===0)throw new Error("No nodes to replace content from");n.sort(w);const i=n.at(0),s=n.at(-1);return e.slice(0,i.position.start.offset)+t+e.slice(s.position.end.offset)},Me=(e,t,n)=>{const i=Math.min(t.position.end.offset,n.position.end.offset),s=Math.max(t.position.start.offset,n.position.start.offset);return e.slice(i,s)},A=(...e)=>e.join(" "),Te=(...e)=>e.join(`
|
|
2
|
+
`),_e=e=>{const t=e.split("?");return t.length>1?[t.slice(0,-1).join("?"),t.at(-1)]:[e,""]},je=e=>_e(e)[0],Z=/,\s*(?![^()]*\))/,K={reserved:{semi:";",slash:"/",question:"?",colon:":",at:"@",equal:"=",and:"&"},unsafe:{quote:'"',angle:"<",unangle:">",hash:"#",percent:"%",curly:"{",uncurly:"}",pipe:"|",back:"\\",carrot:"^",tilde:"~",square:"[",unsquare:"]",tick:"`",line:`
|
|
3
|
+
`}},Ae="-",Y={static:[["'''",'"'],["''","'"],[/parkdown:\s+/g,""],[/p↓:\s+/g,""]],url:[...Object.entries(K.unsafe),...Object.entries(K.reserved)]},ee=(e,[t,n])=>e.replaceAll(t,n),O=(e,t=Ae)=>{const n=Y.static.reduce(ee,e);return Y.url.map(([i,s])=>[t+i+t,s]).reduce(ee,n).replaceAll(t," ")},Oe=["string","number","boolean"],Ie=e=>Oe.includes(e),qe=/^([a-zA-Z0-9_-]+)(?:\(([^)]*)\))?$/,Re=e=>{const t=e.match(qe);if(!t)throw new Error(`Invalid invocation: ${e}`);const[,n,i=""]=t;if(!i.trim())return{name:n,parameters:[]};const s=Pe(i);return{name:n,parameters:s}},We=(e,t)=>{for(let n=t+1;n<e.length;n++)if(e[n]!==void 0)return!1;return!0},Pe=e=>{const t=[];let n="",i=!1;for(let s=0;s<e.length;s++){const o=e[s],r=o==="'";if(r&&e.at(s+1)==="'"){const l=e.at(s+2)==="'";i=!i,n+=l?"'''":"''",s+=l?2:1}else r?(i=!i,n+=o):o===","&&!i?(t.push(n.trim()),n=""):n+=o}return t.push(n.trim()),t.map(s=>s===""?void 0:s?De(s):void 0).filter((s,o,r)=>s!==void 0||!We(r,o))},De=e=>{const t=e.length>=2&&e[0]==="'"&&e.at(-1)==="'",n=t&&e.length>=4&&e[1]==="'"&&e.at(-2)==="'";return!t||n?e:e.slice(1,-1)},Le=e=>{const t=/^([\w-_]+)(?:\(([^)]*)\))?/,n=e.match(t);if(!n)return{name:e};const[,i,s]=n;if(!s)return{name:i};const o=/([\w-_]+)(\?)?:\s*([^,]+)/g,r=[];let l;for(;(l=o.exec(s))!==null;){const[,c,a,u]=l,p=u.trim();if(!Ie(p))throw new Error(`Unsupported type: ${p}`);r.push({name:c,optional:a==="?",type:p})}return{name:i,parameters:r}},I=e=>{const t=e.map(Le).reduce((n,{name:i,parameters:s})=>n.set(i,s),new Map);return n=>{const{name:i,parameters:s}=Re(n);if(!t.has(i))throw new Error(`Unknown method: ${i}`);const o=t.get(i);if(o===void 0)return{name:i};if(s.length>o.length){const r=o.filter(({optional:c})=>!c).length,l=r===o.length?r.toString():`${r} - ${o.length}`;throw new Error(`Too many parameters: ${s.length} for method '${i}' (expected: ${l})`)}return o.reduce((r,{name:l,optional:c,type:a},u)=>{const p=s[u];if(p===void 0){if(c)return r;throw new Error(`Missing required parameter: ${l} for method '${i}'`)}switch(a){case"string":r[l]=p;break;case"number":case"boolean":r[l]=JSON.parse(p);break}if(typeof r[l]!==a)throw new Error(`Invalid type: ${l} must be ${a}, got ${typeof r[l]} for method '${i}'`);return r},{name:i})}},q=e=>Object.entries(e).filter(([t])=>t!=="name"&&!isNaN(Number(t))).map(([t,n])=>n),Ue=I(["code(lang?: string, meta?: string)","quote()","dropdown(summary: string, open?: boolean, space?: string)"]),E=(e,t=1)=>`
|
|
4
4
|
`.repeat(t)+e+`
|
|
5
|
-
`.repeat(t),B=(e,t,n)=>`<${t}${n?` ${n}`:""}>${E(e)}</${t}>`,te=(e,t,n)=>{const
|
|
6
|
-
`))return`\`${e}\``;const i
|
|
5
|
+
`.repeat(t),B=(e,t,n)=>`<${t}${n?` ${n}`:""}>${E(e)}</${t}>`,te=(e,t,n)=>{const i=Ue(t);switch(i.name){case"code":if(!i.lang&&!i.meta&&(n==null?void 0:n.inline)&&!e.includes(`
|
|
6
|
+
`))return`\`${e}\``;const o=i.lang??(n==null?void 0:n.extension)??"",r=i.meta?` ${i.meta}`:"";return E(`\`\`\`${o}${r}${E(e)}\`\`\``);case"quote":return n!=null&&n.inline&&!e.includes(`
|
|
7
7
|
|
|
8
|
-
`)?`> ${e}`:E(B(E(e),"blockquote"));case"dropdown":const l=B(O(
|
|
9
|
-
`),"details",
|
|
10
|
-
`||e===void 0}),
|
|
11
|
-
`;)a--;let
|
|
12
|
-
`;)
|
|
13
|
-
`).length}`,n=`chars: ${e.length}`;return A(f._open,f._flag,"length",t,n,f._close)}},
|
|
14
|
-
`);for(const
|
|
15
|
-
`)},
|
|
8
|
+
`)?`> ${e}`:E(B(E(e),"blockquote"));case"dropdown":const l=B(O(i.summary),"summary");return E(B([l,e].join(`
|
|
9
|
+
`),"details",i.open?"open":void 0))}};class v{constructor(...t){_(this,"_intervals",[]);_(this,"collapsed",!0);for(const[n,i]of t)this.push(n,i)}get intervals(){return this._intervals}push(t,n){return n??(n=t+1),this._intervals.push([Math.min(t,n),Math.max(t,n)]),this.collapsed=!1,this}combine(t){for(const[n,i]of t.intervals)this.push(n,i);return this}collapse(t=!1){const{_intervals:n,collapsed:i}=this;if(i&&!t||!n.length)return this;n.sort((l,c)=>l[0]-c[0]);const s=[];let[o,r]=n[0];for(let l=1;l<n.length;l++){const[c,a]=n[l];c<=r?r=Math.max(r,a):(s.push([o,r]),o=c,r=a)}return s.push([o,r]),this._intervals=s,this.collapsed=!0,this}subtract(t){this.collapse(),t.collapse();const{_intervals:n}=this,{_intervals:i}=t;if(!n.length||!i.length)return this;let s=[...n];for(const[o,r]of i){const l=[];for(const[c,a]of s){if(r<=c||o>=a){l.push([c,a]);continue}o>c&&l.push([c,o]),r<a&&l.push([r,a])}s=l}return this._intervals=s,this.collapse(!0),this}test(t,n="head"){const{_intervals:i}=this;switch(n){case"head":return i.some(([s,o])=>t>=s&&t<o);case"tail":return i.some(([s,o])=>t>s&&t<=o);case"both":return i.some(([s,o])=>t>=s&&t<=o);case"none":return i.some(([s,o])=>t>s&&t<o)}}slice(t){this.collapse();const n=[];for(const[i,s]of this._intervals)n.push(t.slice(i,s));return n.filter(Boolean).join("")}offset(t){for(const n of this._intervals)n[0]+=t,n[1]+=t;return this}}const R=e=>{const t=/(\/\/[^\n]*|\/\*[\s\S]*?\*\/|<!--[\s\S]*?-->)/gm,n=[];let i;for(;(i=t.exec(e))!==null;){const s=[i.index,i.index+i[0].length],o=Be(i[0]).trim();n.push({range:s,value:o})}return n},Be=e=>e.startsWith("//")?e.slice(2):e.startsWith("/*")?e.slice(2,-2):e.startsWith("<!--")?e.slice(4,-3):e,Fe=["(pd)","(p↓)","(parkdown)","pd:","p↓:","parkdown:"],ne=(e,t)=>e.range[0]-t.range[0],F=(e,t,n)=>(n??R(e)).filter(({value:i})=>i.split(" ").includes(t)).sort(ne),se=e=>({isSpace:e===" ",isNewline:e===`
|
|
10
|
+
`||e===void 0}),ie=e=>Fe.flatMap(t=>F(e,t)).sort((t,n)=>t.range[0]-n.range[0]).reverse().reduce((t,{range:[n,i],value:s})=>{const o=(S,k)=>t.slice(0,S)+t.slice(k),r=se(t[n-1]),l=se(t[i]),c=i===t.length;let a=n;for(;a>0&&t[a-1]!==`
|
|
11
|
+
`;)a--;let u=i;for(;u<t.length&&t[u]!==`
|
|
12
|
+
`;)u++;const p=t.slice(a,n).trim()===""&&t.slice(i,u).trim()==="";return r.isNewline&&l.isNewline?o(n-(c?1:0),i+1):r.isNewline||p?o(a,i+(l.isSpace||l.isNewline?1:0)):o(n-(r.isSpace?1:0),i)},e),He=I(["include(id: string, 0?: string, 1?: string, 2?: string, 3?: string, 4?: string, 5?: string, 6?: string, 7?: string, 8?: string, 9?: string, 10?: string)","extract(id: string, 0?: string, 1?: string, 2?: string)","remove(id: string, 0?: string, 1?: string, 2?: string)","replace(id: string, with?: string, space?: string)","remap(id?: string, from: string, to?: string, space?: string)","single-line(id: string, includeBoundaries?: boolean)","trim(id: string, inside?: boolean, outside?: boolean)","trim-start(id: string, left?: boolean, right?: boolean)","trim-end(id: string, left?: boolean, right?: boolean)","splice-start(id: string, deleteCount?: number, insert?: string, space?: string)","splice-end(id: string, deleteCount?: number, insert?: string, space?: string)","debug()"]),b=(e,t,n)=>{const i=F(e,t,n),s=[];for(let o=0;o<i.length-1;o+=2)s.push([i[o],i[o+1]]);return s},Qe=(e,t,n)=>new v(...F(e,t,n).map(({range:i})=>i)),W=e=>ke.dedent(e).trim(),oe=(e,t)=>e[t]!==void 0&&/[^\S\r\n]/.test(e[t]),re=(e,t)=>Math.max(0,Math.min(e.length,t)),le=(e,...t)=>{if(t.length===0)return e;const n=R(e);return W(new v(...t.flatMap(i=>b(e,i,n).map(([{range:[s]},{range:[,o]}])=>{for(;oe(e,s);)s--;for(;oe(e,o);)o++;return[re(e,s),re(e,o)]}))).slice(e))},Ge=(e,...t)=>{if(t.length===0)return e;const n=R(e);return W(new v([0,e.length]).subtract(new v(...t.flatMap(i=>b(e,i,n).map(([{range:[,s]},{range:[o]}])=>[s,o])))).slice(e))},ze=(e,t,n,i)=>{if(!t)return e;let s="",o=0;for(const[r,l]of b(e,t))s+=e.slice(o,r.range[1]),s+=O(n??r.value,i),o=l.range[0];return s+=e.slice(o),W(new v([0,s.length]).subtract(Qe(s,t)).slice(s))},Ve=(e,t,n,i,s,o)=>{if(!t)return e;const r=!(i===void 0||i<0),l=s?O(s,o):"",c=i??0,a=R(e),u=new v(...a.map(({range:p})=>p));return b(e,t,a).map(p=>p[n==="start"?0:1]).sort(ne).reverse().reduce((p,{range:S})=>{const k=new v,D=r?1:-1;let M=Math.abs(c),h=r?S[1]:S[0];for(;M>0&&h<p.length&&h>=0;)u.test(h)||(k.push(h),M--),h+=D;return h=Math.min(Math.max(0,h),p.length),p=p.slice(0,h)+l+p.slice(h),new v([0,p.length]).subtract(k.offset(r?0:l.length)).slice(p)},e)},Xe=(e,t,n,i,s)=>{let o="",r=0;[n,i]=[n,i??""].map(c=>O(c,s));const l=t?b(e,t):[[{range:[0,0]},{range:[e.length,e.length]}]];for(const[c,a]of l)o+=e.slice(r,c.range[1]),o+=e.slice(c.range[1],a.range[0]).replaceAll(n,i),r=a.range[0];return o+=e.slice(r),o},Je=(e,t)=>{if(!t)return e;let n="",i=0;for(const[s,o]of b(e,t))n+=e.slice(i,s.range[1]),n+=e.slice(s.range[1],o.range[0]).replaceAll(/[\s\n]+/g," "),i=o.range[0];return n+=e.slice(i),n},ae=(e,t,n)=>{var o,r,l,c;if(!t)return e;const i=a=>/\s/.test(e[a]),s=new v;for(const[a,u]of b(e,t)){if((o=n.start)!=null&&o.left){let p=a.range[0]-1;for(;i(p);)s.push(p--)}if((r=n.start)!=null&&r.right){let p=a.range[1];for(;i(p);)s.push(p++)}if((l=n.end)!=null&&l.left){let p=u.range[0]-1;for(;i(p);)s.push(p--)}if((c=n.end)!=null&&c.right){let p=u.range[1];for(;i(p);)s.push(p++)}}return new v([0,e.length]).subtract(s).slice(e)},Ze=(e,t,n,i)=>{if(!n)return ie(e);const s=He(n);switch(s.name){case"include":for(const o of[s.id,...q(s)])e+=le(t,o);break;case"extract":e=le(e||t,s.id,...q(s));break;case"remove":e=Ge(e,s.id,...q(s));break;case"replace":e=ze(e,s.id,s.with,s.space);break;case"splice-start":case"splice-end":{const{deleteCount:o,insert:r,space:l,id:c}=s,a=s.name==="splice-start"?"start":"end";e=Ve(e,c,a,o,r,l);break}case"trim-start":case"trim-end":{s.left??(s.left=!0),s.right??(s.right=!0);const o=s.name==="trim-start"?"start":"end",{length:r}=e;e=ae(e,s.id,{[o]:s}),console.log(`Trimmed ${r-e.length} characters from ${o} of "${s.id}" region`);break}case"trim":{const{inside:o,outside:r,id:l}=s,c={left:r??!0,right:o??!0},a={left:o??!0,right:r??!0},{length:u}=e;e=ae(e,l,{start:c,end:a}),console.log(`Trimmed ${u-e.length} characters around "${s.id}" region`);break}case"single-line":e=Je(e,s.id);break;case"remap":e=Xe(e,s.id,s.from,s.to,s.space);break}return s.name==="debug"&&console.log("debug!!!",s),e=i&&s.name!=="debug"?ie(e):e,i?W(e):e},Ke=["recipe(id: string)"],Ye=["recipe(id: string, 0?: string, 1?: string, 2?: string)"],ce={register:I(Ke),apply:I(Ye)},N=class N{constructor(){_(this,"recipes",new Map)}tryStore(t){const n=N.Entries(this.apply(t));for(let i=0;i<n.length;i++){const[s,o]=n[i];if(s!=="register")continue;const r=ce.register(o);switch(r.name){case"recipe":const l=n.slice(i+1).filter(([c])=>c!=="register").map(([c,a])=>`${c}=${a}`).join("&");this.recipes.set(r.id,l);break;default:throw new Error(`Unknown registration: ${r.name}`)}}}apply(t){const n=N.Entries(t),i=[];for(let s=0;s<n.length;s++){const[o,r]=n[s];if(o!=="apply"){i.push(`${o}=${r}`);continue}const l=ce.apply(r);switch(l.name){case"recipe":i.push(this.recipes.get(l.id)),i.push(...q(l).map(c=>this.recipes.get(c)));break;default:throw new Error(`Unknown registration: ${l.name}`)}}return i.join("&")}};_(N,"Entries",t=>Array.from(new URLSearchParams(t).entries()));let H=N;const et=["http","./","../","?"],tt=({url:e})=>et.some(t=>e.startsWith(t)),nt=e=>L(e)&&Ne(e)&&tt(e),pe=({url:e},t)=>`[](${t?g.join(t,e):e})`,f={_open:"<!--",_close:"-->",_flag:"p↓",get begin(){return A(f._open,f._flag,"BEGIN",f._close)},get end(){return A(f._open,f._flag,"END",f._close)},lengthOf(e){const t=`lines: ${e.split(`
|
|
13
|
+
`).length}`,n=`chars: ${e.length}`;return A(f._open,f._flag,"length",t,n,f._close)}},ue=e=>t=>L(t)&&t.value===f[e],st=({position:e,url:t,siblingCount:n},i)=>({position:e,url:t,headingDepth:i,inline:n>=1}),it=({position:{start:e},url:t,siblingCount:n},{position:{end:i}},s)=>({position:{start:e,end:i},url:t,headingDepth:s,inline:n>=1}),ot=(e,t,n)=>(e.inline?A:Te)(pe(e,n),f.begin,f.lengthOf(t),t,f.end),rt=e=>{const t=j(e,"heading").reduce((n,{position:i,depth:s})=>n.set(i.start.line,s),new Map);return n=>{for(let i=n.position.start.line;i>=1;i--){const s=t.get(i);if(s)return s}return 0}},P={openingCommentDoesNotFollowLink:({position:{start:e}})=>new Error(`Opening comment (@${e.line}:${e.column}) does not follow link`),closingCommentNotMatchedToOpening:({position:{start:e}})=>new Error(`Closing comment (@${e.line}:${e.column}) does not match to opening comment`),openingCommentNotClosed:({position:{start:e}})=>new Error(`Opening comment (@${e.line}:${e.column}) is not followed by a closing comment`)},lt=(e,t)=>{const n=[],i=[...e.map(o=>({node:o,type:"open"})),...t.map(o=>({node:o,type:"close"}))].sort((o,r)=>w(o.node,r.node)),s=[];for(const o of i)if(o.type==="open")s.push(o);else{const r=o.node;if(s.length===0)throw P.closingCommentNotMatchedToOpening(r);const l=s.pop().node;if(s.length>0)continue;n.push({open:l,close:r})}if(s.length>0)throw P.openingCommentNotClosed(s[0].node);return n},at=(e,t,n)=>{const i=[...t].sort(w),s=[];return[...n].sort((o,r)=>w.reverse(o.open,r.open)).forEach(o=>{for(;i.length>0;){const r=i.pop();if(r.position.start.offset<o.open.position.start.offset){if(Me(e,r,o.open).trim()!=="")throw P.openingCommentDoesNotFollowLink(o.open);return s.push([r,o])}s.push(r)}throw P.openingCommentDoesNotFollowLink(o.open)}),s.push(...i.reverse()),s.reverse()},de=(e,t)=>{t??(t=U.md(e));const n=rt(t),i=j(t,"link").filter(nt),s=j(t,"html").sort(w),o=s.filter(ue("begin")),r=s.filter(ue("end")),l=lt(o,r);return at(e,i,l).map(a=>Array.isArray(a)?it(a[0],a[1].close,n(a[0])):st(a,n(a)))},ct=(e,{url:t})=>(n=>e(g.join(g.dirname(t),n))),me=(...e)=>{const t=e.reduce((n,i)=>n+i,0);return Math.min(Math.max(t,1),6)},pt=(e,t,n)=>{if(t===0)return e;n??(n=U.md(e));const i=j(n,"heading"),s=e.split(`
|
|
14
|
+
`);for(const o of i){const{depth:r,position:{start:l,end:c}}=o,a=me(r,t),u=s[l.line-1].slice(r,c.column),p="#".repeat(a)+u;s[l.line-1]=p,o.depth=a}return s.join(`
|
|
15
|
+
`)},ge=e=>de(e).reverse().sort(w.reverse).reduce((t,n)=>J(t,pe(n),n),e),he=(e,t,n,i,s)=>{try{e=ge(e),e=pt(e,t);const o=U.md(e),r=new H,l=de(e,o).sort(w);return l.filter(({url:c})=>c.startsWith("?")).forEach(({url:c})=>r.tryStore(c)),l.reverse().map(c=>{var D,M;const{url:a,headingDepth:u}=c,[p,...S]=g.basename(a).split("?"),k=r.apply(S.join("?"));if(!a.startsWith("?"))if(a.startsWith("./")||a.startsWith("../")){const h=p.split(".").pop()??"",Q=g.dirname(a),$e=g.join(Q,p),ye=n($e),T=new be.URLSearchParams(k),G=(D=(C=>{const y=Array.from(T.entries()).filter(([x])=>x===C).map(([x,X])=>X);return y.length>=1?y.join(","):void 0})("region"))==null?void 0:D.split(Z);let $=(G==null?void 0:G.reduce((C,y,x,{length:X})=>Ze(C,ye,y,x===X-1),""))??ye;const dt=T.has("skip"),mt=T.get("heading")??0,gt=T.has("inline");let{inline:z}=c;if(gt&&(z=!0),!dt)if(h==="md"){const C=ct(n,c),y=s?g.join(s,Q):Q,x=me(u,Number(mt));$=he($,x,C,$e,y)}else/^(js|ts)x?|svelte$/i.test(h)&&($=te($,"code",{extension:h,inline:z}));const V=(M=T.get("wrap"))==null?void 0:M.split(Z);return $=(V==null?void 0:V.reduce((C,y)=>te(C,y,{extension:h,inline:z}),$))??$,{target:c,content:ot(c,$,s)}}else throw a.startsWith("http")?new Error("External web links are not implemented yet"):new Error(`Unsupported link type: ${a}`)}).filter(Boolean).reduce((c,{target:a,content:u})=>J(c,u,a),e)}catch(o){throw new Error(`Error populating inclusions in file ${i??"(unknown)"}: ${o}`)}},fe=e=>m.readFileSync(e,"utf-8"),ve=e=>{const t=g.resolve(e),n=g.dirname(t);return{content:fe(t),dir:n,path:t}},we=(e,t=!0,n)=>{const{dir:i,path:s,content:o}=ve(e);n==null||n.unwatch(s),n==null||n.once("change",(c,a)=>{console.log(`Change detected in "${c}". Regenerating "${s}"...`),we(e,t,n)});const l=he(o,0,c=>{const a=g.resolve(i,je(c));return n==null||n.add(a),fe(a)},s);return t&&m.writeFileSync(s,l),n==null||n.add(s),l},ut=(e,t=!0,n)=>{const{path:i,content:s}=ve(e),o=ge(s);return t&&m.writeFileSync(i,o),o};d.depopulateMarkdownInclusions=ut,d.populateMarkdownInclusions=we,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})}));
|
package/package.json
CHANGED
|
@@ -1,51 +1,54 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
2
|
+
"name": "@p-buddy/parkdown",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"private": false,
|
|
5
|
+
"version": "0.0.32",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"bin": "src/cli.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md",
|
|
11
|
+
"LICENSE"
|
|
12
|
+
],
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"typings": "./dist/index.d.ts",
|
|
16
|
+
"bin": "./dist/cli.js",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js",
|
|
21
|
+
"require": "./dist/index.umd.cjs"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"auto:commit:tracked": "git add -u && (git diff-index --quiet HEAD -- || git commit -m \"Automated commit.\")",
|
|
28
|
+
"build:lib": "vite build",
|
|
29
|
+
"build:cli": "vite build --config vite.cli.config.ts",
|
|
30
|
+
"build": "npm run build:lib && npm run build:cli",
|
|
31
|
+
"test": "vitest",
|
|
32
|
+
"test:run": "vitest run",
|
|
33
|
+
"cli": "npx tsx src/cli.ts",
|
|
34
|
+
"doc:commit": "npm run cli && npm run auto:commit:tracked",
|
|
35
|
+
"prepare": "npm run test:run && npm run doc:commit && npm run build && npm version patch && git push && npm run build:cli"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^22.13.10",
|
|
39
|
+
"@types/unist": "^3.0.3",
|
|
40
|
+
"typescript": "^5.8.2",
|
|
41
|
+
"vite": "^6.2.1",
|
|
42
|
+
"vite-plugin-dts": "^4.5.3",
|
|
43
|
+
"vite-plugin-externalize-deps": "^0.9.0",
|
|
44
|
+
"vitest": "^3.0.8"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@commander-js/extra-typings": "^13.1.0",
|
|
48
|
+
"chokidar": "^4.0.3",
|
|
49
|
+
"remark-parse": "^11.0.0",
|
|
50
|
+
"ts-dedent": "^2.2.0",
|
|
51
|
+
"unified": "^11.0.5",
|
|
52
|
+
"unist-util-visit": "^5.0.0"
|
|
53
|
+
}
|
|
54
|
+
}
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from '@commander-js/extra-typings';
|
|
3
|
+
import { version } from '../package.json';
|
|
4
|
+
import { populateMarkdownInclusions, depopulateMarkdownInclusions } from '.';
|
|
5
|
+
import chokidar from 'chokidar';
|
|
6
|
+
|
|
7
|
+
const program = new Command()
|
|
8
|
+
.version(version)
|
|
9
|
+
.option('--nw, --no-write', 'Do NOT write result to file (defaults to false)', false as boolean)
|
|
10
|
+
.option('--ni, --no-inclusions', 'Do NOT process file inclusions (defaults to false)', false as boolean)
|
|
11
|
+
.option('-d, --depopulate', 'Remove populated inclusions from the file', false as boolean)
|
|
12
|
+
.option('-f, --file <flag>', 'The file(s) to process', (value, arr) => (arr.push(value), arr), new Array<string>())
|
|
13
|
+
.option('-w, --watch', 'Watch the file(s) for changes and update automatically', false as boolean)
|
|
14
|
+
.parse();
|
|
15
|
+
|
|
16
|
+
const { inclusions: noInclusions, depopulate, file, write: noWrite, watch } = program.opts();
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
if (file.length === 0) file.push("README.md");
|
|
20
|
+
|
|
21
|
+
/** pd: process-order */
|
|
22
|
+
const processors = [
|
|
23
|
+
[populateMarkdownInclusions, !noInclusions],
|
|
24
|
+
[depopulateMarkdownInclusions, depopulate],
|
|
25
|
+
] as const;
|
|
26
|
+
/** pd: process-order */
|
|
27
|
+
|
|
28
|
+
for (const [processor] of processors.filter(([_, condition]) => condition))
|
|
29
|
+
for (const _file of file) {
|
|
30
|
+
const watcher = watch ? chokidar.watch([], { persistent: true, awaitWriteFinish: true, atomic: true }) : undefined;
|
|
31
|
+
const result = processor(_file, !noWrite, watcher);
|
|
32
|
+
if (noWrite) console.log(result);
|
|
33
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { recursivelyPopulateInclusions, removePopulatedInclusions } from "./include";
|
|
4
|
+
import { removeQueryParams } from "./utils";
|
|
5
|
+
import type chokidar from 'chokidar';
|
|
6
|
+
|
|
7
|
+
const read = (path: string) => readFileSync(path, "utf-8");
|
|
8
|
+
|
|
9
|
+
const tryResolveFile = (file: string) => {
|
|
10
|
+
const path = resolve(file);
|
|
11
|
+
const dir = dirname(path);
|
|
12
|
+
const content = read(path);
|
|
13
|
+
return { content, dir, path };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
type Watcher = ReturnType<typeof chokidar.watch>;
|
|
17
|
+
|
|
18
|
+
export const populateMarkdownInclusions = (file: string, writeFile = true, watcher?: Watcher) => {
|
|
19
|
+
const { dir, path, content } = tryResolveFile(file);
|
|
20
|
+
|
|
21
|
+
watcher?.unwatch(path);
|
|
22
|
+
|
|
23
|
+
watcher?.once("change", (change, stats) => {
|
|
24
|
+
console.log(`Change detected in "${change}". Regenerating "${path}"...`);
|
|
25
|
+
populateMarkdownInclusions(file, writeFile, watcher);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const getContent = (relative: string) => {
|
|
29
|
+
const resolved = resolve(dir, removeQueryParams(relative));
|
|
30
|
+
watcher?.add(resolved);
|
|
31
|
+
return read(resolved);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const result = recursivelyPopulateInclusions(content, 0, getContent, path);
|
|
35
|
+
if (writeFile) writeFileSync(path, result);
|
|
36
|
+
watcher?.add(path);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const depopulateMarkdownInclusions = (file: string, writeFile = true, watcher?: Watcher) => {
|
|
41
|
+
const { path, content } = tryResolveFile(file);
|
|
42
|
+
const result = removePopulatedInclusions(content);
|
|
43
|
+
if (writeFile) writeFileSync(path, result);
|
|
44
|
+
return result;
|
|
45
|
+
};
|