From c607d5955d35f8b28ccf61347e5f83b2ef91abf9 Mon Sep 17 00:00:00 2001
From: nobkd <44443899+nobkd@users.noreply.github.com>
Date: Tue, 28 Jan 2025 01:11:10 +0100
Subject: [PATCH 1/7] fix toc cropped, fix heading not hidden in zen mode
---
packages/nuemark/src/parse-inline.js | 4 +++-
packages/nuemark/src/render-inline.js | 1 +
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/packages/nuemark/src/parse-inline.js b/packages/nuemark/src/parse-inline.js
index f32acc53..c3404565 100644
--- a/packages/nuemark/src/parse-inline.js
+++ b/packages/nuemark/src/parse-inline.js
@@ -78,7 +78,7 @@ const PARSERS = [
// parse tag
const tag = parseTag(str.slice(1, i).trim())
const { name } = tag
- const is_footnote = name[0] == '^'
+ const is_footnote = name && name[0] == '^'
const end = i + 1
// footnote?
@@ -89,6 +89,8 @@ const PARSERS = [
// normal tag
if (name == '!' || isValidName(name)) return { is_tag: true, ...tag, end }
+ // span
+ if (!name) return { is_span: true, ...tag, end }
return { text: c }
}
diff --git a/packages/nuemark/src/render-inline.js b/packages/nuemark/src/render-inline.js
index cc41e959..ce9131c7 100644
--- a/packages/nuemark/src/render-inline.js
+++ b/packages/nuemark/src/render-inline.js
@@ -8,6 +8,7 @@ export function renderToken(token, opts = {}) {
const { text } = token
return text ? text :
+ token.is_span ? elem('span', token.attr, renderInline(token.data?._)) :
token.is_format ? formatText(token, opts) :
token.is_var ? renderVariable(token.name, data) :
token.is_image ? renderImage(token) :
From 534b1389d4b8df4cea54b6ca75b4bb0374b7c667 Mon Sep 17 00:00:00 2001
From: nobkd <44443899+nobkd@users.noreply.github.com>
Date: Fri, 31 Jan 2025 03:15:10 +0100
Subject: [PATCH 2/7] inline span test
---
packages/nuemark/test/inline.test.js | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/packages/nuemark/test/inline.test.js b/packages/nuemark/test/inline.test.js
index 7524c912..ce2e9ba8 100644
--- a/packages/nuemark/test/inline.test.js
+++ b/packages/nuemark/test/inline.test.js
@@ -217,6 +217,23 @@ test('parse simple image', () => {
expect(img.href).toBe('yo.svg')
})
+test('inline span', () => {
+ const md = 'hello [.green "world"]!'
+ const [text, span] = parseInline(md)
+ expect(span.is_span).toBeTrue()
+
+ const result = renderInline(md)
+ expect(result).toBe('hello world!')
+})
+
+test('empty inline span', () => {
+ const result = renderInline('[.myclass#myid]')
+ expect(result).toStartWith('')
+})
+
// parse tags and args
test('inline tag', () => {
From eb939074e567c6bf5c26486f84a032f20f34be77 Mon Sep 17 00:00:00 2001
From: nobkd <44443899+nobkd@users.noreply.github.com>
Date: Mon, 3 Feb 2025 02:57:14 +0100
Subject: [PATCH 3/7] feat: block and inline native html tags
---
packages/nuemark/src/parse-inline.js | 4 +---
packages/nuemark/src/render-inline.js | 1 -
packages/nuemark/src/render-tag.js | 31 +++++++++++++++++++++----
packages/nuemark/test/block.test.js | 26 +++++++++++++++++++++
packages/nuemark/test/inline.test.js | 33 ++++++++++++++++++---------
5 files changed, 76 insertions(+), 19 deletions(-)
diff --git a/packages/nuemark/src/parse-inline.js b/packages/nuemark/src/parse-inline.js
index c3404565..3b1e816f 100644
--- a/packages/nuemark/src/parse-inline.js
+++ b/packages/nuemark/src/parse-inline.js
@@ -88,9 +88,7 @@ const PARSERS = [
}
// normal tag
- if (name == '!' || isValidName(name)) return { is_tag: true, ...tag, end }
- // span
- if (!name) return { is_span: true, ...tag, end }
+ if (!name || name == '!' || isValidName(name)) return { is_inline: true, is_tag: true, ...tag, name: tag.name || 'span', end }
return { text: c }
}
diff --git a/packages/nuemark/src/render-inline.js b/packages/nuemark/src/render-inline.js
index ce9131c7..cc41e959 100644
--- a/packages/nuemark/src/render-inline.js
+++ b/packages/nuemark/src/render-inline.js
@@ -8,7 +8,6 @@ export function renderToken(token, opts = {}) {
const { text } = token
return text ? text :
- token.is_span ? elem('span', token.attr, renderInline(token.data?._)) :
token.is_format ? formatText(token, opts) :
token.is_var ? renderVariable(token.name, data) :
token.is_image ? renderImage(token) :
diff --git a/packages/nuemark/src/render-tag.js b/packages/nuemark/src/render-tag.js
index eef01463..0b63c89a 100644
--- a/packages/nuemark/src/render-tag.js
+++ b/packages/nuemark/src/render-tag.js
@@ -6,6 +6,17 @@ import { elem } from './render-blocks.js'
import { readFileSync } from 'node:fs'
import { join } from 'node:path'
+// mostly the same as first block from <../../nuejs/src/fn.js>, but excludes: html, head
+const HTML_TAGS = 'a abbr acronym address applet area article aside audio b base basefont bdi bdo big\
+ blockquote body br button canvas caption center circle cite clipPath code col colgroup data datalist\
+ dd defs del details dfn dialog dir div dl dt ellipse em embed fieldset figcaption figure font footer\
+ foreignObject form frame frameset g header hgroup h1 h2 h3 h4 h5 h6 hr i iframe image img\
+ input ins kbd keygen label legend li line link main map mark marker mask menu menuitem meta meter\
+ nav noframes noscript object ol optgroup option output p param path pattern picture polygon polyline\
+ pre progress q rect rp rt ruby s samp script section select small source span strike strong style sub\
+ summary sup svg switch symbol table tbody td template text textarea textPath tfoot th thead time\
+ title tr track tspan tt u ul use var video wbr'.split(' ')
+
// built-in tags
const TAGS = {
@@ -22,13 +33,13 @@ const TAGS = {
},
block() {
- const { render, attr, blocks } = this
+ const { render, attr, blocks, name } = this
const divs = sectionize(blocks)
const html = !divs || !divs[1] ? render(blocks) :
divs.map(blocks => elem('div', render(blocks))).join('\n')
- return elem(attr.popover ? 'dialog' : 'div', attr, html)
+ return elem(attr.popover ? 'dialog' : name || 'div', attr, html)
},
@@ -142,9 +153,21 @@ export function renderIcon(name, symbol, icon_dir) {
export function renderTag(tag, opts = {}) {
const tags = { ...TAGS, ...opts.tags }
- const fn = tags[tag.name || 'block']
+ const fn = tags[!tag.is_block && tag.name || 'block']
+
+ if (!fn) {
+ // native html tags
+ if (HTML_TAGS.includes(tag.name)) {
+ // inline / block without blocks, but with '_' data
+ if (tag.is_inline || (!tag.blocks?.length && tag.data?._)) return elem(tag.name, tag.attr, renderInline(tag.data?._, opts))
- if (!fn) return renderIsland(tag, opts.data)
+ // block
+ tag.is_block = true
+ return renderTag(tag)
+ }
+
+ return renderIsland(tag, opts.data)
+ }
const data = { ...opts.data, ...extractData(tag.data, opts.data) }
diff --git a/packages/nuemark/test/block.test.js b/packages/nuemark/test/block.test.js
index bd43c492..d21cf221 100644
--- a/packages/nuemark/test/block.test.js
+++ b/packages/nuemark/test/block.test.js
@@ -30,6 +30,32 @@ test('nested lists', () => {
})
+test('block html tag including non-html tag', () => {
+ const { blocks } = parseBlocks(['[section.hi]', ' content', ' [subtag "data"]'])
+ const parent = blocks[0]
+ expect(blocks.length).toBe(1)
+ expect(parent.is_tag).toBe(true)
+ expect(parent.attr.class).toBe('hi')
+ expect(parent.blocks.length).toBe(2)
+ const children = blocks[0].blocks
+ expect(children[0].is_content).toBe(true)
+ expect(children[1].is_tag).toBe(true)
+ expect(children[1].data).toEqual({ _: "data" })
+
+ const html = renderBlocks(blocks)
+ expect(html).toStartWith(' content
no 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 ce2e9ba8..4533324c 100644 --- a/packages/nuemark/test/inline.test.js +++ b/packages/nuemark/test/inline.test.js @@ -217,23 +217,33 @@ test('parse simple image', () => { expect(img.href).toBe('yo.svg') }) +// anonymous tag test('inline span', () => { - const md = 'hello [.green "world"]!' - const [text, span] = parseInline(md) - expect(span.is_span).toBeTrue() - - const result = renderInline(md) - expect(result).toBe('hello world!') + const html = renderInline('hello [.green "world"]!') + expect(html).toBe('hello world!') }) test('empty inline span', () => { - const result = renderInline('[.myclass#myid]') - expect(result).toStartWith('') + const html = renderInline('[.myclass#myid]') + expect(html).toStartWith('') }) +// named default html tag +test('inline html tag', () => { + const html = renderInline('[b "*content*"]') + expect(html).toBe('content') +}) + +test('empty inline html tag', () => { + const html = renderInline('[del.pink.border#myid]') + expect(html).toStartWith('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('content
no content
') }) -test.skip('block html tag with starting ul', () => { +test('block html tag with starting ul', () => { const { blocks } = parseBlocks(['[div]', ' - hi', ' - hello']) expect(blocks.length).toBe(1) expect(blocks[0].blocks.length).toBe(1) From fb2d3cd1fc12c34ea024fe04105b629529b119d7 Mon Sep 17 00:00:00 2001 From: nobkd <44443899+nobkd@users.noreply.github.com> Date: Sat, 15 Feb 2025 05:48:09 +0100 Subject: [PATCH 7/7] use default rendering for button --- packages/nuemark/src/render-tag.js | 8 -------- packages/nuemark/test/tag.test.js | 6 +++--- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/packages/nuemark/src/render-tag.js b/packages/nuemark/src/render-tag.js index 4f7869c8..21716c77 100644 --- a/packages/nuemark/src/render-tag.js +++ b/packages/nuemark/src/render-tag.js @@ -43,14 +43,6 @@ const TAGS = { return elem(attr.popover ? 'dialog' : name, attr, html) }, - button(data) { - const { href } = data - const label = this.renderInline(data.label || data._) || this.innerHTML || '' - - return href ? elem('a', { ...this.attr, href, role: 'button' }, label) : - elem('button', this.attr, label) - }, - define() { const html = this.sections?.map((blocks, i) => { const { attr, text } = blocks[0] diff --git a/packages/nuemark/test/tag.test.js b/packages/nuemark/test/tag.test.js index 69fddc2e..5d9581fe 100644 --- a/packages/nuemark/test/tag.test.js +++ b/packages/nuemark/test/tag.test.js @@ -213,12 +213,12 @@ test('[table] empty cells', () => { test('[button] inline label', () => { const html = renderLines(['[button href="/" "Hey, *world*"]']) - expect(html).toBe('Hey, world') + expect(html).toBe('') }) test('[button] nested label', () => { const html = renderLines(['[button href=/]', ' ']) - expect(html).toStartWith(' {
test('[svg] nested in [button]', () => {
const html = renderLines(['[button href="/"]', ` [svg ${svgpath}] *Yo*`])
- expect(html).toBe(' Yo')
+ expect(html).toBe('')
})