Skip to content

Commit

Permalink
Nuemark (2): handle [[! yo.svg]](/) nuejs#379
Browse files Browse the repository at this point in the history
  • Loading branch information
tipiirai authored and nobkd committed Nov 14, 2024
1 parent 7e96551 commit 3bbfe71
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 27 deletions.
69 changes: 47 additions & 22 deletions packages/nuemark/src/parse-inline.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,40 @@ const PARSERS = [
}
},

// links
// [link](/), [tag], or [^footnote]
(str, char0) => {
if (char0 == '[') {
return parseLink(str) || parseLink(str, true)
const i = str.indexOf(']', 1)

if (i == -1) return { text: char0 }

// links
if ('([]'.includes(str[i + 1])) {
const link = parseLink(str) || parseLink(str, true)
if (link) return link
}

// parse tag
const tag = parseTag(str.slice(1, i).trim())
const { name } = tag
const end = i + 1

// footnote?
if (name[0] == '^') {
const rel = name.slice(1)
return rel >= 0 || isValidName(rel) ? { is_footnote: true, href: name, end } : { text: char0 }
}

// normal tag
if (name == '!' || isValidName(name)) return { is_tag: true, ...tag, end }



return { text: char0 }
}
},

// images
// ![image](/src.png)
(str, char0) => {
if (char0 == '!' && str[1] == '[') {
const img = parseLink(str.slice(1))
Expand All @@ -69,22 +95,6 @@ const PARSERS = [
}
},


// [tag] or [^footnote]
(str, char0) => {
if (char0 == '[') {
const i = str.indexOf(']', 2)
if (i == -1) return { text: char0 }

const specs = str.slice(1, i).trim()
const tag = parseTag(specs)
const { name } = tag
const end = i + 1

return name[0] == '^' ? { is_footnote: true, href: name, end } : { is_tag: true, ...tag, end }
}
},

// { variables } / { #id.classNames }
(str, char0) => {
if (char0 == '{') {
Expand All @@ -107,6 +117,19 @@ const PARSERS = [
}
]


function isValidName(name) {

// cannot be a number
if (name >= 0) return false

// cannot contain special characters
const i = name.search(/\W/)
const char = name[i]
return i == -1 || i > 0 && char == '-'
}


function empty(char) {
return !char || char == ' '
}
Expand Down Expand Up @@ -138,13 +161,15 @@ export function parseInline(str) {

/*** utils ****/

// function lastIndexOf()

export function parseLink(str, is_reflink) {
const [open, close] = is_reflink ? '[]' : '()'
let i = str.indexOf(']', 1)
let i = str.indexOf(']' + open, 1)

// not a link
const next = str[i + 1]
if (next != open) return
// const next = str[i + 1]
if (i == -1) return

let j = i > 0 ? str.indexOf(close, i + 2) : 0

Expand Down
5 changes: 5 additions & 0 deletions packages/nuemark/test/block.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ test('parse thematic break', () => {
expect(getBreak('*** yo')).toBeUndefined()
})

test.only('parse break', () => {
const html = renderLines(['***', '***Bold Italic***'])
console.info(html)
})

test('render thematic break', () => {
expect(renderLines(['hello', '***'])).toBe('<p>hello</p>\n<hr>')
})
Expand Down
33 changes: 28 additions & 5 deletions packages/nuemark/test/inline.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ test('formatting', () => {

for (const test of tests) {
const [ chars, body, tag ] = test
const ret = parseInline(`A ${chars + body + chars} here`)
expect(ret[1].tag).toBe(tag)
expect(ret[1].body).toBe(body)
expect(ret.length).toBe(3)
const html = parseInline(`A ${chars + body + chars} here`)
expect(html[1].tag).toBe(tag)
expect(html[1].body).toBe(body)
expect(html.length).toBe(3)
}
})

Expand Down Expand Up @@ -108,6 +108,20 @@ test('parse reflink', () => {
expect(link).toMatchObject({ href: 'world', title: 'now', label: 'Hello' })
})


test('bad component names', () => {
const tests = ['[(10)] [3 % 8]', '[-hey]', '[he+y] there']
for (const test of tests) {
const html = renderInline(test)
expect(html).toBe(test)
}
})

test('inline image tag', () => {
const html = renderInline('[! foo.svg]')
expect(html).toStartWith('<figure>')
})

test('complex label with an image', () => {
const complex_label = 'Hey ![Cat](/cat.png)!'
const link = `[${complex_label}](/link/ "lol")`
Expand All @@ -121,6 +135,7 @@ test('complex label with an image', () => {
expect(html).toEndWith('alt="Cat" loading="lazy">!</a>')
})


test('parse complex Wikipedia-style link', () => {
const [text, link, rest] = parseInline('Goto [label](/url/(master)) plan')
expect(link.href).toBe('/url/(master)')
Expand Down Expand Up @@ -174,11 +189,19 @@ test('inline tag', () => {
})

test('inline tag with reflink', () => {
const [ tag, and, link] = parseInline('[tip] and [link][foo]')
const els = parseInline('[tip] and [link][foo]')
const [ tag, and, link] = els
expect(tag.is_tag).toBeTrue()
expect(link.is_reflink).toBeTrue()
})


test('links with tags', () => {
const html = renderInline('lol [[! yo.svg]](/)')
expect(html).toStartWith('lol <a href="/">')
expect(html).toEndWith('src="yo.svg"></figure></a>')
})

test('tag args', () => {
const [ text, comp, rest] = parseInline('Hey [print foo] thing')
expect(comp.name).toBe('print')
Expand Down

0 comments on commit 3bbfe71

Please sign in to comment.