diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 12cb0aa37..ebfd74060 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -131,7 +131,7 @@ const Editor = createClass({ // Highlight inline spans {{content}} if(line.includes('{{') && line.includes('}}')){ - const regex = /{{(?:="[\w,\-. ]*"|[^"'\s])*\s*|}}/g; + const regex = /{{(?::(?:"[\w,\-()#%. ]*"|[\w\,\-()#%.]*)|[^"'{}\s])*\s*|}}/g; let match; let blockCount = 0; while ((match = regex.exec(line)) != null) { @@ -150,7 +150,7 @@ const Editor = createClass({ // Highlight block divs {{\n Content \n}} let endCh = line.length+1; - const match = line.match(/^ *{{(?:="[\w,\-. ]*"|[^"'\s])*$|^ *}}$/); + 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' }); diff --git a/client/homebrew/editor/snippetbar/snippets/snippets.js b/client/homebrew/editor/snippetbar/snippets/snippets.js index 9abedcf28..e61289b6b 100644 --- a/client/homebrew/editor/snippetbar/snippets/snippets.js +++ b/client/homebrew/editor/snippetbar/snippets/snippets.js @@ -33,7 +33,7 @@ module.exports = [ { name : 'Horizontal Spacing', icon : 'fas fa-arrows-alt-h', - gen : ' {{width="100px"}} ' + gen : ' {{width:100px}} ' }, { name : 'Wide Block', @@ -51,23 +51,22 @@ module.exports = [ name : 'Image', icon : 'fas fa-image', gen : dedent` - ![cat warrior](https://s-media-cache-ak0.pinimg.com/736x/4a/81/79/4a8179462cfdf39054a418efd4cb743e.jpg) {width="325px"} + ![cat warrior](https://s-media-cache-ak0.pinimg.com/736x/4a/81/79/4a8179462cfdf39054a418efd4cb743e.jpg) {width:325px} Credit: Kyounghwan Kim` }, { name : 'Background Image', icon : 'fas fa-tree', - gen : `![homebrew mug](http://i.imgur.com/hMna6G0.png) {position="absolute",top="50px",right="30px",width="280px"}` + gen : `![homebrew mug](http://i.imgur.com/hMna6G0.png) {position:absolute,top:50px,right:30px,width:280px}` }, { name : 'QR Code', icon : 'fas fa-qrcode', gen : (brew)=>{ - return ``; + `&size=100x100) {width:100px;mix-blend-mode:multiply}`; } }, @@ -257,7 +256,7 @@ module.exports = [ gen : function(){ return dedent` ##### Typical Difficulty Classes - {{column-count="2" + {{column-count:2 | Task Difficulty | DC | |:----------------|:--:| | Very easy | 5 | diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index 83828f967..1d360751b 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -31,7 +31,7 @@ const mustacheSpans = { start(src) { return src.match(/{{[^{]/)?.index; }, // Hint to Marked.js to stop and check for a match tokenizer(src, tokens) { const completeSpan = /^{{[^\n]*}}/; // Regex for the complete token - const inlineRegex = /{{(?:="[\w,\-()#%. ]*"|[^"'{}\s])*\s*|}}/g; + const inlineRegex = /{{(?::(?:"[\w,\-()#%. ]*"|[\w\,\-()#%.]*)|[^"'{}\s])*\s*|}}/g; const match = completeSpan.exec(src); if(match) { //Find closing delimiter @@ -76,8 +76,8 @@ const mustacheDivs = { level : 'block', start(src) { return src.match(/\n *{{[^{]/m)?.index; }, // Hint to Marked.js to stop and check for a match tokenizer(src, tokens) { - const completeBlock = /^ *{{[^\s}]*\n.*\n *}}/s; // Regex for the complete token - const blockRegex = /^ *{{(?:="[\w,\-()#%. ]*"|[^"'{}\s])*$|^ *}}$/gm; + const completeBlock = /^ *{{[^\s}]* *\n.*\n *}}/s; // Regex for the complete token + const blockRegex = /^ *{{(?::(?:"[\w,\-()#%. ]*"|[\w\,\-()#%.]*)|[^"'{}\s])* *$|^ *}}$/gm; const match = completeBlock.exec(src); if(match) { //Find closing delimiter @@ -121,7 +121,7 @@ const mustacheInjectInline = { level : 'inline', start(src) { return src.match(/ *{[^{\n]/)?.index; }, // Hint to Marked.js to stop and check for a match tokenizer(src, tokens) { - const inlineRegex = /^ *{((?:="[\w,\-()#%. ]*"|[^"'{}\s])*)}/g; + const inlineRegex = /^ *{((?::(?:"[\w,\-()#%. ]*"|[\w\,\-()#%.]*)|[^"'{}\s])*)}/g; const match = inlineRegex.exec(src); if(match) { const lastToken = tokens[tokens.length - 1]; @@ -156,7 +156,7 @@ const mustacheInjectBlock = { level : 'block', start(src) { return src.match(/\n *{[^{\n]/m)?.index; }, // Hint to Marked.js to stop and check for a match tokenizer(src, tokens) { - const inlineRegex = /^ *{((?:="[\w,\-()#%. ]*"|[^"'{}\s])*)}/ym; + const inlineRegex = /^ *{((?::(?:"[\w,\-()#%. ]*"|[\w\,\-()#%.]*)|[^"'{}\s])*)}/ym; const match = inlineRegex.exec(src); if(match) { const lastToken = tokens[tokens.length - 1]; @@ -313,13 +313,15 @@ const tagRegex = new RegExp(`(${ }).join('|')})`, 'g'); const processStyleTags = (string)=>{ - const tags = string.match(/(?:[^, "=]+|="[^"]*")+/g); + //split tags up. quotes can only occur right after colons. + //TODO: can we simplify to just split on commas? + const tags = string.match(/(?:[^, ":]+|:(?:"[^"]*"|))+/g); if(!tags) return '"'; const id = _.remove(tags, (tag)=>tag.startsWith('#')).map((tag)=>tag.slice(1))[0]; - const classes = _.remove(tags, (tag)=>!tag.includes('"')); - const styles = tags.map((tag)=>tag.replace(/="(.*)"/g, ':$1;')); + const classes = _.remove(tags, (tag)=>!tag.includes(':')); + const styles = tags.map((tag)=>tag.replace(/:"?([^"]*)"?/g, ':$1;')); return `${classes.join(' ')}" ${id ? `id="${id}"` : ''} ${styles.length ? `style="${styles.join(' ')}"` : ''}`; }; diff --git a/themes/5ePhb.style.less b/themes/5ePhb.style.less index a1395554d..ac8fff139 100644 --- a/themes/5ePhb.style.less +++ b/themes/5ePhb.style.less @@ -602,7 +602,7 @@ body { break-inside : avoid; -webkit-transform : translateZ(0); //Prevents shadows from breaking across columns } - .inline { + .inline-block { display : inline-block; text-indent : initial; }