diff --git a/.circleci/config.yml b/.circleci/config.yml index 666a9564a..8a756b3de 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -64,6 +64,12 @@ jobs: - run: name: Test - Mustache Spans command: npm run test:mustache-syntax + - run: + name: Test - Definition Lists + command: npm run test:definition-lists + - run: + name: Test - Variables + command: npm run test:variables - run: name: Test - Routes command: npm run test:route diff --git a/changelog.md b/changelog.md index e86c2ea0f..18c3205f7 100644 --- a/changelog.md +++ b/changelog.md @@ -84,7 +84,70 @@ pre { ## changelog For a full record of development, visit our [Github Page](https://github.com/naturalcrit/homebrewery). -### Wednesday 21/2/2024 - v3.11.0 +### Monday 18/3/2024 - v3.12.0 +{{taskList + +##### 5e-Cleric + +* [x] Fix language-specific hyphenation on print page + +Fixes issue [#3294](https://github.com/naturalcrit/homebrewery/issues/3294) + +* [x] Upgrade Font-Awesome to v6.51 + +* [x] Allow downloaded files to be uploaded via {{openSans **NEW {{fa,fa-plus-square}} → FROM UPLOAD {{fa,fa-upload}}**}} + +##### G-Ambatte + +* [x] Fix an edge case crash with empty documents + +Fixes issue [#3315](https://github.com/naturalcrit/homebrewery/issues/3315) + +* [x] Brews on the user page can be searched by tag; clicking a tag adds it to the filter + +Fixes issue [#3164](https://github.com/naturalcrit/homebrewery/issues/3164) + +* [x] Add *DiceFont* icons {{df,d20-20}} `{{df,icon-name}}` + +##### abquintic + +* [x] Fix ^super^ and ^^sub^^ highlighting in the text editor + +* [x] Add new syntax for multiline Definition Lists: + + +``` +Term +::Definition 1 +::Definition 2 +with more text +``` + +produces: + +Term +::Definition 1 +::Definition 2 +with more text + +Fixes issue [#2340](https://github.com/naturalcrit/homebrewery/issues/2340) + +##### RKuerten : +* [x] Fix monster stat block backgrounds on print page + +Fixes issue [#3275](https://github.com/naturalcrit/homebrewery/issues/3275) + +* [x] Added new text editor theme: "Darkvision". + +##### calculuschild, G-Ambatte, 5e-Cleric + +* [x] Codebase and UI cleanup +}} + +\page + + +### Friday 21/2/2024 - v3.11.0 {{taskList ##### Gazook89 @@ -166,14 +229,16 @@ Fixes issue [1488](https://github.com/naturalcrit/homebrewery/issues/1488) Fixes issues [2510](https://github.com/naturalcrit/homebrewery/issues/2510), [2975](https://github.com/naturalcrit/homebrewery/issues/2975) -* [x] New Variables syntax. See below for details. +* [x] Brew Variables }} +\ + {{wide ### Brew Variable Syntax -You may already be familiar with `[link](url)` and `![image](url)` syntax. We have expanded this to include a third `$[variable](text)` syntax. All three of these syntaxes now share a common set of features: +You may already be familiar with `[link](url)` and `![image](url)` synax. We have expanded this to include a third `$[variable](text)` syntax. All three of these syntaxes now share a common set of features: {{varSyntaxTable | syntax | description | @@ -1512,7 +1577,7 @@ myStyle {color: black} ### Sunday, 29/05/2016 - v2.1.0 - Finally added a syntax for doing spell lists. A bit in-depth about why this took so long. Essentially I'm running out of syntax to use in stardard Markdown. There are too many unique elements in the PHB-style to be mapped. I solved this earlier by stacking certain elements together (eg. an `
` before a `blockquote` turns it into moster state block), but those are getting unweildly. I would like to simply wrap these in `div`s with classes, but unfortunately Markdown stops processing when within HTML blocks. To get around this I wrote my own override to the Markdown parser and lexer to process Markdown within a simple div class wrapper. This should open the door for more unique syntaxes in the future. Big step! - Override Ctrl+P (and cmd+P) to launch to the print page. Many people try to just print either the editing or share page to get a PDF. While this dones;t make much sense, I do get a ton of issues about it. So now if you try to do this, it'll just bring you imediately to the print page. Everybody wins! -- The onboarding flow has also been confusing a few users (Homepage -> new -> save -> edit page). If you edit the Homepage text now, a Call to Action to save your work will pop-up. +- The onboarding flow has also been confusing a few users (Homepage → new → save → edit page). If you edit the Homepage text now, a Call to Action to save your work will pop-up. - Added a 'Recently Edited' and 'Recently Viewed' nav item to the edit and share page respectively. Each will remember the last 8 items you edited or viewed and when you viewed it. Makes use of the new title attribute of brews to easy navigatation. - Paragraphs now indent properly after lists (thanks u/slitjen!) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 4f3ef44f5..a9efdb245 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -151,12 +151,19 @@ const Editor = createClass({ // definition lists if(line.includes('::')){ - const regex = /^([^\n]*?)::([^\n]*)(?:\n|$)/ym; + if(/^:*$/.test(line) == true){ return }; + const regex = /^([^\n]*?:?\s?)(::[^\n]*)(?:\n|$)/ymd; // the `d` flag, for match indices, throws an ESLint error. let match; while ((match = regex.exec(line)) != null){ - codeMirror.markText({ line: lineNumber, ch: line.indexOf(match[0]) }, { line: lineNumber, ch: line.indexOf(match[0]) + match[0].length }, { className: 'define' }); - codeMirror.markText({ line: lineNumber, ch: line.indexOf(match[1]) }, { line: lineNumber, ch: line.indexOf(match[1]) + match[1].length }, { className: 'term' }); - codeMirror.markText({ line: lineNumber, ch: line.indexOf(match[2]) }, { line: lineNumber, ch: line.indexOf(match[2]) + match[2].length }, { className: 'definition' }); + codeMirror.markText({ line: lineNumber, ch: match.indices[0][0] }, { line: lineNumber, ch: match.indices[0][1] }, { className: 'dl-highlight' }); + codeMirror.markText({ line: lineNumber, ch: match.indices[1][0] }, { line: lineNumber, ch: match.indices[1][1] }, { className: 'dt-highlight' }); + codeMirror.markText({ line: lineNumber, ch: match.indices[2][0] }, { line: lineNumber, ch: match.indices[2][1] }, { className: 'dd-highlight' }); + const ddIndex = match.indices[2][0]; + let colons = /::/g; + let colonMatches = colons.exec(match[2]); + if(colonMatches !== null){ + codeMirror.markText({ line: lineNumber, ch: colonMatches.index + ddIndex }, { line: lineNumber, ch: colonMatches.index + colonMatches[0].length + ddIndex }, { className: 'dl-colon-highlight'} ) + } } } diff --git a/client/homebrew/editor/editor.less b/client/homebrew/editor/editor.less index b165f91db..d7950ead3 100644 --- a/client/homebrew/editor/editor.less +++ b/client/homebrew/editor/editor.less @@ -55,6 +55,16 @@ vertical-align : sub; font-size : 0.9em; } + .dl-highlight { + &.dl-colon-highlight { + font-weight : bold; + color : #949494; + background : #E5E5E5; + border-radius : 3px; + } + &.dt-highlight { color : rgb(96, 117, 143); } + &.dd-highlight { color : rgb(97, 57, 178); } + } } .brewJump { diff --git a/client/homebrew/pages/errorPage/errors/errorIndex.js b/client/homebrew/pages/errorPage/errors/errorIndex.js index c2de04142..7c7a3ae7f 100644 --- a/client/homebrew/pages/errorPage/errors/errorIndex.js +++ b/client/homebrew/pages/errorPage/errors/errorIndex.js @@ -122,6 +122,16 @@ const errorIndex = (props)=>{ An error occurred while attempting to remove the user from the Homebrewery document author list! **Brew ID:** ${props.brew.brewId}`, + + // Brew locked by Administrators error + '100' : dedent` + ## This brew has been locked. + + Please contact the Administrators to unlock this document. + + **Brew ID:** ${props.brew.brewId} + + **Brew Title:** ${props.brew.brewTitle}`, }; }; diff --git a/package-lock.json b/package-lock.json index 29ea015b6..42b83939f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "homebrewery", - "version": "3.11.0", + "version": "3.12.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "homebrewery", - "version": "3.11.0", + "version": "3.12.0", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -36,7 +36,7 @@ "marked-smartypants-lite": "^1.0.2", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^8.2.1", + "mongoose": "^8.2.2", "nanoid": "3.3.4", "nconf": "^0.12.1", "react": "^18.2.0", @@ -50,7 +50,7 @@ "devDependencies": { "eslint": "^8.57.0", "eslint-plugin-jest": "^27.9.0", - "eslint-plugin-react": "^7.34.0", + "eslint-plugin-react": "^7.34.1", "jest": "^29.7.0", "jest-expect-message": "^1.1.3", "postcss-less": "^6.0.0", @@ -5755,9 +5755,9 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.34.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.0.tgz", - "integrity": "sha512-MeVXdReleBTdkz/bvcQMSnCXGi+c9kvy51IpinjnJgutl3YTHWsDdke7Z1ufZpGfDG8xduBDKyjtB9JH1eBKIQ==", + "version": "7.34.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.1.tgz", + "integrity": "sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==", "dev": true, "dependencies": { "array-includes": "^3.1.7", @@ -10529,9 +10529,9 @@ } }, "node_modules/mongoose": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.2.1.tgz", - "integrity": "sha512-UgZZbXSJH0pdU936qj3FyVI+sBsMoGowFnL5R/RYrA50ayn6+ZYdVr8ehsRgNxRcMYwoNld5XzHIfkFRJTePEw==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.2.2.tgz", + "integrity": "sha512-6sMxe1d3k/dBjiOX4ExNTNOP0g1x0iq8eXyg+ttgIXM3HLnQ0IUyXRwVVAPFFY6O4/8uYN5dB0Ec72FrexbPpw==", "dependencies": { "bson": "^6.2.0", "kareem": "2.5.1", diff --git a/package.json b/package.json index e0c65e306..79e78931b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "homebrewery", "description": "Create authentic looking D&D homebrews using only markdown", - "version": "3.11.0", + "version": "3.12.0", "engines": { "npm": "^10.2.x", "node": "^20.8.x" @@ -31,6 +31,7 @@ "test:mustache-syntax:inline": "jest '.*(mustache-syntax).*' -t '^Inline:.*' --verbose --noStackTrace", "test:mustache-syntax:block": "jest '.*(mustache-syntax).*' -t '^Block:.*' --verbose --noStackTrace", "test:mustache-syntax:injection": "jest '.*(mustache-syntax).*' -t '^Injection:.*' --verbose --noStackTrace", + "test:definition-lists": "jest tests/markdown/definition-lists.test.js --verbose --noStackTrace", "test:route": "jest tests/routes/static-pages.test.js --verbose", "phb": "node scripts/phb.js", "prod": "set NODE_ENV=production && npm run build", @@ -106,7 +107,7 @@ "marked-smartypants-lite": "^1.0.2", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^8.2.1", + "mongoose": "^8.2.2", "nanoid": "3.3.4", "nconf": "^0.12.1", "react": "^18.2.0", @@ -120,7 +121,7 @@ "devDependencies": { "eslint": "^8.57.0", "eslint-plugin-jest": "^27.9.0", - "eslint-plugin-react": "^7.34.0", + "eslint-plugin-react": "^7.34.1", "jest": "^29.7.0", "jest-expect-message": "^1.1.3", "postcss-less": "^6.0.0", diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 20e13ec71..567dc9cf7 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -54,6 +54,10 @@ const api = { }); stub = stub?.toObject(); + if(stub?.lock?.locked && accessType != 'edit') { + throw { HBErrorCode: '100', code: stub.lock.code, message: stub.lock.message, brewId: stub.shareId, brewTitle: stub.title }; + } + // If there is a google id, try to find the google brew if(!stubOnly && (googleId || stub?.googleId)) { let googleError; diff --git a/server/homebrew.api.spec.js b/server/homebrew.api.spec.js index 55a8c414f..8a4748e38 100644 --- a/server/homebrew.api.spec.js +++ b/server/homebrew.api.spec.js @@ -117,7 +117,7 @@ describe('Tests for api', ()=>{ id : '123456789012345678901234567890123abcdefghijkl' } }); - + expect(googleId).toEqual('123456789012345678901234567890123'); expect(id).toEqual('abcdefghijkl'); }); @@ -128,7 +128,7 @@ describe('Tests for api', ()=>{ id : '123456789012345678901234567890123abcdefghij' } }); - + expect(googleId).toEqual('123456789012345678901234567890123'); expect(id).toEqual('abcdefghij'); }); @@ -298,6 +298,18 @@ describe('Tests for api', ()=>{ expect(model.get).toHaveBeenCalledWith({ shareId: '1' }); expect(google.getGoogleBrew).toHaveBeenCalledWith('2', '1', 'share'); }); + + it('access is denied to a locked brew', async()=>{ + const lockBrew = { title: 'test brew', shareId: '1', lock: { locked: true, code: 404, message: 'brew locked' } }; + model.get = jest.fn(()=>toBrewPromise(lockBrew)); + api.getId = jest.fn(()=>({ id: '1', googleId: undefined })); + + const fn = api.getBrew('share', false); + const req = { brew: {} }; + const next = jest.fn(); + + await expect(fn(req, null, next)).rejects.toEqual({ 'HBErrorCode': '100', 'brewId': '1', 'brewTitle': 'test brew', 'code': 404, 'message': 'brew locked' }); + }); }); describe('mergeBrewText', ()=>{ diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index 09f810907..939c2cc81 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -294,10 +294,10 @@ const superSubScripts = { } }; -const definitionLists = { - name : 'definitionLists', +const definitionListsInline = { + name : 'definitionListsInline', level : 'block', - start(src) { return src.match(/^.*?::.*/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) { const regex = /^([^\n]*?)::([^\n]*)(?:\n|$)/ym; let match; @@ -312,7 +312,7 @@ const definitionLists = { } if(definitions.length) { return { - type : 'definitionLists', + type : 'definitionListsInline', raw : src.slice(0, endIndex), definitions }; @@ -326,6 +326,51 @@ const definitionLists = { } }; +const definitionListsMultiline = { + name : 'definitionListsMultiline', + 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 regex = /(\n?\n?(?!::)[^\n]+?(?=\n::))|\n::(.(?:.|\n)*?(?=(?:\n::)|(?:\n\n)|$))/y; + let match; + let endIndex = 0; + const definitions = []; + while (match = regex.exec(src)) { + if(match[1]) { + if(this.lexer.blockTokens(match[1].trim())[0].type !== 'paragraph') // DT must not be another block-level token besides

+ break; + definitions.push({ + dt : this.lexer.inlineTokens(match[1].trim()), + dds : [] + }); + } + if(match[2] && definitions.length) { + definitions[definitions.length - 1].dds.push( + this.lexer.inlineTokens(match[2].trim().replace(/\s/g, ' ')) + ); + } + endIndex = regex.lastIndex; + } + if(definitions.length) { + return { + type : 'definitionListsMultiline', + raw : src.slice(0, endIndex), + definitions + }; + } + }, + renderer(token) { + let returnVal = `

`; + token.definitions.forEach((def)=>{ + const dds = def.dds.map((s)=>{ + return `\n
${this.parser.parseInline(s).trim()}
`; + }).join(''); + returnVal += `
${this.parser.parseInline(def.dt)}
${dds}\n`; + }); + returnVal = returnVal.trim(); + return `${returnVal}
`; + } +}; //v=====--------------------< Variable Handling >-------------------=====v// 242 lines const replaceVar = function(input, hoist=false, allowUnresolved=false) { @@ -572,7 +617,7 @@ function MarkedVariables() { //^=====--------------------< Variable Handling >-------------------=====^// Marked.use(MarkedVariables()); -Marked.use({ extensions: [mustacheSpans, mustacheDivs, mustacheInjectInline, definitionLists, superSubScripts] }); +Marked.use({ extensions: [mustacheSpans, mustacheDivs, mustacheInjectInline, definitionListsMultiline, definitionListsInline, superSubScripts] }); Marked.use(mustacheInjectBlock); Marked.use({ renderer: renderer, tokenizer: tokenizer, mangle: false }); Marked.use(MarkedExtendedTables(), MarkedGFMHeadingId(), MarkedSmartypantsLite()); diff --git a/tests/markdown/definition-lists.test.js b/tests/markdown/definition-lists.test.js new file mode 100644 index 000000000..87ff6f617 --- /dev/null +++ b/tests/markdown/definition-lists.test.js @@ -0,0 +1,85 @@ +/* eslint-disable max-lines */ + +const Markdown = require('naturalcrit/markdown.js'); + +describe('Inline Definition Lists', ()=>{ + test('No Term 1 Definition', function() { + const source = ':: My First Definition\n\n'; + const rendered = Markdown.render(source).trim(); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
My First Definition
\n
'); + }); + + test('Single Definition Term', function() { + const source = 'My term :: My First Definition\n\n'; + const rendered = Markdown.render(source).trim(); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
My term
My First Definition
\n
'); + }); + + test('Multiple Definition Terms', function() { + const source = 'Term 1::Definition of Term 1\nTerm 2::Definition of Term 2\n\n'; + const rendered = Markdown.render(source).trim(); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
Definition of Term 1
\n
Term 2
Definition of Term 2
\n
'); + }); +}); + +describe('Multiline Definition Lists', ()=>{ + test('Single Term, Single Definition', function() { + const source = 'Term 1\n::Definition 1\n\n'; + const rendered = Markdown.render(source).trim(); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
\n
Definition 1
'); + }); + + test('Single Term, Plural Definitions', function() { + const source = 'Term 1\n::Definition 1\n::Definition 2\n\n'; + const rendered = Markdown.render(source).trim(); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
\n
Definition 1
\n
Definition 2
'); + }); + + test('Multiple Term, Single Definitions', function() { + const source = 'Term 1\n::Definition 1\n\nTerm 2\n::Definition 1\n\n'; + const rendered = Markdown.render(source).trim(); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
\n
Definition 1
\n
Term 2
\n
Definition 1
'); + }); + + test('Multiple Term, Plural Definitions', function() { + const source = 'Term 1\n::Definition 1\n::Definition 2\n\nTerm 2\n::Definition 1\n::Definition 2\n\n'; + const rendered = Markdown.render(source).trim(); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
\n
Definition 1
\n
Definition 2
\n
Term 2
\n
Definition 1
\n
Definition 2
'); + }); + + test('Single Term, Single multi-line definition', function() { + const source = 'Term 1\n::Definition 1\nand more and\nmore and more\n\n'; + const rendered = Markdown.render(source).trim(); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
\n
Definition 1 and more and more and more
'); + }); + + test('Single Term, Plural multi-line definitions', function() { + const source = 'Term 1\n::Definition 1\nand more and more\n::Definition 2\nand more\nand more\n::Definition 3\n\n'; + const rendered = Markdown.render(source).trim(); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
\n
Definition 1 and more and more
\n
Definition 2 and more and more
\n
Definition 3
'); + }); + + test('Multiple Term, Single multi-line definition', function() { + const source = 'Term 1\n::Definition 1\nand more and more\n\nTerm 2\n::Definition 1\n::Definition 2\n\n'; + const rendered = Markdown.render(source).trim(); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
\n
Definition 1 and more and more
\n
Term 2
\n
Definition 1
\n
Definition 2
'); + }); + + test('Multiple Term, Single multi-line definition, followed by an inline dl', function() { + const source = 'Term 1\n::Definition 1\nand more and more\n\nTerm 2\n::Definition 1\n::Definition 2\n\n::Inline Definition (no term)'; + const rendered = Markdown.render(source).trim(); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
\n
Definition 1 and more and more
\n
Term 2
\n
Definition 1
\n
Definition 2
Inline Definition (no term)
\n
'); + }); + + test('Multiple Term, Single multi-line definition, followed by paragraph', function() { + const source = 'Term 1\n::Definition 1\nand more and more\n\nTerm 2\n::Definition 1\n::Definition 2\n\nParagraph'; + const rendered = Markdown.render(source).trim(); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
\n
Definition 1 and more and more
\n
Term 2
\n
Definition 1
\n
Definition 2

Paragraph

'); + }); + + test('Block Token cannot be the Term of a multi-line definition', function() { + const source = '## Header\n::Definition 1 of a single-line DL\n::Definition 1 of another single-line DL'; + const rendered = Markdown.render(source).trim(); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('\n
Definition 1 of a single-line DL
\n
Definition 1 of another single-line DL
\n
'); + }); +}); diff --git a/themes/V3/5ePHB/style.less b/themes/V3/5ePHB/style.less index ed3e8604c..a529d591f 100644 --- a/themes/V3/5ePHB/style.less +++ b/themes/V3/5ePHB/style.less @@ -1,6 +1,6 @@ -@import (less) './themes/fonts/5e/fonts.less'; @import (less) './themes/assets/assets.less'; @import (less) './themes/fonts/icon fonts/font-icons.less'; +@import (less) './themes/fonts/icon fonts/dicefont.less'; :root { //Colors diff --git a/themes/V3/Blank/style.less b/themes/V3/Blank/style.less index 3e5b2290f..1d8ca6ee4 100644 --- a/themes/V3/Blank/style.less +++ b/themes/V3/Blank/style.less @@ -1,5 +1,6 @@ @import (less) './themes/fonts/5e/fonts.less'; @import (less) './themes/assets/assets.less'; +@import (less) './themes/fonts/icon fonts/dicefont.less'; :root { //Colors diff --git a/themes/fonts/5e/dicefont.less b/themes/fonts/5e/dicefont.less deleted file mode 100644 index 887a7c27c..000000000 --- a/themes/fonts/5e/dicefont.less +++ /dev/null @@ -1,118 +0,0 @@ -/* - Icon Font: dicefont -*/ -@font-face { - font-family: 'DiceFont'; - src: url('../../../fonts/5e/dicefont.woff2') format('woff2'), - url('../../../fonts/5e/dicefont.woff') format('woff'); - font-weight: normal; - font-style: normal; -} - -.df { - display: inline-block; - font-family: 'DiceFont'; - font-style: normal; - font-weight: normal; - font-variant: normal; - line-height: 1; - text-decoration: inherit; - text-rendering: optimizeLegibility; - text-transform: none; - -moz-osx-font-smoothing: grayscale; - -webkit-font-smoothing: antialiased; - font-smooth: antialiased; - &.F:before { content: '\f190'; } - &.F-minus:before { content: '\f191'; } - &.F-plus:before { content: '\f192'; } - &.F-zero:before { content: '\f193'; } - &.d10:before { content: '\f194'; } - &.d10-0:before { content: '\f100'; } - &.d10-1:before { content: '\f101'; } - &.d10-10:before { content: '\f102'; } - &.d10-2:before { content: '\f103'; } - &.d10-3:before { content: '\f104'; } - &.d10-4:before { content: '\f105'; } - &.d10-5:before { content: '\f106'; } - &.d10-6:before { content: '\f107'; } - &.d10-7:before { content: '\f108'; } - &.d10-8:before { content: '\f109'; } - &.d10-9:before { content: '\f10a'; } - &.d12:before { content: '\f195'; } - &.d12-1:before { content: '\f10b'; } - &.d12-10:before { content: '\f10c'; } - &.d12-11:before { content: '\f10d'; } - &.d12-12:before { content: '\f10e'; } - &.d12-2:before { content: '\f10f'; } - &.d12-3:before { content: '\f110'; } - &.d12-4:before { content: '\f111'; } - &.d12-5:before { content: '\f112'; } - &.d12-6:before { content: '\f113'; } - &.d12-7:before { content: '\f114'; } - &.d12-8:before { content: '\f115'; } - &.d12-9:before { content: '\f116'; } - &.d2:before { content: '\f196'; } - &.d2-1:before { content: '\f117'; } - &.d2-2:before { content: '\f118'; } - &.d20:before { content: '\f197'; } - &.d20-1:before { content: '\f119'; } - &.d20-10:before { content: '\f11a'; } - &.d20-11:before { content: '\f11b'; } - &.d20-12:before { content: '\f11c'; } - &.d20-13:before { content: '\f11d'; } - &.d20-14:before { content: '\f11e'; } - &.d20-15:before { content: '\f11f'; } - &.d20-16:before { content: '\f120'; } - &.d20-17:before { content: '\f121'; } - &.d20-18:before { content: '\f122'; } - &.d20-19:before { content: '\f123'; } - &.d20-2:before { content: '\f124'; } - &.d20-20:before { content: '\f125'; } - &.d20-3:before { content: '\f126'; } - &.d20-4:before { content: '\f127'; } - &.d20-5:before { content: '\f128'; } - &.d20-6:before { content: '\f129'; } - &.d20-7:before { content: '\f12a'; } - &.d20-8:before { content: '\f12b'; } - &.d20-9:before { content: '\f12c'; } - &.d4:before { content: '\f198'; } - &.d4-1:before { content: '\f12d'; } - &.d4-2:before { content: '\f12e'; } - &.d4-3:before { content: '\f12f'; } - &.d4-4:before { content: '\f130'; } - &.d6:before { content: '\f199'; } - &.d6-1:before { content: '\f131'; } - &.d6-2:before { content: '\f132'; } - &.d6-3:before { content: '\f133'; } - &.d6-4:before { content: '\f134'; } - &.d6-5:before { content: '\f135'; } - &.d6-6:before { content: '\f136'; } - &.d8:before { content: '\f19a'; } - &.d8-1:before { content: '\f137'; } - &.d8-2:before { content: '\f138'; } - &.d8-3:before { content: '\f139'; } - &.d8-4:before { content: '\f13a'; } - &.d8-5:before { content: '\f13b'; } - &.d8-6:before { content: '\f13c'; } - &.d8-7:before { content: '\f13d'; } - &.d8-8:before { content: '\f13e'; } - &.dot-d6:before { content: '\f19b'; } - &.dot-d6-1:before { content: '\f13f'; } - &.dot-d6-2:before { content: '\f140'; } - &.dot-d6-3:before { content: '\f141'; } - &.dot-d6-4:before { content: '\f142'; } - &.dot-d6-5:before { content: '\f143'; } - &.dot-d6-6:before { content: '\f18f'; } - &.small-dot-d6-1:before { content: '\f183'; } - &.small-dot-d6-2:before { content: '\f184'; } - &.small-dot-d6-3:before { content: '\f185'; } - &.small-dot-d6-4:before { content: '\f186'; } - &.small-dot-d6-5:before { content: '\f187'; } - &.small-dot-d6-6:before { content: '\f188'; } - &.solid-small-dot-d6-1:before { content: '\f189'; } - &.solid-small-dot-d6-2:before { content: '\f18a'; } - &.solid-small-dot-d6-3:before { content: '\f18b'; } - &.solid-small-dot-d6-4:before { content: '\f18c'; } - &.solid-small-dot-d6-5:before { content: '\f18d'; } - &.solid-small-dot-d6-6:before { content: '\f18e'; } -} \ No newline at end of file diff --git a/themes/fonts/5e/dicefont.woff b/themes/fonts/5e/dicefont.woff deleted file mode 100644 index d6f54f38e..000000000 Binary files a/themes/fonts/5e/dicefont.woff and /dev/null differ diff --git a/themes/fonts/5e/fonts.less b/themes/fonts/5e/fonts.less index b59fe1671..8f089b51c 100644 --- a/themes/fonts/5e/fonts.less +++ b/themes/fonts/5e/fonts.less @@ -1,5 +1,3 @@ -@import url('./dicefont.less'); - /* Main Font, serif */ @font-face { font-family: BookInsanityRemake; diff --git a/themes/fonts/icon fonts/dicefont.less b/themes/fonts/icon fonts/dicefont.less new file mode 100644 index 000000000..78a88f03a --- /dev/null +++ b/themes/fonts/icon fonts/dicefont.less @@ -0,0 +1,114 @@ +/* Icon Font: dicefont */ +@font-face { + font-family : 'DiceFont'; + font-style : normal; + font-weight : normal; + src : url('../../../fonts/icon fonts/dicefont.woff2'); +} + +.df { + display : inline-block; + font-family : 'DiceFont'; + font-style : normal; + font-weight : normal; + font-variant : normal; + line-height : 1; + text-decoration : inherit; + text-transform : none; + text-rendering : optimizeLegibility; + -moz-osx-font-smoothing : grayscale; + -webkit-font-smoothing : antialiased; + &.F::before { content : '\f190'; } + &.F-minus::before { content : '\f191'; } + &.F-plus::before { content : '\f192'; } + &.F-zero::before { content : '\f193'; } + &.d10::before { content : '\f194'; } + &.d10-0::before { content : '\f100'; } + &.d10-1::before { content : '\f101'; } + &.d10-10::before { content : '\f102'; } + &.d10-2::before { content : '\f103'; } + &.d10-3::before { content : '\f104'; } + &.d10-4::before { content : '\f105'; } + &.d10-5::before { content : '\f106'; } + &.d10-6::before { content : '\f107'; } + &.d10-7::before { content : '\f108'; } + &.d10-8::before { content : '\f109'; } + &.d10-9::before { content : '\f10a'; } + &.d12::before { content : '\f195'; } + &.d12-1::before { content : '\f10b'; } + &.d12-10::before { content : '\f10c'; } + &.d12-11::before { content : '\f10d'; } + &.d12-12::before { content : '\f10e'; } + &.d12-2::before { content : '\f10f'; } + &.d12-3::before { content : '\f110'; } + &.d12-4::before { content : '\f111'; } + &.d12-5::before { content : '\f112'; } + &.d12-6::before { content : '\f113'; } + &.d12-7::before { content : '\f114'; } + &.d12-8::before { content : '\f115'; } + &.d12-9::before { content : '\f116'; } + &.d2::before { content : '\f196'; } + &.d2-1::before { content : '\f117'; } + &.d2-2::before { content : '\f118'; } + &.d20::before { content : '\f197'; } + &.d20-1::before { content : '\f119'; } + &.d20-10::before { content : '\f11a'; } + &.d20-11::before { content : '\f11b'; } + &.d20-12::before { content : '\f11c'; } + &.d20-13::before { content : '\f11d'; } + &.d20-14::before { content : '\f11e'; } + &.d20-15::before { content : '\f11f'; } + &.d20-16::before { content : '\f120'; } + &.d20-17::before { content : '\f121'; } + &.d20-18::before { content : '\f122'; } + &.d20-19::before { content : '\f123'; } + &.d20-2::before { content : '\f124'; } + &.d20-20::before { content : '\f125'; } + &.d20-3::before { content : '\f126'; } + &.d20-4::before { content : '\f127'; } + &.d20-5::before { content : '\f128'; } + &.d20-6::before { content : '\f129'; } + &.d20-7::before { content : '\f12a'; } + &.d20-8::before { content : '\f12b'; } + &.d20-9::before { content : '\f12c'; } + &.d4::before { content : '\f198'; } + &.d4-1::before { content : '\f12d'; } + &.d4-2::before { content : '\f12e'; } + &.d4-3::before { content : '\f12f'; } + &.d4-4::before { content : '\f130'; } + &.d6::before { content : '\f199'; } + &.d6-1::before { content : '\f131'; } + &.d6-2::before { content : '\f132'; } + &.d6-3::before { content : '\f133'; } + &.d6-4::before { content : '\f134'; } + &.d6-5::before { content : '\f135'; } + &.d6-6::before { content : '\f136'; } + &.d8::before { content : '\f19a'; } + &.d8-1::before { content : '\f137'; } + &.d8-2::before { content : '\f138'; } + &.d8-3::before { content : '\f139'; } + &.d8-4::before { content : '\f13a'; } + &.d8-5::before { content : '\f13b'; } + &.d8-6::before { content : '\f13c'; } + &.d8-7::before { content : '\f13d'; } + &.d8-8::before { content : '\f13e'; } + &.dot-d6::before { content : '\f19b'; } + &.dot-d6-1::before { content : '\f13f'; } + &.dot-d6-2::before { content : '\f140'; } + &.dot-d6-3::before { content : '\f141'; } + &.dot-d6-4::before { content : '\f142'; } + &.dot-d6-5::before { content : '\f143'; } + &.dot-d6-6::before { content : '\f18f'; } + &.small-dot-d6-1::before { content : '\f183'; } + &.small-dot-d6-2::before { content : '\f184'; } + &.small-dot-d6-3::before { content : '\f185'; } + &.small-dot-d6-4::before { content : '\f186'; } + &.small-dot-d6-5::before { content : '\f187'; } + &.small-dot-d6-6::before { content : '\f188'; } + &.solid-small-dot-d6-1::before { content : '\f189'; } + &.solid-small-dot-d6-2::before { content : '\f18a'; } + &.solid-small-dot-d6-3::before { content : '\f18b'; } + &.solid-small-dot-d6-4::before { content : '\f18c'; } + &.solid-small-dot-d6-5::before { content : '\f18d'; } + &.solid-small-dot-d6-6::before { content : '\f18e'; } +} \ No newline at end of file diff --git a/themes/fonts/5e/dicefont.woff2 b/themes/fonts/icon fonts/dicefont.woff2 similarity index 100% rename from themes/fonts/5e/dicefont.woff2 rename to themes/fonts/icon fonts/dicefont.woff2 diff --git a/themes/fonts/5e/dicefont_license.md b/themes/fonts/icon fonts/dicefont_license.md similarity index 100% rename from themes/fonts/5e/dicefont_license.md rename to themes/fonts/icon fonts/dicefont_license.md diff --git a/themes/fonts/icon fonts/font-icons.less b/themes/fonts/icon fonts/font-icons.less index f8eb19f11..be8efa734 100644 --- a/themes/fonts/icon fonts/font-icons.less +++ b/themes/fonts/icon fonts/font-icons.less @@ -1,6 +1,6 @@ -/* Main Font, serif */ +/* Icon Font: Elderberry Inn */ @font-face { - font-family : 'Eldeberry-Inn'; + font-family : 'Elderberry-Inn'; font-style : normal; font-weight : normal; src : url('../../../fonts/icon fonts/Elderberry-Inn-Icons.woff2'); @@ -10,7 +10,7 @@ span.ei { display : inline-block; margin-right : 3px; - font-family : 'Eldeberry-Inn'; + font-family : 'Elderberry-Inn'; line-height : 1; vertical-align : baseline; -moz-osx-font-smoothing : grayscale;