@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.
@@ -1,15 +1,15 @@
1
- (function(u,d){typeof exports=="object"&&typeof module<"u"?d(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"],d):(u=typeof globalThis<"u"?globalThis:u||self,d(u.index={},u.node_fs,u.node_path,u.node_url,u.unified,u.remarkParse,u.unistUtilVisit,u.tsDedent))})(this,function(u,d,h,$e,ye,Ce,be,Ee){"use strict";var ht=Object.defineProperty;var gt=(u,d,h)=>d in u?ht(u,d,{enumerable:!0,configurable:!0,writable:!0,value:h}):u[d]=h;var _=(u,d,h)=>gt(u,typeof d!="symbol"?d+"":d,h);const $=(e,t)=>e.position.start.offset-t.position.start.offset;$.reverse=(e,t)=>$(t,e);const D=e=>e.position!==void 0&&e.position.start.offset!==void 0&&e.position.end.offset!==void 0,Se=ye.unified().use(Ce),L={md:e=>Se.parse(e)},j=(e,t)=>{const n=[];return be.visit(e,(s,r,i)=>{if(s.type!=="root"){if(t&&s.type!==t)return;if(D(s)){const o=((i==null?void 0:i.children.length)??0)-1;n.push({...s,siblingIndex:r,siblingCount:o})}}}),n},ke=e=>e.children.length===0,J=(e,t,...n)=>{if(n.length===0)throw new Error("No nodes to replace content from");n.sort($);const s=n.at(0),r=n.at(-1);return e.slice(0,s.position.start.offset)+t+e.slice(r.position.end.offset)},xe=(e,t,n)=>{const s=Math.min(t.position.end.offset,n.position.end.offset),r=Math.max(t.position.start.offset,n.position.start.offset);return e.slice(s,r)},A=(...e)=>e.join(" "),Ne=(...e)=>e.join(`
2
- `),Me=e=>{const t=e.split("?");return t.length>1?[t.slice(0,-1).join("?"),t.at(-1)]:[e,""]},Te=e=>Me(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
- `}},_e="-",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=_e)=>{const n=Y.static.reduce(ee,e);return Y.url.map(([s,r])=>[t+s+t,r]).reduce(ee,n).replaceAll(t," ")},je=["string","number","boolean"],Ae=e=>je.includes(e),Oe=/^([a-zA-Z0-9_-]+)(?:\(([^)]*)\))?$/,Ie=e=>{const t=e.match(Oe);if(!t)throw new Error(`Invalid invocation: ${e}`);const[,n,s=""]=t;if(!s.trim())return{name:n,parameters:[]};const r=Re(s);return{name:n,parameters:r}},qe=(e,t)=>{for(let n=t+1;n<e.length;n++)if(e[n]!==void 0)return!1;return!0},Re=e=>{const t=[];let n="",s=!1;for(let r=0;r<e.length;r++){const i=e[r],o=i==="'";if(o&&e.at(r+1)==="'"){const l=e.at(r+2)==="'";s=!s,n+=l?"'''":"''",r+=l?2:1}else o?(s=!s,n+=i):i===","&&!s?(t.push(n.trim()),n=""):n+=i}return t.push(n.trim()),t.map(r=>r===""?void 0:r?We(r):void 0).filter((r,i,o)=>r!==void 0||!qe(o,i))},We=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)},Pe=e=>{const t=/^([\w-_]+)(?:\(([^)]*)\))?/,n=e.match(t);if(!n)return{name:e};const[,s,r]=n;if(!r)return{name:s};const i=/([\w-_]+)(\?)?:\s*([^,]+)/g,o=[];let l;for(;(l=i.exec(r))!==null;){const[,c,a,m]=l,p=m.trim();if(!Ae(p))throw new Error(`Unsupported type: ${p}`);o.push({name:c,optional:a==="?",type:p})}return{name:s,parameters:o}},I=e=>{const t=e.map(Pe).reduce((n,{name:s,parameters:r})=>n.set(s,r),new Map);return n=>{const{name:s,parameters:r}=Ie(n);if(!t.has(s))throw new Error(`Unknown method: ${s}`);const i=t.get(s);if(i===void 0)return{name:s};if(r.length>i.length){const o=i.filter(({optional:c})=>!c).length,l=o===i.length?o.toString():`${o} - ${i.length}`;throw new Error(`Too many parameters: ${r.length} for method '${s}' (expected: ${l})`)}return i.reduce((o,{name:l,optional:c,type:a},m)=>{const p=r[m];if(p===void 0){if(c)return o;throw new Error(`Missing required parameter: ${l} for method '${s}'`)}switch(a){case"string":o[l]=p;break;case"number":case"boolean":o[l]=JSON.parse(p);break}if(typeof o[l]!==a)throw new Error(`Invalid type: ${l} must be ${a}, got ${typeof o[l]} for method '${s}'`);return o},{name:s})}},U=e=>Object.entries(e).filter(([t])=>t!=="name"&&!isNaN(Number(t))).map(([t,n])=>n),De=I(["code(lang?: string, meta?: string)","quote()","dropdown(summary: string, open?: boolean, space?: string)"]),E=(e,t=1)=>`
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 s=De(t);switch(s.name){case"code":if(!s.lang&&!s.meta&&(n==null?void 0:n.inline)&&!e.includes(`
6
- `))return`\`${e}\``;const i=s.lang??(n==null?void 0:n.extension)??"",o=s.meta?` ${s.meta}`:"";return E(`\`\`\`${i}${o}${E(e)}\`\`\``);case"quote":return n!=null&&n.inline&&!e.includes(`
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(s.summary),"summary");return E(B([l,e].join(`
9
- `),"details",s.open?"open":void 0))}};class w{constructor(...t){_(this,"_intervals",[]);_(this,"collapsed",!0);for(const[n,s]of t)this.push(n,s)}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,s]of t.intervals)this.push(n,s);return this}collapse(t=!1){const{_intervals:n,collapsed:s}=this;if(s&&!t||!n.length)return this;n.sort((l,c)=>l[0]-c[0]);const r=[];let[i,o]=n[0];for(let l=1;l<n.length;l++){const[c,a]=n[l];c<=o?o=Math.max(o,a):(r.push([i,o]),i=c,o=a)}return r.push([i,o]),this._intervals=r,this.collapsed=!0,this}subtract(t){this.collapse(),t.collapse();const{_intervals:n}=this,{_intervals:s}=t;if(!n.length||!s.length)return this;let r=[...n];for(const[i,o]of s){const l=[];for(const[c,a]of r){if(o<=c||i>=a){l.push([c,a]);continue}i>c&&l.push([c,i]),o<a&&l.push([o,a])}r=l}return this._intervals=r,this.collapse(!0),this}test(t,n="head"){const{_intervals:s}=this;switch(n){case"head":return s.some(([r,i])=>t>=r&&t<i);case"tail":return s.some(([r,i])=>t>r&&t<=i);case"both":return s.some(([r,i])=>t>=r&&t<=i);case"none":return s.some(([r,i])=>t>r&&t<i)}}slice(t){this.collapse();const n=[];for(const[s,r]of this._intervals)n.push(t.slice(s,r));return n.filter(Boolean).join("")}offset(t){for(const n of this._intervals)n[0]+=t,n[1]+=t;return this}}const q=e=>{const t=/(\/\/[^\n]*|\/\*[\s\S]*?\*\/|<!--[\s\S]*?-->)/gm,n=[];let s;for(;(s=t.exec(e))!==null;){const r=[s.index,s.index+s[0].length],i=Le(s[0]).trim();n.push({range:r,value:i})}return n},Le=e=>e.startsWith("//")?e.slice(2):e.startsWith("/*")?e.slice(2,-2):e.startsWith("<!--")?e.slice(4,-3):e,Ue=["(pd)","(p↓)","(parkdown)","pd:","p↓:","parkdown:"],ne=(e,t)=>e.range[0]-t.range[0],F=(e,t,n)=>(n??q(e)).filter(({value:s})=>s.split(" ").includes(t)).sort(ne),se=e=>({isSpace:e===" ",isNewline:e===`
10
- `||e===void 0}),re=e=>Ue.flatMap(t=>F(e,t)).sort((t,n)=>t.range[0]-n.range[0]).reverse().reduce((t,{range:[n,s],value:r})=>{const i=(S,k)=>t.slice(0,S)+t.slice(k),o=se(t[n-1]),l=se(t[s]),c=s===t.length;let a=n;for(;a>0&&t[a-1]!==`
11
- `;)a--;let m=s;for(;m<t.length&&t[m]!==`
12
- `;)m++;const p=t.slice(a,n).trim()===""&&t.slice(s,m).trim()==="";return o.isNewline&&l.isNewline?i(n-(c?1:0),s+1):o.isNewline||p?i(a,s+(l.isSpace||l.isNewline?1:0)):i(n-(o.isSpace?1:0),s)},e),Be=I(["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()"]),C=(e,t,n)=>{const s=F(e,t,n),r=[];for(let i=0;i<s.length-1;i+=2)r.push([s[i],s[i+1]]);return r},Fe=(e,t,n)=>new w(...F(e,t,n).map(({range:s})=>s)),R=e=>Ee.dedent(e).trim(),ie=(e,t)=>e[t]!==void 0&&/[^\S\r\n]/.test(e[t]),oe=(e,t)=>Math.max(0,Math.min(e.length,t)),He=(e,...t)=>{if(t.length===0)return e;const n=q(e);return R(new w(...t.flatMap(s=>C(e,s,n).map(([{range:[r]},{range:[,i]}])=>{for(;ie(e,r);)r--;for(;ie(e,i);)i++;return[oe(e,r),oe(e,i)]}))).slice(e))},Qe=(e,...t)=>{if(t.length===0)return e;const n=q(e);return R(new w([0,e.length]).subtract(new w(...t.flatMap(s=>C(e,s,n).map(([{range:[,r]},{range:[i]}])=>[r,i])))).slice(e))},Ge=(e,t,n,s)=>{if(!t)return e;let r="",i=0;for(const[o,l]of C(e,t))r+=e.slice(i,o.range[1]),r+=O(n??o.value,s),i=l.range[0];return r+=e.slice(i),R(new w([0,r.length]).subtract(Fe(r,t)).slice(r))},ze=(e,t,n,s,r,i)=>{if(!t)return e;const o=!(s===void 0||s<0),l=r?O(r,i):"",c=s??0,a=q(e),m=new w(...a.map(({range:p})=>p));return C(e,t,a).map(p=>p[n==="start"?0:1]).sort(ne).reverse().reduce((p,{range:S})=>{const k=new w,P=o?1:-1;let M=Math.abs(c),g=o?S[1]:S[0];for(;M>0&&g<p.length&&g>=0;)m.test(g)||(k.push(g),M--),g+=P;return g=Math.min(Math.max(0,g),p.length),p=p.slice(0,g)+l+p.slice(g),new w([0,p.length]).subtract(k.offset(o?0:l.length)).slice(p)},e)},Ve=(e,t,n,s,r)=>{let i="",o=0;[n,s]=[n,s??""].map(c=>O(c,r));const l=t?C(e,t):[[{range:[0,0]},{range:[e.length,e.length]}]];for(const[c,a]of l)i+=e.slice(o,c.range[1]),i+=e.slice(c.range[1],a.range[0]).replaceAll(n,s),o=a.range[0];return i+=e.slice(o),i},Xe=(e,t)=>{if(!t)return e;let n="",s=0;for(const[r,i]of C(e,t))n+=e.slice(s,r.range[1]),n+=e.slice(r.range[1],i.range[0]).replaceAll(/[\s\n]+/g," "),s=i.range[0];return n+=e.slice(s),n},le=(e,t,n)=>{var i,o,l,c;if(!t)return e;const s=a=>/\s/.test(e[a]),r=new w;for(const[a,m]of C(e,t)){if((i=n.start)!=null&&i.left){let p=a.range[0]-1;for(;s(p);)r.push(p--)}if((o=n.start)!=null&&o.right){let p=a.range[1];for(;s(p);)r.push(p++)}if((l=n.end)!=null&&l.left){let p=m.range[0]-1;for(;s(p);)r.push(p--)}if((c=n.end)!=null&&c.right){let p=m.range[1];for(;s(p);)r.push(p++)}}return new w([0,e.length]).subtract(r).slice(e)},Je=(e,t,n)=>{if(!t)return re(e);const s=Be(t);switch(s.name){case"extract":e=He(e,s.id,...U(s));break;case"remove":e=Qe(e,s.id,...U(s));break;case"replace":e=Ge(e,s.id,s.with,s.space);break;case"splice-start":case"splice-end":{const{deleteCount:r,insert:i,space:o,id:l}=s,c=s.name==="splice-start"?"start":"end";e=ze(e,l,c,r,i,o);break}case"trim-start":case"trim-end":{s.left??(s.left=!0),s.right??(s.right=!0);const r=s.name==="trim-start"?"start":"end",{length:i}=e;e=le(e,s.id,{[r]:s}),console.log(`Trimmed ${i-e.length} characters from ${r} of "${s.id}" region`);break}case"trim":{const{inside:r,outside:i,id:o}=s,l={left:i??!0,right:r??!0},c={left:r??!0,right:i??!0},{length:a}=e;e=le(e,o,{start:l,end:c}),console.log(`Trimmed ${a-e.length} characters around "${s.id}" region`);break}case"single-line":e=Xe(e,s.id);break;case"remap":e=Ve(e,s.id,s.from,s.to,s.space);break}return s.name==="debug"&&console.log("debug!!!",s),e=n&&s.name!=="debug"?re(e):e,n?R(e):e},Ze=["recipe(id: string)"],Ke=["recipe(id: string, 0?: string, 1?: string, 2?: string)"],ae={register:I(Ze),apply:I(Ke)},N=class N{constructor(){_(this,"recipes",new Map)}tryStore(t){const n=N.Entries(this.apply(t));for(let s=0;s<n.length;s++){const[r,i]=n[s];if(r!=="register")continue;const o=ae.register(i);switch(o.name){case"recipe":const l=n.slice(s+1).filter(([c])=>c!=="register").map(([c,a])=>`${c}=${a}`).join("&");this.recipes.set(o.id,l);break;default:throw new Error(`Unknown registration: ${o.name}`)}}}apply(t){const n=N.Entries(t),s=[];for(let r=0;r<n.length;r++){const[i,o]=n[r];if(i!=="apply"){s.push(`${i}=${o}`);continue}const l=ae.apply(o);switch(l.name){case"recipe":s.push(this.recipes.get(l.id)),s.push(...U(l).map(c=>this.recipes.get(c)));break;default:throw new Error(`Unknown registration: ${l.name}`)}}return s.join("&")}};_(N,"Entries",t=>Array.from(new URLSearchParams(t).entries()));let H=N;const Ye=["http","./","../","?"],et=({url:e})=>Ye.some(t=>e.startsWith(t)),tt=e=>D(e)&&ke(e)&&et(e),ce=({url:e},t)=>`[](${t?h.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)}},pe=e=>t=>D(t)&&t.value===f[e],nt=({position:e,url:t,siblingCount:n},s)=>({position:e,url:t,headingDepth:s,inline:n>=1}),st=({position:{start:e},url:t,siblingCount:n},{position:{end:s}},r)=>({position:{start:e,end:s},url:t,headingDepth:r,inline:n>=1}),rt=(e,t,n)=>(e.inline?A:Ne)(ce(e,n),f.begin,f.lengthOf(t),t,f.end),it=e=>{const t=j(e,"heading").reduce((n,{position:s,depth:r})=>n.set(s.start.line,r),new Map);return n=>{for(let s=n.position.start.line;s>=1;s--){const r=t.get(s);if(r)return r}return 0}},W={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`)},ot=(e,t)=>{const n=[],s=[...e.map(i=>({node:i,type:"open"})),...t.map(i=>({node:i,type:"close"}))].sort((i,o)=>$(i.node,o.node)),r=[];for(const i of s)if(i.type==="open")r.push(i);else{const o=i.node;if(r.length===0)throw W.closingCommentNotMatchedToOpening(o);const l=r.pop().node;if(r.length>0)continue;n.push({open:l,close:o})}if(r.length>0)throw W.openingCommentNotClosed(r[0].node);return n},lt=(e,t,n)=>{const s=[...t].sort($),r=[];return[...n].sort((i,o)=>$.reverse(i.open,o.open)).forEach(i=>{for(;s.length>0;){const o=s.pop();if(o.position.start.offset<i.open.position.start.offset){if(xe(e,o,i.open).trim()!=="")throw W.openingCommentDoesNotFollowLink(i.open);return r.push([o,i])}r.push(o)}throw W.openingCommentDoesNotFollowLink(i.open)}),r.push(...s.reverse()),r.reverse()},ue=(e,t)=>{t??(t=L.md(e));const n=it(t),s=j(t,"link").filter(tt),r=j(t,"html").sort($),i=r.filter(pe("begin")),o=r.filter(pe("end")),l=ot(i,o);return lt(e,s,l).map(a=>Array.isArray(a)?st(a[0],a[1].close,n(a[0])):nt(a,n(a)))},at=(e,{url:t})=>n=>e(h.join(h.dirname(t),n)),me=(...e)=>{const t=e.reduce((n,s)=>n+s,0);return Math.min(Math.max(t,1),6)},ct=(e,t,n)=>{if(t===0)return e;n??(n=L.md(e));const s=j(n,"heading"),r=e.split(`
14
- `);for(const i of s){const{depth:o,position:{start:l,end:c}}=i,a=me(o,t),m=r[l.line-1].slice(o,c.column),p="#".repeat(a)+m;r[l.line-1]=p,i.depth=a}return r.join(`
15
- `)},de=e=>ue(e).reverse().sort($.reverse).reduce((t,n)=>J(t,ce(n),n),e),he=(e,t,n,s,r)=>{try{e=de(e),e=ct(e,t);const i=L.md(e),o=new H,l=ue(e,i).sort($);return l.filter(({url:c})=>c.startsWith("?")).forEach(({url:c})=>o.tryStore(c)),l.reverse().map(c=>{var P,M;const{url:a,headingDepth:m}=c,[p,...S]=h.basename(a).split("?"),k=o.apply(S.join("?"));if(!a.startsWith("?"))if(a.startsWith("./")||a.startsWith("../")){const g=p.split(".").pop()??"",Q=h.dirname(a),we=h.join(Q,p);let v=n(we);const T=new $e.URLSearchParams(k),G=(P=(b=>{const y=Array.from(T.entries()).filter(([x])=>x===b).map(([x,X])=>X);return y.length>=1?y.join(","):void 0})("region"))==null?void 0:P.split(Z);v=(G==null?void 0:G.reduce((b,y,x,{length:X})=>Je(b,y,x===X-1),v))??v;const ut=T.has("skip"),mt=T.get("heading")??0,dt=T.has("inline");let{inline:z}=c;if(dt&&(z=!0),!ut)if(g==="md"){const b=at(n,c),y=r?h.join(r,Q):Q,x=me(m,Number(mt));v=he(v,x,b,we,y)}else/^(js|ts)x?|svelte$/i.test(g)&&(v=te(v,"code",{extension:g,inline:z}));const V=(M=T.get("wrap"))==null?void 0:M.split(Z);return v=(V==null?void 0:V.reduce((b,y)=>te(b,y,{extension:g,inline:z}),v))??v,{target:c,content:rt(c,v,r)}}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:m})=>J(c,m,a),e)}catch(i){throw new Error(`Error populating inclusions in file ${s??"(unknown)"}: ${i}`)}},ge=e=>d.readFileSync(e,"utf-8"),fe=e=>{const t=h.resolve(e),n=h.dirname(t);return{content:ge(t),dir:n,path:t}},ve=(e,t=!0,n)=>{const{dir:s,path:r,content:i}=fe(e);n==null||n.unwatch(r),n==null||n.once("change",(c,a)=>{console.log(`Change detected in "${c}". Regenerating "${r}"...`),ve(e,t,n)});const l=he(i,0,c=>{const a=h.resolve(s,Te(c));return n==null||n.add(a),ge(a)},r);return t&&d.writeFileSync(r,l),n==null||n.add(r),l},pt=(e,t=!0,n)=>{const{path:s,content:r}=fe(e),i=de(r);return t&&d.writeFileSync(s,i),i};u.depopulateMarkdownInclusions=pt,u.populateMarkdownInclusions=ve,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})});
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
- "name": "@p-buddy/parkdown",
3
- "type": "module",
4
- "private": false,
5
- "version": "0.0.28",
6
- "main": "./dist/index.js",
7
- "bin": "./dist/cli.js",
8
- "files": [
9
- "dist",
10
- "README.md",
11
- "LICENSE"
12
- ],
13
- "publishConfig": {
14
- "access": "public"
15
- },
16
- "devDependencies": {
17
- "@types/node": "^22.13.10",
18
- "@types/unist": "^3.0.3",
19
- "typescript": "^5.8.2",
20
- "vite": "^6.2.1",
21
- "vite-plugin-dts": "^4.5.3",
22
- "vite-plugin-externalize-deps": "^0.9.0",
23
- "vitest": "^3.0.8"
24
- },
25
- "dependencies": {
26
- "@commander-js/extra-typings": "^13.1.0",
27
- "chokidar": "^4.0.3",
28
- "remark-parse": "^11.0.0",
29
- "ts-dedent": "^2.2.0",
30
- "unified": "^11.0.5",
31
- "unist-util-visit": "^5.0.0"
32
- },
33
- "scripts": {
34
- "auto:commit:tracked": "git add -u && (git diff-index --quiet HEAD -- || git commit -m \"Automated commit.\")",
35
- "build:lib": "vite build",
36
- "build:cli": "vite build --config vite.cli.config.ts",
37
- "build": "pnpm run build:lib && pnpm run build:cli",
38
- "test": "vitest",
39
- "test:run": "vitest run",
40
- "cli": "npx tsx src/cli.ts",
41
- "doc:commit": "pnpm cli && pnpm auto:commit:tracked"
42
- },
43
- "typings": "./dist/index.d.ts",
44
- "exports": {
45
- ".": {
46
- "types": "./dist/index.d.ts",
47
- "import": "./dist/index.js",
48
- "require": "./dist/index.umd.cjs"
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
+ };