mirror of
https://github.com/Kornstalx/5etools-mirror-2.github.io.git
synced 2025-10-28 20:45:35 -05:00
131 lines
4.4 KiB
JavaScript
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;
|