mirror of
https://github.com/Kornstalx/5etools-mirror-2.github.io.git
synced 2025-10-28 20:45:35 -05:00
v1.198.1
This commit is contained in:
130
js/converter-background.js
Normal file
130
js/converter-background.js
Normal file
@@ -0,0 +1,130 @@
|
||||
"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;
|
||||
Reference in New Issue
Block a user