Skip to content

Commit 8158ab0

Browse files
authored
Markdown: horizontal rule support (#258)
1 parent ebf829a commit 8158ab0

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

src/components/Markdown/Markdown.test.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,19 @@ describe('Markdown', () => {
103103
const { getByText } = render(<Markdown text={text} />)
104104
expect(getByText('This is a blockquote.')).toBeDefined()
105105
})
106+
107+
it('renders a horizontal rule', () => {
108+
const text = 'First paragraph\n---\nSecond paragraph'
109+
const { container } = render(<Markdown text={text} />)
110+
111+
const paragraphs = container.querySelectorAll('p')
112+
expect(paragraphs.length).toBe(2)
113+
expect(paragraphs[0]?.textContent).toBe('First paragraph')
114+
expect(paragraphs[1]?.textContent).toBe('Second paragraph')
115+
116+
const hr = container.querySelector('hr')
117+
expect(hr).toBeDefined()
118+
})
106119
})
107120

108121
describe('Markdown code blocks', () => {

src/components/Markdown/Markdown.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type Token =
1717
| { type: 'list', ordered: boolean, items: Token[][] }
1818
| { type: 'blockquote', children: Token[] }
1919
| { type: 'codeblock', language?: string, content: string }
20+
| { type: 'hr' }
2021

2122
function parseMarkdown(text: string): Token[] {
2223
const tokens: Token[] = []
@@ -50,6 +51,13 @@ function parseMarkdown(text: string): Token[] {
5051
continue
5152
}
5253

54+
// Horizontal rule
55+
if (/^---+$/.test(line.trim())) {
56+
tokens.push({ type: 'hr' })
57+
i++
58+
continue
59+
}
60+
5361
// Heading
5462
const headingMatch = /^(#{1,6})\s+(.*)/.exec(line)
5563
if (headingMatch !== null) {
@@ -110,6 +118,7 @@ function parseMarkdown(text: string): Token[] {
110118
if (ln.startsWith('>')) break // blockquote
111119
if (/^(#{1,6})\s+/.test(ln)) break // heading
112120
if (/^(\s*)([-*+]|\d+\.)\s+/.test(ln)) break // list item
121+
if (/^---+$/.test(ln.trim())) break // horizontal rule
113122

114123
paraLines.push(ln)
115124
i++
@@ -499,6 +508,8 @@ function renderTokens(tokens: Token[], keyPrefix = ''): ReactNode[] {
499508
{ key },
500509
createElement('code', null, token.content)
501510
)
511+
case 'hr':
512+
return createElement('hr', { key })
502513
default:
503514
return null
504515
}

0 commit comments

Comments
 (0)