UNPKG

@lowlighter/remark-ruby

Version:

Custom syntax for remarkjs, adding ruby (furigana) to markdown.

97 lines (91 loc) 2.49 kB
const GROUP_PATTERN = /\[[^\]]+\]/; function delimitText(input) { let text = input; const ret = []; let match = GROUP_PATTERN.exec(text); if (!match) return text; while (match) { if (match.index !== 0) { ret.push(text.substr(0, match.index)); } ret.push(match[0].substr(1, match[0].length - 2)); text = text.substr(match[0].length + match.index); match = GROUP_PATTERN.exec(text); } if (ret.length <= 1) return ret[0]; return ret; } module.exports = function fromMarkdown(parenthesis) { return { enter: { ruby(token) { this.enter({ type: 'ruby', base: null, text: null, children: [], data: { hName: 'ruby', hChildren: [ ], }, }, token); }, rubyText() { this.stack.push({ type: 'fragment', children: [] }); }, rubyPronunciation() { this.stack.push({ type: 'fragment', children: [] }); }, }, exit: { ruby(token) { const element = this.stack[this.stack.length - 1]; const text = element.base; const pronunciation = element.text; let rubyBase; if (typeof text === 'string') { rubyBase = [{ type: 'text', value: text }]; } else { rubyBase = text.map(base => ({ type: 'element', children: [{ type: 'text', value: base }], tagName: 'rb', })); } const rubyText = [].concat(pronunciation).map(p => ({ type: 'element', children: [{ type: 'text', value: p }], tagName: 'rt', })); element.data.hChildren = [ rubyBase, { type: 'element', children: [ { type: 'text', value: parenthesis[0] }, ], tagName: 'rp', }, rubyText, { type: 'element', children: [ { type: 'text', value: parenthesis[parenthesis.length - 1] }, ], tagName: 'rp', }, ].reduce((prev, curr) => prev.concat(curr), []); this.exit(token); }, rubyText() { const data = delimitText(this.resume()); this.stack[this.stack.length - 1].base = data; }, rubyPronunciation() { const data = delimitText(this.resume()); this.stack[this.stack.length - 1].text = data; }, }, }; };