diff --git a/packages/bbob-preset-html5/lib/index.js b/packages/bbob-preset-html5/lib/index.js
index 3c5effb..ed8d563 100644
--- a/packages/bbob-preset-html5/lib/index.js
+++ b/packages/bbob-preset-html5/lib/index.js
@@ -46,6 +46,61 @@
// [b]bolded text[/b] => bolded text
+const getStyleFromAttrs = (attrs) => {
+ const styles = [];
+
+ if (attrs.color) {
+ styles.push(`color:${attrs.color};`);
+ }
+
+ if (attrs.size) {
+ styles.push(`font-size:${attrs.size};`);
+ }
+
+ return styles.join(' ');
+};
+
+const asListItems = (content) => {
+ const listItems = [];
+ let listIdx = 0;
+ const createItemNode = () => ({ tag: 'li', attrs: {}, content: [] });
+ const ensureListItem = (val) => {
+ listItems[listIdx] = listItems[listIdx] || val;
+ };
+ const addItem = (val) => {
+ if (listItems[listIdx] && listItems[listIdx].content) {
+ listItems[listIdx].content = listItems[listIdx].content.concat(val);
+ } else {
+ listItems[listIdx] = listItems[listIdx].concat(val);
+ }
+ };
+ content.forEach(el => {
+ if (typeof el === 'string' && el[0] === '*') {
+ if (listItems[listIdx]) {
+ listIdx++;
+ }
+ ensureListItem(createItemNode());
+ addItem(el.substr(1));
+ } else if (typeof el === 'object' && el.tag && el.tag === '*') {
+ if (listItems[listIdx]) {
+ listIdx++;
+ }
+ ensureListItem(createItemNode());
+ } else {
+ if (listItems[listIdx] && !listItems[listIdx].tag) {
+ listIdx++;
+ ensureListItem(el);
+ } else if (listItems[listIdx]) {
+ addItem(el);
+ } else {
+ ensureListItem(el);
+ }
+ }
+ });
+
+ return [].concat(listItems);
+};
+
const processors = {
b: node => ({
tag: 'span',
@@ -61,16 +116,66 @@ const processors = {
},
content: node.content,
}),
+ u: node => ({
+ tag: 'span',
+ attrs: {
+ style: 'text-decoration: underline;',
+ },
+ content: node.content,
+ }),
+ s: node => ({
+ tag: 'span',
+ attrs: {
+ style: 'text-decoration: line-through;',
+ },
+ content: node.content,
+ }),
+ url: (node, { render }) => ({
+ tag: 'a',
+ attrs: {
+ href: node.attrs.url ? node.attrs.url : render(node.content),
+ },
+ content: node.content,
+ }),
+ img: (node, { render }) => ({
+ tag: 'img',
+ attrs: {
+ src: render(node.content),
+ },
+ content: null,
+ }),
+ quote: node => ({
+ tag: 'blockquote',
+ attrs: {},
+ content: [{
+ tag: 'p',
+ attrs: {},
+ content: node.content,
+ }],
+ }),
+ code: node => ({
+ tag: 'pre',
+ attrs: {},
+ content: node.content,
+ }),
+ style: node => ({
+ tag: 'span',
+ attrs: {
+ style: getStyleFromAttrs(node.attrs),
+ },
+ content: node.content,
+ }),
+ list: node => ({
+ tag: 'ul',
+ attrs: {},
+ content: asListItems(node.content),
+ }),
};
module.exports = function html5Preset(opts = {}) {
- return function process(tree) {
- tree.forEach((node) => {
- if (node.tag && processors[node.tag]) {
- return processors[node.tag](node, opts);
- }
-
- return node;
- });
+ return function process(tree, core) {
+ tree.walk(node => (node.tag && processors[node.tag]
+ ? processors[node.tag](node, core)
+ : node));
};
};
diff --git a/packages/bbob-preset-html5/test/index.test.js b/packages/bbob-preset-html5/test/index.test.js
index ba659db..d6b2d3e 100644
--- a/packages/bbob-preset-html5/test/index.test.js
+++ b/packages/bbob-preset-html5/test/index.test.js
@@ -1,19 +1,108 @@
const preset = require('../lib/index');
-const bbob = require('@bbob/core');
+const core = require('@bbob/core');
-const processor = bbob([
- preset(),
-]);
+const parse = input => core([preset()]).process(input).html;
-describe('bbob-preset-html5', () => {
- test.skip('render [url]', () => {
- const input = '[url=https://ru.wikipedia.org]Text[/url]';
- const result = 'Text';
-
- expect(processor.process(input, { sync: true })).toBe(result);
+describe('@bbob/preset-html5', () => {
+ test('[b]bolded text[/b]', () => {
+ const input = '[b]bolded text[/b]';
+ const result = 'bolded text';
+ expect(parse(input)).toBe(result);
});
- test('dummy', () => {
- expect(1).toBe(1);
- })
+ test('[i]italicized text[/i]', () => {
+ const input = '[i]italicized text[/i]';
+ const result = 'italicized text';
+ expect(parse(input)).toBe(result);
+ });
+
+ test('[u]underlined text[/u]', () => {
+ const input = '[u]underlined text[/u]';
+ const result = 'underlined text';
+ expect(parse(input)).toBe(result);
+ });
+
+ test('[s]strikethrough text[/s]', () => {
+ const input = '[s]strikethrough text[/s]';
+ const result = 'strikethrough text';
+ expect(parse(input)).toBe(result);
+ });
+
+ test('[url]https://en.wikipedia.org[/url]', () => {
+ const input = '[url]https://en.wikipedia.org[/url]';
+ const result = 'https://en.wikipedia.org';
+
+ expect(parse(input)).toBe(result);
+ });
+
+ test('[url=http://step.pgc.edu/]ECAT[/url]', () => {
+ const input = '[url=http://step.pgc.edu/]ECAT[/url]';
+ const result = 'ECAT';
+
+ expect(parse(input)).toBe(result);
+ });
+
+ test('[img]https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/Go-home-2.svg/100px-Go-home-2.svg.png[/img]', () => {
+ const input = '[img]https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/Go-home-2.svg/100px-Go-home-2.svg.png[/img]';
+ const result = '
';
+
+ expect(parse(input)).toBe(result);
+ });
+
+ test('[quote="author"]quoted text[/quote]', () => {
+ const input = '[quote="author"]quoted text[/quote]';
+ const result = '
'; + + expect(parse(input)).toBe(result); + }); + + test('[code]monospaced text[/code]', () => { + const input = '[code]monospaced text[/code]'; + const result = 'quoted text
monospaced text'; + + expect(parse(input)).toBe(result); + }); + + test('[style size="15px"]Large Text[/style]', () => { + const input = '[style size="15px"]Large Text[/style]'; + const result = 'Large Text'; + + expect(parse(input)).toBe(result); + }); + + test('[style color="red"]Red Text[/style]', () => { + const input = '[style color="red"]Red Text[/style]'; + const result = 'Red Text'; + + expect(parse(input)).toBe(result); + }); + + test(`[list][*]Entry 1[/list]`, () => { + const input = `[list][*]Entry 1[*]Entry 2[/list]`; + const result = '
| table 1 | table 2 |
| table 3 | table 4 |