Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add function to allow users to register their own parser hooks #46

Merged
merged 6 commits into from
Apr 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,30 @@ The original wiki links markup is elaborate, but here we only support simple syn
* Internal links: `[[pageTitle]]` or `[[pageTitle|displayText]]`. For example `[[Apple]]` gives `<a href="./Apple" title="Apple">Apple</a>`.
* External links: `[https://example.com]` or `[https://example.com display text]`

## Extending the parser

Following example illustrates extending the parser to support more parser plugins

```js
const banana = new Banana('en');
banana.registerParserPlugin('sitename', () => {
return 'Wikipedia';
});
banana.registerParserPlugin('link', (nodes) => {
return '<a href="' + nodes[1] + '">' + nodes[0] + '</a>';
});
```

This will parse the message
```js
banana.i18n('{{link:{{SITENAME}}|https://en.wikipedia.org}}');
```
to

```
<a href="https://en.wikipedia.org">Wikipedia</a>
```

## Message documentation

The message keys and messages won't give a enough context about the message being translated to the translator. Whenever a developer adds a new message, it is a usual practice to document the message to a file named qqq.json
Expand Down
23 changes: 23 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import BananaParser from './parser'
import BananaMessageStore from './messagestore'
import BananaEmitter from './emitter'
import fallbacks from './languages/fallbacks.json'

export default class Banana {
Expand Down Expand Up @@ -73,4 +74,26 @@ export default class Banana {
}
return messageKey
}

/**
* Register a plugin for the library's message parser
* Example:
* <pre>
* banana.registerParserPlugin('foobar', nodes => {
* return nodes[0] === 'foo' ? nodes[1] : nodes[2]
* }
* </pre>
* Usage:
* <pre>
* banana.i18n('{{foobar:foo|first message|second message}}') --> 'first message'
* banana.i18n('{{foobar:bar|first message|second message}}') --> 'second message'
* </pre>
* See emitter.js for built-in parser operations.
* @param {string} name - the name of the plugin
* @param {Function} plugin - the plugin function. It receives nodes as argument -
* a mixed array corresponding to the pipe-separated objects in the operation.
*/
registerParserPlugin (name, plugin) {
BananaEmitter.prototype[name] = plugin
}
}
30 changes: 30 additions & 0 deletions test/banana.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,36 @@ describe('Banana', function () {
)
})

it('should allow custom parser plugins', () => {
siddharthvp marked this conversation as resolved.
Show resolved Hide resolved
let locale = 'en'
const banana = new Banana(locale)
banana.registerParserPlugin('foobar', (nodes) => {
return nodes[0] === 'foo' ? nodes[1] : nodes[2]
})
assert.strictEqual(
banana.i18n('{{foobar:foo|first|second}}'),
'first',
'Emits first argument on passing foo to foobar plugin hook'
)
assert.strictEqual(
banana.i18n('{{foobar:bar|first|second}}'),
'second',
'Emits second argument on passing bar to foobar plugin hook'
)

banana.registerParserPlugin('sitename', () => {
return 'Wikipedia'
})
banana.registerParserPlugin('link', (nodes) => {
return '<a href="' + nodes[1] + '">' + nodes[0] + '</a>'
})
assert.strictEqual(
banana.i18n('{{link:{{SITENAME}}|https://en.wikipedia.org}}'),
'<a href="https://en.wikipedia.org">Wikipedia</a>',
'complex use of custom parser plugins'
)
})

it('should parse the Arabic message', () => {
const locale = 'ar'
const banana = new Banana(locale)
Expand Down
3 changes: 2 additions & 1 deletion types/banana-i18n.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export interface Messages {
[ messageKey: string ]: string|Record<string, any>;
[ messageKey: string ]: string|Record<string, any>;
}

export interface BananaOptions {
Expand All @@ -22,6 +22,7 @@ export interface Banana {
setLocale( locale: string ): void;
getFallbackLocales(): string[];
getMessage( messageKey: string ): string;
registerParserPlugin( name: string, plugin: ((nodes: ParameterType[]) => string) ): void;
}

export const Banana: BananaConstructor;