summaryrefslogtreecommitdiff
path: root/src/classes/MessageFormatting.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/classes/MessageFormatting.ts')
-rw-r--r--src/classes/MessageFormatting.ts118
1 files changed, 117 insertions, 1 deletions
diff --git a/src/classes/MessageFormatting.ts b/src/classes/MessageFormatting.ts
index 88df999..a05351d 100644
--- a/src/classes/MessageFormatting.ts
+++ b/src/classes/MessageFormatting.ts
@@ -1,4 +1,5 @@
import {MessageFormattingRule} from "./MessageFormattingRule";
+import {marked} from "marked";
/**
* A collection of rules to apply formatting styles to a message
@@ -38,5 +39,120 @@ export class MessageFormatting {
return mf;
}
- //public static fromMarkdown() {}
+ /**
+ * Transform a Markdown-formatted text into a plain text string
+ * that can be easily displayed.
+ *
+ * @param text - The text to use
+ */
+ public static plainFromMarkdown(text: string) {
+ let renderer = {};
+ text = text.replaceAll(/(?<!\n)<br>/gmi, "\n").replaceAll("<br>", "").replace(/(```)(.*)(\n)/gm, "$1$3").replace(/#+( |)(.*)/gm, "**$2**");
+
+ renderer['strong'] = renderer['em'] = renderer['codespan'] = renderer['code'] = renderer['del'] = renderer['tablerow'] = renderer['tablecell'] = renderer['heading'] = renderer['blockquote'] = (text) => text;
+ renderer['hr'] = () => "—————————";
+ renderer['link'] = (href, title, text) => (title ?? text) + ": " + href;
+ renderer['text'] = (text) => text.replace(/^( *)\* *(.*)/gm, "$1- $2");
+
+ marked.use({
+ async: false,
+ mangle: false,
+ headerIds: false,
+ renderer
+ });
+
+ return marked.parseInline(text).replaceAll("&lt;br&gt;", "\n").replace(/&#(\d+);/g, function(match, dec) {
+ return String.fromCharCode(dec);
+ }).replaceAll("<u>", "").replaceAll("</u>", "").replaceAll("\\<u>", "<u>").replaceAll("\\</u>", "</u>");
+ }
+
+ /**
+ * Transform a Markdown-formatted text into a {@link MessageFormatting},
+ * converting the compatible formatting options.
+ *
+ * @param text - The text to use
+ * @experimental
+ */
+ public static fromMarkdown(text: string) {
+ let plain = MessageFormatting.plainFromMarkdown(text);
+ let styles = [];
+ text = text.replaceAll(/(?<!\n)<br>/gmi, "\n").replaceAll("<br>", "").replace(/(```)(.*)(\n)/gm, "$1$3").replace(/#+( |)(.*)/gm, "**$2**");
+
+ let renderer = {};
+ renderer['strong'] = (text) => {
+ let start = -1;
+ // @ts-ignore
+ while (plain.replace(text, (_, offset) => { start = offset; return '\x00'.repeat(text.length); }) !== plain) {
+ start = -1;
+ plain = plain.replace(text, (_, offset) => { start = offset; return '\x00'.repeat(text.length); });
+
+ styles.push({
+ style: "BOLD",
+ start,
+ length: text.length
+ });
+
+ start = -1;
+ }
+ };
+ renderer['em'] = (text) => {
+ let start = -1;
+ // @ts-ignore
+ while (plain.replace(text, (_, offset) => { start = offset; return '\x00'.repeat(text.length); }) !== plain) {
+ start = -1;
+ plain = plain.replace(text, (_, offset) => { start = offset; return '\x00'.repeat(text.length); });
+
+ styles.push({
+ style: "ITALIC",
+ start,
+ length: text.length
+ });
+
+ start = -1;
+ }
+ };
+ renderer['codespan'] = renderer['code'] = (text) => {
+ let start = -1;
+ // @ts-ignore
+ while (plain.replace(text, (_, offset) => { start = offset; return '\x00'.repeat(text.length); }) !== plain) {
+ start = -1;
+ plain = plain.replace(text, (_, offset) => { start = offset; return '\x00'.repeat(text.length); });
+
+ styles.push({
+ style: "MONOSPACE",
+ start,
+ length: text.length
+ });
+
+ start = -1;
+ }
+ };
+ renderer['del'] = () => {
+ let start = -1;
+ // @ts-ignore
+ while (plain.replace(text, (_, offset) => { start = offset; return '\x00'.repeat(text.length); }) !== plain) {
+ start = -1;
+ plain = plain.replace(text, (_, offset) => { start = offset; return '\x00'.repeat(text.length); });
+
+ styles.push({
+ style: "STRIKETHROUGH",
+ start,
+ length: text.length
+ });
+
+ start = -1;
+ }
+ };
+
+ marked.use({
+ async: false,
+ mangle: false,
+ headerIds: false,
+ renderer
+ });
+
+ marked.parseInline(text);
+ styles = styles.filter(i => i.start !== -1);
+ return new MessageFormatting(plain, styles);
+ }
} \ No newline at end of file