/** * Timeline tag for Hexo * Syntax: * {% timeline [headline],[color] %} * * [content] * * * [content] * * {% endtimeline %} */ 'use strict' const timeLineFn = (args, content) => { // Use named capture groups for better readability const tlBlock = /\n(?[\s\S]*?)/g // Pre-compile markdown render function const renderMd = text => hexo.render.renderSync({ text, engine: 'markdown' }) // Parse arguments more efficiently const [text, color = ''] = args.length ? args.join(' ').split(',') : [] // Build initial headline if text exists const headline = text ? `
${renderMd(text)}
` : '' // Match all timeline blocks in one pass and transform const items = Array.from(content.matchAll(tlBlock)) .map(({ groups: { title, content } }) => `
${renderMd(title)}
${renderMd(content)}
` ) .join('') return `
${headline}${items}
` } hexo.extend.tag.register('timeline', timeLineFn, { ends: true })