@xuda.io/xuda-cli-plugin-html-parser-module.esm.min 1.0.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.
Files changed (2) hide show
  1. package/index.mjs +1 -0
  2. package/package.json +8 -0
package/index.mjs ADDED
@@ -0,0 +1 @@
1
+ export const childlessTags=["style","script","template"];export const closingTags=["html","head","body","p","dt","dd","li","option","thead","th","tbody","tr","td","tfoot","colgroup"];export const closingTagAncestorBreakers={li:["ul","ol","menu"],dt:["dl"],dd:["dl"],tbody:["table"],thead:["table"],tfoot:["table"],tr:["table"],td:["table"]};export const voidTags=["!doctype","area","base","br","col","command","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"];export function uuidv4(){return([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,c=>(c^crypto.getRandomValues(new Uint8Array(1))[0]&15>>c/4).toString(16))}export function isObject(val){return val instanceof Object}export function formatAttributes(attributes,options={}){return Object.keys(attributes).reduce((attrs,attrKey)=>{const key=attrKey;var value=attributes[attrKey];if(value===null||typeof value!=="boolean"&&!value){return`${attrs} ${key}`}if(isObject(value)){const jsonString=JSON.stringify(value);return`${attrs} ${key}='${jsonString}'`}value=value.toString();return`${attrs} ${key}="${value}"`},"")}export function toHTML(tree,options){return tree.map(node=>{if(!node.type)return;if(node.type==="text"){return node.content}if(node.type==="comment"){return`<!--${node.content}-->`}const escapeHtml=unsafe=>{return unsafe.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&#039;")};var text=node.attributes?.["xu-text"]&&escapeHtml(node.attributes?.["xu-text"])||node.attributes?.["xu-html"]||node?.content&&escapeHtml(node.content)||"";var{tagName,attributes,children}=node;delete attributes.internal_tree_id;delete attributes.internal_path;attributes=JSON.parse(JSON.stringify(attributes));if(!attributes.internal_tree_id&&!options.remove_tree_id)attributes.internal_tree_id=node.id;if(options.remove_tree_id){delete attributes.internal_tree_id}if(options.add_studio_meta){attributes.internal_path=node?.path?.toString?.();attributes.xuda_hide=node.$hide}const isSelfClosing=arrayIncludes(options.voidTags,tagName.toLowerCase());return isSelfClosing?`<${tagName}${formatAttributes(attributes)}>`:`<${tagName}${formatAttributes(attributes)}>${text}${toHTML(children,options)}</${tagName}>`}).join("")}export function parser(tokens,options){const root={tagName:null,children:[]};const state={tokens:tokens,options:options,cursor:0,stack:[root]};parserParse(state);return root.children}export function hasTerminalParent(tagName,stack,terminals){const tagParents=terminals[tagName];if(tagParents){let currentIndex=stack.length-1;while(currentIndex>=0){const parentTagName=stack[currentIndex].tagName;if(parentTagName===tagName){break}if(arrayIncludes(tagParents,parentTagName)){return true}currentIndex--}}return false}export function rewindStack(stack,newLength,childrenEndPosition,endPosition){stack[newLength].position.end=endPosition;for(let i=newLength+1,len=stack.length;i<len;i++){stack[i].position.end=childrenEndPosition}stack.splice(newLength)}export function parserParse(state){const{tokens,options}=state;let{stack}=state;let nodes=stack[stack.length-1].children;const len=tokens.length;let{cursor}=state;while(cursor<len){const token=tokens[cursor];if(token.type!=="tag-start"){nodes.push(token);cursor++;continue}const tagToken=tokens[++cursor];cursor++;const tagName=tagToken.content.toLowerCase();if(token.close){let index=stack.length;let shouldRewind=false;while(--index>-1){if(stack[index].tagName===tagName){shouldRewind=true;break}}while(cursor<len){const endToken=tokens[cursor];if(endToken.type!=="tag-end")break;cursor++}if(shouldRewind){rewindStack(stack,index,token.position.start,tokens[cursor-1].position.end);break}else{continue}}const isClosingTag=arrayIncludes(options.closingTags,tagName);let shouldRewindToAutoClose=isClosingTag;if(shouldRewindToAutoClose){const{closingTagAncestorBreakers:terminals}=options;shouldRewindToAutoClose=!hasTerminalParent(tagName,stack,terminals)}if(shouldRewindToAutoClose){let currentIndex=stack.length-1;while(currentIndex>0){if(tagName===stack[currentIndex].tagName){rewindStack(stack,currentIndex,token.position.start,token.position.start);const previousIndex=currentIndex-1;nodes=stack[previousIndex].children;break}currentIndex=currentIndex-1}}let attributes={};let attrToken;while(cursor<len){attrToken=tokens[cursor];if(attrToken.type==="tag-end")break;attributes[attrToken.content]="";cursor++}cursor++;const children=[];const position={start:token.position.start,end:attrToken.position.end};const elementNode={type:"element",tagName:tagToken.content,attributes:attributes,children:children,position:position};nodes.push(elementNode);const hasChildren=!(attrToken.close||arrayIncludes(options.voidTags,tagName));if(hasChildren){const size=stack.push({tagName:tagName,children:children,position:position});const innerState={tokens:tokens,options:options,cursor:cursor,stack:stack};parserParse(innerState);cursor=innerState.cursor;const rewoundInElement=stack.length===size;if(rewoundInElement){elementNode.position.end=tokens[cursor-1].position.end}}}state.cursor=cursor}export function feedPosition(position,str,len){const start=position.index;const end=position.index=start+len;for(let i=start;i<end;i++){const char=str.charAt(i);if(char==="\n"){position.line++;position.column=0}else{position.column++}}}export function jumpPosition(position,str,end){const len=end-position.index;return feedPosition(position,str,len)}export function makeInitialPosition(){return{index:0,column:0,line:0}}export function copyPosition(position){return{index:position.index,line:position.line,column:position.column}}export function lexer(str,options){const state={str:str,options:options,position:makeInitialPosition(),tokens:[]};lex(state);return state.tokens}export function lex(state){const{str,options:{childlessTags}}=state;const len=str.length;while(state.position.index<len){const start=state.position.index;lexText(state);if(state.position.index===start){const isComment=startsWith(str,"!--",start+1);if(isComment){lexComment(state)}else{const tagName=lexTag(state);const safeTag=tagName.toLowerCase();if(arrayIncludes(childlessTags,safeTag)){lexSkipTag(tagName,state)}}}}}const alphanumeric=/[A-Za-z0-9]/;export function findTextEnd(str,index){while(true){const textEnd=str.indexOf("<",index);if(textEnd===-1){return textEnd}const char=str.charAt(textEnd+1);if(char==="/"||char==="!"||alphanumeric.test(char)){return textEnd}index=textEnd+1}}export function lexText(state){const type="text";const{str,position}=state;let textEnd=findTextEnd(str,position.index);if(textEnd===position.index)return;if(textEnd===-1){textEnd=str.length}const start=copyPosition(position);const content=str.slice(position.index,textEnd)?.trim();jumpPosition(position,str,textEnd);const end=copyPosition(position);if(content)state.tokens.push({type:type,content:content,position:{start:start,end:end}})}export function lexComment(state){const{str,position}=state;const start=copyPosition(position);feedPosition(position,str,4);let contentEnd=str.indexOf("--\x3e",position.index);let commentEnd=contentEnd+3;if(contentEnd===-1){contentEnd=commentEnd=str.length}const content=str.slice(position.index,contentEnd);jumpPosition(position,str,commentEnd);state.tokens.push({type:"comment",content:content,position:{start:start,end:copyPosition(position)}})}export function lexTag(state){const{str,position}=state;{const secondChar=str.charAt(position.index+1);const close=secondChar==="/";const start=copyPosition(position);feedPosition(position,str,close?2:1);state.tokens.push({type:"tag-start",close:close,position:{start:start}})}const tagName=lexTagName(state);lexTagAttributes(state);{const firstChar=str.charAt(position.index);const close=firstChar==="/";feedPosition(position,str,close?2:1);const end=copyPosition(position);state.tokens.push({type:"tag-end",close:close,position:{end:end}})}return tagName}const whitespace=/\s/;export function isWhitespaceChar(char){return whitespace.test(char)}export function lexTagName(state){const{str,position}=state;const len=str.length;let start=position.index;while(start<len){const char=str.charAt(start);const isTagChar=!(isWhitespaceChar(char)||char==="/"||char===">");if(isTagChar)break;start++}let end=start+1;while(end<len){const char=str.charAt(end);const isTagChar=!(isWhitespaceChar(char)||char==="/"||char===">");if(!isTagChar)break;end++}jumpPosition(position,str,end);const tagName=str.slice(start,end);state.tokens.push({type:"tag",content:tagName});return tagName}export function lexTagAttributes(state){const{str,position,tokens}=state;let cursor=position.index;let quote=null;let wordBegin=cursor;const words=[];const len=str.length;while(cursor<len){const char=str.charAt(cursor);if(quote){const isQuoteEnd=char===quote;if(isQuoteEnd){quote=null}cursor++;continue}const isTagEnd=char==="/"||char===">";if(isTagEnd){if(cursor!==wordBegin){words.push(str.slice(wordBegin,cursor))}break}const isWordEnd=isWhitespaceChar(char);if(isWordEnd){if(cursor!==wordBegin){words.push(str.slice(wordBegin,cursor))}wordBegin=cursor+1;cursor++;continue}const isQuoteStart=char==="'"||char==='"';if(isQuoteStart){quote=char;cursor++;continue}cursor++}jumpPosition(position,str,cursor);const wLen=words.length;const type="attribute";for(let i=0;i<wLen;i++){const word=words[i];const isNotPair=word.indexOf("=")===-1;if(isNotPair){const secondWord=words[i+1];if(secondWord&&startsWith(secondWord,"=")){if(secondWord.length>1){const newWord=word+secondWord;tokens.push({type:type,content:newWord});i+=1;continue}const thirdWord=words[i+2];i+=1;if(thirdWord){const newWord=word+"="+thirdWord;tokens.push({type:type,content:newWord});i+=1;continue}}}if(endsWith(word,"=")){const secondWord=words[i+1];if(secondWord&&!stringIncludes(secondWord,"=")){const newWord=word+secondWord;tokens.push({type:type,content:newWord});i+=1;continue}const newWord=word.slice(0,-1);tokens.push({type:type,content:newWord});continue}tokens.push({type:type,content:word})}}const push=[].push;export function lexSkipTag(tagName,state){const{str,position,tokens}=state;const safeTagName=tagName.toLowerCase();const len=str.length;let index=position.index;while(index<len){const nextTag=str.indexOf("</",index);if(nextTag===-1){lexText(state);break}const tagStartPosition=copyPosition(position);jumpPosition(tagStartPosition,str,nextTag);const tagState={str:str,position:tagStartPosition,tokens:[]};const name=lexTag(tagState);if(safeTagName!==name.toLowerCase()){index=tagState.position.index;continue}if(nextTag!==position.index){const textStart=copyPosition(position);jumpPosition(position,str,nextTag);tokens.push({type:"text",content:str.slice(textStart.index,nextTag),position:{start:textStart,end:copyPosition(position)}})}push.apply(tokens,tagState.tokens);jumpPosition(position,str,tagState.position.index);break}}export function startsWith(str,searchString,position){return str.substr(position||0,searchString.length)===searchString}export function endsWith(str,searchString,position){const index=(position||str.length)-searchString.length;const lastIndex=str.lastIndexOf(searchString,index);return lastIndex!==-1&&lastIndex===index}export function stringIncludes(str,searchString,position){return str.indexOf(searchString,position||0)!==-1}export function isRealNaN(x){return typeof x==="number"&&isNaN(x)}export function arrayIncludes(array,searchElement,position){const len=array.length;if(len===0)return false;const lookupIndex=position|0;const isNaNElement=isRealNaN(searchElement);let searchIndex=lookupIndex>=0?lookupIndex:len+lookupIndex;while(searchIndex<len){const element=array[searchIndex++];if(element===searchElement)return true;if(isNaNElement&&isRealNaN(element))return true}return false}export function splitHead(str,sep){const idx=str.indexOf(sep);if(idx===-1)return[str];return[str.slice(0,idx),str.slice(idx+sep.length)]}export function unquote(str){const car=str.charAt(0);const end=str.length-1;const isQuoteStart=car==='"'||car==="'";if(isQuoteStart&&car===str.charAt(end)){return str.slice(1,end)}return str}export function format(nodes,options){return nodes.map(node=>{var outputNode={};const type=node.type;if(node.children){var textIndex=node.children?.findIndex(e=>{return e.type==="text"});if(textIndex!==-1){outputNode.content=node.children[textIndex]?.content?.trim();node.children.splice(textIndex,1)}}switch(type){case"element":var ATTRS=renderFormatAttributes(node.attributes);delete ATTRS.internal_tree_id;outputNode={...outputNode,type:type,tagName:node.tagName.toLowerCase(),attributes:ATTRS,children:format(node.children,options),id:node.id||generateTreeId()};break;default:outputNode={type:type,content:node.content?.trim()};break}if(options.includePositions){outputNode.position=node.position}return outputNode})}export function renderFormatAttributes(attributes){var ret={};Object.entries(attributes).forEach(([attribute,val])=>{const parts=splitHead(attribute.trim(),"=");const key=parts[0];const value=typeof parts[1]==="string"?unquote(parts[1]):null;var getValue=value=>{if(!value)return value;const trimmed=value.trim();const looksLikeJSON=trimmed.startsWith("[")||trimmed.startsWith("{")||trimmed.startsWith('"')&&trimmed.endsWith('"');if(looksLikeJSON){try{return JSON.parse(value)}catch(error){console.warn(`Failed to parse JSON attribute ${key}:`,value,error);return value}}return value};ret[key]=getValue(value)});return ret}export const parseDefaults={voidTags:voidTags,closingTags:closingTags,childlessTags:childlessTags,closingTagAncestorBreakers:closingTagAncestorBreakers,includePositions:false};export function generateTreeId(){return"node-"+uuidv4()}export function xudaPrase(str,options=parseDefaults){const tokens=lexer(str,options);const nodes=parser(tokens,options);return format(nodes,{...parseDefaults,...options})}export function xudaStringify(ast,options){return toHTML(ast,{...parseDefaults,...options})}
package/package.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "@xuda.io/xuda-cli-plugin-html-parser-module.esm.min",
3
+ "version": "1.0.0",
4
+ "main": "index.mjs",
5
+ "type": "module",
6
+ "description": "Auto-generated build for xuda-cli-plugin-html-parser-module.esm.min.mjs",
7
+ "author": "Auto Publisher"
8
+ }