142 lines
No EOL
3.6 KiB
JavaScript
Executable file
142 lines
No EOL
3.6 KiB
JavaScript
Executable file
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
|