Fork FancyScribe as BrevyScribe with the datasheet transforms built in
CI / check (push) Has been cancelled
CI / check (push) Has been cancelled
Print generic datasheets - every option a unit could take, the way the official cards read - instead of a record of one particular list. The three Python scripts that used to rewrite the .ros file before upload are now transforms in src/transforms/, running in the browser between DOMParser and the roster parser. Most of each script was machinery for preserving the file byte for byte on the way back to disk; in the browser the document is never serialised, so only the domain logic came across. Because they run on the parsed document rather than the uploaded file, flipping a transform off rebuilds from the original XML with no re-upload. Saved rosters therefore hold the raw roster XML rather than the parsed object, under new localStorage keys. The scripts' output over four 11th-edition rosters is checked in as test fixtures, so the port is measured against an independent implementation that was verified by printing the cards; scripts/update-fixtures.mjs refuses to overwrite those without --force. Two parser call sites now use :scope> rather than repeating the scope element's own name, which means the same thing in a browser and also works under jsdom, where the old form matched nothing. Also: served at the root rather than a GitHub Pages subpath, PostHog analytics removed, and deploy/ carries an nginx site for scribe.luxick.de plus an rsync deploy script. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
// Defaults for the roster transforms. These started life as module constants
|
||||
// in the Python scripts this was ported from; the values are the same, but the app
|
||||
// passes them in so they can be edited without touching the transform code.
|
||||
|
||||
export const defaultConfig = {
|
||||
// --- mergeDuplicateUnits -------------------------------------------------
|
||||
|
||||
// Two force-level selections are the same unit when all of these attributes
|
||||
// agree. ``entryId`` identifies the catalogue entry plus the option path
|
||||
// that produced it, so it is the real key; ``name`` and ``type`` are there
|
||||
// so a unit the user renamed by hand stays a unit of its own.
|
||||
unitMatchAttrs: ["entryId", "name", "type"],
|
||||
|
||||
// Selections carrying one of these categories are roster bookkeeping
|
||||
// (battle size, detachment, ...), not datasheets. Leave them alone.
|
||||
skipCategories: ["Configuration"],
|
||||
|
||||
// --- removeLeaderAbilities ----------------------------------------------
|
||||
|
||||
// Abilities to strip, matched against the ``name`` attribute (exactly,
|
||||
// case-sensitively). Both the Abilities profile and the same-named rule go.
|
||||
abilitiesToStrip: ["Leader", "Support"],
|
||||
|
||||
// --- convertChoiceAbilities ---------------------------------------------
|
||||
|
||||
// Abilities to split into per-option profiles, matched against the
|
||||
// profile's ``name`` attribute.
|
||||
abilitiesToConvert: ["Canticles of the Omnissiah", "Battle Protocols"],
|
||||
|
||||
// Title of the generated profile group, per ability. Anything not listed
|
||||
// here uses the ability's own name, which is what the datasheets do.
|
||||
groupTitleOverrides: {
|
||||
"Canticles of the Omnissiah": "CANTICLES OF THE OMNISSIAH",
|
||||
"Battle Protocols": "BATTLE PROTOCOLS",
|
||||
},
|
||||
};
|
||||
|
||||
// Which transforms run by default when a roster is loaded.
|
||||
export const defaultToggles = {
|
||||
mergeDuplicateUnits: true,
|
||||
removeLeaderAbilities: true,
|
||||
convertChoiceAbilities: true,
|
||||
};
|
||||
|
||||
// typeName BattleScribe files datasheet abilities under. Only profiles of
|
||||
// this type are matched, so a *weapon* that happened to be called "Support"
|
||||
// stays, and a rule that happens to share an ability's name is still removed
|
||||
// deliberately (the strip wants both halves).
|
||||
export const ABILITY_TYPE_NAME = "Abilities";
|
||||
|
||||
// Name of the characteristic holding the rules text.
|
||||
export const DESCRIPTION_CHARACTERISTIC = "Description";
|
||||
|
||||
// Child elements of a <selection> that get merged, in the order BattleScribe
|
||||
// writes them. The order only matters when a container is missing from the
|
||||
// unit we keep and has to be created.
|
||||
export const CONTAINER_ORDER = [
|
||||
"rules",
|
||||
"profiles",
|
||||
"selections",
|
||||
"costs",
|
||||
"categories",
|
||||
];
|
||||
|
||||
// Containers that are removed once a strip empties them. A container that was
|
||||
// *already* empty is left as it was.
|
||||
export const PRUNABLE_CONTAINERS = ["profiles", "rules"];
|
||||
Reference in New Issue
Block a user