import { parseBBCodeTag } from 'pretty-text/engines/discourse-markdown/bbcode-block'; function tokanizeBBCode(state, silent, ruler) { let pos = state.pos; // 91 = [ if (silent || state.src.charCodeAt(pos) !== 91) { return false; } const tagInfo = parseBBCodeTag(state.src, pos, state.posMax); if (!tagInfo) { return false; } let rule, i; let ruleInfo = ruler.getRuleForTag(tagInfo.tag); if (!ruleInfo) { return false; } rule = ruleInfo.rule; if (rule.replace) { // special handling for replace // we pass raw contents to callback so we simply need to greedy match to end tag if (tagInfo.closing) { return false; } let closeTag = '[/' + tagInfo.tag + ']'; let found = false; for(i=state.pos+tagInfo.length; i<=state.posMax-closeTag.length; i++) { if (state.src.charCodeAt(pos) === 91 && state.src.slice(i, i + closeTag.length).toLowerCase() === closeTag) { found = true; break; } } if (!found) { return false; } let content = state.src.slice(state.pos+tagInfo.length, i); if (rule.replace(state, tagInfo, content)) { state.pos = i + closeTag.length; return true; } else { return false; } } else { tagInfo.rule = rule; let token = state.push('text', '' , 0); token.content = state.src.slice(pos, pos+tagInfo.length); token.meta = 'bbcode'; state.delimiters.push({ bbInfo: tagInfo, marker: 'bb' + tagInfo.tag, open: !tagInfo.closing, close: !!tagInfo.closing, token: state.tokens.length - 1, level: state.level, end: -1, jump: 0 }); state.pos = pos + tagInfo.length; return true; } } function processBBCode(state, silent) { let i, startDelim, endDelim, token, tagInfo, delimiters = state.delimiters, max = delimiters.length; if (silent) { return; } for (i=0; i { opts.features['bbcode-inline'] = true; }); helper.registerPlugin(md => { const ruler = md.inline.bbcode.ruler; md.inline.ruler.push('bbcode-inline', (state,silent) => tokanizeBBCode(state,silent,ruler)); md.inline.ruler2.before('text_collapse', 'bbcode-inline', processBBCode); ruler.push('code', { tag: 'code', replace: function(state, tagInfo, content) { let token; token = state.push('code_inline', 'code', 0); token.content = content; return true; } }); const simpleUrlRegex = /^http[s]?:\/\//; ruler.push('url', { tag: 'url', wrap: function(startToken, endToken, tagInfo, content) { const url = (tagInfo.attrs['_default'] || content).trim(); if (simpleUrlRegex.test(url)) { startToken.type = 'link_open'; startToken.tag = 'a'; startToken.attrs = [['href', url], ['data-bbcode', 'true']]; startToken.content = ''; startToken.nesting = 1; endToken.type = 'link_close'; endToken.tag = 'a'; endToken.content = ''; endToken.nesting = -1; } else { // just strip the bbcode tag endToken.content = ''; startToken.content = ''; // edge case, we don't want this detected as a onebox if auto linked // this ensures it is not stripped startToken.type = 'html_inline'; } return false; } }); ruler.push('email', { tag: 'email', replace: function(state, tagInfo, content) { let token; let email = tagInfo.attrs['_default'] || content; token = state.push('link_open', 'a', 1); token.attrs = [['href', 'mailto:' + email], ['data-bbcode', 'true']]; token = state.push('text', '', 0); token.content = content; token = state.push('link_close', 'a', -1); return true; } }); ruler.push('image', { tag: 'img', replace: function(state, tagInfo, content) { let token = state.push('image', 'img', 0); token.attrs = [['src', content],['alt','']]; token.children = []; return true; } }); ruler.push('bold', { tag: 'b', wrap: 'span.bbcode-b', }); ruler.push('italic', { tag: 'i', wrap: 'span.bbcode-i' }); ruler.push('underline', { tag: 'u', wrap: 'span.bbcode-u' }); ruler.push('strike', { tag: 's', wrap: 'span.bbcode-s' }); }); }