@mdgate/html 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,26 @@
1
+ # @mdgate/html
2
+
3
+ Convert HTML, XHTML, and MHTML files to Markdown. Outputs GitHub-Flavored Markdown. Works in Node,
4
+ Edge, and browsers. No native addons.
5
+
6
+ Handles: `.html`, `.htm`, `.xhtml`, `.mhtml`, `.mht`
7
+
8
+ ## Usage
9
+
10
+ ```ts
11
+ import { toMarkdown } from '@mdgate/html';
12
+
13
+ const markdown = await toMarkdown(bytes);
14
+ ```
15
+
16
+ Compose with other converters:
17
+
18
+ ```ts
19
+ import { create } from '@mdgate/core';
20
+ import { html } from '@mdgate/html';
21
+
22
+ const convert = create([html()]);
23
+ ```
24
+
25
+ Part of [mdgate converters](https://github.com/mdgate/converters); install
26
+ `@mdgate/converters` for every format at once.
package/dist/html.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import type { Converter } from '@mdgate/core';
2
+ export declare function html(): Converter;
@@ -0,0 +1,4 @@
1
+ export { html } from './html.js';
2
+ export type { HtmlCtx, StyleProps } from './internal/walk.js';
3
+ export { Stylesheet, toBlocks } from './internal/walk.js';
4
+ export { toMarkdown } from './to-markdown.js';
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ import{hasOleMagic as D0}from"@mdgate/containers";import{ConvertError as I}from"@mdgate/core";import{documentToMarkdown as Of}from"@mdgate/document";import{fileExtension as Sf}from"@mdgate/utils";import{decodeFragment as J0,mimeHeader as Hf,mimeTextHtml as Q0,mimeTextPlain as Z0,parseMime as $0,parseXml as F0,walkMimeParts as K0}from"@mdgate/containers";import{ConvertError as Lf}from"@mdgate/core";import{emptyDocument as gf,plain as V0}from"@mdgate/document";import{AssetSink as Cf,mediaTypeFor as G0}from"@mdgate/office-common";import{decode as j0,isAbsoluteUri as qf,trim as Yf}from"@mdgate/utils";import{Element as p,MAX_XML_DEPTH as r,MAX_XML_NODES as n}from"@mdgate/containers";import{ConvertError as b}from"@mdgate/core";var c=new Set(["area","base","basefont","bgsound","br","col","embed","frame","hr","img","input","keygen","link","meta","param","source","track","wbr"]),Af=new Set(["script","style","textarea","title","noscript"]),uf=new Set(["address","article","aside","blockquote","div","dl","fieldset","footer","form","h1","h2","h3","h4","h5","h6","header","hr","main","nav","ol","p","pre","section","table","ul"]);function m(f){let U=[],z=0;while(z<f.length){if(f.charCodeAt(z)!==60){z+=1;continue}if(f.startsWith("<!--",z)){let Z=f.indexOf("-->",z+4);if(Z<0)return!1;z=Z+3;continue}if(f.startsWith("<![CDATA[",z)){let Z=f.indexOf("]]>",z+9);if(Z<0)return!1;z=Z+3;continue}if(f.startsWith("<?",z)){let Z=f.indexOf("?>",z+2);if(Z<0)return!1;z=Z+2;continue}if(f.startsWith("<!",z)){let Z=a(f,z);if(Z<0)return!1;z=Z;continue}if(f.startsWith("</",z)){z+=2;let Z=S(f,z);if(Z.length===0)return!1;if(z+=Z.length,z=C(f,z),f[z]!==">")return!1;z+=1;let $=U.pop();if($===void 0||$!==Z)return!1;continue}z+=1;let J=S(f,z);if(J.length===0)return!1;z+=J.length;let Q=xf(f,z);if(Q===void 0)return!1;if(z=Q.next,Q.empty)continue;if(c.has(J.toLowerCase()))return!1;U.push(J)}return U.length===0}function l(f){let U=new p(void 0,""),z=[U],J=0,Q=0,Z=()=>{if(J+=1,J>n)throw b.resourceLimit("max_xml_nodes",`part exceeds ${n} xml nodes`)};while(Q<f.length){if(f.charCodeAt(Q)!==60){let G=Q,j=f.indexOf("<",Q);Q=j<0?f.length:j;let H=R(f.slice(G,Q));if(H.length>0)Z(),D(z[z.length-1],H);continue}if(f.startsWith("<!--",Q)){let G=f.indexOf("-->",Q+4);Q=G<0?f.length:G+3;continue}if(f.startsWith("<![CDATA[",Q)){let G=f.indexOf("]]>",Q+9),j=G<0?f.slice(Q+9):f.slice(Q+9,G);if(j.length>0)Z(),D(z[z.length-1],j);Q=G<0?f.length:G+3;continue}if(f.startsWith("<?",Q)){let G=f.indexOf("?>",Q+2);Q=G<0?f.length:G+2;continue}if(f.startsWith("<!",Q)){let G=a(f,Q);Q=G<0?f.length:G;continue}if(f.startsWith("</",Q)){Q+=2;let G=B(f,Q).toLowerCase();if(G.length===0){Z(),D(z[z.length-1],"</");continue}if(Q+=G.length,Q=C(f,Q),f[Q]===">")Q+=1;vf(z,G);continue}if(!t(f.charCodeAt(Q+1))){Z(),D(z[z.length-1],"<"),Q+=1;continue}Q+=1;let $=B(f,Q),F=$.toLowerCase();Q+=$.length;let K=Ef(f,Q);Q=K.next,Nf(z,F),Z();let V=new p(void 0,F,K.attrs);if(z[z.length-1].children.push({type:"elem",elem:V}),K.empty||c.has(F))continue;if(Af.has(F)){let G=hf(f,Q,F),j=G<0?f.slice(Q):f.slice(Q,G);if(j.length>0)Z(),V.children.push({type:"text",text:j});if(G<0)Q=f.length;else Q=f.indexOf(">",G),Q=Q<0?f.length:Q+1;continue}if(z.length>=r)throw b.resourceLimit("max_xml_depth",`element nesting exceeds ${r}`);z.push(V)}return U}function Nf(f,U){let z=f[f.length-1];if(z===void 0||f.length<2)return;let J=z.local;if(U==="li"&&J==="li"){f.pop();return}if((U==="dt"||U==="dd")&&(J==="dt"||J==="dd")){f.pop();return}if((U==="td"||U==="th")&&(J==="td"||J==="th")){f.pop();return}if(U==="tr"){if(J==="td"||J==="th")f.pop();if(f.length>=2&&f[f.length-1].local==="tr")f.pop();return}if(uf.has(U)&&J==="p")f.pop()}function vf(f,U){for(let z=f.length-1;z>=1;z-=1)if(f[z].local===U){f.length=z;return}}function D(f,U){let z=f.children,J=z[z.length-1];if(J?.type==="text")J.text+=U;else z.push({type:"text",text:U})}function S(f,U){let z=U;while(U<f.length&&i(f.charCodeAt(U)))U+=1;return f.slice(z,U)}function B(f,U){let z=U;while(U<f.length&&Tf(f.charCodeAt(U)))U+=1;return f.slice(z,U)}function t(f){return f>=65&&f<=90||f>=97&&f<=122||f===58||f===95}function i(f){return t(f)||f>=48&&f<=57||f===45||f===46}function Tf(f){return i(f)}function xf(f,U){for(;;){U=C(f,U);let z=f[U];if(z===void 0)return;if(z===">")return{next:U+1,empty:!1};if(z==="/"&&f[U+1]===">")return{next:U+2,empty:!0};let J=S(f,U);if(J.length===0)return;if(U+=J.length,U=C(f,U),f[U]!=="=")return;U+=1,U=C(f,U);let Q=f.charCodeAt(U);if(Q!==34&&Q!==39)return;U+=1;let Z=f.indexOf(String.fromCharCode(Q),U);if(Z<0)return;U=Z+1}}function Ef(f,U){let z=[];for(;;){U=C(f,U);let J=f[U];if(J===void 0)return{next:U,empty:!1,attrs:z};if(J===">")return{next:U+1,empty:!1,attrs:z};if(J==="/"&&f[U+1]===">")return{next:U+2,empty:!0,attrs:z};let Q=B(f,U);if(Q.length===0){U+=1;continue}U+=Q.length,U=C(f,U);let Z="";if(f[U]==="="){U+=1,U=C(f,U);let $=f.charCodeAt(U);if($===34||$===39){U+=1;let F=f.indexOf(String.fromCharCode($),U),K=F<0?f.slice(U):f.slice(U,F);U=F<0?f.length:F+1,Z=R(K)}else{let F=U;while(U<f.length){let K=f.charCodeAt(U);if(K===62||K===47||K===32||K===9||K===10||K===13)break;U+=1}Z=R(f.slice(F,U))}}z.push({ns:void 0,local:Q.toLowerCase(),value:Z})}}function hf(f,U,z){let J=`</${z}`,Q=U;while(Q<f.length){let Z=kf(f,J,Q);if(Z<0)return-1;let $=Z+J.length,F=f.charCodeAt($);if(F===62||F===32||F===9||F===10||F===13||Number.isNaN(F))return Z;Q=Z+1}return-1}function kf(f,U,z){let J=U.length,Q=f.length-J;for(let Z=z;Z<=Q;Z+=1){let $=!0;for(let F=0;F<J;F+=1){let K=f.charCodeAt(Z+F),V=U.charCodeAt(F);if(K===V)continue;let G=K>=65&&K<=90?K+32:K,j=V>=65&&V<=90?V+32:V;if(G!==j){$=!1;break}}if($)return Z}return-1}function a(f,U){U+=2;let z=0;while(U<f.length){let J=f[U];if(J==='"'||J==="'"){let Q=J;U+=1;while(U<f.length&&f[U]!==Q)U+=1;if(U<f.length)U+=1;continue}if(J==="<")z+=1;else if(J===">"){if(z===0)return U+1;z-=1}U+=1}return-1}function C(f,U){while(U<f.length){let z=f.charCodeAt(U);if(z!==32&&z!==9&&z!==10&&z!==13)break;U+=1}return U}function R(f){let U="",z=0;while(z<f.length){let J=f.indexOf("&",z);if(J<0){U+=f.slice(z);break}U+=f.slice(z,J);let Q=f.indexOf(";",J+1);if(Q<0||Q-J>32){U+="&",z=J+1;continue}let Z=yf(f.slice(J+1,Q));if(Z!==void 0)U+=Z,z=Q+1;else U+="&",z=J+1}return U}function yf(f){if(f.startsWith("#")){let z=f.slice(1),J=z.startsWith("x")||z.startsWith("X"),Q=J?z.slice(1):z,Z=Number.parseInt(Q,J?16:10);if(!Number.isFinite(Z))return;try{return String.fromCodePoint(Z)}catch{return}}return{amp:"&",lt:"<",gt:">",apos:"'",quot:'"',nbsp:" ",shy:"­",mdash:"—",ndash:"–",lsquo:"‘",rsquo:"’",ldquo:"“",rdquo:"”",hellip:"…",copy:"©",reg:"®",trade:"™",deg:"°",middot:"·",bull:"•",sect:"§",para:"¶",laquo:"«",raquo:"»",times:"×",divide:"÷",plusmn:"±",frac12:"½",frac14:"¼",eacute:"é",egrave:"è",agrave:"à",ccedil:"ç",uuml:"ü",ouml:"ö",auml:"ä",szlig:"ß",aring:"å",oslash:"ø",aelig:"æ",euro:"€",pound:"£",yen:"¥",cent:"¢"}[f]}import{cellSpanning as of,GridBuilder as df,inlinesAreEmpty as v,inlinesToPlainText as s,plain as pf,resolveHeaderRows as rf}from"@mdgate/document";import{deltasEqual as nf,emptyDelta as Ff,mergeDelta as Kf,rebaseEmphasis as bf,resolveDelta as e}from"@mdgate/office-common";import{cleanText as ff,collapseWs as Uf,trim as zf}from"@mdgate/utils";function T(f,U,z){let J=new x(U,z,!0);return J.walkChildren(f,Ff()),J.finish()}var Vf={bold:void 0,italic:void 0,strike:void 0,code:void 0},_={delta:Vf,hidden:void 0};function A(){return{delta:Ff(),hidden:void 0}}function Jf(f,U){return{delta:Kf(f.delta,U.delta),hidden:U.hidden??f.hidden}}function M(f){return nf(f.delta,Vf)&&f.hidden===void 0}var Qf=1e5,Gf=1e6,cf=[],mf=[];class X{rules=[];get isEmpty(){return this.rules.length===0}addFrom(f){let U=f.rules;for(let z=0;z<U.length;z+=1)this.rules.push(U[z])}add(f){if(f.length===0)return;let U=tf(f);if(U.length===0)return;for(let z of U.split("}")){let J=z.indexOf("{");if(J<0)continue;let Q=z.slice(J+1);if(!lf(Q))continue;let Z=jf(Q);if(M(Z.normal)&&M(Z.important))continue;let $=z.slice(0,J);for(let F of $.split(",")){let K=F.trim();if(K.length===0||K.includes(" ")||K.includes(":")||K.includes("["))continue;let V=K.indexOf("."),G,j;if(V>=0){let L=K.slice(0,V);G=L.length===0?void 0:L.toLowerCase(),j=K.slice(V+1)}else G=K.toLowerCase();let H=(j!==void 0?10:0)+(G!==void 0?1:0);if(!M(Z.normal))this.rules.push({tag:G,className:j,priority:H,props:Z.normal});if(!M(Z.important))this.rules.push({tag:G,className:j,priority:Gf+H,props:Z.important})}}}matchingRules(f,U){let z=this.rules;if(z.length===0)return cf;let J=[];for(let Q=0;Q<z.length;Q+=1){let Z=z[Q];if(Z.tag!==void 0&&Z.tag!==f)continue;if(Z.className!==void 0&&!U.includes(Z.className))continue;J.push([Z.priority,Z.props])}return J}}function lf(f){return f.includes("display")||f.includes("font-weight")||f.includes("font-style")||f.includes("text-decoration")}function tf(f){let U=f.indexOf("/*");if(U<0)return f;let z=[],J=0,Q=U;while(Q>=0){if(Q>J)z.push(f.slice(J,Q));let Z=f.indexOf("*/",Q+2);if(Z<0)return z.join("");J=Z+2,Q=f.indexOf("/*",J)}if(J<f.length)z.push(f.slice(J));return z.join("")}function jf(f){let U={normal:A(),important:A()};for(let z of f.split(";")){let J=z.indexOf(":");if(J<0)continue;let Q=z.slice(0,J).trim().toLowerCase(),Z=z.slice(J+1).trim().toLowerCase(),$=!1,F=Z.indexOf("!");if(F>=0){if(Z.slice(F+1).trim()==="important")$=!0;Z=Z.slice(0,F).trimEnd()}let K=$?U.important:U.normal;switch(Q){case"font-weight":{let V=u(Z);K.delta.bold=Z==="bold"||Z==="bolder"||V!==void 0&&V>=600;break}case"font-style":K.delta.italic=Z==="italic"||Z==="oblique";break;case"text-decoration":case"text-decoration-line":if(Z.includes("line-through"))K.delta.strike=!0;else if(Z==="none")K.delta.strike=!1;break;case"display":K.hidden=Z==="none";break;default:break}}return U}function u(f){if(!/^\d+$/.test(f))return;let U=Number(f);if(!Number.isSafeInteger(U)||U<0||U>4294967295)return;return U}class x{blocks=[];inlines=[];css;ctx;startBoundary;constructor(f,U,z){this.css=f,this.ctx=U,this.startBoundary=z}finish(){return this.flushParagraph(),this.blocks}subBlocks(f,U){return this.subBlocksAt(f,U,!0)}subBlocksAt(f,U,z){let J=new x(this.css,this.ctx,z);return J.walkChildren(f,U),J.finish()}elementProps(f){let U=f.attrAny("style");if(this.css.isEmpty&&U===void 0)return _;let z=f.attrAny("class"),J=z!==void 0&&z.length>0?z.split(/\s+/).filter(($)=>$.length>0):mf,Q=this.css.matchingRules(f.local,J);if(U!==void 0){let $=jf(U);Q.push([Qf,$.normal]),Q.push([Gf+Qf,$.important])}if(Q.length===0)return _;if(Q.length===1)return Jf(_,Q[0][1]);Q.sort(($,F)=>$[0]-F[0]);let Z=A();for(let $=0;$<Q.length;$+=1)Z=Jf(Z,Q[$][1]);return Z}pushAnchor(f){let U=f.attrAny("id");if(U!==void 0&&U.length>0)this.inlines.push({type:"anchor",id:this.ctx.anchorId(U)});if(f.local==="a"){let z=f.attrAny("name");if(z!==void 0&&z.length>0)this.inlines.push({type:"anchor",id:this.ctx.anchorId(z)})}}walkChildren(f,U){for(let z of f.children)if(z.type==="text")this.pushText(z.text,U);else this.walkElem(z.elem,U)}pushText(f,U){let z=Uf(ff(f));if(z.length===0)return;let J=z;if(N(this.inlines,this.startBoundary))J=z0(z," ");if(J.length===0)return;this.inlines.push({type:"text",text:J,style:e(U)})}walkElem(f,U){let z=this.elementProps(f);if(z.hidden===!0)return;U=Kf(af(f,U),z.delta);let J=f.local;if(J==="h1"||J==="h2"||J==="h3"||J==="h4"||J==="h5"||J==="h6"){this.flushParagraph();let Q=Number.parseInt(J.slice(1),10)||1,Z=this.inlineChildren(f,U);bf(Z,e(U));let $=f.attrAny("id"),F=$!==void 0?this.ctx.anchorId($):void 0;if(!v(Z))this.blocks.push({type:"heading",level:Q,anchor:F,content:Z});else{let K=[];if(F!==void 0)K.push({type:"anchor",id:F});for(let V of Z)if(V.type==="anchor")K.push(V);if(K.length>0)this.blocks.push({type:"paragraph",inlines:K})}return}if(J==="p"){this.flushParagraph(),this.pushAnchor(f);let Q=this.inlines.splice(0,this.inlines.length);if(Q.push(...this.inlineChildren(f,U)),P(Q))this.blocks.push({type:"paragraph",inlines:Q});return}if(J==="ul"||J==="ol"){this.flushParagraph(),this.blocks.push(...this.parseList(f,U));return}if(J==="table"){this.flushParagraph();let Q=f.childElems().find(($)=>$.local==="caption");if(Q!==void 0){let $=this.inlineChildren(Q,U);if(P($))this.blocks.push({type:"paragraph",inlines:$})}let Z=this.parseTable(f,U);if(Z!==void 0)this.blocks.push(Z);return}if(J==="blockquote"){this.flushParagraph();let Q=this.subBlocks(f,U);if(Q.length>0)this.blocks.push({type:"blockQuote",blocks:Q});return}if(J==="pre"){this.flushParagraph();let Q=f.text();if(zf(Q).length>0)this.blocks.push({type:"codeBlock",lang:void 0,text:Q});return}if(J==="hr"){this.flushParagraph(),this.blocks.push({type:"rule"});return}if(wf(J)){if(this.pushAnchor(f),ef(f))this.flushParagraph(),this.walkChildren(f,U),this.flushParagraph();else this.walkChildren(f,U);return}if(J==="script"||J==="style"||J==="head"||J==="template"||J==="noscript")return;this.walkInline(f,U)}walkInline(f,U){this.pushAnchor(f);let z=f.local;if(z==="br"){this.inlines.push({type:"lineBreak"});return}if(z==="img"||z==="image"){let J=ff(f.attrAny("alt")??""),Q=f.attrAny("src")??f.attrAny("href")??"",Z=this.ctx.imageSource(Q);if(Z!==void 0||zf(J).length>0)this.inlines.push({type:"image",alt:J,source:Z??{type:"unavailable"}});return}if(z==="a"){let J=f.attrAny("href"),Q=J!==void 0?this.ctx.linkTarget(J):void 0,Z=this.inlineChildrenAt(f,U,N(this.inlines,this.startBoundary));if(Q!==void 0)this.inlines.push({type:"link",content:Z,target:Q});else this.inlines.push(...Z);return}this.walkChildren(f,U)}inlineChildren(f,U){return this.inlineChildrenAt(f,U,!0)}inlineChildrenAt(f,U,z){let J=this.subBlocksAt(f,U,z);if(J.length===1&&J[0].type==="paragraph")return J[0].inlines;let Q=[];for(let Z=0;Z<J.length;Z+=1){if(Z>0)Q.push({type:"lineBreak"});let $=J[Z];if($.type==="paragraph")Q.push(...$.inlines);else if($.type==="heading")Q.push(...$.content);else Q.push(pf(Uf(W($))))}return Q}parseList(f,U){let z=f.local==="ol",J=f.childElems().filter((q)=>q.local==="li");if(J.length===0)return[];if(!z)return[{type:"list",list:{marker:"bullet",start:1,items:J.map((w)=>({blocks:this.subBlocks(w,U),checked:void 0,markerLabel:void 0}))}}];let Q=f.attrAny("type"),Z="decimal";if(Q==="a")Z="lowerAlpha";else if(Q==="A")Z="upperAlpha";else if(Q==="i")Z="lowerRoman";else if(Q==="I")Z="upperRoman";let $=f.attrAny("reversed")!==void 0,F=f.attrAny("start"),V=(F!==void 0?Zf(F):void 0)??($?J.length:1),G=[];for(let q of J){let w=q.attrAny("value"),g=w!==void 0?Zf(w):void 0;if(g!==void 0)V=g;G.push(V),V=$?V-1:V+1}if(G.some((q)=>q<1)){let q=J.map((w,g)=>({blocks:this.subBlocks(w,U),checked:void 0,markerLabel:`${G[g]}.`}));return[{type:"list",list:{marker:Z,start:1,items:q}}]}let j=[],H,L=0;for(let q=0;q<J.length;q+=1){let w=G[q],g={blocks:this.subBlocks(J[q],U),checked:void 0,markerLabel:void 0};if(!(H!==void 0&&L+1===w)){if(H!==void 0)j.push({type:"list",list:H});H={marker:Z,start:w,items:[]}}H.items.push(g),L=w}if(H!==void 0)j.push({type:"list",list:H});return j}parseTable(f,U){let z=[],J=0,Q=!1;for(let V of f.childElems())if(V.local==="thead"||V.local==="tbody"||V.local==="tfoot"){if(Q)Q=!1,J+=1;let G=V.local==="thead";for(let j of V.childElems())if(j.local==="tr")z.push([j,G,J]);J+=1}else if(V.local==="tr")Q=!0,z.push([V,!1,J]);if(z.length===0)return;let Z=new Map;for(let V=0;V<z.length;V+=1)Z.set(z[V][2],V);let $=new df,F=0;for(let V=0;V<z.length;V+=1){let[G,j,H]=z[V];$.nextRow();let L=!0,q=!1;for(let w of G.childElems()){if(w.local!=="td"&&w.local!=="th")continue;if(q=!0,w.local!=="th")L=!1;let g=$f(u(w.attrAny("colspan")??"")??1,1,1000),Y,d=w.attrAny("rowspan"),O=d!==void 0?u(d):void 0;if(O===0)Y=(Z.get(H)??V)-V+1;else if(O!==void 0)Y=$f(O,1,65534);else Y=1;$.place(of(this.subBlocks(w,U),g,Y))}if(V===F&&(j||L&&q))F+=1}let K=$.finish("data");if(K.grid.length===0)return;return K.headerRows=rf(K,F),{type:"table",table:K}}flushParagraph(){if(this.inlines.length>0){let f=this.inlines.splice(0,this.inlines.length);if(P(f))this.blocks.push({type:"paragraph",inlines:f})}this.startBoundary=!0}}function af(f,U){let z={...U};switch(f.local){case"b":case"strong":z.bold=!0;break;case"i":case"em":case"cite":case"dfn":case"var":z.italic=!0;break;case"s":case"del":case"strike":z.strike=!0;break;case"code":case"kbd":case"samp":case"tt":z.code=!0;break;default:break}return z}function W(f){switch(f.type){case"paragraph":return s(f.inlines);case"heading":return s(f.content);case"list":return f.list.items.flatMap((U)=>U.blocks.map(W)).join(" ");case"blockQuote":return f.blocks.map(W).join(" ");case"codeBlock":return f.text;case"table":return f.table.grid.flatMap((U)=>U.flatMap((z)=>z.type==="origin"?[z.cell.blocks.map(W).join(" ")]:[])).join(" ");case"rule":return""}}function wf(f){return f==="div"||f==="section"||f==="article"||f==="aside"||f==="main"||f==="nav"||f==="header"||f==="footer"||f==="figure"||f==="figcaption"||f==="center"||f==="details"||f==="summary"||f==="li"||f==="dl"||f==="dt"||f==="dd"||f==="body"}function sf(f){return wf(f)||f==="p"||f==="ul"||f==="ol"||f==="table"||f==="blockquote"||f==="pre"||f==="hr"||f==="h1"||f==="h2"||f==="h3"||f==="h4"||f==="h5"||f==="h6"}function ef(f){return f.childElems().some((U)=>sf(U.local))}function P(f){return!v(f)||f.some((U)=>U.type==="anchor")}function N(f,U){for(let z=f.length-1;z>=0;z-=1){let J=f[z];if(J.type==="anchor")continue;if(J.type==="text"){if(J.text.length===0)continue;return U0(f0(J.text))}if(J.type==="lineBreak")return!0;if(J.type==="link"){if(v(J.content))continue;return N(J.content,!1)}return!1}return U}function f0(f){let U=f.length;if(U===0)return 0;let z=f.charCodeAt(U-1);if(z>=56320&&z<=57343&&U>=2){let J=f.charCodeAt(U-2);if(J>=55296&&J<=56319)return(J-55296<<10)+(z-56320)+65536}return z}function U0(f){return f>=9&&f<=13||f===32||f===133||f===160||f===5760||f>=8192&&f<=8202||f===8232||f===8233||f===8239||f===8287||f===12288}function z0(f,U){let z=0;while(z<f.length&&f[z]===U)z+=1;return f.slice(z)}function Zf(f){let U=f.trim();if(!/^-?\d+$/.test(U))return;let z=Number(U);return Number.isFinite(z)?z:void 0}function $f(f,U,z){return Math.min(z,Math.max(U,f))}function Df(f){let U=w0(f),z=new Cf;return Xf(U,new h(void 0,z),z)}function Mf(f){let U=$0(f),z=Q0(U)??Z0(U);if(z===void 0)throw Lf.malformed("no text/html or text/plain part");let J=new Cf,Q=L0(U),Z=C0(z);if(z.contentType==="text/plain"){let F=gf(),K=Yf(Z);if(K.length>0)F.blocks.push({type:"paragraph",inlines:[V0(K)]});return F.assets=J.assets,F}let $=Wf(Z,new TextEncoder().encode(Z));return Xf($,new h(Q,J),J)}function w0(f){return Wf(Y0(f),f)}function Wf(f,U){if(m(f))try{return F0(U)}catch(z){if(z instanceof Lf&&z.code==="resourceLimit")throw z}return l(f)}function Xf(f,U,z){If(f);let J=q0(f),Q=H0(f),Z=gf();return Z.blocks.push(...T(Q,J,U)),Z.assets=z.assets,Z}function q0(f){let U=new X;for(let z of f.descendantElems())if(z.local==="style")U.add(z.text());return U}function H0(f){if(f.local==="body")return f;let U=f.local==="html"?f:E(f,"html");if(U!==void 0){let J=E(U,"body");if(J!==void 0)return J;return U}return E(f,"body")??f}function E(f,U){return f.childElems().find((z)=>z.local===U)}function If(f){f.local=f.local.toLowerCase();let U=f.attrs;for(let z=0;z<U.length;z+=1)U[z].local=U[z].local.toLowerCase();for(let z of f.childElems())If(z)}class h{cids;assets;constructor(f,U){this.cids=f;this.assets=U}linkTarget(f){if(f.length===0)return;if(f.startsWith("#")){let U=J0(f.slice(1));return U.length>0?{type:"anchor",id:U}:void 0}if(qf(f))return{type:"external",url:f};return{type:"relative",url:f}}imageSource(f){if(f.length===0)return;let U=this.resolveCid(f);if(U!==void 0)return U;if(qf(f))return{type:"external",url:f};return}anchorId(f){return f}resolveCid(f){if(this.cids===void 0)return;if(f.length<4||f.slice(0,4).toLowerCase()!=="cid:")return;let U=f.slice(4);try{U=decodeURIComponent(U)}catch{}if(U.startsWith("<")&&U.endsWith(">")&&U.length>=2)U=U.slice(1,-1);let z=this.cids.get(U.toLowerCase());if(z===void 0)return;let J=z.filename??U,Q=z.contentType.length>0?z.contentType:G0(J);return{type:"asset",id:this.assets.add(Q,J,z.bytes)}}}function L0(f){let U=new Map;for(let z of K0(f)){let J=Hf(z,"content-id");if(J===void 0)continue;let Q=g0(J);if(Q.length>0)U.set(Q.toLowerCase(),z)}return U}function g0(f){let U=Yf(f);if(U.startsWith("<")&&U.endsWith(">")&&U.length>=2)U=U.slice(1,-1);return U}function C0(f){let U=Hf(f,"content-type"),z="utf-8";if(U!==void 0){let J=/charset\s*=\s*("?)([^";\s]+)\1/i.exec(U);if(J!==null)z=J[2]}try{return j0(f.bytes,z)}catch{return new TextDecoder("utf-8",{fatal:!1}).decode(f.bytes)}}function Y0(f){if(f.length>=2&&f[0]===255&&f[1]===254)return new TextDecoder("utf-16le").decode(f);if(f.length>=2&&f[0]===254&&f[1]===255)return new TextDecoder("utf-16be").decode(f);if(f.length>=3&&f[0]===239&&f[1]===187&&f[2]===191)return new TextDecoder("utf-8").decode(f.subarray(3));return new TextDecoder("utf-8").decode(f)}var M0=new Set(["htm","html","xhtml","mhtml","mht"]),W0=new Set(["mhtml","mht"]);function y(){return{id:"html",sniff(f,U){if(O0(f)&&!Bf(f))return 2;if(U?.path!==void 0&&M0.has(Sf(U.path)??""))return 1;return 0},convert(f,U){X0(f);let z=U?.path!==void 0?Sf(U.path):void 0;if(z!==void 0&&W0.has(z)||S0(f))return{markdown:Of(Mf(f))};if(Bf(f))throw I.unsupported("OpenDocument");return{markdown:Of(Df(f))}}}}function X0(f){if(I0(f))throw I.unsupported("pdf");if(D0(f))throw I.unsupported("ole");if(f.length>=4&&f[0]===80&&f[1]===75&&f[2]===3&&f[3]===4)throw I.unsupported("zip")}function I0(f){let U=Pf(f);return B0(f,"%PDF-",U)}function O0(f){let U=Pf(f);if(Rf(f,"<!doctype html",U)&&!_f(f[U+14]))return!0;if(Rf(f,"<html",U)&&!_f(f[U+5]))return!0;return o(f.subarray(0,Math.min(f.length,4096))).includes("http://www.w3.org/1999/xhtml")}function S0(f){let U=o(f.subarray(0,Math.min(f.length,512))).toLowerCase();return U.includes("multipart/related")||U.includes("content-location:")}function Bf(f){let U=o(f.subarray(0,Math.min(f.length,8192))),z=k(U,0);if(U.startsWith("<?xml",z)){let Q=U.indexOf("?>",z);if(Q<0)return!1;z=k(U,Q+2)}while(U.startsWith("<!--",z)){let Q=U.indexOf("-->",z+4);if(Q<0)return!1;z=k(U,Q+3)}let J=U.slice(z,z+2048);return/<office:document\b/.test(J)}function Pf(f){let U=0;if(f.length>=3&&f[0]===239&&f[1]===187&&f[2]===191)U=3;while(U<f.length){let z=f[U];if(z!==9&&z!==10&&z!==13&&z!==32)break;U+=1}return U}function k(f,U){while(U<f.length){let z=f.charCodeAt(U);if(z!==9&&z!==10&&z!==13&&z!==32)break;U+=1}return U}function B0(f,U,z){if(z+U.length>f.length)return!1;for(let J=0;J<U.length;J+=1)if(f[z+J]!==U.charCodeAt(J))return!1;return!0}function Rf(f,U,z){if(z+U.length>f.length)return!1;for(let J=0;J<U.length;J+=1){let Q=f[z+J],Z=U.charCodeAt(J);if(Q===Z)continue;let $=Q>=65&&Q<=90?Q+32:Q,F=Z>=65&&Z<=90?Z+32:Z;if($!==F)return!1}return!0}function _f(f){if(f===void 0)return!1;return f>=48&&f<=57||f>=65&&f<=90||f>=97&&f<=122||f===45||f===95||f===58}function o(f){return new TextDecoder("utf-8",{fatal:!1}).decode(f)}import{create as R0}from"@mdgate/core";var _0=R0([y()]);function P0(f,U){return _0(f,U)}export{P0 as toMarkdown,T as toBlocks,y as html,X as Stylesheet};
@@ -0,0 +1,22 @@
1
+ import type { Element } from '@mdgate/containers';
2
+ import { type AnchorId, type Block, type ImageSource, type LinkTarget } from '@mdgate/document';
3
+ import { type StyleDelta } from '@mdgate/office-common';
4
+ /** Frontend hooks: how hrefs, image sources, and anchor ids resolve. */
5
+ export interface HtmlCtx {
6
+ linkTarget(href: string): LinkTarget | undefined;
7
+ imageSource(src: string): ImageSource | undefined;
8
+ anchorId(raw: string): AnchorId;
9
+ }
10
+ export declare function toBlocks(body: Element, css: Stylesheet, ctx: HtmlCtx): Block[];
11
+ export interface StyleProps {
12
+ delta: StyleDelta;
13
+ hidden: boolean | undefined;
14
+ }
15
+ export declare class Stylesheet {
16
+ private readonly rules;
17
+ get isEmpty(): boolean;
18
+ /** Share already-parsed rules (rules are immutable after `add`). */
19
+ addFrom(other: Stylesheet): void;
20
+ add(css: string): void;
21
+ matchingRules(tag: string, classes: string[]): Array<[number, StyleProps]>;
22
+ }
@@ -0,0 +1,6 @@
1
+ import { type ConvertHint } from '@mdgate/core';
2
+ /**
3
+ * Convert a single file's bytes to Markdown with the html converter.
4
+ * `hint.path` is only a sniff hint; it is never read from disk.
5
+ */
6
+ export declare function toMarkdown(bytes: Uint8Array, hint?: ConvertHint): Promise<string>;
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@mdgate/html",
3
+ "version": "0.1.0",
4
+ "description": "mdgate HTML, XHTML, and MHTML converter",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "sideEffects": false,
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "main": "./dist/index.js",
15
+ "types": "./dist/index.d.ts",
16
+ "files": [
17
+ "dist/**/*.js",
18
+ "dist/**/*.d.ts"
19
+ ],
20
+ "scripts": {
21
+ "build": "bun ../../scripts/build-package.ts",
22
+ "prepublishOnly": "bun run build"
23
+ },
24
+ "dependencies": {
25
+ "@mdgate/containers": "0.1.0",
26
+ "@mdgate/core": "0.1.3",
27
+ "@mdgate/document": "0.1.0",
28
+ "@mdgate/office-common": "0.1.0",
29
+ "@mdgate/utils": "0.1.2"
30
+ },
31
+ "publishConfig": {
32
+ "access": "public"
33
+ },
34
+ "engines": {
35
+ "node": ">=20"
36
+ },
37
+ "keywords": [
38
+ "mdgate",
39
+ "markdown",
40
+ "html",
41
+ "xhtml",
42
+ "mhtml"
43
+ ]
44
+ }