@bbob/parser
Version:
A BBCode to AST Parser part of @bbob
2 lines (1 loc) • 9.13 kB
JavaScript
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).BbobParser={})}(this,function(t){"use strict";let e="[",r="]";function n(t){return"object"==typeof t&&null!==t&&"tag"in t}function s(t,e,r){return Object.keys(t).reduce((r,n)=>e(r,n,t),r)}function i(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/(javascript|data|vbscript|file):/gi,"$1%3A")}function a(t,e){switch(typeof e){case"boolean":return e?""+t:"";case"number":return`${t}="${e}"`;case"string":return`${t}="${i(e)}"`;case"object":return`${t}="${i(JSON.stringify(e))}"`;default:return""}}function o(t){return null==t?"":s(t,(t,e,r)=>[...t,a(e,r[e])],[""]).join(" ")}let u=(t,e)=>{let r=s(e||{},(t,e,r)=>r[e]===e?r[e]:null,null);if(r){let n=a(t,r),s={...e};delete s[r+""];let i=o(s);return`${n}${i}`}return`${t}${o(e)}`},l=(t,e,r)=>n(t)?t.toString({openTag:e,closeTag:r}):t+"",h=(t,e,r)=>Array.isArray(t)?t.reduce((t,n)=>null!==n?t+l(n,e,r):t,""):t?l(t,e,r):null;class c{get length(){return function t(e){return n(e)&&Array.isArray(e.content)?e.content.reduce((e,r)=>e+t(r),0):"string"==typeof e?(e+"").length:0}(this)}attr(t,e){return void 0!==e&&(this.attrs[t]=e),this.attrs[t]}append(t){Array.isArray(this.content)&&this.content.push(t)}setStart(t){this.start=t}setEnd(t){this.end=t}toTagStart({openTag:t=e,closeTag:n=r}={}){let s=u(this.tag+"",this.attrs);return`${t}${s}${n}`}toTagEnd({openTag:t=e,closeTag:n=r}={}){return`${t}/${this.tag}${n}`}toTagNode(){return new c(this.tag,this.attrs,this.content,this.start,this.end)}toString({openTag:t=e,closeTag:n=r}={}){let s=this.content?h(this.content,t,n):"",i=this.toTagStart({openTag:t,closeTag:n});return null===this.content||Array.isArray(this.content)&&0===this.content.length?i:`${i}${s}${this.toTagEnd({openTag:t,closeTag:n})}`}toJSON(){return{tag:this.tag,attrs:this.attrs,content:this.content,start:this.start,end:this.end}}static create(t,e={},r=null,n){return new c(t,e,r,n)}static isOf(t,e){return t.tag===e}constructor(t,e,r,n,s){this.tag=t,this.attrs=e,this.content=r,this.start=n,this.end=s}}let g=t=>t&&void 0!==t.v?t.v:"",f=t=>t&&t.l||0,p=t=>t&&t.r||0,d=t=>t&&t.s||0,T=t=>t&&t.e||0,b=t=>!!t&&void 0!==t.t&&(5===t.t||6===t.t||1===t.t),y=t=>!!t&&void 0!==t.t&&2===t.t,x=t=>47===g(t).charCodeAt(0),k=t=>!x(t),w=t=>!!t&&void 0!==t.t&&3===t.t,C=t=>!!t&&void 0!==t.t&&4===t.t,A=t=>{let e=g(t);return x(t)?e.slice(1):e},N=(t,n=e,s=r)=>n+(g(t)+s);class ${get type(){return this.t}isEmpty(){return 0===this.t||isNaN(this.t)}isText(){return b(this)}isTag(){return y(this)}isAttrName(){return w(this)}isAttrValue(){return C(this)}isStart(){return k(this)}isEnd(){return x(this)}getName(){return A(this)}getValue(){return g(this)}getLine(){return f(this)}getColumn(){return p(this)}getStart(){return d(this)}getEnd(){return T(this)}toString({openTag:t=e,closeTag:n=r}={}){return N(this,t,n)}constructor(t,e,r=0,n=0,s=0,i=0){this.l=r,this.r=n,this.t=t||0,this.v=e+"",this.s=s,this.e=i}}class v{skip(t=1,e){this.c.pos+=t,this.o&&this.o.onSkip&&!e&&this.o.onSkip()}hasNext(){return this.c.len>this.c.pos}getCurr(){return void 0===this.s[this.c.pos]?"":this.s[this.c.pos]}getPos(){return this.c.pos}getLength(){return this.c.len}getRest(){return this.s.substring(this.c.pos)}getNext(){let t=this.c.pos+1;return t<=this.s.length-1?this.s[t]:null}getPrev(){let t=this.c.pos-1;return void 0===this.s[t]?null:this.s[t]}isLast(){return this.c.pos===this.c.len}includes(t){return this.s.indexOf(t,this.c.pos)>=0}grabWhile(t,e){let r=0;if(this.hasNext())for(r=this.c.pos;this.hasNext()&&t(this.getCurr());)this.skip(1,e);return this.s.substring(r,this.c.pos)}grabN(t=0){return this.s.substring(this.c.pos,this.c.pos+t)}substrUntilChar(t){let{pos:e}=this.c,r=this.s.indexOf(t,e);return r>=0?this.s.substring(e,r):""}constructor(t,e={}){this.s=t,this.c={pos:0,len:t.length},this.o=e}}let S=(t,e)=>new v(t,e),L=(t,e)=>{for(;t.charAt(0)===e;)t=t.substring(1);for(;t.charAt(t.length-1)===e;)t=t.substring(0,t.length-1);return t},O=t=>t.replace('\\"','"');function m(t,e,r=0,n=0,s=0,i=0){return new $(t,e,r,n,s,i)}let E=[" "," "],P=["="," "," "],W=t=>E.indexOf(t)>=0,j=t=>"\\"===t,F=t=>P.indexOf(t)>=0,V=t=>"\n"===t,z=t=>O(L(t,'"'));function B(t,n={}){let s=0,i=0,a=0,o=-1,u=0,l=0,h="",c=Array(Math.floor(t.length)),g=n.openTag||e,f=n.closeTag||r,p=!!n.enableEscapeTags,d=(n.contextFreeTags||[]).filter(Boolean).map(t=>t.toLowerCase()),T=n.caseFreeTags||!1,b=new Map,y=n.onToken||(()=>{}),x=[f,g,'"',"\\"," "," ","=","\n","!"],k=[g," "," ","\n"],w=t=>x.indexOf(t)>=0,C=t=>-1===k.indexOf(t),A=t=>t===g||t===f||"\\"===t,N=()=>{a++},$=(t,e)=>{""!==h&&e&&(h="");let r=t.toLowerCase();""===h&&E(t)&&d.includes(r)&&(h=r)},v=t=>`${g}/${t}${f}`,L=S(t,{onSkip:N});function O(t,e,r,n){let u=m(t,e,s,i,r,n);y(u),i=a,c[o+=1]=u}function E(e){let r=v(e);if(b.has(r))return!!b.get(r);{let e=T?t.toLowerCase():t,n=T?r.toLowerCase():r,s=e.indexOf(n)>-1;return b.set(r,s),s}}return{tokenize:function(){for(u=0;L.hasNext();)switch(u){case 1:u=function(){let t=L.getCurr(),e=L.getNext(),r=!!(e&&w(e));L.skip();let s=L.substrUntilChar(f),i=0===s.length||s.indexOf(g)>=0,a=L.isLast(),o=s.indexOf(" ")>=0&&!1===n.whitespaceInTags;if(r||i||a||o)return O(1,t),0;let u=-1===s.indexOf("="),l="/"===s[0];if(u||l){let t=L.getPos()-1,e=L.grabWhile(t=>t!==f),r=t+e.length+2;return L.skip(),O(2,e,t,r),$(e,l),0}return 2}();break;case 2:u=function(){let t=L.getPos(),e=L.grabWhile(t=>t!==f,!0),r=S(e,{onSkip:N}),n=e.split("=")[0],s="/"===n[0],a=-1===n.indexOf(" "),o=!s&&a;for(l=0;r.hasNext();)l=function(t,e,r){if(1===l){let e=t.grabWhile(t=>!("="===t||W(t))),r=t.isLast(),n="="!==t.getCurr();return(t.skip(),r||n?O(4,z(e)):O(3,e),r)?0:n?1:2}if(2===l){let r=!1,n=t.grabWhile(n=>{let s='"'===n,i=t.getPrev(),a=t.getNext(),o="="===a,u=W(n),l=!!a&&W(a);return!!(r&&F(n))||(!s||"\\"===i||!!(r=!r)||!!o||!!l)&&(!!e||!u)});return(t.skip(),O(4,z(n)),'"'===t.getPrev()&&i++,t.isLast())?0:1}let n=r+t.getPos()-1,s=t.grabWhile(e=>!("="===e||W(e)||t.isLast()));return(O(2,s,n,r+t.getLength()+1),$(s),t.skip(),i++,e)?2:t.includes("=")?1:2}(r,o,t);return L.skip(),0}();break;default:u=function(){if(V(L.getCurr()))return O(6,L.getCurr()),L.skip(),a=0,i=0,s++,0;if(W(L.getCurr()))return O(5,L.grabWhile(W)),0;if(L.getCurr()===g){if(h){let t=v(h);if(L.grabN(t.length).toLowerCase()===t.toLowerCase())return 1}else if(L.includes(f))return 1;return O(1,L.getCurr()),L.skip(),i++,0}if(p){if(j(L.getCurr())){let t=L.getCurr(),e=L.getNext();return(L.skip(),e&&A(e))?(L.skip(),O(1,e)):O(1,t),0}return O(1,L.grabWhile(t=>C(t)&&!j(t))),0}return O(1,L.grabWhile(C)),0}()}return c.length=o+1,c},isTokenNested:E}}class I{last(){let t=this.n.length;if(t>0)return this.n[t-1]}has(){return this.n.length>0}flush(){return this.n.length?this.n.pop():void 0}push(t){this.n.push(t)}ref(){return this.n}constructor(){this.n=[]}}let M=()=>new I;function J(t,s={}){let i=s.openTag||e,a=s.closeTag||r,o=(s.onlyAllowTags||[]).filter(Boolean).map(t=>t.toLowerCase()),u=s.caseFreeTags||!1,l=null,h=M(),g=M(),f=null,p=null,d=new Set;function T(t){return u?t.toLowerCase():t}function b(t){return!!d.has(T(t))}function y(){f&&(f=null,p=null)}function x(){let t=g.last();return t&&n(t)?t.content:h.ref()}function k(t,e,r=!0){Array.isArray(t)&&void 0!==e&&(t.push(e.toTagStart({openTag:i,closeTag:a})),Array.isArray(e.content)&&e.content.length&&(e.content.forEach(e=>{t.push(e)}),r&&t.push(e.toTagEnd({openTag:i,closeTag:a}))))}function w(t){let e=x();if(Array.isArray(e)&&void 0!==t){if(n(t)){var r;(r=t.tag,!o.length||o.indexOf(r.toLowerCase())>=0)?e.push(t.toTagNode()):k(e,t)}else e.push(t)}}(l=(s.createTokenizer?s.createTokenizer:B)(t,{onToken:function(t){t.isTag()?(t.isStart()&&function(t){y();let e=c.create(t.getValue(),{},[],{from:t.getStart(),to:t.getEnd()}),r=function(t){let e=T(t.getValue()),{isTokenNested:r}=l||{};return!d.has(e)&&"function"==typeof r&&r(e)?(d.add(e),!0):d.has(e)}(t);f=e,r?g.push(e):w(e)}(t),t.isEnd()&&function(t){let e=t.getValue().slice(1),r=g.flush();if(y(),r)n(r)&&r.setEnd({from:t.getStart(),to:t.getEnd()}),w(r);else if(b(e)){if("function"==typeof s.onError){let e=t.getValue(),r=t.getLine(),n=t.getColumn();s.onError({tagName:e,lineNumber:r,columnNumber:n})}}else w(t.toString({openTag:i,closeTag:a}))}(t)):function(t){let e=t.getValue(),r=b(t.toString());if(f)switch(t.type){case 3:p=e,e&&f.attr(e,"");break;case 4:p?(f.attr(p,e),p=null):f.attr(e,e);break;case 5:case 6:case 1:r?f.append(e):w(e);break;case 2:w(t.toString({openTag:i,closeTag:a}))}else t.isText()?w(e):t.isTag()&&w(t.toString({openTag:i,closeTag:a}))}(t)},openTag:i,closeTag:a,onlyAllowTags:s.onlyAllowTags,contextFreeTags:s.contextFreeTags,caseFreeTags:s.caseFreeTags,enableEscapeTags:s.enableEscapeTags,whitespaceInTags:s.whitespaceInTags})).tokenize();do{let t=g.flush();n(t)&&b(t.tag)?k(x(),t,!1):void 0!==t&&w(t)}while(g.has());return h.ref()}t.TagNode=c,t.createLexer=B,t.createTokenOfType=m,t.default=J,t.parse=J,Object.defineProperty(t,"__esModule",{value:!0})});