@md2docx/html
Version:
Extend MDAST by parsing embedded HTML in Markdown. Converts HTML into structured MDAST nodes compatible with @m2d/core for DOCX generation.
4 lines (2 loc) • 6.26 kB
JavaScript
import{a as b}from"./chunk-CYY6OEIU.mjs";import{AlignmentType as L,BorderStyle as m}from"docx";var O=["A","ABBR","ACRONYM","B","BDI","BDO","BIG","BR","BUTTON","CITE","CODE","DATA","DATALIST","DEL","DFN","EM","I","IMG","INPUT","INS","KBD","LABEL","MARK","METER","NOSCRIPT","OBJECT","OUTPUT","Q","RUBY","RP","RT","S","SAMP","SCRIPT","SELECT","SLOT","SMALL","SPAN","STRONG","SUB","SUP","svg","TEMPLATE","TEXTAREA","TIME","U","TT","VAR","WBR"],I=["br","hr","img","input"],D={A:"link",B:"strong",BR:"break",EM:"emphasis",STRONG:"strong",I:"emphasis",IMG:"image",DEL:"delete",S:"delete"},M=["solid","dashed","dotted","double","none","ridge","groove","inset","outset"],k=t=>{var r;if(!t)return{};let n={},e=t.match(/border(-\w+)?:\s*[^;]+/gi);if(!e)return{};for(let s of e){let[a,d]=s.split(":").map(l=>l.trim()),u=d.split(/\s+/),c=(r=u.find(l=>l.endsWith("px")))==null?void 0:r.replace("px",""),p=u.find(l=>M.includes(l.toLowerCase())),o=u.find(l=>!l.endsWith("px")&&!M.includes(l.toLowerCase())),i=a==="border"?"border":a.replace("border-","");n[i]={...c?{width:parseInt(c,1)}:{},...p?{style:p}:{},...o?{color:o}:{}}}return n},P={solid:m.SINGLE,dashed:m.DASHED,dotted:m.DOTTED,double:m.DOUBLE,none:m.NONE,ridge:m.THREE_D_EMBOSS,groove:m.THREE_D_ENGRAVE,inset:m.INSET,outset:m.OUTSET},T=t=>{if(!t||!Object.keys(t).length)return;let{width:n,color:e,style:r}=t,s={style:r?P[r]:m.SINGLE};return n&&(s.size=n),e&&(s.color=b(e)),s},S=(t,n=!0)=>{var l,h;let e={};if(!(t instanceof HTMLElement||t instanceof SVGElement))return e;let{textAlign:r,fontWeight:s,fontStyle:a,textDecoration:d,textTransform:u,color:c}=t.style,p=t.getAttribute("style"),o=k(p);if(e.style=p!=null?p:void 0,n&&o.border)e.border=T(o.border);else if(Object.keys(o).length){let g={...o.border,...o.left},C={...o.border,...o.right},R={...o.border,...o.top},H={...o.border,...o.bottom};e.border={left:T(g),right:T(C),top:T(R),bottom:T(H)}}if(r){let g=r.toUpperCase();Object.keys(L).includes(g)?e.alignment=L[g]:g==="JUSTIFY"&&(e.alignment=L.JUSTIFIED)}switch((/bold/.test(s)||parseInt(s)>=500)&&(e.bold=!0),/(italic|oblique)/.test(a)&&(e.italics=!0),d){case"underline":e.underline={};break;case"overline":e.emphasisMark={};break;case"line-through":e.strike=!0;break}u==="uppercase"&&(e.allCaps=!0),u==="lowercase"&&(e.smallCaps=!0),c&&(e.color=b(c));let i=t.tagName;return i==="SUP"?e.superScript=!0:i==="SUB"?e.subScript=!0:["STRONG","B"].includes(i)?e.bold=!0:["EM","I"].includes(i)?e.italics=!0:["DEL","S"].includes(i)?e.strike=!0:["U","INS"].includes(i)?e.underline={}:i==="MARK"?(e.highlight="yellow",e.emphasisMark={}):i==="PRE"?e.pre=!0:i==="INPUT"&&(e.type=t.type,e.name=t.name,e.value=(l=t.value)!=null?l:t.defaultValue,e.checked=(h=t.checked)!=null?h:t.defaultChecked),e.tag=i.toLowerCase(),e},f=(t,n=!1)=>{var d,u,c,p,o,i;if(!(t instanceof HTMLElement||t instanceof SVGElement))return{type:"text",value:(u=n?t.textContent:(d=t.textContent)==null?void 0:d.replace(/^\s+|\s+$/g," "))!=null?u:""};let e=Array.from(t.childNodes).map(l=>f(l,n)),r=S(t),s=t.getAttributeNames().reduce((l,h)=>({...l,[h]:t.getAttribute(h)}),{}),a=t.tagName;switch(a){case"BR":return{type:"break"};case"IMG":return{type:"image",url:(c=s.src)!=null?c:"",alt:(p=s.alt)!=null?p:"",data:{...r,...s}};case"svg":return{type:"svg",value:t.outerHTML,data:r};case"EM":case"I":case"STRONG":case"B":case"DEL":case"S":return{type:D[a],children:e,data:r};case"A":return{type:"link",url:(o=s.href)!=null?o:"",children:e,data:r};case"INPUT":return/(radio|checkbox)/.test(t.type)?{type:"checkbox",data:r}:{type:"text",value:(i=r.value)!=null?i:`_${t.value||"_".repeat(20)}_`,data:{...r,border:{style:m.OUTSET}}}}return{type:"fragment",children:e,data:r}},E=(t,n)=>{let e=Array.from(t.childNodes),r=[],s=[];for(let a of e)(a instanceof HTMLElement||a instanceof SVGElement)&&!O.includes(a.tagName)?(s.length&&(r.push({type:"paragraph",children:s.map(d=>f(d,n==null?void 0:n.pre))}),s.length=0),r.push(U(a))):s.push(a);return s.length&&r.push({type:"paragraph",children:s.map(a=>f(a,n==null?void 0:n.pre))}),r.length===1?{...r[0],data:{...n,...r[0].data}}:{type:"fragment",children:r,data:n}},B=(t,n)=>Array.from(t.children).map(e=>{let r={...n,...S(e)};return e.tagName==="TR"?{type:"tableRow",children:Array.from(e.children).map(s=>({type:"tableCell",children:[E(s,{...r,tag:void 0})],data:{...r,tag:s.tagName.toLowerCase()}})),data:r}:B(e,r)}).flat(),y={style:"single"},w={left:y,right:y,top:y,bottom:y},U=t=>{let n=S(t),e=t.tagName;switch(e){case"H1":case"H2":case"H3":case"H4":case"H5":case"H6":return{type:"heading",depth:parseInt(e[1]),children:Array.from(t.childNodes).map(r=>f(r)),data:n};case"PRE":case"P":case"DIV":case"DETAILS":case"SUMMARY":case"FORM":case"LI":return E(t,n);case"UL":case"OL":return{type:"list",ordered:e==="OL",children:Array.from(t.childNodes).map(r=>({type:"listItem",children:[E(r)],data:n}))};case"HR":return{type:"thematicBreak",data:n};case"BLOCKQUOTE":return{type:"blockquote",children:Array.from(t.childNodes).map(r=>E(r)),data:n};case"TABLE":return{type:"table",children:B(t),data:n};case"STYLE":return{type:"paragraph",children:[{type:"text",value:`Not supported yet!
${t.textContent}`}],data:{...n,pre:!0,border:w}}}return{type:"paragraph",children:[f(t)],data:n}},N=t=>{var s,a,d;let n=(a=(s=t.value)==null?void 0:s.trim())!=null?a:"",e=n.split(" ")[0].slice(1),r=document.createElement("div");r.innerHTML=n.endsWith("/>")?n:`${n}</${e}>`,Object.assign(t,{...f(r.children[0]),children:(d=t.children)!=null?d:[]})},A=(t,n=!0)=>{var s,a,d,u;let e=[],r=[];for(let c of t.children){(s=c.children)!=null&&s.length&&A(c,!1);let p=c.value,o=typeof p=="string"?p:"",i=(a=o==null?void 0:o.split)==null?void 0:a.call(o," ")[0].replace(/^<|\/?>$/g,"");if(c.type==="html"&&!I.includes(i)&&/^<[^>]*[^/]>$/.test(o))if(i[0]==="/"){let h=r.shift();if(!h)throw new Error(`Invalid HTML: ${o}`);N(h),((u=(d=r[0])==null?void 0:d.children)!=null?u:e).push(h)}else r.unshift({...c,children:[],tag:i});else r.length?r[0].children.push(c):e.push(c);let l=c.type==="html"&&(I.includes(i)||/^<[^>]*\/>$/.test(o));if(l&&!n)N(c);else if(l&&n||c.type==="html"&&!/^<[^>]*>$/.test(o)){let h=document.createElement("div");h.innerHTML=o,Object.assign(c,E(h))}}t.children=e},_=()=>({preprocess:A});export{_ as htmlPlugin};