@pretextbook/remark-pretext 0.0.2 → 0.0.3
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/dist/index.cjs +6 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +796 -0
- package/dist/lib/context.d.ts +22 -0
- package/dist/lib/directive-factory.d.ts +24 -0
- package/dist/lib/directive-map.d.ts +64 -0
- package/dist/lib/directive-normalizer.d.ts +37 -0
- package/dist/lib/indentation-normalizer.d.ts +36 -0
- package/dist/lib/markdown-to-pretext.d.ts +19 -0
- package/dist/lib/math-parser.d.ts +31 -0
- package/dist/lib/mdast-to-ptxast.d.ts +13 -0
- package/dist/lib/remark-pretext.d.ts +11 -0
- package/index.cjs +1 -1
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/package.json +3 -3
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const R=require("unified"),j=require("remark-parse"),z=require("remark-directive"),W=require("unist-util-visit"),q={theorem:{type:"theorem",category:"theorem-like",requiresStatement:!0},lemma:{type:"lemma",category:"theorem-like",requiresStatement:!0},corollary:{type:"corollary",category:"theorem-like",requiresStatement:!0},proposition:{type:"proposition",category:"theorem-like",requiresStatement:!0},claim:{type:"claim",category:"theorem-like",requiresStatement:!0},fact:{type:"fact",category:"theorem-like",requiresStatement:!0},conjecture:{type:"conjecture",category:"theorem-like",requiresStatement:!0},axiom:{type:"axiom",category:"theorem-like",requiresStatement:!0},principle:{type:"principle",category:"theorem-like",requiresStatement:!0},hypothesis:{type:"hypothesis",category:"theorem-like",requiresStatement:!0},algorithm:{type:"algorithm",category:"theorem-like",requiresStatement:!0},definition:{type:"definition",category:"definition-like",requiresStatement:!0},notation:{type:"notation",category:"definition-like",requiresStatement:!0},remark:{type:"remark",category:"remark-like",requiresStatement:!1},note:{type:"note",category:"remark-like",requiresStatement:!1},observation:{type:"observation",category:"remark-like",requiresStatement:!1},warning:{type:"warning",category:"remark-like",requiresStatement:!1},insight:{type:"insight",category:"remark-like",requiresStatement:!1},assemblage:{type:"assemblage",category:"remark-like",requiresStatement:!1},example:{type:"example",category:"example-like",requiresStatement:!1},question:{type:"question",category:"example-like",requiresStatement:!1},problem:{type:"problem",category:"example-like",requiresStatement:!1},exercise:{type:"exercise",category:"example-like",requiresStatement:!0,hasNestedTasks:!0},activity:{type:"activity",category:"example-like",requiresStatement:!1},exploration:{type:"exploration",category:"example-like",requiresStatement:!1},investigation:{type:"investigation",category:"example-like",requiresStatement:!1},project:{type:"project",category:"example-like",requiresStatement:!0,hasNestedTasks:!0},task:{type:"task",category:"example-like",requiresStatement:!0,hasNestedTasks:!0},proof:{type:"proof",category:"proof-like",requiresStatement:!1},case:{type:"case",category:"proof-like",requiresStatement:!1},solution:{type:"solution",category:"solution-like",requiresStatement:!1},hint:{type:"hint",category:"solution-like",requiresStatement:!1},answer:{type:"answer",category:"solution-like",requiresStatement:!1}},re=q;function oe(e){return q[e.toLowerCase()]}const F=new Set(Object.entries(q).filter(([e,t])=>t.category==="proof-like"||t.category==="solution-like").map(([e])=>e));function v(e,t,n){return{type:"element",name:e,attributes:n??{},children:t}}function C(e){return e.type==="containerDirective"&&e.name==="task"}function se(e){return e.type==="containerDirective"&&F.has(e.name)}function S(e){const t=[];for(const n of e)n.name==="ul"||n.name==="ol"?t.length>0&&t[t.length-1]?.name==="p"?t[t.length-1].children.push(n):t.push(v("p",[n])):t.push(n);return t}function ie(e,t,n,r,o,s,i){const l=[];if(n&&l.push(n),e.hasNestedTasks){const c=r.findIndex(C);if(c!==-1){const a=[];for(let u=0;u<r.length;u++)C(r[u])&&a.push(u);const f=a[a.length-1],d=r.slice(0,c),m=r.slice(c).filter(C),k=[],g=[],N=[];for(let u=c;u<r.length;u++){const p=r[u];if(!C(p)){if(u<f){k.push(p);continue}if(se(p)){N.push(p);continue}g.push(p)}}if(k.length>0&&(o.messages??(o.messages=[])).push({type:"warning",reason:`Dropped ${k.length} non-task node(s) between task directives in ${e.type}.`,category:"dropped-content-between-tasks",position:k[0].position?.start}),d.length>0){const u=S(d.map(p=>s(p,o)).filter(p=>p!==null));u.length>0&&l.push(v("introduction",u))}for(const u of m){const p=i(u,o);p&&l.push(p)}if(g.length>0){const u=S(g.map(p=>s(p,o)).filter(p=>p!==null));u.length>0&&l.push(v("conclusion",u))}for(const u of N){const p=i(u,o);p&&l.push(p)}}else $(l,e,r,o,s,i)}else $(l,e,r,o,s,i);return v(e.type,l,t)}function $(e,t,n,r,o,s){if(t.requiresStatement){const i=[],l=[];for(const c of n)if(c.type==="containerDirective"&&F.has(c.name)){const a=s(c,r);a&&l.push(a)}else i.push(c);if(i.length>0){const c=S(i.map(a=>o(a,r)).filter(a=>a!==null));c.length>0&&e.push(v("statement",c))}e.push(...l)}else{const i=S(n.map(l=>o(l,r)).filter(l=>l!==null));e.push(...i)}}function B(e){return{type:"text",value:e}}function h(e,t,n){return{type:"element",name:e,attributes:n??{},children:t}}function x(e,t,n){return h(e,[B(t)],n)}function U(e){const t=[];for(const n of e)n.name==="ul"||n.name==="ol"?t.length>0&&t[t.length-1]?.name==="p"?t[t.length-1].children.push(n):t.push(h("p",[n])):t.push(n);return t}function T(e,t){return le(e,t).tree}function le(e,t){const n=[],r={ancestors:[],depth:0,messages:n,source:t},o=e.children;return{tree:{type:"root",children:H(o,r)},messages:n}}const O=["chapter","section","subsection","subsubsection","paragraphs"];function ce(e){return O[Math.min(e-1,O.length-1)]}function H(e,t,n=!1){let r=7;for(const a of e)a.type==="heading"&&(r=Math.min(r,a.depth));if(r===7)return w(e,t,n);const o=[];let s=null,i=[],l=[];const c=()=>{s&&(o.push(ae(s,l,t)),s=null,l=[])};for(const a of e)a.type==="heading"&&a.depth===r?(!s&&i.length>0&&(o.push(...w(i,t,n)),i=[]),c(),s=a,l=[]):s?l.push(a):i.push(a);return!s&&i.length>0&&o.push(...w(i,t,n)),c(),o}function w(e,t,n=!1){const r=[];for(let o=0;o<e.length;o+=1){const s=e[o],i=M(s,t);if(i!==null){if(i.name==="p"&&i.children.length===1&&i.children[0].name==="md"){const l=i.children[0],c=r[r.length-1],a=o+1<e.length?M(e[o+1],t):null,f=a?.name==="p"?a.children:null;if(c?.name==="p")c.children.push(l),f&&(c.children.push(...f),o+=1);else{const d=[l];f&&(d.push(...f),o+=1),r.push(h("p",d))}continue}if((i.name==="ul"||i.name==="ol")&&r.length>0){const l=r[r.length-1];if(l?.name==="p"){l.children.push(i);continue}}r.push(i)}}return n?U(r):r}function ae(e,t,n){const r=ce(e.depth),o=h("title",b(e.children,n)),s=ue(e),i=H(t,{...n,depth:n.depth+1},!0),l=U(i);return h(r,[o,...l],s)}function ue(e){const t=e.data;return t?.id?{"xml:id":t.id}:void 0}const pe={paragraph:(e,t)=>Z(e,t),blockquote:(e,t)=>fe(e,t),list:(e,t)=>he(e,t),code:(e,t)=>me(e),containerDirective:(e,t)=>V(e,t)};function M(e,t){const n=pe[e.type];return n?n(e,t):(t.messages&&t.messages.push({type:"warning",reason:`Unknown block type: ${e.type}`,category:"unknown-block-type"}),null)}function Z(e,t){return h("p",b(e.children,t))}function fe(e,t){const n=e.children.filter(r=>r.type==="paragraph").map(r=>{const o={...t,ancestors:[...t.ancestors,e],depth:t.depth+1};return Z(r,o)});return h("blockquote",n)}function he(e,t){const n=e.children.map(r=>{const o={...t,ancestors:[...t.ancestors,e],depth:t.depth+1};return de(r,o)});return h(e.ordered?"ol":"ul",n)}function de(e,t){const n=w(e.children,t);return h("li",n)}function me(e,t){return x("program",e.value,e.lang?{language:e.lang}:void 0)}function ge(e,t){const n=e.value.split(/\\\\|[\r\n]+/).map(r=>r.trim()).filter(r=>r.length>0);return n.length>1?h("md",n.map(r=>x("mrow",r))):x("md",n[0]??"")}function ye(e,t){return e.meta==="inline"?x("m",e.value):ge(e)}function V(e,t){const n=oe(e.name);if(!n)return t.messages&&t.messages.push({type:"warning",reason:`Unknown directive: ${e.name}`,category:"unknown-directive"}),null;const r=ve(e),o=e.children,{title:s,body:i}=ke(o,t),l={...t,ancestors:[...t.ancestors,e],depth:t.depth+1};return ie(n,r,s,i,l,(c,a)=>M(c,a),(c,a)=>V(c,a))}function ke(e,t){const n=e[0];return n?.type==="paragraph"&&n.data?.directiveLabel===!0?{title:h("title",b(n.children,t)),body:e.slice(1)}:{title:null,body:e}}function ve(e){const t=e.attributes??{},n={};for(const[r,o]of Object.entries(t))o!=null&&(n[r==="id"?"xml:id":r]=o);return Object.keys(n).length>0?n:void 0}function xe(e,t){return!t||e.position?.start?.offset===null||e.position?.start?.offset===void 0?"asterisk":t.charAt(e.position.start.offset)==="_"?"underscore":"asterisk"}const be={text:(e,t)=>B(e.value),emphasis:(e,t)=>{const r=xe(e,t.source)==="underscore"?"term":"em";return h(r,b(e.children,t))},strong:(e,t)=>h("alert",b(e.children,t)),inlineCode:(e,t)=>x("c",e.value),math:(e,t)=>ye(e)};function b(e,t){return e.flatMap(n=>Ce(n,t)).filter(n=>n!==null)}function Ce(e,t){const n=be[e.type];if(!n)return t.messages&&t.messages.push({type:"warning",reason:`Unknown inline type: ${e.type}`,category:"unknown-inline-type"}),null;const r={...t,ancestors:[...t.ancestors,e]};return n(e,r)}const we=[{open:"$$",close:"$$",isDisplay:!0},{open:"\\[",close:"\\]",isDisplay:!0},{open:"$",close:"$",isDisplay:!1},{open:"\\(",close:"\\)",isDisplay:!1}],X="PTX_MATH_TOKEN_",I=new RegExp(`${X}(\\d+)`,"g");function K(e,t){let n=null;for(const r of we){const o=e.indexOf(r.open,t);if(o===-1)continue;const s=e.indexOf(r.close,o+r.open.length);if(s!==-1&&!(r.open==="$"&&(o>0&&e[o-1]==="$"||o+1<e.length&&e[o+1]==="$"))&&(!n||o<n.index)){const i=e.substring(o+r.open.length,s);n={index:o,pattern:r,content:i}}}return n}function Se(e,t){let n=t;for(;n<e.length;){const r=e.indexOf("`",n);if(r===-1)return null;let o=0,s=r;for(;s<e.length&&e[s]==="`";)o++,s++;const i="`".repeat(o);let l=s;for(;l<e.length;){const c=e.indexOf(i,l);if(c===-1)break;const a=c+o;if(a>=e.length||e[a]!=="`")return{start:r,end:a};l=c+1}n=r+o}return null}function De(e){const t=new Map;let n="",r=0,o=0;for(;r<e.length;){const s=Se(e,r),i=K(e,r);if(s&&(!i||s.start<i.index)){n+=e.substring(r,s.end),r=s.end;continue}if(!i){n+=e.substring(r);break}n+=e.substring(r,i.index);const l=`${X}${o}`;n+=l,t.set(l,{type:"math",value:i.content,meta:i.pattern.isDisplay?"display":"inline"}),r=i.index+i.pattern.open.length+i.content.length+i.pattern.close.length,o+=1}return{markdown:n,tokens:t}}function qe(e){const t=[];let n=0;for(;n<e.length;){const r=K(e,n);if(!r){n<e.length&&t.push({type:"text",value:e.substring(n)});break}r.index>n&&t.push({type:"text",value:e.substring(n,r.index)}),t.push({type:"math",value:r.content,meta:r.pattern.isDisplay?"display":"inline"}),n=r.index+r.pattern.open.length+r.content.length+r.pattern.close.length}return t.length===0?[{type:"text",value:e}]:t}function Ie(e,t){const n=[];let r=0;I.lastIndex=0;let o=I.exec(e);for(;o;){const s=o.index,i=o[0];s>r&&n.push({type:"text",value:e.substring(r,s)});const l=t.get(i);l?n.push(l):n.push({type:"text",value:i}),r=s+i.length,o=I.exec(e)}return r<e.length&&n.push({type:"text",value:e.substring(r)}),n.length===0?[{type:"text",value:e}]:n}function Y(e){W.visit(e,"paragraph",t=>{const n=t.children||[],r=[];for(const o of n)if(o.type==="text"){const s=qe(o.value);r.push(...s)}else r.push(o);t.children=r})}function Te(e,t){W.visit(e,"paragraph",n=>{const r=n.children||[],o=[];for(const s of r)if(s.type==="text"){const i=Ie(s.value,t);o.push(...i)}else o.push(s);n.children=o})}const Me=()=>e=>{Y(e)};function Ee(e){const t=e.trim();if(!t.startsWith(":"))return null;let n=0;for(let s=0;s<t.length&&t[s]===":";s++)n++;if(n<3)return null;const r=t.slice(n).trim(),o=r.match(/^([a-zA-Z0-9_-]+)(\[[^\]]*\])?(\{[^}]*\})?$/);return r===""?{colons:n,label:null,lineIndex:-1,isOpen:!1}:o?{colons:n,label:o[0],lineIndex:-1,isOpen:!0}:null}function Le(e){const t=[],n=[];for(const r of e)if(r.isOpen){const o={colons:r.colons,finalColons:r.colons,label:r.label,openLineIndex:r.lineIndex,closeLineIndex:null,children:[],parent:null};if(t.length>0){const s=t[t.length-1];o.parent=s,s.children.push(o)}else n.push(o);t.push(o)}else{const o=t[t.length-1];o&&o.colons===r.colons&&(o.closeLineIndex=r.lineIndex,t.pop())}return n}function G(e){if(e.children.length===0)e.finalColons=e.colons;else{const t=Math.max(...e.children.map(G));e.finalColons=Math.max(e.colons,t+1)}return e.finalColons}function Fe(e,t,n){const r=e.slice(),o=[],s=t.slice();for(;s.length>0;){const i=s.shift();o.push(i),s.push(...i.children)}for(const i of o){if(i.openLineIndex>=0){const l=r[i.openLineIndex],c=l.match(/^:+/)?.[0].length||3,a=l.slice(c);r[i.openLineIndex]=":".repeat(i.finalColons)+a}i.closeLineIndex!==null&&i.closeLineIndex>=0&&(r[i.closeLineIndex]=":".repeat(i.finalColons))}return r}function Ne(e){const t=e.split(`
|
|
2
|
+
`),n=[];let r=!1,o=null;for(let l=0;l<t.length;l++){const c=t[l],f=c.trim().match(/^(`{3,}|~{3,})/);if(f){const m=f[1];r?o&&m[0]===o[0]&&m.length>=o.length&&(r=!1,o=null):(r=!0,o=m);continue}if(r)continue;const d=Ee(c);d&&n.push({...d,lineIndex:l})}if(n.length===0)return e;const s=Le(n);for(const l of s)G(l);return Fe(t,s).join(`
|
|
3
|
+
`)}function $e(e){const t=e.trim();if(!t.endsWith(":"))return null;const n=t.slice(0,-1);if(!/^[a-zA-Z]/.test(n))return null;const r=n.match(/^([a-zA-Z][a-zA-Z0-9_-]*)(.*)$/);if(!r)return null;const[,o,s]=r;return s&&!/^(\[[^\]]*\]|\{[^}]*\})*$/.test(s)||!q[o.toLowerCase()]?null:n}function E(e){let t=0;for(let n=0;n<e.length;n++)if(e[n]===" ")t+=1;else if(e[n]===" ")t+=4;else break;return t}function Oe(e,t){const n=E(e[t]);for(let r=t+1;r<e.length;r++)if(!J(e[r]))return E(e[r])>n;return!1}function J(e){return e.trim()===""}function Pe(e){const t=e.split(`
|
|
4
|
+
`),n=[],r={level:0,openDirectives:[],inCodeFence:!1,codeFenceMarker:null};for(let o=0;o<t.length;o++){const s=t[o],i=s.trim(),l=E(s),c=i.match(/^(`{3,}|~{3,})/);if(c){const f=c[1];r.inCodeFence?r.codeFenceMarker&&i.startsWith(r.codeFenceMarker)&&(r.inCodeFence=!1,r.codeFenceMarker=null):(r.inCodeFence=!0,r.codeFenceMarker=f),n.push(s);continue}if(r.inCodeFence){n.push(s);continue}if(J(s)){n.push("");continue}const a=$e(i);if(a&&Oe(t,o)){for(;r.openDirectives.length>0&&!(r.openDirectives[r.openDirectives.length-1].indentLevel<l);){const g=r.openDirectives.pop();g&&n.push(":".repeat(g.colonCount))}const f=a.match(/^([a-zA-Z][a-zA-Z0-9_-]*)(.*)/),d=f?f[1].toLowerCase()+(f[2]||""):a,m=r.openDirectives.length*1+3;n.push(":".repeat(m)+d),r.openDirectives.push({label:d,indentLevel:l,colonCount:m}),r.level=l}else{for(;r.openDirectives.length>0&&l<=r.openDirectives[r.openDirectives.length-1].indentLevel;){const f=r.openDirectives.pop();f&&n.push(":".repeat(f.colonCount))}r.openDirectives.length>0,n.push(s),r.level=l}}for(;r.openDirectives.length>0;){const o=r.openDirectives.pop();o&&n.push(":".repeat(o.colonCount))}return n.join(`
|
|
5
|
+
`)}const Q=function(){return function(t,n){if(typeof n?.value=="string"){const r=Pe(n.value),o=Ne(r),s=De(o),l=R.unified().use(j).use(z).parse(s.markdown);return Te(l,s.tokens),T(l,s.markdown)}return Y(t),T(t)}},Ae=/["&'<>`]/g,_e=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,Re=/[\x01-\t\v\f\x0E-\x1F\x7F\x81\x8D\x8F\x90\x9D\xA0-\uFFFF]/g,je=/[|\\{}()[\]^$+*?.]/g,P=new WeakMap;function ze(e,t){if(e=e.replace(t.subset?We(t.subset):Ae,r),t.subset||t.escapeOnly)return e;return e.replace(_e,n).replace(Re,r);function n(o,s,i){return t.format((o.charCodeAt(0)-55296)*1024+o.charCodeAt(1)-56320+65536,i.charCodeAt(s+2),t)}function r(o,s,i){return t.format(o.charCodeAt(0),i.charCodeAt(s+1),t)}}function We(e){let t=P.get(e);return t||(t=Be(e),P.set(e,t)),t}function Be(e){const t=[];let n=-1;for(;++n<e.length;)t.push(e[n].replace(je,"\\$&"));return new RegExp("(?:"+t.join("|")+")","g")}function Ue(e){return"&#x"+e.toString(16).toUpperCase()+";"}function He(e,t){return ze(e,Object.assign({format:Ue},t))}const Ze=/[\u0000-\u0008\u000B\u000C\u000E-\u001F]/g;function y(e,t,n){const r=Ve(e);return n?r.replace(n,o):o(r);function o(s){return He(s,{subset:t})}}function Ve(e){return String(e||"").replace(Ze,"")}const Xe=/]]>/g,Ke=[">"];function Ye(e){return"<![CDATA["+y(e.value,Ke,Xe)+"]]>"}function Ge(e){return"<!--"+y(e.value,["-"])+"-->"}const Je=[" ",`
|
|
6
|
+
`," ",'"',"&","'","/","<","=",">"];function D(e){return y(e,Je)}function A(e,t){const n=String(e);if(typeof t!="string")throw new TypeError("Expected character");let r=0,o=n.indexOf(t);for(;o!==-1;)r++,o=n.indexOf(t,o+t.length);return r}function L(e,t){const n=String(e);let r=t.options.quote||'"';if(t.options.quoteSmart){const o=r==='"'?"'":'"';A(n,r)>A(n,o)&&(r=o)}return r+y(n,["<","&",r])+r}function Qe(e,t){const n=D(e.name),r=e.public,o=e.system;let s="<!DOCTYPE";return n!==""&&(s+=" "+n),r?s+=" PUBLIC "+L(r,t):o&&(s+=" SYSTEM"),o&&(s+=" "+L(o,t)),s+">"}const et={}.hasOwnProperty;function tt(e,t){const n=D(e.name),r=ne(e,t),o=e.attributes||{},s=r?!1:t.options.closeEmptyElements,i=[];let l;for(l in o)if(et.call(o,l)){const c=o[l];c!=null&&i.push(D(l)+"="+L(c,t))}return"<"+n+(i.length===0?"":" "+i.join(" "))+(s?(t.options.tightClose?"":" ")+"/":"")+">"+r+(s?"":"</"+n+">")}const nt=/\?>/g,rt=[">"];function ot(e){const t=D(e.name)||"x",n=y(e.value,rt,nt);return"<?"+t+(n?" "+n:"")+"?>"}const st=["&","<"];function ee(e){return y(e.value,st)}function it(e,t){return t.options.allowDangerousXml?e.value:ee(e)}const lt={}.hasOwnProperty,_={cdata:Ye,comment:Ge,doctype:Qe,element:tt,instruction:ot,raw:it,root:ne,text:ee};function te(e,t){const n=e&&e.type;if(!n)throw new Error("Expected node, not `"+e+"`");if(!lt.call(_,n))throw new Error("Cannot compile unknown node `"+n+"`");const r=_[n];return r(e,t)}function ne(e,t){const n=e&&e.children||[];let r=-1;const o=[];for(;++r<n.length;)o[r]=te(n[r],t);return o.join("")}function ct(e,t){const n={options:{}};if(typeof n.options.quote=="string"&&n.options.quote!=='"'&&n.options.quote!=="'")throw new Error("Invalid quote `"+n.options.quote+"`, expected `'` or `\"`");const r=Array.isArray(e)?{type:"root",children:e}:e;return te(r,n)}function at(e){const t=R.unified().use(j).use(z).use(Q),n=t.parse(e),r=t.runSync(n,{value:e});return ct(r.children)}exports.DIRECTIVE_MAP=re;exports.PROOF_SOLUTION_NAMES=F;exports.markdownToPretext=at;exports.mdastToPtxast=T;exports.remarkMath=Me;exports.remarkPretext=Q;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { default as remarkPretext } from './lib/remark-pretext.js';
|
|
2
|
+
export { markdownToPretext } from './lib/markdown-to-pretext.js';
|
|
3
|
+
export { mdastToPtxast } from './lib/remark-pretext.js';
|
|
4
|
+
export { DIRECTIVE_MAP, PROOF_SOLUTION_NAMES } from './lib/directive-map.js';
|
|
5
|
+
export type { DirectiveInfo, DirectiveCategory } from './lib/directive-map.js';
|
|
6
|
+
export type { RemarkPretextOptions } from './lib/remark-pretext.js';
|
|
7
|
+
export { default as remarkMath } from './lib/math-parser.js';
|
|
8
|
+
export type { Math } from './lib/math-parser.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,796 @@
|
|
|
1
|
+
import { unified as _ } from "unified";
|
|
2
|
+
import R from "remark-parse";
|
|
3
|
+
import j from "remark-directive";
|
|
4
|
+
import { visit as z } from "unist-util-visit";
|
|
5
|
+
const q = {
|
|
6
|
+
// theorem-like (requires statement wrapping)
|
|
7
|
+
theorem: { type: "theorem", category: "theorem-like", requiresStatement: !0 },
|
|
8
|
+
lemma: { type: "lemma", category: "theorem-like", requiresStatement: !0 },
|
|
9
|
+
corollary: { type: "corollary", category: "theorem-like", requiresStatement: !0 },
|
|
10
|
+
proposition: { type: "proposition", category: "theorem-like", requiresStatement: !0 },
|
|
11
|
+
claim: { type: "claim", category: "theorem-like", requiresStatement: !0 },
|
|
12
|
+
fact: { type: "fact", category: "theorem-like", requiresStatement: !0 },
|
|
13
|
+
conjecture: { type: "conjecture", category: "theorem-like", requiresStatement: !0 },
|
|
14
|
+
axiom: { type: "axiom", category: "theorem-like", requiresStatement: !0 },
|
|
15
|
+
principle: { type: "principle", category: "theorem-like", requiresStatement: !0 },
|
|
16
|
+
hypothesis: { type: "hypothesis", category: "theorem-like", requiresStatement: !0 },
|
|
17
|
+
algorithm: { type: "algorithm", category: "theorem-like", requiresStatement: !0 },
|
|
18
|
+
// definition-like (requires statement wrapping)
|
|
19
|
+
definition: { type: "definition", category: "definition-like", requiresStatement: !0 },
|
|
20
|
+
notation: { type: "notation", category: "definition-like", requiresStatement: !0 },
|
|
21
|
+
// remark-like (no statement wrapping)
|
|
22
|
+
remark: { type: "remark", category: "remark-like", requiresStatement: !1 },
|
|
23
|
+
note: { type: "note", category: "remark-like", requiresStatement: !1 },
|
|
24
|
+
observation: { type: "observation", category: "remark-like", requiresStatement: !1 },
|
|
25
|
+
warning: { type: "warning", category: "remark-like", requiresStatement: !1 },
|
|
26
|
+
insight: { type: "insight", category: "remark-like", requiresStatement: !1 },
|
|
27
|
+
assemblage: { type: "assemblage", category: "remark-like", requiresStatement: !1 },
|
|
28
|
+
// example-like (exercise/project/task support nested tasks; require statement if no nested tasks)
|
|
29
|
+
example: { type: "example", category: "example-like", requiresStatement: !1 },
|
|
30
|
+
question: { type: "question", category: "example-like", requiresStatement: !1 },
|
|
31
|
+
problem: { type: "problem", category: "example-like", requiresStatement: !1 },
|
|
32
|
+
exercise: { type: "exercise", category: "example-like", requiresStatement: !0, hasNestedTasks: !0 },
|
|
33
|
+
activity: { type: "activity", category: "example-like", requiresStatement: !1 },
|
|
34
|
+
exploration: { type: "exploration", category: "example-like", requiresStatement: !1 },
|
|
35
|
+
investigation: { type: "investigation", category: "example-like", requiresStatement: !1 },
|
|
36
|
+
project: { type: "project", category: "example-like", requiresStatement: !0, hasNestedTasks: !0 },
|
|
37
|
+
// task (can have nested tasks, requires statement if no nested tasks)
|
|
38
|
+
task: { type: "task", category: "example-like", requiresStatement: !0, hasNestedTasks: !0 },
|
|
39
|
+
// proof-like (no statement wrapping)
|
|
40
|
+
proof: { type: "proof", category: "proof-like", requiresStatement: !1 },
|
|
41
|
+
case: { type: "case", category: "proof-like", requiresStatement: !1 },
|
|
42
|
+
// solution-like (no statement wrapping)
|
|
43
|
+
solution: { type: "solution", category: "solution-like", requiresStatement: !1 },
|
|
44
|
+
hint: { type: "hint", category: "solution-like", requiresStatement: !1 },
|
|
45
|
+
answer: { type: "answer", category: "solution-like", requiresStatement: !1 }
|
|
46
|
+
}, pt = q;
|
|
47
|
+
function ne(e) {
|
|
48
|
+
return q[e.toLowerCase()];
|
|
49
|
+
}
|
|
50
|
+
const W = new Set(
|
|
51
|
+
Object.entries(q).filter(([e, t]) => t.category === "proof-like" || t.category === "solution-like").map(([e]) => e)
|
|
52
|
+
);
|
|
53
|
+
function v(e, t, n) {
|
|
54
|
+
return {
|
|
55
|
+
type: "element",
|
|
56
|
+
name: e,
|
|
57
|
+
attributes: n ?? {},
|
|
58
|
+
children: t
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function C(e) {
|
|
62
|
+
return e.type === "containerDirective" && e.name === "task";
|
|
63
|
+
}
|
|
64
|
+
function re(e) {
|
|
65
|
+
return e.type === "containerDirective" && W.has(e.name);
|
|
66
|
+
}
|
|
67
|
+
function D(e) {
|
|
68
|
+
const t = [];
|
|
69
|
+
for (const n of e)
|
|
70
|
+
n.name === "ul" || n.name === "ol" ? t.length > 0 && t[t.length - 1]?.name === "p" ? t[t.length - 1].children.push(n) : t.push(v("p", [n])) : t.push(n);
|
|
71
|
+
return t;
|
|
72
|
+
}
|
|
73
|
+
function oe(e, t, n, r, o, s, i) {
|
|
74
|
+
const l = [];
|
|
75
|
+
if (n && l.push(n), e.hasNestedTasks) {
|
|
76
|
+
const c = r.findIndex(C);
|
|
77
|
+
if (c !== -1) {
|
|
78
|
+
const a = [];
|
|
79
|
+
for (let u = 0; u < r.length; u++)
|
|
80
|
+
C(r[u]) && a.push(u);
|
|
81
|
+
const f = a[a.length - 1], d = r.slice(0, c), m = r.slice(c).filter(C), k = [], g = [], L = [];
|
|
82
|
+
for (let u = c; u < r.length; u++) {
|
|
83
|
+
const p = r[u];
|
|
84
|
+
if (!C(p)) {
|
|
85
|
+
if (u < f) {
|
|
86
|
+
k.push(p);
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (re(p)) {
|
|
90
|
+
L.push(p);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
g.push(p);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (k.length > 0 && (o.messages ?? (o.messages = [])).push({
|
|
97
|
+
type: "warning",
|
|
98
|
+
reason: `Dropped ${k.length} non-task node(s) between task directives in ${e.type}.`,
|
|
99
|
+
category: "dropped-content-between-tasks",
|
|
100
|
+
position: k[0].position?.start
|
|
101
|
+
}), d.length > 0) {
|
|
102
|
+
const u = D(
|
|
103
|
+
d.map((p) => s(p, o)).filter((p) => p !== null)
|
|
104
|
+
);
|
|
105
|
+
u.length > 0 && l.push(v("introduction", u));
|
|
106
|
+
}
|
|
107
|
+
for (const u of m) {
|
|
108
|
+
const p = i(u, o);
|
|
109
|
+
p && l.push(p);
|
|
110
|
+
}
|
|
111
|
+
if (g.length > 0) {
|
|
112
|
+
const u = D(
|
|
113
|
+
g.map((p) => s(p, o)).filter((p) => p !== null)
|
|
114
|
+
);
|
|
115
|
+
u.length > 0 && l.push(v("conclusion", u));
|
|
116
|
+
}
|
|
117
|
+
for (const u of L) {
|
|
118
|
+
const p = i(u, o);
|
|
119
|
+
p && l.push(p);
|
|
120
|
+
}
|
|
121
|
+
} else
|
|
122
|
+
F(l, e, r, o, s, i);
|
|
123
|
+
} else
|
|
124
|
+
F(l, e, r, o, s, i);
|
|
125
|
+
return v(e.type, l, t);
|
|
126
|
+
}
|
|
127
|
+
function F(e, t, n, r, o, s) {
|
|
128
|
+
if (t.requiresStatement) {
|
|
129
|
+
const i = [], l = [];
|
|
130
|
+
for (const c of n)
|
|
131
|
+
if (c.type === "containerDirective" && W.has(c.name)) {
|
|
132
|
+
const a = s(c, r);
|
|
133
|
+
a && l.push(a);
|
|
134
|
+
} else
|
|
135
|
+
i.push(c);
|
|
136
|
+
if (i.length > 0) {
|
|
137
|
+
const c = D(
|
|
138
|
+
i.map((a) => o(a, r)).filter((a) => a !== null)
|
|
139
|
+
);
|
|
140
|
+
c.length > 0 && e.push(v("statement", c));
|
|
141
|
+
}
|
|
142
|
+
e.push(...l);
|
|
143
|
+
} else {
|
|
144
|
+
const i = D(
|
|
145
|
+
n.map((l) => o(l, r)).filter((l) => l !== null)
|
|
146
|
+
);
|
|
147
|
+
e.push(...i);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function B(e) {
|
|
151
|
+
return { type: "text", value: e };
|
|
152
|
+
}
|
|
153
|
+
function h(e, t, n) {
|
|
154
|
+
return {
|
|
155
|
+
type: "element",
|
|
156
|
+
name: e,
|
|
157
|
+
attributes: n ?? {},
|
|
158
|
+
children: t
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function x(e, t, n) {
|
|
162
|
+
return h(e, [B(t)], n);
|
|
163
|
+
}
|
|
164
|
+
function H(e) {
|
|
165
|
+
const t = [];
|
|
166
|
+
for (const n of e)
|
|
167
|
+
n.name === "ul" || n.name === "ol" ? t.length > 0 && t[t.length - 1]?.name === "p" ? t[t.length - 1].children.push(n) : t.push(h("p", [n])) : t.push(n);
|
|
168
|
+
return t;
|
|
169
|
+
}
|
|
170
|
+
function $(e, t) {
|
|
171
|
+
return se(e, t).tree;
|
|
172
|
+
}
|
|
173
|
+
function se(e, t) {
|
|
174
|
+
const n = [], r = { ancestors: [], depth: 0, messages: n, source: t }, o = e.children;
|
|
175
|
+
return {
|
|
176
|
+
tree: { type: "root", children: U(o, r) },
|
|
177
|
+
messages: n
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
const N = ["chapter", "section", "subsection", "subsubsection", "paragraphs"];
|
|
181
|
+
function ie(e) {
|
|
182
|
+
return N[Math.min(e - 1, N.length - 1)];
|
|
183
|
+
}
|
|
184
|
+
function U(e, t, n = !1) {
|
|
185
|
+
let r = 7;
|
|
186
|
+
for (const a of e)
|
|
187
|
+
a.type === "heading" && (r = Math.min(r, a.depth));
|
|
188
|
+
if (r === 7)
|
|
189
|
+
return w(e, t, n);
|
|
190
|
+
const o = [];
|
|
191
|
+
let s = null, i = [], l = [];
|
|
192
|
+
const c = () => {
|
|
193
|
+
s && (o.push(le(s, l, t)), s = null, l = []);
|
|
194
|
+
};
|
|
195
|
+
for (const a of e)
|
|
196
|
+
a.type === "heading" && a.depth === r ? (!s && i.length > 0 && (o.push(...w(i, t, n)), i = []), c(), s = a, l = []) : s ? l.push(a) : i.push(a);
|
|
197
|
+
return !s && i.length > 0 && o.push(...w(i, t, n)), c(), o;
|
|
198
|
+
}
|
|
199
|
+
function w(e, t, n = !1) {
|
|
200
|
+
const r = [];
|
|
201
|
+
for (let o = 0; o < e.length; o += 1) {
|
|
202
|
+
const s = e[o], i = T(s, t);
|
|
203
|
+
if (i !== null) {
|
|
204
|
+
if (i.name === "p" && i.children.length === 1 && i.children[0].name === "md") {
|
|
205
|
+
const l = i.children[0], c = r[r.length - 1], a = o + 1 < e.length ? T(e[o + 1], t) : null, f = a?.name === "p" ? a.children : null;
|
|
206
|
+
if (c?.name === "p")
|
|
207
|
+
c.children.push(l), f && (c.children.push(...f), o += 1);
|
|
208
|
+
else {
|
|
209
|
+
const d = [l];
|
|
210
|
+
f && (d.push(...f), o += 1), r.push(h("p", d));
|
|
211
|
+
}
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
if ((i.name === "ul" || i.name === "ol") && r.length > 0) {
|
|
215
|
+
const l = r[r.length - 1];
|
|
216
|
+
if (l?.name === "p") {
|
|
217
|
+
l.children.push(i);
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
r.push(i);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return n ? H(r) : r;
|
|
225
|
+
}
|
|
226
|
+
function le(e, t, n) {
|
|
227
|
+
const r = ie(e.depth), o = h("title", b(e.children, n)), s = ce(e), i = U(t, { ...n, depth: n.depth + 1 }, !0), l = H(i);
|
|
228
|
+
return h(r, [o, ...l], s);
|
|
229
|
+
}
|
|
230
|
+
function ce(e) {
|
|
231
|
+
const t = e.data;
|
|
232
|
+
return t?.id ? { "xml:id": t.id } : void 0;
|
|
233
|
+
}
|
|
234
|
+
const ae = {
|
|
235
|
+
paragraph: (e, t) => Z(e, t),
|
|
236
|
+
blockquote: (e, t) => ue(e, t),
|
|
237
|
+
list: (e, t) => pe(e, t),
|
|
238
|
+
code: (e, t) => he(e),
|
|
239
|
+
containerDirective: (e, t) => X(e, t)
|
|
240
|
+
};
|
|
241
|
+
function T(e, t) {
|
|
242
|
+
const n = ae[e.type];
|
|
243
|
+
return n ? n(e, t) : (t.messages && t.messages.push({
|
|
244
|
+
type: "warning",
|
|
245
|
+
reason: `Unknown block type: ${e.type}`,
|
|
246
|
+
category: "unknown-block-type"
|
|
247
|
+
}), null);
|
|
248
|
+
}
|
|
249
|
+
function Z(e, t) {
|
|
250
|
+
return h("p", b(e.children, t));
|
|
251
|
+
}
|
|
252
|
+
function ue(e, t) {
|
|
253
|
+
const n = e.children.filter((r) => r.type === "paragraph").map((r) => {
|
|
254
|
+
const o = { ...t, ancestors: [...t.ancestors, e], depth: t.depth + 1 };
|
|
255
|
+
return Z(r, o);
|
|
256
|
+
});
|
|
257
|
+
return h("blockquote", n);
|
|
258
|
+
}
|
|
259
|
+
function pe(e, t) {
|
|
260
|
+
const n = e.children.map((r) => {
|
|
261
|
+
const o = { ...t, ancestors: [...t.ancestors, e], depth: t.depth + 1 };
|
|
262
|
+
return fe(r, o);
|
|
263
|
+
});
|
|
264
|
+
return h(e.ordered ? "ol" : "ul", n);
|
|
265
|
+
}
|
|
266
|
+
function fe(e, t) {
|
|
267
|
+
const n = w(e.children, t);
|
|
268
|
+
return h("li", n);
|
|
269
|
+
}
|
|
270
|
+
function he(e, t) {
|
|
271
|
+
return x("program", e.value, e.lang ? { language: e.lang } : void 0);
|
|
272
|
+
}
|
|
273
|
+
function de(e, t) {
|
|
274
|
+
const n = e.value.split(/\\\\|[\r\n]+/).map((r) => r.trim()).filter((r) => r.length > 0);
|
|
275
|
+
return n.length > 1 ? h("md", n.map((r) => x("mrow", r))) : x("md", n[0] ?? "");
|
|
276
|
+
}
|
|
277
|
+
function me(e, t) {
|
|
278
|
+
return e.meta === "inline" ? x("m", e.value) : de(e);
|
|
279
|
+
}
|
|
280
|
+
function X(e, t) {
|
|
281
|
+
const n = ne(e.name);
|
|
282
|
+
if (!n)
|
|
283
|
+
return t.messages && t.messages.push({
|
|
284
|
+
type: "warning",
|
|
285
|
+
reason: `Unknown directive: ${e.name}`,
|
|
286
|
+
category: "unknown-directive"
|
|
287
|
+
}), null;
|
|
288
|
+
const r = ye(e), o = e.children, { title: s, body: i } = ge(o, t), l = { ...t, ancestors: [...t.ancestors, e], depth: t.depth + 1 };
|
|
289
|
+
return oe(
|
|
290
|
+
n,
|
|
291
|
+
r,
|
|
292
|
+
s,
|
|
293
|
+
i,
|
|
294
|
+
l,
|
|
295
|
+
(c, a) => T(c, a),
|
|
296
|
+
(c, a) => X(c, a)
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
function ge(e, t) {
|
|
300
|
+
const n = e[0];
|
|
301
|
+
return n?.type === "paragraph" && n.data?.directiveLabel === !0 ? {
|
|
302
|
+
title: h("title", b(n.children, t)),
|
|
303
|
+
body: e.slice(1)
|
|
304
|
+
} : { title: null, body: e };
|
|
305
|
+
}
|
|
306
|
+
function ye(e) {
|
|
307
|
+
const t = e.attributes ?? {}, n = {};
|
|
308
|
+
for (const [r, o] of Object.entries(t))
|
|
309
|
+
o != null && (n[r === "id" ? "xml:id" : r] = o);
|
|
310
|
+
return Object.keys(n).length > 0 ? n : void 0;
|
|
311
|
+
}
|
|
312
|
+
function ke(e, t) {
|
|
313
|
+
return !t || e.position?.start?.offset === null || e.position?.start?.offset === void 0 ? "asterisk" : t.charAt(e.position.start.offset) === "_" ? "underscore" : "asterisk";
|
|
314
|
+
}
|
|
315
|
+
const ve = {
|
|
316
|
+
text: (e, t) => B(e.value),
|
|
317
|
+
emphasis: (e, t) => {
|
|
318
|
+
const r = ke(e, t.source) === "underscore" ? "term" : "em";
|
|
319
|
+
return h(r, b(e.children, t));
|
|
320
|
+
},
|
|
321
|
+
strong: (e, t) => h("alert", b(e.children, t)),
|
|
322
|
+
inlineCode: (e, t) => x("c", e.value),
|
|
323
|
+
math: (e, t) => me(e)
|
|
324
|
+
};
|
|
325
|
+
function b(e, t) {
|
|
326
|
+
return e.flatMap((n) => xe(n, t)).filter((n) => n !== null);
|
|
327
|
+
}
|
|
328
|
+
function xe(e, t) {
|
|
329
|
+
const n = ve[e.type];
|
|
330
|
+
if (!n)
|
|
331
|
+
return t.messages && t.messages.push({
|
|
332
|
+
type: "warning",
|
|
333
|
+
reason: `Unknown inline type: ${e.type}`,
|
|
334
|
+
category: "unknown-inline-type"
|
|
335
|
+
}), null;
|
|
336
|
+
const r = { ...t, ancestors: [...t.ancestors, e] };
|
|
337
|
+
return n(e, r);
|
|
338
|
+
}
|
|
339
|
+
const be = [
|
|
340
|
+
// Display math (check these first, before single $)
|
|
341
|
+
{ open: "$$", close: "$$", isDisplay: !0 },
|
|
342
|
+
{ open: "\\[", close: "\\]", isDisplay: !0 },
|
|
343
|
+
// Inline math
|
|
344
|
+
{ open: "$", close: "$", isDisplay: !1 },
|
|
345
|
+
{ open: "\\(", close: "\\)", isDisplay: !1 }
|
|
346
|
+
], K = "PTX_MATH_TOKEN_", I = new RegExp(`${K}(\\d+)`, "g");
|
|
347
|
+
function Y(e, t) {
|
|
348
|
+
let n = null;
|
|
349
|
+
for (const r of be) {
|
|
350
|
+
const o = e.indexOf(r.open, t);
|
|
351
|
+
if (o === -1) continue;
|
|
352
|
+
const s = e.indexOf(r.close, o + r.open.length);
|
|
353
|
+
if (s !== -1 && !(r.open === "$" && (o > 0 && e[o - 1] === "$" || o + 1 < e.length && e[o + 1] === "$")) && (!n || o < n.index)) {
|
|
354
|
+
const i = e.substring(o + r.open.length, s);
|
|
355
|
+
n = { index: o, pattern: r, content: i };
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
return n;
|
|
359
|
+
}
|
|
360
|
+
function Ce(e, t) {
|
|
361
|
+
let n = t;
|
|
362
|
+
for (; n < e.length; ) {
|
|
363
|
+
const r = e.indexOf("`", n);
|
|
364
|
+
if (r === -1) return null;
|
|
365
|
+
let o = 0, s = r;
|
|
366
|
+
for (; s < e.length && e[s] === "`"; )
|
|
367
|
+
o++, s++;
|
|
368
|
+
const i = "`".repeat(o);
|
|
369
|
+
let l = s;
|
|
370
|
+
for (; l < e.length; ) {
|
|
371
|
+
const c = e.indexOf(i, l);
|
|
372
|
+
if (c === -1) break;
|
|
373
|
+
const a = c + o;
|
|
374
|
+
if (a >= e.length || e[a] !== "`")
|
|
375
|
+
return { start: r, end: a };
|
|
376
|
+
l = c + 1;
|
|
377
|
+
}
|
|
378
|
+
n = r + o;
|
|
379
|
+
}
|
|
380
|
+
return null;
|
|
381
|
+
}
|
|
382
|
+
function we(e) {
|
|
383
|
+
const t = /* @__PURE__ */ new Map();
|
|
384
|
+
let n = "", r = 0, o = 0;
|
|
385
|
+
for (; r < e.length; ) {
|
|
386
|
+
const s = Ce(e, r), i = Y(e, r);
|
|
387
|
+
if (s && (!i || s.start < i.index)) {
|
|
388
|
+
n += e.substring(r, s.end), r = s.end;
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
391
|
+
if (!i) {
|
|
392
|
+
n += e.substring(r);
|
|
393
|
+
break;
|
|
394
|
+
}
|
|
395
|
+
n += e.substring(r, i.index);
|
|
396
|
+
const l = `${K}${o}`;
|
|
397
|
+
n += l, t.set(l, {
|
|
398
|
+
type: "math",
|
|
399
|
+
value: i.content,
|
|
400
|
+
meta: i.pattern.isDisplay ? "display" : "inline"
|
|
401
|
+
}), r = i.index + i.pattern.open.length + i.content.length + i.pattern.close.length, o += 1;
|
|
402
|
+
}
|
|
403
|
+
return { markdown: n, tokens: t };
|
|
404
|
+
}
|
|
405
|
+
function De(e) {
|
|
406
|
+
const t = [];
|
|
407
|
+
let n = 0;
|
|
408
|
+
for (; n < e.length; ) {
|
|
409
|
+
const r = Y(e, n);
|
|
410
|
+
if (!r) {
|
|
411
|
+
n < e.length && t.push({ type: "text", value: e.substring(n) });
|
|
412
|
+
break;
|
|
413
|
+
}
|
|
414
|
+
r.index > n && t.push({
|
|
415
|
+
type: "text",
|
|
416
|
+
value: e.substring(n, r.index)
|
|
417
|
+
}), t.push({
|
|
418
|
+
type: "math",
|
|
419
|
+
value: r.content,
|
|
420
|
+
meta: r.pattern.isDisplay ? "display" : "inline"
|
|
421
|
+
}), n = r.index + r.pattern.open.length + r.content.length + r.pattern.close.length;
|
|
422
|
+
}
|
|
423
|
+
return t.length === 0 ? [{ type: "text", value: e }] : t;
|
|
424
|
+
}
|
|
425
|
+
function Se(e, t) {
|
|
426
|
+
const n = [];
|
|
427
|
+
let r = 0;
|
|
428
|
+
I.lastIndex = 0;
|
|
429
|
+
let o = I.exec(e);
|
|
430
|
+
for (; o; ) {
|
|
431
|
+
const s = o.index, i = o[0];
|
|
432
|
+
s > r && n.push({ type: "text", value: e.substring(r, s) });
|
|
433
|
+
const l = t.get(i);
|
|
434
|
+
l ? n.push(l) : n.push({ type: "text", value: i }), r = s + i.length, o = I.exec(e);
|
|
435
|
+
}
|
|
436
|
+
return r < e.length && n.push({ type: "text", value: e.substring(r) }), n.length === 0 ? [{ type: "text", value: e }] : n;
|
|
437
|
+
}
|
|
438
|
+
function V(e) {
|
|
439
|
+
z(e, "paragraph", (t) => {
|
|
440
|
+
const n = t.children || [], r = [];
|
|
441
|
+
for (const o of n)
|
|
442
|
+
if (o.type === "text") {
|
|
443
|
+
const s = De(o.value);
|
|
444
|
+
r.push(...s);
|
|
445
|
+
} else
|
|
446
|
+
r.push(o);
|
|
447
|
+
t.children = r;
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
function qe(e, t) {
|
|
451
|
+
z(e, "paragraph", (n) => {
|
|
452
|
+
const r = n.children || [], o = [];
|
|
453
|
+
for (const s of r)
|
|
454
|
+
if (s.type === "text") {
|
|
455
|
+
const i = Se(s.value, t);
|
|
456
|
+
o.push(...i);
|
|
457
|
+
} else
|
|
458
|
+
o.push(s);
|
|
459
|
+
n.children = o;
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
const ft = () => (e) => {
|
|
463
|
+
V(e);
|
|
464
|
+
};
|
|
465
|
+
function Ie(e) {
|
|
466
|
+
const t = e.trim();
|
|
467
|
+
if (!t.startsWith(":")) return null;
|
|
468
|
+
let n = 0;
|
|
469
|
+
for (let s = 0; s < t.length && t[s] === ":"; s++)
|
|
470
|
+
n++;
|
|
471
|
+
if (n < 3) return null;
|
|
472
|
+
const r = t.slice(n).trim(), o = r.match(/^([a-zA-Z0-9_-]+)(\[[^\]]*\])?(\{[^}]*\})?$/);
|
|
473
|
+
return r === "" ? { colons: n, label: null, lineIndex: -1, isOpen: !1 } : o ? { colons: n, label: o[0], lineIndex: -1, isOpen: !0 } : null;
|
|
474
|
+
}
|
|
475
|
+
function Te(e) {
|
|
476
|
+
const t = [], n = [];
|
|
477
|
+
for (const r of e)
|
|
478
|
+
if (r.isOpen) {
|
|
479
|
+
const o = {
|
|
480
|
+
colons: r.colons,
|
|
481
|
+
finalColons: r.colons,
|
|
482
|
+
label: r.label,
|
|
483
|
+
openLineIndex: r.lineIndex,
|
|
484
|
+
closeLineIndex: null,
|
|
485
|
+
children: [],
|
|
486
|
+
parent: null
|
|
487
|
+
};
|
|
488
|
+
if (t.length > 0) {
|
|
489
|
+
const s = t[t.length - 1];
|
|
490
|
+
o.parent = s, s.children.push(o);
|
|
491
|
+
} else
|
|
492
|
+
n.push(o);
|
|
493
|
+
t.push(o);
|
|
494
|
+
} else {
|
|
495
|
+
const o = t[t.length - 1];
|
|
496
|
+
o && o.colons === r.colons && (o.closeLineIndex = r.lineIndex, t.pop());
|
|
497
|
+
}
|
|
498
|
+
return n;
|
|
499
|
+
}
|
|
500
|
+
function G(e) {
|
|
501
|
+
if (e.children.length === 0)
|
|
502
|
+
e.finalColons = e.colons;
|
|
503
|
+
else {
|
|
504
|
+
const t = Math.max(...e.children.map(G));
|
|
505
|
+
e.finalColons = Math.max(e.colons, t + 1);
|
|
506
|
+
}
|
|
507
|
+
return e.finalColons;
|
|
508
|
+
}
|
|
509
|
+
function Ee(e, t, n) {
|
|
510
|
+
const r = e.slice(), o = [], s = t.slice();
|
|
511
|
+
for (; s.length > 0; ) {
|
|
512
|
+
const i = s.shift();
|
|
513
|
+
o.push(i), s.push(...i.children);
|
|
514
|
+
}
|
|
515
|
+
for (const i of o) {
|
|
516
|
+
if (i.openLineIndex >= 0) {
|
|
517
|
+
const l = r[i.openLineIndex], c = l.match(/^:+/)?.[0].length || 3, a = l.slice(c);
|
|
518
|
+
r[i.openLineIndex] = ":".repeat(i.finalColons) + a;
|
|
519
|
+
}
|
|
520
|
+
i.closeLineIndex !== null && i.closeLineIndex >= 0 && (r[i.closeLineIndex] = ":".repeat(i.finalColons));
|
|
521
|
+
}
|
|
522
|
+
return r;
|
|
523
|
+
}
|
|
524
|
+
function Me(e) {
|
|
525
|
+
const t = e.split(`
|
|
526
|
+
`), n = [];
|
|
527
|
+
let r = !1, o = null;
|
|
528
|
+
for (let l = 0; l < t.length; l++) {
|
|
529
|
+
const c = t[l], f = c.trim().match(/^(`{3,}|~{3,})/);
|
|
530
|
+
if (f) {
|
|
531
|
+
const m = f[1];
|
|
532
|
+
r ? o && m[0] === o[0] && m.length >= o.length && (r = !1, o = null) : (r = !0, o = m);
|
|
533
|
+
continue;
|
|
534
|
+
}
|
|
535
|
+
if (r)
|
|
536
|
+
continue;
|
|
537
|
+
const d = Ie(c);
|
|
538
|
+
d && n.push({ ...d, lineIndex: l });
|
|
539
|
+
}
|
|
540
|
+
if (n.length === 0)
|
|
541
|
+
return e;
|
|
542
|
+
const s = Te(n);
|
|
543
|
+
for (const l of s)
|
|
544
|
+
G(l);
|
|
545
|
+
return Ee(t, s).join(`
|
|
546
|
+
`);
|
|
547
|
+
}
|
|
548
|
+
function Le(e) {
|
|
549
|
+
const t = e.trim();
|
|
550
|
+
if (!t.endsWith(":")) return null;
|
|
551
|
+
const n = t.slice(0, -1);
|
|
552
|
+
if (!/^[a-zA-Z]/.test(n)) return null;
|
|
553
|
+
const r = n.match(/^([a-zA-Z][a-zA-Z0-9_-]*)(.*)$/);
|
|
554
|
+
if (!r) return null;
|
|
555
|
+
const [, o, s] = r;
|
|
556
|
+
return s && !/^(\[[^\]]*\]|\{[^}]*\})*$/.test(s) || !q[o.toLowerCase()] ? null : n;
|
|
557
|
+
}
|
|
558
|
+
function E(e) {
|
|
559
|
+
let t = 0;
|
|
560
|
+
for (let n = 0; n < e.length; n++)
|
|
561
|
+
if (e[n] === " ")
|
|
562
|
+
t += 1;
|
|
563
|
+
else if (e[n] === " ")
|
|
564
|
+
t += 4;
|
|
565
|
+
else
|
|
566
|
+
break;
|
|
567
|
+
return t;
|
|
568
|
+
}
|
|
569
|
+
function Fe(e, t) {
|
|
570
|
+
const n = E(e[t]);
|
|
571
|
+
for (let r = t + 1; r < e.length; r++)
|
|
572
|
+
if (!J(e[r]))
|
|
573
|
+
return E(e[r]) > n;
|
|
574
|
+
return !1;
|
|
575
|
+
}
|
|
576
|
+
function J(e) {
|
|
577
|
+
return e.trim() === "";
|
|
578
|
+
}
|
|
579
|
+
function $e(e) {
|
|
580
|
+
const t = e.split(`
|
|
581
|
+
`), n = [], r = {
|
|
582
|
+
level: 0,
|
|
583
|
+
openDirectives: [],
|
|
584
|
+
inCodeFence: !1,
|
|
585
|
+
codeFenceMarker: null
|
|
586
|
+
};
|
|
587
|
+
for (let o = 0; o < t.length; o++) {
|
|
588
|
+
const s = t[o], i = s.trim(), l = E(s), c = i.match(/^(`{3,}|~{3,})/);
|
|
589
|
+
if (c) {
|
|
590
|
+
const f = c[1];
|
|
591
|
+
r.inCodeFence ? r.codeFenceMarker && i.startsWith(r.codeFenceMarker) && (r.inCodeFence = !1, r.codeFenceMarker = null) : (r.inCodeFence = !0, r.codeFenceMarker = f), n.push(s);
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
if (r.inCodeFence) {
|
|
595
|
+
n.push(s);
|
|
596
|
+
continue;
|
|
597
|
+
}
|
|
598
|
+
if (J(s)) {
|
|
599
|
+
n.push("");
|
|
600
|
+
continue;
|
|
601
|
+
}
|
|
602
|
+
const a = Le(i);
|
|
603
|
+
if (a && Fe(t, o)) {
|
|
604
|
+
for (; r.openDirectives.length > 0 && !(r.openDirectives[r.openDirectives.length - 1].indentLevel < l); ) {
|
|
605
|
+
const g = r.openDirectives.pop();
|
|
606
|
+
g && n.push(":".repeat(g.colonCount));
|
|
607
|
+
}
|
|
608
|
+
const f = a.match(/^([a-zA-Z][a-zA-Z0-9_-]*)(.*)/), d = f ? f[1].toLowerCase() + (f[2] || "") : a, m = r.openDirectives.length * 1 + 3;
|
|
609
|
+
n.push(":".repeat(m) + d), r.openDirectives.push({
|
|
610
|
+
label: d,
|
|
611
|
+
indentLevel: l,
|
|
612
|
+
colonCount: m
|
|
613
|
+
}), r.level = l;
|
|
614
|
+
} else {
|
|
615
|
+
for (; r.openDirectives.length > 0 && l <= r.openDirectives[r.openDirectives.length - 1].indentLevel; ) {
|
|
616
|
+
const f = r.openDirectives.pop();
|
|
617
|
+
f && n.push(":".repeat(f.colonCount));
|
|
618
|
+
}
|
|
619
|
+
r.openDirectives.length > 0, n.push(s), r.level = l;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
for (; r.openDirectives.length > 0; ) {
|
|
623
|
+
const o = r.openDirectives.pop();
|
|
624
|
+
o && n.push(":".repeat(o.colonCount));
|
|
625
|
+
}
|
|
626
|
+
return n.join(`
|
|
627
|
+
`);
|
|
628
|
+
}
|
|
629
|
+
const Ne = function() {
|
|
630
|
+
return function(t, n) {
|
|
631
|
+
if (typeof n?.value == "string") {
|
|
632
|
+
const r = $e(n.value), o = Me(r), s = we(o), l = _().use(R).use(j).parse(s.markdown);
|
|
633
|
+
return qe(l, s.tokens), $(l, s.markdown);
|
|
634
|
+
}
|
|
635
|
+
return V(t), $(t);
|
|
636
|
+
};
|
|
637
|
+
}, Ae = /["&'<>`]/g, Oe = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g, Pe = (
|
|
638
|
+
// eslint-disable-next-line no-control-regex, unicorn/no-hex-escape
|
|
639
|
+
/[\x01-\t\v\f\x0E-\x1F\x7F\x81\x8D\x8F\x90\x9D\xA0-\uFFFF]/g
|
|
640
|
+
), _e = /[|\\{}()[\]^$+*?.]/g, A = /* @__PURE__ */ new WeakMap();
|
|
641
|
+
function Re(e, t) {
|
|
642
|
+
if (e = e.replace(
|
|
643
|
+
t.subset ? je(t.subset) : Ae,
|
|
644
|
+
r
|
|
645
|
+
), t.subset || t.escapeOnly)
|
|
646
|
+
return e;
|
|
647
|
+
return e.replace(Oe, n).replace(Pe, r);
|
|
648
|
+
function n(o, s, i) {
|
|
649
|
+
return t.format(
|
|
650
|
+
(o.charCodeAt(0) - 55296) * 1024 + o.charCodeAt(1) - 56320 + 65536,
|
|
651
|
+
i.charCodeAt(s + 2),
|
|
652
|
+
t
|
|
653
|
+
);
|
|
654
|
+
}
|
|
655
|
+
function r(o, s, i) {
|
|
656
|
+
return t.format(
|
|
657
|
+
o.charCodeAt(0),
|
|
658
|
+
i.charCodeAt(s + 1),
|
|
659
|
+
t
|
|
660
|
+
);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
function je(e) {
|
|
664
|
+
let t = A.get(e);
|
|
665
|
+
return t || (t = ze(e), A.set(e, t)), t;
|
|
666
|
+
}
|
|
667
|
+
function ze(e) {
|
|
668
|
+
const t = [];
|
|
669
|
+
let n = -1;
|
|
670
|
+
for (; ++n < e.length; )
|
|
671
|
+
t.push(e[n].replace(_e, "\\$&"));
|
|
672
|
+
return new RegExp("(?:" + t.join("|") + ")", "g");
|
|
673
|
+
}
|
|
674
|
+
function We(e) {
|
|
675
|
+
return "&#x" + e.toString(16).toUpperCase() + ";";
|
|
676
|
+
}
|
|
677
|
+
function Be(e, t) {
|
|
678
|
+
return Re(e, Object.assign({ format: We }, t));
|
|
679
|
+
}
|
|
680
|
+
const He = /[\u0000-\u0008\u000B\u000C\u000E-\u001F]/g;
|
|
681
|
+
function y(e, t, n) {
|
|
682
|
+
const r = Ue(e);
|
|
683
|
+
return n ? r.replace(n, o) : o(r);
|
|
684
|
+
function o(s) {
|
|
685
|
+
return Be(s, { subset: t });
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
function Ue(e) {
|
|
689
|
+
return String(e || "").replace(He, "");
|
|
690
|
+
}
|
|
691
|
+
const Ze = /]]>/g, Xe = [">"];
|
|
692
|
+
function Ke(e) {
|
|
693
|
+
return "<![CDATA[" + y(e.value, Xe, Ze) + "]]>";
|
|
694
|
+
}
|
|
695
|
+
function Ye(e) {
|
|
696
|
+
return "<!--" + y(e.value, ["-"]) + "-->";
|
|
697
|
+
}
|
|
698
|
+
const Ve = [" ", `
|
|
699
|
+
`, " ", '"', "&", "'", "/", "<", "=", ">"];
|
|
700
|
+
function S(e) {
|
|
701
|
+
return y(e, Ve);
|
|
702
|
+
}
|
|
703
|
+
function O(e, t) {
|
|
704
|
+
const n = String(e);
|
|
705
|
+
if (typeof t != "string")
|
|
706
|
+
throw new TypeError("Expected character");
|
|
707
|
+
let r = 0, o = n.indexOf(t);
|
|
708
|
+
for (; o !== -1; )
|
|
709
|
+
r++, o = n.indexOf(t, o + t.length);
|
|
710
|
+
return r;
|
|
711
|
+
}
|
|
712
|
+
function M(e, t) {
|
|
713
|
+
const n = String(e);
|
|
714
|
+
let r = t.options.quote || '"';
|
|
715
|
+
if (t.options.quoteSmart) {
|
|
716
|
+
const o = r === '"' ? "'" : '"';
|
|
717
|
+
O(n, r) > O(n, o) && (r = o);
|
|
718
|
+
}
|
|
719
|
+
return r + y(n, ["<", "&", r]) + r;
|
|
720
|
+
}
|
|
721
|
+
function Ge(e, t) {
|
|
722
|
+
const n = S(e.name), r = e.public, o = e.system;
|
|
723
|
+
let s = "<!DOCTYPE";
|
|
724
|
+
return n !== "" && (s += " " + n), r ? s += " PUBLIC " + M(r, t) : o && (s += " SYSTEM"), o && (s += " " + M(o, t)), s + ">";
|
|
725
|
+
}
|
|
726
|
+
const Je = {}.hasOwnProperty;
|
|
727
|
+
function Qe(e, t) {
|
|
728
|
+
const n = S(e.name), r = te(e, t), o = e.attributes || {}, s = r ? !1 : t.options.closeEmptyElements, i = [];
|
|
729
|
+
let l;
|
|
730
|
+
for (l in o)
|
|
731
|
+
if (Je.call(o, l)) {
|
|
732
|
+
const c = o[l];
|
|
733
|
+
c != null && i.push(S(l) + "=" + M(c, t));
|
|
734
|
+
}
|
|
735
|
+
return "<" + n + (i.length === 0 ? "" : " " + i.join(" ")) + (s ? (t.options.tightClose ? "" : " ") + "/" : "") + ">" + r + (s ? "" : "</" + n + ">");
|
|
736
|
+
}
|
|
737
|
+
const et = /\?>/g, tt = [">"];
|
|
738
|
+
function nt(e) {
|
|
739
|
+
const t = S(e.name) || "x", n = y(e.value, tt, et);
|
|
740
|
+
return "<?" + t + (n ? " " + n : "") + "?>";
|
|
741
|
+
}
|
|
742
|
+
const rt = ["&", "<"];
|
|
743
|
+
function Q(e) {
|
|
744
|
+
return y(e.value, rt);
|
|
745
|
+
}
|
|
746
|
+
function ot(e, t) {
|
|
747
|
+
return t.options.allowDangerousXml ? e.value : Q(e);
|
|
748
|
+
}
|
|
749
|
+
const st = {}.hasOwnProperty, P = {
|
|
750
|
+
cdata: Ke,
|
|
751
|
+
comment: Ye,
|
|
752
|
+
doctype: Ge,
|
|
753
|
+
element: Qe,
|
|
754
|
+
instruction: nt,
|
|
755
|
+
raw: ot,
|
|
756
|
+
root: te,
|
|
757
|
+
text: Q
|
|
758
|
+
};
|
|
759
|
+
function ee(e, t) {
|
|
760
|
+
const n = e && e.type;
|
|
761
|
+
if (!n)
|
|
762
|
+
throw new Error("Expected node, not `" + e + "`");
|
|
763
|
+
if (!st.call(P, n))
|
|
764
|
+
throw new Error("Cannot compile unknown node `" + n + "`");
|
|
765
|
+
const r = P[n];
|
|
766
|
+
return r(e, t);
|
|
767
|
+
}
|
|
768
|
+
function te(e, t) {
|
|
769
|
+
const n = e && e.children || [];
|
|
770
|
+
let r = -1;
|
|
771
|
+
const o = [];
|
|
772
|
+
for (; ++r < n.length; )
|
|
773
|
+
o[r] = ee(n[r], t);
|
|
774
|
+
return o.join("");
|
|
775
|
+
}
|
|
776
|
+
function it(e, t) {
|
|
777
|
+
const n = { options: {} };
|
|
778
|
+
if (typeof n.options.quote == "string" && n.options.quote !== '"' && n.options.quote !== "'")
|
|
779
|
+
throw new Error(
|
|
780
|
+
"Invalid quote `" + n.options.quote + "`, expected `'` or `\"`"
|
|
781
|
+
);
|
|
782
|
+
const r = Array.isArray(e) ? { type: "root", children: e } : e;
|
|
783
|
+
return ee(r, n);
|
|
784
|
+
}
|
|
785
|
+
function ht(e) {
|
|
786
|
+
const t = _().use(R).use(j).use(Ne), n = t.parse(e), r = t.runSync(n, { value: e });
|
|
787
|
+
return it(r.children);
|
|
788
|
+
}
|
|
789
|
+
export {
|
|
790
|
+
pt as DIRECTIVE_MAP,
|
|
791
|
+
W as PROOF_SOLUTION_NAMES,
|
|
792
|
+
ht as markdownToPretext,
|
|
793
|
+
$ as mdastToPtxast,
|
|
794
|
+
ft as remarkMath,
|
|
795
|
+
Ne as remarkPretext
|
|
796
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { BlockContent, DefinitionContent, PhrasingContent } from 'mdast';
|
|
2
|
+
export interface VisitContext {
|
|
3
|
+
/** Parent node, if any. */
|
|
4
|
+
parent?: BlockContent | DefinitionContent | PhrasingContent;
|
|
5
|
+
/** All ancestor nodes in traversal order. */
|
|
6
|
+
ancestors: (BlockContent | DefinitionContent | PhrasingContent)[];
|
|
7
|
+
/** Nesting depth. */
|
|
8
|
+
depth: number;
|
|
9
|
+
/** Accumulated error/warning messages. */
|
|
10
|
+
messages?: ConversionMessage[];
|
|
11
|
+
/** Raw source markdown (optional, used for delimiter detection). */
|
|
12
|
+
source?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ConversionMessage {
|
|
15
|
+
type: 'warning' | 'error';
|
|
16
|
+
reason: string;
|
|
17
|
+
category: string;
|
|
18
|
+
position?: {
|
|
19
|
+
line?: number;
|
|
20
|
+
column?: number;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { BlockContent, DefinitionContent } from 'mdast';
|
|
2
|
+
import { ContainerDirective } from 'mdast-util-directive';
|
|
3
|
+
import { Element } from 'xast';
|
|
4
|
+
import { DirectiveSpec } from './directive-map.js';
|
|
5
|
+
import { VisitContext } from './context.js';
|
|
6
|
+
/**
|
|
7
|
+
* Generic factory function: applies semantic rules from spec.
|
|
8
|
+
*
|
|
9
|
+
* Handles:
|
|
10
|
+
* - Statement wrapping for theorem-like elements
|
|
11
|
+
* - Task nesting with introduction wrapping (exercise/project/task)
|
|
12
|
+
* - Proof/solution sibling extraction
|
|
13
|
+
*
|
|
14
|
+
* @param spec Semantic specification for this directive type
|
|
15
|
+
* @param attrs HTML/XML attributes for the element
|
|
16
|
+
* @param titleEl Optional <title> element (extracted from first paragraph if present)
|
|
17
|
+
* @param children Body content of the directive
|
|
18
|
+
* @param ctx Visitor context
|
|
19
|
+
* @param convertBlock Callback to recursively convert block children
|
|
20
|
+
* @param convertDirective Callback to recursively convert nested directives
|
|
21
|
+
*
|
|
22
|
+
* @returns XAST element for this directive
|
|
23
|
+
*/
|
|
24
|
+
export declare function buildDirectiveWithSpec(spec: DirectiveSpec, attrs: Record<string, string> | undefined, titleEl: Element | null, children: Array<BlockContent | DefinitionContent>, ctx: VisitContext, convertBlock: (child: BlockContent | DefinitionContent, ctx: VisitContext) => Element | null, convertDirective: (node: ContainerDirective, ctx: VisitContext) => Element | null): Element;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps directive names (from remark-directive's `:::name`) to their
|
|
3
|
+
* corresponding xast element names and semantic specifications.
|
|
4
|
+
*
|
|
5
|
+
* Architecture (Phase 2 refactor):
|
|
6
|
+
* - Separated semantic specs (requiresStatement) from routing logic
|
|
7
|
+
* - Factories apply spec-driven semantic rules uniformly
|
|
8
|
+
* - Adding new directives requires only configuration change, not new functions
|
|
9
|
+
*/
|
|
10
|
+
export type DirectiveCategory = 'theorem-like' | 'proof-like' | 'definition-like' | 'axiom-like' | 'remark-like' | 'example-like' | 'project-like' | 'exercise-like' | 'solution-like';
|
|
11
|
+
/**
|
|
12
|
+
* Semantic specification for how a directive type should be converted.
|
|
13
|
+
* This pattern mirrors unified-latex-to-pretext's factory specifications.
|
|
14
|
+
*/
|
|
15
|
+
export interface DirectiveSpec {
|
|
16
|
+
/** The PreTeXt XML element name (= xast `name` field). */
|
|
17
|
+
type: string;
|
|
18
|
+
/** Routing category for handler selection. */
|
|
19
|
+
category: DirectiveCategory;
|
|
20
|
+
/**
|
|
21
|
+
* If true, the directive's body content is wrapped in a <statement> element,
|
|
22
|
+
* and proof/solution siblings are extracted as siblings of the statement
|
|
23
|
+
* (not children of it). This matches PreTeXt semantics where theorems have:
|
|
24
|
+
* <theorem><title/><statement>...</statement><proof/></theorem>
|
|
25
|
+
*
|
|
26
|
+
* If false, content is added directly without statement wrapping.
|
|
27
|
+
*/
|
|
28
|
+
requiresStatement: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* If true, this directive can have nested task children.
|
|
31
|
+
* Content before the first task becomes an <introduction> wrapper.
|
|
32
|
+
* Example:
|
|
33
|
+
* <exercise><introduction>...</introduction><task>...</task><task>...</task></exercise>
|
|
34
|
+
*
|
|
35
|
+
* Only applies if nested tasks are actually present in the body.
|
|
36
|
+
* If no tasks are found, requiresStatement still applies.
|
|
37
|
+
*/
|
|
38
|
+
hasNestedTasks?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Backwards-compatible type for code that only needs type+category.
|
|
42
|
+
* @deprecated Use DirectiveSpec instead for new code.
|
|
43
|
+
*/
|
|
44
|
+
export interface DirectiveInfo {
|
|
45
|
+
type: string;
|
|
46
|
+
category: DirectiveCategory;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Semantic specification table: directive name → spec.
|
|
50
|
+
*
|
|
51
|
+
* Pattern mirrors unified-latex-to-pretext's environment specification approach:
|
|
52
|
+
* Declarative table + factory functions apply rules uniformly.
|
|
53
|
+
* To add a new directive: just add an entry here.
|
|
54
|
+
*/
|
|
55
|
+
export declare const DIRECTIVE_SPEC_TABLE: Readonly<Record<string, DirectiveSpec>>;
|
|
56
|
+
/**
|
|
57
|
+
* @deprecated Use DIRECTIVE_SPEC_TABLE directly or via getDirectiveSpec().
|
|
58
|
+
* Kept for backwards compatibility. Returns spec as old DirectiveInfo type.
|
|
59
|
+
*/
|
|
60
|
+
export declare const DIRECTIVE_MAP: Readonly<Record<string, DirectiveInfo>>;
|
|
61
|
+
/** Get directive spec, or undefined if not found. */
|
|
62
|
+
export declare function getDirectiveSpec(name: string): DirectiveSpec | undefined;
|
|
63
|
+
/** Set of directive names that are proof/solution-like (used when separating statement siblings). */
|
|
64
|
+
export declare const PROOF_SOLUTION_NAMES: Set<string>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Directive Normalizer (Two-Pass Algorithm)
|
|
3
|
+
*
|
|
4
|
+
* Transforms user-friendly flexible colon syntax into standard remark-directive format.
|
|
5
|
+
*
|
|
6
|
+
* INPUT (flexible):
|
|
7
|
+
* :::exercise
|
|
8
|
+
* Intro
|
|
9
|
+
* :::task
|
|
10
|
+
* Content
|
|
11
|
+
* :::
|
|
12
|
+
* :::task
|
|
13
|
+
* More
|
|
14
|
+
* :::
|
|
15
|
+
* :::
|
|
16
|
+
*
|
|
17
|
+
* OUTPUT (normalized for remark-directive):
|
|
18
|
+
* ::::exercise
|
|
19
|
+
* Intro
|
|
20
|
+
* :::task
|
|
21
|
+
* Content
|
|
22
|
+
* :::
|
|
23
|
+
* :::task
|
|
24
|
+
* More
|
|
25
|
+
* :::
|
|
26
|
+
* ::::
|
|
27
|
+
*
|
|
28
|
+
* Algorithm (Two-Pass):
|
|
29
|
+
* - Pass 1: Parse markers, build nesting tree with parent references
|
|
30
|
+
* - Pass 2: Traverse tree bottom-up, compute final colon counts
|
|
31
|
+
* (each parent = max(children) + 1, ensuring proper nesting)
|
|
32
|
+
* - Pass 3: Re-emit with adjusted markers
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* Main normalization function
|
|
36
|
+
*/
|
|
37
|
+
export declare function normalizeDirectiveColons(markdown: string): string;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Indentation-Based Directive Normalizer
|
|
3
|
+
*
|
|
4
|
+
* Transforms Python-like indentation-based directive syntax into colon syntax.
|
|
5
|
+
*
|
|
6
|
+
* INPUT (indentation-based):
|
|
7
|
+
* Theorem[Pythagorean]{#thm}:
|
|
8
|
+
* Statement text here.
|
|
9
|
+
*
|
|
10
|
+
* Proof:
|
|
11
|
+
* Proof content.
|
|
12
|
+
*
|
|
13
|
+
* Plain text (outdented).
|
|
14
|
+
*
|
|
15
|
+
* OUTPUT (colon-based):
|
|
16
|
+
* :::theorem[Pythagorean]{#thm}
|
|
17
|
+
* Statement text here.
|
|
18
|
+
*
|
|
19
|
+
* ::::proof
|
|
20
|
+
* Proof content.
|
|
21
|
+
* ::::
|
|
22
|
+
* :::
|
|
23
|
+
*
|
|
24
|
+
* Plain text (outdented).
|
|
25
|
+
*
|
|
26
|
+
* Algorithm:
|
|
27
|
+
* 1. Track fenced code blocks (``` and ~~~) and skip directive detection inside them
|
|
28
|
+
* 2. Parse each line to detect directive markers (Keyword[...]{...}:)
|
|
29
|
+
* 3. Track indentation stack: when indent increases, open a block; when decreases, close block(s)
|
|
30
|
+
* 4. Convert to colon syntax with proper nesting depth (validated against DIRECTIVE_SPEC_TABLE)
|
|
31
|
+
* 5. Preserve all non-directive content and indentation outside directives and code fences
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* Normalize indentation-based syntax to colon-based syntax
|
|
35
|
+
*/
|
|
36
|
+
export declare function normalizeIndentationDirectives(markdown: string): string;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a markdown string (with PreTeXt directive extensions) to a PreTeXt
|
|
3
|
+
* XML string.
|
|
4
|
+
*
|
|
5
|
+
* The output contains the converted XML fragment — the children of the root
|
|
6
|
+
* node serialized as a string — suitable for embedding in a PreTeXt document.
|
|
7
|
+
*
|
|
8
|
+
* @param markdown - The markdown source to convert.
|
|
9
|
+
* @returns A PreTeXt XML string.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { markdownToPretext } from '@pretextbook/remark-pretext';
|
|
14
|
+
*
|
|
15
|
+
* const xml = markdownToPretext('# Hello\n\nThis is a paragraph.');
|
|
16
|
+
* // → '<section>\n <title>Hello</title>\n <p>This is a paragraph.</p>\n</section>'
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare function markdownToPretext(markdown: string): string;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Plugin } from 'unified';
|
|
2
|
+
import { Root, Text } from 'mdast';
|
|
3
|
+
export interface Math {
|
|
4
|
+
type: 'math';
|
|
5
|
+
value: string;
|
|
6
|
+
meta?: string;
|
|
7
|
+
}
|
|
8
|
+
declare module 'mdast' {
|
|
9
|
+
interface PhrasingContentMap {
|
|
10
|
+
math: Math;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export interface MathTokenizationResult {
|
|
14
|
+
markdown: string;
|
|
15
|
+
tokens: Map<string, Math>;
|
|
16
|
+
}
|
|
17
|
+
export declare function tokenizeMathInMarkdown(markdown: string): MathTokenizationResult;
|
|
18
|
+
/**
|
|
19
|
+
* Find math in a string and split into text and math nodes.
|
|
20
|
+
* Returns array of alternating Text and Math nodes.
|
|
21
|
+
*
|
|
22
|
+
* Order matters: we check longer/more specific delimiters first.
|
|
23
|
+
*/
|
|
24
|
+
export declare function splitTextWithMath(text: string): (Text | Math)[];
|
|
25
|
+
/**
|
|
26
|
+
* Remark plugin that detects and parses math delimiters in text nodes.
|
|
27
|
+
*/
|
|
28
|
+
export declare function applyMathDelimiters(tree: Root): void;
|
|
29
|
+
export declare function applyMathTokens(tree: Root, tokens: Map<string, Math>): void;
|
|
30
|
+
declare const remarkMath: Plugin<[], Root>;
|
|
31
|
+
export default remarkMath;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Root as MdastRoot } from 'mdast';
|
|
2
|
+
import { Root } from 'xast';
|
|
3
|
+
import { ConversionMessage } from './context.js';
|
|
4
|
+
/** Result type for conversion: tree + diagnostic messages. */
|
|
5
|
+
export interface ConversionResult {
|
|
6
|
+
tree: Root;
|
|
7
|
+
messages: ConversionMessage[];
|
|
8
|
+
}
|
|
9
|
+
/** Transform an mdast Root node into an xast Root node (backwards compatible). */
|
|
10
|
+
export declare function mdastToPtxast(tree: MdastRoot, source?: string): Root;
|
|
11
|
+
export { mdastToPtxast as mdastToXast };
|
|
12
|
+
/** Transform an mdast Root node, returning tree + diagnostic messages. */
|
|
13
|
+
export declare function mdastToPtxastWithDiagnostics(tree: MdastRoot, source?: string): ConversionResult;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Plugin } from 'unified';
|
|
2
|
+
import { Root as MdastRoot } from 'mdast';
|
|
3
|
+
import { Root } from 'xast';
|
|
4
|
+
/** Options for the remark-pretext plugin (currently none, reserved for future use). */
|
|
5
|
+
export interface RemarkPretextOptions {
|
|
6
|
+
}
|
|
7
|
+
declare const remarkPretext: Plugin<[RemarkPretextOptions?], MdastRoot, Root>;
|
|
8
|
+
export default remarkPretext;
|
|
9
|
+
export { mdastToPtxast } from './mdast-to-ptxast.js';
|
|
10
|
+
export { DIRECTIVE_MAP, PROOF_SOLUTION_NAMES } from './directive-map.js';
|
|
11
|
+
export type { DirectiveInfo, DirectiveCategory } from './directive-map.js';
|
package/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports = require('
|
|
1
|
+
module.exports = require('./dist/index.cjs');
|
package/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from "./dist/index.d.ts";
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from '
|
|
1
|
+
export * from './dist/index.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pretextbook/remark-pretext",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "remark plugin to transform markdown-style PreTeXt directives into ptxast",
|
|
5
5
|
"author": "Oscar Levin",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"*.cjs",
|
|
32
32
|
"*.d.ts",
|
|
33
33
|
"*.d.cts",
|
|
34
|
-
"
|
|
34
|
+
"dist",
|
|
35
35
|
"types"
|
|
36
36
|
],
|
|
37
37
|
"scripts": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"test": "vitest run"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@pretextbook/ptxast": "^0.0.
|
|
42
|
+
"@pretextbook/ptxast": "^0.0.3",
|
|
43
43
|
"@types/mdast": "^4.0.0",
|
|
44
44
|
"mdast-util-directive": "^3.0.0",
|
|
45
45
|
"remark-directive": "^4.0.0",
|