diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 24fcc9e9b..cd74b0af5 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -185,7 +185,7 @@ const Editor = createClass({ // Highlight injectors {style} if(line.includes('{') && line.includes('}')){ - const regex = /(?:^|[^{\n])({(?=((?::(?:"[\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"':{}\s]*)*))\2})/gm; + const regex = /(?:^|[^{\n])({(?=((?:[:=](?:"[\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"':={}\s]*)*))\2})/gm; let match; while ((match = regex.exec(line)) != null) { codeMirror.markText({ line: lineNumber, ch: line.indexOf(match[1]) }, { line: lineNumber, ch: line.indexOf(match[1]) + match[1].length }, { className: 'injection' }); @@ -193,7 +193,7 @@ const Editor = createClass({ } // Highlight inline spans {{content}} if(line.includes('{{') && line.includes('}}')){ - const regex = /{{(?=((?::(?:"[\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"':{}\s]*)*))\1 *|}}/g; + const regex = /{{(?=((?:[:=](?:"[\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"':={}\s]*)*))\1 *|}}/g; let match; let blockCount = 0; while ((match = regex.exec(line)) != null) { @@ -212,7 +212,7 @@ const Editor = createClass({ // Highlight block divs {{\n Content \n}} let endCh = line.length+1; - const match = line.match(/^ *{{(?=((?::(?:"[\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"':{}\s]*)*))\1 *$|^ *}}$/); + const match = line.match(/^ *{{(?=((?:[:=](?:"[\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"':={}\s]*)*))\1 *$|^ *}}$/); if(match) endCh = match.index+match[0].length; codeMirror.markText({ line: lineNumber, ch: 0 }, { line: lineNumber, ch: endCh }, { className: 'block' }); diff --git a/package-lock.json b/package-lock.json index e52ed4b9d..209d8609f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,9 +10,9 @@ "hasInstallScript": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.23.5", - "@babel/plugin-transform-runtime": "^7.23.4", - "@babel/preset-env": "^7.23.5", + "@babel/core": "^7.23.6", + "@babel/plugin-transform-runtime": "^7.23.6", + "@babel/preset-env": "^7.23.6", "@babel/preset-react": "^7.23.3", "@googleapis/drive": "^8.4.0", "body-parser": "^1.20.2", @@ -30,18 +30,18 @@ "less": "^3.13.1", "lodash": "^4.17.21", "marked": "5.1.1", - "marked-extended-tables": "^1.0.7", + "marked-extended-tables": "^1.0.8", "marked-gfm-heading-id": "^3.1.2", "marked-smartypants-lite": "^1.0.1", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.29.4", - "mongoose": "^8.0.2", + "mongoose": "^8.0.3", "nanoid": "3.3.4", "nconf": "^0.12.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-frame-component": "^4.1.3", - "react-router-dom": "6.20.1", + "react-router-dom": "6.21.0", "sanitize-filename": "1.6.3", "superagent": "^8.1.2", "vitreum": "git+https://git@github.com/calculuschild/vitreum.git" @@ -106,20 +106,20 @@ } }, "node_modules/@babel/core": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz", - "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz", + "integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.5", - "@babel/helper-compilation-targets": "^7.22.15", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.5", - "@babel/parser": "^7.23.5", + "@babel/helpers": "^7.23.6", + "@babel/parser": "^7.23.6", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.5", - "@babel/types": "^7.23.5", + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -140,11 +140,11 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, "node_modules/@babel/generator": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", - "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", "dependencies": { - "@babel/types": "^7.23.5", + "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -189,13 +189,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", - "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.15", - "browserslist": "^4.21.9", + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -449,13 +449,13 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz", - "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz", + "integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==", "dependencies": { "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.5", - "@babel/types": "^7.23.5" + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6" }, "engines": { "node": ">=6.9.0" @@ -475,9 +475,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", - "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", "bin": { "parser": "bin/babel-parser.js" }, @@ -1031,11 +1031,12 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.3.tgz", - "integrity": "sha512-X8jSm8X1CMwxmK878qsUGJRmbysKNbdpTv/O1/v0LuY/ZkZrng5WYiekYSdg9m09OTmDDUWeEDsTE+17WYbAZw==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", + "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1455,9 +1456,9 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.4.tgz", - "integrity": "sha512-ITwqpb6V4btwUG0YJR82o2QvmWrLgDnx/p2A3CTPYGaRgULkDiC0DRA2C4jlRB9uXGUEfaSS/IGHfVW+ohzYDw==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.6.tgz", + "integrity": "sha512-kF1Zg62aPseQ11orDhFRw+aPG/eynNQtI+TyY+m33qJa2cJ5EEvza2P2BNTIA9E5MyqFABHEyY6CPHwgdy9aNg==", "dependencies": { "@babel/helper-module-imports": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", @@ -1604,12 +1605,12 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.5.tgz", - "integrity": "sha512-0d/uxVD6tFGWXGDSfyMD1p2otoaKmu6+GD+NfAx0tMaH+dxORnp7T9TaVQ6mKyya7iBtCIVxHjWT7MuzzM9z+A==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.6.tgz", + "integrity": "sha512-2XPn/BqKkZCpzYhUUNZ1ssXw7DcXfKQEjv/uXZUXgaebCMYmkEsfZ2yY+vv+xtXv50WmL5SGhyB6/xsWxIvvOQ==", "dependencies": { "@babel/compat-data": "^7.23.5", - "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-option": "^7.23.5", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", @@ -1649,7 +1650,7 @@ "@babel/plugin-transform-dynamic-import": "^7.23.4", "@babel/plugin-transform-exponentiation-operator": "^7.23.3", "@babel/plugin-transform-export-namespace-from": "^7.23.4", - "@babel/plugin-transform-for-of": "^7.23.3", + "@babel/plugin-transform-for-of": "^7.23.6", "@babel/plugin-transform-function-name": "^7.23.3", "@babel/plugin-transform-json-strings": "^7.23.4", "@babel/plugin-transform-literals": "^7.23.3", @@ -1758,19 +1759,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz", - "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", + "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", "dependencies": { "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.5", + "@babel/generator": "^7.23.6", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.5", - "@babel/types": "^7.23.5", - "debug": "^4.1.0", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -1778,9 +1779,9 @@ } }, "node_modules/@babel/types": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", - "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", "dependencies": { "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", @@ -2837,9 +2838,9 @@ } }, "node_modules/@remix-run/router": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.13.1.tgz", - "integrity": "sha512-so+DHzZKsoOcoXrILB4rqDkMDy7NLMErRdOxvzvOKb507YINKUP4Di+shbTZDhSE/pBZ+vr7XGIpcOO0VLSA+Q==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.14.0.tgz", + "integrity": "sha512-WOHih+ClN7N8oHk9N4JUiMxQJmRVaOxcg8w7F/oHUXzJt920ekASLI/7cYX8XkntDWRhLZtsk6LbGrkgOAvi5A==", "engines": { "node": ">=14.0.0" } @@ -4227,9 +4228,9 @@ } }, "node_modules/browserslist": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", - "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", "funding": [ { "type": "opencollective", @@ -4245,9 +4246,9 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001541", - "electron-to-chromium": "^1.4.535", - "node-releases": "^2.0.13", + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", "update-browserslist-db": "^1.0.13" }, "bin": { @@ -4408,9 +4409,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001547", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001547.tgz", - "integrity": "sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA==", + "version": "1.0.30001570", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", + "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", "funding": [ { "type": "opencollective", @@ -5381,9 +5382,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.551", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.551.tgz", - "integrity": "sha512-/Ng/W/kFv7wdEHYzxdK7Cv0BHEGSkSB3M0Ssl8Ndr1eMiYeas/+Mv4cNaDqamqWx6nd2uQZfPz6g25z25M/sdw==" + "version": "1.4.612", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.612.tgz", + "integrity": "sha512-dM8BMtXtlH237ecSMnYdYuCkib2QHq0kpWfUnavjdYsyr/6OsAwg5ZGUfnQ9KD1Ga4QgB2sqXlB2NT8zy2GnVg==" }, "node_modules/elliptic": { "version": "6.5.4", @@ -10052,11 +10053,11 @@ } }, "node_modules/marked-extended-tables": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/marked-extended-tables/-/marked-extended-tables-1.0.7.tgz", - "integrity": "sha512-DwURXYCPxhIdEP6y0rI9Od3qPM6ieXK7ce6hqR0/9MpkSmBUMrrBtoH3fMp6+oEXjfmIq4YBGPi9Ios80N3Q2w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/marked-extended-tables/-/marked-extended-tables-1.0.8.tgz", + "integrity": "sha512-GcVQP7EnfQ98o09ooqM4t4M0qfpKdKuk7/z4qZfgkLyXTXsIyFS1eeBmfC36o1NbR6aSq8ynL/LeTz3w4RS27Q==", "peerDependencies": { - "marked": ">=3 <10" + "marked": ">=3 <12" } }, "node_modules/marked-gfm-heading-id": { @@ -10453,9 +10454,9 @@ } }, "node_modules/mongoose": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.0.2.tgz", - "integrity": "sha512-Vsi9GzTXjdBVzheT1HZOZ2jHNzzR9Xwb5OyLz/FvDEAhlwrRnXnuqJf0QHINUOQSm7aoyvnPks0q85HJkd6yDw==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.0.3.tgz", + "integrity": "sha512-LJRT0yP4TW14HT4r2RkxqyvoTylMSzWpl5QOeVHTnRggCLQSpkoBdgbUtORFq/mSL2o9cLCPJz+6uzFj25qbHw==", "dependencies": { "bson": "^6.2.0", "kareem": "2.5.1", @@ -10834,9 +10835,9 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" }, "node_modules/nodemon": { "version": "2.0.21", @@ -11873,11 +11874,11 @@ "dev": true }, "node_modules/react-router": { - "version": "6.20.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.20.1.tgz", - "integrity": "sha512-ccvLrB4QeT5DlaxSFFYi/KR8UMQ4fcD8zBcR71Zp1kaYTC5oJKYAp1cbavzGrogwxca+ubjkd7XjFZKBW8CxPA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.21.0.tgz", + "integrity": "sha512-hGZ0HXbwz3zw52pLZV3j3+ec+m/PQ9cTpBvqjFQmy2XVUWGn5MD+31oXHb6dVTxYzmAeaiUBYjkoNz66n3RGCg==", "dependencies": { - "@remix-run/router": "1.13.1" + "@remix-run/router": "1.14.0" }, "engines": { "node": ">=14.0.0" @@ -11887,12 +11888,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.20.1", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.20.1.tgz", - "integrity": "sha512-npzfPWcxfQN35psS7rJgi/EW0Gx6EsNjfdJSAk73U/HqMEJZ2k/8puxfwHFgDQhBGmS3+sjnGbMdMSV45axPQw==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.21.0.tgz", + "integrity": "sha512-1dUdVj3cwc1npzJaf23gulB562ESNvxf7E4x8upNJycqyUm5BRRZ6dd3LrlzhtLaMrwOCO8R0zoiYxdaJx4LlQ==", "dependencies": { - "@remix-run/router": "1.13.1", - "react-router": "6.20.1" + "@remix-run/router": "1.14.0", + "react-router": "6.21.0" }, "engines": { "node": ">=14.0.0" diff --git a/package.json b/package.json index fc80c65c8..ebeafd6b2 100644 --- a/package.json +++ b/package.json @@ -80,9 +80,9 @@ ] }, "dependencies": { - "@babel/core": "^7.23.5", - "@babel/plugin-transform-runtime": "^7.23.4", - "@babel/preset-env": "^7.23.5", + "@babel/core": "^7.23.6", + "@babel/plugin-transform-runtime": "^7.23.6", + "@babel/preset-env": "^7.23.6", "@babel/preset-react": "^7.23.3", "@googleapis/drive": "^8.4.0", "body-parser": "^1.20.2", @@ -100,18 +100,18 @@ "less": "^3.13.1", "lodash": "^4.17.21", "marked": "5.1.1", - "marked-extended-tables": "^1.0.7", + "marked-extended-tables": "^1.0.8", "marked-gfm-heading-id": "^3.1.2", "marked-smartypants-lite": "^1.0.1", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.29.4", - "mongoose": "^8.0.2", + "mongoose": "^8.0.3", "nanoid": "3.3.4", "nconf": "^0.12.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-frame-component": "^4.1.3", - "react-router-dom": "6.20.1", + "react-router-dom": "6.21.0", "sanitize-filename": "1.6.3", "superagent": "^8.1.2", "vitreum": "git+https://git@github.com/calculuschild/vitreum.git" diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index fcfee1dbf..0a99570db 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -7,7 +7,7 @@ const cx = require('classnames'); const closeTag = require('./close-tag'); let CodeMirror; -if(typeof navigator !== 'undefined'){ +if(typeof window !== 'undefined'){ CodeMirror = require('codemirror'); //Language Modes diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index 7a584a927..f016218ba 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -34,7 +34,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,\-()#%. ]*"|[\w\-()#%.]*)|[^"':{}\s]*)*))\1 *|}}/g; + const inlineRegex = /{{(?=((?:[:=](?:"['\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"=':{}\s]*)*))\1 *|}}/g; const match = completeSpan.exec(src); if(match) { //Find closing delimiter @@ -45,7 +45,7 @@ const mustacheSpans = { let delim; while (delim = inlineRegex.exec(match[0])) { if(!tags) { - tags = ` ${processStyleTags(delim[0].substring(2))}`; + tags = `${processStyleTags(delim[0].substring(2))}`; endTags = delim[0].length; } if(delim[0].startsWith('{{')) { @@ -84,7 +84,7 @@ const mustacheDivs = { start(src) { return src.match(/\n *{{[^{]/m)?.index; }, // Hint to Marked.js to stop and check for a match tokenizer(src, tokens) { 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); if(match) { //Find closing delimiter @@ -95,7 +95,7 @@ const mustacheDivs = { let delim; while (delim = blockRegex.exec(match[0])?.[0].trim()) { if(!tags) { - tags = ` ${processStyleTags(delim.substring(2))}`; + tags = `${processStyleTags(delim.substring(2))}`; endTags = delim.length; } if(delim.startsWith('{{')) { @@ -132,14 +132,14 @@ 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,\-()#%. ]*"|[\w\-()#%.]*)|[^"':{}\s]*)*))\1}/g; + const inlineRegex = /^ *{(?=((?:[:=](?:"['\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"=':{}\s]*)*))\1}/g; const match = inlineRegex.exec(src); if(match) { const lastToken = tokens[tokens.length - 1]; if(!lastToken || lastToken.type == 'mustacheInjectInline') return false; - const tags = ` ${processStyleTags(match[1])}`; + const tags = `${processStyleTags(match[1])}`; lastToken.originalType = lastToken.type; lastToken.type = 'mustacheInjectInline'; lastToken.tags = tags; @@ -167,7 +167,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,\-()#%. ]*"|[\w\-()#%.]*)|[^"':{}\s]*)*))\1}/ym; + const inlineRegex = /^ *{(?=((?:[:=](?:"['\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"=':{}\s]*)*))\1}/ym; const match = inlineRegex.exec(src); if(match) { const lastToken = tokens[tokens.length - 1]; @@ -175,7 +175,7 @@ const mustacheInjectBlock = { return false; lastToken.originalType = 'mustacheInjectBlock'; - lastToken.tags = ` ${processStyleTags(match[1])}`; + lastToken.tags = `${processStyleTags(match[1])}`; return { type : 'mustacheInjectBlock', // Should match "name" above raw : match[0], // Text to consume from the source @@ -367,16 +367,19 @@ const voidTags = new Set([ ]); const processStyleTags = (string)=>{ - //split tags up. quotes can only occur right after colons. + //split tags up. quotes can only occur right after : or =. //TODO: can we simplify to just split on commas? - const tags = string.match(/(?:[^, ":]+|:(?:"[^"]*"|))+/g); + 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(':')) && (!tag.includes('='))); + const attributes = _.remove(tags, (tag)=>(tag.includes('='))).map((tag)=>tag.replace(/="?([^"]*)"?/g, '="$1"')); + const styles = tags?.length ? tags.map((tag)=>tag.replace(/:"?([^"]*)"?/g, ':$1;').trim()) : []; - 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;')); - return `${classes.join(' ')}" ${id ? `id="${id}"` : ''} ${styles.length ? `style="${styles.join(' ')}"` : ''}`; + return `${classes?.length ? ` ${classes.join(' ')}` : ''}"` + + `${id ? ` id="${id}"` : ''}` + + `${styles?.length ? ` style="${styles.join(' ')}"` : ''}` + + `${attributes?.length ? ` ${attributes.join(' ')}` : ''}`; }; module.exports = { diff --git a/tests/markdown/mustache-syntax.test.js b/tests/markdown/mustache-syntax.test.js index d9e1ce6f9..835bcc575 100644 --- a/tests/markdown/mustache-syntax.test.js +++ b/tests/markdown/mustache-syntax.test.js @@ -13,137 +13,134 @@ String.prototype.trimReturns = function(){ // Remove the `.failing()` method once you have fixed the issue. describe('Inline: When using the Inline syntax {{ }}', ()=>{ - it.failing('Renders a mustache span with text only', function() { + it('Renders a mustache span with text only', function() { const source = '{{ text}}'; const rendered = Markdown.render(source); - // FIXME: adds extra \s after class names expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); - it.failing('Renders a mustache span with text only, but with spaces', function() { + it('Renders a mustache span with text only, but with spaces', function() { const source = '{{ this is a text}}'; const rendered = Markdown.render(source); - // FIXME: adds extra \s after class names expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('this is a text'); }); - it.failing('Renders an empty mustache span', function() { + it('Renders an empty mustache span', function() { const source = '{{}}'; const rendered = Markdown.render(source); - // FIXME: adds extra \s after class names expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(''); }); - it.failing('Renders a mustache span with just a space', function() { + it('Renders a mustache span with just a space', function() { const source = '{{ }}'; const rendered = Markdown.render(source); - // FIXME: adds extra \s after class names expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(''); }); - it.failing('Renders a mustache span with a few spaces only', function() { + it('Renders a mustache span with a few spaces only', function() { const source = '{{ }}'; const rendered = Markdown.render(source); - // FIXME: adds extra \s after class names expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(''); }); - it.failing('Renders a mustache span with text and class', function() { + it('Renders a mustache span with text and class', function() { const source = '{{my-class text}}'; const rendered = Markdown.render(source); - // FIXME: adds two extra \s before closing `>` in opening tag. expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); - it.failing('Renders a mustache span with text and two classes', function() { + it('Renders a mustache span with text and two classes', function() { const source = '{{my-class,my-class2 text}}'; const rendered = Markdown.render(source); - // FIXME: adds two extra \s before closing `>` in opening tag. expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); - it.failing('Renders a mustache span with text with spaces and class', function() { + it('Renders a mustache span with text with spaces and class', function() { const source = '{{my-class this is a text}}'; const rendered = Markdown.render(source); - // FIXME: adds two extra \s before closing `>` in opening tag expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('this is a text'); }); - it.failing('Renders a mustache span with text and id', function() { + it('Renders a mustache span with text and id', function() { const source = '{{#my-span text}}'; const rendered = Markdown.render(source); - // FIXME: adds extra \s before closing `>` in opening tag, and another after class names expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); - it.failing('Renders a mustache span with text and two ids', function() { + it('Renders a mustache span with text and two ids', function() { const source = '{{#my-span,#my-favorite-span text}}'; const rendered = Markdown.render(source); - // FIXME: adds extra \s before closing `>` in opening tag, and another after class names expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); - it.failing('Renders a mustache span with text and css property', function() { + it('Renders a mustache span with text and css property', function() { const source = '{{color:red text}}'; const rendered = Markdown.render(source); - // FIXME: adds extra \s after class names expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); - it.failing('Renders a mustache span with text and two css properties', function() { + it('Renders a mustache span with text and two css properties', function() { const source = '{{color:red,padding:5px text}}'; const rendered = Markdown.render(source); - // FIXME: adds extra \s after class names expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); - it.failing('Renders a mustache span with text and css property which contains quotes', function() { + it('Renders a mustache span with text and css property which contains quotes', function() { const source = '{{font-family:"trebuchet ms" text}}'; const rendered = Markdown.render(source); - // FIXME: adds extra \s after class names expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); - it.failing('Renders a mustache span with text and two css properties which contains quotes', function() { + it('Renders a mustache span with text and two css properties which contains quotes', function() { const source = '{{font-family:"trebuchet ms",padding:"5px 10px" text}}'; const rendered = Markdown.render(source); - // FIXME: adds extra \s after class names expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); - it.failing('Renders a mustache span with text with quotes and css property which contains quotes', function() { + it('Renders a mustache span with text with quotes and css property which contains double quotes', function() { const source = '{{font-family:"trebuchet ms" text "with quotes"}}'; const rendered = Markdown.render(source); - // FIXME: adds extra \s after class names expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text “with quotes”'); }); + + it('Renders a mustache span with text with quotes and css property which contains double and simple quotes', function() { + const source = `{{--stringVariable:"'string'" text "with quotes"}}`; + const rendered = Markdown.render(source); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`text “with quotes”`); + }); + + it('Renders a mustache span with text, id, class and a couple of css properties', function() { const source = '{{pen,#author,color:orange,font-family:"trebuchet ms" text}}'; const rendered = Markdown.render(source); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); + + it('Renders a span with added attributes', function() { + const source = 'Text and {{pen,#author,color:orange,font-family:"trebuchet ms",a="b and c",d=e, text}} and more text!'; + const rendered = Markdown.render(source); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('

Text and text and more text!

\n'); + }); }); // BLOCK SYNTAX describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{ - it.failing('Renders a div with text only', function() { + it('Renders a div with text only', function() { const source = dedent`{{ text }}`; const rendered = Markdown.render(source).trimReturns(); - // FIXME: adds extra \s after class names expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

text

`); }); - it.failing('Renders an empty div', function() { + it('Renders an empty div', function() { const source = dedent`{{ }}`; const rendered = Markdown.render(source).trimReturns(); - // FIXME: adds extra \s after class names expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`); }); @@ -151,52 +148,62 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{ const source = dedent`{{ }}`; const rendered = Markdown.render(source).trimReturns(); - // this actually renders in HB as '{{ }}'... expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

{{}}

`); }); - it.failing('Renders a div with a single class', function() { + it('Renders a div with a single class', function() { const source = dedent`{{cat }}`; const rendered = Markdown.render(source).trimReturns(); - // FIXME: adds two extra \s before closing `>` in opening tag expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`); }); - it.failing('Renders a div with a single class and text', function() { + it('Renders a div with a single class and text', function() { const source = dedent`{{cat Sample text. }}`; const rendered = Markdown.render(source).trimReturns(); - // FIXME: adds two extra \s before closing `>` in opening tag expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Sample text.

`); }); - it.failing('Renders a div with two classes and text', function() { + it('Renders a div with two classes and text', function() { const source = dedent`{{cat,dog Sample text. }}`; const rendered = Markdown.render(source).trimReturns(); - // FIXME: adds two extra \s before closing `>` in opening tag expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Sample text.

`); }); - it.failing('Renders a div with a style and text', function() { + it('Renders a div with a style and text', function() { const source = dedent`{{color:red Sample text. }}`; const rendered = Markdown.render(source).trimReturns(); - // FIXME: adds two extra \s before closing `>` in opening tag expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Sample text.

`); }); - it.failing('Renders a div with a class, style and text', function() { + it('Renders a div with a style that has a string variable, and text', function() { + const source = dedent`{{--stringVariable:"'string'" + Sample text. + }}`; + const rendered = Markdown.render(source).trimReturns(); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Sample text.

`); + }); + + it('Renders a div with a style that has a string variable, and text', function() { + const source = dedent`{{--stringVariable:"'string'" + Sample text. + }}`; + const rendered = Markdown.render(source).trimReturns(); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Sample text.

`); + }); + + it('Renders a div with a class, style and text', function() { const source = dedent`{{cat,color:red Sample text. }}`; const rendered = Markdown.render(source).trimReturns(); - // FIXME: adds extra \s after the class attribute expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Sample text.

`); }); @@ -208,14 +215,27 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Sample text.

`); }); - it.failing('Renders a div with a single ID', function() { + it('Renders a div with a single ID', function() { const source = dedent`{{#cat,#dog Sample text. }}`; const rendered = Markdown.render(source).trimReturns(); - // FIXME: adds extra \s before closing `>` in opening tag, and another after class names expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Sample text.

`); }); + + it('Renders a div with an ID, class, style and text, and a variable assignment', function() { + const source = dedent`{{color:red,cat,#dog,a="b and c",d="e" + Sample text. + }}`; + const rendered = Markdown.render(source).trimReturns(); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Sample text.

`); + }); + + it('Renders a div with added attributes', function() { + const source = '{{pen,#author,color:orange,font-family:"trebuchet ms",a="b and c",d=e\nText and text and more text!\n}}\n'; + const rendered = Markdown.render(source); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('

Text and text and more text!

\n
'); + }); }); // MUSTACHE INJECTION SYNTAX @@ -235,12 +255,24 @@ describe('Injection: When an injection tag follows an element', ()=>{ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); + it.failing('Renders a span "text" with injected attribute', function() { + const source = '{{ text}}{a="b and c"}'; + const rendered = Markdown.render(source); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); + }); + it.failing('Renders a span "text" with injected style', function() { const source = '{{ text}}{color:red}'; const rendered = Markdown.render(source); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); + it.failing('Renders a span "text" with injected style using a string variable', function() { + const source = `{{ text}}{--stringVariable:"'string'"}`; + const rendered = Markdown.render(source); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`text`); + }); + it.failing('Renders a span "text" with two injected styles', function() { const source = '{{ text}}{color:red,background:blue}'; const rendered = Markdown.render(source); @@ -270,6 +302,12 @@ describe('Injection: When an injection tag follows an element', ()=>{ const rendered = Markdown.render(source).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('

text{background:blue}

'); }); + + it('Renders an image with added attributes', function() { + const source = `![homebrew mug](https://i.imgur.com/hMna6G0.png) {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(`

homebrew mug

`); + }); }); describe('and that element is a block', ()=>{ @@ -297,7 +335,16 @@ describe('Injection: When an injection tag follows an element', ()=>{ }} {color:red,background:blue}`; const rendered = Markdown.render(source).trimReturns(); - expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('

text

'); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

text

`); + }); + + it.failing('renders a div "text" with injected variable string', function() { + const source = dedent`{{ + text + }} + {--stringVariable:"'string'"}`; + const rendered = Markdown.render(source).trimReturns(); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

text

`); }); it.failing('renders an h2 header "text" with injected class name', function() { diff --git a/themes/V3/5ePHB/style.less b/themes/V3/5ePHB/style.less index fbb00c670..daa983a9d 100644 --- a/themes/V3/5ePHB/style.less +++ b/themes/V3/5ePHB/style.less @@ -14,16 +14,13 @@ --HB_Color_Footnotes : #C9AD6A; // Gold } -@page { margin : 0; } -body { counter-reset : phb-page-numbers; } -* { -webkit-print-color-adjust : exact; } .useSansSerif() { font-family : 'ScalySansRemake'; font-size : 0.318cm; line-height : 1.2em; p,dl,ul,ol { line-height : 1.2em; } ul, ol { padding-left : 1em; } - em { font-style : italic; } + em { font-style : italic; } strong { font-weight : 800; letter-spacing : -0.02em; @@ -42,53 +39,31 @@ body { counter-reset : phb-page-numbers; } -webkit-column-gap : 0.9cm; -moz-column-gap : 0.9cm; } -.columnWrapper { - column-gap : inherit; - max-height : 100%; - column-span : all; - columns : inherit; -} .page { .useColumns(); - position : relative; - z-index : 15; - box-sizing : border-box; - width : 215.9mm; - height : 279.4mm; - padding : 1.4cm 1.9cm 1.7cm; - overflow : hidden; - font-family : 'BookInsanityRemake'; - font-size : 0.34cm; - counter-increment : phb-page-numbers; - background-color : var(--HB_Color_Background); - background-image : @backgroundImage; - text-rendering : optimizeLegibility; + font-family : 'BookInsanityRemake'; + font-size : 0.34cm; + background-image : @backgroundImage; } -//***************************** +// ***************************** // * BASE - // *****************************/ +// *****************************/ .page { p { - display : block; - line-height : 1.25em; - overflow-wrap : break-word; //TODO: MAKE ALL MARGINS TOP-ONLY. USE * + * STYLE SELECTORS - & + * { margin-top : 0.325cm; } + line-height : 1.25em; + & + * { margin-top : 0.325cm; } //TODO: MAKE ALL MARGINS TOP-ONLY. USE * + * STYLE SELECTORS & + p { margin-top : 0; } } ul { - padding-left : 1.4em; - margin-bottom : 0.8em; - line-height : 1.25em; - list-style-position : outside; - list-style-type : disc; + padding-left : 1.4em; + margin-bottom : 0.8em; + line-height : 1.25em; } ol { - padding-left : 1.4em; - margin-bottom : 0.8em; - line-height : 1.25em; - list-style-position : outside; - list-style-type : decimal; + padding-left : 1.4em; + margin-bottom : 0.8em; + line-height : 1.25em; } //Indents after p or lists p + p, ul + p, ol + p { text-indent : 1em; } @@ -97,24 +72,12 @@ body { counter-reset : phb-page-numbers; } font-weight : bold; letter-spacing : -0.02em; } - em { font-style : italic; } - sup { - font-size : smaller; - line-height : 0; - vertical-align : super; - } - sub { - font-size : smaller; - line-height : 0; - vertical-align : sub; - } - //***************************** + // ***************************** // * HEADERS // *****************************/ h1,h2,h3,h4 { - font-family : 'MrEavesRemake'; - font-weight : 800; - color : var(--HB_Color_HeaderText); + font-family : 'MrEavesRemake'; + color : var(--HB_Color_HeaderText); } h1 { margin-bottom : 0.18cm; //Margin-bottom only because this is WIDE @@ -143,8 +106,8 @@ body { counter-reset : phb-page-numbers; } h2 { //margin-top : 0px; //Font is misaligned. Shift up slightly //margin-bottom : 0.05cm; - font-size : 0.75cm; - line-height : 0.988em; //Font is misaligned. Shift up slightly + font-size : 0.75cm; + line-height : 0.988em; //Font is misaligned. Shift up slightly } h3 { //margin-top : -0.1cm; //Font is misaligned. Shift up slightly @@ -160,8 +123,8 @@ body { counter-reset : phb-page-numbers; } h4 { //margin-top : -0.02cm; //Font is misaligned. Shift up slightly //margin-bottom : 0.02cm; - font-size : 0.458cm; - line-height : 0.971em; //Font is misaligned. Shift up slightly + font-size : 0.458cm; + line-height : 0.971em; //Font is misaligned. Shift up slightly & + * { margin-top : 0.09cm; } } * + h4 { @@ -170,19 +133,17 @@ body { counter-reset : phb-page-numbers; } h5 { //margin-top : -0.02cm; //Font is misaligned. Shift up slightly //margin-bottom : 0.02cm; - font-family : 'ScalySansSmallCapsRemake'; - font-size : 0.423cm; - font-weight : 900; - line-height : 0.951em; //Font is misaligned. Shift up slightly + font-family : 'ScalySansSmallCapsRemake'; + font-size : 0.423cm; + line-height : 0.951em; //Font is misaligned. Shift up slightly & + * { margin-top : 0.2cm; } } - //***************************** + // ***************************** // * TABLE // *****************************/ table { .useSansSerif(); - width : 100%; - line-height : 16px; + line-height : 16px; & + * { margin-top : 0.325cm; } thead { display : table-row-group; @@ -198,15 +159,15 @@ body { counter-reset : phb-page-numbers; } tr { td { //padding : 0.14em 0.4em; - padding : 0px 1.5px; // Both of these are temporary, just to force + padding : 0px 1.5px; // Both of these are temporary, just to force //line-height : 16px; // PDF to render at same height until Chrome 108 } &:nth-child(odd) { background-color : var(--HB_Color_Accent); } } } } - //***************************** - // * QUOTE + // ***************************** + // * QUOTE // *****************************/ .quote { @@ -239,9 +200,7 @@ body { counter-reset : phb-page-numbers; } } - - - //***************************** + // ***************************** // * NOTE // *****************************/ .note { @@ -255,7 +214,7 @@ body { counter-reset : phb-page-numbers; } border-image-outset : 9px 0px; box-shadow : 1px 4px 14px #888888; .page :where(&) { - margin-top : 9px; //Prevent top border getting cut off on colbreak + margin-top : 9px; //Prevent top border getting cut off on colbreak } & + * { margin-top : 0.45cm; } h5 { font-size : 0.375cm; } @@ -265,7 +224,7 @@ body { counter-reset : phb-page-numbers; } } :last-child { margin-bottom : 0; } } - //************************************ + // ************************************ // * DESCRIPTIVE TEXT BOX // ************************************/ .descriptive { @@ -289,7 +248,7 @@ body { counter-reset : phb-page-numbers; } } :last-child { margin-bottom : 0; } } - //***************************** + // ***************************** // * Images Snippets // *****************************/ @@ -318,42 +277,10 @@ body { counter-reset : phb-page-numbers; } } /* Watermark */ - .watermark { - position : absolute; - top : 0; - left : 0; - z-index : 500; - display : grid !important; - place-items : center; - justify-content : center; - width : 100%; - height : 100%; - font-size : 120px; - color : black; - text-transform : uppercase; - mix-blend-mode : overlay; - opacity : 30%; - transform : rotate(-45deg); - p { margin-bottom : none; } - } + .watermark { color : black; } /* Watercolor */ - [class*='watercolor'] { - position : absolute; - z-index : -2; - width : 2000px; /* dimensions need to be real big so the user can set */ - height : 2000px; /* height or width and the image will maintain aspect ratio */ - background-color : var(--HB_Color_WatercolorStain); /* default color */ - background-size : cover; - -webkit-mask-image : var(--wc); - -webkit-mask-size : contain; - -webkit-mask-repeat : no-repeat; - mask-image : var(--wc); - mask-size : contain; - mask-repeat : no-repeat; - --wc : @watercolor1; /* default image */ - } - + .watercolor1 { --wc : @watercolor1; } .watercolor2 { --wc : @watercolor2; } .watercolor3 { --wc : @watercolor3; } @@ -367,7 +294,7 @@ body { counter-reset : phb-page-numbers; } .watercolor11 { --wc : @watercolor11; } .watercolor12 { --wc : @watercolor12; } - //***************************** + // ***************************** // * MONSTER STAT BLOCK // *****************************/ .monster { @@ -388,24 +315,24 @@ body { counter-reset : phb-page-numbers; } box-shadow : 1px 4px 14px #888888; } - position : relative; - padding : 0px; - margin-bottom : 0.325cm; + position : relative; + padding : 0px; + margin-bottom : 0.325cm; //Headers h2 { - margin : 0; - font-size : 0.62cm; - line-height : 1em; + margin : 0; + font-size : 0.62cm; + line-height : 1em; & + p { margin-bottom : 0; font-size : 0.304cm; //Monster size and type subtext } } h3 { - font-family : 'ScalySansSmallCapsRemake'; - font-size : 0.45cm; - border-bottom : 1.5px solid var(--HB_Color_HeaderText); + font-family : 'ScalySansSmallCapsRemake'; + font-size : 0.45cm; + border-bottom : 1.5px solid var(--HB_Color_HeaderText); } //Triangle dividers @@ -452,10 +379,10 @@ body { counter-reset : phb-page-numbers; } .useColumns(0.96, @fillMode: balance); } - //***************************** + // ***************************** // * FOOTER // *****************************/ - &:after { + &::after { position : absolute; bottom : 0px; left : 0px; @@ -495,23 +422,18 @@ body { counter-reset : phb-page-numbers; } color : var(--HB_Color_Footnotes); text-align : right; } - //************************************ + // ************************************ // * CODE BLOCKS // ************************************/ code { padding : 0px 4px; - font-family : 'Courier New', 'Courier', monospace; - font-size : 0.325; + font-size : 0.325cm; color : #58180D; - overflow-wrap : break-word; - white-space : pre-wrap; background-color : #FAF7EA; border-radius : 4px; } pre code { - display : inline-block; - width : 100%; padding : 0.15cm; margin-bottom : 2px; border-style : solid; @@ -525,26 +447,13 @@ body { counter-reset : phb-page-numbers; } } & + * { margin-top : 0.325cm; } } - //***************************** + // ***************************** // * EXTRAS // *****************************/ hr { margin : 0px; visibility : hidden; } - .columnSplit { - visibility : hidden; - -webkit-column-break-after : always; - break-after : always; - -moz-column-break-after : always; - } - //Avoid breaking up - blockquote,table { - z-index : 15; - -webkit-column-break-inside : avoid; - page-break-inside : avoid; - break-inside : avoid; - } //Text indent right after table table + p { text-indent : 1em; } // Nested lists @@ -552,18 +461,13 @@ body { counter-reset : phb-page-numbers; } margin-bottom : 0px; margin-left : 1.5em; } - li { - -webkit-column-break-inside : avoid; - page-break-inside : avoid; - break-inside : avoid; - } } -//***************************** +// ***************************** // * SPELL LIST // *****************************/ .page .spellList { .useSansSerif(); - column-count : 2; + column-count : 2; ul + h5 { margin-top : 15px; } p, ul { font-size : 0.352cm; @@ -581,7 +485,7 @@ body { counter-reset : phb-page-numbers; } &.wide { column-count : 4; } } -//***************************** +// ***************************** // * CLASS TABLE // *****************************/ .page .classTable { @@ -628,7 +532,7 @@ body { counter-reset : phb-page-numbers; } } h5 + table { margin-top : 0.2cm; } } -//***************************** +// ***************************** // * FRONT COVER PAGE // *****************************/ .page:has(.frontCover) { @@ -722,7 +626,7 @@ body { counter-reset : phb-page-numbers; } } } } -//***************************** +// ***************************** // * INSIDE COVER PAGE // *****************************/ .page:has(.insideCover) { @@ -767,7 +671,7 @@ body { counter-reset : phb-page-numbers; } } } } -//***************************** +// ***************************** // * BACK COVER // *****************************/ .page:has(.backCover) { @@ -849,10 +753,10 @@ body { counter-reset : phb-page-numbers; } } } -//***************************** +// ***************************** // * PART COVER - // *****************************/ - .page:has(.partCover) { +// *****************************/ +.page:has(.partCover) { padding-top : 0; text-align : center; columns : 1; @@ -888,7 +792,7 @@ body { counter-reset : phb-page-numbers; } } } -//***************************** +// ***************************** // * TABLE OF CONTENTS // *****************************/ .page { @@ -957,33 +861,26 @@ body { counter-reset : phb-page-numbers; } } } -//***************************** +// ***************************** // * DEFINITION LISTS // *****************************/ .page { dl { - padding-left : 1em; line-height : 1.25em; - white-space : pre-line; - & + * { margin-top : 0.17cm; } + & + * { margin-top : 0.17cm; } } p + dl { margin-top : 0.17cm; } - dt { + dt { display : inline; margin-right : 5px; margin-left : -1em; } - dd { - display : inline; - margin-left : 0px; - text-indent : 0px; - } } -//***************************** +// ***************************** // * WIDE // *****************************/ -.page .wide { margin-bottom : 0.325cm; } +.page .wide { margin-bottom : 0.325cm; } .page h1 + * { margin-top : 0; } @@ -1022,7 +919,7 @@ body { counter-reset : phb-page-numbers; } } } } -//***************************** +// ***************************** // * INDEX // *****************************/ .page { diff --git a/themes/V3/Blank/snippets.js b/themes/V3/Blank/snippets.js index 72372c297..e437c0535 100644 --- a/themes/V3/Blank/snippets.js +++ b/themes/V3/Blank/snippets.js @@ -111,6 +111,21 @@ module.exports = [ icon : 'fas fa-code', gen : '' }, + { + name : 'Homebrewery Credit', + icon : 'fas fa-dice-d20', + gen : function(){ + return dedent` + {{homebreweryCredits + Made With + + {{homebreweryIcon}} + + The Homebrewery + [Homebrewery.Naturalcrit.com](https://homebrewery.naturalcrit.com) + }}\n\n`; + }, + } ] }, { diff --git a/themes/V3/Blank/style.less b/themes/V3/Blank/style.less index cbb748195..d31919fab 100644 --- a/themes/V3/Blank/style.less +++ b/themes/V3/Blank/style.less @@ -7,13 +7,9 @@ --HB_Color_WatercolorStain : #000000; // Black } -@page { margin: 0; } -body { - counter-reset : phb-page-numbers; -} -*{ - -webkit-print-color-adjust : exact; -} +@page { margin : 0; } +body { counter-reset : phb-page-numbers; } +* { -webkit-print-color-adjust : exact; } //***************************** // * MUSTACHE DIVS/SPANS @@ -23,9 +19,7 @@ body { break-inside : avoid; display : inline-block; width : 100%; - img { - z-index : 0; - } + img { z-index : 0; } } .inline-block { display : inline-block; @@ -33,97 +27,81 @@ body { } } -.useColumns(@multiplier : 1, @fillMode: auto){ +.useColumns(@multiplier : 1, @fillMode: auto) { column-fill : @fillMode; column-count : 2; } -.columnWrapper{ +.columnWrapper { + column-gap : inherit; max-height : 100%; column-span : all; columns : inherit; - column-gap : inherit; column-fill : inherit; } -.page{ +.page { .useColumns(); - height : 279.4mm; - width : 215.9mm; - padding : 1.4cm 1.9cm 1.7cm; - counter-increment : phb-page-numbers; - background-color : var(--HB_Color_Background); position : relative; z-index : 15; box-sizing : border-box; + width : 215.9mm; + height : 279.4mm; + padding : 1.4cm 1.9cm 1.7cm; overflow : hidden; + counter-increment : phb-page-numbers; + background-color : var(--HB_Color_Background); text-rendering : optimizeLegibility; contain : size; } - //***************************** - // * BASE +//***************************** +// * BASE // *****************************/ -.page{ - p{ - overflow-wrap : break-word; +.page { + p { display : block; + overflow-wrap : break-word; } - strong{ - font-weight : bold; - } - em{ - font-style : italic; - } - sup{ + strong { font-weight : bold; } + em { font-style : italic; } + sup { + font-size : smaller; + line-height : 0; vertical-align : super; - font-size : smaller; - line-height : 0; } - sub{ - vertical-align : sub; + sub { font-size : smaller; line-height : 0; + vertical-align : sub; } ul { + padding-left : 1.4em; list-style-position : outside; //Needed for multiline list items list-style-type : disc; - padding-left : 1.4em; } ol { + padding-left : 1.4em; list-style-position : outside; list-style-type : decimal; - padding-left : 1.4em; - } - img{ - z-index : -1; } + img { z-index : -1; } //***************************** // * HEADERS // *****************************/ - h1,h2,h3,h4,h5,h6{ + h1,h2,h3,h4,h5,h6 { font-weight : bold; line-height : 1.2em; } - h1{ - font-size : 2em; - } - h2{ - font-size : 1.5em; - } - h3{ - font-size : 1.17em; - } - h4{ - font-size : 1em; - } - h5{ - font-size : 0.83em; - } + h1 { font-size : 2em; } + h2 { font-size : 1.5em; } + h3 { font-size : 1.17em; } + h4 { font-size : 1em; } + h5 { font-size : 0.83em; } //***************************** // * TABLE // *****************************/ - table{ + table { width : 100%; - thead{ + thead { display : table-row-group; font-weight : bold; } @@ -135,42 +113,40 @@ body { //************************************ // * CODE BLOCKS // ************************************/ - code{ - font-family : "Courier New", Courier, monospace; - white-space : pre-wrap; + code { + font-family : 'Courier New', "Courier", monospace; overflow-wrap : break-word; + white-space : pre-wrap; } - pre code{ - width : 100%; + pre code { display : inline-block; + width : 100%; } //***************************** // * EXTRAS // *****************************/ .columnSplit { + margin-top : 0; visibility : hidden; -webkit-column-break-after : always; break-after : always; -moz-column-break-after : always; - margin-top : 0; - & + * { - margin-top : 0; - } + & + * { margin-top : 0; } } //Avoid breaking up - blockquote,table{ + blockquote,table { z-index : 15; -webkit-column-break-inside : avoid; page-break-inside : avoid; break-inside : avoid; } // Nested lists - ul ul,ol ol,ul ol,ol ul{ + ul ul,ol ol,ul ol,ol ul { margin-bottom : 0px; margin-left : 1.5em; } - li{ + li { -webkit-column-break-inside : avoid; page-break-inside : avoid; break-inside : avoid; @@ -178,69 +154,66 @@ body { /* Watermark */ .watermark { - display : grid !important; - place-items : center; - justify-content : center; position : absolute; - margin : 0; top : 0; left : 0; + z-index : 500; + display : grid !important; + place-items : center; + justify-content : center; width : 100%; height : 100%; + margin : 0; font-size : 120px; - text-transform : uppercase; + text-transform : uppercase; mix-blend-mode : overlay; opacity : 30%; transform : rotate(-45deg); - z-index : 500; - p { - margin-bottom : none; - } + p { margin-bottom : none; } } /* Watercolor */ - [class*="watercolor"] { + [class*='watercolor'] { position : absolute; + z-index : -2; width : 2000px; /* dimensions need to be real big so the user can set */ height : 2000px; /* height or width and the image will maintain aspect ratio */ + background-color : var(--HB_Color_WatercolorStain); /* default color */ + background-size : cover; -webkit-mask-image : var(--wc); -webkit-mask-size : contain; -webkit-mask-repeat : no-repeat; mask-image : var(--wc); mask-size : contain; mask-repeat : no-repeat; - background-size : cover; - background-color : var(--HB_Color_WatercolorStain); /*default color*/ - --wc : @watercolor1; /*default image*/ - z-index : -2; + --wc : @watercolor1; /* default image */ } - .watercolor1 { --wc : @watercolor1; } - .watercolor2 { --wc : @watercolor2; } - .watercolor3 { --wc : @watercolor3; } - .watercolor4 { --wc : @watercolor4; } - .watercolor5 { --wc : @watercolor5; } - .watercolor6 { --wc : @watercolor6; } - .watercolor7 { --wc : @watercolor7; } - .watercolor8 { --wc : @watercolor8; } - .watercolor9 { --wc : @watercolor9; } + .watercolor1 { --wc : @watercolor1; } + .watercolor2 { --wc : @watercolor2; } + .watercolor3 { --wc : @watercolor3; } + .watercolor4 { --wc : @watercolor4; } + .watercolor5 { --wc : @watercolor5; } + .watercolor6 { --wc : @watercolor6; } + .watercolor7 { --wc : @watercolor7; } + .watercolor8 { --wc : @watercolor8; } + .watercolor9 { --wc : @watercolor9; } .watercolor10 { --wc : @watercolor10; } .watercolor11 { --wc : @watercolor11; } .watercolor12 { --wc : @watercolor12; } /* Image Masks */ - [class*="imageMask"] { + [class*='imageMask'] { position : absolute; - height : 200%; - width : 200%; - left : 50%; bottom : 50%; - --rotation : 0; - --revealer : none; - --checkerboard : none; - --scaleX : 1; - --scaleY : 1; + left : 50%; + z-index : -1; + width : 200%; + height : 200%; + background-image : var(--checkerboard); + background-size : 20px; + transform : translateY(50%) translateX(-50%) rotate(calc(1deg * var(--rotation))) scaleX(var(--scaleX)) scaleY(var(--scaleY)); -webkit-mask-image : var(--wc), var(--revealer); -webkit-mask-repeat : repeat-x; -webkit-mask-size : 50%; //Scale only X to fit page width, leave height at aspect ratio, designed to hang off the edge @@ -249,61 +222,63 @@ body { mask-repeat : repeat-x; mask-size : 50%; mask-position : 50% calc(50% - var(--offset)); - background-image : var(--checkerboard); - background-size : 20px; - z-index : -1; - transform : translateY(50%) translateX(-50%) rotate(calc(1deg * var(--rotation))) scaleX(var(--scaleX)) scaleY(var(--scaleY)); + --rotation : 0; + --revealer : none; + --checkerboard : none; + --scaleX : 1; + --scaleY : 1; & > p:has(img) { position : absolute; - width : 50%; - height : 50%; bottom : 50%; left : 50%; + width : 50%; + height : 50%; transform : translateX(-50%) translateY(50%) rotate(calc(-1deg * var(--rotation))) scaleX(calc(1 / var(--scaleX))) scaleY(calc(1 / var(--scaleY))); } & img { position : absolute; - display : block; bottom : 0; + display : block; } &.bottom { --rotation : 0; - & img {bottom: 0;} + & img {bottom : 0;} } &.top { --rotation : 180; - & img {top: 0;} + & img {top : 0;} } &.left { --rotation : 90; - & img {left: 0;} + & img {left : 0;} } &.right { --rotation : -90; - & img {right: 0;} + & img {right : 0;} } &.revealImage { - --revealer : linear-gradient(0deg, rgba(0,0,0,.2) 0%, rgba(0,0,0,0.2)); - --checkerboard : url(/assets/waterColorMasks/missingImage.png); //shows any masked regions not filled by image + --revealer : linear-gradient(0deg, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0.2)); + --checkerboard : url("/assets/waterColorMasks/missingImage.png"); //shows any masked regions not filled by image } } .imageMaskEdge { - &1 { --wc : url(/assets/waterColorMasks/edge/0001.webp); } - &2 { --wc : url(/assets/waterColorMasks/edge/0002.webp); } - &3 { --wc : url(/assets/waterColorMasks/edge/0003.webp); } - &4 { --wc : url(/assets/waterColorMasks/edge/0004.webp); } - &5 { --wc : url(/assets/waterColorMasks/edge/0005.webp); } - &6 { --wc : url(/assets/waterColorMasks/edge/0006.webp); } - &7 { --wc : url(/assets/waterColorMasks/edge/0007.webp); } - &8 { --wc : url(/assets/waterColorMasks/edge/0008.webp); } + &1 { --wc : url("/assets/waterColorMasks/edge/0001.webp"); } + &2 { --wc : url("/assets/waterColorMasks/edge/0002.webp"); } + &3 { --wc : url("/assets/waterColorMasks/edge/0003.webp"); } + &4 { --wc : url("/assets/waterColorMasks/edge/0004.webp"); } + &5 { --wc : url("/assets/waterColorMasks/edge/0005.webp"); } + &6 { --wc : url("/assets/waterColorMasks/edge/0006.webp"); } + &7 { --wc : url("/assets/waterColorMasks/edge/0007.webp"); } + &8 { --wc : url("/assets/waterColorMasks/edge/0008.webp"); } } - [class*="imageMaskCenter"] { + [class*='imageMaskCenter'] { + bottom : calc(var(--offsetY)); + left : calc(var(--offsetX)); width : 100%; height : 100%; - left : calc(var(--offsetX)); - bottom : calc(var(--offsetY)); + transform : rotate(calc(1deg * var(--rotation))) scaleX(var(--scaleX)) scaleY(var(--scaleY)); -webkit-mask-image : var(--wc), var(--revealer); -webkit-mask-repeat : no-repeat; -webkit-mask-size : 100% 100%; //Scale both dimensions to fit page size @@ -312,48 +287,48 @@ body { mask-repeat : no-repeat; mask-size : 100% 100%; //Scale both dimensions to fit page size mask-position : 50% 50%; - transform : rotate(calc(1deg * var(--rotation))) scaleX(var(--scaleX)) scaleY(var(--scaleY)); & > p:has(img) { position : absolute; - width : 100%; - height : 100%; bottom : 0; left : 0; + width : 100%; + height : 100%; transform : unset; transform : scaleX(calc(1 / var(--scaleX))) scaleY(calc(1 / var(--scaleY))) - rotate(calc(-1deg * var(--rotation))) - translateX(calc(-1 * var(--offsetX))) - translateY(calc(1 * var(--offsetY))); + rotate(calc(-1deg * var(--rotation))) + translateX(calc(-1 * var(--offsetX))) + translateY(calc(1 * var(--offsetY))); } } .imageMaskCenter { - &1 { --wc : url(/assets/waterColorMasks/center/0001.webp); } - &2 { --wc : url(/assets/waterColorMasks/center/0002.webp); } - &3 { --wc : url(/assets/waterColorMasks/center/0003.webp); } - &4 { --wc : url(/assets/waterColorMasks/center/0004.webp); } - &5 { --wc : url(/assets/waterColorMasks/center/0005.webp); } - &6 { --wc : url(/assets/waterColorMasks/center/0006.webp); } - &7 { --wc : url(/assets/waterColorMasks/center/0007.webp); } - &8 { --wc : url(/assets/waterColorMasks/center/0008.webp); } - &9 { --wc : url(/assets/waterColorMasks/center/0009.webp); } - &10 { --wc : url(/assets/waterColorMasks/center/0010.webp); } - &11 { --wc : url(/assets/waterColorMasks/center/0011.webp); } - &12 { --wc : url(/assets/waterColorMasks/center/0012.webp); } - &13 { --wc : url(/assets/waterColorMasks/center/0013.webp); } - &14 { --wc : url(/assets/waterColorMasks/center/0014.webp); } - &15 { --wc : url(/assets/waterColorMasks/center/0015.webp); } - &16 { --wc : url(/assets/waterColorMasks/center/0016.webp); } - &special { --wc : url(/assets/waterColorMasks/center/special.webp); } + &1 { --wc : url("/assets/waterColorMasks/center/0001.webp"); } + &2 { --wc : url("/assets/waterColorMasks/center/0002.webp"); } + &3 { --wc : url("/assets/waterColorMasks/center/0003.webp"); } + &4 { --wc : url("/assets/waterColorMasks/center/0004.webp"); } + &5 { --wc : url("/assets/waterColorMasks/center/0005.webp"); } + &6 { --wc : url("/assets/waterColorMasks/center/0006.webp"); } + &7 { --wc : url("/assets/waterColorMasks/center/0007.webp"); } + &8 { --wc : url("/assets/waterColorMasks/center/0008.webp"); } + &9 { --wc : url("/assets/waterColorMasks/center/0009.webp"); } + &10 { --wc : url("/assets/waterColorMasks/center/0010.webp"); } + &11 { --wc : url("/assets/waterColorMasks/center/0011.webp"); } + &12 { --wc : url("/assets/waterColorMasks/center/0012.webp"); } + &13 { --wc : url("/assets/waterColorMasks/center/0013.webp"); } + &14 { --wc : url("/assets/waterColorMasks/center/0014.webp"); } + &15 { --wc : url("/assets/waterColorMasks/center/0015.webp"); } + &16 { --wc : url("/assets/waterColorMasks/center/0016.webp"); } + &special { --wc : url("/assets/waterColorMasks/center/special.webp"); } } - [class*="imageMaskCorner"] { - height : 200%; - width : 200%; - left : calc(-50% + var(--offsetX)); + [class*='imageMaskCorner'] { bottom : calc(-50% + var(--offsetY)); + left : calc(-50% + var(--offsetX)); + width : 200%; + height : 200%; + transform : rotate(calc(1deg * var(--rotation))) scaleX(var(--scaleX)) scaleY(var(--scaleY)); -webkit-mask-image : var(--wc), var(--revealer); -webkit-mask-repeat : no-repeat; -webkit-mask-size : 100% 100%; //Scale both dimensions to fit page size @@ -362,56 +337,55 @@ body { mask-repeat : no-repeat; mask-size : 100% 100%; //Scale both dimensions to fit page size mask-position : 50% 50%; - transform : rotate(calc(1deg * var(--rotation))) scaleX(var(--scaleX)) scaleY(var(--scaleY)); & > p:has(img) { + bottom : 25%; + left : 25%; width : 50%; height : 50%; //Complex transform below to handle mix of % and cm offsets - left : 25%; - bottom : 25%; transform : scaleX(calc(1 / var(--scaleX))) scaleY(calc(1 / var(--scaleY))) - rotate(calc(-1deg * var(--rotation))) - translateX(calc(-1 * var(--offsetX))) - translateY(calc(1 * var(--offsetY))); + rotate(calc(-1deg * var(--rotation))) + translateX(calc(-1 * var(--offsetX))) + translateY(calc(1 * var(--offsetY))); } } .imageMaskCorner { - &1 { --wc : url(/assets/waterColorMasks/corner/0001.webp); } - &2 { --wc : url(/assets/waterColorMasks/corner/0002.webp); } - &3 { --wc : url(/assets/waterColorMasks/corner/0003.webp); } - &4 { --wc : url(/assets/waterColorMasks/corner/0004.webp); } - &5 { --wc : url(/assets/waterColorMasks/corner/0005.webp); } - &6 { --wc : url(/assets/waterColorMasks/corner/0006.webp); } - &7 { --wc : url(/assets/waterColorMasks/corner/0007.webp); } - &8 { --wc : url(/assets/waterColorMasks/corner/0008.webp); } - &9 { --wc : url(/assets/waterColorMasks/corner/0009.webp); } - &10 { --wc : url(/assets/waterColorMasks/corner/0010.webp); } - &11 { --wc : url(/assets/waterColorMasks/corner/0011.webp); } - &12 { --wc : url(/assets/waterColorMasks/corner/0012.webp); } - &13 { --wc : url(/assets/waterColorMasks/corner/0013.webp); } - &14 { --wc : url(/assets/waterColorMasks/corner/0014.webp); } - &15 { --wc : url(/assets/waterColorMasks/corner/0015.webp); } - &16 { --wc : url(/assets/waterColorMasks/corner/0016.webp); } - &17 { --wc : url(/assets/waterColorMasks/corner/0017.webp); } - &18 { --wc : url(/assets/waterColorMasks/corner/0018.webp); } - &19 { --wc : url(/assets/waterColorMasks/corner/0019.webp); } - &20 { --wc : url(/assets/waterColorMasks/corner/0020.webp); } - &21 { --wc : url(/assets/waterColorMasks/corner/0021.webp); } - &22 { --wc : url(/assets/waterColorMasks/corner/0022.webp); } - &23 { --wc : url(/assets/waterColorMasks/corner/0023.webp); } - &24 { --wc : url(/assets/waterColorMasks/corner/0024.webp); } - &25 { --wc : url(/assets/waterColorMasks/corner/0025.webp); } - &26 { --wc : url(/assets/waterColorMasks/corner/0026.webp); } - &27 { --wc : url(/assets/waterColorMasks/corner/0027.webp); } - &28 { --wc : url(/assets/waterColorMasks/corner/0028.webp); } - &29 { --wc : url(/assets/waterColorMasks/corner/0029.webp); } - &30 { --wc : url(/assets/waterColorMasks/corner/0030.webp); } - &31 { --wc : url(/assets/waterColorMasks/corner/0031.webp); } - &32 { --wc : url(/assets/waterColorMasks/corner/0032.webp); } - &33 { --wc : url(/assets/waterColorMasks/corner/0033.webp); } - &34 { --wc : url(/assets/waterColorMasks/corner/0034.webp); } - &35 { --wc : url(/assets/waterColorMasks/corner/0035.webp); } - &36 { --wc : url(/assets/waterColorMasks/corner/0036.webp); } - &37 { --wc : url(/assets/waterColorMasks/corner/0037.webp); } + &1 { --wc : url("/assets/waterColorMasks/corner/0001.webp"); } + &2 { --wc : url("/assets/waterColorMasks/corner/0002.webp"); } + &3 { --wc : url("/assets/waterColorMasks/corner/0003.webp"); } + &4 { --wc : url("/assets/waterColorMasks/corner/0004.webp"); } + &5 { --wc : url("/assets/waterColorMasks/corner/0005.webp"); } + &6 { --wc : url("/assets/waterColorMasks/corner/0006.webp"); } + &7 { --wc : url("/assets/waterColorMasks/corner/0007.webp"); } + &8 { --wc : url("/assets/waterColorMasks/corner/0008.webp"); } + &9 { --wc : url("/assets/waterColorMasks/corner/0009.webp"); } + &10 { --wc : url("/assets/waterColorMasks/corner/0010.webp"); } + &11 { --wc : url("/assets/waterColorMasks/corner/0011.webp"); } + &12 { --wc : url("/assets/waterColorMasks/corner/0012.webp"); } + &13 { --wc : url("/assets/waterColorMasks/corner/0013.webp"); } + &14 { --wc : url("/assets/waterColorMasks/corner/0014.webp"); } + &15 { --wc : url("/assets/waterColorMasks/corner/0015.webp"); } + &16 { --wc : url("/assets/waterColorMasks/corner/0016.webp"); } + &17 { --wc : url("/assets/waterColorMasks/corner/0017.webp"); } + &18 { --wc : url("/assets/waterColorMasks/corner/0018.webp"); } + &19 { --wc : url("/assets/waterColorMasks/corner/0019.webp"); } + &20 { --wc : url("/assets/waterColorMasks/corner/0020.webp"); } + &21 { --wc : url("/assets/waterColorMasks/corner/0021.webp"); } + &22 { --wc : url("/assets/waterColorMasks/corner/0022.webp"); } + &23 { --wc : url("/assets/waterColorMasks/corner/0023.webp"); } + &24 { --wc : url("/assets/waterColorMasks/corner/0024.webp"); } + &25 { --wc : url("/assets/waterColorMasks/corner/0025.webp"); } + &26 { --wc : url("/assets/waterColorMasks/corner/0026.webp"); } + &27 { --wc : url("/assets/waterColorMasks/corner/0027.webp"); } + &28 { --wc : url("/assets/waterColorMasks/corner/0028.webp"); } + &29 { --wc : url("/assets/waterColorMasks/corner/0029.webp"); } + &30 { --wc : url("/assets/waterColorMasks/corner/0030.webp"); } + &31 { --wc : url("/assets/waterColorMasks/corner/0031.webp"); } + &32 { --wc : url("/assets/waterColorMasks/corner/0032.webp"); } + &33 { --wc : url("/assets/waterColorMasks/corner/0033.webp"); } + &34 { --wc : url("/assets/waterColorMasks/corner/0034.webp"); } + &35 { --wc : url("/assets/waterColorMasks/corner/0035.webp"); } + &36 { --wc : url("/assets/waterColorMasks/corner/0036.webp"); } + &37 { --wc : url("/assets/waterColorMasks/corner/0037.webp"); } } } @@ -423,16 +397,16 @@ body { padding-left : 1em; white-space : pre-line; } - dt { - display : inline; - margin-right : 0.5ch; + dt { + display : inline; + margin-right : 0.5ch; margin-left : -1em; - } - dd { + } + dd { display : inline; margin-left : 0; text-indent : 0; - } + } } //***************************** @@ -442,9 +416,7 @@ body { .blank { height : 1em; margin-top : 0; - & + * { - margin-top : 0; - } + & + * { margin-top : 0; } } } @@ -452,12 +424,39 @@ body { // * WIDE // *****************************/ .page { - .wide{ + .wide { column-span : all; display : block; margin-bottom : 1em; - &+* { - margin-top : 0; - } + & + * { margin-top : 0; } } } + +//***************************** +//* CREDITS +//*****************************/ +.page .homebreweryCredits { + p { + font-family : 'NodestoCapsWide'; + font-size : 0.4cm; + line-height : 1em; + text-align : center; + text-indent : 0; + letter-spacing : 0.08em; + } + a { + color : inherit; + text-decoration : none; + &:hover { text-decoration : underline; } + } + .homebreweryIcon { + display : block; + height : 1.5cm; + margin : 0 auto; + background-color : black; + -webkit-mask : url("/assets/naturalCritLogoWhite.svg") center / contain no-repeat; + mask : url("/assets/naturalCritLogoWhite.svg") center / contain no-repeat; + } + .homebreweryIcon.red { background-color : red; } + .homebreweryIcon.gold { background-image : linear-gradient(to top left, brown 22.5%, gold 40%, white 60%, gold 67.5%, brown 82.5%); } +}