mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-01-03 17:02:40 +00:00
Merge branch 'master' into brew_themes_user_selection
This commit is contained in:
39
changelog.md
39
changelog.md
@@ -84,6 +84,45 @@ pre {
|
|||||||
## changelog
|
## changelog
|
||||||
For a full record of development, visit our [Github Page](https://github.com/naturalcrit/homebrewery).
|
For a full record of development, visit our [Github Page](https://github.com/naturalcrit/homebrewery).
|
||||||
|
|
||||||
|
### Friday 28/6/2024 - v3.13.0
|
||||||
|
{{taskList
|
||||||
|
|
||||||
|
##### calculuschild
|
||||||
|
|
||||||
|
* [x] Add `:emoji:` Markdown syntax, with autosuggest; start typing after the first `:` for matching emojis from
|
||||||
|
:fab_font_awesome: FontAwesome, :df_d20: DiceFont, :ei_action: ElderberryInn, and a subset of :gi_broadsword: GameIcons
|
||||||
|
|
||||||
|
* [x] Fix `{curly injection}` to append to, rather than erase and replace target CSS
|
||||||
|
* [x] {{openSans **GET PDF**}} {{fa,fa-file-pdf}} now opens the print dialog directly, rather than redirecting to a separate page
|
||||||
|
|
||||||
|
##### Gazook
|
||||||
|
|
||||||
|
* [x] Several small style tweaks to the UI
|
||||||
|
* [x] Cleaning and refactoring several large pieces of code
|
||||||
|
|
||||||
|
##### 5e-Cleric
|
||||||
|
|
||||||
|
* [x] For error pages, add links to user account and `/share` page if available
|
||||||
|
|
||||||
|
Fixes issue [#3298](https://github.com/naturalcrit/homebrewery/issues/3298)
|
||||||
|
|
||||||
|
* [x] Change FrontCover title to use stroke outline instead of faking it with dozens of shadows
|
||||||
|
* [x] Cleaning and refactoring several large pieces of CSS
|
||||||
|
|
||||||
|
##### abquintic
|
||||||
|
|
||||||
|
* [x] Added additional {{openSans **TABLE OF CONTENTS**}} snippet options. Explicitly include or exclude items from the ToC generation via CSS properties
|
||||||
|
`--TOC:exclude` or `--TOC:include`, or change the included header depth from 3 to 6 (default 3) with `tocDepthH6`
|
||||||
|
|
||||||
|
##### MurdoMaclachlan *(new contributor!)*
|
||||||
|
|
||||||
|
* [x] Added "proficiency bonus" to Monster Stat Block snippet.
|
||||||
|
|
||||||
|
Fixes issue [#3397](https://github.com/naturalcrit/homebrewery/issues/3397)
|
||||||
|
}}
|
||||||
|
|
||||||
|
\column
|
||||||
|
|
||||||
### Monday 18/3/2024 - v3.12.0
|
### Monday 18/3/2024 - v3.12.0
|
||||||
{{taskList
|
{{taskList
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ const BrewPage = (props)=>{
|
|||||||
index : 0,
|
index : 0,
|
||||||
...props
|
...props
|
||||||
};
|
};
|
||||||
const cleanText = DOMPurify.sanitize(props.contents, purifyConfig);
|
const cleanText = props.contents; //DOMPurify.sanitize(props.contents, purifyConfig);
|
||||||
return <div className={props.className} id={`p${props.index + 1}`} >
|
return <div className={props.className} id={`p${props.index + 1}`} >
|
||||||
<div className='columnWrapper' dangerouslySetInnerHTML={{ __html: cleanText }} />
|
<div className='columnWrapper' dangerouslySetInnerHTML={{ __html: cleanText }} />
|
||||||
</div>;
|
</div>;
|
||||||
@@ -126,7 +126,7 @@ const BrewRenderer = (props)=>{
|
|||||||
|
|
||||||
const renderStyle = ()=>{
|
const renderStyle = ()=>{
|
||||||
if(!props.style) return;
|
if(!props.style) return;
|
||||||
const cleanStyle = DOMPurify.sanitize(props.style, purifyConfig);
|
const cleanStyle = props.style; //DOMPurify.sanitize(props.style, purifyConfig);
|
||||||
//return <div style={{ display: 'none' }} dangerouslySetInnerHTML={{ __html: `<style>@layer styleTab {\n${sanitizeScriptTags(props.style)}\n} </style>` }} />;
|
//return <div style={{ display: 'none' }} dangerouslySetInnerHTML={{ __html: `<style>@layer styleTab {\n${sanitizeScriptTags(props.style)}\n} </style>` }} />;
|
||||||
return <div style={{ display: 'none' }} dangerouslySetInnerHTML={{ __html: `<style> ${cleanStyle} </style>` }} />;
|
return <div style={{ display: 'none' }} dangerouslySetInnerHTML={{ __html: `<style> ${cleanStyle} </style>` }} />;
|
||||||
};
|
};
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "homebrewery",
|
"name": "homebrewery",
|
||||||
"version": "3.12.0",
|
"version": "3.13.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "homebrewery",
|
"name": "homebrewery",
|
||||||
"version": "3.12.0",
|
"version": "3.13.0",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "homebrewery",
|
"name": "homebrewery",
|
||||||
"description": "Create authentic looking D&D homebrews using only markdown",
|
"description": "Create authentic looking D&D homebrews using only markdown",
|
||||||
"version": "3.12.0",
|
"version": "3.13.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"npm": "^10.2.x",
|
"npm": "^10.2.x",
|
||||||
"node": "^20.8.x"
|
"node": "^20.8.x"
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
@import (less) './themes/fonts/iconFonts/diceFont.less';
|
@import (less) './themes/fonts/iconFonts/diceFont.less';
|
||||||
@import (less) './themes/fonts/iconFonts/elderberryInn.less';
|
@import (less) './themes/fonts/iconFonts/elderberryInn.less';
|
||||||
@import (less) './themes/fonts/iconFonts/gameIcons.less';
|
@import (less) './themes/fonts/iconFonts/gameIcons.less';
|
||||||
|
@import (less) './themes/fonts/iconFonts/fontAwesome.less';
|
||||||
|
|
||||||
@keyframes sourceMoveAnimation {
|
@keyframes sourceMoveAnimation {
|
||||||
50% {background-color: red; color: white;}
|
50% {background-color: red; color: white;}
|
||||||
|
|||||||
@@ -102,7 +102,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,\-()#%. ]*"|[\w\-()#%.]*)|[^"=':{}\s]*)*))\1 *|}}/g;
|
const inlineRegex = /{{(?=((?:[:=](?:"['\w,\-()#%=?. ]*"|[\w\-()#%.]*)|[^"=':{}\s]*)*))\1 *|}}/g;
|
||||||
const match = completeSpan.exec(src);
|
const match = completeSpan.exec(src);
|
||||||
if(match) {
|
if(match) {
|
||||||
//Find closing delimiter
|
//Find closing delimiter
|
||||||
@@ -159,7 +159,7 @@ const mustacheDivs = {
|
|||||||
start(src) { return src.match(/\n *{{[^{]/m)?.index; }, // Hint to Marked.js to stop and check for a match
|
start(src) { return src.match(/\n *{{[^{]/m)?.index; }, // Hint to Marked.js to stop and check for a match
|
||||||
tokenizer(src, tokens) {
|
tokenizer(src, tokens) {
|
||||||
const completeBlock = /^ *{{[^\n}]* *\n.*\n *}}/s; // Regex for the complete token
|
const completeBlock = /^ *{{[^\n}]* *\n.*\n *}}/s; // Regex for the complete token
|
||||||
const blockRegex = /^ *{{(?=((?:[:=](?:"['\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"=':{}\s]*)*))\1 *$|^ *}}$/gm;
|
const blockRegex = /^ *{{(?=((?:[:=](?:"['\w,\-()#%=?. ]*"|[\w\-()#%.]*)|[^"=':{}\s]*)*))\1 *$|^ *}}$/gm;
|
||||||
const match = completeBlock.exec(src);
|
const match = completeBlock.exec(src);
|
||||||
if(match) {
|
if(match) {
|
||||||
//Find closing delimiter
|
//Find closing delimiter
|
||||||
@@ -214,7 +214,7 @@ const mustacheInjectInline = {
|
|||||||
level : 'inline',
|
level : 'inline',
|
||||||
start(src) { return src.match(/ *{[^{\n]/)?.index; }, // Hint to Marked.js to stop and check for a match
|
start(src) { return src.match(/ *{[^{\n]/)?.index; }, // Hint to Marked.js to stop and check for a match
|
||||||
tokenizer(src, tokens) {
|
tokenizer(src, tokens) {
|
||||||
const inlineRegex = /^ *{(?=((?:[:=](?:"['\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"=':{}\s]*)*))\1}/g;
|
const inlineRegex = /^ *{(?=((?:[:=](?:"['\w,\-()#%=?. ]*"|[\w\-()#%.]*)|[^"=':{}\s]*)*))\1}/g;
|
||||||
const match = inlineRegex.exec(src);
|
const match = inlineRegex.exec(src);
|
||||||
if(match) {
|
if(match) {
|
||||||
const lastToken = tokens[tokens.length - 1];
|
const lastToken = tokens[tokens.length - 1];
|
||||||
@@ -265,7 +265,7 @@ const mustacheInjectBlock = {
|
|||||||
level : 'block',
|
level : 'block',
|
||||||
start(src) { return src.match(/\n *{[^{\n]/m)?.index; }, // Hint to Marked.js to stop and check for a match
|
start(src) { return src.match(/\n *{[^{\n]/m)?.index; }, // Hint to Marked.js to stop and check for a match
|
||||||
tokenizer(src, tokens) {
|
tokenizer(src, tokens) {
|
||||||
const inlineRegex = /^ *{(?=((?:[:=](?:"['\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"=':{}\s]*)*))\1}/ym;
|
const inlineRegex = /^ *{(?=((?:[:=](?:"['\w,\-()#%=?. ]*"|[\w\-()#%.]*)|[^"=':{}\s]*)*))\1}/ym;
|
||||||
const match = inlineRegex.exec(src);
|
const match = inlineRegex.exec(src);
|
||||||
if(match) {
|
if(match) {
|
||||||
const lastToken = tokens[tokens.length - 1];
|
const lastToken = tokens[tokens.length - 1];
|
||||||
@@ -771,7 +771,8 @@ const processStyleTags = (string)=>{
|
|||||||
const attributes = _.remove(tags, (tag)=>(tag.includes('='))).map((tag)=>tag.replace(/="?([^"]*)"?/g, '="$1"'))
|
const attributes = _.remove(tags, (tag)=>(tag.includes('='))).map((tag)=>tag.replace(/="?([^"]*)"?/g, '="$1"'))
|
||||||
?.filter((attr)=>!attr.startsWith('class="') && !attr.startsWith('style="') && !attr.startsWith('id="'))
|
?.filter((attr)=>!attr.startsWith('class="') && !attr.startsWith('style="') && !attr.startsWith('id="'))
|
||||||
.reduce((obj, attr)=>{
|
.reduce((obj, attr)=>{
|
||||||
let [key, value] = attr.split('=');
|
const index = attr.indexOf('=');
|
||||||
|
let [key, value] = [attr.substring(0, index), attr.substring(index + 1)];
|
||||||
value = value.replace(/"/g, '');
|
value = value.replace(/"/g, '');
|
||||||
obj[key] = value;
|
obj[key] = value;
|
||||||
return obj;
|
return obj;
|
||||||
@@ -793,7 +794,8 @@ const extractHTMLStyleTags = (htmlString)=>{
|
|||||||
const attributes = htmlString.match(/[a-zA-Z]+="[^"]*"/g)
|
const attributes = htmlString.match(/[a-zA-Z]+="[^"]*"/g)
|
||||||
?.filter((attr)=>!attr.startsWith('class="') && !attr.startsWith('style="') && !attr.startsWith('id="'))
|
?.filter((attr)=>!attr.startsWith('class="') && !attr.startsWith('style="') && !attr.startsWith('id="'))
|
||||||
.reduce((obj, attr)=>{
|
.reduce((obj, attr)=>{
|
||||||
let [key, value] = attr.split('=');
|
const index = attr.indexOf('=');
|
||||||
|
let [key, value] = [attr.substring(0, index), attr.substring(index + 1)];
|
||||||
value = value.replace(/"/g, '');
|
value = value.replace(/"/g, '');
|
||||||
obj[key] = value;
|
obj[key] = value;
|
||||||
return obj;
|
return obj;
|
||||||
|
|||||||
@@ -338,6 +338,18 @@ describe('Injection: When an injection tag follows an element', ()=>{
|
|||||||
const rendered = Markdown.render(source).trimReturns();
|
const rendered = Markdown.render(source).trimReturns();
|
||||||
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<p><img style="position:absolute; bottom:20px; left:130px; width:220px;" src="https://i.imgur.com/hMna6G0.png" alt="homebrew mug" a="b and c" d="e"></p>`);
|
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<p><img style="position:absolute; bottom:20px; left:130px; width:220px;" src="https://i.imgur.com/hMna6G0.png" alt="homebrew mug" a="b and c" d="e"></p>`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Renders an image with "=" in the url, and added attributes', function() {
|
||||||
|
const source = ` {position:absolute,bottom:20px,left:130px,width:220px,a="b and c",d=e}`;
|
||||||
|
const rendered = Markdown.render(source).trimReturns();
|
||||||
|
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<p><img style="position:absolute; bottom:20px; left:130px; width:220px;" src="https://i.imgur.com/hMna6G0.png?auth=12345&height=1024" alt="homebrew mug" a="b and c" d="e"></p>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Renders an image and added attributes with "=" in the value, ', function() {
|
||||||
|
const source = ` {position:absolute,bottom:20px,left:130px,width:220px,a="b and c",d=e,otherUrl="url?auth=12345"}`;
|
||||||
|
const rendered = Markdown.render(source).trimReturns();
|
||||||
|
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<p><img style="position:absolute; bottom:20px; left:130px; width:220px;" src="https://i.imgur.com/hMna6G0.png" alt="homebrew mug" a="b and c" d="e" otherUrl="url?auth=12345"></p>`);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('and that element is a block', ()=>{
|
describe('and that element is a block', ()=>{
|
||||||
|
|||||||
@@ -21,9 +21,43 @@ module.exports = [
|
|||||||
view : 'text',
|
view : 'text',
|
||||||
snippets : [
|
snippets : [
|
||||||
{
|
{
|
||||||
name : 'Table of Contents',
|
name : 'Table of Contents',
|
||||||
icon : 'fas fa-book',
|
icon : 'fas fa-book',
|
||||||
gen : TableOfContentsGen
|
gen : TableOfContentsGen,
|
||||||
|
experimental : true,
|
||||||
|
subsnippets : [
|
||||||
|
{
|
||||||
|
name : 'Table of Contents',
|
||||||
|
icon : 'fas fa-book',
|
||||||
|
gen : TableOfContentsGen,
|
||||||
|
experimental : true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'Include in ToC up to H3',
|
||||||
|
icon : 'fas fa-dice-three',
|
||||||
|
gen : dedent `\n{{tocDepthH3
|
||||||
|
}}\n`,
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'Include in ToC up to H4',
|
||||||
|
icon : 'fas fa-dice-four',
|
||||||
|
gen : dedent `\n{{tocDepthH4
|
||||||
|
}}\n`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'Include in ToC up to H5',
|
||||||
|
icon : 'fas fa-dice-five',
|
||||||
|
gen : dedent `\n{{tocDepthH5
|
||||||
|
}}\n`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'Include in ToC up to H6',
|
||||||
|
icon : 'fas fa-dice-six',
|
||||||
|
gen : dedent `\n{{tocDepthH6
|
||||||
|
}}\n`,
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name : 'Index',
|
name : 'Index',
|
||||||
|
|||||||
@@ -2,77 +2,68 @@ const _ = require('lodash');
|
|||||||
const dedent = require('dedent-tabs').default;
|
const dedent = require('dedent-tabs').default;
|
||||||
|
|
||||||
const getTOC = (pages)=>{
|
const getTOC = (pages)=>{
|
||||||
const add1 = (title, page)=>{
|
|
||||||
res.push({
|
const recursiveAdd = (title, page, targetDepth, child, curDepth=0)=>{
|
||||||
title : title,
|
if(curDepth > 5) return; // Something went wrong.
|
||||||
page : page + 1,
|
if(curDepth == targetDepth) {
|
||||||
children : []
|
child.push({
|
||||||
});
|
title : title,
|
||||||
};
|
page : page,
|
||||||
const add2 = (title, page)=>{
|
children : []
|
||||||
if(!_.last(res)) add1(null, page);
|
});
|
||||||
_.last(res).children.push({
|
} else {
|
||||||
title : title,
|
if(child.length == 0) {
|
||||||
page : page + 1,
|
child.push({
|
||||||
children : []
|
title : null,
|
||||||
});
|
page : page,
|
||||||
};
|
children : []
|
||||||
const add3 = (title, page)=>{
|
});
|
||||||
if(!_.last(res)) add1(null, page);
|
}
|
||||||
if(!_.last(_.last(res).children)) add2(null, page);
|
recursiveAdd(title, page, targetDepth, _.last(child).children, curDepth+1,);
|
||||||
_.last(_.last(res).children).children.push({
|
}
|
||||||
title : title,
|
|
||||||
page : page + 1,
|
|
||||||
children : []
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const res = [];
|
const res = [];
|
||||||
_.each(pages, (page, pageNum)=>{
|
|
||||||
if(!page.includes('{{frontCover}}') && !page.includes('{{insideCover}}') && !page.includes('{{partCover}}') && !page.includes('{{backCover}}')) {
|
const iframe = document.getElementById('BrewRenderer');
|
||||||
const lines = page.split('\n');
|
const iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
|
||||||
_.each(lines, (line)=>{
|
const headings = iframeDocument.querySelectorAll('h1, h2, h3, h4, h5, h6');
|
||||||
if(_.startsWith(line, '# ')){
|
const headerDepth = ['H1', 'H2', 'H3', 'H4', 'H5', 'H6'];
|
||||||
const title = line.replace('# ', '');
|
|
||||||
add1(title, pageNum);
|
_.each(headings, (heading)=>{
|
||||||
}
|
const onPage = parseInt(heading.closest('.page').id?.replace(/^p/, ''));
|
||||||
if(_.startsWith(line, '## ')){
|
const ToCExclude = getComputedStyle(heading).getPropertyValue('--TOC');
|
||||||
const title = line.replace('## ', '');
|
|
||||||
add2(title, pageNum);
|
if(ToCExclude != 'exclude') {
|
||||||
}
|
recursiveAdd(heading.innerText.trim(), onPage, headerDepth.indexOf(heading.tagName), res);
|
||||||
if(_.startsWith(line, '### ')){
|
|
||||||
const title = line.replace('### ', '');
|
|
||||||
add3(title, pageNum);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const ToCIterate = (entries, curDepth=0)=>{
|
||||||
|
const levelPad = ['- ###', ' - ####', ' - ', ' - ', ' - ', ' - '];
|
||||||
|
const toc = [];
|
||||||
|
if(entries.title !== null){
|
||||||
|
toc.push(`${levelPad[curDepth]} [{{ ${entries.title}}}{{ ${entries.page}}}](#p${entries.page})`);
|
||||||
|
}
|
||||||
|
if(entries.children.length) {
|
||||||
|
_.each(entries.children, (entry, idx)=>{
|
||||||
|
const children = ToCIterate(entry, entry.title == null ? curDepth : curDepth+1);
|
||||||
|
if(children.length) {
|
||||||
|
toc.push(...children);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return toc;
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = function(props){
|
module.exports = function(props){
|
||||||
const pages = props.brew.text.split('\\page');
|
const pages = props.brew.text.split('\\page');
|
||||||
const TOC = getTOC(pages);
|
const TOC = getTOC(pages);
|
||||||
const markdown = _.reduce(TOC, (r, g1, idx1)=>{
|
const markdown = _.reduce(TOC, (r, g1, idx1)=>{
|
||||||
if(g1.title !== null) {
|
r.push(ToCIterate(g1).join('\n'));
|
||||||
r.push(`- ### [{{ ${g1.title}}}{{ ${g1.page}}}](#p${g1.page})`);
|
|
||||||
}
|
|
||||||
if(g1.children.length){
|
|
||||||
_.each(g1.children, (g2, idx2)=>{
|
|
||||||
if(g2.title !== null) {
|
|
||||||
r.push(` - #### [{{ ${g2.title}}}{{ ${g2.page}}}](#p${g2.page})`);
|
|
||||||
}
|
|
||||||
if(g2.children.length){
|
|
||||||
_.each(g2.children, (g3, idx3)=>{
|
|
||||||
if(g2.title !== null) {
|
|
||||||
r.push(` - [{{ ${g3.title}}}{{ ${g3.page}}}](#p${g3.page})`);
|
|
||||||
} else { // Don't over-indent if no level-2 parent entry
|
|
||||||
r.push(` - [{{ ${g3.title}}}{{ ${g3.page}}}](#p${g3.page})`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return r;
|
return r;
|
||||||
}, []).join('\n');
|
}, []).join('\n');
|
||||||
|
|
||||||
|
|||||||
@@ -786,6 +786,39 @@
|
|||||||
// *****************************
|
// *****************************
|
||||||
// * TABLE OF CONTENTS
|
// * TABLE OF CONTENTS
|
||||||
// *****************************/
|
// *****************************/
|
||||||
|
|
||||||
|
// Default Exclusions
|
||||||
|
// Anything not exlcuded is included, default Headers are H1, H2, and H3.
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6,
|
||||||
|
.page:has(.frontCover),
|
||||||
|
.page:has(.backCover),
|
||||||
|
.page:has(.insideCover),
|
||||||
|
.monster,
|
||||||
|
.noToC,
|
||||||
|
.toc { --TOC: exclude; }
|
||||||
|
|
||||||
|
.tocDepthH2 :is(h1, h2) {--TOC: include; }
|
||||||
|
.tocDepthH3 :is(h1, h2, h3) {--TOC: include; }
|
||||||
|
.tocDepthH4 :is(h1, h2, h3, h4) {--TOC: include; }
|
||||||
|
.tocDepthH5 :is(h1, h2, h3, h4, h5) {--TOC: include; }
|
||||||
|
.tocDepthH6 :is(h1, h2, h3, h4, h5, h6) {--TOC: include; }
|
||||||
|
|
||||||
|
.tocIncludeH1 h1 {--TOC: include; }
|
||||||
|
.tocIncludeH2 h2 {--TOC: include; }
|
||||||
|
.tocIncludeH3 h3 {--TOC: include; }
|
||||||
|
.tocIncludeH4 h4 {--TOC: include; }
|
||||||
|
.tocIncludeH5 h5 {--TOC: include; }
|
||||||
|
.tocIncludeH6 h6 {--TOC: include; }
|
||||||
|
|
||||||
|
.page:has(.partCover) {
|
||||||
|
--TOC: exclude;
|
||||||
|
& h1 {
|
||||||
|
--TOC: include;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.page {
|
.page {
|
||||||
&:has(.toc)::after { display : none; }
|
&:has(.toc)::after { display : none; }
|
||||||
.toc {
|
.toc {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
@import (less) './themes/fonts/iconFonts/elderberryInn.less';
|
@import (less) './themes/fonts/iconFonts/elderberryInn.less';
|
||||||
@import (less) './themes/fonts/iconFonts/diceFont.less';
|
@import (less) './themes/fonts/iconFonts/diceFont.less';
|
||||||
@import (less) './themes/fonts/iconFonts/gameIcons.less';
|
@import (less) './themes/fonts/iconFonts/gameIcons.less';
|
||||||
|
@import (less) './themes/fonts/iconFonts/fontAwesome.less';
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
//Colors
|
//Colors
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.df {
|
.df {
|
||||||
display : inline-block;
|
display : inline;
|
||||||
font-family : 'DiceFont';
|
font-family : 'DiceFont';
|
||||||
font-style : normal;
|
font-style : normal;
|
||||||
font-weight : normal;
|
font-weight : normal;
|
||||||
@@ -16,8 +16,11 @@
|
|||||||
text-decoration : inherit;
|
text-decoration : inherit;
|
||||||
text-transform : none;
|
text-transform : none;
|
||||||
text-rendering : optimizeLegibility;
|
text-rendering : optimizeLegibility;
|
||||||
-moz-osx-font-smoothing : grayscale;
|
|
||||||
|
/* Better Font Rendering =========== */
|
||||||
-webkit-font-smoothing : antialiased;
|
-webkit-font-smoothing : antialiased;
|
||||||
|
-moz-osx-font-smoothing : grayscale;
|
||||||
|
|
||||||
&.F::before { content : '\f190'; }
|
&.F::before { content : '\f190'; }
|
||||||
&.F-minus::before { content : '\f191'; }
|
&.F-minus::before { content : '\f191'; }
|
||||||
&.F-plus::before { content : '\f192'; }
|
&.F-plus::before { content : '\f192'; }
|
||||||
|
|||||||
@@ -7,15 +7,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ei {
|
.ei {
|
||||||
display : inline-block;
|
display : inline;
|
||||||
margin-right : 3px;
|
|
||||||
font-family : 'Elderberry-Inn';
|
font-family : 'Elderberry-Inn';
|
||||||
line-height : 1;
|
line-height : 1;
|
||||||
vertical-align : baseline;
|
vertical-align : baseline;
|
||||||
-moz-osx-font-smoothing : grayscale;
|
|
||||||
-webkit-font-smoothing : antialiased;
|
|
||||||
text-rendering : auto;
|
text-rendering : auto;
|
||||||
|
|
||||||
|
/* Better Font Rendering =========== */
|
||||||
|
-webkit-font-smoothing : antialiased;
|
||||||
|
-moz-osx-font-smoothing : grayscale;
|
||||||
|
|
||||||
&.book::before { content : '\E900'; }
|
&.book::before { content : '\E900'; }
|
||||||
&.screen::before { content : '\E901'; }
|
&.screen::before { content : '\E901'; }
|
||||||
|
|
||||||
|
|||||||
2
themes/fonts/iconFonts/fontAwesome.less
Normal file
2
themes/fonts/iconFonts/fontAwesome.less
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/* Icon Font: Font Awesome */
|
||||||
|
.far,.fas,.fab { display : inline; }
|
||||||
@@ -8,19 +8,15 @@
|
|||||||
|
|
||||||
.gi {
|
.gi {
|
||||||
/* use !important to prevent issues with browser extensions that change fonts */
|
/* use !important to prevent issues with browser extensions that change fonts */
|
||||||
display : inline-block;
|
display : inline;
|
||||||
margin-right : 3px;
|
|
||||||
font-family : 'Game-Icons' !important;
|
font-family : 'Game-Icons' !important;
|
||||||
line-height : 1;
|
line-height : 1;
|
||||||
vertical-align : baseline;
|
vertical-align : baseline;
|
||||||
-moz-osx-font-smoothing : grayscale;
|
|
||||||
-webkit-font-smoothing : antialiased;
|
|
||||||
text-rendering : auto;
|
text-rendering : auto;
|
||||||
|
|
||||||
/* Better Font Rendering =========== */
|
/* Better Font Rendering =========== */
|
||||||
-webkit-font-smoothing : antialiased;
|
-webkit-font-smoothing : antialiased;
|
||||||
-moz-osx-font-smoothing : grayscale;
|
-moz-osx-font-smoothing : grayscale;
|
||||||
|
|
||||||
|
|
||||||
&.zigzag-leaf::before { content : '\e900'; }
|
&.zigzag-leaf::before { content : '\e900'; }
|
||||||
&.zebra-shield::before { content : '\e901'; }
|
&.zebra-shield::before { content : '\e901'; }
|
||||||
|
|||||||
Reference in New Issue
Block a user