import IntlMessageFormat from 'intl-messageformat'; import SimpleMarkdown from 'simple-markdown'; const FORMAT_RE = /\{.+?}/; const MARKDOWN_RE = /[~*_]{2}.+?[~*_]{2}|\[.+?]\(.+?\)|\n\n/; const UNSAFE_RE = /!!/; const UNSAFE_RE_ALL = /!!/g; let updateRules = rules => rules; if (__IOS__) { updateRules = require('./updateRules.ios'); } else if (__WEB__ && !__SDK__) { updateRules = require('./updateRules.web'); } function parserFor(rules) { const parser = SimpleMarkdown.parserFor(updateRules(rules)); const output = SimpleMarkdown.reactFor(SimpleMarkdown.ruleOutput(rules, 'react')); return function(str, context, unsafeContext) { const inline = str.indexOf('\n\n') === -1; if (!inline) { str += '\n\n'; } return output(parser(str, {inline, context, unsafeContext})); }; } function parserForNonReact(rules) { const parser = SimpleMarkdown.parserFor(rules); return function(str, context, unsafeContext) { return parser(str + '\n\n', {inline: false, context, unsafeContext}); }; } const linkRule = SimpleMarkdown.defaultRules.link; const rules = { newline: SimpleMarkdown.defaultRules.newline, paragraph: SimpleMarkdown.defaultRules.paragraph, url: SimpleMarkdown.defaultRules.url, link: { ...linkRule, parse(capture, parse, state) { const node = linkRule.parse(capture, parse, state); node.context = state.context; return node; } }, strong: SimpleMarkdown.defaultRules.strong, u: SimpleMarkdown.defaultRules.u, br: SimpleMarkdown.defaultRules.br, em: SimpleMarkdown.defaultRules.em, hook: { order: SimpleMarkdown.defaultRules.text.order, match: SimpleMarkdown.inlineRegex(/^\$\[(.*?)\]\((\w+)\)/), parse(capture, parse, state) { const {context} = state; return { render: context[capture[2]], content: parse(capture[1], state) }; }, react(node, output, state) { return node.render(output(node.content, state), state.key); } }, noparse: { order: SimpleMarkdown.defaultRules.text.order, match: SimpleMarkdown.inlineRegex(/^!!(\d+?)!!/), parse(capture, parse, {unsafeContext}) { return { type: 'text', content: unsafeContext[capture[1]] }; }, react(node) { return node.content; } }, text: SimpleMarkdown.defaultRules.text }; const parse = parserFor(rules); const parseForNonReact = parserForNonReact(rules); function getMessage(str, locale) { if (str == null) { return str; } str = str.replace(/^\n+|\n+$/g, ''); const hasMarkdown = MARKDOWN_RE.test(str); if (FORMAT_RE.test(str) || hasMarkdown) { if (!hasMarkdown) { str = str.replace(UNSAFE_RE_ALL, ''); } const intlMessage = new IntlMessageFormat(str, locale); if (hasMarkdown) { const originalFormat = intlMessage.format; const unsafe = UNSAFE_RE.test(str); intlMessage.format = (context={}, react=true) => { const unsafeContext = {}; if (unsafe) { let i = 0; for (const key of Object.keys(context)) { const value = context[key]; if (typeof value === 'string') { unsafeContext[++i] = value; context[key] = i; } } } if (!react) { return parseForNonReact(originalFormat(context), context, unsafeContext); } return parse(originalFormat(context), context, unsafeContext); }; intlMessage.plainFormat = originalFormat; } return intlMessage; } return str; } export default { getMessage }; // WEBPACK FOOTER // // ./discord_common/js/i18n/parse.js