From 6b3afeafdb62ae057876061b606db922a679fb6a Mon Sep 17 00:00:00 2001 From: Bobby Sudekum Date: Tue, 3 Oct 2017 15:01:01 -0700 Subject: [PATCH 01/25] Add fallback code for unsupported locales --- index.js | 52 +++++++++++++++++++++++++++------- test/index_test.js | 69 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 106 insertions(+), 15 deletions(-) diff --git a/index.js b/index.js index faa7f9728..ffd0f32e2 100644 --- a/index.js +++ b/index.js @@ -13,17 +13,20 @@ module.exports = function(version, _options) { return { capitalizeFirstLetter: function(language, string) { - return string.charAt(0).toLocaleUpperCase(language) + string.slice(1); + return string.charAt(0).toLocaleUpperCase(this.getBestMatchingLanguage(language)) + string.slice(1); }, - ordinalize: function(language, number) { + ordinalize: function(originalLanguage, number) { // Transform numbers to their translated ordinalized value - if (!language) throw new Error('No language code provided'); + if (!originalLanguage) throw new Error('No language code provided'); + + var language = this.getBestMatchingLanguage(originalLanguage); return instructions[language][version].constants.ordinalize[number.toString()] || ''; }, - directionFromDegree: function(language, degree) { + directionFromDegree: function(originalLanguage, degree) { // Transform degrees to their translated compass direction - if (!language) throw new Error('No language code provided'); + if (!originalLanguage) throw new Error('No language code provided'); + var language = this.getBestMatchingLanguage(originalLanguage); if (!degree && degree !== 0) { // step had no bearing_after degree, ignoring return ''; @@ -108,9 +111,10 @@ module.exports = function(version, _options) { return wayName; }, - compile: function(language, step, options) { - if (!language) throw new Error('No language code provided'); - if (languages.supportedCodes.indexOf(language) === -1) throw new Error('language code ' + language + ' not loaded'); + compile: function(originalLanguage, step, options) { + if (!originalLanguage) throw new Error('No language code provided'); + var language = this.getBestMatchingLanguage(originalLanguage); + if (!step.maneuver) throw new Error('No step maneuver provided'); var type = step.maneuver.type; @@ -205,7 +209,10 @@ module.exports = function(version, _options) { return this.tokenize(language, instruction, replaceTokens); }, - grammarize: function(language, name, grammar) { + grammarize: function(originalLanguage, name, grammar) { + if (!originalLanguage) throw new Error('No language code provided'); + + var language = this.getBestMatchingLanguage(originalLanguage); // Process way/rotary name with applying grammar rules if any if (name && grammar && grammars && grammars[language] && grammars[language][version]) { var rules = grammars[language][version][grammar]; @@ -224,7 +231,10 @@ module.exports = function(version, _options) { return name; }, - tokenize: function(language, instruction, tokens) { + tokenize: function(originalLanguage, instruction, tokens) { + if (!originalLanguage) throw new Error('No language code provided'); + + var language = this.getBestMatchingLanguage(originalLanguage); // Keep this function context to use in inline function below (no arrow functions in ES4) var that = this; var output = instruction.replace(/\{(\w+):?(\w+)?\}/g, function(token, tag, grammar) { @@ -243,6 +253,28 @@ module.exports = function(version, _options) { } return output; + }, + getBestMatchingLanguage: function(language) { + if (languages.supportedCodes.indexOf(language) > -1) return language; + + // If the language is not found, try a little harder + var languageCode = language.toLowerCase().split('-')[0]; + + var filteredSupportedLanguages = languages.supportedCodes.filter(function(locale) { + return locale.toLowerCase().split('-')[0] === languageCode; + }); + + if (filteredSupportedLanguages.length === 1) { + return filteredSupportedLanguages[0]; + } else if (filteredSupportedLanguages.length > 1) { + // If more than one language is found, use the most generic version, + // no country code needed. + return filteredSupportedLanguages.sort(function(a, b) { + return a.length - b.length; + })[0]; + } + + return 'en'; } }; }; diff --git a/test/index_test.js b/test/index_test.js index e16ebab6a..ed785f252 100644 --- a/test/index_test.js +++ b/test/index_test.js @@ -185,13 +185,72 @@ tape.test('v5 compile', function(t) { assert.end(); }); - t.test('throws an error if a non supported language code is provided', function(assert) { + t.test('Fallback to en if unsupported language', function(assert) { var v5Compiler = compiler('v5'); - assert.throws(function() { - v5Compiler.compile('foo'); - }, /language code foo not loaded/ - ); + assert.equal(v5Compiler.compile('foo', { + maneuver: { + type: 'turn', + modifier: 'left' + }, + name: 'Way Name' + }), 'Turn left onto Way Name'); + + assert.end(); + }); + + t.test('en-US fallback to en', function(assert) { + var v5Compiler = compiler('v5'); + + assert.equal(v5Compiler.compile('en-US', { + maneuver: { + type: 'turn', + modifier: 'left' + }, + name: 'Way Name' + }), 'Turn left onto Way Name'); + + assert.end(); + }); + + t.test('zh-CN fallback to zh-Hans', function(assert) { + var v5Compiler = compiler('v5'); + + assert.equal(v5Compiler.compile('zh-CN', { + maneuver: { + type: 'turn', + modifier: 'left' + }, + name: 'Way Name' + }), '左转,上Way Name'); + + assert.end(); + }); + + t.test('zh-Hant-TW fallback to zh-Hant', function(assert) { + var v5Compiler = compiler('v5'); + + assert.equal(v5Compiler.compile('zh-Hant', { + maneuver: { + type: 'turn', + modifier: 'left' + }, + name: 'Way Name' + }), '左转,上Way Name'); + + assert.end(); + }); + + t.test('es-MX fallback to es', function(assert) { + var v5Compiler = compiler('v5'); + + assert.equal(v5Compiler.compile('es-MX', { + maneuver: { + type: 'turn', + modifier: 'straight' + }, + name: 'Way Name' + }), 'Ve recto en Way Name'); assert.end(); }); From 4d952e8a078c204ab731c81e3590b011797cee32 Mon Sep 17 00:00:00 2001 From: Bobby Sudekum Date: Wed, 4 Oct 2017 11:50:32 -0700 Subject: [PATCH 02/25] fix lint --- .eslintrc.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index ab5122222..009b344cf 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -80,7 +80,7 @@ "lines-around-comment": "error", "max-depth": "error", "max-len": "off", - "max-lines": "error", + "max-lines": "off", "max-nested-callbacks": "error", "max-params": "error", "max-statements": "off", From 46af76e7720c24950b8f223d2feb7ea33efaa652 Mon Sep 17 00:00:00 2001 From: Bobby Sudekum Date: Wed, 4 Oct 2017 12:35:08 -0700 Subject: [PATCH 03/25] improve --- index.js | 54 +++++++++++++++++++++++++++++++++------------- test/index_test.js | 14 ++++++++++++ 2 files changed, 53 insertions(+), 15 deletions(-) diff --git a/index.js b/index.js index ffd0f32e2..eb22ba86e 100644 --- a/index.js +++ b/index.js @@ -255,26 +255,50 @@ module.exports = function(version, _options) { return output; }, getBestMatchingLanguage: function(language) { - if (languages.supportedCodes.indexOf(language) > -1) return language; + if (languages.instructions[language]) return language; // If the language is not found, try a little harder - var languageCode = language.toLowerCase().split('-')[0]; + var splitLocale = language.toLowerCase().split('-'); + var languageCode = false; + var scriptCode = false; + var countryCode = false; + + if (splitLocale.lenth === 1) { + languageCode = splitLocale[0]; + } else if (splitLocale.length === 2 && splitLocale[1].length === 4) { + languageCode = splitLocale[0]; + scriptCode = splitLocale[1]; + } else if (splitLocale.length === 2 && splitLocale[1].length === 2) { + languageCode = splitLocale[0]; + countryCode = splitLocale[1]; + } else if (splitLocale.length === 3) { + languageCode = splitLocale[0]; + scriptCode = splitLocale[1]; + countryCode = splitLocale[2]; + } - var filteredSupportedLanguages = languages.supportedCodes.filter(function(locale) { - return locale.toLowerCase().split('-')[0] === languageCode; - }); + // Same language code and script code (lng-Scpt) + if (languages.instructions[languageCode + '-' + scriptCode]) { + return languageCode + '-' + scriptCode; - if (filteredSupportedLanguages.length === 1) { - return filteredSupportedLanguages[0]; - } else if (filteredSupportedLanguages.length > 1) { - // If more than one language is found, use the most generic version, - // no country code needed. - return filteredSupportedLanguages.sort(function(a, b) { - return a.length - b.length; - })[0]; - } + // Same language code and country code (lng-CC) + } else if (languages.instructions[languageCode + '-' + countryCode]) { + return languageCode + '-' + countryCode; + + // Same language code (lng) + } else if (languages.instructions[languageCode]) { + return languageCode; - return 'en'; + // Same language code and any script code (lng-Scpx) + } else if (languages.instructions[languageCode] && scriptCode) { + return languageCode; + + // Same language code and any country code (lng-CX) + } else if (languages.instructions[languageCode] && countryCode) { + return languageCode; + } else { + return 'en'; + } } }; }; diff --git a/test/index_test.js b/test/index_test.js index ed785f252..879bd3ea1 100644 --- a/test/index_test.js +++ b/test/index_test.js @@ -227,6 +227,20 @@ tape.test('v5 compile', function(t) { assert.end(); }); + t.test('zh-Hant fallback to zh-Hanz', function(assert) { + var v5Compiler = compiler('v5'); + + assert.equal(v5Compiler.compile('zh-Hant', { + maneuver: { + type: 'turn', + modifier: 'left' + }, + name: 'Way Name' + }), '左转,上Way Name'); + + assert.end(); + }); + t.test('zh-Hant-TW fallback to zh-Hant', function(assert) { var v5Compiler = compiler('v5'); From 5cedb00ddce3b240840de6b34f3fa7017ff72fe4 Mon Sep 17 00:00:00 2001 From: Bobby Sudekum Date: Wed, 4 Oct 2017 12:46:57 -0700 Subject: [PATCH 04/25] fix --- index.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/index.js b/index.js index eb22ba86e..c6d35b1e6 100644 --- a/index.js +++ b/index.js @@ -277,6 +277,10 @@ module.exports = function(version, _options) { countryCode = splitLocale[2]; } + var supportedLanguageCode = languages.supportedCodes.map(function(locale) { + return locale.toLowerCase().split('-')[0]; + }); + // Same language code and script code (lng-Scpt) if (languages.instructions[languageCode + '-' + scriptCode]) { return languageCode + '-' + scriptCode; @@ -286,16 +290,16 @@ module.exports = function(version, _options) { return languageCode + '-' + countryCode; // Same language code (lng) - } else if (languages.instructions[languageCode]) { - return languageCode; + } else if (supportedLanguageCode.indexOf(languageCode) > -1) { + return languages.supportedCodes[supportedLanguageCode.indexOf(languageCode)]; // Same language code and any script code (lng-Scpx) - } else if (languages.instructions[languageCode] && scriptCode) { - return languageCode; + } else if (supportedLanguageCode.indexOf(languageCode) > -1 && scriptCode) { + return languages.supportedCodes[supportedLanguageCode.indexOf(languageCode)]; // Same language code and any country code (lng-CX) - } else if (languages.instructions[languageCode] && countryCode) { - return languageCode; + } else if (supportedLanguageCode.indexOf(languageCode) > -1 && countryCode) { + return languages.supportedCodes[supportedLanguageCode.indexOf(languageCode)]; } else { return 'en'; } From 91bba84441853f206fdf62ddbf6954cfdb877bc3 Mon Sep 17 00:00:00 2001 From: Bobby Sudekum Date: Wed, 4 Oct 2017 13:32:41 -0700 Subject: [PATCH 05/25] Update --- Readme.md | 4 ++-- index.js | 33 +++++++++++++-------------------- test/index_test.js | 27 ++++++++++++++------------- 3 files changed, 29 insertions(+), 35 deletions(-) diff --git a/Readme.md b/Readme.md index 3a29d3eb3..9f9344029 100644 --- a/Readme.md +++ b/Readme.md @@ -27,9 +27,9 @@ Grammatical cases and other translated strings customization after [Transifex](h var version = 'v5'; var osrmTextInstructions = require('osrm-text-instructions')(version); -// make your request against the API, save result to response variable +// If you are unsure if the users locale is supported, use `getBestMatchingLanguage` method to find an appropriate language. +var language = osrmTextInstructions.getBestMatchingLanguage('en'); -var language = 'en'; response.legs.forEach(function(leg) { leg.steps.forEach(function(step) { instruction = osrmTextInstructions.compile(language, step, options) diff --git a/index.js b/index.js index c6d35b1e6..1e36eafee 100644 --- a/index.js +++ b/index.js @@ -13,20 +13,17 @@ module.exports = function(version, _options) { return { capitalizeFirstLetter: function(language, string) { - return string.charAt(0).toLocaleUpperCase(this.getBestMatchingLanguage(language)) + string.slice(1); + return string.charAt(0).toLocaleUpperCase(language) + string.slice(1); }, - ordinalize: function(originalLanguage, number) { + ordinalize: function(language, number) { // Transform numbers to their translated ordinalized value - if (!originalLanguage) throw new Error('No language code provided'); - - var language = this.getBestMatchingLanguage(originalLanguage); + if (!language) throw new Error('No language code provided'); return instructions[language][version].constants.ordinalize[number.toString()] || ''; }, - directionFromDegree: function(originalLanguage, degree) { + directionFromDegree: function(language, degree) { // Transform degrees to their translated compass direction - if (!originalLanguage) throw new Error('No language code provided'); - var language = this.getBestMatchingLanguage(originalLanguage); + if (!language) throw new Error('No language code provided'); if (!degree && degree !== 0) { // step had no bearing_after degree, ignoring return ''; @@ -75,6 +72,7 @@ module.exports = function(version, _options) { getWayName: function(language, step, options) { var classes = options ? options.classes || [] : []; if (typeof step !== 'object') throw new Error('step must be an Object'); + if (!language) throw new Error('No language code provided'); if (!Array.isArray(classes)) throw new Error('classes must be an Array or undefined'); var wayName; @@ -111,10 +109,9 @@ module.exports = function(version, _options) { return wayName; }, - compile: function(originalLanguage, step, options) { - if (!originalLanguage) throw new Error('No language code provided'); - var language = this.getBestMatchingLanguage(originalLanguage); - + compile: function(language, step, options) { + if (!language) throw new Error('No language code provided'); + if (languages.supportedCodes.indexOf(language) === -1) throw new Error('language code ' + language + ' not loaded'); if (!step.maneuver) throw new Error('No step maneuver provided'); var type = step.maneuver.type; @@ -209,10 +206,8 @@ module.exports = function(version, _options) { return this.tokenize(language, instruction, replaceTokens); }, - grammarize: function(originalLanguage, name, grammar) { - if (!originalLanguage) throw new Error('No language code provided'); - - var language = this.getBestMatchingLanguage(originalLanguage); + grammarize: function(language, name, grammar) { + if (!language) throw new Error('No language code provided'); // Process way/rotary name with applying grammar rules if any if (name && grammar && grammars && grammars[language] && grammars[language][version]) { var rules = grammars[language][version][grammar]; @@ -231,10 +226,8 @@ module.exports = function(version, _options) { return name; }, - tokenize: function(originalLanguage, instruction, tokens) { - if (!originalLanguage) throw new Error('No language code provided'); - - var language = this.getBestMatchingLanguage(originalLanguage); + tokenize: function(language, instruction, tokens) { + if (!language) throw new Error('No language code provided'); // Keep this function context to use in inline function below (no arrow functions in ES4) var that = this; var output = instruction.replace(/\{(\w+):?(\w+)?\}/g, function(token, tag, grammar) { diff --git a/test/index_test.js b/test/index_test.js index 879bd3ea1..e8b96cace 100644 --- a/test/index_test.js +++ b/test/index_test.js @@ -185,24 +185,21 @@ tape.test('v5 compile', function(t) { assert.end(); }); - t.test('Fallback to en if unsupported language', function(assert) { + t.test('throws an error if a non supported language code is provided', function(assert) { var v5Compiler = compiler('v5'); - assert.equal(v5Compiler.compile('foo', { - maneuver: { - type: 'turn', - modifier: 'left' - }, - name: 'Way Name' - }), 'Turn left onto Way Name'); + assert.throws(function() { + v5Compiler.compile('foo'); + }, /language code foo not loaded/); assert.end(); }); t.test('en-US fallback to en', function(assert) { var v5Compiler = compiler('v5'); + var language = v5Compiler.getBestMatchingLanguage('en-us'); - assert.equal(v5Compiler.compile('en-US', { + assert.equal(v5Compiler.compile(language, { maneuver: { type: 'turn', modifier: 'left' @@ -215,8 +212,9 @@ tape.test('v5 compile', function(t) { t.test('zh-CN fallback to zh-Hans', function(assert) { var v5Compiler = compiler('v5'); + var language = v5Compiler.getBestMatchingLanguage('zh-CN'); - assert.equal(v5Compiler.compile('zh-CN', { + assert.equal(v5Compiler.compile(language, { maneuver: { type: 'turn', modifier: 'left' @@ -229,8 +227,9 @@ tape.test('v5 compile', function(t) { t.test('zh-Hant fallback to zh-Hanz', function(assert) { var v5Compiler = compiler('v5'); + var language = v5Compiler.getBestMatchingLanguage('zh-Hant'); - assert.equal(v5Compiler.compile('zh-Hant', { + assert.equal(v5Compiler.compile(language, { maneuver: { type: 'turn', modifier: 'left' @@ -243,8 +242,9 @@ tape.test('v5 compile', function(t) { t.test('zh-Hant-TW fallback to zh-Hant', function(assert) { var v5Compiler = compiler('v5'); + var language = v5Compiler.getBestMatchingLanguage('zh-Hant-TW'); - assert.equal(v5Compiler.compile('zh-Hant', { + assert.equal(v5Compiler.compile(language, { maneuver: { type: 'turn', modifier: 'left' @@ -257,8 +257,9 @@ tape.test('v5 compile', function(t) { t.test('es-MX fallback to es', function(assert) { var v5Compiler = compiler('v5'); + var language = v5Compiler.getBestMatchingLanguage('es-MX'); - assert.equal(v5Compiler.compile('es-MX', { + assert.equal(v5Compiler.compile(language, { maneuver: { type: 'turn', modifier: 'straight' From a7e10aa1fef54675688587a10f12e02b14b0d2a6 Mon Sep 17 00:00:00 2001 From: Bobby Sudekum Date: Wed, 4 Oct 2017 13:49:31 -0700 Subject: [PATCH 06/25] Update name, add unit test --- index.js | 15 ++++++++------- test/index_test.js | 7 +++++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/index.js b/index.js index 1e36eafee..4cd5b1299 100644 --- a/index.js +++ b/index.js @@ -270,7 +270,7 @@ module.exports = function(version, _options) { countryCode = splitLocale[2]; } - var supportedLanguageCode = languages.supportedCodes.map(function(locale) { + var supportedLanguageCodes = languages.supportedCodes.map(function(locale) { return locale.toLowerCase().split('-')[0]; }); @@ -283,16 +283,17 @@ module.exports = function(version, _options) { return languageCode + '-' + countryCode; // Same language code (lng) - } else if (supportedLanguageCode.indexOf(languageCode) > -1) { - return languages.supportedCodes[supportedLanguageCode.indexOf(languageCode)]; + } else if (languages.instructions[languageCode]) { + return languageCode; // Same language code and any script code (lng-Scpx) - } else if (supportedLanguageCode.indexOf(languageCode) > -1 && scriptCode) { - return languages.supportedCodes[supportedLanguageCode.indexOf(languageCode)]; + } else if (supportedLanguageCodes.indexOf(languageCode) > -1 && scriptCode) { + console.log('hit'); + return languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)]; // Same language code and any country code (lng-CX) - } else if (supportedLanguageCode.indexOf(languageCode) > -1 && countryCode) { - return languages.supportedCodes[supportedLanguageCode.indexOf(languageCode)]; + } else if (supportedLanguageCodes.indexOf(languageCode) > -1 && countryCode) { + return languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)]; } else { return 'en'; } diff --git a/test/index_test.js b/test/index_test.js index e8b96cace..8ade3e4c5 100644 --- a/test/index_test.js +++ b/test/index_test.js @@ -270,6 +270,13 @@ tape.test('v5 compile', function(t) { assert.end(); }); + t.test('getBestMatchingLanguage', function(t) { + t.assert(compiler('v5').getBestMatchingLanguage('zh-Hant'), 'zh-Hans'); + t.assert(compiler('v5').getBestMatchingLanguage('zh-Hant-TW'), 'zh-Hans'); + t.assert(compiler('v5').getBestMatchingLanguage('zh'), 'zh-Hans'); + t.end(); + }); + t.test('respects options.instructionStringHook', function(assert) { var v5Compiler = compiler('v5', { hooks: { From e46bea7da74af5f667f582f42214ecf4f41ff0aa Mon Sep 17 00:00:00 2001 From: Bobby Sudekum Date: Wed, 4 Oct 2017 13:50:21 -0700 Subject: [PATCH 07/25] remove lint --- index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/index.js b/index.js index 4cd5b1299..0430b2d71 100644 --- a/index.js +++ b/index.js @@ -288,7 +288,6 @@ module.exports = function(version, _options) { // Same language code and any script code (lng-Scpx) } else if (supportedLanguageCodes.indexOf(languageCode) > -1 && scriptCode) { - console.log('hit'); return languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)]; // Same language code and any country code (lng-CX) From 167f7c2e783d043d6bce307f4173d16115b7f0f0 Mon Sep 17 00:00:00 2001 From: Bobby Sudekum Date: Wed, 4 Oct 2017 13:54:26 -0700 Subject: [PATCH 08/25] Strengthen script --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 0430b2d71..ee6d9fec6 100644 --- a/index.js +++ b/index.js @@ -286,8 +286,8 @@ module.exports = function(version, _options) { } else if (languages.instructions[languageCode]) { return languageCode; - // Same language code and any script code (lng-Scpx) - } else if (supportedLanguageCodes.indexOf(languageCode) > -1 && scriptCode) { + // Same language code and any script code (lng-Scpx) and the found language contains a script + } else if (supportedLanguageCodes.indexOf(languageCode) > -1 && scriptCode && languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)].split('-')[1].length === 4) { return languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)]; // Same language code and any country code (lng-CX) From 2f40ceb3a267e01349e254706dcd129cd110a618 Mon Sep 17 00:00:00 2001 From: Bobby Sudekum Date: Wed, 4 Oct 2017 13:58:56 -0700 Subject: [PATCH 09/25] stronger --- index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index ee6d9fec6..4b345a486 100644 --- a/index.js +++ b/index.js @@ -287,7 +287,9 @@ module.exports = function(version, _options) { return languageCode; // Same language code and any script code (lng-Scpx) and the found language contains a script - } else if (supportedLanguageCodes.indexOf(languageCode) > -1 && scriptCode && languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)].split('-')[1].length === 4) { + } else if (supportedLanguageCodes.indexOf(languageCode) > -1 && scriptCode && + languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)].split('-').length > 1 && + languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)].split('-')[1].length === 4) { return languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)]; // Same language code and any country code (lng-CX) From 46a02f085bf104f59e6d0ce584e89f5a8e1dfcf8 Mon Sep 17 00:00:00 2001 From: Bobby Sudekum Date: Wed, 4 Oct 2017 14:01:31 -0700 Subject: [PATCH 10/25] Update changlog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54d19fa01..cab0c98d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Change Log All notable changes to this project will be documented in this file. For change log formatting, see http://keepachangelog.com/ +## Master + +- Added `getBestMatchingLanguage` for determining the best language when it's unknown if the users locale is supported. + ## 0.8.0 2017-10-04 - Added grammatical cases support for Russian way names [#102](https://github.com/Project-OSRM/osrm-text-instructions/pull/102) From 9580c375f75e5fe3c572fb4123af7b0fa0a0d016 Mon Sep 17 00:00:00 2001 From: Bobby Sudekum Date: Thu, 5 Oct 2017 09:13:36 -0700 Subject: [PATCH 11/25] more --- index.js | 19 ++++++++++++++----- test/index_test.js | 5 +++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index 4b345a486..2ff89ecaa 100644 --- a/index.js +++ b/index.js @@ -256,7 +256,20 @@ module.exports = function(version, _options) { var scriptCode = false; var countryCode = false; - if (splitLocale.lenth === 1) { + /** + Documentation on how the language tag is being split: https://en.wikipedia.org/wiki/IETF_language_tag#Syntax_of_language_tags + + Example: zh-Hant-TW + language code: zh + script code: Hant + country code: TW + + Example: en-US + language code: en + country code: US + */ + + if (splitLocale.length === 1) { languageCode = splitLocale[0]; } else if (splitLocale.length === 2 && splitLocale[1].length === 4) { languageCode = splitLocale[0]; @@ -277,21 +290,17 @@ module.exports = function(version, _options) { // Same language code and script code (lng-Scpt) if (languages.instructions[languageCode + '-' + scriptCode]) { return languageCode + '-' + scriptCode; - // Same language code and country code (lng-CC) } else if (languages.instructions[languageCode + '-' + countryCode]) { return languageCode + '-' + countryCode; - // Same language code (lng) } else if (languages.instructions[languageCode]) { return languageCode; - // Same language code and any script code (lng-Scpx) and the found language contains a script } else if (supportedLanguageCodes.indexOf(languageCode) > -1 && scriptCode && languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)].split('-').length > 1 && languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)].split('-')[1].length === 4) { return languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)]; - // Same language code and any country code (lng-CX) } else if (supportedLanguageCodes.indexOf(languageCode) > -1 && countryCode) { return languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)]; diff --git a/test/index_test.js b/test/index_test.js index 8ade3e4c5..a77a833c5 100644 --- a/test/index_test.js +++ b/test/index_test.js @@ -271,9 +271,14 @@ tape.test('v5 compile', function(t) { }); t.test('getBestMatchingLanguage', function(t) { + t.assert(compiler('v5').getBestMatchingLanguage('foo'), 'en'); + t.assert(compiler('v5').getBestMatchingLanguage('en-US'), 'en'); + t.assert(compiler('v5').getBestMatchingLanguage('zh-CN'), 'zh-Hans'); t.assert(compiler('v5').getBestMatchingLanguage('zh-Hant'), 'zh-Hans'); t.assert(compiler('v5').getBestMatchingLanguage('zh-Hant-TW'), 'zh-Hans'); t.assert(compiler('v5').getBestMatchingLanguage('zh'), 'zh-Hans'); + t.assert(compiler('v5').getBestMatchingLanguage('es-MX'), 'es'); + t.assert(compiler('v5').getBestMatchingLanguage('es-es'), 'es-es'); t.end(); }); From 9a19e1eacde4f7bbdc48543c1f26b49476ce284a Mon Sep 17 00:00:00 2001 From: Bobby Sudekum Date: Thu, 5 Oct 2017 12:08:43 -0700 Subject: [PATCH 12/25] improve --- index.js | 74 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 31 deletions(-) diff --git a/index.js b/index.js index 2ff89ecaa..a19b7c8db 100644 --- a/index.js +++ b/index.js @@ -249,10 +249,46 @@ module.exports = function(version, _options) { }, getBestMatchingLanguage: function(language) { if (languages.instructions[language]) return language; + var that = this; + + var codes = that.divideLanguageCodes(language); + var languageCode = codes.languageCode; + var scriptCode = codes.scriptCode; + var countryCode = codes.countryCode; + + var supportedLanguageCodes = languages.supportedCodes.map(function(locale) { + return locale.toLowerCase().split('-')[0]; + }); + var availableLanguages = languages.supportedCodes.map(function(language) { + return that.divideLanguageCodes(language); + }); + + // Same language code and script code (lng-Scpt) + if (languages.instructions[languageCode + '-' + scriptCode]) { + return languageCode + '-' + scriptCode; + // Same language code and country code (lng-CC) + } else if (languages.instructions[languageCode + '-' + countryCode]) { + return languageCode + '-' + countryCode; + // Same language code (lng) + } else if (languages.instructions[languageCode]) { + return languageCode; + // Same language code and any script code (lng-Scpx) and the found language contains a script + } else if (availableLanguages.find(function (language) { + return language.languageCode === languageCode && language.scriptCode; + })) { + return languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)]; + // Same language code and any country code (lng-CX) + } else if (supportedLanguageCodes.indexOf(languageCode) > -1 && countryCode) { + return languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)]; + } else { + return 'en'; + } + }, + divideLanguageCodes: function(language) { // If the language is not found, try a little harder var splitLocale = language.toLowerCase().split('-'); - var languageCode = false; + var languageCode = splitLocale[0]; var scriptCode = false; var countryCode = false; @@ -269,44 +305,20 @@ module.exports = function(version, _options) { country code: US */ - if (splitLocale.length === 1) { - languageCode = splitLocale[0]; - } else if (splitLocale.length === 2 && splitLocale[1].length === 4) { - languageCode = splitLocale[0]; + if (splitLocale.length === 2 && splitLocale[1].length === 4) { scriptCode = splitLocale[1]; } else if (splitLocale.length === 2 && splitLocale[1].length === 2) { - languageCode = splitLocale[0]; countryCode = splitLocale[1]; } else if (splitLocale.length === 3) { - languageCode = splitLocale[0]; scriptCode = splitLocale[1]; countryCode = splitLocale[2]; } - var supportedLanguageCodes = languages.supportedCodes.map(function(locale) { - return locale.toLowerCase().split('-')[0]; - }); - - // Same language code and script code (lng-Scpt) - if (languages.instructions[languageCode + '-' + scriptCode]) { - return languageCode + '-' + scriptCode; - // Same language code and country code (lng-CC) - } else if (languages.instructions[languageCode + '-' + countryCode]) { - return languageCode + '-' + countryCode; - // Same language code (lng) - } else if (languages.instructions[languageCode]) { - return languageCode; - // Same language code and any script code (lng-Scpx) and the found language contains a script - } else if (supportedLanguageCodes.indexOf(languageCode) > -1 && scriptCode && - languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)].split('-').length > 1 && - languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)].split('-')[1].length === 4) { - return languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)]; - // Same language code and any country code (lng-CX) - } else if (supportedLanguageCodes.indexOf(languageCode) > -1 && countryCode) { - return languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)]; - } else { - return 'en'; - } + return { + languageCode: languageCode, + scriptCode: scriptCode, + countryCode: countryCode + }; } }; }; From fb3336744edce28c31a529ee04fcb4cc906a82c5 Mon Sep 17 00:00:00 2001 From: Bobby Sudekum Date: Thu, 5 Oct 2017 12:17:51 -0700 Subject: [PATCH 13/25] language --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index a19b7c8db..5dcd58c2e 100644 --- a/index.js +++ b/index.js @@ -256,8 +256,8 @@ module.exports = function(version, _options) { var scriptCode = codes.scriptCode; var countryCode = codes.countryCode; - var supportedLanguageCodes = languages.supportedCodes.map(function(locale) { - return locale.toLowerCase().split('-')[0]; + var supportedLanguageCodes = languages.supportedCodes.map(function(language) { + return language.toLowerCase().split('-')[0]; }); var availableLanguages = languages.supportedCodes.map(function(language) { From 86c0761e70d3d1909a854e6692e240bffdfeebae Mon Sep 17 00:00:00 2001 From: Bobby Sudekum Date: Thu, 5 Oct 2017 14:37:44 -0700 Subject: [PATCH 14/25] move --- index.js | 40 ++-------------------------------------- languages.js | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/index.js b/index.js index 5dcd58c2e..8fe196e26 100644 --- a/index.js +++ b/index.js @@ -249,9 +249,8 @@ module.exports = function(version, _options) { }, getBestMatchingLanguage: function(language) { if (languages.instructions[language]) return language; - var that = this; - var codes = that.divideLanguageCodes(language); + var codes = languages.parseLanguageIntoCodes(language); var languageCode = codes.languageCode; var scriptCode = codes.scriptCode; var countryCode = codes.countryCode; @@ -261,7 +260,7 @@ module.exports = function(version, _options) { }); var availableLanguages = languages.supportedCodes.map(function(language) { - return that.divideLanguageCodes(language); + return languages.parseLanguageIntoCodes(language); }); // Same language code and script code (lng-Scpt) @@ -284,41 +283,6 @@ module.exports = function(version, _options) { } else { return 'en'; } - }, - divideLanguageCodes: function(language) { - // If the language is not found, try a little harder - var splitLocale = language.toLowerCase().split('-'); - var languageCode = splitLocale[0]; - var scriptCode = false; - var countryCode = false; - - /** - Documentation on how the language tag is being split: https://en.wikipedia.org/wiki/IETF_language_tag#Syntax_of_language_tags - - Example: zh-Hant-TW - language code: zh - script code: Hant - country code: TW - - Example: en-US - language code: en - country code: US - */ - - if (splitLocale.length === 2 && splitLocale[1].length === 4) { - scriptCode = splitLocale[1]; - } else if (splitLocale.length === 2 && splitLocale[1].length === 2) { - countryCode = splitLocale[1]; - } else if (splitLocale.length === 3) { - scriptCode = splitLocale[1]; - countryCode = splitLocale[2]; - } - - return { - languageCode: languageCode, - scriptCode: scriptCode, - countryCode: countryCode - }; } }; }; diff --git a/languages.js b/languages.js index d5d0f59b6..cfde95d25 100755 --- a/languages.js +++ b/languages.js @@ -49,8 +49,45 @@ var grammars = { 'ru': grammarRu }; +function parseLanguageIntoCodes (language) { + // If the language is not found, try a little harder + var splitLocale = language.toLowerCase().split('-'); + var languageCode = splitLocale[0]; + var scriptCode = false; + var countryCode = false; + + /** + Documentation on how the language tag is being split: https://en.wikipedia.org/wiki/IETF_language_tag#Syntax_of_language_tags + + Example: zh-Hant-TW + language code: zh + script code: Hant + country code: TW + + Example: en-US + language code: en + country code: US + */ + + if (splitLocale.length === 2 && splitLocale[1].length === 4) { + scriptCode = splitLocale[1]; + } else if (splitLocale.length === 2 && splitLocale[1].length === 2) { + countryCode = splitLocale[1]; + } else if (splitLocale.length === 3) { + scriptCode = splitLocale[1]; + countryCode = splitLocale[2]; + } + + return { + languageCode: languageCode, + scriptCode: scriptCode, + countryCode: countryCode + }; +} + module.exports = { supportedCodes: Object.keys(instructions), instructions: instructions, - grammars: grammars + grammars: grammars, + parseLanguageIntoCodes: parseLanguageIntoCodes }; From 6fcd345eb3b128156a591326d54f35c7a77bd253 Mon Sep 17 00:00:00 2001 From: Bobby Sudekum Date: Thu, 5 Oct 2017 14:39:34 -0700 Subject: [PATCH 15/25] export --- index.js | 6 +----- languages.js | 3 +++ 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index 8fe196e26..53b2136af 100644 --- a/index.js +++ b/index.js @@ -259,10 +259,6 @@ module.exports = function(version, _options) { return language.toLowerCase().split('-')[0]; }); - var availableLanguages = languages.supportedCodes.map(function(language) { - return languages.parseLanguageIntoCodes(language); - }); - // Same language code and script code (lng-Scpt) if (languages.instructions[languageCode + '-' + scriptCode]) { return languageCode + '-' + scriptCode; @@ -273,7 +269,7 @@ module.exports = function(version, _options) { } else if (languages.instructions[languageCode]) { return languageCode; // Same language code and any script code (lng-Scpx) and the found language contains a script - } else if (availableLanguages.find(function (language) { + } else if (languages.parsedSupportedCodes.find(function (language) { return language.languageCode === languageCode && language.scriptCode; })) { return languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)]; diff --git a/languages.js b/languages.js index cfde95d25..e913502ea 100755 --- a/languages.js +++ b/languages.js @@ -87,6 +87,9 @@ function parseLanguageIntoCodes (language) { module.exports = { supportedCodes: Object.keys(instructions), + parsedSupportedCodes: Object.keys(instructions).map(function(language) { + return parseLanguageIntoCodes(language); + }), instructions: instructions, grammars: grammars, parseLanguageIntoCodes: parseLanguageIntoCodes From f69f3c3dfa0296556b58063fbc29d9cf73ff950a Mon Sep 17 00:00:00 2001 From: Bobby Sudekum Date: Thu, 5 Oct 2017 14:40:33 -0700 Subject: [PATCH 16/25] use find --- index.js | 4 +++- languages.js | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 53b2136af..9f8b72852 100644 --- a/index.js +++ b/index.js @@ -272,7 +272,9 @@ module.exports = function(version, _options) { } else if (languages.parsedSupportedCodes.find(function (language) { return language.languageCode === languageCode && language.scriptCode; })) { - return languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)]; + return languages.parsedSupportedCodes.find(function (language) { + return language.languageCode === languageCode && language.scriptCode; + }).locale; // Same language code and any country code (lng-CX) } else if (supportedLanguageCodes.indexOf(languageCode) > -1 && countryCode) { return languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)]; diff --git a/languages.js b/languages.js index e913502ea..0f0c631df 100755 --- a/languages.js +++ b/languages.js @@ -79,6 +79,7 @@ function parseLanguageIntoCodes (language) { } return { + locale: language, languageCode: languageCode, scriptCode: scriptCode, countryCode: countryCode From 2550759263f757549bcecb8cf7c729b89f81d021 Mon Sep 17 00:00:00 2001 From: Bobby Sudekum Date: Thu, 5 Oct 2017 15:17:18 -0700 Subject: [PATCH 17/25] more test --- index.js | 12 ++++++++++-- test/index_test.js | 34 ++++++++++++++++++++++++++-------- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/index.js b/index.js index 9f8b72852..c6dc17df7 100644 --- a/index.js +++ b/index.js @@ -266,11 +266,11 @@ module.exports = function(version, _options) { } else if (languages.instructions[languageCode + '-' + countryCode]) { return languageCode + '-' + countryCode; // Same language code (lng) - } else if (languages.instructions[languageCode]) { + } else if (supportedLanguageCodes[languageCode]) { return languageCode; // Same language code and any script code (lng-Scpx) and the found language contains a script } else if (languages.parsedSupportedCodes.find(function (language) { - return language.languageCode === languageCode && language.scriptCode; + return language.language === languageCode && language.scriptCode; })) { return languages.parsedSupportedCodes.find(function (language) { return language.languageCode === languageCode && language.scriptCode; @@ -278,6 +278,14 @@ module.exports = function(version, _options) { // Same language code and any country code (lng-CX) } else if (supportedLanguageCodes.indexOf(languageCode) > -1 && countryCode) { return languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)]; + // Only language code provided, but we on support this language code + // with either script/country code. + } else if (languages.parsedSupportedCodes.find(function (language) { + return language.languageCode === languageCode; + })) { + return (languages.parsedSupportedCodes.find(function (language) { + return language.languageCode === languageCode; + })).locale; } else { return 'en'; } diff --git a/test/index_test.js b/test/index_test.js index a77a833c5..c23a23ee6 100644 --- a/test/index_test.js +++ b/test/index_test.js @@ -271,17 +271,35 @@ tape.test('v5 compile', function(t) { }); t.test('getBestMatchingLanguage', function(t) { - t.assert(compiler('v5').getBestMatchingLanguage('foo'), 'en'); - t.assert(compiler('v5').getBestMatchingLanguage('en-US'), 'en'); - t.assert(compiler('v5').getBestMatchingLanguage('zh-CN'), 'zh-Hans'); - t.assert(compiler('v5').getBestMatchingLanguage('zh-Hant'), 'zh-Hans'); - t.assert(compiler('v5').getBestMatchingLanguage('zh-Hant-TW'), 'zh-Hans'); - t.assert(compiler('v5').getBestMatchingLanguage('zh'), 'zh-Hans'); - t.assert(compiler('v5').getBestMatchingLanguage('es-MX'), 'es'); - t.assert(compiler('v5').getBestMatchingLanguage('es-es'), 'es-es'); + t.equal(compiler('v5').getBestMatchingLanguage('foo'), 'en'); + t.equal(compiler('v5').getBestMatchingLanguage('en-US'), 'en'); + t.equal(compiler('v5').getBestMatchingLanguage('zh-CN'), 'zh-Hans'); + t.equal(compiler('v5').getBestMatchingLanguage('zh-Hant'), 'zh-Hans'); + t.equal(compiler('v5').getBestMatchingLanguage('zh-Hant-TW'), 'zh-Hans'); + t.equal(compiler('v5').getBestMatchingLanguage('zh'), 'zh-Hans'); + t.equal(compiler('v5').getBestMatchingLanguage('es-MX'), 'es'); + t.equal(compiler('v5').getBestMatchingLanguage('es-ES'), 'es-ES'); + t.equal(compiler('v5').getBestMatchingLanguage('pt-PT'), 'pt-BR'); + t.equal(compiler('v5').getBestMatchingLanguage('pt'), 'pt-BR'); t.end(); }); + /* eslint-disable */ + t.test('parseLanguageIntoCodes', function(t) { + t.deepEqual(languages.parseLanguageIntoCodes('foo'), { countryCode: false, languageCode: 'foo', locale: 'foo', scriptCode: false }); + t.deepEqual(languages.parseLanguageIntoCodes('en-US'), { countryCode: 'us', languageCode: 'en', locale: 'en-US', scriptCode: false }); + t.deepEqual(languages.parseLanguageIntoCodes('zh-CN'), { countryCode: 'cn', languageCode: 'zh', locale: 'zh-CN', scriptCode: false }); + t.deepEqual(languages.parseLanguageIntoCodes('zh-Hant'), { countryCode: false, languageCode: 'zh', locale: 'zh-Hant', scriptCode: 'hant' }); + t.deepEqual(languages.parseLanguageIntoCodes('zh-Hant-TW'), { countryCode: 'tw', languageCode: 'zh', locale: 'zh-Hant-TW', scriptCode: 'hant' }); + t.deepEqual(languages.parseLanguageIntoCodes('zh'), { countryCode: false, languageCode: 'zh', locale: 'zh', scriptCode: false }); + t.deepEqual(languages.parseLanguageIntoCodes('es-MX'), { countryCode: 'mx', languageCode: 'es', locale: 'es-MX', scriptCode: false }); + t.deepEqual(languages.parseLanguageIntoCodes('es-ES'), { countryCode: 'es', languageCode: 'es', locale: 'es-ES', scriptCode: false }); + t.deepEqual(languages.parseLanguageIntoCodes('pt-PT'), { countryCode: 'pt', languageCode: 'pt', locale: 'pt-PT', scriptCode: false }); + t.deepEqual(languages.parseLanguageIntoCodes('pt'), { countryCode: false, languageCode: 'pt', locale: 'pt', scriptCode: false }); + t.end(); + }); + /* eslint-enable */ + t.test('respects options.instructionStringHook', function(assert) { var v5Compiler = compiler('v5', { hooks: { From 72ea8951a06c56b19ae06ecbd7d4a1dca5980f7e Mon Sep 17 00:00:00 2001 From: Bobby Sudekum Date: Thu, 5 Oct 2017 15:38:22 -0700 Subject: [PATCH 18/25] Use regex --- languages.js | 47 +++++++++++++++++----------------------------- test/index_test.js | 20 ++++++++++---------- 2 files changed, 27 insertions(+), 40 deletions(-) diff --git a/languages.js b/languages.js index 0f0c631df..f3b61556a 100755 --- a/languages.js +++ b/languages.js @@ -50,39 +50,26 @@ var grammars = { }; function parseLanguageIntoCodes (language) { - // If the language is not found, try a little harder - var splitLocale = language.toLowerCase().split('-'); - var languageCode = splitLocale[0]; - var scriptCode = false; - var countryCode = false; - - /** - Documentation on how the language tag is being split: https://en.wikipedia.org/wiki/IETF_language_tag#Syntax_of_language_tags - - Example: zh-Hant-TW - language code: zh - script code: Hant - country code: TW - - Example: en-US - language code: en - country code: US - */ - - if (splitLocale.length === 2 && splitLocale[1].length === 4) { - scriptCode = splitLocale[1]; - } else if (splitLocale.length === 2 && splitLocale[1].length === 2) { - countryCode = splitLocale[1]; - } else if (splitLocale.length === 3) { - scriptCode = splitLocale[1]; - countryCode = splitLocale[2]; + var match = language.match(/(\w\w)(?:-(\w\w\w\w))?(?:-(\w\w))?/i); + var locale = []; + if (match[1]) { + match[1] = match[1].toLowerCase(); + locale.push(match[1]); + } + if (match[2]) { + match[2] = match[2][0].toUpperCase() + match[2].substring(1).toLowerCase(); + locale.push(match[2]); + } + if (match[3]) { + match[3] = match[3].toUpperCase(); + locale.push(match[3]); } return { - locale: language, - languageCode: languageCode, - scriptCode: scriptCode, - countryCode: countryCode + locale: locale.join('-'), + languageCode: match[1], + scriptCode: match[2], + countryCode: match[3] }; } diff --git a/test/index_test.js b/test/index_test.js index c23a23ee6..113ba69c6 100644 --- a/test/index_test.js +++ b/test/index_test.js @@ -286,16 +286,16 @@ tape.test('v5 compile', function(t) { /* eslint-disable */ t.test('parseLanguageIntoCodes', function(t) { - t.deepEqual(languages.parseLanguageIntoCodes('foo'), { countryCode: false, languageCode: 'foo', locale: 'foo', scriptCode: false }); - t.deepEqual(languages.parseLanguageIntoCodes('en-US'), { countryCode: 'us', languageCode: 'en', locale: 'en-US', scriptCode: false }); - t.deepEqual(languages.parseLanguageIntoCodes('zh-CN'), { countryCode: 'cn', languageCode: 'zh', locale: 'zh-CN', scriptCode: false }); - t.deepEqual(languages.parseLanguageIntoCodes('zh-Hant'), { countryCode: false, languageCode: 'zh', locale: 'zh-Hant', scriptCode: 'hant' }); - t.deepEqual(languages.parseLanguageIntoCodes('zh-Hant-TW'), { countryCode: 'tw', languageCode: 'zh', locale: 'zh-Hant-TW', scriptCode: 'hant' }); - t.deepEqual(languages.parseLanguageIntoCodes('zh'), { countryCode: false, languageCode: 'zh', locale: 'zh', scriptCode: false }); - t.deepEqual(languages.parseLanguageIntoCodes('es-MX'), { countryCode: 'mx', languageCode: 'es', locale: 'es-MX', scriptCode: false }); - t.deepEqual(languages.parseLanguageIntoCodes('es-ES'), { countryCode: 'es', languageCode: 'es', locale: 'es-ES', scriptCode: false }); - t.deepEqual(languages.parseLanguageIntoCodes('pt-PT'), { countryCode: 'pt', languageCode: 'pt', locale: 'pt-PT', scriptCode: false }); - t.deepEqual(languages.parseLanguageIntoCodes('pt'), { countryCode: false, languageCode: 'pt', locale: 'pt', scriptCode: false }); + t.deepEqual(languages.parseLanguageIntoCodes('foo'), { countryCode: undefined, languageCode: 'fo', locale: 'fo', scriptCode: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('en-US'), { countryCode: 'US', languageCode: 'en', locale: 'en-US', scriptCode: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('zh-CN'), { countryCode: 'CN', languageCode: 'zh', locale: 'zh-CN', scriptCode: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('zh-Hant'), { countryCode: undefined, languageCode: 'zh', locale: 'zh-Hant', scriptCode: 'Hant' }); + t.deepEqual(languages.parseLanguageIntoCodes('zh-Hant-TW'), { countryCode: 'TW', languageCode: 'zh', locale: 'zh-Hant-TW', scriptCode: 'Hant' }); + t.deepEqual(languages.parseLanguageIntoCodes('zh'), { countryCode: undefined, languageCode: 'zh', locale: 'zh', scriptCode: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('es-MX'), { countryCode: 'MX', languageCode: 'es', locale: 'es-MX', scriptCode: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('es-ES'), { countryCode: 'ES', languageCode: 'es', locale: 'es-ES', scriptCode: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('pt-PT'), { countryCode: 'PT', languageCode: 'pt', locale: 'pt-PT', scriptCode: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('pt'), { countryCode: undefined, languageCode: 'pt', locale: 'pt', scriptCode: undefined }); t.end(); }); /* eslint-enable */ From 1cfe1553f67de805b10a9c3e65d4d41b2867b32f Mon Sep 17 00:00:00 2001 From: Bobby Sudekum Date: Thu, 5 Oct 2017 15:41:09 -0700 Subject: [PATCH 19/25] pt-pt --- test/index_test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/index_test.js b/test/index_test.js index 113ba69c6..c9bd58148 100644 --- a/test/index_test.js +++ b/test/index_test.js @@ -281,6 +281,7 @@ tape.test('v5 compile', function(t) { t.equal(compiler('v5').getBestMatchingLanguage('es-ES'), 'es-ES'); t.equal(compiler('v5').getBestMatchingLanguage('pt-PT'), 'pt-BR'); t.equal(compiler('v5').getBestMatchingLanguage('pt'), 'pt-BR'); + t.equal(compiler('v5').getBestMatchingLanguage('pt-pt'), 'pt-BR'); t.end(); }); From 5237e1272ec26183fbcd8fef01b6283b095b2cce Mon Sep 17 00:00:00 2001 From: Bobby Sudekum Date: Thu, 5 Oct 2017 15:51:50 -0700 Subject: [PATCH 20/25] fix --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index c6dc17df7..6107bd5c3 100644 --- a/index.js +++ b/index.js @@ -270,7 +270,7 @@ module.exports = function(version, _options) { return languageCode; // Same language code and any script code (lng-Scpx) and the found language contains a script } else if (languages.parsedSupportedCodes.find(function (language) { - return language.language === languageCode && language.scriptCode; + return language.languageCode === languageCode && language.scriptCode; })) { return languages.parsedSupportedCodes.find(function (language) { return language.languageCode === languageCode && language.scriptCode; From e4d58a1ee9adae07e86f986461bc1b2525d77a44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Thu, 5 Oct 2017 15:53:20 -0700 Subject: [PATCH 21/25] Simplified language matching --- index.js | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/index.js b/index.js index 6107bd5c3..5e48cfe3d 100644 --- a/index.js +++ b/index.js @@ -262,33 +262,44 @@ module.exports = function(version, _options) { // Same language code and script code (lng-Scpt) if (languages.instructions[languageCode + '-' + scriptCode]) { return languageCode + '-' + scriptCode; + } + // Same language code and country code (lng-CC) - } else if (languages.instructions[languageCode + '-' + countryCode]) { + if (languages.instructions[languageCode + '-' + countryCode]) { return languageCode + '-' + countryCode; + } + // Same language code (lng) - } else if (supportedLanguageCodes[languageCode]) { + if (supportedLanguageCodes[languageCode]) { return languageCode; + } + // Same language code and any script code (lng-Scpx) and the found language contains a script - } else if (languages.parsedSupportedCodes.find(function (language) { + var anyScript = languages.parsedSupportedCodes.find(function (language) { return language.languageCode === languageCode && language.scriptCode; - })) { - return languages.parsedSupportedCodes.find(function (language) { - return language.languageCode === languageCode && language.scriptCode; - }).locale; + }); + if (anyScript) { + return anyScript.locale; + } + // Same language code and any country code (lng-CX) - } else if (supportedLanguageCodes.indexOf(languageCode) > -1 && countryCode) { - return languages.supportedCodes[supportedLanguageCodes.indexOf(languageCode)]; + var anyCountry = languages.parsedSupportedCodes.find(function (language) { + return language.languageCode === languageCode && language.scriptCode; + }); + if (anyCountry) { + return anyCountry.locale; + } + // Only language code provided, but we on support this language code // with either script/country code. - } else if (languages.parsedSupportedCodes.find(function (language) { + var sameLanguage = languages.parsedSupportedCodes.find(function (language) { return language.languageCode === languageCode; - })) { - return (languages.parsedSupportedCodes.find(function (language) { - return language.languageCode === languageCode; - })).locale; - } else { - return 'en'; + }); + if (sameLanguage) { + return sameLanguage.locale; } + + return 'en'; } }; }; From e605e829ad5dc5f07cdca99233107cc88af39842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Thu, 5 Oct 2017 15:57:02 -0700 Subject: [PATCH 22/25] Simplified properties in language objects --- index.js | 22 +++++++++++----------- languages.js | 6 +++--- test/index_test.js | 20 ++++++++++---------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/index.js b/index.js index 5e48cfe3d..d490325a1 100644 --- a/index.js +++ b/index.js @@ -251,9 +251,9 @@ module.exports = function(version, _options) { if (languages.instructions[language]) return language; var codes = languages.parseLanguageIntoCodes(language); - var languageCode = codes.languageCode; - var scriptCode = codes.scriptCode; - var countryCode = codes.countryCode; + var languageCode = codes.language; + var scriptCode = codes.script; + var regionCode = codes.region; var supportedLanguageCodes = languages.supportedCodes.map(function(language) { return language.toLowerCase().split('-')[0]; @@ -264,9 +264,9 @@ module.exports = function(version, _options) { return languageCode + '-' + scriptCode; } - // Same language code and country code (lng-CC) - if (languages.instructions[languageCode + '-' + countryCode]) { - return languageCode + '-' + countryCode; + // Same language code and region code (lng-CC) + if (languages.instructions[languageCode + '-' + regionCode]) { + return languageCode + '-' + regionCode; } // Same language code (lng) @@ -276,24 +276,24 @@ module.exports = function(version, _options) { // Same language code and any script code (lng-Scpx) and the found language contains a script var anyScript = languages.parsedSupportedCodes.find(function (language) { - return language.languageCode === languageCode && language.scriptCode; + return language.language === languageCode && language.script; }); if (anyScript) { return anyScript.locale; } - // Same language code and any country code (lng-CX) + // Same language code and any region code (lng-CX) var anyCountry = languages.parsedSupportedCodes.find(function (language) { - return language.languageCode === languageCode && language.scriptCode; + return language.language === languageCode && language.script; }); if (anyCountry) { return anyCountry.locale; } // Only language code provided, but we on support this language code - // with either script/country code. + // with either script/region code. var sameLanguage = languages.parsedSupportedCodes.find(function (language) { - return language.languageCode === languageCode; + return language.language === languageCode; }); if (sameLanguage) { return sameLanguage.locale; diff --git a/languages.js b/languages.js index f3b61556a..4d3fff26b 100755 --- a/languages.js +++ b/languages.js @@ -67,9 +67,9 @@ function parseLanguageIntoCodes (language) { return { locale: locale.join('-'), - languageCode: match[1], - scriptCode: match[2], - countryCode: match[3] + language: match[1], + script: match[2], + region: match[3] }; } diff --git a/test/index_test.js b/test/index_test.js index c9bd58148..f923c0fd5 100644 --- a/test/index_test.js +++ b/test/index_test.js @@ -287,16 +287,16 @@ tape.test('v5 compile', function(t) { /* eslint-disable */ t.test('parseLanguageIntoCodes', function(t) { - t.deepEqual(languages.parseLanguageIntoCodes('foo'), { countryCode: undefined, languageCode: 'fo', locale: 'fo', scriptCode: undefined }); - t.deepEqual(languages.parseLanguageIntoCodes('en-US'), { countryCode: 'US', languageCode: 'en', locale: 'en-US', scriptCode: undefined }); - t.deepEqual(languages.parseLanguageIntoCodes('zh-CN'), { countryCode: 'CN', languageCode: 'zh', locale: 'zh-CN', scriptCode: undefined }); - t.deepEqual(languages.parseLanguageIntoCodes('zh-Hant'), { countryCode: undefined, languageCode: 'zh', locale: 'zh-Hant', scriptCode: 'Hant' }); - t.deepEqual(languages.parseLanguageIntoCodes('zh-Hant-TW'), { countryCode: 'TW', languageCode: 'zh', locale: 'zh-Hant-TW', scriptCode: 'Hant' }); - t.deepEqual(languages.parseLanguageIntoCodes('zh'), { countryCode: undefined, languageCode: 'zh', locale: 'zh', scriptCode: undefined }); - t.deepEqual(languages.parseLanguageIntoCodes('es-MX'), { countryCode: 'MX', languageCode: 'es', locale: 'es-MX', scriptCode: undefined }); - t.deepEqual(languages.parseLanguageIntoCodes('es-ES'), { countryCode: 'ES', languageCode: 'es', locale: 'es-ES', scriptCode: undefined }); - t.deepEqual(languages.parseLanguageIntoCodes('pt-PT'), { countryCode: 'PT', languageCode: 'pt', locale: 'pt-PT', scriptCode: undefined }); - t.deepEqual(languages.parseLanguageIntoCodes('pt'), { countryCode: undefined, languageCode: 'pt', locale: 'pt', scriptCode: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('foo'), { region: undefined, language: 'fo', locale: 'fo', script: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('en-US'), { region: 'US', language: 'en', locale: 'en-US', script: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('zh-CN'), { region: 'CN', language: 'zh', locale: 'zh-CN', script: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('zh-Hant'), { region: undefined, language: 'zh', locale: 'zh-Hant', script: 'Hant' }); + t.deepEqual(languages.parseLanguageIntoCodes('zh-Hant-TW'), { region: 'TW', language: 'zh', locale: 'zh-Hant-TW', script: 'Hant' }); + t.deepEqual(languages.parseLanguageIntoCodes('zh'), { region: undefined, language: 'zh', locale: 'zh', script: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('es-MX'), { region: 'MX', language: 'es', locale: 'es-MX', script: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('es-ES'), { region: 'ES', language: 'es', locale: 'es-ES', script: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('pt-PT'), { region: 'PT', language: 'pt', locale: 'pt-PT', script: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('pt'), { region: undefined, language: 'pt', locale: 'pt', script: undefined }); t.end(); }); /* eslint-enable */ From d5b63317ae262db9498df32adac2470a3cc5834b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Thu, 5 Oct 2017 16:03:11 -0700 Subject: [PATCH 23/25] Eliminated extra map when matching languages --- index.js | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/index.js b/index.js index d490325a1..1d432c359 100644 --- a/index.js +++ b/index.js @@ -255,10 +255,6 @@ module.exports = function(version, _options) { var scriptCode = codes.script; var regionCode = codes.region; - var supportedLanguageCodes = languages.supportedCodes.map(function(language) { - return language.toLowerCase().split('-')[0]; - }); - // Same language code and script code (lng-Scpt) if (languages.instructions[languageCode + '-' + scriptCode]) { return languageCode + '-' + scriptCode; @@ -270,7 +266,7 @@ module.exports = function(version, _options) { } // Same language code (lng) - if (supportedLanguageCodes[languageCode]) { + if (languages.instructions[languageCode]) { return languageCode; } @@ -284,21 +280,12 @@ module.exports = function(version, _options) { // Same language code and any region code (lng-CX) var anyCountry = languages.parsedSupportedCodes.find(function (language) { - return language.language === languageCode && language.script; + return language.language === languageCode && language.region; }); if (anyCountry) { return anyCountry.locale; } - // Only language code provided, but we on support this language code - // with either script/region code. - var sameLanguage = languages.parsedSupportedCodes.find(function (language) { - return language.language === languageCode; - }); - if (sameLanguage) { - return sameLanguage.locale; - } - return 'en'; } }; From 3684ed3ada22e18d5719a2c2ec33b32899f935a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Thu, 5 Oct 2017 16:10:44 -0700 Subject: [PATCH 24/25] Moved language tests to the right file --- test/index_test.js | 16 ---------------- test/languages_test.js | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/test/index_test.js b/test/index_test.js index f923c0fd5..414bc9189 100644 --- a/test/index_test.js +++ b/test/index_test.js @@ -285,22 +285,6 @@ tape.test('v5 compile', function(t) { t.end(); }); - /* eslint-disable */ - t.test('parseLanguageIntoCodes', function(t) { - t.deepEqual(languages.parseLanguageIntoCodes('foo'), { region: undefined, language: 'fo', locale: 'fo', script: undefined }); - t.deepEqual(languages.parseLanguageIntoCodes('en-US'), { region: 'US', language: 'en', locale: 'en-US', script: undefined }); - t.deepEqual(languages.parseLanguageIntoCodes('zh-CN'), { region: 'CN', language: 'zh', locale: 'zh-CN', script: undefined }); - t.deepEqual(languages.parseLanguageIntoCodes('zh-Hant'), { region: undefined, language: 'zh', locale: 'zh-Hant', script: 'Hant' }); - t.deepEqual(languages.parseLanguageIntoCodes('zh-Hant-TW'), { region: 'TW', language: 'zh', locale: 'zh-Hant-TW', script: 'Hant' }); - t.deepEqual(languages.parseLanguageIntoCodes('zh'), { region: undefined, language: 'zh', locale: 'zh', script: undefined }); - t.deepEqual(languages.parseLanguageIntoCodes('es-MX'), { region: 'MX', language: 'es', locale: 'es-MX', script: undefined }); - t.deepEqual(languages.parseLanguageIntoCodes('es-ES'), { region: 'ES', language: 'es', locale: 'es-ES', script: undefined }); - t.deepEqual(languages.parseLanguageIntoCodes('pt-PT'), { region: 'PT', language: 'pt', locale: 'pt-PT', script: undefined }); - t.deepEqual(languages.parseLanguageIntoCodes('pt'), { region: undefined, language: 'pt', locale: 'pt', script: undefined }); - t.end(); - }); - /* eslint-enable */ - t.test('respects options.instructionStringHook', function(assert) { var v5Compiler = compiler('v5', { hooks: { diff --git a/test/languages_test.js b/test/languages_test.js index a60327786..83272e80f 100644 --- a/test/languages_test.js +++ b/test/languages_test.js @@ -35,3 +35,19 @@ tape.test('verify language files structure', function(assert) { assert.end(); }); + +/* eslint-disable */ +tape.test('parseLanguageIntoCodes', function(t) { + t.deepEqual(languages.parseLanguageIntoCodes('foo'), { region: undefined, language: 'fo', locale: 'fo', script: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('en-US'), { region: 'US', language: 'en', locale: 'en-US', script: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('zh-CN'), { region: 'CN', language: 'zh', locale: 'zh-CN', script: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('zh-Hant'), { region: undefined, language: 'zh', locale: 'zh-Hant', script: 'Hant' }); + t.deepEqual(languages.parseLanguageIntoCodes('zh-Hant-TW'), { region: 'TW', language: 'zh', locale: 'zh-Hant-TW', script: 'Hant' }); + t.deepEqual(languages.parseLanguageIntoCodes('zh'), { region: undefined, language: 'zh', locale: 'zh', script: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('es-MX'), { region: 'MX', language: 'es', locale: 'es-MX', script: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('es-ES'), { region: 'ES', language: 'es', locale: 'es-ES', script: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('pt-PT'), { region: 'PT', language: 'pt', locale: 'pt-PT', script: undefined }); + t.deepEqual(languages.parseLanguageIntoCodes('pt'), { region: undefined, language: 'pt', locale: 'pt', script: undefined }); + t.end(); +}); +/* eslint-enable */ From d32fbc945680cb6b5d9488be8a1bcb90dc7c9a43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Thu, 5 Oct 2017 16:10:52 -0700 Subject: [PATCH 25/25] Copyedited changelog and readme --- CHANGELOG.md | 2 +- Readme.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cab0c98d4..c7167a94b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ All notable changes to this project will be documented in this file. For change ## Master -- Added `getBestMatchingLanguage` for determining the best language when it's unknown if the users locale is supported. +- Added `getBestMatchingLanguage` for determining the closest available language. Pass a user locale into this method before passing the return value into `compile`. [#168](https://github.com/Project-OSRM/osrm-text-instructions/pull/168) ## 0.8.0 2017-10-04 diff --git a/Readme.md b/Readme.md index 9f9344029..f00c36d81 100644 --- a/Readme.md +++ b/Readme.md @@ -27,8 +27,8 @@ Grammatical cases and other translated strings customization after [Transifex](h var version = 'v5'; var osrmTextInstructions = require('osrm-text-instructions')(version); -// If you are unsure if the users locale is supported, use `getBestMatchingLanguage` method to find an appropriate language. -var language = osrmTextInstructions.getBestMatchingLanguage('en'); +// If you’re unsure if the user’s locale is supported, use `getBestMatchingLanguage` method to find an appropriate language. +var language = osrmTextInstructions.getBestMatchingLanguage('en-US'); response.legs.forEach(function(leg) { leg.steps.forEach(function(step) {