Files
5etools-mirror-2.github.io/js/converter-background.js
TheGiddyLimit 8117ebddc5 v1.198.1
2024-01-01 19:34:49 +00:00

131 lines
4.4 KiB
JavaScript

"use strict";
class _ParseStateTextBackground extends BaseParseStateText {
}
class BackgroundParser extends BaseParserFeature {
/**
* Parses backgrounds from raw text pastes
* @param inText Input text.
* @param options Options object.
* @param options.cbWarning Warning callback.
* @param options.cbOutput Output callback.
* @param options.isAppend Default output append mode.
* @param options.source Entity source.
* @param options.page Entity page.
* @param options.titleCaseFields Array of fields to be title-cased in this entity (if enabled).
* @param options.isTitleCase Whether title-case fields should be title-cased in this entity.
*/
static doParseText (inText, options) {
options = this._getValidOptions(options);
const {toConvert, entity: background} = this._doParse_getInitialState(inText, options);
if (!toConvert) return;
const state = new _ParseStateTextBackground({toConvert, options, entity: background});
state.doPreLoop();
for (; state.ixToConvert < toConvert.length; ++state.ixToConvert) {
state.initCurLine();
if (state.isSkippableCurLine()) continue;
switch (state.stage) {
case "name": this._doParseText_stepName(state); state.stage = "entries"; break;
case "entries": this._doParseText_stepEntries(state); break;
default: throw new Error(`Unknown stage "${state.stage}"`);
}
}
state.doPostLoop();
if (!background.entries?.length) delete background.entries;
const entityOut = this._getFinalEntity(state, options);
options.cbOutput(entityOut, options.isAppend);
}
static _doParseText_stepName (state) {
const name = state.curLine.replace(/ Traits$/i, "");
state.entity.name = this._getAsTitle("name", name, state.options.titleCaseFields, state.options.isTitleCase);
}
static _doParseText_stepEntries (state) {
const ptrI = {_: state.ixToConvert};
state.entity.entries = EntryConvert.coalesceLines(
ptrI,
state.toConvert,
);
state.ixToConvert = ptrI._;
}
// SHARED UTILITY FUNCTIONS ////////////////////////////////////////////////////////////////////////////////////////
static _getFinalEntity (state, options) {
this._doBackgroundPostProcess(state, options);
return PropOrder.getOrdered(state.entity, state.entity.__prop || "background");
}
static _doBackgroundPostProcess (state, options) {
if (!state.entity.entries) return;
// region Tag
EntryConvert.tryRun(state.entity, "entries");
TagJsons.mutTagObject(state.entity, {keySet: new Set(["entries"]), isOptimistic: false});
// endregion
// region Background-specific cleanup and generation
this._doPostProcess_setPrerequisites(state, options);
this._doBackgroundPostProcess_feature(state.entity, options);
BackgroundSkillTollLanguageEquipmentCoalesce.tryRun(state.entity, {cbWarning: options.cbWarning});
BackgroundSkillToolLanguageTag.tryRun(state.entity, {cbWarning: options.cbWarning});
this._doBackgroundPostProcess_equipment(state.entity, options);
EquipmentBreakdown.tryRun(state.entity, {cbWarning: options.cbWarning});
this._doBackgroundPostProcess_tables(state.entity, options);
// endregion
}
static _doBackgroundPostProcess_feature (background, options) {
const entFeature = background.entries.find(ent => ent.name?.startsWith("Feature: "));
if (!entFeature) return;
(entFeature.data ||= {}).isFeature = true;
const walker = MiscUtil.getWalker({isNoModification: true});
walker.walk(
entFeature.entries,
{
string: (str) => {
str.replace(/{@feat (?<tagContents>[^}]+)}/g, (...m) => {
const {name, source} = DataUtil.proxy.unpackUid("feat", m.at(-1).tagContents, "feat", {isLower: true});
(background.feats ||= []).push({[`${name}|${source}`]: true});
(background.fromFeature ||= {}).feats = true;
});
},
},
);
}
static _doBackgroundPostProcess_equipment (background, options) {
const entryEquipment = UtilBackgroundParser.getEquipmentEntry(background);
if (!entryEquipment) return;
entryEquipment.entry = ItemTag.tryRunBasicEquipment(entryEquipment.entry);
}
static _doBackgroundPostProcess_tables (background, options) {
for (let i = 1; i < background.entries.length; ++i) {
const entPrev = background.entries[i - 1];
if (!entPrev.entries?.length) continue;
const ent = background.entries[i];
if (ent.type !== "table") continue;
entPrev.entries.push(ent);
background.entries.splice(i--, 1);
}
}
}
globalThis.BackgroundParser = BackgroundParser;