import { REGEX } from '../../Regex' ; import { TemplateBodyType , TemplateType } from '../../schema/templates/Templates' ; import { Logger } from '../Logger' ; export interface Renderer { toTemplate : ( type : TemplateType , attribs : { [ k ] : any ; } , body : TemplateBodyType , line : number ) => any ; toTrigger : ( attribs : { [ k ] : any ; } , line : number ) => any ; toQuest : ( attribs : { [ k ] : any ; } , line : number ) => any ; finalize : ( quest : any , inner : any [ ] ) => any ; validate : ( rendered : any , log ? : Logger ) => void ; } export function sanitizeStyles ( text ) { const ops = [ ] ; let startOfCapture ; const syntaxStack = [ ] ; for ( let i = 0 ; i < text . length ; i ++ ) { const c1 = text [ i ] ; const c2 = text [ i + 1 ] ; if ( syntaxStack . length > 0 ) { const lastSyntax = syntaxStack [ syntaxStack . length - 1 ] ; if ( c1 === '\\' ) { i ++ ; } else if ( c1 === '"' ) { if ( lastSyntax !== c1 ) { syntaxStack . push ( c1 ) ; } else { syntaxStack . pop ( ) ; } } else if ( lastSyntax !== '"' && c1 === '}' && c2 === '}' ) { let openCurlyCount = 0 ; for ( const s of syntaxStack ) { openCurlyCount += ( s === '{' ) ? 1 : 0 ; } if ( openCurlyCount < 2 ) { syntaxStack . pop ( ) ; const endOfCapture = i ; const op = text . slice ( startOfCapture , endOfCapture ) ; ops . push ( op ) ; text = text . slice ( 0 , startOfCapture ) + text . slice ( endOfCapture ) ; i -= op . length ; } } else if ( c1 === '{' ) { syntaxStack . push ( c1 ) ; } else if ( c1 === '}' && lastSyntax === '{' ) { syntaxStack . pop ( ) ; } } else if ( c1 === '{' && c2 === '{' ) { syntaxStack . push ( '{{' ) ; startOfCapture = i + 2 ; i ++ ; } } const artOrIcon = new RegExp ( `(${ REGEX . ART . source }|${ REGEX . ICON . source })` , 'g' ) ; const art = [ ] ; let matches = artOrIcon . exec ( text ) ; while ( matches ) { art . push ( matches [ 1 ] ) ; matches = artOrIcon . exec ( text ) ; } text = text . replace ( artOrIcon , '[art]' ) ; text = text . replace ( /<strong>(.*?)<\/strong>/igm , '**$1**' ) ; text = text . replace ( /<b>(.*?)<\/b>/igm , '**$1**' ) ; text = text . replace ( /<em>(.*?)<\/em>/igm , '*$1*' ) ; text = text . replace ( /<i>(.*?)<\/i>/igm , '*$1*' ) ; text = text . replace ( /<del>(.*?)<\/del>/igm , '~~$1~~' ) ; text = text . replace ( new RegExp ( REGEX . HTML_TAG . source , 'g' ) , '' ) ; text = text . replace ( new RegExp ( REGEX . NEWLINE . source , 'g' ) , '<br/>' ) ; text = text . replace ( new RegExp ( REGEX . BOLD_ASTERISKS . source , 'g' ) , '<b>$1</b>' ) ; text = text . replace ( new RegExp ( REGEX . BOLD_UNDERSCORES . source , 'g' ) , '<b>$1</b>' ) ; text = text . replace ( new RegExp ( REGEX . ITALIC_ASTERISKS . source , 'g' ) , '<i>$1</i>' ) ; text = text . replace ( new RegExp ( REGEX . ITALIC_UNDERSCORES . source , 'g' ) , '<i>$1</i>' ) ; text = text . replace ( new RegExp ( REGEX . STRIKETHROUGH . source , 'g' ) , '<del>$1</del>' ) ; text = text . replace ( /{{}}/g , ( ) => '{{' + ops . shift ( ) + '}}' ) ; text = text . replace ( /\[art\]/g , ( ) => { const a = art . shift ( ) ; if ( a === undefined ) { throw new Error ( 'Mismatch in [art] tag vs captured art' ) ; } return a ; } ) ; return text ; }