Skip to content

Commit

Permalink
Nuemark (2): handle images inside link labels. #379
Browse files Browse the repository at this point in the history
  • Loading branch information
tipiirai committed Oct 21, 2024
1 parent f9a5cf2 commit 203003c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 17 deletions.
31 changes: 23 additions & 8 deletions packages/nuemark/src/parse-inline.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const PARSERS = [
}
},

// links (must be before formatting)
// links
(str, char0) => {
if (char0 == '[') {
return parseLink(str) || parseLink(str, true)
Expand All @@ -69,6 +69,7 @@ const PARSERS = [
}
},


// [tag] or [^footnote]
(str, char0) => {
if (char0 == '[') {
Expand Down Expand Up @@ -139,24 +140,38 @@ export function parseInline(str) {

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

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

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

// not a link
if (j <= 0 || str[i] == ' ') return
if (j == -1) return

// label
let label = str.slice(1, i)

// image inside label
if (label.includes('![')) {
i = str.indexOf(']' + open, j)
label = str.slice(1, i)
j = str.indexOf(close, i + 2)
if (i == -1 || j == -1) return

} else {
// links with closing bracket (ie. Wikipedia)
if (str[j + 1] == ')') j++
}

// links with closing bracket (ie. Wikipedia)
if (str[j + 1] == ')') j++

// href & title
let { href, title } = parseLinkTitle(str.slice(i + 2, j))

return {
href, title, label: str.slice(1, i),
href, title, label,
is_footnote: href[0] == '^',
is_reflink,
end: j + 1
Expand Down
31 changes: 22 additions & 9 deletions packages/nuemark/test/inline.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ test('render image', () => {
expect(html).toBe('<img src="/bar.png" alt="foo" loading="lazy"> post')
})


test('inline code', () => {
const html = renderInline('Hey `[zoo] *boo*`')
expect(html).toBe('Hey <code>[zoo] *boo*</code>')
Expand Down Expand Up @@ -95,11 +96,31 @@ test('link subject', () => {
expect(link).toMatchObject({ href: '/world', title: 'today', label: 'Hello' })
})

test('parse inline link', () => {
const [text, link] = parseInline('Goto [label](/url/ "the subject")')
expect(link.title).toBe('the subject')
expect(link.label).toBe('label')
expect(link.href).toBe('/url/')
})

test('parse reflink', () => {
const link = parseLink('[Hello][world "now"]', true)
expect(link).toMatchObject({ href: 'world', title: 'now', label: 'Hello' })
})

test('complex label with an image', () => {
const complex_label = 'Hey ![Cat](/cat.png)!'
const link = `[${complex_label}](/link/ "lol")`

const el = parseLink(link)
expect(el.label).toBe(complex_label)
expect(el.href).toBe('/link/')

const html = renderInline(link)
expect(html).toStartWith('<a title="lol" href="/link/">Hey')
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 @@ -139,14 +160,6 @@ test('render reflinks', () => {
expect(html).toBe('<a title="Bruh" href="/">Foobar</a>')
})


test('parse subject link', () => {
const [text, link] = parseInline('Goto [label](/url/ "the subject")')
expect(link.title).toBe('the subject')
expect(link.label).toBe('label')
expect(link.href).toBe('/url/')
})

test('parse simple image', () => {
const [text, img] = parseInline('Image ![](yo.svg)')
expect(img.is_image).toBeTrue()
Expand All @@ -160,7 +173,7 @@ test('inline tag', () => {
expect(el.name).toBe('version')
})

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

0 comments on commit 203003c

Please sign in to comment.