Changeset View
Changeset View
Standalone View
Standalone View
lib/shared/markdown.js
Show First 20 Lines • Show All 251 Lines • ▼ Show 20 Lines | |||||
const spoilerRegex: RegExp = /^\|\|([^\n]+?)\|\|/g; | const spoilerRegex: RegExp = /^\|\|([^\n]+?)\|\|/g; | ||||
const replaceSpoilerRegex: RegExp = /\|\|(.+?)\|\|/g; | const replaceSpoilerRegex: RegExp = /\|\|(.+?)\|\|/g; | ||||
const spoilerReplacement: string = '⬛⬛⬛'; | const spoilerReplacement: string = '⬛⬛⬛'; | ||||
const stripSpoilersFromNotifications = (text: string): string => | const stripSpoilersFromNotifications = (text: string): string => | ||||
text.replace(replaceSpoilerRegex, spoilerReplacement); | text.replace(replaceSpoilerRegex, spoilerReplacement); | ||||
function stripSpoilersFromMarkdownAST(ast: SingleASTNode[]): SingleASTNode[] { | |||||
// Either takes top-level AST, or array of nodes under an items node (list) | |||||
return ast.map(replaceSpoilersFromMarkdownAST); | |||||
} | |||||
function replaceSpoilersFromMarkdownAST(node: SingleASTNode): SingleASTNode { | |||||
const { content, items, type } = node; | |||||
if (content && typeof content === 'string') { | |||||
// Base case (leaf node) | |||||
return node; | |||||
} else if (type === 'spoiler') { | |||||
// The actual point of this function: replacing the spoilers | |||||
return { | |||||
type: 'text', | |||||
content: spoilerReplacement, | |||||
}; | |||||
} else if (content) { | |||||
// Common case... most nodes nest children with content | |||||
// If content isn't a string, it should be an array | |||||
return { | |||||
...node, | |||||
content: stripSpoilersFromMarkdownAST(content), | |||||
}; | |||||
} else if (items) { | |||||
// Special case for lists, which has a nested array of arrays within items | |||||
return { | |||||
...node, | |||||
items: items.map(stripSpoilersFromMarkdownAST), | |||||
}; | |||||
} | |||||
throw new Error( | |||||
`unexpected Markdown node of type ${type} with no content or items`, | |||||
); | |||||
} | |||||
export { | export { | ||||
paragraphRegex, | paragraphRegex, | ||||
paragraphStripTrailingNewlineRegex, | paragraphStripTrailingNewlineRegex, | ||||
urlRegex, | urlRegex, | ||||
blockQuoteRegex, | blockQuoteRegex, | ||||
blockQuoteStripFollowingNewlineRegex, | blockQuoteStripFollowingNewlineRegex, | ||||
headingRegex, | headingRegex, | ||||
headingStripFollowingNewlineRegex, | headingStripFollowingNewlineRegex, | ||||
codeBlockRegex, | codeBlockRegex, | ||||
codeBlockStripTrailingNewlineRegex, | codeBlockStripTrailingNewlineRegex, | ||||
fenceRegex, | fenceRegex, | ||||
fenceStripTrailingNewlineRegex, | fenceStripTrailingNewlineRegex, | ||||
spoilerRegex, | spoilerRegex, | ||||
matchBlockQuote, | matchBlockQuote, | ||||
parseBlockQuote, | parseBlockQuote, | ||||
jsonMatch, | jsonMatch, | ||||
jsonPrint, | jsonPrint, | ||||
matchList, | matchList, | ||||
parseList, | parseList, | ||||
matchMentions, | matchMentions, | ||||
stripSpoilersFromNotifications, | stripSpoilersFromNotifications, | ||||
stripSpoilersFromMarkdownAST, | |||||
}; | }; |