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:
323
js/utils-generate-tables-data.js
Normal file
323
js/utils-generate-tables-data.js
Normal file
@@ -0,0 +1,323 @@
|
||||
"use strict";
|
||||
|
||||
class UtilGenTables {
|
||||
static _getTableSectionIndex (sectionOrders, chapterName, sectionName) {
|
||||
((sectionOrders[chapterName] =
|
||||
sectionOrders[chapterName] || {})[sectionName] =
|
||||
sectionOrders[chapterName][sectionName] || 1);
|
||||
const val = sectionOrders[chapterName][sectionName];
|
||||
sectionOrders[chapterName][sectionName]++;
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param opts
|
||||
* @param opts.sectionOrders
|
||||
* @param opts.path
|
||||
* @param opts.tmpMeta
|
||||
* @param opts.section
|
||||
* @param opts.data
|
||||
* @param opts.stacks
|
||||
* @param opts.isRequireIncludes
|
||||
*/
|
||||
static _doSearch (opts) {
|
||||
const {sectionOrders, path, tmpMeta, section, data, stacks, isRequireIncludes} = opts;
|
||||
|
||||
if (data.data && data.data.tableIgnore) return;
|
||||
|
||||
if (data.entries) {
|
||||
const nxtSection = data.name || section;
|
||||
if (data.name || data.page) {
|
||||
const {name, page} = data;
|
||||
path.push({name, page});
|
||||
}
|
||||
data.entries.forEach(ent => this._doSearch({...opts, section: nxtSection, data: ent}));
|
||||
if (data.name || data.page) path.pop();
|
||||
} else if (data.items) {
|
||||
if (data.name || data.page) {
|
||||
const {name, page} = data;
|
||||
path.push({name, page});
|
||||
}
|
||||
data.items.forEach(item => this._doSearch({...opts, data: item}));
|
||||
if (data.name || data.page) path.pop();
|
||||
} else if (data.type === "table" || data.type === "tableGroup") {
|
||||
if (isRequireIncludes && !(data.data && data.data[VeCt.ENTDATA_TABLE_INCLUDE])) return;
|
||||
|
||||
const cpy = MiscUtil.copy(data);
|
||||
|
||||
cpy._tmpMeta = MiscUtil.copy(tmpMeta);
|
||||
cpy.path = MiscUtil.copy(path);
|
||||
cpy.section = section;
|
||||
cpy.sectionIndex = this._getTableSectionIndex(sectionOrders, tmpMeta.name, section);
|
||||
|
||||
stacks[data.type].push(cpy);
|
||||
}
|
||||
}
|
||||
|
||||
static _getCleanSectionName (name) {
|
||||
return name.replace(/^(?:Step )?[-\d]+[:.]?\s*/, "");
|
||||
}
|
||||
|
||||
static _isSectionInTitle (sections, title) {
|
||||
const lowTitle = title.toLowerCase();
|
||||
return sections.some(section => lowTitle.includes(section.toLowerCase()));
|
||||
}
|
||||
|
||||
static _mutDataAddPage (table) {
|
||||
for (let i = table.path.length - 1; i >= 0; --i) {
|
||||
if (table.path[i].page) {
|
||||
table.page = table.path[i].page;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static _mutCleanData (table) {
|
||||
delete table.path;
|
||||
delete table.section;
|
||||
delete table.sectionIndex;
|
||||
|
||||
if (table._tmpMeta.metaType === "adventure-book") {
|
||||
table.chapter = table._tmpMeta;
|
||||
delete table._tmpMeta;
|
||||
|
||||
// clean chapter
|
||||
if (table.data && table.data.tableChapterIgnore) {
|
||||
delete table.chapter;
|
||||
} else {
|
||||
const chapterOut = {};
|
||||
chapterOut.name = table.chapter.name;
|
||||
chapterOut.ordinal = table.chapter.ordinal;
|
||||
chapterOut.index = table.chapter.index;
|
||||
table.chapter = chapterOut;
|
||||
}
|
||||
} else if (table._tmpMeta.metaType === "class") {
|
||||
table.parentEntity = {
|
||||
type: table._tmpMeta.metaType,
|
||||
name: table._tmpMeta.className,
|
||||
source: table._tmpMeta.classSource,
|
||||
};
|
||||
delete table._tmpMeta;
|
||||
} else if (table._tmpMeta.metaType === "subclass") {
|
||||
table.parentEntity = {
|
||||
type: table._tmpMeta.metaType,
|
||||
name: table._tmpMeta.subclassName,
|
||||
shortName: table._tmpMeta.subclassShortName,
|
||||
source: table._tmpMeta.subclassSource,
|
||||
className: table._tmpMeta.className,
|
||||
classSource: table._tmpMeta.classSource,
|
||||
};
|
||||
delete table._tmpMeta;
|
||||
} else {
|
||||
table.parentEntity = {
|
||||
type: table._tmpMeta.metaType,
|
||||
name: table._tmpMeta.name,
|
||||
source: table._tmpMeta.source,
|
||||
};
|
||||
delete table._tmpMeta;
|
||||
}
|
||||
|
||||
if (table.type === "table") delete table.type;
|
||||
delete table.data;
|
||||
|
||||
if (table.name) table.name = Renderer.stripTags(table.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param doc
|
||||
* @param opts
|
||||
* @param opts.headProp
|
||||
* @param opts.bodyProp
|
||||
* @param [opts.isRequireIncludes]
|
||||
*/
|
||||
static getAdventureBookTables (doc, opts) {
|
||||
const sectionOrders = {};
|
||||
const stacks = {table: [], tableGroup: []};
|
||||
|
||||
if (!(doc[opts.headProp] && doc[opts.bodyProp])) return;
|
||||
|
||||
doc[opts.bodyProp].data.forEach((chapter, ixChapter) => {
|
||||
const tmpMeta = MiscUtil.copy(doc[opts.headProp].contents[ixChapter]);
|
||||
tmpMeta.index = ixChapter;
|
||||
tmpMeta.metaType = "adventure-book";
|
||||
|
||||
const path = [];
|
||||
this._doSearch({
|
||||
sectionOrders,
|
||||
path,
|
||||
tmpMeta: tmpMeta,
|
||||
section: doc[opts.headProp].name,
|
||||
data: chapter,
|
||||
stacks: stacks,
|
||||
isRequireIncludes: opts.isRequireIncludes,
|
||||
});
|
||||
});
|
||||
|
||||
stacks.table.forEach(tbl => {
|
||||
const cleanSectionNames = tbl.path.filter(ent => ent.name).map(ent => this._getCleanSectionName(ent.name));
|
||||
|
||||
if (tbl.data && tbl.data.tableNamePrefix && tbl.caption) {
|
||||
tbl.name = `${tbl.data.tableNamePrefix}; ${tbl.caption}`;
|
||||
} else if (tbl.data && tbl.data.tableName) {
|
||||
tbl.name = tbl.data.tableName;
|
||||
} else if (tbl.caption) {
|
||||
if (this._isSectionInTitle(cleanSectionNames, tbl.caption) || (tbl.data && tbl.data.skipSectionPrefix)) {
|
||||
tbl.name = tbl.caption;
|
||||
} else {
|
||||
tbl.name = cleanSectionNames.length ? `${cleanSectionNames.last()}; ${tbl.caption}` : tbl.caption;
|
||||
}
|
||||
} else {
|
||||
// If this is the only table in this section, remove the numerical suffix
|
||||
if (tbl.sectionIndex === 1 && sectionOrders[tbl._tmpMeta.name][tbl.section] === 2) {
|
||||
tbl.name = cleanSectionNames.last();
|
||||
} else {
|
||||
tbl.name = `${cleanSectionNames.last()}; ${tbl.sectionIndex}`;
|
||||
}
|
||||
}
|
||||
|
||||
this._mutDataAddPage(tbl);
|
||||
tbl.source = doc[opts.headProp].source || doc[opts.headProp].id;
|
||||
this._mutCleanData(tbl);
|
||||
});
|
||||
|
||||
stacks.tableGroup.forEach(tg => {
|
||||
const cleanSections = tg.path.filter(ent => ent.name).map(ent => this._getCleanSectionName(ent.name));
|
||||
if (!tg.name) throw new Error("Group had no name!");
|
||||
|
||||
if (!this._isSectionInTitle(cleanSections, tg.name)) {
|
||||
tg.name = `${cleanSections.last()}; ${tg.name}`;
|
||||
}
|
||||
|
||||
this._mutDataAddPage(tg);
|
||||
tg.source = doc[opts.headProp].source || doc[opts.headProp].id;
|
||||
this._mutCleanData(tg);
|
||||
});
|
||||
|
||||
return stacks;
|
||||
}
|
||||
|
||||
static getClassTables (cls) {
|
||||
const sectionOrders = {};
|
||||
const stacks = {table: [], tableGroup: []};
|
||||
const path = [];
|
||||
|
||||
cls.classFeatures.forEach((lvl, lvlI) => {
|
||||
const tmpMeta = {
|
||||
metaType: "class",
|
||||
className: cls.name,
|
||||
classSource: cls.source || Parser.SRC_PHB,
|
||||
level: lvlI + 1,
|
||||
};
|
||||
|
||||
lvl.forEach(feat => this._doSearch({
|
||||
sectionOrders,
|
||||
path,
|
||||
tmpMeta,
|
||||
section: cls.name,
|
||||
data: feat,
|
||||
stacks: stacks,
|
||||
isRequireIncludes: true,
|
||||
|
||||
// Used to deduplicate headers
|
||||
name: cls.name,
|
||||
}));
|
||||
});
|
||||
|
||||
stacks.table.forEach(it => {
|
||||
it.name = it.caption;
|
||||
it.source = it._tmpMeta.subclassSource || it._tmpMeta.classSource;
|
||||
it.srd = !!cls.srd;
|
||||
|
||||
this._mutDataAddPage(it);
|
||||
this._mutCleanData(it);
|
||||
});
|
||||
|
||||
return stacks;
|
||||
}
|
||||
|
||||
static getSubclassTables (sc) {
|
||||
const sectionOrders = {};
|
||||
const stacks = {table: [], tableGroup: []};
|
||||
const path = [];
|
||||
|
||||
sc.subclassFeatures.forEach(lvl => {
|
||||
const level = lvl[0].level;
|
||||
|
||||
const tmpMeta = {
|
||||
metaType: "subclass",
|
||||
className: sc.className,
|
||||
classSource: sc.classSource || Parser.SRC_PHB,
|
||||
level,
|
||||
subclassName: sc.name,
|
||||
subclassShortName: sc.shortName,
|
||||
subclassSource: sc.source || sc.classSource || Parser.SRC_PHB,
|
||||
|
||||
// Used to deduplicate headers
|
||||
name: sc.name,
|
||||
};
|
||||
|
||||
lvl.forEach(feat => this._doSearch({
|
||||
sectionOrders,
|
||||
path,
|
||||
tmpMeta,
|
||||
section: sc.className,
|
||||
data: feat,
|
||||
stacks: stacks,
|
||||
isRequireIncludes: true,
|
||||
}));
|
||||
});
|
||||
|
||||
stacks.table.forEach(it => {
|
||||
it.name = it.caption;
|
||||
it.source = it._tmpMeta.subclassSource || it._tmpMeta.classSource;
|
||||
it.srd = !!sc.srd;
|
||||
|
||||
this._mutDataAddPage(it);
|
||||
this._mutCleanData(it);
|
||||
});
|
||||
|
||||
return stacks;
|
||||
}
|
||||
|
||||
static getGenericTables (entity, metaType, ...props) {
|
||||
const sectionOrders = {};
|
||||
const stacks = {table: [], tableGroup: []};
|
||||
const path = [];
|
||||
|
||||
props.forEach(prop => {
|
||||
if (!entity[prop]) return;
|
||||
const tmpMeta = {
|
||||
metaType: metaType,
|
||||
name: entity.name,
|
||||
source: entity.source,
|
||||
};
|
||||
|
||||
entity[prop].forEach(ent => {
|
||||
this._doSearch({
|
||||
sectionOrders,
|
||||
path,
|
||||
tmpMeta,
|
||||
section: entity.name,
|
||||
data: ent,
|
||||
stacks: stacks,
|
||||
isRequireIncludes: true,
|
||||
|
||||
// Used to deduplicate headers
|
||||
name: entity.name,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
stacks.table.forEach(it => {
|
||||
it.name = it.caption;
|
||||
it.source = it._tmpMeta.source;
|
||||
|
||||
this._mutDataAddPage(it);
|
||||
this._mutCleanData(it);
|
||||
});
|
||||
|
||||
return stacks;
|
||||
}
|
||||
}
|
||||
|
||||
globalThis.UtilGenTables = UtilGenTables;
|
||||
Reference in New Issue
Block a user