transcriptify 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +78 -0
- package/dist/src/generateHtml.d.ts +3 -0
- package/dist/src/generateHtml.js +303 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.js +252 -0
- package/dist/src/transcript.d.ts +12 -0
- package/dist/src/transcript.js +179 -0
- package/dist/src/types/entities.d.ts +30 -0
- package/dist/src/types/entities.js +2 -0
- package/dist/src/utils/assetManager.d.ts +12 -0
- package/dist/src/utils/assetManager.js +295 -0
- package/dist/src/utils/authors.d.ts +4 -0
- package/dist/src/utils/authors.js +115 -0
- package/dist/src/utils/cache.d.ts +16 -0
- package/dist/src/utils/cache.js +29 -0
- package/dist/src/utils/extractors.d.ts +112 -0
- package/dist/src/utils/extractors.js +223 -0
- package/dist/src/utils/polls.d.ts +2 -0
- package/dist/src/utils/polls.js +91 -0
- package/dist/src/utils/transformer.d.ts +6 -0
- package/dist/src/utils/transformer.js +78 -0
- package/dist/src/utils/user.d.ts +4 -0
- package/dist/src/utils/user.js +56 -0
- package/dist/src/web/client.d.ts +20 -0
- package/dist/src/web/client.js +21 -0
- package/dist/src/web/discord-components/AudioPlayer.d.ts +5 -0
- package/dist/src/web/discord-components/AudioPlayer.js +231 -0
- package/dist/src/web/discord-components/Button.d.ts +3 -0
- package/dist/src/web/discord-components/Button.js +27 -0
- package/dist/src/web/discord-components/ChannelPinnedMessage.d.ts +7 -0
- package/dist/src/web/discord-components/ChannelPinnedMessage.js +11 -0
- package/dist/src/web/discord-components/DateSeperator.d.ts +3 -0
- package/dist/src/web/discord-components/DateSeperator.js +19 -0
- package/dist/src/web/discord-components/Embed.d.ts +2 -0
- package/dist/src/web/discord-components/Embed.js +78 -0
- package/dist/src/web/discord-components/ForwardedMessage.d.ts +2 -0
- package/dist/src/web/discord-components/ForwardedMessage.js +44 -0
- package/dist/src/web/discord-components/Message.d.ts +2 -0
- package/dist/src/web/discord-components/Message.js +543 -0
- package/dist/src/web/discord-components/PinnedMessagesModal.d.ts +6 -0
- package/dist/src/web/discord-components/PinnedMessagesModal.js +119 -0
- package/dist/src/web/discord-components/PinnedMessagesOverview.d.ts +5 -0
- package/dist/src/web/discord-components/PinnedMessagesOverview.js +22 -0
- package/dist/src/web/discord-components/Reply.d.ts +2 -0
- package/dist/src/web/discord-components/Reply.js +42 -0
- package/dist/src/web/discord-components/StickerPreview.d.ts +6 -0
- package/dist/src/web/discord-components/StickerPreview.js +40 -0
- package/dist/src/web/discord-components/ThemeSwitcher.d.ts +2 -0
- package/dist/src/web/discord-components/ThemeSwitcher.js +54 -0
- package/dist/src/web/discord-components/Transcript.d.ts +2 -0
- package/dist/src/web/discord-components/Transcript.js +174 -0
- package/dist/src/web/discord-components/UserJoinMessage.d.ts +3 -0
- package/dist/src/web/discord-components/UserJoinMessage.js +33 -0
- package/dist/src/web/discord-components/VideoPlayer.d.ts +6 -0
- package/dist/src/web/discord-components/VideoPlayer.js +222 -0
- package/dist/src/web/discord-components/icons/ChevronDownIcon.d.ts +1 -0
- package/dist/src/web/discord-components/icons/ChevronDownIcon.js +7 -0
- package/dist/src/web/discord-components/icons/CloseIcon.d.ts +1 -0
- package/dist/src/web/discord-components/icons/CloseIcon.js +7 -0
- package/dist/src/web/discord-components/icons/ExternalLinkIcon.d.ts +1 -0
- package/dist/src/web/discord-components/icons/ExternalLinkIcon.js +7 -0
- package/dist/src/web/discord-components/icons/FileAudioIcon.d.ts +1 -0
- package/dist/src/web/discord-components/icons/FileAudioIcon.js +7 -0
- package/dist/src/web/discord-components/icons/FileCodeIcon.d.ts +1 -0
- package/dist/src/web/discord-components/icons/FileCodeIcon.js +7 -0
- package/dist/src/web/discord-components/icons/FileDocumentIcon.d.ts +1 -0
- package/dist/src/web/discord-components/icons/FileDocumentIcon.js +7 -0
- package/dist/src/web/discord-components/icons/PinIcon.d.ts +1 -0
- package/dist/src/web/discord-components/icons/PinIcon.js +7 -0
- package/dist/src/web/discord-components/icons/VerifiedIcon.d.ts +1 -0
- package/dist/src/web/discord-components/icons/VerifiedIcon.js +7 -0
- package/dist/src/web/discord-components/index.d.ts +11 -0
- package/dist/src/web/discord-components/index.js +24 -0
- package/dist/src/web/discord-components/messageHelpers.d.ts +8 -0
- package/dist/src/web/discord-components/messageHelpers.js +72 -0
- package/dist/src/web/discord-components/themeColors.d.ts +9 -0
- package/dist/src/web/discord-components/themeColors.js +320 -0
- package/dist/src/web/discord-components/transcriptHelpers.d.ts +19 -0
- package/dist/src/web/discord-components/transcriptHelpers.js +120 -0
- package/dist/src/web/discord-components/types.d.ts +1 -0
- package/dist/src/web/discord-components/types.js +2 -0
- package/dist/src/web/discord-components/utils/date.d.ts +3 -0
- package/dist/src/web/discord-components/utils/date.js +50 -0
- package/dist/src/web/discord-components/utils/markdown.d.ts +11 -0
- package/dist/src/web/discord-components/utils/markdown.js +538 -0
- package/dist/src/web/discord-components/utils/markdownUtils.d.ts +12 -0
- package/dist/src/web/discord-components/utils/markdownUtils.js +140 -0
- package/dist/src/web/helpers/avatarHelpers.d.ts +2 -0
- package/dist/src/web/helpers/avatarHelpers.js +15 -0
- package/dist/src/web/helpers/cdnHelpers.d.ts +5 -0
- package/dist/src/web/helpers/cdnHelpers.js +48 -0
- package/dist/src/web/helpers/contentHelpers.d.ts +9 -0
- package/dist/src/web/helpers/contentHelpers.js +41 -0
- package/dist/src/web/helpers/renderContent.d.ts +2 -0
- package/dist/src/web/helpers/renderContent.js +15 -0
- package/dist/src/web/helpers/scrollHelpers.d.ts +2 -0
- package/dist/src/web/helpers/scrollHelpers.js +31 -0
- package/dist/src/web/helpers/timestampHelpers.d.ts +6 -0
- package/dist/src/web/helpers/timestampHelpers.js +66 -0
- package/dist/src/web/hooks/useMessageContent.d.ts +5 -0
- package/dist/src/web/hooks/useMessageContent.js +37 -0
- package/dist/src/web/index.d.ts +1 -0
- package/dist/src/web/index.js +17 -0
- package/dist/src/web/types/attachment.d.ts +6 -0
- package/dist/src/web/types/attachment.js +2 -0
- package/dist/src/web/types/author.d.ts +14 -0
- package/dist/src/web/types/author.js +2 -0
- package/dist/src/web/types/channel.d.ts +8 -0
- package/dist/src/web/types/channel.js +2 -0
- package/dist/src/web/types/embed.d.ts +52 -0
- package/dist/src/web/types/embed.js +2 -0
- package/dist/src/web/types/interaction.d.ts +8 -0
- package/dist/src/web/types/interaction.js +2 -0
- package/dist/src/web/types/markdown.d.ts +5 -0
- package/dist/src/web/types/markdown.js +2 -0
- package/dist/src/web/types/message.d.ts +73 -0
- package/dist/src/web/types/message.js +2 -0
- package/dist/src/web/types/poll.d.ts +11 -0
- package/dist/src/web/types/poll.js +2 -0
- package/dist/src/web/types/props.d.ts +155 -0
- package/dist/src/web/types/props.js +2 -0
- package/dist/src/web/types/reaction.d.ts +6 -0
- package/dist/src/web/types/reaction.js +2 -0
- package/dist/src/web/types/theme.d.ts +14 -0
- package/dist/src/web/types/theme.js +2 -0
- package/dist/src/web/types/ui.d.ts +10 -0
- package/dist/src/web/types/ui.js +2 -0
- package/dist/types/download.d.ts +12 -0
- package/dist/types/download.js +2 -0
- package/dist/types/exportableTranscript.d.ts +169 -0
- package/dist/types/exportableTranscript.js +2 -0
- package/dist/types/general.d.ts +90 -0
- package/dist/types/general.js +2 -0
- package/package.json +46 -0
|
@@ -0,0 +1,538 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseMarkdown = parseMarkdown;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_1 = __importDefault(require("react"));
|
|
9
|
+
const common_1 = __importDefault(require("highlight.js/lib/common"));
|
|
10
|
+
const cdnHelpers_1 = require("../../helpers/cdnHelpers");
|
|
11
|
+
const markdownUtils_1 = require("./markdownUtils");
|
|
12
|
+
let __parseMarkdownId = 0;
|
|
13
|
+
function normalizeCodeLang(lang) {
|
|
14
|
+
if (!lang)
|
|
15
|
+
return undefined;
|
|
16
|
+
const s = lang.toLowerCase();
|
|
17
|
+
if (s === "py")
|
|
18
|
+
return "python";
|
|
19
|
+
if (s === "js")
|
|
20
|
+
return "javascript";
|
|
21
|
+
if (s === "ts")
|
|
22
|
+
return "typescript";
|
|
23
|
+
if (s === "jsx")
|
|
24
|
+
return "javascript";
|
|
25
|
+
if (s === "tsx")
|
|
26
|
+
return "typescript";
|
|
27
|
+
return s;
|
|
28
|
+
}
|
|
29
|
+
function getHighlightedHtml(code, lang) {
|
|
30
|
+
const normalized = normalizeCodeLang(lang);
|
|
31
|
+
const useLang = normalized && common_1.default.getLanguage(normalized) ? normalized : undefined;
|
|
32
|
+
const result = useLang ? common_1.default.highlight(code, { language: useLang, ignoreIllegals: true }) : common_1.default.highlightAuto(code);
|
|
33
|
+
return result.value || (0, markdownUtils_1.escapeHtml)(code);
|
|
34
|
+
}
|
|
35
|
+
function Spoiler({ children }) {
|
|
36
|
+
const [revealed, setRevealed] = react_1.default.useState(false);
|
|
37
|
+
return ((0, jsx_runtime_1.jsx)("span", { className: "rounded px-0.5 cursor-pointer transition-colors", style: {
|
|
38
|
+
backgroundColor: revealed ? "#2b2d31" : "#202225",
|
|
39
|
+
color: revealed ? "#dcddde" : "transparent",
|
|
40
|
+
userSelect: revealed ? "text" : "none"
|
|
41
|
+
}, onClick: () => setRevealed(!revealed), title: revealed ? "Hide" : "Click to reveal spoiler", children: children }));
|
|
42
|
+
}
|
|
43
|
+
function renderTokens(tokens, keyBase = 0) {
|
|
44
|
+
const nodes = [];
|
|
45
|
+
tokens.forEach((t, i) => {
|
|
46
|
+
const key = `${keyBase}-${i}`;
|
|
47
|
+
const rawVal = t.value ?? "";
|
|
48
|
+
let v = "";
|
|
49
|
+
if (typeof rawVal === "string") {
|
|
50
|
+
v = rawVal;
|
|
51
|
+
}
|
|
52
|
+
else if (rawVal && typeof rawVal === "object") {
|
|
53
|
+
v = rawVal.name || rawVal.text || rawVal.value || "";
|
|
54
|
+
}
|
|
55
|
+
if (rawVal && typeof rawVal === "object" && Array.isArray(rawVal.tokens)) {
|
|
56
|
+
nodes.push((0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: renderTokens(rawVal.tokens, Number(`${keyBase}${i}`)) }, key));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
switch (t.type) {
|
|
60
|
+
case "text":
|
|
61
|
+
nodes.push(v);
|
|
62
|
+
break;
|
|
63
|
+
case "strike":
|
|
64
|
+
case "s":
|
|
65
|
+
case "strikethrough":
|
|
66
|
+
case "del":
|
|
67
|
+
case "deleted":
|
|
68
|
+
nodes.push((0, jsx_runtime_1.jsx)("s", { style: { textDecoration: "line-through", opacity: 0.8 }, children: v }, key));
|
|
69
|
+
break;
|
|
70
|
+
case "inlineCode":
|
|
71
|
+
nodes.push((0, jsx_runtime_1.jsx)("code", { className: "bg-[#1e1f22] text-[#dbdee1] px-1 rounded text-[0.875rem] font-mono", children: v }, key));
|
|
72
|
+
break;
|
|
73
|
+
case "spoiler":
|
|
74
|
+
nodes.push((0, jsx_runtime_1.jsx)(Spoiler, { children: v }, key));
|
|
75
|
+
break;
|
|
76
|
+
case "codeBlock": {
|
|
77
|
+
const lang = t.meta?.lang || undefined;
|
|
78
|
+
const codeContent = typeof rawVal === "string" ? rawVal : (rawVal && rawVal.raw) || "";
|
|
79
|
+
const langForHighlight = normalizeCodeLang(lang);
|
|
80
|
+
const highlighted = getHighlightedHtml(codeContent, langForHighlight);
|
|
81
|
+
nodes.push((0, jsx_runtime_1.jsxs)("div", { className: "relative my-2 rounded bg-[#2B2D31] border border-[#1E1F22]", children: [(0, jsx_runtime_1.jsx)("div", { className: "absolute top-1 right-2 px-2 py-0.5 text-xs text-[#B5BAC1]", children: lang || "code" }), (0, jsx_runtime_1.jsx)("pre", { className: "p-3 pt-6 text-sm overflow-x-auto text-[#DBDEE1]", children: (0, jsx_runtime_1.jsx)("code", { className: langForHighlight ? `language-${langForHighlight} hljs` : "hljs", dangerouslySetInnerHTML: { __html: highlighted } }) })] }, key));
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
default:
|
|
85
|
+
nodes.push(v);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
return nodes;
|
|
89
|
+
}
|
|
90
|
+
function parseMarkdown(text, resolvedUsers, resolvedRoles, resolvedChannels, currentGuildId) {
|
|
91
|
+
if (!text && text !== 0)
|
|
92
|
+
return null;
|
|
93
|
+
if (text && typeof text === "object" && Array.isArray(text.tokens)) {
|
|
94
|
+
const tokens = text.tokens;
|
|
95
|
+
const allTextOnly = tokens.every((t) => t.type === "text");
|
|
96
|
+
if (allTextOnly) {
|
|
97
|
+
return parseMarkdown(tokens.map((t) => t.value ?? "").join(""), resolvedUsers, resolvedRoles, resolvedChannels, currentGuildId);
|
|
98
|
+
}
|
|
99
|
+
return (0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: react_1.default.Children.toArray(renderTokens(tokens)) }, `pm-${++__parseMarkdownId}`);
|
|
100
|
+
}
|
|
101
|
+
let raw = typeof text === "string"
|
|
102
|
+
? text
|
|
103
|
+
: text && typeof text.raw === "string"
|
|
104
|
+
? text.raw
|
|
105
|
+
: text && typeof text.content === "string"
|
|
106
|
+
? text.content
|
|
107
|
+
: text && typeof text.text === "string"
|
|
108
|
+
? text.text
|
|
109
|
+
: typeof text === "number"
|
|
110
|
+
? String(text)
|
|
111
|
+
: "";
|
|
112
|
+
raw = raw.replace(/<@!?(\d+)>/g, (_match, id, offset, src) => {
|
|
113
|
+
const resolveUserName = (map, uid) => {
|
|
114
|
+
if (!map || !uid)
|
|
115
|
+
return null;
|
|
116
|
+
const direct = map[uid];
|
|
117
|
+
if (direct && (direct.displayName || direct.username))
|
|
118
|
+
return direct.displayName || direct.username || null;
|
|
119
|
+
const nId = Number(uid);
|
|
120
|
+
if (!Number.isNaN(nId)) {
|
|
121
|
+
for (const k of Object.keys(map)) {
|
|
122
|
+
if (Number(k) === nId) {
|
|
123
|
+
const v = map[k];
|
|
124
|
+
if (v && (v.displayName || v.username))
|
|
125
|
+
return v.displayName || v.username || null;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
for (const k of Object.keys(map)) {
|
|
130
|
+
if (String(k).trim() === String(uid).trim()) {
|
|
131
|
+
const v = map[k];
|
|
132
|
+
if (v && (v.displayName || v.username))
|
|
133
|
+
return v.displayName || v.username || null;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
};
|
|
138
|
+
const name = resolveUserName(resolvedUsers, id) || "unknown-user";
|
|
139
|
+
const safe = (0, markdownUtils_1.escapeHtml)(String(name));
|
|
140
|
+
const nextChar = src.charAt(offset + _match.length) || "";
|
|
141
|
+
const needsSpace = nextChar && !/\s/.test(nextChar);
|
|
142
|
+
return `<user>${safe}</user>${needsSpace ? " " : ""}`;
|
|
143
|
+
});
|
|
144
|
+
raw = raw.replace(/<@&(\d+)>/g, (_match, roleId) => {
|
|
145
|
+
const role = resolvedRoles?.[roleId];
|
|
146
|
+
if (role && role.name) {
|
|
147
|
+
return `<role${role.color && ` data-color="${role.color}"`}>${(0, markdownUtils_1.escapeHtml)(String(role.name))}</role>`;
|
|
148
|
+
}
|
|
149
|
+
return "unknown-role";
|
|
150
|
+
});
|
|
151
|
+
const resolveChannelName = (map, id) => {
|
|
152
|
+
if (!map || !id)
|
|
153
|
+
return null;
|
|
154
|
+
const direct = map[id];
|
|
155
|
+
if (direct && direct.name)
|
|
156
|
+
return direct.name;
|
|
157
|
+
const nId = Number(id);
|
|
158
|
+
if (!Number.isNaN(nId)) {
|
|
159
|
+
for (const k of Object.keys(map)) {
|
|
160
|
+
if (Number(k) === nId) {
|
|
161
|
+
const v = map[k];
|
|
162
|
+
if (v && v.name)
|
|
163
|
+
return v.name;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
for (const k of Object.keys(map)) {
|
|
168
|
+
if (String(k).trim() === String(id).trim()) {
|
|
169
|
+
const v = map[k];
|
|
170
|
+
if (v && v.name)
|
|
171
|
+
return v.name;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return null;
|
|
175
|
+
};
|
|
176
|
+
raw = raw.replace(/<#(\d+)>/g, (_match, channelId) => {
|
|
177
|
+
const name = resolveChannelName(resolvedChannels, channelId);
|
|
178
|
+
if (name)
|
|
179
|
+
return `<channel data-id="${channelId}">${(0, markdownUtils_1.escapeHtml)(String(name))}</channel>`;
|
|
180
|
+
return `<channel data-id="${channelId}">unknown</channel>`;
|
|
181
|
+
});
|
|
182
|
+
raw = raw.replace(/https:\/\/discord\.com\/channels\/(\d+)\/(\d+)(?:\/(\d+))?/g, (_match, _guildId, channelId) => {
|
|
183
|
+
const name = resolveChannelName(resolvedChannels, channelId);
|
|
184
|
+
if (name)
|
|
185
|
+
return `<channel data-id="${channelId}">${(0, markdownUtils_1.escapeHtml)(String(name))}</channel>`;
|
|
186
|
+
return `<channel data-id="${channelId}">unknown</channel>`;
|
|
187
|
+
});
|
|
188
|
+
raw = raw
|
|
189
|
+
.replace(/<br\s*\/?>(\r?\n)?/gi, "\n")
|
|
190
|
+
.replace(/<strong>([\s\S]*?)<\/strong>/gi, "**$1**")
|
|
191
|
+
.replace(/<b>([\s\S]*?)<\/b>/gi, "**$1**")
|
|
192
|
+
.replace(/<u>([\s\S]*?)<\/u>/gi, "__$1__")
|
|
193
|
+
.replace(/<em>([\s\S]*?)<\/em>/gi, "*$1*")
|
|
194
|
+
.replace(/<i>([\s\S]*?)<\/i>/gi, "*$1*")
|
|
195
|
+
.replace(/<s>([\s\S]*?)<\/s>/gi, "~~$1~~");
|
|
196
|
+
raw = raw.replace(/\\([*_~`\\_])/g, "$1");
|
|
197
|
+
const linesForIndentCalc = raw.split("\n");
|
|
198
|
+
let minIndent = null;
|
|
199
|
+
for (const l of linesForIndentCalc) {
|
|
200
|
+
if (!l.trim())
|
|
201
|
+
continue;
|
|
202
|
+
const m = l.match(/^\s*/);
|
|
203
|
+
const indent = m ? m[0].length : 0;
|
|
204
|
+
if (minIndent === null || indent < minIndent)
|
|
205
|
+
minIndent = indent;
|
|
206
|
+
}
|
|
207
|
+
if (minIndent && minIndent > 0) {
|
|
208
|
+
raw = linesForIndentCalc.map((l) => (l.startsWith(" ".repeat(minIndent)) ? l.slice(minIndent) : l)).join("\n");
|
|
209
|
+
}
|
|
210
|
+
const segments = (0, markdownUtils_1.splitFencedCodeBlocks)(raw);
|
|
211
|
+
const outputNodes = [];
|
|
212
|
+
const processTextSegment = (txt) => {
|
|
213
|
+
const lines = txt.split("\n");
|
|
214
|
+
const processedLines = [];
|
|
215
|
+
let quoteBuffer = [];
|
|
216
|
+
lines.forEach((line, idx) => {
|
|
217
|
+
const trimmedLine = line.trimStart();
|
|
218
|
+
const isQuote = trimmedLine.startsWith(">");
|
|
219
|
+
if (isQuote) {
|
|
220
|
+
const quoteLine = trimmedLine.replace(/^>\s?/, "");
|
|
221
|
+
quoteBuffer.push(quoteLine);
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
if (quoteBuffer.length > 0) {
|
|
225
|
+
processedLines.push((0, jsx_runtime_1.jsx)("div", { className: "my-1 pl-3 border-l-4 border-[#4e505880] text-[#dbdee1]", children: quoteBuffer.map((qLine, qIdx) => ((0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [processSimpleMarkdown(qLine, resolvedChannels), qIdx < quoteBuffer.length - 1 ? (0, jsx_runtime_1.jsx)("br", {}) : null] }, qIdx))) }, `quote-${idx}`));
|
|
226
|
+
quoteBuffer = [];
|
|
227
|
+
}
|
|
228
|
+
const headingMatch = trimmedLine.match(/^(#{1,6})\s+(.+)$/);
|
|
229
|
+
if (headingMatch) {
|
|
230
|
+
const level = headingMatch[1].length;
|
|
231
|
+
const text = headingMatch[2];
|
|
232
|
+
const HeadingTag = `h${level}`;
|
|
233
|
+
processedLines.push((0, jsx_runtime_1.jsx)(HeadingTag, { style: { fontWeight: 600, margin: "0.5rem 0" }, children: processSimpleMarkdown(text, resolvedChannels) }, idx));
|
|
234
|
+
}
|
|
235
|
+
else if (trimmedLine.startsWith("-#")) {
|
|
236
|
+
let text = trimmedLine.slice(2);
|
|
237
|
+
if (text.startsWith(" "))
|
|
238
|
+
text = text.slice(1);
|
|
239
|
+
const inner = processSimpleMarkdown(text, resolvedChannels);
|
|
240
|
+
const smallContent = scaleImagesInNode(inner, true);
|
|
241
|
+
processedLines.push((0, jsx_runtime_1.jsx)("small", { style: { fontSize: "0.875rem", opacity: 0.8 }, children: (0, jsx_runtime_1.jsx)("span", { children: smallContent }) }, idx));
|
|
242
|
+
if (idx < lines.length - 1)
|
|
243
|
+
processedLines.push((0, jsx_runtime_1.jsx)("br", {}, `br-${idx}`));
|
|
244
|
+
}
|
|
245
|
+
else if (trimmedLine.startsWith("- ")) {
|
|
246
|
+
const text = trimmedLine.slice(2);
|
|
247
|
+
processedLines.push((0, jsx_runtime_1.jsx)("li", { style: { marginLeft: "1.5rem" }, children: processSimpleMarkdown(text, resolvedChannels) }, idx));
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
processedLines.push((0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [processSimpleMarkdown(line, resolvedChannels), idx < lines.length - 1 ? (0, jsx_runtime_1.jsx)("br", {}) : null] }, idx));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
if (quoteBuffer.length > 0) {
|
|
255
|
+
processedLines.push((0, jsx_runtime_1.jsx)("div", { className: "my-1 pl-3 border-l-4 border-[#4e505880] text-[#dbdee1]", children: quoteBuffer.map((qLine, qIdx) => ((0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [processSimpleMarkdown(qLine, resolvedChannels), qIdx < quoteBuffer.length - 1 ? (0, jsx_runtime_1.jsx)("br", {}) : null] }, qIdx))) }, "quote-end"));
|
|
256
|
+
}
|
|
257
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: react_1.default.Children.toArray(processedLines) });
|
|
258
|
+
};
|
|
259
|
+
segments.forEach((seg, sIdx) => {
|
|
260
|
+
if (seg.type === "text") {
|
|
261
|
+
outputNodes.push((0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: processTextSegment(seg.value) }, `seg-${sIdx}`));
|
|
262
|
+
}
|
|
263
|
+
else if (seg.type === "code") {
|
|
264
|
+
const lang = seg.lang;
|
|
265
|
+
const code = seg.value || "";
|
|
266
|
+
const codeText = code || "";
|
|
267
|
+
const detectedLang = (lang || "").toLowerCase();
|
|
268
|
+
const langForHighlight = normalizeCodeLang(detectedLang);
|
|
269
|
+
const highlighted = getHighlightedHtml(codeText, langForHighlight);
|
|
270
|
+
outputNodes.push((0, jsx_runtime_1.jsxs)("div", { className: "relative my-2 rounded bg-[#2B2D31] border border-[#1E1F22]", children: [(0, jsx_runtime_1.jsx)("div", { className: "absolute top-1 right-2 px-2 py-0.5 text-xs text-[#B5BAC1]", children: lang || "code" }), (0, jsx_runtime_1.jsx)("pre", { className: "p-3 pt-6 text-sm overflow-x-auto text-[#DBDEE1]", children: (0, jsx_runtime_1.jsx)("code", { className: langForHighlight ? `language-${langForHighlight} hljs` : "hljs", dangerouslySetInnerHTML: { __html: highlighted } }) })] }, `code-${sIdx}`));
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
return (0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: react_1.default.Children.toArray(outputNodes) }, `pm-${++__parseMarkdownId}`);
|
|
274
|
+
}
|
|
275
|
+
function processSimpleMarkdown(line, resolvedChannels) {
|
|
276
|
+
const timestampMatches = [];
|
|
277
|
+
const processed = line.replace(/<t:(\d+)(?::([tTdDfFR]))?>/g, (match, timestamp, style) => {
|
|
278
|
+
const placeholder = `__TIMESTAMP_${timestampMatches.length}__`;
|
|
279
|
+
timestampMatches.push({ timestamp, style: style || "f", formatted: (0, markdownUtils_1.parseDiscordTimestamp)(parseInt(timestamp, 10), style || "f") });
|
|
280
|
+
return placeholder;
|
|
281
|
+
});
|
|
282
|
+
const regex = /(`[^`]+`)|(\|\|([^|]+)\|\|)|(~~(.+?)~~)|(\*\*\*(.+?)\*\*\*)|(\*\*(.+?)\*\*)|(__TIMESTAMP_(\d+)__)|(__([\s\S]+?)__)|\*(.+?)\*|(<\/([A-Za-z0-9_-]+):(\d+)>)|(<user>[^<]+<\/user>)|(<role[^>]*>[^<]+<\/role>)|(<channel[^>]*>[^<]+<\/channel>)/g;
|
|
283
|
+
let lastIndex = 0;
|
|
284
|
+
let match;
|
|
285
|
+
const parts = [];
|
|
286
|
+
while ((match = regex.exec(processed)) !== null) {
|
|
287
|
+
if (match.index > lastIndex)
|
|
288
|
+
parts.push((0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: processLinks(processed.substring(lastIndex, match.index)) }, `text-${lastIndex}`));
|
|
289
|
+
if (match[1]) {
|
|
290
|
+
const code = match[1].slice(1, -1);
|
|
291
|
+
parts.push((0, jsx_runtime_1.jsx)("code", { className: "bg-[#1e1f22] text-[#dbdee1] px-1 rounded text-[0.875rem] font-mono", children: code }, match.index));
|
|
292
|
+
}
|
|
293
|
+
else if (match[2]) {
|
|
294
|
+
const text = match[3];
|
|
295
|
+
parts.push((0, jsx_runtime_1.jsx)(Spoiler, { children: parseInline(text) }, match.index));
|
|
296
|
+
}
|
|
297
|
+
else if (match[4]) {
|
|
298
|
+
const text = match[5];
|
|
299
|
+
parts.push((0, jsx_runtime_1.jsx)("s", { style: { textDecoration: "line-through", opacity: 0.8 }, children: parseInline(text) }, match.index));
|
|
300
|
+
}
|
|
301
|
+
else if (match[6]) {
|
|
302
|
+
const text = match[7];
|
|
303
|
+
parts.push((0, jsx_runtime_1.jsx)("strong", { style: { fontWeight: 600 }, children: (0, jsx_runtime_1.jsx)("em", { style: { fontStyle: "italic" }, children: parseInline(text) }) }, match.index));
|
|
304
|
+
}
|
|
305
|
+
else if (match[8]) {
|
|
306
|
+
const text = match[9];
|
|
307
|
+
parts.push((0, jsx_runtime_1.jsx)("strong", { style: { fontWeight: 600 }, children: parseInline(text) }, match.index));
|
|
308
|
+
}
|
|
309
|
+
else if (match[10]) {
|
|
310
|
+
const idx = parseInt(match[11], 10);
|
|
311
|
+
const { formatted } = timestampMatches[idx];
|
|
312
|
+
parts.push((0, jsx_runtime_1.jsx)("span", { className: "bg-[#5865f21a] text-[#00a8fc] px-0.5 rounded cursor-default", title: formatted, children: formatted }, match.index));
|
|
313
|
+
}
|
|
314
|
+
else if (match[12]) {
|
|
315
|
+
const text = match[13];
|
|
316
|
+
parts.push((0, jsx_runtime_1.jsx)("u", { style: { textDecoration: "underline", textDecorationThickness: "1px" }, children: parseInline(text) }, match.index));
|
|
317
|
+
}
|
|
318
|
+
else if (match[14]) {
|
|
319
|
+
const text = match[14].slice(1, -1);
|
|
320
|
+
parts.push((0, jsx_runtime_1.jsx)("em", { style: { fontStyle: "italic" }, children: parseInline(text) }, match.index));
|
|
321
|
+
}
|
|
322
|
+
else if (match[15]) {
|
|
323
|
+
const commandName = match[16];
|
|
324
|
+
parts.push((0, jsx_runtime_1.jsx)("span", { className: "inline-flex items-center rounded px-2 py-0.5 text-sm font-medium mr-1", style: { backgroundColor: "#1d193f", color: "#9697ec" }, children: `/${commandName}` }, match.index));
|
|
325
|
+
}
|
|
326
|
+
else if (match[18]) {
|
|
327
|
+
const userTag = match[18];
|
|
328
|
+
let userName = userTag.replace(/<\/?user>/g, "");
|
|
329
|
+
userName = String(userName).replace(/\s+/g, " ").trim();
|
|
330
|
+
const display = `@${userName}`;
|
|
331
|
+
parts.push((0, jsx_runtime_1.jsx)("span", { className: "bg-[#5865f233] text-[#c9d1ff] px-0.5 rounded cursor-pointer hover:bg-[#5865f24d] transition-colors", style: { fontWeight: 500 }, children: display }, match.index));
|
|
332
|
+
try {
|
|
333
|
+
const nextChar = processed.charAt(regex.lastIndex) || "";
|
|
334
|
+
if (nextChar && !/\s/.test(nextChar)) {
|
|
335
|
+
parts.push((0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: " " }, `sp-${match.index}`));
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
catch (_) { }
|
|
339
|
+
}
|
|
340
|
+
else if (match[19]) {
|
|
341
|
+
const roleTag = match[19];
|
|
342
|
+
const colorMatch = roleTag.match(/data-color="([^"]+)"/);
|
|
343
|
+
const roleName = roleTag.replace(/<role[^>]*>|<\/role>/g, "");
|
|
344
|
+
if (colorMatch) {
|
|
345
|
+
const rawColor = colorMatch[1];
|
|
346
|
+
let colorInt = 0;
|
|
347
|
+
if (/^#?[0-9a-fA-F]{6}$/.test(rawColor)) {
|
|
348
|
+
colorInt = parseInt(rawColor.replace("#", ""), 16);
|
|
349
|
+
}
|
|
350
|
+
else if (/^0x[0-9a-fA-F]+$/.test(rawColor)) {
|
|
351
|
+
colorInt = parseInt(rawColor.replace("0x", ""), 16);
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
colorInt = parseInt(rawColor, 10) || 0;
|
|
355
|
+
}
|
|
356
|
+
const r = (colorInt >> 16) & 0xff;
|
|
357
|
+
const g = (colorInt >> 8) & 0xff;
|
|
358
|
+
const b = colorInt & 0xff;
|
|
359
|
+
const textColor = `rgb(${r}, ${g}, ${b})`;
|
|
360
|
+
const bgColor = `rgba(${r}, ${g}, ${b}, 0.12)`;
|
|
361
|
+
parts.push((0, jsx_runtime_1.jsx)("span", { className: "px-0.5 rounded cursor-pointer transition-opacity hover:opacity-80", style: { color: textColor, backgroundColor: bgColor, fontWeight: 500 }, children: `@${roleName}` }, match.index));
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
parts.push((0, jsx_runtime_1.jsx)("span", { children: `@${roleName}` }, match.index));
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
else if (match[20]) {
|
|
368
|
+
const channelTag = match[20];
|
|
369
|
+
const idMatch = channelTag.match(/data-id=\"([^\"]+)\"/);
|
|
370
|
+
const channelIdAttr = idMatch ? idMatch[1] : undefined;
|
|
371
|
+
const innerText = channelTag.replace(/<channel[^>]*>|<\/channel>/g, "");
|
|
372
|
+
let displayName = innerText;
|
|
373
|
+
if (channelIdAttr) {
|
|
374
|
+
const resolved = (0, markdownUtils_1.resolveChannelNameGlobal)(resolvedChannels, channelIdAttr);
|
|
375
|
+
if (resolved)
|
|
376
|
+
displayName = `#${resolved}`;
|
|
377
|
+
}
|
|
378
|
+
parts.push((0, jsx_runtime_1.jsx)("span", { className: "bg-[#5865f21a] text-[#00a8fc] px-0.5 rounded cursor-pointer hover:bg-[#5865f233] transition-colors", style: { fontWeight: 500 }, "data-channel-id": channelIdAttr, children: displayName }, match.index));
|
|
379
|
+
}
|
|
380
|
+
lastIndex = regex.lastIndex;
|
|
381
|
+
}
|
|
382
|
+
if (lastIndex < processed.length)
|
|
383
|
+
parts.push((0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: processLinks(processed.substring(lastIndex)) }, `text-${lastIndex}`));
|
|
384
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: react_1.default.Children.toArray(parts) });
|
|
385
|
+
}
|
|
386
|
+
function processLinks(str) {
|
|
387
|
+
const mdRegex = /\[([^\]]+)\]\(\s*(?:<\s*(https?:\/\/[^>\s]+)\s*>|(https?:\/\/[^\s)]+))\s*\)/g;
|
|
388
|
+
const segments = [];
|
|
389
|
+
let lastIdx = 0;
|
|
390
|
+
let mdMatch;
|
|
391
|
+
while ((mdMatch = mdRegex.exec(str)) !== null) {
|
|
392
|
+
if (mdMatch.index > lastIdx) {
|
|
393
|
+
segments.push((0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: processBareLinks(str.substring(lastIdx, mdMatch.index)) }, `seg-${lastIdx}`));
|
|
394
|
+
}
|
|
395
|
+
const label = mdMatch[1];
|
|
396
|
+
const url = (mdMatch[2] || mdMatch[3]);
|
|
397
|
+
if (!url || !/^https?:\/\//i.test(url)) {
|
|
398
|
+
segments.push((0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: label }, `mdlink-${mdMatch.index}`));
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
segments.push((0, jsx_runtime_1.jsx)("a", { href: url, style: { color: "blue" }, target: "_blank", rel: "noreferrer", children: label }, `mdlink-${mdMatch.index}`));
|
|
402
|
+
}
|
|
403
|
+
lastIdx = mdRegex.lastIndex;
|
|
404
|
+
}
|
|
405
|
+
if (lastIdx < str.length) {
|
|
406
|
+
segments.push((0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: processBareLinks(str.substring(lastIdx)) }, `seg-${lastIdx}`));
|
|
407
|
+
}
|
|
408
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: react_1.default.Children.toArray(segments) });
|
|
409
|
+
}
|
|
410
|
+
function processBareLinks(str) {
|
|
411
|
+
const urlRegex = /<\s*(https?:\/\/[^>\s]+)\s*>|(https?:\/\/[^\s)]+)/g;
|
|
412
|
+
const parts = [];
|
|
413
|
+
let last = 0;
|
|
414
|
+
let match;
|
|
415
|
+
while ((match = urlRegex.exec(str)) !== null) {
|
|
416
|
+
if (match.index > last)
|
|
417
|
+
parts.push((0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: str.substring(last, match.index) }, `text-${last}`));
|
|
418
|
+
const url = (match[1] || match[2]);
|
|
419
|
+
const isSticker = /\/stickers\/\d+\.webp(\?.*)?$/i.test(url) || url.includes("/stickers/");
|
|
420
|
+
if (isSticker) {
|
|
421
|
+
parts.push((0, jsx_runtime_1.jsx)("img", { src: url, alt: "sticker", className: "inline h-10 w-10 align-text-bottom mr-0.5" }, `sticker-${match.index}`));
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
parts.push((0, jsx_runtime_1.jsx)("a", { href: url, style: { color: "blue" }, target: "_blank", rel: "noreferrer", children: url }, `u-${match.index}`));
|
|
425
|
+
}
|
|
426
|
+
last = urlRegex.lastIndex;
|
|
427
|
+
}
|
|
428
|
+
if (last < str.length)
|
|
429
|
+
parts.push((0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: str.substring(last) }, `text-${last}`));
|
|
430
|
+
const rendered = parts.map((p, i) => {
|
|
431
|
+
if (typeof p === "string") {
|
|
432
|
+
return (0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: processEmojis(p) }, `emoji-${i}`);
|
|
433
|
+
}
|
|
434
|
+
if (react_1.default.isValidElement(p) && p.props && typeof p.props.children === "string") {
|
|
435
|
+
return (0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: processEmojis(p.props.children) }, `emoji-frag-${i}`);
|
|
436
|
+
}
|
|
437
|
+
return p;
|
|
438
|
+
});
|
|
439
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: react_1.default.Children.toArray(rendered) });
|
|
440
|
+
}
|
|
441
|
+
function processEmojis(str) {
|
|
442
|
+
const nodes = [];
|
|
443
|
+
const emojiRegex = /<(a)?:([^:>]+):(\d+)>/g;
|
|
444
|
+
let last = 0;
|
|
445
|
+
let m;
|
|
446
|
+
while ((m = emojiRegex.exec(str)) !== null) {
|
|
447
|
+
if (m.index > last)
|
|
448
|
+
nodes.push(str.substring(last, m.index));
|
|
449
|
+
const animated = !!m[1];
|
|
450
|
+
const name = m[2];
|
|
451
|
+
const id = m[3];
|
|
452
|
+
const src = (0, cdnHelpers_1.buildEmojiCdnUrl)(id, animated, 96) || "";
|
|
453
|
+
if (src) {
|
|
454
|
+
nodes.push((0, jsx_runtime_1.jsx)("img", { src: src, alt: name, className: "inline h-5 w-5 align-text-bottom mr-0.5" }, `e-${id}-${m.index}`));
|
|
455
|
+
}
|
|
456
|
+
last = emojiRegex.lastIndex;
|
|
457
|
+
}
|
|
458
|
+
if (last < str.length)
|
|
459
|
+
nodes.push(str.substring(last));
|
|
460
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: react_1.default.Children.toArray(nodes) });
|
|
461
|
+
}
|
|
462
|
+
function scaleImagesInNode(node, small) {
|
|
463
|
+
if (!small)
|
|
464
|
+
return node;
|
|
465
|
+
if (node === null || node === undefined)
|
|
466
|
+
return node;
|
|
467
|
+
if (typeof node === "string" || typeof node === "number")
|
|
468
|
+
return node;
|
|
469
|
+
if (Array.isArray(node)) {
|
|
470
|
+
const mapped = node.map((n, i) => {
|
|
471
|
+
const scaled = scaleImagesInNode(n, small);
|
|
472
|
+
if (Array.isArray(scaled)) {
|
|
473
|
+
return react_1.default.Children.toArray(scaled).map((c, j) => react_1.default.isValidElement(c) ? react_1.default.cloneElement(c, { key: `si-${i}-${j}` }) : react_1.default.createElement(react_1.default.Fragment, { key: `si-${i}-${j}` }, c));
|
|
474
|
+
}
|
|
475
|
+
if (react_1.default.isValidElement(scaled)) {
|
|
476
|
+
if (scaled.key == null)
|
|
477
|
+
return react_1.default.cloneElement(scaled, { key: `si-${i}` });
|
|
478
|
+
return scaled;
|
|
479
|
+
}
|
|
480
|
+
return react_1.default.createElement(react_1.default.Fragment, { key: `si-txt-${i}` }, scaled);
|
|
481
|
+
});
|
|
482
|
+
return react_1.default.Children.toArray(mapped.flat());
|
|
483
|
+
}
|
|
484
|
+
if (react_1.default.isValidElement(node)) {
|
|
485
|
+
const el = node;
|
|
486
|
+
const props = el.props || {};
|
|
487
|
+
const children = props.children;
|
|
488
|
+
const newChildren = scaleImagesInNode(children, small);
|
|
489
|
+
if (el.type === react_1.default.Fragment) {
|
|
490
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: newChildren });
|
|
491
|
+
}
|
|
492
|
+
const isImageLike = el.type === "img" || (props && typeof props.src === "string");
|
|
493
|
+
if (isImageLike) {
|
|
494
|
+
const newStyle = Object.assign({}, props.style || {}, { height: "0.875rem", width: "0.875rem" });
|
|
495
|
+
return react_1.default.cloneElement(el, Object.assign({}, props, { style: newStyle }));
|
|
496
|
+
}
|
|
497
|
+
return react_1.default.cloneElement(el, Object.assign({}, props), newChildren);
|
|
498
|
+
}
|
|
499
|
+
return node;
|
|
500
|
+
}
|
|
501
|
+
function parseInline(text) {
|
|
502
|
+
const nodes = [];
|
|
503
|
+
const regex = /(~~([\s\S]+?)~~)|(\*\*__|__\*\*)([\s\S]+?)(__\*\*|\*\*__)|__([\s\S]+?)__|(\*\*\*([\s\S]+?)\*\*\*)|(\*\*(.+?)\*\*)|(\*([^*]+)\*)/g;
|
|
504
|
+
let lastIndex = 0;
|
|
505
|
+
let m;
|
|
506
|
+
while ((m = regex.exec(text)) !== null) {
|
|
507
|
+
if (m.index > lastIndex)
|
|
508
|
+
nodes.push((0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: processLinks(text.substring(lastIndex, m.index)) }, `link-${lastIndex}`));
|
|
509
|
+
if (m[1]) {
|
|
510
|
+
// ~~strike~~
|
|
511
|
+
nodes.push((0, jsx_runtime_1.jsx)("s", { style: { textDecoration: "line-through", opacity: 0.8 }, children: parseInline(m[2]) }, `st-${m.index}`));
|
|
512
|
+
}
|
|
513
|
+
else if (m[3]) {
|
|
514
|
+
// **__bold+underline__** or __**__ combo
|
|
515
|
+
nodes.push((0, jsx_runtime_1.jsx)("strong", { style: { fontWeight: 600 }, children: (0, jsx_runtime_1.jsx)("u", { style: { textDecoration: "underline" }, children: processLinks(m[4]) }) }, `bu-${m.index}`));
|
|
516
|
+
}
|
|
517
|
+
else if (m[6]) {
|
|
518
|
+
// __underline__
|
|
519
|
+
nodes.push((0, jsx_runtime_1.jsx)("u", { style: { textDecoration: "underline", textDecorationThickness: "1px" }, children: processLinks(m[6]) }, `u-${m.index}`));
|
|
520
|
+
}
|
|
521
|
+
else if (m[7]) {
|
|
522
|
+
// ***bold italic***
|
|
523
|
+
nodes.push((0, jsx_runtime_1.jsx)("strong", { style: { fontWeight: 600 }, children: (0, jsx_runtime_1.jsx)("em", { children: processLinks(m[8]) }) }, `bui-${m.index}`));
|
|
524
|
+
}
|
|
525
|
+
else if (m[9]) {
|
|
526
|
+
// **bold**
|
|
527
|
+
nodes.push((0, jsx_runtime_1.jsx)("strong", { style: { fontWeight: 600 }, children: processLinks(m[10]) }, `b-${m.index}`));
|
|
528
|
+
}
|
|
529
|
+
else if (m[11]) {
|
|
530
|
+
// *italic*
|
|
531
|
+
nodes.push((0, jsx_runtime_1.jsx)("em", { style: { fontStyle: "italic" }, children: processLinks(m[12]) }, `i-${m.index}`));
|
|
532
|
+
}
|
|
533
|
+
lastIndex = regex.lastIndex;
|
|
534
|
+
}
|
|
535
|
+
if (lastIndex < text.length)
|
|
536
|
+
nodes.push((0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: processLinks(text.substring(lastIndex)) }, `link-${lastIndex}`));
|
|
537
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: react_1.default.Children.toArray(nodes) });
|
|
538
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare function parseDiscordTimestamp(unixTimestamp: number, style?: string): string;
|
|
2
|
+
export declare function formatRelativeTime(date: Date): string;
|
|
3
|
+
export declare function escapeHtml(s: string): string;
|
|
4
|
+
export declare function splitFencedCodeBlocks(input: string): Array<{
|
|
5
|
+
type: "text" | "code";
|
|
6
|
+
value: string;
|
|
7
|
+
lang?: string;
|
|
8
|
+
}>;
|
|
9
|
+
export declare const resolveChannelNameGlobal: (map?: Record<string, {
|
|
10
|
+
name?: string | null;
|
|
11
|
+
guildId?: string | null;
|
|
12
|
+
}>, id?: string) => string | null;
|