Skip to content

Instantly share code, notes, and snippets.

@segdeha
Created September 29, 2016 17:58
Show Gist options
  • Save segdeha/670ad8345ccb2773fad16bf5e6a43b96 to your computer and use it in GitHub Desktop.
Save segdeha/670ad8345ccb2773fad16bf5e6a43b96 to your computer and use it in GitHub Desktop.
Method for creating abstracted string generators
/**
* Returns a function that composes strings from ES6 template literals.
* Based on http://stackoverflow.com/a/22619256/11577
*
* @usage formatter`${0}, ${1}!`.format('Hello', 'world') // -> 'Hello, world!'
*
* @param array<string> literals Array of string literals
* @param array<mixed> substitutions Rest parameter of substitution values
*
* @return function
*/
exports.formatter = function formatter(literals, ...substitutions) {
return {
format: function format() {
return literals.reduce((accumulator, part, i) => {
let sub = arguments[substitutions[i - 1]]
sub = Array.isArray(sub) ? combineMultiple(sub) : sub
return accumulator + sub + part
})
}
}
}
/**
* Combine multiple values in an array in a standard way
*
* @usage combineMultiple(['Me']) // -> 'Me'
* @usage combineMultiple(['Me', 'You']) // -> 'Me &amp; You'
* @usage combineMultiple(['Me', 'You', 'Us']) // -> 'Me, You &amp; Us'
*
* @param array<mixed> Array of values
*
* @return string
*/
function combineMultiple(arr) {
switch (arr.length) {
case 0:
return ''
case 1:
return `${arr[0]}` // always return a string
case 2:
return `${arr[0]} &amp; ${arr[1]}`
default:
let lastVal = arr.pop()
return `${arr.join(', ')} &amp; ${lastVal}`
}
}
// The idea is to create helpers (similar to `itemsAdded()` below) for creating
// the various formats of strings that will be needed in the activities
// interface. I haven’t worked out yet how this will mesh with the translation
// library.
/*
function itemsAdded() {
return formatter`${0} added ${1} ${2} to ${3}`.format.call(null, ...arguments)
}
itemsAdded(['James Chou'], 42, 'photos', 'Pretty Sunsets')
// => "James Chou added 42 photos to Pretty Sunsets"
itemsAdded(['James Chou', 'Terry Liu'], 42, 'photos', 'Pretty Sunsets')
// => "James Chou &amp; Terry Liu added 42 photos to Pretty Sunsets"
itemsAdded(['James Chou', 'Terry Liu', 'Fan Zhang'], 42, 'photos', 'Pretty Sunsets')
// => "James Chou, Terry Liu &amp; Fan Zhang added 42 photos to Pretty Sunsets"
*/
// One way to use this for localiztion would be to create helpers based on
// locale. We could end up with a lot of functions, but it would give us exact
// control over the sentence structure for each language. But even my simple
// example below illustrates the complexity of localization. The word ‘photos’
// would need to be translated before it hits the helper the way I have the
// functions written.
/*
let helpers = {
de: {
itemsAdded: () => formatter`${0} hinzugefügt ${1} ${2} zu ${3}`.format.call(null, ...arguments)
}
en: {
itemsAdded: () => formatter`${0} added ${1} ${2} to ${3}`.format.call(null, ...arguments)
},
es: {
itemsAdded: () => formatter`${0} añadido ${1} ${2} a ${3}`.format.call(null, ...arguments)
},
fr: {
itemsAdded: () => formatter`${0} a ajouté ${1} ${2} à ${3}`.format.call(null, ...arguments)
}
}
const locale = store.getIn(['ui', 'locale'])
const action = 'itemsAdded'
const output = helpers[locale][action](['James Chou'], 42, 'photos', 'Pretty Sunsets')
// 'de' => James Chou hinzugefügt 42 Fotos zu Pretty Sunsets
// 'en' => James Chou added 42 photos to Pretty Sunsets
// 'es' => James Chou añadido 42 fotos a Pretty Sunsets
// 'fr' => James Chou a ajouté 42 photos à Pretty Sunsets
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment