@pretextbook/import 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,3 +1,5 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./upload-BnRj1gU1.cjs"),h=require("./import-mode-CV7gCDzF.cjs"),Z=/\$(?![\s$])([^$\n]{1,200})\$/;function J(e){const n=Z.exec(e);if(!n)return!1;const o=n[1];return/[\\^_{}]/.test(o)||/^[A-Za-z]'?$/.test(o.trim())}const Q=[{pattern:/\\(?:begin|end)\{[a-zA-Z*]+\}/,weight:3},{pattern:/\\\[[\s\S]*?\\\]|\$\$[\s\S]*?\$\$/,weight:3},{pattern:/\\[a-zA-Z]+\s*\{/,weight:2},{pattern:/\\\([\s\S]*?\\\)/,weight:2},{pattern:/\\[a-zA-Z]+\b/,weight:1},{pattern:/\\(?:label|ref|eqref|cite)\b/,weight:2}],ee=[{pattern:/^#{1,6}\s+\S/m,weight:3},{pattern:/^\s*```/m,weight:3},{pattern:/^\s*[-*+]\s+\S/m,weight:2},{pattern:/^\s*\d+[.)]\s+\S/m,weight:2},{pattern:/\*\*[^\s*][^*]*\*\*/,weight:2},{pattern:/\[[^\]\n]+\]\([^)\s]+\)/,weight:2},{pattern:/^\s*>\s+\S/m,weight:2},{pattern:/(?:^|\s)_[^_\s][^_\n]*_(?:\s|[.,;:!?]|$)/,weight:1},{pattern:/`[^`\n]+`/,weight:1}],te=2;function D(e,n){return n.reduce((o,{pattern:r,weight:i})=>o+(r.test(e)?i:0),0)}function O(e){return{latex:D(e,Q)+(J(e)?2:0),markdown:D(e,ee)}}function ne(e){const n=e.trim();if(!n||n.startsWith("<"))return;const{latex:o,markdown:r}=O(n);if(!(Math.max(o,r)<te))return o>=r?"latex":"markdown"}const re={png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",pdf:"application/pdf",eps:"application/postscript",ps:"application/postscript",bmp:"image/bmp",tiff:"image/tiff",tif:"image/tiff",webp:"image/webp",ico:"image/vnd.microsoft.icon"};function oe(e){const n=e.split(".").pop()?.toLowerCase()??"";return re[n]??"application/octet-stream"}const I="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function ie(e){const n=e.length,o=[];for(let r=0;r<n;r+=3){const i=e[r],c=r+1<n,s=r+2<n,a=c?e[r+1]:0,l=s?e[r+2]:0;o.push(I[i>>2]),o.push(I[(i&3)<<4|a>>4]),o.push(c?I[(a&15)<<2|l>>6]:"="),o.push(s?I[l&63]:"=")}return o.join("")}function y(e){return{ref:e.ref,fileName:e.fileName,contentType:oe(e.fileName),data:ie(e.data)}}function C(e){return{ref:e.xmlId,source:e.content,sourceFormat:e.sourceFormat,isRoot:e.isRoot}}function $(e){return{title:e.title,docinfo:e.docinfo,documentKind:e.documentKind,divisions:e.divisions.map(C),assets:e.assets.map(y)}}function se(e){return{ref:e.ref,kind:"file",title:e.fileName,short_description:e.fileName,file:{filename:e.fileName,content_type:e.contentType,data:e.data}}}function N(e){return{title:e.title,docinfo:e.docinfo,document_type:e.documentKind,divisions_attributes:e.divisions.map(n=>({ref:n.ref,source:n.source,source_format:n.sourceFormat,is_root:n.isRoot})),assets_attributes:e.assets.map(se)}}function ae(e){return N($(e))}function ce(e,n){const{root:o,entries:r}=t.insertEntries(e,n),i=new Set(r.map(s=>s.xmlId)),c=e.divisions.filter(s=>!i.has(s.xmlId)&&!(n.unwrapRoot&&s.xmlId===o.xmlId));return{divisions:[...r,...c].map(C),assets:e.assets.map(y),placeholders:r.map(s=>`<plus:${s.type} ref="${s.xmlId}"/>`)}}const v={mainSourcePath:"source/main.ptx",publicationPath:"publication/publication.ptx",projectFilePath:"project.ptx",docinfoPath:"source/docinfo.ptx"};function k(e){return t.findAnyElement(e,"pretext")?e:`<pretext>
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./upload-BnRj1gU1.cjs"),h=require("./import-mode-CV7gCDzF.cjs"),ee=/\$(?![\s$])([^$\n]{1,200})\$/;function te(e){const n=ee.exec(e);if(!n)return!1;const r=n[1];return/[\\^_{}]/.test(r)||/^[A-Za-z]'?$/.test(r.trim())}const ne=[{pattern:/\\(?:begin|end)\{[a-zA-Z*]+\}/,weight:3},{pattern:/\\\[[\s\S]*?\\\]|\$\$[\s\S]*?\$\$/,weight:3},{pattern:/\\[a-zA-Z]+\s*\{/,weight:2},{pattern:/\\\([\s\S]*?\\\)/,weight:2},{pattern:/\\[a-zA-Z]+\b/,weight:1},{pattern:/\\(?:label|ref|eqref|cite)\b/,weight:2}],re=[{pattern:/^#{1,6}\s+\S/m,weight:3},{pattern:/^\s*```/m,weight:3},{pattern:/^\s*[-*+]\s+\S/m,weight:2},{pattern:/^\s*\d+[.)]\s+\S/m,weight:2},{pattern:/\*\*[^\s*][^*]*\*\*/,weight:2},{pattern:/\[[^\]\n]+\]\([^)\s]+\)/,weight:2},{pattern:/^\s*>\s+\S/m,weight:2},{pattern:/(?:^|\s)_[^_\s][^_\n]*_(?:\s|[.,;:!?]|$)/,weight:1},{pattern:/`[^`\n]+`/,weight:1}],oe=2;function D(e,n){return n.reduce((r,{pattern:o,weight:i})=>r+(o.test(e)?i:0),0)}function O(e){return{latex:D(e,ne)+(te(e)?2:0),markdown:D(e,re)}}function ie(e){const n=e.trim();if(!n||n.startsWith("<"))return;const{latex:r,markdown:o}=O(n);if(!(Math.max(r,o)<oe))return r>=o?"latex":"markdown"}const se={png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",pdf:"application/pdf",eps:"application/postscript",ps:"application/postscript",bmp:"image/bmp",tiff:"image/tiff",tif:"image/tiff",webp:"image/webp",ico:"image/vnd.microsoft.icon"};function ae(e){const n=e.split(".").pop()?.toLowerCase()??"";return se[n]??"application/octet-stream"}const S="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function ce(e){const n=e.length,r=[];for(let o=0;o<n;o+=3){const i=e[o],a=o+1<n,s=o+2<n,c=a?e[o+1]:0,l=s?e[o+2]:0;r.push(S[i>>2]),r.push(S[(i&3)<<4|c>>4]),r.push(a?S[(c&15)<<2|l>>6]:"="),r.push(s?S[l&63]:"=")}return r.join("")}function y(e){return{ref:e.ref,fileName:e.fileName,contentType:ae(e.fileName),data:ce(e.data)}}function $(e){return{ref:e.xmlId,source:e.content,sourceFormat:e.sourceFormat,isRoot:e.isRoot}}function N(e){return{title:e.title,docinfo:e.docinfo,documentKind:e.documentKind,divisions:e.divisions.map($),assets:e.assets.map(y)}}function le(e){return{ref:e.ref,kind:"file",title:e.fileName,short_description:e.fileName,file:{filename:e.fileName,content_type:e.contentType,data:e.data}}}function k(e){return{title:e.title,docinfo:e.docinfo,document_type:e.documentKind,divisions_attributes:e.divisions.map(n=>({ref:n.ref,source:n.source,source_format:n.sourceFormat,is_root:n.isRoot})),assets_attributes:e.assets.map(le)}}function de(e){return k(N(e))}function ue(e,n){const{root:r,entries:o}=t.insertEntries(e,n),i=new Set(o.map(s=>s.xmlId)),a=e.divisions.filter(s=>!i.has(s.xmlId)&&!(n.unwrapRoot&&s.xmlId===r.xmlId));return{divisions:[...o,...a].map($),assets:e.assets.map(y),placeholders:o.map(s=>`<plus:${s.type} ref="${s.xmlId}"/>`)}}const R=/<(\/?)p(?=[\s>/])/g;function pe(e){let n=0;R.lastIndex=0;let r;for(;(r=R.exec(e))!==null;)n+=r[1]?-1:1;return n>0}const me=new RegExp(`<(${t.PRETEXT_DIVISION_TAGS.join("|")})(?=[\\s>/])`);function j(e){return me.exec(e)?.[1]}function X(e,n,r){return e.split(`
2
+ `).map((o,i)=>i===0&&r?o:o&&n+o).join(`
3
+ `)}function fe(e,n){let r=e.trim(),o;if(n.inline){const i=r.replace(/^<p>\s*([\s\S]*?)\s*<\/p>$/,"$1");r=i!==r?i:r.replace(/^<p>/,"");const a=j(r);a&&(o=`Pasted content produced a <${a}>, which cannot sit inside a <p>. It was inserted as-is — move it out of the paragraph to make the document valid.`)}return n.baseIndent&&(r=X(r,n.baseIndent,n.midLine)),{markup:r,warning:o}}const v={mainSourcePath:"source/main.ptx",publicationPath:"publication/publication.ptx",projectFilePath:"project.ptx",docinfoPath:"source/docinfo.ptx"};function z(e){return t.findAnyElement(e,"pretext")?e:`<pretext>
2
4
  ${e}
3
- </pretext>`}function j(e,n,o){const r=new Map,i=[],c=`${n}-`;return e.forEach((s,a)=>{const l=s.attributes["xml:id"];let d;if(l){const f=t.slugify(l);d=f.startsWith(c)?f:`${c}${f}`}else d=`${c}${t.padIndex(a+1,e.length)}`,o.push({action:"anomaly",severity:"info",kind:"structure",category:"missing_xml_id",macro:s.name,occurrences:1,message:`<${s.name}> at position ${a+1} has no xml:id; using \`${d}\` as filename.`});const p=r.get(d)??0;r.set(d,p+1);const u=p===0?d:`${d}-${p+1}`;i.push({span:s,slug:u,filename:`${u}.ptx`})}),i}function le(e,n,o,r){const i=t.findTopLevelElements(e,"section");if(i.length===0)return e;const s=j(i,"sec",r).map(a=>{const l=`source/${n}/${a.filename}`;return o[l]=t.withProlog(a.span.outer),{start:a.span.start,end:a.span.end,replacement:`<xi:include href="${n}/${a.filename}"/>`}});return t.spliceReplacements(e,s)}function de(e,n,o){const r=t.findAnyElement(e,"book");if(!r)return o.push({action:"anomaly",severity:"warning",kind:"structure",category:"missing_root",macro:"book",occurrences:1,message:"Document was treated as a book but no <book> element found; emitting as a single file."}),z(e,n);const i={},c=t.findTopLevelElements(r.inner,"chapter");let s=r.inner;if(n.splitChapters&&c.length>0){const p=j(c,"ch",o).map(u=>{let f=u.span.outer;if(n.splitSections){const m=u.span.inner,g=le(m,u.slug,i,o);f=u.span.outer.slice(0,u.span.startTagEnd-u.span.start)+g+u.span.outer.slice(u.span.contentEnd-u.span.start)}const P=`source/${u.filename}`;return i[P]=t.withProlog(f),{start:u.span.start,end:u.span.end,replacement:`<xi:include href="${u.filename}"/>`}});s=t.spliceReplacements(r.inner,p)}const a=e.slice(r.start,r.startTagEnd)+s+e.slice(r.contentEnd,r.end),l=e.slice(0,r.start)+a+e.slice(r.end);return i[n.mainSourcePath]=t.withProlog(t.ensureXIncludeNamespace(k(l.trim()))),i}function z(e,n,o){const r={};return r[n.mainSourcePath]=t.withProlog(k(e.trim())),r}function ue(e,n={}){const o=[],r=n.documentKind??t.detectDocumentKind(e),i={splitChapters:n.splitChapters??r==="book",splitSections:n.splitSections??!1,mainSourcePath:n.mainSourcePath??v.mainSourcePath,publicationPath:n.publicationPath??v.publicationPath,projectFilePath:n.projectFilePath??v.projectFilePath,docinfoPath:n.docinfoPath??v.docinfoPath},c=r==="book"?de(e,i,o):z(e,i);return c[i.projectFilePath]=t.renderProjectPtx({mainSource:i.mainSourcePath,publication:i.publicationPath}),c[i.publicationPath]=t.renderPublicationPtx(),{files:c,documentKind:r,warnings:o}}class X extends Error{constructor(){super("Import cancelled."),this.name="ConversionCancelledError"}}let pe=0;function U(e,n,o={}){const r=`convert-${pe++}`,i=e(),{assets:c={},...s}=o;let a;const l=new Promise((p,u)=>{let f=!1;const P=m=>{f||(f=!0,i.terminate(),m())};a=()=>P(()=>u(new X)),i.addEventListener("message",m=>{const g=m.data;if(!(!g||g.requestId!==r)){if(g.type==="result"){P(()=>p(g.result));return}P(()=>u(new Error(g.message)))}}),i.addEventListener("error",m=>{const g=typeof m=="object"&&m&&"message"in m?String(m.message):"The import worker failed to start.";P(()=>u(new Error(g)))})}),d=[...new Set(Object.values(c).map(p=>p.buffer).filter(p=>p instanceof ArrayBuffer))];return i.postMessage({type:"convert",requestId:r,files:n,assets:c,options:s},d),{result:l,cancel:()=>a?.()}}function me(e){const{createWorker:n,id:o="worker",label:r="Built-in converter",description:i="Create a new project starting with LaTeX, Markdown, or PreTeXt files.",acceptExtensions:c}=e;let s=null;const a=async(l,d)=>{s?.cancel(),s=U(n,l,d);try{return await s.result}finally{s=null}};return{id:o,label:r,description:i,acceptExtensions:c,prepare:async l=>{const{files:d,assets:p}=await t.extractUpload(l);return{fileName:l.name,files:d,assets:p,analysis:t.analyzeImportSources(d)}},convertPrepared:(l,d)=>a(l.files,{...d,assets:l.assets}),convertFile:async(l,d)=>{const{files:p,assets:u}=await t.extractUpload(l);return a(p,{...d,assets:u})},cancel:()=>{s?.cancel(),s=null}}}const W={".docx":"docx",".odt":"odt",".epub":"epub",".tex":"latex",".ltx":"latex",".md":"markdown",".markdown":"markdown",".html":"html",".htm":"html",".rst":"rst",".org":"org",".ipynb":"ipynb",".typ":"typst",".xml":"docbook",".textile":"textile"},fe=new Set(["docx","odt","epub"]),w=[".docx",".odt",".epub",".html",".htm",".rst",".org",".ipynb",".typ",".textile",".tex",".ltx",".md",".markdown"];function F(e){const n=e.lastIndexOf(".");return n<=0?"":e.slice(n).toLowerCase()}function K(e){return W[F(e)]}function B(e){const{convertToPretext:n,id:o="pandoc",label:r="Pandoc",description:i="Convert Word, OpenOffice, EPUB, HTML, reStructuredText, and more.",acceptExtensions:c=w}=e;return{id:o,label:r,description:i,acceptExtensions:c,convertFile:async(s,a)=>{const l=await n(s,a);if(!l.trim())throw new Error(`Pandoc produced no output for ${s.name}. The file may be empty or in an unexpected format.`);const d=t.importProjectFromFiles({"source.ptx":l},{documentKind:a.documentKind,splitChapters:a.splitChapters,splitSections:a.splitSections,splitLevel:a.splitLevel});return"pretextError"in d||(d.sourceName=s.name,d.sourcePath=s.name),d}}}const H=3e4;function G(e){const n=/<pre>([\s\S]*?)<\/pre>/i.exec(e);return(n?n[1]:e).replace(/<[^>]+>/g,"").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#39;/g,"'").replace(/&amp;/g,"&").trim()}function V(e,n,o){const r=he(G(n)),i=r?` (${M(r)})`:"";switch(e){case 400:return`The pandoc server will not convert ${o}${i}.${E(o)}`;case 401:case 403:return`The pandoc server rejected this site's credentials, so ${o} was never converted. Nothing is wrong with your file — this is a configuration problem with the service, and worth reporting.${E(o)}`;case 404:return`The pandoc conversion service could not be found at the address this site is configured to use. Nothing is wrong with your file — this is a configuration problem worth reporting.${E(o)}`;case 413:return`${o} is too large for the pandoc server to accept. Splitting it into chapters and importing them one at a time should get through.`;case 422:return`Pandoc could not read ${o}${i}. The file may be damaged, or may use features pandoc does not support.`;case 503:return`The pandoc server is running without its PreTeXt writer, so it cannot convert anything right now. Nothing is wrong with your file — this is a problem with the service, and worth reporting.${E(o)}`;case 504:return`Converting ${o} took longer than the pandoc server allows. Splitting it into chapters and importing them one at a time usually works.`;default:{const c=r?`(HTTP ${e}: ${M(r)})`:`(HTTP ${e})`;return`The pandoc server could not convert ${o} ${c}.${E(o)}`}}}const R=300;function he(e){return e.replace(/\s+/g," ").trim()}function M(e){return e.length<=R?e:`${e.slice(0,R).trimEnd()}…`}const ge=new Set([".tex",".ltx",".md",".markdown"]);function E(e){return ge.has(F(e))?" You can import this file with the built-in converter instead.":""}function Pe(e){const{url:n,token:o,headers:r,credentials:i,standalone:c=!0,from:s,timeoutMs:a=H,fetchImpl:l,id:d="pandoc-remote",label:p="Pandoc (server)",description:u="Convert Word, OpenOffice, EPUB, HTML, reStructuredText, and more — no local install needed.",acceptExtensions:f=w}=e;return B({convertToPretext:async(m,g)=>{const _=l??globalThis.fetch;if(typeof _!="function")throw new Error("This environment has no fetch; pass fetchImpl to createRemotePandocEngine.");const A=s??K(m.name);if(!A)throw new Error(`Pandoc cannot determine a format for ${m.name}. Supported extensions: ${f.join(", ")}.`);const T=new FormData;o&&T.set("token",o),T.set("file",m,m.name),T.set("from",A),c&&T.set("standalone","yes");const L=new AbortController,q=setTimeout(()=>L.abort(),a);let S;try{S=await _(n,{method:"POST",body:T,headers:r,credentials:i,signal:L.signal})}catch(x){if(x instanceof Error&&x.name==="AbortError")throw new Error(`Pandoc conversion of ${m.name} timed out after ${Math.round(a/1e3)}s.`);const Y=x instanceof Error?x.message:String(x);throw new Error(`Could not reach the pandoc server: ${Y}`)}finally{clearTimeout(q)}const b=await S.text();if(!S.ok)throw new Error(V(S.status,b,m.name));return b},id:d,label:p,description:u,acceptExtensions:f})}exports.CLEAN_RULES=t.CLEAN_RULES;exports.DIVISION_LADDER=t.DIVISION_LADDER;exports.LADDER_OVERFLOW_TAG=t.LADDER_OVERFLOW_TAG;exports.LATEX_DIVISION_COMMANDS=t.LATEX_DIVISION_COMMANDS;exports.LATEX_FORMAT_MARKERS=t.LATEX_FORMAT_MARKERS;exports.MARKDOWN_FORMAT_MARKERS=t.MARKDOWN_FORMAT_MARKERS;exports.MAX_SUGGESTED_SPLIT_LEVEL=t.MAX_SUGGESTED_SPLIT_LEVEL;exports.PRETEXT_DIVISION_TAGS=t.PRETEXT_DIVISION_TAGS;exports.PRETEXT_ROOT_TAGS=t.PRETEXT_ROOT_TAGS;exports.PROJECT_DESTINATION=t.PROJECT_DESTINATION;exports.analyzeImportSources=t.analyzeImportSources;exports.applyLatexFixes=t.applyLatexFixes;exports.attachLatexRoots=t.attachLatexRoots;exports.attachMarkdownRoots=t.attachMarkdownRoots;exports.buildDivisionPool=t.buildDivisionPool;exports.buildNativeDivisionPool=t.buildNativeDivisionPool;exports.carryOverProjectFiles=t.carryOverProjectFiles;exports.cleanLatex=t.cleanLatex;exports.cleanLatexInChunks=t.cleanLatexInChunks;exports.cleanLatexText=t.cleanLatexText;exports.convertLatexToPretext=t.convertLatexToPretext;exports.convertMarkdownToPretext=t.convertMarkdownToPretext;exports.convertSourceToPretext=t.convertSourceToPretext;exports.dedupeXmlIds=t.dedupeXmlIds;exports.defaultAttachLevel=t.defaultAttachLevel;exports.defaultManifestTarget=t.defaultManifestTarget;exports.detectDocumentKind=t.detectDocumentKind;exports.detectSourceFormat=t.detectSourceFormat;exports.divisionChildRefs=t.divisionChildRefs;exports.divisionsAtLevel=t.divisionsAtLevel;exports.expandPretextIncludes=t.expandPretextIncludes;exports.extractUpload=t.extractUpload;exports.filePrefixForDivision=t.filePrefixForDivision;exports.findLatexFixes=t.findLatexFixes;exports.findLatexHeaders=t.findLatexHeaders;exports.findProjectManifest=t.findProjectManifest;exports.fixesToWarnings=t.fixesToWarnings;exports.getConversionErrorMessage=t.getConversionErrorMessage;exports.getLatexCleanDiagnostics=t.getLatexCleanDiagnostics;exports.handleImportUploadFile=t.handleImportUploadFile;exports.importProjectFromFiles=t.importProjectFromFiles;exports.isDivisionTag=t.isDivisionTag;exports.ladderDepth=t.ladderDepth;exports.latexDivisionHierarchy=t.latexDivisionHierarchy;exports.latexFixesToCodeActions=t.latexFixesToCodeActions;exports.mergeChunksAtLevel=t.mergeChunksAtLevel;exports.normalizePretextSource=t.normalizePretextSource;exports.outlineDivisions=t.outlineDivisions;exports.parseLatexDivisions=t.parseLatexDivisions;exports.parseProjectManifest=t.parseProjectManifest;exports.prepareInsertSource=t.prepareInsertSource;exports.pruneDivisions=t.pruneDivisions;exports.rebuildImport=t.rebuildImport;exports.relayoutImport=t.relayoutImport;exports.renderProjectPtx=t.renderProjectPtx;exports.renderProjectPtxFromManifest=t.renderProjectPtxFromManifest;exports.renderPublicationPtx=t.renderPublicationPtx;exports.reselectImport=t.reselectImport;exports.resolveImportSplitLevel=t.resolveImportSplitLevel;exports.resolveSplitLevel=t.resolveSplitLevel;exports.retargetFragment=t.retargetFragment;exports.retargetFragmentToDepth=t.retargetFragmentToDepth;exports.retargetImport=t.retargetImport;exports.sanitizeRef=t.sanitizeRef;exports.serializeForDestination=t.serializeForDestination;exports.serializeInsertFiles=t.serializeInsertFiles;exports.serializeProjectToFiles=t.serializeProjectToFiles;exports.shiftLadderTag=t.shiftLadderTag;exports.suggestSplitLevel=t.suggestSplitLevel;exports.DEFAULT_IMPORT_MODE=h.DEFAULT_IMPORT_MODE;exports.assetsForImportMode=h.assetsForImportMode;exports.diffHunks=h.diffHunks;exports.diffLines=h.diffLines;exports.diffStats=h.diffStats;exports.fileChangesForImport=h.fileChangesForImport;exports.filesForImportMode=h.filesForImportMode;exports.formatWarningLine=h.formatWarningLine;exports.hasNativeImportMode=h.hasNativeImportMode;exports.projectForImportMode=h.projectForImportMode;exports.resolveImportMode=h.resolveImportMode;exports.ConversionCancelledError=X;exports.DEFAULT_REMOTE_PANDOC_TIMEOUT_MS=H;exports.PANDOC_ACCEPT_EXTENSIONS=w;exports.PANDOC_BINARY_FORMATS=fe;exports.PANDOC_EXTENSION_FORMATS=W;exports.buildPretextProjectFiles=ue;exports.createPandocEngine=B;exports.createRemotePandocEngine=Pe;exports.createWorkerEngine=me;exports.describeRemotePandocFailure=V;exports.detectSnippetFormat=ne;exports.extractPandocErrorDetail=G;exports.fileExtension=F;exports.pandocFormatForFileName=K;exports.recordsToPlusPayload=N;exports.runConversionInWorker=U;exports.scoreSnippetFormats=O;exports.serializeInsertToRecords=ce;exports.serializeProjectToPlusPayload=ae;exports.serializeProjectToRecords=$;
5
+ </pretext>`}function U(e,n,r){const o=new Map,i=[],a=`${n}-`;return e.forEach((s,c)=>{const l=s.attributes["xml:id"];let d;if(l){const f=t.slugify(l);d=f.startsWith(a)?f:`${a}${f}`}else d=`${a}${t.padIndex(c+1,e.length)}`,r.push({action:"anomaly",severity:"info",kind:"structure",category:"missing_xml_id",macro:s.name,occurrences:1,message:`<${s.name}> at position ${c+1} has no xml:id; using \`${d}\` as filename.`});const p=o.get(d)??0;o.set(d,p+1);const u=p===0?d:`${d}-${p+1}`;i.push({span:s,slug:u,filename:`${u}.ptx`})}),i}function he(e,n,r,o){const i=t.findTopLevelElements(e,"section");if(i.length===0)return e;const s=U(i,"sec",o).map(c=>{const l=`source/${n}/${c.filename}`;return r[l]=t.withProlog(c.span.outer),{start:c.span.start,end:c.span.end,replacement:`<xi:include href="${n}/${c.filename}"/>`}});return t.spliceReplacements(e,s)}function ge(e,n,r){const o=t.findAnyElement(e,"book");if(!o)return r.push({action:"anomaly",severity:"warning",kind:"structure",category:"missing_root",macro:"book",occurrences:1,message:"Document was treated as a book but no <book> element found; emitting as a single file."}),W(e,n);const i={},a=t.findTopLevelElements(o.inner,"chapter");let s=o.inner;if(n.splitChapters&&a.length>0){const p=U(a,"ch",r).map(u=>{let f=u.span.outer;if(n.splitSections){const m=u.span.inner,g=he(m,u.slug,i,r);f=u.span.outer.slice(0,u.span.startTagEnd-u.span.start)+g+u.span.outer.slice(u.span.contentEnd-u.span.start)}const T=`source/${u.filename}`;return i[T]=t.withProlog(f),{start:u.span.start,end:u.span.end,replacement:`<xi:include href="${u.filename}"/>`}});s=t.spliceReplacements(o.inner,p)}const c=e.slice(o.start,o.startTagEnd)+s+e.slice(o.contentEnd,o.end),l=e.slice(0,o.start)+c+e.slice(o.end);return i[n.mainSourcePath]=t.withProlog(t.ensureXIncludeNamespace(z(l.trim()))),i}function W(e,n,r){const o={};return o[n.mainSourcePath]=t.withProlog(z(e.trim())),o}function Te(e,n={}){const r=[],o=n.documentKind??t.detectDocumentKind(e),i={splitChapters:n.splitChapters??o==="book",splitSections:n.splitSections??!1,mainSourcePath:n.mainSourcePath??v.mainSourcePath,publicationPath:n.publicationPath??v.publicationPath,projectFilePath:n.projectFilePath??v.projectFilePath,docinfoPath:n.docinfoPath??v.docinfoPath},a=o==="book"?ge(e,i,r):W(e,i);return a[i.projectFilePath]=t.renderProjectPtx({mainSource:i.mainSourcePath,publication:i.publicationPath}),a[i.publicationPath]=t.renderPublicationPtx(),{files:a,documentKind:o,warnings:r}}class K extends Error{constructor(){super("Import cancelled."),this.name="ConversionCancelledError"}}let Pe=0;function G(e,n,r={}){const o=`convert-${Pe++}`,i=e(),{assets:a={},...s}=r;let c;const l=new Promise((p,u)=>{let f=!1;const T=m=>{f||(f=!0,i.terminate(),m())};c=()=>T(()=>u(new K)),i.addEventListener("message",m=>{const g=m.data;if(!(!g||g.requestId!==o)){if(g.type==="result"){T(()=>p(g.result));return}T(()=>u(new Error(g.message)))}}),i.addEventListener("error",m=>{const g=typeof m=="object"&&m&&"message"in m?String(m.message):"The import worker failed to start.";T(()=>u(new Error(g)))})}),d=[...new Set(Object.values(a).map(p=>p.buffer).filter(p=>p instanceof ArrayBuffer))];return i.postMessage({type:"convert",requestId:o,files:n,assets:a,options:s},d),{result:l,cancel:()=>c?.()}}function xe(e){const{createWorker:n,id:r="worker",label:o="Built-in converter",description:i="Create a new project starting with LaTeX, Markdown, or PreTeXt files.",acceptExtensions:a}=e;let s=null;const c=async(l,d)=>{s?.cancel(),s=G(n,l,d);try{return await s.result}finally{s=null}};return{id:r,label:o,description:i,acceptExtensions:a,prepare:async l=>{const{files:d,assets:p}=await t.extractUpload(l);return{fileName:l.name,files:d,assets:p,analysis:t.analyzeImportSources(d)}},convertPrepared:(l,d)=>c(l.files,{...d,assets:l.assets}),convertFile:async(l,d)=>{const{files:p,assets:u}=await t.extractUpload(l);return c(p,{...d,assets:u})},cancel:()=>{s?.cancel(),s=null}}}const B={".docx":"docx",".odt":"odt",".epub":"epub",".tex":"latex",".ltx":"latex",".md":"markdown",".markdown":"markdown",".html":"html",".htm":"html",".rst":"rst",".org":"org",".ipynb":"ipynb",".typ":"typst",".xml":"docbook",".textile":"textile"},Ee=new Set(["docx","odt","epub"]),w=[".docx",".odt",".epub",".html",".htm",".rst",".org",".ipynb",".typ",".textile",".tex",".ltx",".md",".markdown"];function _(e){const n=e.lastIndexOf(".");return n<=0?"":e.slice(n).toLowerCase()}function H(e){return B[_(e)]}function V(e){const{convertToPretext:n,id:r="pandoc",label:o="Pandoc",description:i="Convert Word, OpenOffice, EPUB, HTML, reStructuredText, and more.",acceptExtensions:a=w}=e;return{id:r,label:o,description:i,acceptExtensions:a,convertFile:async(s,c)=>{const l=await n(s,c);if(!l.trim())throw new Error(`Pandoc produced no output for ${s.name}. The file may be empty or in an unexpected format.`);const d=t.importProjectFromFiles({"source.ptx":l},{documentKind:c.documentKind,splitChapters:c.splitChapters,splitSections:c.splitSections,splitLevel:c.splitLevel});return"pretextError"in d||(d.sourceName=s.name,d.sourcePath=s.name),d}}}const q=3e4;function Y(e){const n=/<pre>([\s\S]*?)<\/pre>/i.exec(e);return(n?n[1]:e).replace(/<[^>]+>/g,"").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#39;/g,"'").replace(/&amp;/g,"&").trim()}function Z(e,n,r){const o=Ie(Y(n)),i=o?` (${C(o)})`:"";switch(e){case 400:return`The pandoc server will not convert ${r}${i}.${E(r)}`;case 401:case 403:return`The pandoc server rejected this site's credentials, so ${r} was never converted. Nothing is wrong with your file — this is a configuration problem with the service, and worth reporting.${E(r)}`;case 404:return`The pandoc conversion service could not be found at the address this site is configured to use. Nothing is wrong with your file — this is a configuration problem worth reporting.${E(r)}`;case 413:return`${r} is too large for the pandoc server to accept. Splitting it into chapters and importing them one at a time should get through.`;case 422:return`Pandoc could not read ${r}${i}. The file may be damaged, or may use features pandoc does not support.`;case 503:return`The pandoc server is running without its PreTeXt writer, so it cannot convert anything right now. Nothing is wrong with your file — this is a problem with the service, and worth reporting.${E(r)}`;case 504:return`Converting ${r} took longer than the pandoc server allows. Splitting it into chapters and importing them one at a time usually works.`;default:{const a=o?`(HTTP ${e}: ${C(o)})`:`(HTTP ${e})`;return`The pandoc server could not convert ${r} ${a}.${E(r)}`}}}const M=300;function Ie(e){return e.replace(/\s+/g," ").trim()}function C(e){return e.length<=M?e:`${e.slice(0,M).trimEnd()}…`}const Se=new Set([".tex",".ltx",".md",".markdown"]);function E(e){return Se.has(_(e))?" You can import this file with the built-in converter instead.":""}function ve(e){const{url:n,token:r,headers:o,credentials:i,standalone:a=!0,from:s,timeoutMs:c=q,fetchImpl:l,id:d="pandoc-remote",label:p="Pandoc (server)",description:u="Convert Word, OpenOffice, EPUB, HTML, reStructuredText, and more — no local install needed.",acceptExtensions:f=w}=e;return V({convertToPretext:async(m,g)=>{const F=l??globalThis.fetch;if(typeof F!="function")throw new Error("This environment has no fetch; pass fetchImpl to createRemotePandocEngine.");const A=s??H(m.name);if(!A)throw new Error(`Pandoc cannot determine a format for ${m.name}. Supported extensions: ${f.join(", ")}.`);const P=new FormData;r&&P.set("token",r),P.set("file",m,m.name),P.set("from",A),a&&P.set("standalone","yes");const L=new AbortController,J=setTimeout(()=>L.abort(),c);let I;try{I=await F(n,{method:"POST",body:P,headers:o,credentials:i,signal:L.signal})}catch(x){if(x instanceof Error&&x.name==="AbortError")throw new Error(`Pandoc conversion of ${m.name} timed out after ${Math.round(c/1e3)}s.`);const Q=x instanceof Error?x.message:String(x);throw new Error(`Could not reach the pandoc server: ${Q}`)}finally{clearTimeout(J)}const b=await I.text();if(!I.ok)throw new Error(Z(I.status,b,m.name));return b},id:d,label:p,description:u,acceptExtensions:f})}exports.CLEAN_RULES=t.CLEAN_RULES;exports.DIVISION_LADDER=t.DIVISION_LADDER;exports.LADDER_OVERFLOW_TAG=t.LADDER_OVERFLOW_TAG;exports.LATEX_DIVISION_COMMANDS=t.LATEX_DIVISION_COMMANDS;exports.LATEX_FORMAT_MARKERS=t.LATEX_FORMAT_MARKERS;exports.MARKDOWN_FORMAT_MARKERS=t.MARKDOWN_FORMAT_MARKERS;exports.MAX_SUGGESTED_SPLIT_LEVEL=t.MAX_SUGGESTED_SPLIT_LEVEL;exports.PRETEXT_DIVISION_TAGS=t.PRETEXT_DIVISION_TAGS;exports.PRETEXT_ROOT_TAGS=t.PRETEXT_ROOT_TAGS;exports.PROJECT_DESTINATION=t.PROJECT_DESTINATION;exports.analyzeImportSources=t.analyzeImportSources;exports.applyLatexFixes=t.applyLatexFixes;exports.attachLatexRoots=t.attachLatexRoots;exports.attachMarkdownRoots=t.attachMarkdownRoots;exports.buildDivisionPool=t.buildDivisionPool;exports.buildNativeDivisionPool=t.buildNativeDivisionPool;exports.carryOverProjectFiles=t.carryOverProjectFiles;exports.cleanLatex=t.cleanLatex;exports.cleanLatexInChunks=t.cleanLatexInChunks;exports.cleanLatexText=t.cleanLatexText;exports.convertLatexToPretext=t.convertLatexToPretext;exports.convertMarkdownToPretext=t.convertMarkdownToPretext;exports.convertSourceToPretext=t.convertSourceToPretext;exports.dedupeXmlIds=t.dedupeXmlIds;exports.defaultAttachLevel=t.defaultAttachLevel;exports.defaultManifestTarget=t.defaultManifestTarget;exports.detectDocumentKind=t.detectDocumentKind;exports.detectSourceFormat=t.detectSourceFormat;exports.divisionChildRefs=t.divisionChildRefs;exports.divisionsAtLevel=t.divisionsAtLevel;exports.expandPretextIncludes=t.expandPretextIncludes;exports.extractUpload=t.extractUpload;exports.filePrefixForDivision=t.filePrefixForDivision;exports.findLatexFixes=t.findLatexFixes;exports.findLatexHeaders=t.findLatexHeaders;exports.findProjectManifest=t.findProjectManifest;exports.fixesToWarnings=t.fixesToWarnings;exports.getConversionErrorMessage=t.getConversionErrorMessage;exports.getLatexCleanDiagnostics=t.getLatexCleanDiagnostics;exports.handleImportUploadFile=t.handleImportUploadFile;exports.importProjectFromFiles=t.importProjectFromFiles;exports.isDivisionTag=t.isDivisionTag;exports.ladderDepth=t.ladderDepth;exports.latexDivisionHierarchy=t.latexDivisionHierarchy;exports.latexFixesToCodeActions=t.latexFixesToCodeActions;exports.mergeChunksAtLevel=t.mergeChunksAtLevel;exports.normalizePretextSource=t.normalizePretextSource;exports.outlineDivisions=t.outlineDivisions;exports.parseLatexDivisions=t.parseLatexDivisions;exports.parseProjectManifest=t.parseProjectManifest;exports.prepareInsertSource=t.prepareInsertSource;exports.pruneDivisions=t.pruneDivisions;exports.rebuildImport=t.rebuildImport;exports.relayoutImport=t.relayoutImport;exports.renderProjectPtx=t.renderProjectPtx;exports.renderProjectPtxFromManifest=t.renderProjectPtxFromManifest;exports.renderPublicationPtx=t.renderPublicationPtx;exports.reselectImport=t.reselectImport;exports.resolveImportSplitLevel=t.resolveImportSplitLevel;exports.resolveSplitLevel=t.resolveSplitLevel;exports.retargetFragment=t.retargetFragment;exports.retargetFragmentToDepth=t.retargetFragmentToDepth;exports.retargetImport=t.retargetImport;exports.sanitizeRef=t.sanitizeRef;exports.serializeForDestination=t.serializeForDestination;exports.serializeInsertFiles=t.serializeInsertFiles;exports.serializeProjectToFiles=t.serializeProjectToFiles;exports.shiftLadderTag=t.shiftLadderTag;exports.suggestSplitLevel=t.suggestSplitLevel;exports.DEFAULT_IMPORT_MODE=h.DEFAULT_IMPORT_MODE;exports.assetsForImportMode=h.assetsForImportMode;exports.diffHunks=h.diffHunks;exports.diffLines=h.diffLines;exports.diffStats=h.diffStats;exports.fileChangesForImport=h.fileChangesForImport;exports.filesForImportMode=h.filesForImportMode;exports.formatWarningLine=h.formatWarningLine;exports.hasNativeImportMode=h.hasNativeImportMode;exports.projectForImportMode=h.projectForImportMode;exports.resolveImportMode=h.resolveImportMode;exports.ConversionCancelledError=K;exports.DEFAULT_REMOTE_PANDOC_TIMEOUT_MS=q;exports.PANDOC_ACCEPT_EXTENSIONS=w;exports.PANDOC_BINARY_FORMATS=Ee;exports.PANDOC_EXTENSION_FORMATS=B;exports.buildPretextProjectFiles=Te;exports.createPandocEngine=V;exports.createRemotePandocEngine=ve;exports.createWorkerEngine=xe;exports.describeRemotePandocFailure=Z;exports.detectSnippetFormat=ie;exports.extractPandocErrorDetail=Y;exports.fileExtension=_;exports.firstDivisionTag=j;exports.isInlineContext=pe;exports.pandocFormatForFileName=H;exports.placeConvertedMarkup=fe;exports.recordsToPlusPayload=k;exports.reindentForContext=X;exports.runConversionInWorker=G;exports.scoreSnippetFormats=O;exports.serializeInsertToRecords=ue;exports.serializeProjectToPlusPayload=de;exports.serializeProjectToRecords=N;
package/dist/index.d.ts CHANGED
@@ -12,6 +12,7 @@ export { attachLatexRoots, attachMarkdownRoots, defaultAttachLevel, type AttachL
12
12
  export { defaultManifestTarget, findProjectManifest, parseProjectManifest, type ManifestTarget, type ProjectManifest, } from './lib/project/manifest';
13
13
  export { carryOverProjectFiles, renderProjectPtxFromManifest, type CarryOverOptions, type CarryOverResult, } from './lib/project/existing-project';
14
14
  export { DIVISION_LADDER, LADDER_OVERFLOW_TAG, PRETEXT_DIVISION_TAGS, PRETEXT_ROOT_TAGS, filePrefixForDivision, isDivisionTag, ladderDepth, shiftLadderTag, type LadderTag, type PretextDivisionTag, type PretextRootTag, } from './lib/pretext-divisions';
15
+ export { firstDivisionTag, isInlineContext, placeConvertedMarkup, reindentForContext, type PlacedMarkup, type PlacementContext, } from './lib/paste/place-markup';
15
16
  export { outlineDivisions, pruneDivisions, type DivisionOutlineItem, type DivisionPath, type PruneDivisionsResult, } from './lib/select/divisions';
16
17
  export { retargetFragment, retargetFragmentToDepth, dedupeXmlIds, prepareInsertSource, PROJECT_DESTINATION, type ImportDestination, type ProjectDestination, type InsertDestination, type PreparedInsertSource, type RetargetFragmentResult, type DedupeXmlIdsOptions, type DedupeXmlIdsResult, type IdRenameContext, type XmlIdRename, } from './lib/insert';
17
18
  export { DEFAULT_IMPORT_MODE, filesForImportMode, assetsForImportMode, hasNativeImportMode, projectForImportMode, resolveImportMode, formatWarningLine, type ImportMode, } from './lib/import-mode';
package/dist/index.js CHANGED
@@ -1,15 +1,15 @@
1
- import { i as K, d as W, r as H, a as U, f as y, b as C, w as S, s as R, e as G, c as q, p as V, g as $, h as Z, j as Y } from "./upload-H_OCZBBn.js";
2
- import { C as Re, D as ke, L as De, k as Me, l as Oe, M as Ne, m as je, P as Xe, n as ze, o as Be, q as Ke, t as We, u as He, v as Ue, x as Ge, y as qe, z as Ve, A as Ze, B as Ye, E as Je, F as Qe, G as et, H as tt, I as nt, J as rt, K as ot, N as st, O as at, Q as it, R as ct, S as lt, T as ut, U as pt, V as dt, W as mt, X as ft, Y as ht, Z as gt, _ as wt, $ as xt, a0 as Tt, a1 as Pt, a2 as Et, a3 as St, a4 as bt, a5 as vt, a6 as It, a7 as _t, a8 as $t, a9 as At, aa as Ft, ab as Lt, ac as yt, ad as Ct, ae as Rt, af as kt, ag as Dt, ah as Mt, ai as Ot, aj as Nt, ak as jt, al as Xt, am as zt } from "./upload-H_OCZBBn.js";
3
- import { D as Kt, a as Wt, d as Ht, b as Ut, c as Gt, f as qt, e as Vt, g as Zt, h as Yt, p as Jt, r as Qt } from "./import-mode-DQ8g5P8P.js";
4
- const J = /\$(?![\s$])([^$\n]{1,200})\$/;
5
- function Q(e) {
6
- const t = J.exec(e);
1
+ import { i as W, P as H, d as U, r as G, a as V, f as C, b as R, w as v, s as k, e as q, c as Z, p as Y, g as $, h as J, j as Q } from "./upload-H_OCZBBn.js";
2
+ import { C as Xe, D as ze, L as Be, k as Ke, l as We, M as He, m as Ue, n as Ge, o as Ve, q as qe, t as Ze, u as Ye, v as Je, x as Qe, y as et, z as tt, A as nt, B as rt, E as ot, F as st, G as at, H as it, I as ct, J as lt, K as ut, N as pt, O as dt, Q as mt, R as ft, S as ht, T as gt, U as wt, V as Tt, W as xt, X as Pt, Y as Et, Z as vt, _ as St, $ as bt, a0 as It, a1 as _t, a2 as $t, a3 as At, a4 as Ft, a5 as Lt, a6 as yt, a7 as Ct, a8 as Rt, a9 as kt, aa as Dt, ab as Mt, ac as Ot, ad as Nt, ae as jt, af as Xt, ag as zt, ah as Bt, ai as Kt, aj as Wt, ak as Ht, al as Ut, am as Gt } from "./upload-H_OCZBBn.js";
3
+ import { D as qt, a as Zt, d as Yt, b as Jt, c as Qt, f as en, e as tn, g as nn, h as rn, p as on, r as sn } from "./import-mode-DQ8g5P8P.js";
4
+ const ee = /\$(?![\s$])([^$\n]{1,200})\$/;
5
+ function te(e) {
6
+ const t = ee.exec(e);
7
7
  if (!t)
8
8
  return !1;
9
- const r = t[1];
10
- return /[\\^_{}]/.test(r) || /^[A-Za-z]'?$/.test(r.trim());
9
+ const n = t[1];
10
+ return /[\\^_{}]/.test(n) || /^[A-Za-z]'?$/.test(n.trim());
11
11
  }
12
- const ee = [
12
+ const ne = [
13
13
  // \begin{...} / \end{...} — unambiguous.
14
14
  { pattern: /\\(?:begin|end)\{[a-zA-Z*]+\}/, weight: 3 },
15
15
  // Display math, either delimiter style.
@@ -22,7 +22,7 @@ const ee = [
22
22
  { pattern: /\\[a-zA-Z]+\b/, weight: 1 },
23
23
  // Label/ref machinery is a strong hint even without braces nearby.
24
24
  { pattern: /\\(?:label|ref|eqref|cite)\b/, weight: 2 }
25
- ], te = [
25
+ ], re = [
26
26
  // ATX heading.
27
27
  { pattern: /^#{1,6}\s+\S/m, weight: 3 },
28
28
  // Fenced code block.
@@ -41,25 +41,25 @@ const ee = [
41
41
  { pattern: /(?:^|\s)_[^_\s][^_\n]*_(?:\s|[.,;:!?]|$)/, weight: 1 },
42
42
  // Inline code span.
43
43
  { pattern: /`[^`\n]+`/, weight: 1 }
44
- ], ne = 2;
44
+ ], oe = 2;
45
45
  function A(e, t) {
46
46
  return t.reduce(
47
- (r, { pattern: n, weight: o }) => r + (n.test(e) ? o : 0),
47
+ (n, { pattern: r, weight: o }) => n + (r.test(e) ? o : 0),
48
48
  0
49
49
  );
50
50
  }
51
- function re(e) {
52
- return { latex: A(e, ee) + (Q(e) ? 2 : 0), markdown: A(e, te) };
51
+ function se(e) {
52
+ return { latex: A(e, ne) + (te(e) ? 2 : 0), markdown: A(e, re) };
53
53
  }
54
- function ve(e) {
54
+ function Fe(e) {
55
55
  const t = e.trim();
56
56
  if (!t || t.startsWith("<"))
57
57
  return;
58
- const { latex: r, markdown: n } = re(t);
59
- if (!(Math.max(r, n) < ne))
60
- return r >= n ? "latex" : "markdown";
58
+ const { latex: n, markdown: r } = se(t);
59
+ if (!(Math.max(n, r) < oe))
60
+ return n >= r ? "latex" : "markdown";
61
61
  }
62
- const oe = {
62
+ const ae = {
63
63
  png: "image/png",
64
64
  jpg: "image/jpeg",
65
65
  jpeg: "image/jpeg",
@@ -73,28 +73,28 @@ const oe = {
73
73
  webp: "image/webp",
74
74
  ico: "image/vnd.microsoft.icon"
75
75
  };
76
- function se(e) {
76
+ function ie(e) {
77
77
  const t = e.split(".").pop()?.toLowerCase() ?? "";
78
- return oe[t] ?? "application/octet-stream";
78
+ return ae[t] ?? "application/octet-stream";
79
79
  }
80
80
  const P = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
81
- function ae(e) {
82
- const t = e.length, r = [];
83
- for (let n = 0; n < t; n += 3) {
84
- const o = e[n], i = n + 1 < t, s = n + 2 < t, a = i ? e[n + 1] : 0, c = s ? e[n + 2] : 0;
85
- r.push(P[o >> 2]), r.push(P[(o & 3) << 4 | a >> 4]), r.push(i ? P[(a & 15) << 2 | c >> 6] : "="), r.push(s ? P[c & 63] : "=");
81
+ function ce(e) {
82
+ const t = e.length, n = [];
83
+ for (let r = 0; r < t; r += 3) {
84
+ const o = e[r], a = r + 1 < t, s = r + 2 < t, i = a ? e[r + 1] : 0, c = s ? e[r + 2] : 0;
85
+ n.push(P[o >> 2]), n.push(P[(o & 3) << 4 | i >> 4]), n.push(a ? P[(i & 15) << 2 | c >> 6] : "="), n.push(s ? P[c & 63] : "=");
86
86
  }
87
- return r.join("");
87
+ return n.join("");
88
88
  }
89
- function k(e) {
89
+ function D(e) {
90
90
  return {
91
91
  ref: e.ref,
92
92
  fileName: e.fileName,
93
- contentType: se(e.fileName),
94
- data: ae(e.data)
93
+ contentType: ie(e.fileName),
94
+ data: ce(e.data)
95
95
  };
96
96
  }
97
- function D(e) {
97
+ function M(e) {
98
98
  return {
99
99
  ref: e.xmlId,
100
100
  source: e.content,
@@ -102,16 +102,16 @@ function D(e) {
102
102
  isRoot: e.isRoot
103
103
  };
104
104
  }
105
- function ie(e) {
105
+ function le(e) {
106
106
  return {
107
107
  title: e.title,
108
108
  docinfo: e.docinfo,
109
109
  documentKind: e.documentKind,
110
- divisions: e.divisions.map(D),
111
- assets: e.assets.map(k)
110
+ divisions: e.divisions.map(M),
111
+ assets: e.assets.map(D)
112
112
  };
113
113
  }
114
- function ce(e) {
114
+ function ue(e) {
115
115
  return {
116
116
  ref: e.ref,
117
117
  kind: "file",
@@ -124,7 +124,7 @@ function ce(e) {
124
124
  }
125
125
  };
126
126
  }
127
- function le(e) {
127
+ function pe(e) {
128
128
  return {
129
129
  title: e.title,
130
130
  docinfo: e.docinfo,
@@ -135,55 +135,87 @@ function le(e) {
135
135
  source_format: t.sourceFormat,
136
136
  is_root: t.isRoot
137
137
  })),
138
- assets_attributes: e.assets.map(ce)
138
+ assets_attributes: e.assets.map(ue)
139
139
  };
140
140
  }
141
- function Ie(e) {
142
- return le(ie(e));
141
+ function Le(e) {
142
+ return pe(le(e));
143
143
  }
144
- function _e(e, t) {
145
- const { root: r, entries: n } = K(e, t), o = new Set(n.map((s) => s.xmlId)), i = e.divisions.filter(
146
- (s) => !o.has(s.xmlId) && !(t.unwrapRoot && s.xmlId === r.xmlId)
144
+ function ye(e, t) {
145
+ const { root: n, entries: r } = W(e, t), o = new Set(r.map((s) => s.xmlId)), a = e.divisions.filter(
146
+ (s) => !o.has(s.xmlId) && !(t.unwrapRoot && s.xmlId === n.xmlId)
147
147
  );
148
148
  return {
149
- divisions: [...n, ...i].map(D),
150
- assets: e.assets.map(k),
151
- placeholders: n.map(
149
+ divisions: [...r, ...a].map(M),
150
+ assets: e.assets.map(D),
151
+ placeholders: r.map(
152
152
  (s) => `<plus:${s.type} ref="${s.xmlId}"/>`
153
153
  )
154
154
  };
155
155
  }
156
+ const F = /<(\/?)p(?=[\s>/])/g;
157
+ function Ce(e) {
158
+ let t = 0;
159
+ F.lastIndex = 0;
160
+ let n;
161
+ for (; (n = F.exec(e)) !== null; )
162
+ t += n[1] ? -1 : 1;
163
+ return t > 0;
164
+ }
165
+ const de = new RegExp(
166
+ `<(${H.join("|")})(?=[\\s>/])`
167
+ );
168
+ function me(e) {
169
+ return de.exec(e)?.[1];
170
+ }
171
+ function fe(e, t, n) {
172
+ return e.split(`
173
+ `).map(
174
+ (r, o) => o === 0 && n ? r : r && t + r
175
+ ).join(`
176
+ `);
177
+ }
178
+ function Re(e, t) {
179
+ let n = e.trim(), r;
180
+ if (t.inline) {
181
+ const o = n.replace(/^<p>\s*([\s\S]*?)\s*<\/p>$/, "$1");
182
+ n = o !== n ? o : n.replace(/^<p>/, "");
183
+ const a = me(n);
184
+ a && (r = `Pasted content produced a <${a}>, which cannot sit inside a <p>. It was inserted as-is — move it out of the paragraph to make the document valid.`);
185
+ }
186
+ return t.baseIndent && (n = fe(n, t.baseIndent, t.midLine)), { markup: n, warning: r };
187
+ }
156
188
  const E = {
157
189
  mainSourcePath: "source/main.ptx",
158
190
  publicationPath: "publication/publication.ptx",
159
191
  projectFilePath: "project.ptx",
160
192
  docinfoPath: "source/docinfo.ptx"
161
193
  };
162
- function M(e) {
163
- return y(e, "pretext") ? e : `<pretext>
194
+ function O(e) {
195
+ return C(e, "pretext") ? e : `<pretext>
164
196
  ${e}
165
197
  </pretext>`;
166
198
  }
167
- function O(e, t, r) {
168
- const n = /* @__PURE__ */ new Map(), o = [], i = `${t}-`;
169
- return e.forEach((s, a) => {
199
+ function N(e, t, n) {
200
+ const r = /* @__PURE__ */ new Map(), o = [], a = `${t}-`;
201
+ return e.forEach((s, i) => {
170
202
  const c = s.attributes["xml:id"];
171
203
  let l;
172
204
  if (c) {
173
- const m = q(c);
174
- l = m.startsWith(i) ? m : `${i}${m}`;
205
+ const m = Z(c);
206
+ l = m.startsWith(a) ? m : `${a}${m}`;
175
207
  } else
176
- l = `${i}${V(a + 1, e.length)}`, r.push({
208
+ l = `${a}${Y(i + 1, e.length)}`, n.push({
177
209
  action: "anomaly",
178
210
  severity: "info",
179
211
  kind: "structure",
180
212
  category: "missing_xml_id",
181
213
  macro: s.name,
182
214
  occurrences: 1,
183
- message: `<${s.name}> at position ${a + 1} has no xml:id; using \`${l}\` as filename.`
215
+ message: `<${s.name}> at position ${i + 1} has no xml:id; using \`${l}\` as filename.`
184
216
  });
185
- const p = n.get(l) ?? 0;
186
- n.set(l, p + 1);
217
+ const p = r.get(l) ?? 0;
218
+ r.set(l, p + 1);
187
219
  const u = p === 0 ? l : `${l}-${p + 1}`;
188
220
  o.push({
189
221
  span: s,
@@ -192,24 +224,24 @@ function O(e, t, r) {
192
224
  });
193
225
  }), o;
194
226
  }
195
- function ue(e, t, r, n) {
196
- const o = C(e, "section");
227
+ function he(e, t, n, r) {
228
+ const o = R(e, "section");
197
229
  if (o.length === 0)
198
230
  return e;
199
- const s = O(o, "sec", n).map((a) => {
200
- const c = `source/${t}/${a.filename}`;
201
- return r[c] = S(a.span.outer), {
202
- start: a.span.start,
203
- end: a.span.end,
204
- replacement: `<xi:include href="${t}/${a.filename}"/>`
231
+ const s = N(o, "sec", r).map((i) => {
232
+ const c = `source/${t}/${i.filename}`;
233
+ return n[c] = v(i.span.outer), {
234
+ start: i.span.start,
235
+ end: i.span.end,
236
+ replacement: `<xi:include href="${t}/${i.filename}"/>`
205
237
  };
206
238
  });
207
- return R(e, s);
239
+ return k(e, s);
208
240
  }
209
- function pe(e, t, r) {
210
- const n = y(e, "book");
211
- if (!n)
212
- return r.push({
241
+ function ge(e, t, n) {
242
+ const r = C(e, "book");
243
+ if (!r)
244
+ return n.push({
213
245
  action: "anomaly",
214
246
  severity: "warning",
215
247
  kind: "structure",
@@ -217,72 +249,72 @@ function pe(e, t, r) {
217
249
  macro: "book",
218
250
  occurrences: 1,
219
251
  message: "Document was treated as a book but no <book> element found; emitting as a single file."
220
- }), N(e, t);
221
- const o = {}, i = C(n.inner, "chapter");
222
- let s = n.inner;
223
- if (t.splitChapters && i.length > 0) {
224
- const p = O(i, "ch", r).map((u) => {
252
+ }), j(e, t);
253
+ const o = {}, a = R(r.inner, "chapter");
254
+ let s = r.inner;
255
+ if (t.splitChapters && a.length > 0) {
256
+ const p = N(a, "ch", n).map((u) => {
225
257
  let m = u.span.outer;
226
258
  if (t.splitSections) {
227
- const d = u.span.inner, f = ue(
259
+ const d = u.span.inner, f = he(
228
260
  d,
229
261
  u.slug,
230
262
  o,
231
- r
263
+ n
232
264
  );
233
265
  m = u.span.outer.slice(0, u.span.startTagEnd - u.span.start) + f + u.span.outer.slice(u.span.contentEnd - u.span.start);
234
266
  }
235
267
  const h = `source/${u.filename}`;
236
- return o[h] = S(m), {
268
+ return o[h] = v(m), {
237
269
  start: u.span.start,
238
270
  end: u.span.end,
239
271
  replacement: `<xi:include href="${u.filename}"/>`
240
272
  };
241
273
  });
242
- s = R(n.inner, p);
274
+ s = k(r.inner, p);
243
275
  }
244
- const a = e.slice(n.start, n.startTagEnd) + s + e.slice(n.contentEnd, n.end), c = e.slice(0, n.start) + a + e.slice(n.end);
245
- return o[t.mainSourcePath] = S(
246
- G(M(c.trim()))
276
+ const i = e.slice(r.start, r.startTagEnd) + s + e.slice(r.contentEnd, r.end), c = e.slice(0, r.start) + i + e.slice(r.end);
277
+ return o[t.mainSourcePath] = v(
278
+ q(O(c.trim()))
247
279
  ), o;
248
280
  }
249
- function N(e, t, r) {
250
- const n = {};
251
- return n[t.mainSourcePath] = S(
252
- M(e.trim())
253
- ), n;
281
+ function j(e, t, n) {
282
+ const r = {};
283
+ return r[t.mainSourcePath] = v(
284
+ O(e.trim())
285
+ ), r;
254
286
  }
255
- function $e(e, t = {}) {
256
- const r = [], n = t.documentKind ?? W(e), o = {
257
- splitChapters: t.splitChapters ?? n === "book",
287
+ function ke(e, t = {}) {
288
+ const n = [], r = t.documentKind ?? U(e), o = {
289
+ splitChapters: t.splitChapters ?? r === "book",
258
290
  splitSections: t.splitSections ?? !1,
259
291
  mainSourcePath: t.mainSourcePath ?? E.mainSourcePath,
260
292
  publicationPath: t.publicationPath ?? E.publicationPath,
261
293
  projectFilePath: t.projectFilePath ?? E.projectFilePath,
262
294
  docinfoPath: t.docinfoPath ?? E.docinfoPath
263
- }, i = n === "book" ? pe(e, o, r) : N(e, o);
264
- return i[o.projectFilePath] = H({
295
+ }, a = r === "book" ? ge(e, o, n) : j(e, o);
296
+ return a[o.projectFilePath] = G({
265
297
  mainSource: o.mainSourcePath,
266
298
  publication: o.publicationPath
267
- }), i[o.publicationPath] = U(), { files: i, documentKind: n, warnings: r };
299
+ }), a[o.publicationPath] = V(), { files: a, documentKind: r, warnings: n };
268
300
  }
269
- class de extends Error {
301
+ class we extends Error {
270
302
  constructor() {
271
303
  super("Import cancelled."), this.name = "ConversionCancelledError";
272
304
  }
273
305
  }
274
- let me = 0;
275
- function fe(e, t, r = {}) {
276
- const n = `convert-${me++}`, o = e(), { assets: i = {}, ...s } = r;
277
- let a;
306
+ let Te = 0;
307
+ function xe(e, t, n = {}) {
308
+ const r = `convert-${Te++}`, o = e(), { assets: a = {}, ...s } = n;
309
+ let i;
278
310
  const c = new Promise((p, u) => {
279
311
  let m = !1;
280
312
  const h = (d) => {
281
313
  m || (m = !0, o.terminate(), d());
282
314
  };
283
- a = () => h(() => u(new de())), o.addEventListener("message", (d) => {
315
+ i = () => h(() => u(new we())), o.addEventListener("message", (d) => {
284
316
  const f = d.data;
285
- if (!(!f || f.requestId !== n)) {
317
+ if (!(!f || f.requestId !== r)) {
286
318
  if (f.type === "result") {
287
319
  h(() => p(f.result));
288
320
  return;
@@ -295,27 +327,27 @@ function fe(e, t, r = {}) {
295
327
  });
296
328
  }), l = [
297
329
  ...new Set(
298
- Object.values(i).map((p) => p.buffer).filter(
330
+ Object.values(a).map((p) => p.buffer).filter(
299
331
  (p) => p instanceof ArrayBuffer
300
332
  )
301
333
  )
302
334
  ];
303
335
  return o.postMessage(
304
- { type: "convert", requestId: n, files: t, assets: i, options: s },
336
+ { type: "convert", requestId: r, files: t, assets: a, options: s },
305
337
  l
306
- ), { result: c, cancel: () => a?.() };
338
+ ), { result: c, cancel: () => i?.() };
307
339
  }
308
- function Ae(e) {
340
+ function De(e) {
309
341
  const {
310
342
  createWorker: t,
311
- id: r = "worker",
312
- label: n = "Built-in converter",
343
+ id: n = "worker",
344
+ label: r = "Built-in converter",
313
345
  description: o = "Create a new project starting with LaTeX, Markdown, or PreTeXt files.",
314
- acceptExtensions: i
346
+ acceptExtensions: a
315
347
  } = e;
316
348
  let s = null;
317
- const a = async (c, l) => {
318
- s?.cancel(), s = fe(t, c, l);
349
+ const i = async (c, l) => {
350
+ s?.cancel(), s = xe(t, c, l);
319
351
  try {
320
352
  return await s.result;
321
353
  } finally {
@@ -323,30 +355,30 @@ function Ae(e) {
323
355
  }
324
356
  };
325
357
  return {
326
- id: r,
327
- label: n,
358
+ id: n,
359
+ label: r,
328
360
  description: o,
329
- acceptExtensions: i,
361
+ acceptExtensions: a,
330
362
  prepare: async (c) => {
331
363
  const { files: l, assets: p } = await $(c);
332
364
  return {
333
365
  fileName: c.name,
334
366
  files: l,
335
367
  assets: p,
336
- analysis: Z(l)
368
+ analysis: J(l)
337
369
  };
338
370
  },
339
- convertPrepared: (c, l) => a(c.files, { ...l, assets: c.assets }),
371
+ convertPrepared: (c, l) => i(c.files, { ...l, assets: c.assets }),
340
372
  convertFile: async (c, l) => {
341
373
  const { files: p, assets: u } = await $(c);
342
- return a(p, { ...l, assets: u });
374
+ return i(p, { ...l, assets: u });
343
375
  },
344
376
  cancel: () => {
345
377
  s?.cancel(), s = null;
346
378
  }
347
379
  };
348
380
  }
349
- const he = {
381
+ const Pe = {
350
382
  ".docx": "docx",
351
383
  ".odt": "odt",
352
384
  ".epub": "epub",
@@ -362,7 +394,7 @@ const he = {
362
394
  ".typ": "typst",
363
395
  ".xml": "docbook",
364
396
  ".textile": "textile"
365
- }, Fe = /* @__PURE__ */ new Set(["docx", "odt", "epub"]), j = [
397
+ }, Me = /* @__PURE__ */ new Set(["docx", "odt", "epub"]), X = [
366
398
  ".docx",
367
399
  ".odt",
368
400
  ".epub",
@@ -378,143 +410,143 @@ const he = {
378
410
  ".md",
379
411
  ".markdown"
380
412
  ];
381
- function X(e) {
413
+ function z(e) {
382
414
  const t = e.lastIndexOf(".");
383
415
  return t <= 0 ? "" : e.slice(t).toLowerCase();
384
416
  }
385
- function ge(e) {
386
- return he[X(e)];
417
+ function Ee(e) {
418
+ return Pe[z(e)];
387
419
  }
388
- function we(e) {
420
+ function ve(e) {
389
421
  const {
390
422
  convertToPretext: t,
391
- id: r = "pandoc",
392
- label: n = "Pandoc",
423
+ id: n = "pandoc",
424
+ label: r = "Pandoc",
393
425
  description: o = "Convert Word, OpenOffice, EPUB, HTML, reStructuredText, and more.",
394
- acceptExtensions: i = j
426
+ acceptExtensions: a = X
395
427
  } = e;
396
428
  return {
397
- id: r,
398
- label: n,
429
+ id: n,
430
+ label: r,
399
431
  description: o,
400
- acceptExtensions: i,
401
- convertFile: async (s, a) => {
402
- const c = await t(s, a);
432
+ acceptExtensions: a,
433
+ convertFile: async (s, i) => {
434
+ const c = await t(s, i);
403
435
  if (!c.trim())
404
436
  throw new Error(
405
437
  `Pandoc produced no output for ${s.name}. The file may be empty or in an unexpected format.`
406
438
  );
407
- const l = Y(
439
+ const l = Q(
408
440
  { "source.ptx": c },
409
441
  {
410
- documentKind: a.documentKind,
411
- splitChapters: a.splitChapters,
412
- splitSections: a.splitSections,
413
- splitLevel: a.splitLevel
442
+ documentKind: i.documentKind,
443
+ splitChapters: i.splitChapters,
444
+ splitSections: i.splitSections,
445
+ splitLevel: i.splitLevel
414
446
  }
415
447
  );
416
448
  return "pretextError" in l || (l.sourceName = s.name, l.sourcePath = s.name), l;
417
449
  }
418
450
  };
419
451
  }
420
- const xe = 3e4;
421
- function Te(e) {
452
+ const Se = 3e4;
453
+ function be(e) {
422
454
  const t = /<pre>([\s\S]*?)<\/pre>/i.exec(e);
423
455
  return (t ? t[1] : e).replace(/<[^>]+>/g, "").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#39;/g, "'").replace(/&amp;/g, "&").trim();
424
456
  }
425
- function Pe(e, t, r) {
426
- const n = Ee(Te(t)), o = n ? ` (${L(n)})` : "";
457
+ function Ie(e, t, n) {
458
+ const r = _e(be(t)), o = r ? ` (${y(r)})` : "";
427
459
  switch (e) {
428
460
  case 400:
429
- return `The pandoc server will not convert ${r}${o}.${x(r)}`;
461
+ return `The pandoc server will not convert ${n}${o}.${T(n)}`;
430
462
  case 401:
431
463
  case 403:
432
- return `The pandoc server rejected this site's credentials, so ${r} was never converted. Nothing is wrong with your file — this is a configuration problem with the service, and worth reporting.${x(r)}`;
464
+ return `The pandoc server rejected this site's credentials, so ${n} was never converted. Nothing is wrong with your file — this is a configuration problem with the service, and worth reporting.${T(n)}`;
433
465
  case 404:
434
- return `The pandoc conversion service could not be found at the address this site is configured to use. Nothing is wrong with your file — this is a configuration problem worth reporting.${x(r)}`;
466
+ return `The pandoc conversion service could not be found at the address this site is configured to use. Nothing is wrong with your file — this is a configuration problem worth reporting.${T(n)}`;
435
467
  case 413:
436
- return `${r} is too large for the pandoc server to accept. Splitting it into chapters and importing them one at a time should get through.`;
468
+ return `${n} is too large for the pandoc server to accept. Splitting it into chapters and importing them one at a time should get through.`;
437
469
  case 422:
438
- return `Pandoc could not read ${r}${o}. The file may be damaged, or may use features pandoc does not support.`;
470
+ return `Pandoc could not read ${n}${o}. The file may be damaged, or may use features pandoc does not support.`;
439
471
  case 503:
440
- return `The pandoc server is running without its PreTeXt writer, so it cannot convert anything right now. Nothing is wrong with your file — this is a problem with the service, and worth reporting.${x(r)}`;
472
+ return `The pandoc server is running without its PreTeXt writer, so it cannot convert anything right now. Nothing is wrong with your file — this is a problem with the service, and worth reporting.${T(n)}`;
441
473
  case 504:
442
- return `Converting ${r} took longer than the pandoc server allows. Splitting it into chapters and importing them one at a time usually works.`;
474
+ return `Converting ${n} took longer than the pandoc server allows. Splitting it into chapters and importing them one at a time usually works.`;
443
475
  default: {
444
- const i = n ? `(HTTP ${e}: ${L(n)})` : `(HTTP ${e})`;
445
- return `The pandoc server could not convert ${r} ${i}.${x(r)}`;
476
+ const a = r ? `(HTTP ${e}: ${y(r)})` : `(HTTP ${e})`;
477
+ return `The pandoc server could not convert ${n} ${a}.${T(n)}`;
446
478
  }
447
479
  }
448
480
  }
449
- const F = 300;
450
- function Ee(e) {
481
+ const L = 300;
482
+ function _e(e) {
451
483
  return e.replace(/\s+/g, " ").trim();
452
484
  }
453
- function L(e) {
454
- return e.length <= F ? e : `${e.slice(0, F).trimEnd()}…`;
485
+ function y(e) {
486
+ return e.length <= L ? e : `${e.slice(0, L).trimEnd()}…`;
455
487
  }
456
- const Se = /* @__PURE__ */ new Set([
488
+ const $e = /* @__PURE__ */ new Set([
457
489
  ".tex",
458
490
  ".ltx",
459
491
  ".md",
460
492
  ".markdown"
461
493
  ]);
462
- function x(e) {
463
- return Se.has(X(e)) ? " You can import this file with the built-in converter instead." : "";
494
+ function T(e) {
495
+ return $e.has(z(e)) ? " You can import this file with the built-in converter instead." : "";
464
496
  }
465
- function Le(e) {
497
+ function Oe(e) {
466
498
  const {
467
499
  url: t,
468
- token: r,
469
- headers: n,
500
+ token: n,
501
+ headers: r,
470
502
  credentials: o,
471
- standalone: i = !0,
503
+ standalone: a = !0,
472
504
  from: s,
473
- timeoutMs: a = xe,
505
+ timeoutMs: i = Se,
474
506
  fetchImpl: c,
475
507
  id: l = "pandoc-remote",
476
508
  label: p = "Pandoc (server)",
477
509
  description: u = "Convert Word, OpenOffice, EPUB, HTML, reStructuredText, and more — no local install needed.",
478
- acceptExtensions: m = j
510
+ acceptExtensions: m = X
479
511
  } = e;
480
- return we({
512
+ return ve({
481
513
  convertToPretext: async (d, f) => {
482
- const b = c ?? globalThis.fetch;
483
- if (typeof b != "function")
514
+ const S = c ?? globalThis.fetch;
515
+ if (typeof S != "function")
484
516
  throw new Error(
485
517
  "This environment has no fetch; pass fetchImpl to createRemotePandocEngine."
486
518
  );
487
- const v = s ?? ge(d.name);
488
- if (!v)
519
+ const b = s ?? Ee(d.name);
520
+ if (!b)
489
521
  throw new Error(
490
522
  `Pandoc cannot determine a format for ${d.name}. Supported extensions: ${m.join(", ")}.`
491
523
  );
492
524
  const g = new FormData();
493
- r && g.set("token", r), g.set("file", d, d.name), g.set("from", v), i && g.set("standalone", "yes");
494
- const I = new AbortController(), z = setTimeout(() => I.abort(), a);
495
- let T;
525
+ n && g.set("token", n), g.set("file", d, d.name), g.set("from", b), a && g.set("standalone", "yes");
526
+ const I = new AbortController(), B = setTimeout(() => I.abort(), i);
527
+ let x;
496
528
  try {
497
- T = await b(t, {
529
+ x = await S(t, {
498
530
  method: "POST",
499
531
  body: g,
500
- headers: n,
532
+ headers: r,
501
533
  credentials: o,
502
534
  signal: I.signal
503
535
  });
504
536
  } catch (w) {
505
537
  if (w instanceof Error && w.name === "AbortError")
506
538
  throw new Error(
507
- `Pandoc conversion of ${d.name} timed out after ${Math.round(a / 1e3)}s.`
539
+ `Pandoc conversion of ${d.name} timed out after ${Math.round(i / 1e3)}s.`
508
540
  );
509
- const B = w instanceof Error ? w.message : String(w);
510
- throw new Error(`Could not reach the pandoc server: ${B}`);
541
+ const K = w instanceof Error ? w.message : String(w);
542
+ throw new Error(`Could not reach the pandoc server: ${K}`);
511
543
  } finally {
512
- clearTimeout(z);
544
+ clearTimeout(B);
513
545
  }
514
- const _ = await T.text();
515
- if (!T.ok)
546
+ const _ = await x.text();
547
+ if (!x.ok)
516
548
  throw new Error(
517
- Pe(T.status, _, d.name)
549
+ Ie(x.status, _, d.name)
518
550
  );
519
551
  return _;
520
552
  },
@@ -525,104 +557,108 @@ function Le(e) {
525
557
  });
526
558
  }
527
559
  export {
528
- Re as CLEAN_RULES,
529
- de as ConversionCancelledError,
530
- Kt as DEFAULT_IMPORT_MODE,
531
- xe as DEFAULT_REMOTE_PANDOC_TIMEOUT_MS,
532
- ke as DIVISION_LADDER,
533
- De as LADDER_OVERFLOW_TAG,
534
- Me as LATEX_DIVISION_COMMANDS,
535
- Oe as LATEX_FORMAT_MARKERS,
536
- Ne as MARKDOWN_FORMAT_MARKERS,
537
- je as MAX_SUGGESTED_SPLIT_LEVEL,
538
- j as PANDOC_ACCEPT_EXTENSIONS,
539
- Fe as PANDOC_BINARY_FORMATS,
540
- he as PANDOC_EXTENSION_FORMATS,
541
- Xe as PRETEXT_DIVISION_TAGS,
542
- ze as PRETEXT_ROOT_TAGS,
543
- Be as PROJECT_DESTINATION,
544
- Z as analyzeImportSources,
545
- Ke as applyLatexFixes,
546
- Wt as assetsForImportMode,
547
- We as attachLatexRoots,
548
- He as attachMarkdownRoots,
549
- Ue as buildDivisionPool,
550
- Ge as buildNativeDivisionPool,
551
- $e as buildPretextProjectFiles,
552
- qe as carryOverProjectFiles,
553
- Ve as cleanLatex,
554
- Ze as cleanLatexInChunks,
555
- Ye as cleanLatexText,
556
- Je as convertLatexToPretext,
557
- Qe as convertMarkdownToPretext,
558
- et as convertSourceToPretext,
559
- we as createPandocEngine,
560
- Le as createRemotePandocEngine,
561
- Ae as createWorkerEngine,
562
- tt as dedupeXmlIds,
563
- nt as defaultAttachLevel,
564
- rt as defaultManifestTarget,
565
- Pe as describeRemotePandocFailure,
566
- W as detectDocumentKind,
567
- ve as detectSnippetFormat,
568
- ot as detectSourceFormat,
569
- Ht as diffHunks,
570
- Ut as diffLines,
571
- Gt as diffStats,
572
- st as divisionChildRefs,
573
- at as divisionsAtLevel,
574
- it as expandPretextIncludes,
575
- Te as extractPandocErrorDetail,
560
+ Xe as CLEAN_RULES,
561
+ we as ConversionCancelledError,
562
+ qt as DEFAULT_IMPORT_MODE,
563
+ Se as DEFAULT_REMOTE_PANDOC_TIMEOUT_MS,
564
+ ze as DIVISION_LADDER,
565
+ Be as LADDER_OVERFLOW_TAG,
566
+ Ke as LATEX_DIVISION_COMMANDS,
567
+ We as LATEX_FORMAT_MARKERS,
568
+ He as MARKDOWN_FORMAT_MARKERS,
569
+ Ue as MAX_SUGGESTED_SPLIT_LEVEL,
570
+ X as PANDOC_ACCEPT_EXTENSIONS,
571
+ Me as PANDOC_BINARY_FORMATS,
572
+ Pe as PANDOC_EXTENSION_FORMATS,
573
+ H as PRETEXT_DIVISION_TAGS,
574
+ Ge as PRETEXT_ROOT_TAGS,
575
+ Ve as PROJECT_DESTINATION,
576
+ J as analyzeImportSources,
577
+ qe as applyLatexFixes,
578
+ Zt as assetsForImportMode,
579
+ Ze as attachLatexRoots,
580
+ Ye as attachMarkdownRoots,
581
+ Je as buildDivisionPool,
582
+ Qe as buildNativeDivisionPool,
583
+ ke as buildPretextProjectFiles,
584
+ et as carryOverProjectFiles,
585
+ tt as cleanLatex,
586
+ nt as cleanLatexInChunks,
587
+ rt as cleanLatexText,
588
+ ot as convertLatexToPretext,
589
+ st as convertMarkdownToPretext,
590
+ at as convertSourceToPretext,
591
+ ve as createPandocEngine,
592
+ Oe as createRemotePandocEngine,
593
+ De as createWorkerEngine,
594
+ it as dedupeXmlIds,
595
+ ct as defaultAttachLevel,
596
+ lt as defaultManifestTarget,
597
+ Ie as describeRemotePandocFailure,
598
+ U as detectDocumentKind,
599
+ Fe as detectSnippetFormat,
600
+ ut as detectSourceFormat,
601
+ Yt as diffHunks,
602
+ Jt as diffLines,
603
+ Qt as diffStats,
604
+ pt as divisionChildRefs,
605
+ dt as divisionsAtLevel,
606
+ mt as expandPretextIncludes,
607
+ be as extractPandocErrorDetail,
576
608
  $ as extractUpload,
577
- qt as fileChangesForImport,
578
- X as fileExtension,
579
- ct as filePrefixForDivision,
580
- Vt as filesForImportMode,
581
- lt as findLatexFixes,
582
- ut as findLatexHeaders,
583
- pt as findProjectManifest,
584
- dt as fixesToWarnings,
585
- Zt as formatWarningLine,
586
- mt as getConversionErrorMessage,
587
- ft as getLatexCleanDiagnostics,
588
- ht as handleImportUploadFile,
589
- Yt as hasNativeImportMode,
590
- Y as importProjectFromFiles,
591
- gt as isDivisionTag,
592
- wt as ladderDepth,
593
- xt as latexDivisionHierarchy,
594
- Tt as latexFixesToCodeActions,
595
- Pt as mergeChunksAtLevel,
596
- Et as normalizePretextSource,
597
- St as outlineDivisions,
598
- ge as pandocFormatForFileName,
599
- bt as parseLatexDivisions,
600
- vt as parseProjectManifest,
601
- It as prepareInsertSource,
602
- Jt as projectForImportMode,
603
- _t as pruneDivisions,
604
- $t as rebuildImport,
605
- le as recordsToPlusPayload,
606
- At as relayoutImport,
607
- H as renderProjectPtx,
608
- Ft as renderProjectPtxFromManifest,
609
- U as renderPublicationPtx,
610
- Lt as reselectImport,
611
- Qt as resolveImportMode,
612
- yt as resolveImportSplitLevel,
613
- Ct as resolveSplitLevel,
614
- Rt as retargetFragment,
615
- kt as retargetFragmentToDepth,
616
- Dt as retargetImport,
617
- fe as runConversionInWorker,
618
- Mt as sanitizeRef,
619
- re as scoreSnippetFormats,
620
- Ot as serializeForDestination,
621
- Nt as serializeInsertFiles,
622
- _e as serializeInsertToRecords,
623
- jt as serializeProjectToFiles,
624
- Ie as serializeProjectToPlusPayload,
625
- ie as serializeProjectToRecords,
626
- Xt as shiftLadderTag,
627
- zt as suggestSplitLevel
609
+ en as fileChangesForImport,
610
+ z as fileExtension,
611
+ ft as filePrefixForDivision,
612
+ tn as filesForImportMode,
613
+ ht as findLatexFixes,
614
+ gt as findLatexHeaders,
615
+ wt as findProjectManifest,
616
+ me as firstDivisionTag,
617
+ Tt as fixesToWarnings,
618
+ nn as formatWarningLine,
619
+ xt as getConversionErrorMessage,
620
+ Pt as getLatexCleanDiagnostics,
621
+ Et as handleImportUploadFile,
622
+ rn as hasNativeImportMode,
623
+ Q as importProjectFromFiles,
624
+ vt as isDivisionTag,
625
+ Ce as isInlineContext,
626
+ St as ladderDepth,
627
+ bt as latexDivisionHierarchy,
628
+ It as latexFixesToCodeActions,
629
+ _t as mergeChunksAtLevel,
630
+ $t as normalizePretextSource,
631
+ At as outlineDivisions,
632
+ Ee as pandocFormatForFileName,
633
+ Ft as parseLatexDivisions,
634
+ Lt as parseProjectManifest,
635
+ Re as placeConvertedMarkup,
636
+ yt as prepareInsertSource,
637
+ on as projectForImportMode,
638
+ Ct as pruneDivisions,
639
+ Rt as rebuildImport,
640
+ pe as recordsToPlusPayload,
641
+ fe as reindentForContext,
642
+ kt as relayoutImport,
643
+ G as renderProjectPtx,
644
+ Dt as renderProjectPtxFromManifest,
645
+ V as renderPublicationPtx,
646
+ Mt as reselectImport,
647
+ sn as resolveImportMode,
648
+ Ot as resolveImportSplitLevel,
649
+ Nt as resolveSplitLevel,
650
+ jt as retargetFragment,
651
+ Xt as retargetFragmentToDepth,
652
+ zt as retargetImport,
653
+ xe as runConversionInWorker,
654
+ Bt as sanitizeRef,
655
+ se as scoreSnippetFormats,
656
+ Kt as serializeForDestination,
657
+ Wt as serializeInsertFiles,
658
+ ye as serializeInsertToRecords,
659
+ Ht as serializeProjectToFiles,
660
+ Le as serializeProjectToPlusPayload,
661
+ le as serializeProjectToRecords,
662
+ Ut as shiftLadderTag,
663
+ Gt as suggestSplitLevel
628
664
  };
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Is `prefix` — the document text up to the insertion point — inside a `<p>`?
3
+ *
4
+ * Counted by walking the paragraph tags rather than parsing, because the
5
+ * document is mid-edit and frequently not well-formed. Only the depth matters,
6
+ * so a stray unclosed tag degrades to "treat it as block context", which is the
7
+ * safer of the two guesses.
8
+ */
9
+ export declare function isInlineContext(prefix: string): boolean;
10
+ /** The first division element in `markup`, if it has one. */
11
+ export declare function firstDivisionTag(markup: string): string | undefined;
12
+ /**
13
+ * Prepend baseIndent to every non-empty line of text.
14
+ * When skipFirst is true (the insertion starts mid-line), the first line is
15
+ * left as-is because the editor places it after the existing content there.
16
+ */
17
+ export declare function reindentForContext(text: string, baseIndent: string, skipFirst: boolean): string;
18
+ export interface PlacementContext {
19
+ /** The insertion point sits inside a `<p>`, so only inline content fits. */
20
+ inline: boolean;
21
+ /** Indentation of the line the insertion starts on. */
22
+ baseIndent: string;
23
+ /** The insertion starts partway along a line, after existing content. */
24
+ midLine: boolean;
25
+ }
26
+ export interface PlacedMarkup {
27
+ markup: string;
28
+ /** Something the author should know about — reported by the caller. */
29
+ warning?: string;
30
+ }
31
+ /**
32
+ * Fit converted markup to where it is going.
33
+ *
34
+ * Two adjustments, both about context rather than conversion. Inside a
35
+ * paragraph the converter's own wrapping `<p>` is one paragraph too many, so it
36
+ * is unwrapped. A division landing inside a paragraph cannot be repaired here
37
+ * at all — the honest thing is to insert it and say so, leaving the author to
38
+ * move it, rather than silently emitting invalid markup or refusing a paste
39
+ * they asked for.
40
+ */
41
+ export declare function placeConvertedMarkup(converted: string, context: PlacementContext): PlacedMarkup;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pretextbook/import",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "Shared import helpers for converting LaTeX/Markdown/PreTeXt into PreTeXt for VS Code and web apps",
5
5
  "author": "Oscar Levin",
6
6
  "license": "MIT",
@@ -54,10 +54,10 @@
54
54
  "test": "vitest run"
55
55
  },
56
56
  "dependencies": {
57
- "@pretextbook/format": "*",
58
- "@pretextbook/latex-pretext": "*",
59
- "@pretextbook/latex-style-pretext": "*",
60
- "@pretextbook/remark-pretext": "*",
57
+ "@pretextbook/format": "^0.5.0",
58
+ "@pretextbook/latex-pretext": "^0.3.1",
59
+ "@pretextbook/latex-style-pretext": "^0.5.1",
60
+ "@pretextbook/remark-pretext": "^0.1.0",
61
61
  "@tailwindcss/vite": "^4.0.0",
62
62
  "jszip": "^3.10.1",
63
63
  "tailwindcss": "^4.0.0"