From 68811eb3fc4a957556b9dec0b3f080cc8ba48199 Mon Sep 17 00:00:00 2001 From: Christian Brickhouse Date: Wed, 24 Feb 2021 18:58:11 -0800 Subject: [PATCH] Implementing magic item snippet from Issue 671. (#842) * Implementing magic item snippet from Issue 671. * Fixes syntax errors. Function moved into existing magic module. * Implementing magic item snippet from Issue 671. * Fixes syntax errors. Function moved into existing magic module. * Magic Item Snippet,
, `:` for blank line Co-authored-by: Trevor Buckner --- client/homebrew/editor/editor.jsx | 21 +++--- .../editor/snippetbar/snippets/magic.gen.js | 20 +++++- .../editor/snippetbar/snippets/snippets.js | 5 ++ client/homebrew/phbStyle/phb.style.less | 39 ++++++++++- scripts/buildHomebrew.js | 3 +- server.js | 2 +- shared/naturalcrit/markdown.js | 64 +++++++++++-------- 7 files changed, 110 insertions(+), 44 deletions(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index d2bf5c8368..467c60a44a 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -109,21 +109,14 @@ const Editor = createClass({ r.push(lineNumber); } - if(line.startsWith('\\column')){ + if(line.match(/^\\column$/)){ codeMirror.addLineClass(lineNumber, 'text', 'columnSplit'); r.push(lineNumber); } - if(line.startsWith('{{') || line.startsWith('}}')){ - let endCh = line.length+1; - const match = line.match(/{{(?:[\w,#-]|="[\w, ]*")*\s*|}}/); - if(match) - endCh = match.index+match[0].length; - codeMirror.markText({ line: lineNumber, ch: 0 }, { line: lineNumber, ch: endCh }, { className: 'block' }); - } - + // Highlight inline spans {{content}} if(line.includes('{{') && line.includes('}}')){ - const regex = /{{(?:[\w,#-]|="[\w, ]*")*\s*|}}/g; + const regex = /{{(?:="[\w,\-. ]*"|[^"'\s])*\s*|}}/g; let match; let blockCount = 0; while ((match = regex.exec(line)) != null) { @@ -138,6 +131,14 @@ const Editor = createClass({ } codeMirror.markText({ line: lineNumber, ch: match.index }, { line: lineNumber, ch: match.index + match[0].length }, { className: 'inline-block' }); } + } else if(line.trimLeft().startsWith('{{') || line.trimLeft().startsWith('}}')){ + // Highlight block divs {{\n Content \n}} + let endCh = line.length+1; + + const match = line.match(/^ *{{(?:="[\w,\-. ]*"|[^"'\s])*$|^ *}}$/); + if(match) + endCh = match.index+match[0].length; + codeMirror.markText({ line: lineNumber, ch: 0 }, { line: lineNumber, ch: endCh }, { className: 'block' }); } } diff --git a/client/homebrew/editor/snippetbar/snippets/magic.gen.js b/client/homebrew/editor/snippetbar/snippets/magic.gen.js index ed17f86922..31af3e7eb4 100644 --- a/client/homebrew/editor/snippetbar/snippets/magic.gen.js +++ b/client/homebrew/editor/snippetbar/snippets/magic.gen.js @@ -47,6 +47,12 @@ const spellNames = [ 'Ultimate Rite of the Confetti Angel', 'Ultimate Ritual of Mouthwash', ]; +const itemNames = [ + 'Doorknob of Niceness', + 'Paper Armor of Folding', + 'Mixtape of Sadness', + 'Staff of Endless Confetti', +]; module.exports = { @@ -87,5 +93,17 @@ module.exports = { 'A *continual flame* can be covered or hidden but not smothered or quenched.', '\n\n\n' ].join('\n'); + }, + + item : function() { + return [ + `#### ${_.sample(itemNames)}`, + `*${_.sample(['Wondrous item', 'Armor', 'Weapon'])}, ${_.sample(['Common', 'Uncommon', 'Rare', 'Very Rare', 'Legendary', 'Artifact'])} (requires attunement)*`, + `:`, + `This knob is pretty nice. When attached to a door, it allows a user to`, + `open that door with the strength of the nearest animal. For example, if`, + `there is a cow nearby, the user will have the "strength of a cow" while`, + `opening this door.` + ].join('\n'); } -}; \ No newline at end of file +}; diff --git a/client/homebrew/editor/snippetbar/snippets/snippets.js b/client/homebrew/editor/snippetbar/snippets/snippets.js index fc7393aa97..73246c5e31 100644 --- a/client/homebrew/editor/snippetbar/snippets/snippets.js +++ b/client/homebrew/editor/snippetbar/snippets/snippets.js @@ -143,6 +143,11 @@ module.exports = [ icon : 'fas fa-file-word', gen : CoverPageGen, }, + { + name : 'Magic Item', + icon : 'fas fa-hat-wizard', + gen : MagicGen.item, + }, ] }, diff --git a/client/homebrew/phbStyle/phb.style.less b/client/homebrew/phbStyle/phb.style.less index 792755adea..c4c38c5d1b 100644 --- a/client/homebrew/phbStyle/phb.style.less +++ b/client/homebrew/phbStyle/phb.style.less @@ -60,10 +60,10 @@ body { // *****************************/ p{ overflow-wrap : break-word; - padding-bottom : 0.8em; + padding-top : 0em; line-height : 1.3em; &+p{ - margin-top : -0.8em; + padding-top : 0em; } } ul{ @@ -478,3 +478,38 @@ body { margin-bottom : 10px; } } + +//***************************** +// * MUSTACHE DIVS/SPANS +// *****************************/ +.phb3 { + .inline-block { + display : block; + } +} + +//***************************** +// * DEFINITION LISTS +// *****************************/ +.phb3 { + // dl { + // margin-top: 10px; + // } + dt { + float: left; + //clear: left; //Doesn't seem necessary + margin-right: 5px; + } + // dd { + // margin-left: 0px; + // } +} + +//***************************** +// * BLANK LINE +// *****************************/ +.phb3 { + .blank { + height: 0.8em; + } +} diff --git a/scripts/buildHomebrew.js b/scripts/buildHomebrew.js index 43acd73185..6d77979354 100644 --- a/scripts/buildHomebrew.js +++ b/scripts/buildHomebrew.js @@ -19,7 +19,6 @@ const build = async ({ bundle, render, ssr })=>{ await fs.outputFile('./build/homebrew/bundle.css', css); await fs.outputFile('./build/homebrew/bundle.js', bundle); await fs.outputFile('./build/homebrew/ssr.js', ssr); - await fs.outputFile('./build/homebrew/render.js', render); //compress files in production if(!isDev){ @@ -48,6 +47,6 @@ pack('./client/homebrew/homebrew.jsx', { if(isDev){ livereload('./build'); watchFile('./server.js', { - watch : ['./homebrew'] // Watch additional folders if you want + watch : ['./client'] // Watch additional folders if you want }); } diff --git a/server.js b/server.js index 92a17c3018..c33a755aae 100644 --- a/server.js +++ b/server.js @@ -25,7 +25,7 @@ const config = require('nconf') //DB const mongoose = require('mongoose'); mongoose.connect(config.get('mongodb_uri') || config.get('mongolab_uri') || 'mongodb://localhost/naturalcrit', - { retryWrites: false, useNewUrlParser: true }); + { retryWrites: false, useNewUrlParser: true, useCreateIndex: true, useUnifiedTopology: true }); mongoose.connection.on('error', ()=>{ console.log('Error : Could not connect to a Mongo Database.'); console.log(' If you are running locally, make sure mongodb.exe is running.'); diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index 355620d1f6..38522488cf 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -11,6 +11,7 @@ renderer.html = function (html) { html = html.substring(0, html.lastIndexOf('')); return `${openTag} ${Markdown(html)} `; } + //if(html.startsWith('
')) // if(_.startsWith(_.trim(html), '')){ // const openTag = html.substring(0, html.indexOf('>')+1); // html = html.substring(html.indexOf('>')+1); @@ -21,46 +22,28 @@ renderer.html = function (html) { return html; }; -// Ensure {{ Divs don't confuse paragraph parsing (else it renders empty paragraphs) +// Don't render {{ Divs or {{ empty Spans on their own line inside a

renderer.paragraph = function(text){ + let match; if(text.startsWith('${text}

\n`; }; // Mustache-style Divs {{class \n content ... \n}} let blockCount = 0; -const blockRegex = /^ *{{(?:="[\w, ]*"|[^"'\s])*$|^ *}}$/gm; +const blockRegex = /^ *{{(?:="[\w,\-. ]*"|[^"'\s])*$|^ *}}$/gm; const inlineFullRegex = /{{[^\n]*}}/g; -const inlineRegex = /{{(?:="[\w, ]*"|[^"'\s])*\s*|}}/g; +const inlineRegex = /{{(?:="[\w,\-. ]*"|[^"'{}}\s])*\s*|}}/g; renderer.text = function(text){ const newText = text.replaceAll('"', '"'); let matches; - //DIV - BLOCK-LEVEL - if(matches = newText.match(blockRegex)) { - 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(`
`); - blockCount++; - } else if(block == '}}' && blockCount !== 0){ - r.push('
'); - blockCount--; - } - - matchIndex++; - - return r; - }, []).join(''); - return res; - } else if(matches = newText.match(inlineFullRegex)) { + if(matches = newText.match(inlineFullRegex)) { //SPAN - INLINE matches = newText.match(inlineRegex); @@ -72,7 +55,7 @@ renderer.text = function(text){ const block = matches[matchIndex] ? matches[matchIndex].trimLeft() : ''; if(block && block.startsWith('{{')) { const values = processStyleTags(block.substring(2)); - r.push(``); blockCount++; } else if(block == '}}' && blockCount !== 0){ r.push(''); @@ -84,7 +67,28 @@ renderer.text = function(text){ return r; }, []).join(''); return `${res}`; - } else { + } else if(matches = newText.match(blockRegex)) { + //DIV - BLOCK-LEVEL + 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(`
`); + blockCount++; + } else if(block == '}}' && blockCount !== 0){ + r.push('
'); + blockCount--; + } + + matchIndex++; + + return r; + }, []).join(''); + return res; + } else { if(!matches) { return `${text}`; } @@ -188,9 +192,13 @@ module.exports = { marked : Markdown, render : (rawBrewText)=>{ blockCount = 0; - rawBrewText = rawBrewText.replace(/^\\column/gm, `
`) + rawBrewText = rawBrewText.replace(/^\\column$/gm, `
`) + .replace(/^(:+)$/gm, (match)=>`${`
`.repeat(match.length)}\n`) + .replace(/(?:^|>) *:([^:\n]*):([^\n]*)\n/gm, (match, term, def)=>`
${Markdown.parseInline(term)}
${def}
`) + .replace(/(
.*<\/dt>
.*<\/dd>\n?)+/gm, `
$1
\n\n`) .replace(/^}}/gm, '\n}}') .replace(/^({{[^\n]*)$/gm, '$1\n'); + console.log(rawBrewText); return Markdown( sanatizeScriptTags(rawBrewText), { renderer: renderer }