obsidian#parseYaml TypeScript Examples

The following examples show how to use obsidian#parseYaml. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: parser.ts    From obsidian-chartsview-plugin with MIT License 6 votes vote down vote up
export async function parseConfig(content: string, plugin: ChartsViewPlugin, sourcePath: string): Promise<ChartProps> {
    const dataProps = parseYaml(content) as DataProps;
    const { type, data } = dataProps;

    // @ts-ignore
    const chart = Plots[type] || Graphs[type];
    if (chart === undefined) {
        throw new Error(`Unsupported chart type ${type}.`);
    }

    const options = stringToFunction(dataProps.options || {});
    const config = type == "MultiView" || type == "Mix" ?
        await parseMultiViewConfig(dataProps, data, options, plugin, sourcePath)
        :
        { data: await loadFromFile(data, plugin, sourcePath), ...customOptions(options, plugin) };
    const { theme, padding } = config;
    //@ts-ignore
    const isBgColorCustomed = theme && (theme.background || (theme.styleSheet && theme.styleSheet.backgroundColor));
    config.theme = theme ?? getTheme(plugin.settings.theme);
    config.backgroundColor = isBgColorCustomed ? undefined : plugin.settings.backgroundColor;
    config.padding = padding ? undefined : [
        plugin.settings.paddingTop, plugin.settings.paddingRight,
        plugin.settings.paddingBottom, plugin.settings.paddingLeft
    ];

    return {
        type,
        showExportBtn: plugin.settings.showExportBtn,
        config
    };
}
Example #2
Source File: chartRenderer.ts    From obsidian-charts with GNU Affero General Public License v3.0 6 votes vote down vote up
/**
     * @param yaml the copied codeblock
     * @returns base64 encoded image in png format
     */
    async imageRenderer(yaml: string, options: ImageOptions): Promise<string> {
        const delay = (ms: number): Promise<void> => new Promise(resolve => setTimeout(resolve, ms));
        const destination = document.createElement('canvas');
        const destinationContext = destination.getContext("2d");

        const chartOptions = await this.datasetPrep(await parseYaml(yaml.replace("```chart", "").replace("```", "").replace(/\t/g, '    ')), document.body);

        new Chart(destinationContext, chartOptions.chartOptions);

        document.body.append(destination);
        await delay(250);
        const dataurl = destination.toDataURL(options.format, options.quality);
        document.body.removeChild(destination);

        return dataurl.substring(dataurl.indexOf(',') + 1);
    }
Example #3
Source File: main.ts    From obsidian-charts with GNU Affero General Public License v3.0 6 votes vote down vote up
postprocessor = async (content: string, el: HTMLElement, ctx: MarkdownPostProcessorContext) => {

		let data;
		try {
			data = await parseYaml(content.replace(/	/g, '    '));
		} catch (error) {
			renderError(error, el);
			return;
		}

		if(!data.id) {
			if (!data || !data.type || !data.labels || !data.series) {
				renderError("Missing type, labels or series", el)
				return;
			}
		}

		await this.renderer.renderFromYaml(data, el, ctx);
	}
Example #4
Source File: index.ts    From obsidian-initiative-tracker with GNU General Public License v3.0 6 votes vote down vote up
async postprocess() {
        const encounters = this.src.split("---") ?? [];
        const containerEl = this.containerEl.createDiv("encounter-container");
        const empty = containerEl.createSpan({
            text: "No encounters created. Please check your syntax and try again."
        });

        for (let encounter of encounters) {
            if (!encounter?.trim().length) continue;
            try {
                const params: EncounterParameters = parseYaml(encounter);
                new EncounterComponent(
                    await this.parser.parse(params),
                    containerEl.createDiv("encounter-instance"),
                    this.plugin
                );
                empty.detach();
            } catch (e) {
                console.error(e);
                new Notice(
                    "Initiative Tracker: here was an issue parsing: \n\n" +
                        encounter
                );
            }
        }
        this.registerEvent(
            this.plugin.app.workspace.on("initiative-tracker:unload", () => {
                this.containerEl.empty();
                this.containerEl.createEl("pre").createEl("code", {
                    text: `\`\`\`encounter\n${this.src}\`\`\``
                });
            })
        );
    }
Example #5
Source File: index.ts    From obsidian-initiative-tracker with GNU General Public License v3.0 5 votes vote down vote up
async postprocessTable() {
        const encounterSource = this.src.split("---") ?? [];
        const containerEl = this.containerEl.createDiv("encounter-container");
        const empty = containerEl.createSpan({
            text: "No encounters created. Please check your syntax and try again."
        });

        const encounters: ParsedParams[] = [];

        for (let encounter of encounterSource) {
            if (!encounter?.trim().length) continue;
            try {
                const params: EncounterParameters = parseYaml(encounter);
                encounters.push(await this.parser.parse(params));
            } catch (e) {
                console.error(e);
                new Notice(
                    "Initiative Tracker: here was an issue parsing: \n\n" +
                        encounter
                );
            }
        }
        if (encounters.length) {
            empty.detach();
            new EncounterTable({
                target: this.containerEl,
                props: {
                    encounters,
                    plugin: this.plugin
                }
            });
        }
        this.registerEvent(
            this.plugin.app.workspace.on("initiative-tracker:unload", () => {
                this.containerEl.empty();
                this.containerEl.createEl("pre").createEl("code", {
                    text: `\`\`\`encounter-table\n${this.src}\`\`\``
                });
            })
        );
    }
Example #6
Source File: parsing.ts    From obsidian-tracker with MIT License 4 votes vote down vote up
export function getRenderInfoFromYaml(
    yamlText: string,
    plugin: Tracker
): RenderInfo | string {
    let yaml;
    try {
        // console.log(yamlText);
        yaml = parseYaml(yamlText);
    } catch (err) {
        let errorMessage = "Error parsing YAML";
        console.log(err);
        return errorMessage;
    }
    if (!yaml) {
        let errorMessage = "Error parsing YAML";
        return errorMessage;
    }
    // console.log(yaml);
    let keysFoundInYAML = getAvailableKeysOfClass(yaml);
    // console.log(keysFoundInYAML);

    let errorMessage = "";

    // Search target
    if (!keysFoundInYAML.includes("searchTarget")) {
        let errorMessage = "Parameter 'searchTarget' not found in YAML";
        return errorMessage;
    }
    let searchTarget: Array<string> = [];
    if (typeof yaml.searchTarget === "object" && yaml.searchTarget !== null) {
        if (Array.isArray(yaml.searchTarget)) {
            for (let target of yaml.searchTarget) {
                if (typeof target === "string") {
                    if (target !== "") {
                        searchTarget.push(target);
                    } else {
                        errorMessage = "Empty search target is not allowed.";
                        break;
                    }
                }
            }
        }
    } else if (typeof yaml.searchTarget === "string") {
        let splitted = splitInputByComma(yaml.searchTarget);
        // console.log(splitted);
        if (splitted.length > 1) {
            for (let piece of splitted) {
                piece = piece.trim();
                if (piece !== "") {
                    searchTarget.push(piece);
                } else {
                    errorMessage = "Empty search target is not allowed.";
                    break;
                }
            }
        } else if (yaml.searchTarget === "") {
            errorMessage = "Empty search target is not allowed.";
        } else {
            searchTarget.push(yaml.searchTarget);
        }
    } else {
        errorMessage = "Invalid search target (searchTarget)";
    }
    for (let ind = 0; ind < searchTarget.length; ind++) {
        searchTarget[ind] = helper.replaceImgTagByAlt(searchTarget[ind]);
    }
    // console.log(searchTarget);

    if (errorMessage !== "") {
        return errorMessage;
    }

    let numDatasets = searchTarget.length;

    // Search type
    if (!keysFoundInYAML.includes("searchType")) {
        let errorMessage = "Parameter 'searchType' not found in YAML";
        return errorMessage;
    }
    let searchType: Array<SearchType> = [];
    let retSearchType = getStringArrayFromInput(
        "searchType",
        yaml.searchType,
        numDatasets,
        "",
        validateSearchType,
        false
    );
    if (typeof retSearchType === "string") {
        return retSearchType; // errorMessage
    }
    for (let strType of retSearchType) {
        switch (strType.toLowerCase()) {
            case "tag":
                searchType.push(SearchType.Tag);
                break;
            case "frontmatter":
                searchType.push(SearchType.Frontmatter);
                break;
            case "wiki":
                searchType.push(SearchType.Wiki);
                break;
            case "wiki.link":
                searchType.push(SearchType.WikiLink);
                break;
            case "wiki.display":
                searchType.push(SearchType.WikiDisplay);
                break;
            case "text":
                searchType.push(SearchType.Text);
                break;
            case "dvfield":
                searchType.push(SearchType.dvField);
                break;
            case "table":
                searchType.push(SearchType.Table);
                break;
            case "filemeta":
                searchType.push(SearchType.FileMeta);
                break;
            case "task":
                searchType.push(SearchType.Task);
                break;
            case "task.all":
                searchType.push(SearchType.Task);
                break;
            case "task.done":
                searchType.push(SearchType.TaskDone);
                break;
            case "task.notdone":
                searchType.push(SearchType.TaskNotDone);
                break;
        }
    }
    // Currently, we don't allow type 'table' used with other types
    if (
        searchType.includes(SearchType.Table) &&
        searchType.filter((t) => t !== SearchType.Table).length > 0
    ) {
        let errorMessage =
            "searchType 'table' doestn't work with other types for now";
        return errorMessage;
    }
    // console.log(searchType);

    // separator
    let multipleValueSparator: Array<string> = [];
    let retMultipleValueSparator = getStringArrayFromInput(
        "separator",
        yaml.separator,
        numDatasets,
        "", // set the default value later
        null,
        true
    );
    if (typeof retMultipleValueSparator === "string") {
        return retMultipleValueSparator; // errorMessage
    }
    multipleValueSparator = retMultipleValueSparator.map((sep) => {
        if (sep === "comma" || sep === "\\,") {
            return ",";
        }
        return sep;
    });
    // console.log(multipleValueSparator);

    // xDataset
    let retXDataset = getNumberArrayFromInput(
        "xDataset",
        yaml.xDataset,
        numDatasets,
        -1,
        true
    );
    if (typeof retXDataset === "string") {
        return retXDataset; // errorMessage
    }
    let xDataset = retXDataset.map((d: number) => {
        if (d < 0 || d >= numDatasets) {
            return -1;
        }
        return d;
    });
    // assign this to renderInfo later

    // Create queries
    let queries: Array<Query> = [];
    for (let ind = 0; ind < searchTarget.length; ind++) {
        let query = new Query(
            queries.length,
            searchType[ind],
            searchTarget[ind]
        );
        query.setSeparator(multipleValueSparator[ind]);
        if (xDataset.includes(ind)) query.usedAsXDataset = true;
        queries.push(query);
    }
    // console.log(queries);

    // Create grarph info
    let renderInfo = new RenderInfo(queries);
    let keysOfRenderInfo = getAvailableKeysOfClass(renderInfo);
    let additionalAllowedKeys = ["searchType", "searchTarget", "separator"];
    // console.log(keysOfRenderInfo);
    let yamlLineKeys = [];
    let yamlBarKeys = [];
    let yamlPieKeys = [];
    let yamlSummaryKeys = [];
    let yamlMonthKeys = [];
    let yamlHeatmapKeys = [];
    let yamlBulletKeys = [];
    for (let key of keysFoundInYAML) {
        if (/^line[0-9]*$/.test(key)) {
            yamlLineKeys.push(key);
            additionalAllowedKeys.push(key);
        }
        if (/^bar[0-9]*$/.test(key)) {
            yamlBarKeys.push(key);
            additionalAllowedKeys.push(key);
        }
        if (/^pie[0-9]*$/.test(key)) {
            yamlPieKeys.push(key);
            additionalAllowedKeys.push(key);
        }
        if (/^summary[0-9]*$/.test(key)) {
            yamlSummaryKeys.push(key);
            additionalAllowedKeys.push(key);
        }
        if (/^bullet[0-9]*$/.test(key)) {
            yamlBulletKeys.push(key);
            additionalAllowedKeys.push(key);
        }
        if (/^month[0-9]*$/.test(key)) {
            yamlMonthKeys.push(key);
            additionalAllowedKeys.push(key);
        }
        if (/^heatmap[0-9]*$/.test(key)) {
            yamlHeatmapKeys.push(key);
            additionalAllowedKeys.push(key);
        }
    }
    // Custom dataset
    let yamlCustomDatasetKeys = [];
    for (let key of keysFoundInYAML) {
        if (/^dataset[0-9]*$/.test(key)) {
            // Check the id of custom dataset is not duplicated
            let customDatasetId = -1;
            let strCustomDatasetId = key.replace("dataset", "");
            if (strCustomDatasetId === "") {
                customDatasetId = 0;
            } else {
                customDatasetId = parseFloat(strCustomDatasetId);
            }

            if (
                queries.some((q) => {
                    return q.getId() === customDatasetId;
                })
            ) {
                errorMessage = "Duplicated dataset id for key '" + key + "'";
                return errorMessage;
            }

            yamlCustomDatasetKeys.push(key);
            additionalAllowedKeys.push(key);
        }
    }
    // console.log(additionalAllowedKeys);
    for (let key of keysFoundInYAML) {
        if (
            !keysOfRenderInfo.includes(key) &&
            !additionalAllowedKeys.includes(key)
        ) {
            errorMessage = "'" + key + "' is not an available key";
            return errorMessage;
        }
    }

    let totalNumOutputs =
        yamlLineKeys.length +
        yamlBarKeys.length +
        yamlPieKeys.length +
        yamlSummaryKeys.length +
        yamlBulletKeys.length +
        yamlMonthKeys.length +
        yamlHeatmapKeys.length;
    if (totalNumOutputs === 0) {
        return "No output parameter provided, please place line, bar, pie, month, bullet, or summary.";
    }

    // Root folder to search
    renderInfo.folder = getStringFromInput(
        yaml?.folder,
        plugin.settings.folder
    );
    if (renderInfo.folder.trim() === "") {
        renderInfo.folder = plugin.settings.folder;
    }
    // console.log("renderInfo folder: " + renderInfo.folder);

    let abstractFolder = plugin.app.vault.getAbstractFileByPath(
        normalizePath(renderInfo.folder)
    );
    if (!abstractFolder || !(abstractFolder instanceof TFolder)) {
        let errorMessage = "Folder '" + renderInfo.folder + "' doesn't exist";
        return errorMessage;
    }

    // file
    if (typeof yaml.file === "string") {
        let retFiles = getStringArray("file", yaml.file);
        if (typeof retFiles === "string") {
            return retFiles; // error message
        }
        renderInfo.file = retFiles;
    }
    // console.log(renderInfo.file);

    // specifiedFilesOnly
    if (typeof yaml.specifiedFilesOnly === "boolean") {
        renderInfo.specifiedFilesOnly = yaml.specifiedFilesOnly;
    }
    // console.log(renderInfo.specifiedFilesOnly);

    // fileContainsLinkedFiles
    if (typeof yaml.fileContainsLinkedFiles === "string") {
        let retFiles = getStringArray(
            "fileContainsLinkedFiles",
            yaml.fileContainsLinkedFiles
        );
        if (typeof retFiles === "string") {
            return retFiles;
        }
        renderInfo.fileContainsLinkedFiles = retFiles;
    }
    // console.log(renderInfo.fileContainsLinkedFiles);

    // fileMultiplierAfterLink
    renderInfo.fileMultiplierAfterLink = getStringFromInput(
        yaml?.fileMultiplierAfterLink,
        renderInfo.fileMultiplierAfterLink
    );
    // console.log(renderInfo.fileMultiplierAfterLink);

    // Date format
    const dateFormat = yaml.dateFormat;
    //?? not sure why I need this to make it works,
    // without that, the assigned the renderInfo.dateFormat will become undefined
    if (typeof yaml.dateFormat === "string") {
        if (yaml.dateFormat === "") {
            renderInfo.dateFormat = plugin.settings.dateFormat;
        } else {
            renderInfo.dateFormat = dateFormat;
        }
    } else {
        renderInfo.dateFormat = plugin.settings.dateFormat;
    }
    // console.log("renderInfo dateFormat: " + renderInfo.dateFormat);

    // Date format prefix
    renderInfo.dateFormatPrefix = getStringFromInput(
        yaml?.dateFormatPrefix,
        renderInfo.dateFormatPrefix
    );

    // Date fromat suffix
    renderInfo.dateFormatSuffix = getStringFromInput(
        yaml?.dateFormatSuffix,
        renderInfo.dateFormatSuffix
    );

    // startDate, endDate
    // console.log("Parsing startDate");
    if (typeof yaml.startDate === "string") {
        if (/^([\-]?[0-9]+[\.][0-9]+|[\-]?[0-9]+)m$/.test(yaml.startDate)) {
            let errorMessage =
                "'m' for 'minute' is too small for parameter startDate, please use 'd' for 'day' or 'M' for month";
            return errorMessage;
        }
        let strStartDate = helper.getDateStringFromInputString(
            yaml.startDate,
            renderInfo.dateFormatPrefix,
            renderInfo.dateFormatSuffix
        );
        // console.log(strStartDate);

        // relative date
        let startDate = null;
        let isStartDateValid = false;
        startDate = helper.getDateByDurationToToday(
            strStartDate,
            renderInfo.dateFormat
        );
        // console.log(startDate);

        if (startDate) {
            isStartDateValid = true;
        } else {
            startDate = helper.strToDate(strStartDate, renderInfo.dateFormat);
            if (startDate.isValid()) {
                isStartDateValid = true;
            }
        }
        // console.log(startDate);

        if (!isStartDateValid || startDate === null) {
            let errorMessage =
                "Invalid startDate, the format of startDate may not match your dateFormat " +
                renderInfo.dateFormat;
            return errorMessage;
        }
        renderInfo.startDate = startDate;
    }

    // console.log("Parsing endDate");
    if (typeof yaml.endDate === "string") {
        if (/^([\-]?[0-9]+[\.][0-9]+|[\-]?[0-9]+)m$/.test(yaml.endDate)) {
            let errorMessage =
                "'m' for 'minute' is too small for parameter endDate, please use 'd' for 'day' or 'M' for month";
            return errorMessage;
        }
        let strEndDate = helper.getDateStringFromInputString(
            yaml.endDate,
            renderInfo.dateFormatPrefix,
            renderInfo.dateFormatSuffix
        );

        let endDate = null;
        let isEndDateValid = false;
        endDate = helper.getDateByDurationToToday(
            strEndDate,
            renderInfo.dateFormat
        );
        if (endDate) {
            isEndDateValid = true;
        } else {
            endDate = helper.strToDate(strEndDate, renderInfo.dateFormat);
            if (endDate.isValid()) {
                isEndDateValid = true;
            }
        }
        // console.log(endDate);

        if (!isEndDateValid || endDate === null) {
            let errorMessage =
                "Invalid endDate, the format of endDate may not match your dateFormat " +
                renderInfo.dateFormat;
            return errorMessage;
        }
        renderInfo.endDate = endDate;
    }
    if (
        renderInfo.startDate !== null &&
        renderInfo.startDate.isValid() &&
        renderInfo.endDate !== null &&
        renderInfo.endDate.isValid()
    ) {
        // Make sure endDate > startDate
        if (renderInfo.endDate < renderInfo.startDate) {
            let errorMessage =
                "Invalid date range (startDate larger than endDate)";
            return errorMessage;
        }
    }
    // console.log(renderInfo.startDate);
    // console.log(renderInfo.endDate);

    // xDataset
    renderInfo.xDataset = xDataset;
    // console.log(renderInfo.xDataset);

    // Dataset name (need xDataset to set default name)
    let retDatasetName = getStringArrayFromInput(
        "datasetName",
        yaml.datasetName,
        numDatasets,
        "untitled",
        null,
        true
    );
    if (typeof retDatasetName === "string") {
        return retDatasetName; // errorMessage
    }
    // rename untitled
    let indUntitled = 0;
    for (let ind = 0; ind < retDatasetName.length; ind++) {
        if (renderInfo.xDataset.includes(ind)) continue;
        if (retDatasetName[ind] === "untitled") {
            retDatasetName[ind] = "untitled" + indUntitled.toString();
            indUntitled++;
        }
    }
    // Check duplicated names
    if (new Set(retDatasetName).size === retDatasetName.length) {
        renderInfo.datasetName = retDatasetName;
    } else {
        let errorMessage = "Not enough dataset names or duplicated names";
        return errorMessage;
    }
    // console.log(renderInfo.datasetName);

    // constValue
    let retConstValue = getNumberArrayFromInput(
        "constValue",
        yaml.constValue,
        numDatasets,
        1.0,
        true
    );
    if (typeof retConstValue === "string") {
        return retConstValue; // errorMessage
    }
    renderInfo.constValue = retConstValue;
    // console.log(renderInfo.constValue);

    // ignoreAttachedValue
    let retIgnoreAttachedValue = getBoolArrayFromInput(
        "ignoreAttachedValue",
        yaml.ignoreAttachedValue,
        numDatasets,
        false,
        true
    );
    if (typeof retIgnoreAttachedValue === "string") {
        return retIgnoreAttachedValue;
    }
    renderInfo.ignoreAttachedValue = retIgnoreAttachedValue;
    // console.log(renderInfo.ignoreAttachedValue);

    // ignoreZeroValue
    let retIgnoreZeroValue = getBoolArrayFromInput(
        "ignoreZeroValue",
        yaml.ignoreZeroValue,
        numDatasets,
        false,
        true
    );
    if (typeof retIgnoreZeroValue === "string") {
        return retIgnoreZeroValue;
    }
    renderInfo.ignoreZeroValue = retIgnoreZeroValue;
    // console.log(renderInfo.ignoreAttachedValue);

    // accum
    let retAccum = getBoolArrayFromInput(
        "accum",
        yaml.accum,
        numDatasets,
        false,
        true
    );
    if (typeof retAccum === "string") {
        return retAccum;
    }
    renderInfo.accum = retAccum;
    // console.log(renderInfo.accum);

    // penalty
    let retPenalty = getNumberArrayFromInput(
        "penalty",
        yaml.penalty,
        numDatasets,
        null,
        true
    );
    if (typeof retPenalty === "string") {
        return retPenalty;
    }
    renderInfo.penalty = retPenalty;
    // console.log(renderInfo.penalty);

    // valueShift
    let retValueShift = getNumberArrayFromInput(
        "valueShift",
        yaml.valueShift,
        numDatasets,
        0,
        true
    );
    if (typeof retValueShift === "string") {
        return retValueShift;
    }
    renderInfo.valueShift = retValueShift;
    // console.log(renderInfo.valueShift);

    // shiftOnlyValueLargerThan
    let retShiftOnlyValueLargerThan = getNumberArrayFromInput(
        "shiftOnlyValueLargerThan",
        yaml.shiftOnlyValueLargerThan,
        numDatasets,
        null,
        true
    );
    if (typeof retShiftOnlyValueLargerThan === "string") {
        return retShiftOnlyValueLargerThan;
    }
    renderInfo.shiftOnlyValueLargerThan = retShiftOnlyValueLargerThan;
    // console.log(renderInfo.shiftOnlyValueLargerThan);

    // textValueMap
    if (typeof yaml.textValueMap !== "undefined") {
        let keys = getAvailableKeysOfClass(yaml.textValueMap);
        // console.log(texts);
        for (let key of keys) {
            let text = key.trim();
            renderInfo.textValueMap[text] = yaml.textValueMap[text];
        }
    }
    // console.log(renderInfo.textValueMap);

    // fixedScale
    if (typeof yaml.fixedScale === "number") {
        renderInfo.fixedScale = yaml.fixedScale;
    }

    // fitPanelWidth
    if (typeof yaml.fitPanelWidth === "boolean") {
        renderInfo.fitPanelWidth = yaml.fitPanelWidth;
    }

    // margin
    let retMargin = getNumberArrayFromInput("margin", yaml.margin, 4, 10, true);
    if (typeof retMargin === "string") {
        return retMargin; // errorMessage
    }
    if (retMargin.length > 4) {
        return "margin accepts not more than four values for top, right, bottom, and left margins.";
    }
    renderInfo.margin = new Margin(
        retMargin[0],
        retMargin[1],
        retMargin[2],
        retMargin[3]
    );
    // console.log(renderInfo.margin);

    // customDataset related parameters
    for (let datasetKey of yamlCustomDatasetKeys) {
        let customDataset = new CustomDatasetInfo();
        let yamlCustomDataset = yaml[datasetKey];

        let keysOfCustomDatasetInfo = getAvailableKeysOfClass(customDataset);
        let keysFoundInYAML = getAvailableKeysOfClass(yamlCustomDataset);
        // console.log(keysOfCustomDatasetInfo);
        // console.log(keysFoundInYAML);
        for (let key of keysFoundInYAML) {
            if (!keysOfCustomDatasetInfo.includes(key)) {
                errorMessage = "'" + key + "' is not an available key";
                return errorMessage;
            }
        }

        // id
        let customDatasetId = -1;
        let strCustomDatasetId = datasetKey.replace("dataset", "");
        if (strCustomDatasetId === "") {
            customDatasetId = 0;
        } else {
            customDatasetId = parseFloat(strCustomDatasetId);
        }
        customDataset.id = customDatasetId;

        // name
        customDataset.name = getStringFromInput(
            yamlCustomDataset?.name,
            customDataset.name
        );

        // xData
        let retXData = getStringArray("xData", yamlCustomDataset?.xData);
        if (typeof retXData === "string") {
            return retXData;
        }
        customDataset.xData = retXData;
        // console.log(customDataset.xData);
        let numXData = customDataset.xData.length;

        // yData
        let retYData = getStringArray("yData", yamlCustomDataset?.yData);
        if (typeof retYData === "string") {
            return retYData;
        }
        customDataset.yData = retYData;
        // console.log(customDataset.yData);
        if (customDataset.yData.length !== numXData) {
            let errorMessage =
                "Number of elements in xData and yData not matched";
            return errorMessage;
        }

        renderInfo.customDataset.push(customDataset);
    } // customDataset related parameters
    // console.log(renderInfo.customDataset);

    // line related parameters
    for (let lineKey of yamlLineKeys) {
        let line = new LineInfo();
        let yamlLine = yaml[lineKey];

        let keysOfLineInfo = getAvailableKeysOfClass(line);
        let keysFoundInYAML = getAvailableKeysOfClass(yamlLine);
        // console.log(keysOfLineInfo);
        // console.log(keysFoundInYAML);
        for (let key of keysFoundInYAML) {
            if (!keysOfLineInfo.includes(key)) {
                errorMessage = "'" + key + "' is not an available key";
                return errorMessage;
            }
        }

        let retParseCommonChartInfo = parseCommonChartInfo(yamlLine, line);
        if (typeof retParseCommonChartInfo === "string") {
            return retParseCommonChartInfo;
        }

        // lineColor
        let retLineColor = getStringArrayFromInput(
            "lineColor",
            yamlLine?.lineColor,
            numDatasets,
            "",
            validateColor,
            true
        );
        if (typeof retLineColor === "string") {
            return retLineColor; // errorMessage
        }
        line.lineColor = retLineColor;
        // console.log(line.lineColor);

        // lineWidth
        let retLineWidth = getNumberArrayFromInput(
            "lineWidth",
            yamlLine?.lineWidth,
            numDatasets,
            1.5,
            true
        );
        if (typeof retLineWidth === "string") {
            return retLineWidth; // errorMessage
        }
        line.lineWidth = retLineWidth;
        // console.log(line.lineWidth);

        // showLine
        let retShowLine = getBoolArrayFromInput(
            "showLine",
            yamlLine?.showLine,
            numDatasets,
            true,
            true
        );
        if (typeof retShowLine === "string") {
            return retShowLine;
        }
        line.showLine = retShowLine;
        // console.log(line.showLine);

        // showPoint
        let retShowPoint = getBoolArrayFromInput(
            "showPoint",
            yamlLine?.showPoint,
            numDatasets,
            true,
            true
        );
        if (typeof retShowPoint === "string") {
            return retShowPoint;
        }
        line.showPoint = retShowPoint;
        // console.log(line.showPoint);

        // pointColor
        let retPointColor = getStringArrayFromInput(
            "pointColor",
            yamlLine?.pointColor,
            numDatasets,
            "#69b3a2",
            validateColor,
            true
        );
        if (typeof retPointColor === "string") {
            return retPointColor;
        }
        line.pointColor = retPointColor;
        // console.log(line.pointColor);

        // pointBorderColor
        let retPointBorderColor = getStringArrayFromInput(
            "pointBorderColor",
            yamlLine?.pointBorderColor,
            numDatasets,
            "#69b3a2",
            validateColor,
            true
        );
        if (typeof retPointBorderColor === "string") {
            return retPointBorderColor;
        }
        line.pointBorderColor = retPointBorderColor;
        // console.log(line.pointBorderColor);

        // pointBorderWidth
        let retPointBorderWidth = getNumberArrayFromInput(
            "pointBorderWidth",
            yamlLine?.pointBorderWidth,
            numDatasets,
            0.0,
            true
        );
        if (typeof retPointBorderWidth === "string") {
            return retPointBorderWidth; // errorMessage
        }
        line.pointBorderWidth = retPointBorderWidth;
        // console.log(line.pointBorderWidth);

        // pointSize
        let retPointSize = getNumberArrayFromInput(
            "pointSize",
            yamlLine?.pointSize,
            numDatasets,
            3.0,
            true
        );
        if (typeof retPointSize === "string") {
            return retPointSize; // errorMessage
        }
        line.pointSize = retPointSize;
        // console.log(line.pointSize);

        // fillGap
        let retFillGap = getBoolArrayFromInput(
            "fillGap",
            yamlLine?.fillGap,
            numDatasets,
            false,
            true
        );
        if (typeof retFillGap === "string") {
            return retFillGap;
        }
        line.fillGap = retFillGap;
        // console.log(line.fillGap);

        // yAxisLocation
        let retYAxisLocation = getStringArrayFromInput(
            "yAxisLocation",
            yamlLine?.yAxisLocation,
            numDatasets,
            "left",
            validateYAxisLocation,
            true
        );
        if (typeof retYAxisLocation === "string") {
            return retYAxisLocation; // errorMessage
        }
        line.yAxisLocation = retYAxisLocation;
        // console.log(line.yAxisLocation);

        renderInfo.line.push(line);
    } // line related parameters
    // console.log(renderInfo.line);

    // bar related parameters
    for (let barKey of yamlBarKeys) {
        let bar = new BarInfo();
        let yamlBar = yaml[barKey];

        let keysOfBarInfo = getAvailableKeysOfClass(bar);
        let keysFoundInYAML = getAvailableKeysOfClass(yamlBar);
        // console.log(keysOfBarInfo);
        // console.log(keysFoundInYAML);
        for (let key of keysFoundInYAML) {
            if (!keysOfBarInfo.includes(key)) {
                errorMessage = "'" + key + "' is not an available key";
                return errorMessage;
            }
        }

        let retParseCommonChartInfo = parseCommonChartInfo(yamlBar, bar);
        if (typeof retParseCommonChartInfo === "string") {
            return retParseCommonChartInfo;
        }

        // barColor
        let retBarColor = getStringArrayFromInput(
            "barColor",
            yamlBar?.barColor,
            numDatasets,
            "",
            validateColor,
            true
        );
        if (typeof retBarColor === "string") {
            return retBarColor; // errorMessage
        }
        bar.barColor = retBarColor;
        // console.log(bar.barColor);

        // yAxisLocation
        let retYAxisLocation = getStringArrayFromInput(
            "yAxisLocation",
            yamlBar?.yAxisLocation,
            numDatasets,
            "left",
            validateYAxisLocation,
            true
        );
        if (typeof retYAxisLocation === "string") {
            return retYAxisLocation; // errorMessage
        }
        bar.yAxisLocation = retYAxisLocation;
        // console.log(bar.yAxisLocation);

        renderInfo.bar.push(bar);
    } // bar related parameters
    // console.log(renderInfo.bar);

    // pie related parameters
    for (let pieKey of yamlPieKeys) {
        let pie = new PieInfo();
        let yamlPie = yaml[pieKey];

        let keysOfPieInfo = getAvailableKeysOfClass(pie);
        let keysFoundInYAML = getAvailableKeysOfClass(yamlPie);
        // console.log(keysOfPieInfo);
        // console.log(keysFoundInYAML);
        for (let key of keysFoundInYAML) {
            if (!keysOfPieInfo.includes(key)) {
                errorMessage = "'" + key + "' is not an available key";
                return errorMessage;
            }
        }

        // title
        pie.title = getStringFromInput(yamlPie?.title, pie.title);
        // console.log(pie.title);

        // data
        let retData = getStringArray("data", yamlPie?.data);
        if (typeof retData === "string") {
            return retData;
        }
        pie.data = retData;
        // console.log(pie.data);
        let numData = pie.data.length;

        // dataColor
        let retDataColor = getStringArrayFromInput(
            "dataColor",
            yamlPie?.dataColor,
            numData,
            null,
            validateColor,
            true
        );
        if (typeof retDataColor === "string") {
            return retDataColor; // errorMessage
        }
        pie.dataColor = retDataColor;
        // console.log(pie.dataColor);

        // dataName
        let retDataName = getStringArrayFromInput(
            "dataName",
            yamlPie?.dataName,
            numData,
            "",
            null,
            true
        );
        if (typeof retDataName === "string") {
            return retDataName; // errorMessage
        }
        pie.dataName = retDataName;
        // console.log(pie.dataName);

        // label
        let retLabel = getStringArrayFromInput(
            "label",
            yamlPie?.label,
            numData,
            "",
            null,
            true
        );
        if (typeof retLabel === "string") {
            return retLabel; // errorMessage
        }
        pie.label = retLabel;
        // console.log(pie.label);

        // hideLabelLessThan
        if (typeof yamlPie?.hideLabelLessThan === "number") {
            pie.hideLabelLessThan = yamlPie.hideLabelLessThan;
        }
        // console.log(pie.hideLabelLessThan);

        // extLabel
        let retExtLabel = getStringArrayFromInput(
            "extLabel",
            yamlPie?.extLabel,
            numData,
            "",
            null,
            true
        );
        if (typeof retExtLabel === "string") {
            return retExtLabel; // errorMessage
        }
        pie.extLabel = retExtLabel;
        // console.log(pie.extLabel);

        // showExtLabelOnlyIfNoLabel
        if (typeof yamlPie?.showExtLabelOnlyIfNoLabel === "boolean") {
            pie.showExtLabelOnlyIfNoLabel = yamlPie.showExtLabelOnlyIfNoLabel;
        }
        // console.log(pie.showExtLabelOnlyIfNoLabel);

        // ratioInnerRadius
        if (typeof yamlPie?.ratioInnerRadius === "number") {
            pie.ratioInnerRadius = yamlPie.ratioInnerRadius;
        }
        // console.log(pie.ratioInnerRadius);

        // showLegend
        if (typeof yamlPie?.showLegend === "boolean") {
            pie.showLegend = yamlPie.showLegend;
        }

        // legendPosition
        pie.legendPosition = getStringFromInput(
            yamlPie?.legendPosition,
            "right"
        );

        // legendOrient
        let defaultLegendOrientation = "horizontal";
        if (pie.legendPosition === "top" || pie.legendPosition === "bottom") {
            defaultLegendOrientation = "horizontal";
        } else if (
            pie.legendPosition === "left" ||
            pie.legendPosition === "right"
        ) {
            defaultLegendOrientation = "vertical";
        } else {
            defaultLegendOrientation = "horizontal";
        }
        pie.legendOrientation = getStringFromInput(
            yamlPie?.legendOrientation,
            defaultLegendOrientation
        );
        // console.log(pie.legendPosition);
        // console.log(pie.legendOrientation);

        // legendBgColor
        pie.legendBgColor = getStringFromInput(
            yamlPie?.legendBgColor,
            pie.legendBgColor
        );

        // legendBorderColor
        pie.legendBorderColor = getStringFromInput(
            yamlPie?.legendBorderColor,
            pie.legendBorderColor
        );

        renderInfo.pie.push(pie);
    } // pie related parameters
    // console.log(renderInfo.pie);

    // summary related parameters
    for (let summaryKey of yamlSummaryKeys) {
        let summary = new SummaryInfo();
        let yamlSummary = yaml[summaryKey];

        let keysOfSummaryInfo = getAvailableKeysOfClass(summary);
        let keysFoundInYAML = getAvailableKeysOfClass(yamlSummary);
        // console.log(keysOfSummaryInfo);
        // console.log(keysFoundInYAML);
        for (let key of keysFoundInYAML) {
            if (!keysOfSummaryInfo.includes(key)) {
                errorMessage = "'" + key + "' is not an available key";
                return errorMessage;
            }
        }

        // template
        summary.template = getStringFromInput(
            yamlSummary?.template,
            summary.template
        );

        // style
        summary.style = getStringFromInput(yamlSummary?.style, summary.style);

        renderInfo.summary.push(summary);
    } // summary related parameters

    // Month related parameters
    for (let monthKey of yamlMonthKeys) {
        let month = new MonthInfo();
        let yamlMonth = yaml[monthKey];

        let keysOfMonthInfo = getAvailableKeysOfClass(month);
        let keysFoundInYAML = getAvailableKeysOfClass(yamlMonth);
        // console.log(keysOfSummaryInfo);
        // console.log(keysFoundInYAML);
        for (let key of keysFoundInYAML) {
            if (!keysOfMonthInfo.includes(key)) {
                errorMessage = "'" + key + "' is not an available key";
                return errorMessage;
            }
        }

        // mode
        month.mode = getStringFromInput(yamlMonth?.mode, month.mode);
        // console.log(month.mode);

        // dataset
        let retDataset = getNumberArray("dataset", yamlMonth?.dataset);
        if (typeof retDataset === "string") {
            return retDataset;
        }
        if (retDataset.length === 0) {
            // insert y dataset given
            for (let q of queries) {
                retDataset.push(q.getId());
            }
        }
        month.dataset = retDataset;
        // console.log(month.dataset);
        let numDataset = month.dataset.length;

        // startWeekOn
        month.startWeekOn = getStringFromInput(
            yamlMonth?.startWeekOn,
            month.startWeekOn
        );
        // console.log(month.startWeekOn);

        // showCircle
        if (typeof yamlMonth?.showCircle === "boolean") {
            month.showCircle = yamlMonth.showCircle;
        }
        // console.log(month.showCircle);

        // threshold
        let retThreshold = getNumberArray("threshold", yamlMonth?.threshold);
        if (typeof retThreshold === "string") {
            return retThreshold;
        }
        month.threshold = retThreshold;
        if (month.threshold.length === 0) {
            for (let indDataset = 0; indDataset < numDataset; indDataset++) {
                month.threshold.push(0);
            }
        }
        if (month.threshold.length !== month.dataset.length) {
            // console.log(month.threshold);
            // console.log(month.dataset);
            const errorMessage =
                "The number of inputs of threshold and dataset not matched";
            return errorMessage;
        }
        // console.log(month.threshold);

        // yMin
        let retYMin = getNumberArray("yMin", yamlMonth?.yMin);
        if (typeof retYMin === "string") {
            return retYMin;
        }
        month.yMin = retYMin;
        if (month.yMin.length === 0) {
            for (let indDataset = 0; indDataset < numDataset; indDataset++) {
                month.yMin.push(null);
            }
        }
        if (month.yMin.length !== month.dataset.length) {
            const errorMessage =
                "The number of inputs of yMin and dataset not matched";
            return errorMessage;
        }
        // console.log(month.yMin);

        // yMax
        let retYMax = getNumberArray("yMax", yamlMonth?.yMax);
        if (typeof retYMax === "string") {
            return retYMax;
        }
        month.yMax = retYMax;
        if (month.yMax.length === 0) {
            for (let indDataset = 0; indDataset < numDataset; indDataset++) {
                month.yMax.push(null);
            }
        }
        if (month.yMax.length !== month.dataset.length) {
            const errorMessage =
                "The number of inputs of yMin and dataset not matched";
            return errorMessage;
        }
        // console.log(month.yMax);

        // color
        month.color = getStringFromInput(yamlMonth?.color, month.color);
        // console.log(month.color);

        // dimNotInMonth
        if (typeof yamlMonth?.dimNotInMonth === "boolean") {
            month.dimNotInMonth = yamlMonth.dimNotInMonth;
        }
        // console.log(month.dimNotInMonth);

        // showStreak
        if (typeof yamlMonth?.showStreak === "boolean") {
            month.showStreak = yamlMonth.showStreak;
        }
        // console.log(month.showStreak);

        // showTodayRing
        if (typeof yamlMonth?.showTodayRing === "boolean") {
            month.showTodayRing = yamlMonth.showTodayRing;
        }
        // console.log(month.showTodayRing);

        // showSelectedValue
        if (typeof yamlMonth?.showSelectedValue === "boolean") {
            month.showSelectedValue = yamlMonth.showSelectedValue;
        }
        // console.log(month.showSelectedValue);

        // showSelectedRing
        if (typeof yamlMonth?.showSelectedRing === "boolean") {
            month.showSelectedRing = yamlMonth.showSelectedRing;
        }
        // console.log(month.showSelectedRing);

        // circleColor
        month.circleColor = getStringFromInput(
            yamlMonth?.circleColor,
            month.circleColor
        );
        // console.log(month.circleColor);

        // circleColorByValue
        if (typeof yamlMonth?.circleColorByValue === "boolean") {
            month.circleColorByValue = yamlMonth.circleColorByValue;
        }
        // console.log(month.circleColorByValue);

        // headerYearColor
        month.headerYearColor = getStringFromInput(
            yamlMonth?.headerYearColor,
            month.headerYearColor
        );
        // console.log(month.headerYearColor);

        // headerMonthColor
        month.headerMonthColor = getStringFromInput(
            yamlMonth?.headerMonthColor,
            month.headerMonthColor
        );
        // console.log(month.headerMonthColor);

        // dividingLineColor
        month.dividingLineColor = getStringFromInput(
            yamlMonth?.dividingLineColor,
            month.dividingLineColor
        );
        // console.log(month.dividingLineColor);

        // todayRingColor
        month.todayRingColor = getStringFromInput(
            yamlMonth?.todayRingColor,
            month.todayRingColor
        );
        // console.log(month.todayRingColor);

        // selectedRingColor
        month.selectedRingColor = getStringFromInput(
            yamlMonth?.selectedRingColor,
            month.selectedRingColor
        );
        // console.log(month.selectedRingColor);

        // initMonth
        month.initMonth = getStringFromInput(
            yamlMonth?.initMonth,
            month.initMonth
        );
        // console.log(month.initMonth);

        // showAnnotation
        if (typeof yamlMonth?.showAnnotation === "boolean") {
            month.showAnnotation = yamlMonth.showAnnotation;
        }
        // console.log(month.showAnnotation);

        // annotation
        let retAnnotation = getStringArray("annotation", yamlMonth?.annotation);
        if (typeof retAnnotation === "string") {
            return retAnnotation;
        }
        month.annotation = retAnnotation;
        if (month.annotation.length === 0) {
            for (let indDataset = 0; indDataset < numDataset; indDataset++) {
                month.annotation.push(null);
            }
        }
        if (month.annotation.length !== month.dataset.length) {
            const errorMessage =
                "The number of inputs of annotation and dataset not matched";
            return errorMessage;
        }
        // console.log(month.annotation);

        // showAnnotationOfAllTargets
        if (typeof yamlMonth?.showAnnotationOfAllTargets === "boolean") {
            month.showAnnotationOfAllTargets =
                yamlMonth.showAnnotationOfAllTargets;
        }
        // console.log(month.showAnnotationOfAllTargets);

        renderInfo.month.push(month);
    } // Month related parameters
    // console.log(renderInfo.month);

    // Heatmap related parameters
    for (let heatmapKey of yamlHeatmapKeys) {
        let heatmap = new HeatmapInfo();
        let yamlHeatmap = yaml[heatmapKey];

        let keysOfHeatmapInfo = getAvailableKeysOfClass(heatmap);
        let keysFoundInYAML = getAvailableKeysOfClass(yamlHeatmap);
        // console.log(keysOfHeatmapInfo);
        // console.log(keysFoundInYAML);
        for (let key of keysFoundInYAML) {
            if (!keysOfHeatmapInfo.includes(key)) {
                errorMessage = "'" + key + "' is not an available key";
                return errorMessage;
            }
        }

        renderInfo.heatmap.push(heatmap);
    }
    // console.log(renderInfo.heatmap);

    // Bullet related parameters
    for (let bulletKey of yamlBulletKeys) {
        let bullet = new BulletInfo();
        let yamlBullet = yaml[bulletKey];

        let keysOfBulletInfo = getAvailableKeysOfClass(bullet);
        let keysFoundInYAML = getAvailableKeysOfClass(yamlBullet);
        // console.log(keysOfSummaryInfo);
        // console.log(keysFoundInYAML);
        for (let key of keysFoundInYAML) {
            if (!keysOfBulletInfo.includes(key)) {
                errorMessage = "'" + key + "' is not an available key";
                return errorMessage;
            }
        }

        // title
        bullet.title = getStringFromInput(yamlBullet?.title, bullet.title);
        // console.log(bullet.title);

        // dataset
        bullet.dataset = getStringFromInput(
            yamlBullet?.dataset,
            bullet.dataset
        );
        // console.log(bullet.dataset);

        // orientation
        bullet.orientation = getStringFromInput(
            yamlBullet?.orientation,
            bullet.orientation
        );
        // console.log(bullet.orientation);

        // range
        let retRange = getNumberArray("range", yamlBullet?.range);
        if (typeof retRange === "string") {
            return retRange;
        }
        let range = retRange as Array<number>;
        // Check the value is monotonically increasing
        // Check the value is not negative
        if (range.length === 1) {
            if (range[0] < 0) {
                errorMessage = "Negative range value is not allowed";
                return errorMessage;
            }
        } else if (range.length > 1) {
            let lastBound = range[0];
            if (lastBound < 0) {
                errorMessage = "Negative range value is not allowed";
                return errorMessage;
            } else {
                for (let ind = 1; ind < range.length; ind++) {
                    if (range[ind] <= lastBound) {
                        errorMessage =
                            "Values in parameter 'range' should be monotonically increasing";
                        return errorMessage;
                    }
                }
            }
        } else {
            errorMessage = "Empty range is not allowed";
            return errorMessage;
        }
        bullet.range = range;
        let numRange = range.length;
        // console.log(renderInfo.bullet.range);

        // range color
        let retRangeColor = getStringArrayFromInput(
            "rangeColor",
            yamlBullet?.rangeColor,
            numRange,
            "",
            validateColor,
            true
        );
        if (typeof retRangeColor === "string") {
            return retRangeColor; // errorMessage
        }
        bullet.rangeColor = retRangeColor;
        // console.log(bullet.rangeColor);

        // actual value, can possess template variable
        bullet.value = getStringFromInput(yamlBullet?.value, bullet.value);
        // console.log(bullet.value);

        // value unit
        bullet.valueUnit = getStringFromInput(
            yamlBullet?.valueUnit,
            bullet.valueUnit
        );
        // console.log(bullet.valueUnit);

        // value color
        bullet.valueColor = getStringFromInput(
            yamlBullet?.valueColor,
            bullet.valueColor
        );
        // console.log(bullet.valueColor);

        // show mark
        if (typeof yamlBullet?.showMarker === "boolean") {
            bullet.showMarker = yamlBullet.showMarker;
        }
        // console.log(bullet.showMark);

        // mark value
        if (typeof yamlBullet?.markerValue === "number") {
            bullet.markerValue = yamlBullet.markerValue;
        }
        // console.log(bullet.markValue);

        // mark color
        bullet.markerColor = getStringFromInput(
            yamlBullet?.markerColor,
            bullet.markerColor
        );
        // console.log(bullet.markValue);

        renderInfo.bullet.push(bullet);
    } // Bullet related parameters
    // console.log(renderInfo.bullet);

    return renderInfo;
}
Example #7
Source File: main.ts    From obsidian-initiative-tracker with GNU General Public License v3.0 4 votes vote down vote up
async onload() {
        registerIcons();

        await this.loadSettings();

        this.addSettingTab(new InitiativeTrackerSettings(this));

        this.registerView(
            INTIATIVE_TRACKER_VIEW,
            (leaf: WorkspaceLeaf) => new TrackerView(leaf, this)
        );
        this.registerView(
            CREATURE_TRACKER_VIEW,
            (leaf: WorkspaceLeaf) => new CreatureView(leaf, this)
        );

        this.addCommands();

        this.registerMarkdownCodeBlockProcessor("encounter", (src, el, ctx) => {
            const handler = new EncounterBlock(this, src, el);
            ctx.addChild(handler);
        });
        this.registerMarkdownCodeBlockProcessor(
            "encounter-table",
            (src, el, ctx) => {
                const handler = new EncounterBlock(this, src, el, true);
                ctx.addChild(handler);
            }
        );

        this.registerMarkdownPostProcessor(async (el, ctx) => {
            if (!el || !el.firstElementChild) return;

            const codeEls = el.querySelectorAll<HTMLElement>("code");
            if (!codeEls || !codeEls.length) return;

            const codes = Array.from(codeEls).filter((code) =>
                /^encounter:\s/.test(code.innerText)
            );
            if (!codes.length) return;

            for (const code of codes) {
                const creatures = code.innerText
                    .replace(`encounter:`, "")
                    .trim()
                    .split(",")
                    .map((s) => parseYaml(s.trim()));
                const parser = new EncounterParser(this);
                const parsed = await parser.parse({ creatures });

                if (!parsed || !parsed.creatures || !parsed.creatures.size)
                    continue;

                const target = createSpan("initiative-tracker-encounter-line");
                new EncounterLine({
                    target,
                    props: {
                        ...parsed,
                        plugin: this
                    }
                });

                code.replaceWith(target);
            }
        });

        this.playerCreatures = new Map(
            this.data.players.map((p) => [p.name, Creature.from(p)])
        );
        this.homebrewCreatures = new Map(
            this.bestiary.map((p) => [p.name, Creature.from(p)])
        );

        this.app.workspace.onLayoutReady(async () => {
            this.addTrackerView();
            //Update players from < 7.2
            for (const player of this.data.players) {
                if (player.path) continue;
                if (!player.note) continue;
                const file = await this.app.metadataCache.getFirstLinkpathDest(
                    player.note,
                    ""
                );
                if (
                    !file ||
                    !this.app.metadataCache.getFileCache(file)?.frontmatter
                ) {
                    new Notice(
                        `Initiative Tracker: There was an issue with the linked note for ${player.name}.\n\nPlease re-link it in settings.`
                    );
                    continue;
                }
            }
            this.registerEvent(
                this.app.metadataCache.on("changed", (file) => {
                    if (!(file instanceof TFile)) return;
                    const players = this.data.players.filter(
                        (p) => p.path == file.path
                    );
                    if (!players.length) return;
                    const frontmatter: FrontMatterCache =
                        this.app.metadataCache.getFileCache(file)?.frontmatter;
                    if (!frontmatter) return;
                    for (let player of players) {
                        const { ac, hp, modifier, level } = frontmatter;
                        player.ac = ac;
                        player.hp = hp;
                        player.modifier = modifier;
                        player.level = level;

                        this.playerCreatures.set(
                            player.name,
                            Creature.from(player)
                        );
                        if (this.view) {
                            const creature = this.view.ordered.find(
                                (c) => c.name == player.name
                            );
                            if (creature) {
                                this.view.updateCreature(creature, {
                                    max: player.hp,
                                    ac: player.ac
                                });
                            }
                        }
                    }
                })
            );
            this.registerEvent(
                this.app.vault.on("rename", (file, old) => {
                    if (!(file instanceof TFile)) return;
                    const players = this.data.players.filter(
                        (p) => p.path == old
                    );
                    if (!players.length) return;
                    for (const player of players) {
                        player.path = file.path;
                        player.note = file.basename;
                    }
                })
            );
            this.registerEvent(
                this.app.vault.on("delete", (file) => {
                    if (!(file instanceof TFile)) return;
                    const players = this.data.players.filter(
                        (p) => p.path == file.path
                    );
                    if (!players.length) return;
                    for (const player of players) {
                        player.path = null;
                        player.note = null;
                    }
                })
            );
        });

        console.log("Initiative Tracker v" + this.manifest.version + " loaded");
    }