diff --git a/esbuild.config.mjs b/esbuild.config.mjs index 8133966..78ba102 100644 --- a/esbuild.config.mjs +++ b/esbuild.config.mjs @@ -4,6 +4,20 @@ (https://github.com/jdanielmourao/obsidian-sanctum) Further based on https://github.com/damiankorcz/Prism-Theme/blob/main/esbuild.config.mjs Updated to Esbuild 17 by @Sigrunixia + + Usage: + + Dev build + $ node esbuild.config.mjs + + Prod build + $ node esbuild.config.mjs production + + Dev build for one system only (pf2e or bnb): + $ node esbuild.config.mjs + + Dev build for one system only (pf2e or bnb), output to outfile: + $ node esbuild.config.mjs */ import * as esbuild from "esbuild"; @@ -13,50 +27,38 @@ import time from 'esbuild-plugin-time'; config(); -const prod = process.argv[2] === "production"; const dir = "./"; -/** Paths for final file */ -/** PF2E */ -const pf2efileProd = `${dir}/Basic-Pathfinder-2e-Layout.css`; -const pf2efileDev = `${dir}/Basic-Pathfinder-2e-Layout-DEV.css`; +const isProd = process.argv[2] === "production"; +// The systems that will be built. By default and in prod, build all. The values here correspond to the +// keys of the systemConfig object below. +const systems = (isProd || !process.argv[2]) ? ["pf2e", "bnb"] : [process.argv[2]]; +// The output file. Ignored in production. +const devFile = process.argv[3]; -const buildPF2E = async () => { - const context = await esbuild.build({ - /** Entry point should be where everything is imported into. */ +// The specific system config set here will overwrite the default config entries +// set below. +const systemConfig = { + // PF2E + pf2e: { + // Entry point should be where everything is imported into. entryPoints: ["pf2e-index.scss"], - logLevel: "info", - outfile: prod ? pf2efileProd : pf2efileDev, - // minify: true, - plugins: [ - sassPlugin({ - cache: true, - charset: false, - alertColor: true, - alertAscii: true, - }), - time() - ] - }); - - // Enable watch mode - if (!prod) { - await context.rebuild(); - await context.watch(); + // Path for final file + outfile: isProd ? `${dir}/Basic-Pathfinder-2e-Layout.css` : (devFile || `${dir}/Basic-Pathfinder-2e-Layout-DEV.css`), + }, + // BNB Bestiary + bnb: { + minify: true, + // Entry point should be where everything is imported into. + entryPoints: ["bnb-index.scss"], + // Path for final file + outfile: isProd ? `${dir}/BnB-Layout.css` : (devFile || `${dir}/BnB-Layout-DEV.css`), } -}; - -/** BNB Bestiary */ -const bnbfileProd = `${dir}/BnB-Layout.css`; -const bnbfileDev = `${dir}/BnB-Layout-DEV.css`; +} -const buildBNB = async () => { - const context = await esbuild.build({ - /** Entry point should be where everything is imported into. */ - entryPoints: ["bnb-index.scss"], +async function build(systemConfig) { + const config = { logLevel: "info", - outfile: prod ? bnbfileProd : bnbfileDev, - minify: true, plugins: [ sassPlugin({ cache: true, @@ -65,16 +67,20 @@ const buildBNB = async () => { alertAscii: true, }), time() - ] - }); + ], + ...systemConfig + }; - // Enable watch mode - if (!prod) { + if (isProd) { + await esbuild.build(config); + } else { + const context = await esbuild.context(config) await context.rebuild(); await context.watch(); } -}; +} -// Call the build functions -buildPF2E().catch(() => process.exit(1)); -buildBNB().catch(() => process.exit(1)); +// Build the files +for (var system of systems) { + build(systemConfig[system]).catch(() => process.exit(1)) +} \ No newline at end of file diff --git a/package.json b/package.json index 549fdc3..48ce8e7 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,8 @@ "version": "1.5.0", "scripts": { "dev": "node ./esbuild.config.mjs", + "dev-pf2e": "node ./esbuild.config.mjs pf2e", + "dev-bnb": "node ./esbuild.config.mjs bnb", "build": "node ./esbuild.config.mjs production" }, "devDependencies": { diff --git a/pf2e/components/_statblock-types.scss b/pf2e/components/_statblock-types.scss index fcce58c..9c1b494 100644 --- a/pf2e/components/_statblock-types.scss +++ b/pf2e/components/_statblock-types.scss @@ -1,5 +1,6 @@ $names: ( "basic-pathfinder-2e-layout", + "experimental-pathfinder-2e-layout", "pathfinder-2e-action-layout", "pathfinder-2e-hazard-layout", "pathfinder-2e-influence-layout", diff --git a/pf2e/components/font-styling.scss b/pf2e/components/font-styling.scss index 96921bf..9e36dc3 100644 --- a/pf2e/components/font-styling.scss +++ b/pf2e/components/font-styling.scss @@ -14,12 +14,17 @@ $statblock-ul-margin: 0 0.5em; @each $block_name in statblocks.$names { .statblock.#{$block_name} { + a, a:-webkit-any-link, a.internal-link { color: $statblock-font-color-blue; - font-weight: var(--statblock-property-name-font-weight); - text-decoration: none; + @if $block_name != "experimental-pathfinder-2e-layout" { + font-weight: var(--statblock-property-name-font-weight); + text-decoration: none; + } @else { + text-decoration: underline; + } } b, @@ -33,8 +38,12 @@ $statblock-ul-margin: 0 0.5em; em, .cm-em { font-style: italic; - color: $statblock-font-color-purple; - font-weight: 500; + + /* Don't override the weight and color for italics within the statblock name */ + :not(.property-name) & { + color: $statblock-font-color-purple; + font-weight: 500; + } } ul { diff --git a/pf2e/components/property-and-line.scss b/pf2e/components/property-and-line.scss index 7cefb76..b1407f9 100644 --- a/pf2e/components/property-and-line.scss +++ b/pf2e/components/property-and-line.scss @@ -23,5 +23,15 @@ .property { line-height: var(--statblock-property-line-height); } + + // Override the em color and weight set in font-styling + .property-name strong > em { + color: var(--active-traits-name-font-color); + font-weight: var(--statblock-traits-name-font-weight); + } } } + +.statblock.experimental-pathfinder-2e-layout .property-name { + margin-right: 0; +} diff --git a/pf2e/components/statblock-content.scss b/pf2e/components/statblock-content.scss index 5f71843..4bd1b8e 100644 --- a/pf2e/components/statblock-content.scss +++ b/pf2e/components/statblock-content.scss @@ -25,6 +25,47 @@ $statblock-content-margin: 0.5em 2px; padding: $statblock-content-padding; gap: 1rem; + // Experimental Layout Specific + @if $block_name == "experimental-pathfinder-2e-layout" { + .statblock-item-container.statblock-trait-prop .property.attacks > .property-name { + font-weight: normal; + font-style: normal; + } + + // Style .oneline containers to show all props inline separated by semicolons. + .inline-container.oneline { + display: block; + + *:not(.dice-roller) { + display: inline; + } + + & > .statblock-inline-item:not(:first-child) .property-name { + margin-right: 0; + &::before { + content: "; "; + font-weight: normal; + } + } + } + + // These containers denote that all props except the first are just notes and + // should be displayed inline, but shouldn't have property names + .inline-container.withnote { + * { + display: inline; + } + + & > .statblock-inline-item:not(:first-child) .property-name { + display: none; + } + } + + // Make callouts within statblocks visible. + .callout { + mix-blend-mode: normal; + } + } .statblock-detached { position: absolute; @@ -92,24 +133,26 @@ $statblock-content-margin: 0.5em 2px; margin-top: 0; } - & > .statblock-item-inline:has(.rare_01, - .rare_02, - .rare_03, - .rare_04, - .alignment, - .size, - .xp, - .kingdom_xp, - .trait_01, - .trait_02, - .trait_03, - .trait_04, - .trait_05, - .trait_06, - .trait_07) { - row-gap: var(--statblock-traits-gap); - - margin-bottom: $statblock-content-container-spacing * 2; + @if $block_name != "experimental-pathfinder-2e-layout" { + & > .statblock-item-inline:has(.rare_01, + .rare_02, + .rare_03, + .rare_04, + .alignment, + .size, + .xp, + .kingdom_xp, + .trait_01, + .trait_02, + .trait_03, + .trait_04, + .trait_05, + .trait_06, + .trait_07) { + row-gap: var(--statblock-traits-gap); + + margin-bottom: $statblock-content-container-spacing * 2; + } } /* Hazard Block Specific */ diff --git a/pf2e/components/traits.scss b/pf2e/components/traits.scss index 6340169..cd81792 100644 --- a/pf2e/components/traits.scss +++ b/pf2e/components/traits.scss @@ -9,7 +9,6 @@ $statblock-trait-text-color: rgb(255, 255, 255); $statblock-trait-font-weight: 900; $statblock-trait-font-style: normal; - @each $block_name in statblocks.$names { .statblock.#{$block_name} { @@ -20,75 +19,157 @@ $statblock-trait-font-style: normal; font-style: $statblock-trait-font-style !important; } + @if $block_name != "experimental-pathfinder-2e-layout" { + .rare_01 { + background-color: var(--statblock-color-common) !important; + /* common */ + } - .rare_01 { - background-color: var(--statblock-color-common) !important; - /* common */ - } + .rare_02 { + background-color: var(--statblock-color-uncommon) !important; + /* uncommon */ + } - .rare_02 { - background-color: var(--statblock-color-uncommon) !important; - /* uncommon */ - } + .rare_03 { + background-color: var(--statblock-color-rare) !important; + /* rare */ + } - .rare_03 { - background-color: var(--statblock-color-rare) !important; - /* rare */ - } + .rare_04 { + background-color: var(--statblock-color-unique) !important; + /* unique */ + } - .rare_04 { - background-color: var(--statblock-color-unique) !important; - /* unique */ - } + .alignment { + background-color: var(--statblock-color-alignment) !important; + } - .alignment { - background-color: var(--statblock-color-alignment) !important; - } + .size { + background-color: var(--statblock-color-size) !important; + } - .size { - background-color: var(--statblock-color-size) !important; - } - .xp, - .kingdom_xp, - .trait_01, - .trait_02, - .trait_03, - .trait_04, - .trait_05, - .trait_06, - .trait_07 { - background-color: var(--statblock-color-trait) !important; - } + .xp, + .kingdom_xp, + .trait_01, + .trait_02, + .trait_03, + .trait_04, + .trait_05, + .trait_06, + .trait_07 { + background-color: var(--statblock-color-trait) !important; + } - .rare_01, - .rare_02, - .rare_03, - .rare_04, - .alignment, - .size, - .xp, - .kingdom_xp, - .trait_01, - .trait_02, - .trait_03, - .trait_04, - .trait_05, - .trait_06, - .trait_07 { - color: $statblock-trait-text-color !important; - font-size: 12px; - font-style: $statblock-trait-font-style !important; - font-weight: $statblock-trait-font-weight !important; - letter-spacing: 0.01em; - min-width: 4em; - margin: 0 var(--statblock-traits-gap) 0 0; - padding: 0.4em 1.1em 0.2em; - text-align: center; - text-transform: uppercase; - - span.property-name { - display: none; + .rare_01, + .rare_02, + .rare_03, + .rare_04, + .alignment, + .size, + .xp, + .kingdom_xp, + .trait_01, + .trait_02, + .trait_03, + .trait_04, + .trait_05, + .trait_06, + .trait_07 { + color: $statblock-trait-text-color !important; + font-size: 12px; + font-style: $statblock-trait-font-style !important; + font-weight: $statblock-trait-font-weight !important; + letter-spacing: 0.01em; + min-width: 4em; + margin: 0 var(--statblock-traits-gap) 0 0; + padding: 0.4em 1.1em 0.2em; + text-align: center; + text-transform: uppercase; + + span.property-name { + display: none; + } + } + } @else { + // Over-specifying here to win the selector war with some of the generic property styling + .pf2e-traits.statblock-item-container.property-container { + + margin: 0; + + > .line.traits { + margin: 0; + display: block; + + } + + .property-name { + display: none; + } + + ul { + row-gap: var(--statblock-traits-gap); + display: flex; + flex-flow: row wrap; + place-content: start; + justify-content: flex-start; + padding: 0; + margin: 0; + list-style: none; + } + + + li { + display: block; + background-color: var(--statblock-color-trait); + margin: 0 var(--statblock-traits-gap) 0 0; + color: $statblock-trait-text-color !important; + font-size: 12px; + font-style: $statblock-trait-font-style !important; + font-weight: $statblock-trait-font-weight !important; + letter-spacing: 0.01em; + min-width: 4em; + text-align: center; + text-transform: uppercase; + padding: 0; + + &:not(:has(> .alignment, > .rarity, > .size)), + & > span:is(.alignment, .rarity, .size) { + padding: 0.4em 1.1em 0.2em; + line-height: var(--statblock-property-line-height); + } + + & > span:is(.alignment, .rarity, .size) { + width: 100%; + height: 100%; + display: block; + } + + // Remove bullets added by themes + &::before { + display: none; + } + + // Some sensible default styling to preserve the trait appearance + strong, i, em, b { + color: $statblock-trait-text-color; + } + + a, + a:-webkit-any-link, + a.internal-link { + color: $statblock-trait-text-color; + text-decoration: none; + text-transform: uppercase; + font-style: normal; + } + } + + @each $trait in (common uncommon rare unique alignment size) { + li > .#{$trait} { + background-color: var(--statblock-color-#{$trait}); + } + } } } } diff --git a/pf2e/layouts/Experimental Pathfinder 2e Layout.json b/pf2e/layouts/Experimental Pathfinder 2e Layout.json new file mode 100644 index 0000000..2e07933 --- /dev/null +++ b/pf2e/layouts/Experimental Pathfinder 2e Layout.json @@ -0,0 +1 @@ +{"blocks":[{"type":"inline","id":"e9b8483aeafa","properties":[],"nested":[{"type":"property","id":"2b596a6919fb","properties":["name"],"fallback":"-","markdown":true,"dice":false,"conditioned":true,"display":" "},{"type":"inline","id":"499aea6a9aca","properties":[],"nested":[{"type":"action","id":"8a6a7a499b78","icon":"sword","callback":"try { InitiativeTracker.newEncounter({roll: true, creatures: [monster]}); } catch(e) {}"},{"type":"action","id":"fbea380b09b9","icon":"plus-with-circle","callback":"try { InitiativeTracker.addCreatures([monster]); } catch(e) {}"}]},{"type":"property","id":"98389a48f808","properties":["level"],"fallback":"-","display":" ","conditioned":true,"markdown":true,"dice":false}],"hasRule":true},{"type":"group","id":"4b3a6809a938","properties":[],"nested":[{"type":"property","id":"0979a989583a","properties":["traits"],"fallback":"-","callback":"if (!monster.traits) return \"\";\nvar s = \"\"\nif (monster.rarity) {\n s += `- ${monster.rarity}\\n`\n}\nif (monster.alignment) {\n s += `- ${monster.alignment}\\n`\n}\nif (monster.size) {\n s += `- ${monster.size}\\n`\n}\nfor (const text of monster.traits) {\n s += `- ${text}\\n`\n}\nreturn s;","conditioned":true,"display":""}],"hasRule":true,"cls":"pf2e-traits"},{"type":"group","id":"5999ea79ca3b","properties":[],"nested":[{"type":"inline","id":"881859197838","properties":[],"nested":[{"type":"property","id":"4ad9f92ab8f8","properties":["modifier"],"fallback":"-","display":"Perception","conditioned":false,"dice":false,"diceCallback":"return [\"+\" + property, \" (\", { text: \"1d20+\" + property }, \")\"]"},{"type":"property","id":"8bd82998dadb","properties":["senses"],"fallback":"-","conditioned":true,"display":""}],"cls":"oneline","conditioned":true},{"type":"property","id":"ba28f9384918","properties":["languages"],"fallback":"-","display":"Language","conditioned":true,"markdown":true},{"type":"inline","id":"db1a38ebcb6b","properties":[],"nested":[{"type":"saves","id":"6a2b78099b0b","properties":["skills"],"fallback":"-","display":"Skills","conditioned":true,"dice":true},{"type":"property","id":"2b987aead8ab","properties":["skillsNote"],"fallback":"-","conditioned":true,"display":""}],"heading":"","cls":"oneline","conditioned":true},{"type":"table","id":"b82b0a1a9969","properties":["abilityMods"],"headers":["Str","Dex","Con","Int","Wis","Cha"],"calculate":false,"fallback":"-","conditioned":true,"dice":false},{"type":"property","id":"1b6a98ba4888","properties":["items"],"fallback":"-","display":"Items","conditioned":true},{"type":"traits","id":"e96ba9d8a80a","properties":["abilities_top"],"fallback":"-","conditioned":true,"dice":true,"markdown":true,"heading":" ","hasRule":false}],"hasRule":true},{"type":"group","id":"faaa08993a98","properties":[],"nested":[{"type":"inline","id":"3a5ab84a2b89","properties":[],"nested":[{"type":"inline","id":"cb6a7809aa2b","properties":[],"nested":[{"type":"property","id":"6b0b0bda0a7a","properties":["ac"],"fallback":"-","display":"AC"},{"type":"property","id":"0908aaab3b1b","properties":["acNote"],"fallback":"-","conditioned":true,"display":""}],"cls":"withnote","conditioned":true},{"type":"saves","id":"9999386a58ea","properties":["saves"],"fallback":"-","dice":true,"display":"","conditioned":true},{"type":"property","id":"69aa5a7b196a","properties":["savesNote"],"fallback":"-","display":"","conditioned":true}],"cls":"oneline","conditioned":true},{"type":"inline","id":"ea29d9ea5aa8","properties":[],"nested":[{"type":"inline","id":"39584be95ae9","properties":[],"nested":[{"type":"property","id":"bb6989092939","properties":["hp"],"fallback":"-","display":"HP"},{"type":"property","id":"b9fa1a89c8d9","properties":["hpNote"],"fallback":"-","doNotAddClass":false,"conditioned":true,"display":""}],"cls":"withnote","conditioned":true},{"type":"property","id":"4bbaa9380a9b","properties":["hardness"],"fallback":"-","display":"Hardness","conditioned":true},{"type":"property","id":"0a8ac8d96bba","properties":["immunities"],"fallback":"-","conditioned":true,"display":"Immunities"},{"type":"property","id":"8b7a3b89fa59","properties":["resistances"],"fallback":"-","conditioned":true,"display":"Resistances"},{"type":"property","id":"78689b6b6b79","properties":["weaknesses"],"fallback":"-","conditioned":true,"display":"Weaknesses"}],"cls":"oneline","conditioned":true},{"type":"traits","id":"ca2bf968987b","properties":["abilities_mid"],"fallback":"-","heading":"","conditioned":true,"dice":true,"markdown":true,"hasRule":false}],"hasRule":true},{"type":"group","id":"cbeabaf93b58","properties":[],"nested":[{"type":"property","id":"0b4809ba0b29","properties":["speed"],"fallback":"-","display":"Speed","conditioned":true,"markdown":true,"dice":false},{"type":"traits","id":"882bc9aa0898","properties":["attacks"],"fallback":"-","conditioned":true,"dice":true,"markdown":true,"headingProp":false,"heading":"","callback":"var s = property.bonus < 0 ? \"-\" : \"+\";\ns += Math.abs(property.bonus);\nif (property.desc) {\n s += \" \" + property.desc\n}\nif (property.damage) {\n s += \", __Damage__ \" + property.damage\n}\nreturn s"},{"type":"traits","id":"faeafb7b6b1b","properties":["spellcasting"],"fallback":"-","conditioned":true,"dice":true},{"type":"traits","id":"aacb399a3b58","properties":["abilities_bot"],"fallback":"-","conditioned":true,"dice":true,"markdown":true,"hasRule":false}],"hasRule":true},{"type":"text","id":"1b195a894b58","properties":["token"],"text":null,"fallback":"","heading":"Show to Players","conditioned":true,"markdown":true},{"type":"image","id":"1bba89582b29","properties":["token"],"fallback":"","conditioned":true,"hasRule":true},{"type":"property","id":"88e97a485b79","properties":["sourcebook"],"fallback":"-","conditioned":true,"markdown":true,"dice":false,"display":" Source:"}],"name":"Experimental Pathfinder 2e Layout","id":"b8ab3ae89a0a","diceParsing":[{"regex":"(\\s|^)(\\d+d\\d+(?:\\s*[+-]\\s*\\d+)?)(\\W|$)","parser":"const [, before, text, after] = matches;\nreturn [before + text, \" (\", { text }, \")\", after];","id":"4a79397b896a","desc":"1d6+10"},{"regex":"(^|\\s)([+-]\\d+)(\\W|$)(?!status|bonus)","parser":"let [, before, bonus, after] = matches;\nreturn [\n before + bonus,\n \" (\", { text: \"1d20\" + bonus }, \")\",\n after\n];","id":"8bb8fbbb0869","desc":"+15"}]} \ No newline at end of file