import { WikiFile } from './wiki-file' ; import { StoredFile } from './stored-file' ; import { TagIndexService } from './tag-index.service' ; import { Settings } from './settings' ; import { Queue } from './queue' ; import { LoggingService } from './logging-service' ; import { Injectable } from '@angular/core' ; import * as marked from 'marked' ; import * as XRegExp from 'xregexp' ; @ Injectable ( ) export class MarkdownerService { constructor ( private settings , private tagIndexService , private loggingService ) { this . initializeRegex ( ) ; } private wikiWordsRegex ; private htmlTagsRegex = XRegExp ( '\<a\s.+?\<\/a\>|\<[^\>]+\>' , 'g' ) ; private usedCurly : boolean ; static createWikiLink ( wikiword ) { return `<a href="ema:${ encodeURI ( wikiword ) }">${ wikiword }</a>` ; } private initializeRegex ( ) { this . wikiWordsRegex = XRegExp ( '(~)?' + '(?:' + '(?<wikiword1>' + '\\p{Lu}' + '\\p{Ll}+' + '\\p{Lu}' + '\\w*)' + ( this . settings . getUseCurly ( ) ? '|' + '\\{' + '(?<wikiword2>' + '[^\{\\}]+' + ')\\}' : '' ) + '|' + '\\[\\[' + '(?<wikiword3>' + '[^\\]]+' + ')\\]\\]' + ')' , 'gx' ) ; this . usedCurly = this . settings . getUseCurly ( ) ; } process ( storedFile ) { const emaPlaceholder = '<ema-placeholder>' ; return new Promise ( ( resolve , reject ) => { let result ; try { if ( ! storedFile . contents ) { result = new WikiFile ( '' , '' ) ; result . tags = [ ] ; resolve ( result ) ; return ; } const tagsFromContent = this . tagIndexService . separateTagsFromContent ( storedFile . contents . toString ( ) ) ; const tags = tagsFromContent . tags ; const markedDown = marked ( tagsFromContent . strippedContent ) ; const queue = new Queue < string > ( ) ; const protectedMarkedDown = markedDown . replace ( this . htmlTagsRegex , match => { queue . enqueue ( match ) ; return emaPlaceholder ; } ) ; const wikiworded = this . wikiword ( protectedMarkedDown ) ; const processed = wikiworded . replace ( this . htmlTagsRegex , match => { if ( match === emaPlaceholder ) { return queue . dequeue ( ) ; } return match ; } ) ; result = new WikiFile ( storedFile . contents . toString ( ) , processed ) ; result . tags = tags ; resolve ( result ) ; } catch ( err ) { this . loggingService . log ( 'Error markdowning ' + name , err ) ; result = new WikiFile ( storedFile . contents . toString ( ) , '<strong>File could not be parsed</strong><pre>' + storedFile . contents + '</pre>' ) ; resolve ( result ) ; } } ) ; } private wikiword ( markdown ) { if ( this . settings . getUseCurly ( ) !== this . usedCurly ) { this . initializeRegex ( ) ; } return markdown . replace ( this . wikiWordsRegex , this . replacer ) ; } private replacer ( ) { const marker = arguments [ 1 ] ; if ( marker ) { return ( arguments [ 0 ] as string ) . substring ( 1 ) ; } const wikiwordByCase = arguments [ 2 ] as string ; const wikiwordByCurly = arguments [ 3 ] as string ; const wikiwordByDoubleSquare = arguments [ 4 ] as string ; const wikiword = wikiwordByCase || wikiwordByCurly || wikiwordByDoubleSquare ; const wikiLink = MarkdownerService . createWikiLink ( wikiword ) ; return wikiLink ; } }