diff --git a/client/homebrew/editor/snippetbar/snippets/snippets.js b/client/homebrew/editor/snippetbar/snippets/snippets.js index f72817c7a..fca5a539b 100644 --- a/client/homebrew/editor/snippetbar/snippets/snippets.js +++ b/client/homebrew/editor/snippetbar/snippets/snippets.js @@ -27,18 +27,34 @@ module.exports = [ }, { name : 'Vertical Spacing', - icon : 'fas fa-times-circle', - gen : '' + icon : 'fas fa-arrows-alt-v', + gen : '\n::::\n' + }, + { + name : 'Horizontal Spacing', + icon : 'fas fa-arrows-alt-h', + gen : ' {{width="100px"}} ' }, { name : 'Wide Block', - icon : 'fas fa-times-circle', - gen : '' + icon : 'fas fa-window-maximize', + gen : dedent`\n + {{wide + Everything in here will be extra wide. Tables, text, everything! + Beware though, CSS columns can behave a bit weird sometimes. You may + have to rely on the automatic column-break rather than \`\column\` if + you mix columns and wide blocks on the same page. + }} + \n` }, { name : 'Image', - icon : 'fas fa-times-circle', - gen : '' + icon : 'fas fa-image', + gen : dedent` + + Credit: Kyounghwan Kim` }, { name : 'Background Image', diff --git a/client/homebrew/editor/snippetbar/snippets/tableOfContents.gen.js b/client/homebrew/editor/snippetbar/snippets/tableOfContents.gen.js index 8a03b0530..e2a1221eb 100644 --- a/client/homebrew/editor/snippetbar/snippets/tableOfContents.gen.js +++ b/client/homebrew/editor/snippetbar/snippets/tableOfContents.gen.js @@ -1,4 +1,5 @@ const _ = require('lodash'); +const dedent = require('dedent-tabs').default; const getTOC = (pages)=>{ const add1 = (title, page)=>{ @@ -51,13 +52,13 @@ module.exports = function(brew){ const pages = brew.text.split('\\page'); const TOC = getTOC(pages); const markdown = _.reduce(TOC, (r, g1, idx1)=>{ - r.push(`- **[${idx1 + 1} ${g1.title}](#p${g1.page})**`); + r.push(`\t\t- ### [{{ ${g1.title}}}{{ ${g1.page}}}](#p${g1.page})`); if(g1.children.length){ _.each(g1.children, (g2, idx2)=>{ - r.push(` - [${idx1 + 1}.${idx2 + 1} ${g2.title}](#p${g2.page})`); + r.push(`\t\t - #### [{{ ${g2.title}}}{{ ${g2.page}}}](#p${g2.page})`); if(g2.children.length){ _.each(g2.children, (g3, idx3)=>{ - r.push(` - [${idx1 + 1}.${idx2 + 1}.${idx3 + 1} ${g3.title}](#p${g3.page})`); + r.push(`\t\t - [{{ ${g3.title}}}{{ ${g3.page}}}](#p${g3.page})`); }); } }); @@ -65,8 +66,11 @@ module.exports = function(brew){ return r; }, []).join('\n'); - return `
-##### Table Of Contents + return dedent` + {{toc + # Table Of Contents + ${markdown} -
\n`; + }} + \n`; }; diff --git a/client/homebrew/phbStyle/phb.style.less b/client/homebrew/phbStyle/phb.style.less index a5c66b7f4..30ecb657a 100644 --- a/client/homebrew/phbStyle/phb.style.less +++ b/client/homebrew/phbStyle/phb.style.less @@ -505,19 +505,60 @@ body { -webkit-column-break-inside : avoid; page-break-inside : avoid; break-inside : avoid; + h1 { + text-align : center; + margin-bottom : 0.1cm; + } a{ - color : black; + display : table; + color : inherit; text-decoration : none; &:hover{ text-decoration : underline; } } + h4 { + margin-top : 0.1cm; + } ul{ padding-left : 0; list-style-type : none; - } - &>ul>li{ - margin-bottom : 10px; + li + li h3 { + margin-top : 0.26cm; + line-height : 1em + } + h3 span:first-child::after { + border : none; + } + span { + display : table-cell; + &:first-child { + position : relative; + overflow : hidden; + &::after { + content : ""; + position : absolute; + bottom : 0.08cm; /* Set as you want */ + margin-left : 0.06cm; /* Spacing before dot leaders */ + width : 100%; + border-bottom : 0.05cm dotted #000; + } + } + &:last-child { + font-family : BookInsanityRemake; + font-size : 0.34cm; + font-weight : normal; + color : black; + text-align : right; + vertical-align : bottom; /* Keep Price text bottom-aligned */ + width : 1%; + padding-left : 0.06cm; /* Spacing after dot leaders */ + /*white-space: nowrap; /* Uncomment if needed */ + } + } + ul { /*List indent*/ + margin-left : 1em; + } } } @@ -528,8 +569,8 @@ body { .block { break-inside : avoid; } - .inline-block { - display : block; + .inline { + display : inline-block; } div { column-gap : 0.5cm; //Default spacing if a div uses multicolumns diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index 317c8fdc0..a8c287c93 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -19,74 +19,105 @@ 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 inlineFullRegex = /{{[^\n]*}}/g; -const inlineRegex = /{{(?:="[\w,\-. ]*"|[^"'{}}\s])*\s*|}}/g; - -renderer.text = function(text){ - const newText = text.replaceAll('"', '"'); - let matches; - - if(matches = newText.match(inlineFullRegex)) { - - //SPAN - INLINE - matches = newText.match(inlineRegex); - let matchIndex = 0; - const res = _.reduce(newText.split(inlineRegex), (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(`{ - 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}`; + return { // Token to generate + type : 'mustacheSpans', // Should match "name" above + raw : raw, // Text to consume from the source + text : text, // Additional custom properties + tags : tags, + tokens : this.inlineTokens(text) // inlineTokens to process **bold**, *italics*, etc. + }; + } } + }, + renderer(token) { + return `tag.replace(/="(.*)"/g, ':$1;')); - return `${classes.join(' ')}" ${id ? `id="${id}"` : ''} ${styles ? `style="${styles.join(' ')}"` : ''}`; + return `${classes.join(' ')}" ${id ? `id="${id}"` : ''} ${styles.length ? `style="${styles.join(' ')}"` : ''}`; }; module.exports = { marked : Markdown, render : (rawBrewText)=>{ - blockCount = 0; rawBrewText = rawBrewText.replace(/^\\column$/gm, `
`) .replace(/^(:+)$/gm, (match)=>`${`
`.repeat(match.length)}\n`) .replace(/(?:^|>) *:([^:\n]*):([^\n]*)\n/gm, (match, term, def)=>`
${Markdown.parseInline(term)}
${def}
`)