UNPKG

@m2d/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) 7.06 kB
"use strict";var b=Object.defineProperty;var O=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var P=(e,n)=>{for(var t in n)b(e,t,{get:n[t],enumerable:!0})},w=(e,n,t,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let s of D(n))!k.call(e,s)&&s!==t&&b(e,s,{get:()=>n[s],enumerable:!(r=O(n,s))||r.enumerable});return e};var U=e=>w(b({},"__esModule",{value:!0}),e);var W={};P(W,{htmlPlugin:()=>V});module.exports=U(W);var S=e=>{let n=document.createElement("canvas").getContext("2d");return n?(n.fillStyle=e,n.fillStyle.slice(1)):e.startsWith("#")?e.slice(1):"auto"};var d=require("docx"),v=["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"],M=["br","hr","img","input"],x={A:"link",B:"strong",BR:"break",EM:"emphasis",STRONG:"strong",I:"emphasis",IMG:"image",DEL:"delete",S:"delete"},I=["solid","dashed","dotted","double","none","ridge","groove","inset","outset"],G=e=>{var r;if(!e)return{};let n={},t=e.match(/border(-\w+)?:\s*[^;]+/gi);if(!t)return{};for(let s of t){let[a,p]=s.split(":").map(l=>l.trim()),h=p.split(/\s+/),c=(r=h.find(l=>l.endsWith("px")))==null?void 0:r.replace("px",""),u=h.find(l=>I.includes(l.toLowerCase())),o=h.find(l=>!l.endsWith("px")&&!I.includes(l.toLowerCase())),i=a==="border"?"border":a.replace("border-","");n[i]={...c?{width:parseInt(c,1)}:{},...u?{style:u}:{},...o?{color:o}:{}}}return n},_={solid:d.BorderStyle.SINGLE,dashed:d.BorderStyle.DASHED,dotted:d.BorderStyle.DOTTED,double:d.BorderStyle.DOUBLE,none:d.BorderStyle.NONE,ridge:d.BorderStyle.THREE_D_EMBOSS,groove:d.BorderStyle.THREE_D_ENGRAVE,inset:d.BorderStyle.INSET,outset:d.BorderStyle.OUTSET},T=e=>{if(!e||!Object.keys(e).length)return;let{width:n,color:t,style:r}=e,s={style:r?_[r]:d.BorderStyle.SINGLE};return n&&(s.size=n),t&&(s.color=S(t)),s},L=(e,n=!0)=>{var l,m;let t={};if(!(e instanceof HTMLElement||e instanceof SVGElement))return t;let{textAlign:r,fontWeight:s,fontStyle:a,textDecoration:p,textTransform:h,color:c}=e.style,u=e.getAttribute("style"),o=G(u);if(t.style=u!=null?u:void 0,n&&o.border)t.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};t.border={left:T(g),right:T(C),top:T(R),bottom:T(H)}}if(r){let g=r.toUpperCase();Object.keys(d.AlignmentType).includes(g)?t.alignment=d.AlignmentType[g]:g==="JUSTIFY"&&(t.alignment=d.AlignmentType.JUSTIFIED)}switch((/bold/.test(s)||parseInt(s)>=500)&&(t.bold=!0),/(italic|oblique)/.test(a)&&(t.italics=!0),p){case"underline":t.underline={};break;case"overline":t.emphasisMark={};break;case"line-through":t.strike=!0;break}h==="uppercase"&&(t.allCaps=!0),h==="lowercase"&&(t.smallCaps=!0),c&&(t.color=S(c));let i=e.tagName;return i==="SUP"?t.superScript=!0:i==="SUB"?t.subScript=!0:["STRONG","B"].includes(i)?t.bold=!0:["EM","I"].includes(i)?t.italics=!0:["DEL","S"].includes(i)?t.strike=!0:["U","INS"].includes(i)?t.underline={}:i==="MARK"?(t.highlight="yellow",t.emphasisMark={}):i==="PRE"?t.pre=!0:i==="INPUT"&&(t.type=e.type,t.name=e.name,t.value=(l=e.value)!=null?l:e.defaultValue,t.checked=(m=e.checked)!=null?m:e.defaultChecked),t.tag=i.toLowerCase(),t},f=(e,n=!1)=>{var p,h,c,u,o,i;if(!(e instanceof HTMLElement||e instanceof SVGElement))return{type:"text",value:(h=n?e.textContent:(p=e.textContent)==null?void 0:p.replace(/^\s+|\s+$/g," "))!=null?h:""};let t=Array.from(e.childNodes).map(l=>f(l,n)),r=L(e),s=e.getAttributeNames().reduce((l,m)=>({...l,[m]:e.getAttribute(m)}),{}),a=e.tagName;switch(a){case"BR":return{type:"break"};case"IMG":return{type:"image",url:(c=s.src)!=null?c:"",alt:(u=s.alt)!=null?u:"",data:{...r,...s}};case"svg":return{type:"svg",value:e.outerHTML,data:r};case"EM":case"I":case"STRONG":case"B":case"DEL":case"S":return{type:x[a],children:t,data:r};case"A":return{type:"link",url:(o=s.href)!=null?o:"",children:t,data:r};case"INPUT":return/(radio|checkbox)/.test(e.type)?{type:"checkbox",data:r}:{type:"text",value:(i=r.value)!=null?i:`_${e.value||"_".repeat(20)}_`,data:{...r,border:{style:d.BorderStyle.OUTSET}}}}return{type:"fragment",children:t,data:r}},E=(e,n)=>{let t=Array.from(e.childNodes),r=[],s=[];for(let a of t)(a instanceof HTMLElement||a instanceof SVGElement)&&!v.includes(a.tagName)?(s.length&&(r.push({type:"paragraph",children:s.map(p=>f(p,n==null?void 0:n.pre))}),s.length=0),r.push(Y(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=(e,n)=>Array.from(e.children).map(t=>{let r={...n,...L(t)};return t.tagName==="TR"?{type:"tableRow",children:Array.from(t.children).map(s=>({type:"tableCell",children:[E(s,{...r,tag:void 0})],data:{...r,tag:s.tagName.toLowerCase()}})),data:r}:B(t,r)}).flat(),y={style:"single"},$={left:y,right:y,top:y,bottom:y},Y=e=>{let n=L(e),t=e.tagName;switch(t){case"H1":case"H2":case"H3":case"H4":case"H5":case"H6":return{type:"heading",depth:parseInt(t[1]),children:Array.from(e.childNodes).map(r=>f(r)),data:n};case"PRE":case"P":case"DIV":case"DETAILS":case"SUMMARY":case"FORM":case"LI":return E(e,n);case"UL":case"OL":return{type:"list",ordered:t==="OL",children:Array.from(e.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(e.childNodes).map(r=>E(r)),data:n};case"TABLE":return{type:"table",children:B(e),data:n};case"STYLE":return{type:"paragraph",children:[{type:"text",value:`Not supported yet! ${e.textContent}`}],data:{...n,pre:!0,border:$}}}return{type:"paragraph",children:[f(e)],data:n}},N=e=>{var s,a,p;let n=(a=(s=e.value)==null?void 0:s.trim())!=null?a:"",t=n.split(" ")[0].slice(1),r=document.createElement("div");r.innerHTML=n.endsWith("/>")?n:`${n}</${t}>`,Object.assign(e,{...f(r.children[0]),children:(p=e.children)!=null?p:[]})},A=(e,n=!0)=>{var s,a,p,h;let t=[],r=[];for(let c of e.children){(s=c.children)!=null&&s.length&&A(c,!1);let u=c.value,o=typeof u=="string"?u:"",i=(a=o==null?void 0:o.split)==null?void 0:a.call(o," ")[0].replace(/^<|\/?>$/g,"");if(c.type==="html"&&!M.includes(i)&&/^<[^>]*[^/]>$/.test(o))if(i[0]==="/"){let m=r.shift();if(!m){console.warn(`[HTML Plugin] Invalid HTML detected: closing tag without matching opening tag: ${o}`);continue}N(m),((h=(p=r[0])==null?void 0:p.children)!=null?h:t).push(m)}else r.unshift({...c,children:[],tag:i});else r.length?r[0].children.push(c):t.push(c);let l=c.type==="html"&&(M.includes(i)||/^<[^>]*\/>$/.test(o));if(l&&!n)N(c);else if(l&&n||c.type==="html"&&!/^<[^>]*>$/.test(o)){let m=document.createElement("div");m.innerHTML=o,Object.assign(c,E(m))}}e.children=t},V=()=>({preprocess:A});0&&(module.exports={htmlPlugin});