12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- const { mo, po } = require('gettext-parser')
- const getPluralFunction = require('./plural-forms')
- const defaultOptions = {
- defaultCharset: null,
- forceContext: false,
- pluralFunction: null,
- pluralVariablePattern: /%(?:\((\w+)\))?\w/,
- replacements: [
- {
- pattern: /[\\{}#]/g,
- replacement: '\\$&'
- },
- {
- pattern: /%(\d+)(?:\$\w)?/g,
- replacement: (_, n) => `{${n - 1}}`
- },
- {
- pattern: /%\((\w+)\)\w/g,
- replacement: '{$1}'
- },
- {
- pattern: /%\w/g,
- replacement: function () { return `{${this.n++}}` },
- state: { n: 0 }
- },
- {
- pattern: /%%/g,
- replacement: '%'
- }
- ],
- verbose: false
- }
- const getMessageFormat = (
- { pluralFunction, pluralVariablePattern, replacements, verbose },
- { msgid, msgid_plural, msgstr }
- ) => {
- if (!msgid || !msgstr) return null
- if (!msgstr[0]) {
- if (verbose) console.warn('Translation not found:', msgid)
- msgstr[0] = msgid
- }
- if (msgid_plural) {
- if (!pluralFunction) throw new Error('Plural-Forms not defined')
- for (let i = 1; i < pluralFunction.cardinal.length; ++i) {
- if (!msgstr[i]) {
- if (verbose) console.warn('Plural translation not found:', msgid, i)
- msgstr[i] = msgid_plural
- }
- }
- }
- msgstr = msgstr.map(str => (
- replacements.reduce((str, { pattern, replacement, state }) => {
- if (state) replacement = replacement.bind(Object.assign({}, state))
- return str.replace(pattern, replacement)
- }, str)
- ))
- if (msgid_plural) {
- const m = msgid_plural.match(pluralVariablePattern)
- const pv = m && m[1] || '0'
- const pc = pluralFunction.cardinal.map((c, i) => `${c}{${msgstr[i]}}`)
- return `{${pv}, plural, ${pc.join(' ')}}`
- }
- return msgstr[0]
- }
- const convert = (parse, input, options) => {
- options = Object.assign({}, defaultOptions, options)
- const { headers, translations } = parse(input, options.defaultCharset)
- if (!options.pluralFunction) {
- options.pluralFunction = getPluralFunction(headers['plural-forms'])
- }
- let hasContext = false
- for (const context in translations) {
- if (context) hasContext = true
- const data = translations[context]
- for (const id in data) {
- const mf = getMessageFormat(options, data[id])
- if (mf) data[id] = mf
- else delete data[id]
- }
- }
- return {
- headers,
- pluralFunction: options.pluralFunction,
- translations: hasContext || options.forceContext ? translations : translations['']
- }
- }
- module.exports = {
- parseMo: (input, options) => convert(mo.parse, input, options),
- parsePo: (input, options) => convert(po.parse, input, options)
- }
|