Skip to content

Commit

Permalink
fix(cli): Refactor cli.js, splitting out print-categories, print-plur…
Browse files Browse the repository at this point in the history
…als & print-umd
  • Loading branch information
eemeli committed Aug 20, 2019
1 parent 02d2110 commit 76f1941
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 133 deletions.
166 changes: 33 additions & 133 deletions packages/cli/src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,127 +8,12 @@
* ./bin/make-plural [lc] [n] [ord] // prints the (ORD ? ordinal : plural) category for N in locale LC
*/

import aliases from 'cldr-core/supplemental/aliases.json'
import pluralData from 'cldr-core/supplemental/plurals.json'
import ordinalData from 'cldr-core/supplemental/ordinals.json'
import { source } from 'common-tags'
import MakePluralCompiler from 'make-plural-compiler'
import minimist from 'minimist'
import { identifier } from 'safe-identifier'
import * as common from './common'

const MakePlural = MakePluralCompiler.load(pluralData, ordinalData)

const { languageAlias } = aliases.supplemental.metadata.alias
function getAlias(lc) {
const alias = languageAlias[lc]
if (!alias) return null
const r = alias._replacement
return MakePlural.rules.cardinal[r] ? r : null // https://unicode-org.atlassian.net/browse/CLDR-13227
}

function write(str, end) {
process.stdout.write(str)
if (end) process.stdout.write(end)
}

// UMD pattern adapted from https://github.com/umdjs/umd/blob/master/returnExports.js
const umd = (global, value) => source`
(function (root, ${global}) {
if (typeof define === 'function' && define.amd) {
define(${global});
} else if (typeof exports === 'object') {
module.exports = ${global};
} else {
root.${global} = ${global};
}
}(this, {
${value}
}));
`

function printPluralsModule(es6) {
const { plurals: cp } = MakePlural.ordinals
? common.combined
: common.cardinals
const aliased = []
const plurals = Object.keys(MakePlural.rules.cardinal).map(lc => {
const alias = getAlias(lc)
if (alias) {
aliased.push([lc, alias])
return [lc, alias]
}
const mpc = new MakePlural(lc)
const fn = mpc.compile().toString()
mpc.test()
const i = cp.indexOf(fn)
return [
lc,
i === -1
? fn.replace(/^function\b/, `function ${identifier(lc)}`)
: `_${i}`
]
})
for (let i = 0; i < cp.length; ++i) {
write(cp[i].replace(/^function\b/, `function _${i}`), '\n')
}
for (const [src, tgt] of aliased) {
const idx = plurals.findIndex(pl => pl[0] === tgt)
process.stderr.write(JSON.stringify({ tgt, idx }) + '\n')
const [lc, fn] = plurals[idx]
if (fn.startsWith('_')) {
const jdx = plurals.findIndex(pl => pl[0] === src)
plurals[jdx][1] = fn
} else if (!es6) {
write(fn, '\n')
plurals[idx][1] = identifier(lc)
}
}
write('\n')
if (es6) {
for (const [lc, fn] of plurals) {
if (fn.startsWith('function')) {
write(`export ${fn}`, '\n')
} else {
const id = identifier(lc)
write(`export const ${id} = ${fn};`, '\n')
}
}
} else {
const pm = plurals.map(([lc, fn]) => `${identifier(lc)}: ${fn}`)
write(umd('plurals', pm.join(',\n\n')), '\n')
}
}

function printCategoriesModule(es6) {
const { categories: cc } = MakePlural.ordinals
? common.combined
: common.cardinals
const categories = Object.keys(MakePlural.rules.cardinal).map(lc => {
const mpc = new MakePlural(lc)
mpc.compile()
mpc.test()
const cat = JSON.stringify(mpc.categories).replace(/"(\w+)":/g, '$1:')
const i = cc.indexOf(cat)
return [lc, i === -1 ? cat : `_${i}`]
})
if (es6) {
write(cc.map((c, i) => `const _${i} = ${c};`).join('\n'), '\n\n')
for (const [lc, cat] of categories) {
const id = identifier(lc)
write(`export const ${id} = ${cat};`, '\n')
}
} else {
write(cc.map((c, i) => `var _${i} = ${c};`).join('\n'), '\n\n')
const cm = categories.map(([lc, cat]) => `${identifier(lc)}: ${cat}`)
write(umd('pluralCategories', cm.join(',\n')), '\n')
}
}

function truthy(v) {
if (v === '0' || v === 'false') return false
return !!v
}
import printCategoriesModule from './print-categories'
import printPluralsModule from './print-plurals'

function getArguments() {
var args = minimist(process.argv.slice(2), {
Expand Down Expand Up @@ -160,33 +45,48 @@ function getArguments() {
return args
}

function main({ cardinal, categories, es6, locale, ordinal, value, width }) {
function truthy(v) {
if (v === '0' || v === 'false') return false
return !!v
}

function printResult(MakePlural, { categories, locale, ordinal, value }) {
const mpc = new MakePlural(locale)
const mp = mpc.compile()
mpc.test()

if (categories) {
const cats = mpc.categories.cardinal
.concat(mpc.categories.ordinal)
.filter((v, i, self) => self.indexOf(v) === i)
return cats.join(', ')
} else if (value !== null) {
return mp(value, truthy(ordinal))
} else {
return mp.toString(locale)
}
}

function main(args) {
const { cardinal, categories, locale, ordinal, width } = args

const MakePlural = MakePluralCompiler.load(pluralData, ordinalData)
MakePlural.cardinals = cardinal !== null ? truthy(cardinal) : true
MakePlural.ordinals = ordinal !== null ? truthy(ordinal) : true
const foldWidth = Number(width)
if (foldWidth > 0) MakePlural.foldWidth = foldWidth

let str
if (locale) {
const mpc = new MakePlural(locale)
const mp = mpc.compile()
mpc.test()
if (categories) {
const cats = mpc.categories.cardinal
.concat(mpc.categories.ordinal)
.filter((v, i, self) => self.indexOf(v) === i)
write(cats.join(', '))
} else if (value !== null) {
write(mp(value, truthy(ordinal)))
} else {
write(mp.toString(locale))
}
str = printResult(MakePlural, args)
} else {
if (categories) {
printCategoriesModule(es6)
str = printCategoriesModule(MakePlural, args)
} else {
printPluralsModule(es6)
str = printPluralsModule(MakePlural, args)
}
}
process.stdout.write(str)
}

main(getArguments())
32 changes: 32 additions & 0 deletions packages/cli/src/print-categories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { identifier } from 'safe-identifier'
import * as common from './common'
import umd from './print-umd'

export default function printCategoriesModule(MakePlural, { es6 }) {
const { categories: cc } = MakePlural.ordinals
? common.combined
: common.cardinals
const categories = Object.keys(MakePlural.rules.cardinal).map(lc => {
const mpc = new MakePlural(lc)
mpc.compile()
mpc.test()
const cat = JSON.stringify(mpc.categories).replace(/"(\w+)":/g, '$1:')
const i = cc.indexOf(cat)
return [lc, i === -1 ? cat : `_${i}`]
})

let str
if (es6) {
str = cc.map((c, i) => `const _${i} = ${c};`).join('\n') + '\n\n'
for (const [lc, cat] of categories) {
const id = identifier(lc)
str += `export const ${id} = ${cat};\n`
}
} else {
str = cc.map((c, i) => `var _${i} = ${c};`).join('\n') + '\n\n'
const cm = categories.map(([lc, cat]) => `${identifier(lc)}: ${cat}`)
str += umd('pluralCategories', cm.join(',\n')) + '\n'
}
return str
}

67 changes: 67 additions & 0 deletions packages/cli/src/print-plurals.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import aliases from 'cldr-core/supplemental/aliases.json'
import { identifier } from 'safe-identifier'
import * as common from './common'
import umd from './print-umd'

function getAlias(MakePlural, lc) {
const alias = aliases.supplemental.metadata.alias.languageAlias[lc]
if (!alias) return null
const r = alias._replacement
return MakePlural.rules.cardinal[r] ? r : null // https://unicode-org.atlassian.net/browse/CLDR-13227
}

export default function printPluralsModule(MakePlural, { es6 }) {
const { plurals: cp } = MakePlural.ordinals
? common.combined
: common.cardinals
const aliased = []
const plurals = Object.keys(MakePlural.rules.cardinal).map(lc => {
const alias = getAlias(MakePlural, lc)
if (alias) {
aliased.push([lc, alias])
return [lc, alias]
}
const mpc = new MakePlural(lc)
const fn = mpc.compile().toString()
mpc.test()
const i = cp.indexOf(fn)
return [
lc,
i === -1
? fn.replace(/^function\b/, `function ${identifier(lc)}`)
: `_${i}`
]
})

let str = ''
for (let i = 0; i < cp.length; ++i) {
str += cp[i].replace(/^function\b/, `function _${i}`) + '\n'
}
for (const [src, tgt] of aliased) {
const idx = plurals.findIndex(pl => pl[0] === tgt)
process.stderr.write(JSON.stringify({ tgt, idx }) + '\n')
const [lc, fn] = plurals[idx]
if (fn.startsWith('_')) {
const jdx = plurals.findIndex(pl => pl[0] === src)
plurals[jdx][1] = fn
} else if (!es6) {
str += `${fn}\n`
plurals[idx][1] = identifier(lc)
}
}
str += '\n'
if (es6) {
for (const [lc, fn] of plurals) {
if (fn.startsWith('function')) {
str += `export ${fn}\n`
} else {
const id = identifier(lc)
str += `export const ${id} = ${fn};\n`
}
}
} else {
const pm = plurals.map(([lc, fn]) => `${identifier(lc)}: ${fn}`)
str += umd('plurals', pm.join(',\n\n')) + '\n'
}
return str
}
18 changes: 18 additions & 0 deletions packages/cli/src/print-umd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { source } from 'common-tags'

// UMD pattern adapted from https://github.com/umdjs/umd/blob/master/returnExports.js
export default function umd(global, value) {
return source`
(function (root, ${global}) {
if (typeof define === 'function' && define.amd) {
define(${global});
} else if (typeof exports === 'object') {
module.exports = ${global};
} else {
root.${global} = ${global};
}
}(this, {
${value}
}));
`
}

0 comments on commit 76f1941

Please sign in to comment.