support translations markup
This commit is contained in:
parent
bea2b12f2d
commit
1602e19214
|
@ -1,5 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
import { markupToReact } from './markup';
|
||||||
let activeLanguage = 'en';
|
let activeLanguage = 'en';
|
||||||
let fallbackLanguage = 'en';
|
let fallbackLanguage = 'en';
|
||||||
let repository = {};
|
let repository = {};
|
||||||
|
@ -36,5 +36,7 @@ export function setLanguage(code: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function translate(key: string) {
|
export default function translate(key: string) {
|
||||||
return repository[activeLanguage][key] || repository[fallbackLanguage][key] || key;
|
return markupToReact(
|
||||||
|
repository[activeLanguage][key] || repository[fallbackLanguage][key] || key
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
// ad-hoc parser for translation strings
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const BOLD_REGEXP = /(\*\*)(.*?)\1/;
|
||||||
|
const LINK_REGEXP = /\[([^\[]+)\]\(([^\)]+)\)/;
|
||||||
|
|
||||||
|
function linkify(mdString: string) {
|
||||||
|
const parts = mdString.split(LINK_REGEXP);
|
||||||
|
if (parts.length === 1) {
|
||||||
|
return parts[0];
|
||||||
|
}
|
||||||
|
const result = [];
|
||||||
|
let i = 0;
|
||||||
|
while (i + 1 < parts.length) {
|
||||||
|
result.push(parts[i]);
|
||||||
|
result.push(<a href={parts[i + 2]} target="_blank">{parts[i + 1]}</a>);
|
||||||
|
i += 3;
|
||||||
|
}
|
||||||
|
result.push(parts[parts.length - 1]);
|
||||||
|
return result.filter(Boolean);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function markupToReact(mdString: string) {
|
||||||
|
const parts = mdString.split(BOLD_REGEXP);
|
||||||
|
if (parts.length === 1) {
|
||||||
|
return linkify(parts[0]);
|
||||||
|
}
|
||||||
|
let result = [];
|
||||||
|
let i = 0;
|
||||||
|
while (i + 1 < parts.length) {
|
||||||
|
result = result.concat(linkify(parts[i]));
|
||||||
|
result.push(<b>{parts[i + 2]}</b>);
|
||||||
|
i += 3;
|
||||||
|
}
|
||||||
|
result = result.concat(linkify(parts.pop()));
|
||||||
|
return result.filter(Boolean);
|
||||||
|
}
|
|
@ -10,7 +10,6 @@
|
||||||
"^routing": "<rootDir>/common/routing",
|
"^routing": "<rootDir>/common/routing",
|
||||||
"^components$": "<rootDir>/common/components",
|
"^components$": "<rootDir>/common/components",
|
||||||
"^containers$": "<rootDir>/common/containers",
|
"^containers$": "<rootDir>/common/containers",
|
||||||
"^config$": "<rootDir>/common/config/test.js",
|
"^translations(.*)": "<rootDir>/common/translations$1"
|
||||||
"^translations$": "<rootDir>/common/translations"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { markupToReact } from 'translations/markup';
|
||||||
|
|
||||||
|
describe('markupToReact', () => {
|
||||||
|
it('passes plain string as is', () => {
|
||||||
|
const value = 'string';
|
||||||
|
const expected = 'string';
|
||||||
|
expect(markupToReact(value)).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('transforms bold syntax', () => {
|
||||||
|
let value = '**foo**';
|
||||||
|
let expected = [<b>foo</b>];
|
||||||
|
expect(markupToReact(value)).toEqual(expected);
|
||||||
|
|
||||||
|
value = '**foo** bar';
|
||||||
|
expected = [<b>foo</b>, ' bar'];
|
||||||
|
expect(markupToReact(value)).toEqual(expected);
|
||||||
|
|
||||||
|
value = 'bar **foo**';
|
||||||
|
expected = ['bar ', <b>foo</b>];
|
||||||
|
expect(markupToReact(value)).toEqual(expected);
|
||||||
|
|
||||||
|
value = 'bar **foo** baz';
|
||||||
|
expected = ['bar ', <b>foo</b>, ' baz'];
|
||||||
|
expect(markupToReact(value)).toEqual(expected);
|
||||||
|
|
||||||
|
value = '**foo****bar**';
|
||||||
|
expected = [<b>foo</b>, <b>bar</b>];
|
||||||
|
expect(markupToReact(value)).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('transforms link syntax', () => {
|
||||||
|
let value = '[foo](http://google.com)';
|
||||||
|
let expected = [<a href="http://google.com" target="_blank">foo</a>];
|
||||||
|
expect(markupToReact(value)).toEqual(expected);
|
||||||
|
|
||||||
|
value = '[foo](http://google.com) bar';
|
||||||
|
expected = [<a href="http://google.com" target="_blank">foo</a>, ' bar'];
|
||||||
|
expect(markupToReact(value)).toEqual(expected);
|
||||||
|
|
||||||
|
value = 'bar [foo](http://google.com)';
|
||||||
|
expected = ['bar ', <a href="http://google.com" target="_blank">foo</a>];
|
||||||
|
expect(markupToReact(value)).toEqual(expected);
|
||||||
|
|
||||||
|
value = 'bar [foo](http://google.com) baz';
|
||||||
|
expected = ['bar ', <a href="http://google.com" target="_blank">foo</a>, ' baz'];
|
||||||
|
expect(markupToReact(value)).toEqual(expected);
|
||||||
|
|
||||||
|
value = '[foo](http://google.com)[bar](http://google.ca)';
|
||||||
|
expected = [
|
||||||
|
<a href="http://google.com" target="_blank">foo</a>,
|
||||||
|
<a href="http://google.ca" target="_blank">bar</a>
|
||||||
|
];
|
||||||
|
expect(markupToReact(value)).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('converts mixed syntax', () => {
|
||||||
|
let value = 'Bold **foo** link [foo](http://google.com) text';
|
||||||
|
let expected = [
|
||||||
|
'Bold ',
|
||||||
|
<b>foo</b>,
|
||||||
|
' link ',
|
||||||
|
<a href="http://google.com" target="_blank">foo</a>,
|
||||||
|
' text'
|
||||||
|
];
|
||||||
|
expect(markupToReact(value)).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue