Skip to content

Commit

Permalink
Fix pair of issues with markdown conversion (#14811)
Browse files Browse the repository at this point in the history
- Convert description overrides
- Prevent Foundry content links from being treated as markdown links
  • Loading branch information
stwlam authored and CarlosFdez committed May 29, 2024
1 parent 52b6aa1 commit 4b74350
Showing 1 changed file with 31 additions and 15 deletions.
46 changes: 31 additions & 15 deletions src/module/item/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,27 @@ class ItemChatData {
htmlOptions: EnrichmentOptionsPF2e;

/** A showdown markdown converter */
declare static mdConverter: showdown.Converter;
static #mdConverter: showdown.Converter | null = null;

constructor({ item, data, htmlOptions = {} }: ItemChatDataConstructorOptions) {
this.item = item;
this.data = data;
this.htmlOptions = htmlOptions;
// Workaround vite not resolving import in time
ItemChatData.mdConverter ??= new showdown.Converter();
}

/** Sanitized and convert stringy markdown into stringy HTML, with any initial HTML content stripped */
static markdownToHTML(markdown: string): string {
const converter = (ItemChatData.#mdConverter ??= new showdown.Converter());
const htmlStripped = createHTMLElement("div", { innerHTML: game.i18n.localize(markdown).trim() }).innerText;
// Prevent markdown converter from treating Foundry content links as markdown links
const withSubbedBrackets = htmlStripped.replaceAll("[", "⟦").replaceAll("]", "⟧");
const stringyHTML = converter
.makeHtml(withSubbedBrackets)
.replace(/<\/?p[^>]*>/g, "")
.replaceAll("⟦", "[")
.replaceAll("⟧", "]");

return TextEditor.truncateHTML(createHTMLElement("div", { innerHTML: stringyHTML })).innerHTML.trim();
}

async process(): Promise<RawItemChatData> {
Expand All @@ -65,15 +78,11 @@ class ItemChatData {
return fu.mergeObject(this.data, { description }, { inplace: false });
}

#sanitizeMarkdown(text: string): string {
const htmlStripped = createHTMLElement("div", { innerHTML: game.i18n.localize(text).trim() }).innerText;
const stringyHTML = ItemChatData.mdConverter.makeHtml(htmlStripped).replace(/<\/?p[^>]*>/g, "");
return TextEditor.truncateHTML(createHTMLElement("div", { innerHTML: stringyHTML })).innerHTML.trim();
}

async #prepareDescription(): Promise<Pick<ItemDescriptionData, "value" | "gm">> {
const { data, item } = this;
const rollOptions = new Set(R.compact([item.actor?.getRollOptions(), item.getRollOptions("item")].flat()));
const rollOptions = new Set(
R.filter([item.actor?.getRollOptions(), item.getRollOptions("item")].flat(), R.isTruthy),
);

const baseText = await (async (): Promise<string> => {
const override = data.description?.override;
Expand All @@ -86,9 +95,14 @@ class ItemChatData {
? createHTMLElement("strong", { children: [game.i18n.localize(line.title)] })
: null;
const whitespace = title ? " " : null;
const text = game.i18n.localize(line.text);
const paragraph = createHTMLElement("p", { children: R.compact([title, whitespace, text]) });
return R.compact([hr, paragraph].map((e) => e?.outerHTML));
const text = ItemChatData.markdownToHTML(line.text);
const paragraph = createHTMLElement("p", {
children: R.filter([title, whitespace, text], R.isTruthy),
});
return R.filter(
[hr, paragraph].map((e) => e?.outerHTML),
R.isTruthy,
);
})
.join("\n");
})();
Expand All @@ -105,7 +119,7 @@ class ItemChatData {
.filter((c) => c.predicate.test(rollOptions))
.map((line) => {
line.title &&= game.i18n.localize(line.title).trim();
line.text = this.#sanitizeMarkdown(line.text);
line.text = ItemChatData.markdownToHTML(line.text);
return line;
}),
};
Expand All @@ -114,7 +128,9 @@ class ItemChatData {
);
})();

const assembled = R.compact([baseText, addenda.length > 0 ? "\n<hr />\n" : null, ...addenda]).join("\n");
const assembled = R.filter([baseText, addenda.length > 0 ? "\n<hr />\n" : null, ...addenda], R.isTruthy).join(
"\n",
);
const rollData = fu.mergeObject(this.item.getRollData(), this.htmlOptions.rollData);

return {
Expand Down

0 comments on commit 4b74350

Please sign in to comment.