UNPKG

plural-rules

Version:

Evaluates plural rules, so that localization libraries can choose the right plural form.

104 lines (92 loc) 3.36 kB
import { createRequire } from 'module' import { readFileSync } from 'fs' import { writeFile } from 'fs/promises' import { packPluralForms } from './data-packer.js' import { unpackPluralForms } from './data-unpacker.js' const require = createRequire(import.meta.url) const originalPluralData = JSON.parse(readFileSync(require.resolve('cldr-data/supplemental/plurals.json'), 'utf8')) function normalizeLocale (locale) { return locale.toLowerCase().replace('_', '-') } function getLanguage (locale) { const separator = locale.indexOf('-') return separator > 0 && locale.substr(0, separator) } function isRequestedLocale (availableLocale, locales, languages) { if (!locales.length) { return true } availableLocale = normalizeLocale(availableLocale) // Look either fr the requested locale, or only for the language. return locales.includes(availableLocale) || languages.includes(availableLocale) } function transformData (data, options) { let { locales = [], packed, includeVersion } = options const supplemental = data.supplemental const transformForms = packed ? packPluralForms : unpackPluralForms locales = locales.map(normalizeLocale) const languages = locales.map(getLanguage) // Collect unique plural rules. let rules = [] // Rename the key "plurals-type-cardinal" to "pluralCardinals". const originalForms = supplemental['plurals-type-cardinal'] const cardinals = Object .keys(originalForms) .filter(locale => isRequestedLocale(locale, locales, languages)) .reduce((result, locale) => { // Pack plural forms and rules for the specific locale. const forms = originalForms[locale] result[normalizeLocale(locale)] = transformForms(forms, rules) return result }, {}) if (!rules.length) { rules = undefined } // Unwrap the "supplemental" object. const version = includeVersion ? supplemental.version : undefined return { version, rules, cardinals } } function formatESModule (content) { return `export default ${content}` } function formatCJSModule (content) { return `module.exports = ${content}` } function formatAMDModule (content) { return `define(function () { return ${content} })` } function formatUMDModule (content, umdName) { return `(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : factory(global.${umdName || 'pluralData'} = {}) } (this, (function (exports) { Object.assign(exports, ${content}) Object.defineProperty(exports, '__esModule', { value: true }) })))` } function createPluralData (options = {}) { const { asModule, asCjsModule, asAmdModule, asUmdModule, umdName, outputFile } = options const data = transformData(originalPluralData, options) let content = JSON.stringify(data, undefined, 2) if (asModule) { content = formatESModule(content) } else if (asCjsModule) { content = formatCJSModule(content) } else if (asAmdModule) { content = formatAMDModule(content) } else if (asUmdModule) { content = formatUMDModule(content, umdName) } if (outputFile) { console.log(`Writing plural data module "${outputFile}"...`) return writeFile(outputFile, content) } return Promise.resolve(content) } export { createPluralData }