Dice rollers!
All checks were successful
Build and Deploy Nuxt / build (push) Successful in 58s

This commit is contained in:
2026-05-02 23:37:17 +02:00
parent b7ad2dc406
commit 030060286f
6 changed files with 221 additions and 29 deletions

View File

@@ -1,20 +1,26 @@
import { Marked } from "marked";
const widget_map = {
test: () => import("~/components/viewer/widgets/TestWidget.vue"),
table: () => import("~/components/viewer/widgets/TableWidget.vue"),
roll: () => import("~/components/viewer/widgets/RollWidget.vue"),
inline: {
roll: () => import("~/components/viewer/widgets/inline/RollWidgetInline.vue"),
},
display: {
roll: () => import("~/components/viewer/widgets/display/RollWidgetDisplay.vue"),
}
};
const componentCache = {}
const componentCache = {
inline: {},
display: {}
}
const GetWidget = (type) => {
if (!componentCache[type]) {
componentCache[type] = defineAsyncComponent(
widget_map[type]
const GetWidget = (type, name) => {
if (!componentCache[type][name]) {
componentCache[type][name] = defineAsyncComponent(
widget_map[type][name]
)
}
return componentCache[type]
return componentCache[type][name]
}
@@ -39,7 +45,7 @@ const extension = {
},
renderer(token) {
return `<div class="vue-component" data-component="${token.name}" data-content="${token.text}"></div>`;
return `<div class="vue-component-display" data-component="${token.name}" data-content="${token.text}"></div>`;
},
};
@@ -64,7 +70,7 @@ const inlineExtension = {
},
renderer(token) {
return `<span class="vue-component" data-component="${token.name}" data-content="${token.text}"></span>`;
return `<span class="vue-component-inline" data-component="${token.name}" data-content="${token.text}"></span>`;
},
};

View File

@@ -1,4 +1,4 @@
// dice-parser.js
// DiceParser.js
function roll(sides) {
return Math.floor(Math.random() * sides) + 1;
@@ -27,10 +27,9 @@ export function parse(expr) {
const tokens = tokenize(expr);
if (!tokens.length) throw new Error('Empty expression');
let pos = 0;
const rolls = [];
function peek() { return tokens[pos]; }
function consume() { return tokens[pos++]; }
const peek = () => tokens[pos];
const consume = () => tokens[pos++];
function parseExpr() { return parseAddSub(); }
@@ -41,7 +40,7 @@ export function parse(expr) {
const right = parseMulDiv();
left = {
value: op === '+' ? left.value + right.value : left.value - right.value,
rolls: [...left.rolls, ...right.rolls],
steps: [...left.steps, { type: 'op', op }, ...right.steps],
};
}
return left;
@@ -55,7 +54,7 @@ export function parse(expr) {
if (op === '/' && right.value === 0) throw new Error('Division by zero');
left = {
value: op === '*' ? left.value * right.value : Math.floor(left.value / right.value),
rolls: [...left.rolls, ...right.rolls],
steps: [...left.steps, { type: 'op', op }, ...right.steps],
};
}
return left;
@@ -65,7 +64,7 @@ export function parse(expr) {
if (peek() === '-') {
consume();
const r = parsePrimary();
return { value: -r.value, rolls: r.rolls };
return { value: -r.value, steps: [{ type: 'op', op: '-' }, ...r.steps] };
}
return parsePrimary();
}
@@ -79,7 +78,10 @@ export function parse(expr) {
const inner = parseExpr();
if (peek() !== ')') throw new Error('Missing closing )');
consume();
return inner;
return {
value: inner.value,
steps: [{ type: 'op', op: '(' }, ...inner.steps, { type: 'op', op: ')' }],
};
}
const diceInfo = parseDiceToken(tok);
@@ -90,7 +92,8 @@ export function parse(expr) {
if (/^\d+$/.test(tok)) {
consume();
return { value: parseInt(tok), rolls: [] };
const v = parseInt(tok);
return { value: v, steps: [{ type: 'const', value: v }] };
}
throw new Error(`Unexpected token: ${tok}`);
@@ -119,12 +122,13 @@ export function parse(expr) {
}
const entry = { sides, rawRolls, kept, mod, value: kept.reduce((a, b) => a + b, 0) };
rolls.push(entry);
return { value: entry.value, rolls: [entry] };
return {
value: entry.value,
steps: [{ type: 'dice', entry }],
};
}
const result = parseExpr();
if (pos < tokens.length) throw new Error(`Unexpected token: ${tokens[pos]}`);
return { total: result.value, rolls: result.rolls };
return { total: result.value, steps: result.steps };
}