0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-18 05:42:48 +00:00

MustacheDivs to Marked.js extension

This commit is contained in:
Trevor Buckner
2021-07-11 00:33:47 -04:00
parent 63ba9f4fb9
commit 50991dfe92

View File

@@ -20,8 +20,8 @@ renderer.paragraph = function(text){
if(text.startsWith('<div') || text.startsWith('</div')) if(text.startsWith('<div') || text.startsWith('</div'))
return `${text}`; return `${text}`;
else if(match = text.match(/(^|^.*?\n)<span class="inline(.*?<\/span>)$/)) { else if(match = text.match(/(^|^.*?\n)<span class="inline(.*?<\/span>)$/)) {
return `${match[1].trim() ? `<p>${match[1]}</p>` : ''}<span class="inline-block${match[2]}`; } return `${match[1].trim() ? `<p>${match[1]}</p>` : ''}<span class="inline-block${match[2]}`;
else } else
return `<p>${text}</p>\n`; return `<p>${text}</p>\n`;
}; };
@@ -31,7 +31,7 @@ const mustacheSpans = {
start(src) { return src.match(/{{[^{]/)?.index; }, // Hint to Marked.js to stop and check for a match start(src) { return src.match(/{{[^{]/)?.index; }, // Hint to Marked.js to stop and check for a match
tokenizer(src, tokens) { tokenizer(src, tokens) {
const completeSpan = /^{{[^\n]*}}/; // Regex for the complete token const completeSpan = /^{{[^\n]*}}/; // Regex for the complete token
const inlineRegex = /{{(?:="[\w,\-. ]*"|[^"'{}}\s])*\s*|}}/g; const inlineRegex = /{{(?:="[\w,\-. ]*"|[^"'{}\s])*\s*|}}/g;
const match = completeSpan.exec(src); const match = completeSpan.exec(src);
if(match) { if(match) {
//Find closing delimiter //Find closing delimiter
@@ -41,10 +41,9 @@ const mustacheSpans = {
let delim; let delim;
while (delim = inlineRegex.exec(match[0])) { while (delim = inlineRegex.exec(match[0])) {
if(delim[0].startsWith('{{')) { if(delim[0].startsWith('{{')) {
tags = tags || ' ' + processStyleTags(delim[0].substring(2)); tags = tags || ` ${processStyleTags(delim[0].substring(2))}`;
blockCount++; blockCount++;
} } else if(delim[0] == '}}' && blockCount !== 0) {
else if(delim[0] == '}}' && blockCount !== 0) {
blockCount--; blockCount--;
if(blockCount == 0) { if(blockCount == 0) {
endIndex = inlineRegex.lastIndex; endIndex = inlineRegex.lastIndex;
@@ -55,7 +54,7 @@ const mustacheSpans = {
if(endIndex) { if(endIndex) {
const raw = src.slice(0, endIndex); const raw = src.slice(0, endIndex);
const text = raw.slice((raw.indexOf(' ')+1) || -2, -2) const text = raw.slice((raw.indexOf(' ')+1) || -2, -2);
return { // Token to generate return { // Token to generate
type : 'mustacheSpans', // Should match "name" above type : 'mustacheSpans', // Should match "name" above
@@ -63,58 +62,62 @@ const mustacheSpans = {
text : text, // Additional custom properties text : text, // Additional custom properties
tags : tags, tags : tags,
tokens : this.inlineTokens(text) // inlineTokens to process **bold**, *italics*, etc. tokens : this.inlineTokens(text) // inlineTokens to process **bold**, *italics*, etc.
} };
} }
} }
}, },
renderer(token) { renderer(token) {
console.log(token);
return `<span class="inline${token.tags}>${this.parseInline(token.tokens)}</span>`; // parseInline to turn child tokens into HTML return `<span class="inline${token.tags}>${this.parseInline(token.tokens)}</span>`; // parseInline to turn child tokens into HTML
} }
}; };
Markdown.use({extensions : [mustacheSpans]}); const mustacheDivs = {
name : 'mustacheDivs',
// Mustache-style Divs {{class \n content ... \n}} level : 'block',
start(src) { return src.match(/^ *{{[^{]/)?.index; }, // Hint to Marked.js to stop and check for a match
tokenizer(src, tokens) {
const completeBlock = /^ *{{.*\n *}}/s; // Regex for the complete token
const blockRegex = /^ *{{(?:="[\w,\-. ]*"|[^"'{}\s])*$|^ *}}$/gm;
const match = completeBlock.exec(src);
if(match) {
//Find closing delimiter
let blockCount = 0; let blockCount = 0;
const blockRegex = /^ *{{(?:="[\w,\-. ]*"|[^"'\s])*$|^ *}}$/gm; let tags = '';
const inlineFullRegex = /{{[^\n]*}}/g; let endIndex = 0;
const inlineRegex = /{{(?:="[\w,\-. ]*"|[^"'{}}\s])*\s*|}}/g; let delim;
while (delim = blockRegex.exec(match[0])?.[0].trim()) {
renderer.text = function(text){ if(delim.startsWith('{{')) {
const newText = text.replaceAll('&quot;', '"'); tags = tags || ` ${processStyleTags(delim.substring(2))}`;
let matches;
if(matches = newText.match(blockRegex)) {
//DIV - BLOCK-LEVEL
console.log({match: matches});
console.log({newText: newText});
let matchIndex = 0;
const res = _.reduce(newText.split(blockRegex), (r, splitText)=>{
if(splitText) r.push(Markdown.parseInline(splitText, { renderer: renderer }));
const block = matches[matchIndex] ? matches[matchIndex].trimLeft() : '';
if(block && block.startsWith('{')) {
const values = processStyleTags(block.substring(2));
r.push(`<div class="block ${values}">`);
blockCount++; blockCount++;
} else if(block == '}}' && blockCount !== 0){ } else if(delim == '}}' && blockCount !== 0) {
r.push('</div>');
blockCount--; blockCount--;
if(blockCount == 0) {
endIndex = blockRegex.lastIndex;
break;
}
}
} }
matchIndex++; if(endIndex) {
const raw = src.slice(0, endIndex);
return r; const text = raw.slice((raw.indexOf('\n')+1) || -2, -2);
}, []).join(''); return { // Token to generate
return res; type : 'mustacheDivs', // Should match "name" above
} else { raw : raw, // Text to consume from the source
if(!matches) { text : text, // Additional custom properties
return `${text}`; tags : tags,
tokens : this.inline(this.blockTokens(text))
};
} }
} }
},
renderer(token) {
return `<div class="block${token.tags}>${this.parse(token.tokens)}</div>`; // parseInline to turn child tokens into HTML
}
}; };
Markdown.use({ extensions: [mustacheSpans, mustacheDivs] });
//Fix local links in the Preview iFrame to link inside the frame //Fix local links in the Preview iFrame to link inside the frame
renderer.link = function (href, title, text) { renderer.link = function (href, title, text) {
let self = false; let self = false;
@@ -211,7 +214,6 @@ const processStyleTags = (string)=>{
module.exports = { module.exports = {
marked : Markdown, marked : Markdown,
render : (rawBrewText)=>{ render : (rawBrewText)=>{
blockCount = 0;
rawBrewText = rawBrewText.replace(/^\\column$/gm, `<div class='columnSplit'></div>`) rawBrewText = rawBrewText.replace(/^\\column$/gm, `<div class='columnSplit'></div>`)
.replace(/^(:+)$/gm, (match)=>`${`<div class='blank'></div>`.repeat(match.length)}\n`) .replace(/^(:+)$/gm, (match)=>`${`<div class='blank'></div>`.repeat(match.length)}\n`)
.replace(/(?:^|>) *:([^:\n]*):([^\n]*)\n/gm, (match, term, def)=>`<dt>${Markdown.parseInline(term)}</dt><dd>${def}</dd>`) .replace(/(?:^|>) *:([^:\n]*):([^\n]*)\n/gm, (match, term, def)=>`<dt>${Markdown.parseInline(term)}</dt><dd>${def}</dd>`)