From a99e432380e7459fbf7ae6e777d311bbaa195746 Mon Sep 17 00:00:00 2001 From: nobkd <44443899+nobkd@users.noreply.github.com> Date: Mon, 3 Feb 2025 20:10:05 +0100 Subject: [PATCH] append data attrs on html tags --- packages/nuemark/src/render-tag.js | 22 +++++++++++++++++----- packages/nuemark/test/block.test.js | 28 ++++++++++++++++++++++++++++ packages/nuemark/test/inline.test.js | 9 +++++++++ 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/packages/nuemark/src/render-tag.js b/packages/nuemark/src/render-tag.js index f146afb1..0cf3e7ba 100644 --- a/packages/nuemark/src/render-tag.js +++ b/packages/nuemark/src/render-tag.js @@ -33,12 +33,14 @@ const TAGS = { }, block() { - const { render, attr, blocks, name } = this + const { render, attr, data, blocks, name } = this const divs = sectionize(blocks) const html = !divs || !divs[1] ? render(blocks) : divs.map(blocks => elem('div', render(blocks))).join('\n') + Object.assign(attr, data) + return elem(attr.popover ? 'dialog' : name || 'div', attr, html) }, @@ -85,6 +87,15 @@ const TAGS = { return elem('figure', attr, img) }, + inline() { + const { name, attr, data, opts } = this + + const content = data._ + delete data._ + Object.assign(attr, data) + + return elem(name, attr, this.renderInline(content, opts)) + }, list() { const items = this.sections || getListItems(this.blocks) @@ -153,16 +164,17 @@ export function renderIcon(name, symbol, icon_dir) { export function renderTag(tag, opts = {}) { const tags = { ...TAGS, ...opts.tags } - const fn = tags[!tag.is_block && tag.name || 'block'] + const tag_fn = !tag.name || tag.to_block ? 'block' : tag.to_inline ? 'inline' : tag.name + const fn = tags[tag_fn] if (!fn) { // native html tags if (HTML_TAGS.includes(tag.name)) { // inline / block without blocks - if (tag.is_inline || !tag.blocks?.length) return elem(tag.name, tag.attr, renderInline(tag.data?._, opts)) - + if (tag.is_inline || !tag.blocks?.length) tag.to_inline = true // block - tag.is_block = true + else tag.to_block = true + return renderTag(tag) } diff --git a/packages/nuemark/test/block.test.js b/packages/nuemark/test/block.test.js index 966a3632..5f7b98b5 100644 --- a/packages/nuemark/test/block.test.js +++ b/packages/nuemark/test/block.test.js @@ -56,6 +56,34 @@ test('block html tag without children with content', () => { expect(html).toBe('
content
\n

no content

') }) +test.skip('block html tag with starting ul', () => { + const { blocks } = parseBlocks(['[div]', ' - hi', ' - hello']) + expect(blocks.length).toBe(1) + expect(blocks[0].blocks.length).toBe(1) + + const html = renderBlocks(blocks) + expect(html).toBe('
') +}) + +test('inlined block html with attrs', () => { + const { blocks } = parseBlocks(['[div myattr="data" "content"]']) + console.log(blocks) + expect(blocks.length).toBe(1) + expect(blocks[0].data).toEqual({ myattr: 'data', _: 'content' }) + + const html = renderBlocks(blocks) + expect(html).toBe('
content
') +}) + +test('block html with attrs', () => { + const { blocks } = parseBlocks(['[div myattr="data" "not content"]', ' content']) + expect(blocks.length).toBe(1) + expect(blocks[0].data).toEqual({ myattr: 'data', _: "not content" }) + + const html = renderBlocks(blocks) + expect(html).toBe('

content

') +}) + test('nested tag data', () => { const { blocks } = parseBlocks(['[hello]', '', '', ' foo: bar', '', ' bro: 10']) expect(blocks[0].data).toEqual({ foo: "bar", bro: 10 }) diff --git a/packages/nuemark/test/inline.test.js b/packages/nuemark/test/inline.test.js index 4533324c..72c1d0d9 100644 --- a/packages/nuemark/test/inline.test.js +++ b/packages/nuemark/test/inline.test.js @@ -231,6 +231,15 @@ test('empty inline span', () => { expect(html).toEndWith('>') }) +test('inline html with attrs', () => { + const md = '[span myattr="data" "content"]' + const [tag] = parseInline(md) + expect(tag.data).toEqual({ myattr: 'data', _: 'content' }) + + const html = renderInline(md) + expect(html).toBe('content') +}) + // named default html tag test('inline html tag', () => { const html = renderInline('[b "*content*"]')