From 2a13edf418cab7beb9efb5ca995bffb758dc101b Mon Sep 17 00:00:00 2001 From: Siddharth VP Date: Sun, 16 May 2021 02:13:24 +0530 Subject: [PATCH] Don't throw on `{{X}}` syntax where X is not a valid i18n parser operator Render them literally instead. Fixes issue https://github.com/wikimedia-gadgets/twinkle-core/issues/6. --- README.md | 6 ++++-- package-lock.json | 4 ++-- package.json | 2 +- src/emitter.js | 7 ++++++- test/banana.test.js | 21 +++++++++++++++++++++ 5 files changed, 34 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7099d98..ff8b7ef 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,10 @@ Some of the changes done in this fork have been merged upstream. The only signif - ~~This needs the knowledge of how different languages separate words – this can be done using the MediaWiki i18n messages `word-separator`, `comma-separator` and `and` which we fetch using the MediaWiki API at the build step.~~ - Reverted. Now that custom parser hooks are supported, this can instead be implemented as a parser hook. 4. (366319eb) Added support for custom parser hooks. Mostly intended for cases where the hook relies on data that is not available with orange-i18n but is present in the client script. - - MERGED UPSTREAM in https://github.com/wikimedia/banana-i18n/pull/46 -5. Added TypeScript type definitions. + - MERGED UPSTREAM in https://github.com/wikimedia/banana-i18n/pull/46 +5. Added TypeScript type definitions. + - ALSO implemented in upstream +6. Make it easier to mention wiki-templates in messages by not throwing an error for `{{X}}` syntax where X is not a valid i18n parser operator. Such usages are rendered literally instead. #### Removed/missing features: Certain features are removed/missing in order to keep the library light-weight. diff --git a/package-lock.json b/package-lock.json index 11c351b..1d326bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { "name": "orange-i18n", - "version": "3.0.0", + "version": "3.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "3.0.0", + "version": "3.1.0", "license": "MIT", "devDependencies": { "@rollup/plugin-commonjs": "^17.1.0", diff --git a/package.json b/package.json index 8264c2e..0601078 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orange-i18n", - "version": "3.0.0", + "version": "3.1.0", "description": "Banana Internationalization library", "main": "dist/banana-i18n.js", "typings": "types/index.d.ts", diff --git a/src/emitter.js b/src/emitter.js index 1d1065d..a16d2e1 100644 --- a/src/emitter.js +++ b/src/emitter.js @@ -1,4 +1,5 @@ import languages from './languages' +import BananaParser from './parser' /** * Matches the first strong directionality codepoint: @@ -54,7 +55,11 @@ class BananaEmitter { if (typeof this[operation] === 'function') { ret = this[operation](subnodes, replacements) } else { - throw new Error('unknown operation "' + operation + '"') + // they probably are just talking about wiki templates + // In the name of the wikitemplate, any operators like plural, grammar, etc CANNOT be used. + // Placeholders ($1, $2, ...) can be used + // All operators can be used in wikitemplate parameters. + ret = '{{' + new BananaParser(this.locale).simpleParse(node[0], replacements) + subnodes.map(n => '|' + n) + '}}' } break diff --git a/test/banana.test.js b/test/banana.test.js index c941dfb..0ddc307 100644 --- a/test/banana.test.js +++ b/test/banana.test.js @@ -411,6 +411,27 @@ describe('Banana', function () { assert.strictEqual(banana.i18n('message_2'), 'Message two') }) + it('should not throw errors when referring to wiki-templates', () => { + let banana = new Banana('en') + + // simple + assert.strictEqual(banana.i18n('{{Cleanup}}'), '{{Cleanup}}', 'simple') + + // should support processing of parameters + assert.strictEqual(banana.i18n('{{Cleanup|count={{PLURAL:$1|$1|$1}}}}', '2'), '{{Cleanup|count=2}}', 'supports processing of parameters') + + // should support template names containing placeholders + assert.strictEqual(banana.i18n('{{$1}}', 'Cleanup'), '{{Cleanup}}', 'supports template name being a $N') + + assert.strictEqual(banana.i18n('{{$1|minor=$2}}', 'Cleanup', 'yes'), '{{Cleanup|minor=yes}}', 'complex') + + assert.strictEqual(banana.i18n('{{cleanup| count = 23}}'), '{{cleanup| count = 23}}', 'preserves spacing in wikitemplates') + assert.strictEqual(banana.i18n('{{cleanup | count = 23 }}'), '{{cleanup | count = 23 }}', 'preserves spacing in wikitemplates') + + // won't work + // assert.strictEqual(banana.i18n('{{{{PLURAL:$1|$1|$1}}}}', '4'), '{{4}}', 'support operations in template name') + }) + it('should throw errors on invalid locales', () => { assert.throws(() => { // eslint-disable-next-line no-new