Skip to content

Commit 1ea1c38

Browse files
committed
fix: definition list support
1 parent 3c94d8e commit 1ea1c38

File tree

3 files changed

+132
-3
lines changed

3 files changed

+132
-3
lines changed

src/const.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,13 @@ export const TAG_BDO = 94
9696
export const TAG_RUBY = 95
9797
export const TAG_RT = 96
9898
export const TAG_RP = 97
99+
export const TAG_DD = 98
100+
export const TAG_DT = 99
101+
export const TAG_ADDRESS = 100
102+
export const TAG_DL = 101
103+
104+
// Maximum tag ID for creating the typed array (97 for TAG_RP + 1 for buffer)
105+
export const MAX_TAG_ID = 102
99106

100107
// HTML character entity mapping
101108
export const HTML_ENTITIES: Record<string, string> = {
@@ -214,11 +221,12 @@ export const TagIdMap: Record<string, number> = {
214221
ruby: TAG_RUBY,
215222
rt: TAG_RT,
216223
rp: TAG_RP,
224+
dd: TAG_DD,
225+
dt: TAG_DT,
226+
dl: TAG_DL,
227+
address: TAG_ADDRESS,
217228
}
218229

219-
// Maximum tag ID for creating the typed array (97 for TAG_RP + 1 for buffer)
220-
export const MAX_TAG_ID = 98
221-
222230
// Pre-defined strings to avoid repeated allocations
223231
export const MARKDOWN_STRONG = '**'
224232
export const MARKDOWN_EMPHASIS = '_'

src/tags.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
TABLE_ROW_SPACING,
1313
TAG_A,
1414
TAG_ABBR,
15+
TAG_ADDRESS,
1516
TAG_AREA,
1617
TAG_ASIDE,
1718
TAG_AUDIO,
@@ -27,11 +28,14 @@ import {
2728
TAG_CITE,
2829
TAG_CODE,
2930
TAG_COL,
31+
TAG_DD,
3032
TAG_DEL,
3133
TAG_DETAILS,
3234
TAG_DFN,
3335
TAG_DIALOG,
3436
TAG_DIV,
37+
TAG_DL,
38+
TAG_DT,
3539
TAG_EM,
3640
TAG_EMBED,
3741
TAG_FIELDSET,
@@ -787,4 +791,31 @@ export const tagHandlers: Record<number, TagHandler> = {
787791
spacing: NO_SPACING,
788792
isInline: true,
789793
},
794+
795+
[TAG_ADDRESS]: {
796+
enter: () => '<address>',
797+
exit: () => '</address>',
798+
spacing: NO_SPACING,
799+
},
800+
801+
[TAG_DL]: {
802+
spacing: NO_SPACING,
803+
enter: () => '<dl>',
804+
exit: () => '</dl>',
805+
},
806+
807+
[TAG_DT]: {
808+
// Definition term
809+
enter: () => '<dt>',
810+
exit: () => '</dt>',
811+
collapsesInnerWhiteSpace: true,
812+
spacing: [0, 1],
813+
},
814+
815+
[TAG_DD]: {
816+
// Definition term
817+
enter: () => '<dd>',
818+
exit: () => '</dd>',
819+
spacing: [0, 1],
820+
},
790821
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { describe, expect, it } from 'vitest'
2+
import { syncHtmlToMarkdown } from '../../../src'
3+
4+
describe('definition lists', () => {
5+
it('converts address tags', () => {
6+
const result = syncHtmlToMarkdown(`
7+
<address>
8+
John Doe<br>
9+
123 Main St<br>
10+
Anytown, CA 12345
11+
</address>
12+
`)
13+
expect(result).toMatchInlineSnapshot(`"<address>John Doe 123 Main St Anytown, CA 12345 </address>"`)
14+
})
15+
16+
it('handles definition lists', () => {
17+
const result = syncHtmlToMarkdown(`
18+
<dl>
19+
<dt>HTML</dt>
20+
<dd>HyperText Markup Language</dd>
21+
<dt>CSS</dt>
22+
<dd>Cascading Style Sheets</dd>
23+
</dl>
24+
`)
25+
expect(result).toMatchInlineSnapshot(`
26+
"<dl><dt>HTML</dt>
27+
<dd>HyperText Markup Language</dd>
28+
<dt>CSS</dt>
29+
<dd>Cascading Style Sheets</dd>
30+
</dl>"
31+
`)
32+
})
33+
34+
it('handles nested definition lists', () => {
35+
const result = syncHtmlToMarkdown(`
36+
<dl>
37+
<dt>Web Languages</dt>
38+
<dd>
39+
<dl>
40+
<dt>HTML</dt>
41+
<dd>HyperText Markup Language</dd>
42+
<dt>CSS</dt>
43+
<dd>Cascading Style Sheets</dd>
44+
</dl>
45+
</dd>
46+
<dt>Runtime</dt>
47+
<dd>JavaScript</dd>
48+
</dl>
49+
`)
50+
expect(result).toMatchInlineSnapshot(`
51+
"<dl><dt>Web Languages</dt>
52+
<dd><dl><dt>HTML</dt>
53+
<dd>HyperText Markup Language</dd>
54+
<dt>CSS</dt>
55+
<dd>Cascading Style Sheets</dd>
56+
</dl></dd>
57+
<dt>Runtime</dt>
58+
<dd>JavaScript</dd>
59+
</dl>"
60+
`)
61+
})
62+
63+
it('handles complex definition list content', () => {
64+
const result = syncHtmlToMarkdown(`
65+
<dl>
66+
<dt>Term with <strong>formatting</strong></dt>
67+
<dd>Definition with <a href="https://example.com">link</a></dd>
68+
<dt>Another Term</dt>
69+
<dd>
70+
<p>Paragraph in definition</p>
71+
<ul>
72+
<li>List item in definition</li>
73+
</ul>
74+
</dd>
75+
</dl>
76+
`)
77+
expect(result).toMatchInlineSnapshot(`
78+
"<dl><dt>Term with **formatting**</dt>
79+
<dd>Definition with [link](https://example.com)</dd>
80+
<dt>Another Term</dt>
81+
<dd>
82+
83+
Paragraph in definition
84+
85+
- List item in definition
86+
87+
</dd></dl>"
88+
`)
89+
})
90+
})

0 commit comments

Comments
 (0)