Skip to content

Commit 7789814

Browse files
authored
refactor(markdownRender): improve markdownRender (#307)
1 parent f98dd6b commit 7789814

File tree

8 files changed

+431
-75
lines changed

8 files changed

+431
-75
lines changed
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`Test MarkdownRender Component Should detect language by highlight 1`] = `
4+
<DocumentFragment>
5+
<div
6+
class="dtc-markdown-render-body dtc-vs-dark"
7+
>
8+
<pre>
9+
<code>
10+
hljs console.
11+
<span
12+
class="hljs-built_in"
13+
>
14+
log
15+
</span>
16+
(
17+
<span
18+
class="hljs-string"
19+
>
20+
'test'
21+
</span>
22+
);
23+
24+
</code>
25+
</pre>
26+
</div>
27+
</DocumentFragment>
28+
`;
29+
30+
exports[`Test MarkdownRender Component Should match snapshot 1`] = `
31+
<DocumentFragment>
32+
<div
33+
class="dtc-markdown-render-body dtc-vs"
34+
>
35+
<h1
36+
id="h1"
37+
>
38+
h1
39+
</h1>
40+
41+
42+
<h2
43+
id="h2"
44+
>
45+
h2
46+
</h2>
47+
48+
49+
<h3
50+
id="h3"
51+
>
52+
h3
53+
</h3>
54+
55+
56+
<ul>
57+
58+
59+
<li>
60+
a
61+
</li>
62+
63+
64+
<li>
65+
b
66+
</li>
67+
68+
69+
<li>
70+
c
71+
</li>
72+
73+
74+
</ul>
75+
76+
77+
<p>
78+
<a
79+
href="https://github.com/DTStack/dt-react-component"
80+
>
81+
url
82+
</a>
83+
</p>
84+
85+
86+
<p>
87+
<strong>
88+
strong1
89+
</strong>
90+
</p>
91+
92+
93+
<p>
94+
<strong>
95+
strong2
96+
</strong>
97+
</p>
98+
99+
100+
<p>
101+
<em>
102+
Italic
103+
</em>
104+
</p>
105+
106+
107+
<blockquote>
108+
109+
110+
<p>
111+
blockquote
112+
</p>
113+
114+
115+
</blockquote>
116+
117+
118+
<p>
119+
<code>
120+
code block
121+
</code>
122+
</p>
123+
124+
125+
<hr />
126+
127+
128+
<table>
129+
130+
131+
<tbody>
132+
<tr>
133+
134+
135+
<td>
136+
Foo
137+
</td>
138+
139+
140+
</tr>
141+
142+
143+
</tbody>
144+
</table>
145+
146+
147+
<pre>
148+
<code
149+
class="hljs sql language-sql"
150+
>
151+
<span
152+
class="hljs-comment"
153+
>
154+
-- desc
155+
</span>
156+
157+
158+
<span
159+
class="hljs-keyword"
160+
>
161+
select
162+
</span>
163+
164+
<span
165+
class="hljs-operator"
166+
>
167+
*
168+
</span>
169+
170+
<span
171+
class="hljs-keyword"
172+
>
173+
from
174+
</span>
175+
employees
176+
177+
</code>
178+
</pre>
179+
</div>
180+
</DocumentFragment>
181+
`;
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import { cleanup, render } from '@testing-library/react';
2+
import React from 'react';
3+
import MarkdownRender from '..';
4+
5+
describe('Test MarkdownRender Component', () => {
6+
beforeEach(cleanup);
7+
it('Should match snapshot', () => {
8+
const { asFragment } = render(
9+
<MarkdownRender
10+
value={`
11+
# h1
12+
## h2
13+
### h3
14+
15+
- a
16+
- b
17+
- c
18+
19+
[url](https://github.com/DTStack/dt-react-component)
20+
21+
**strong1**
22+
23+
__strong2__
24+
25+
_Italic_
26+
27+
> blockquote
28+
29+
\`code block\`
30+
31+
---
32+
33+
<table>
34+
<tr>
35+
<td>Foo</td>
36+
</tr>
37+
</table>
38+
39+
\`\`\`sql
40+
-- desc
41+
select * from employees
42+
\`\`\`
43+
`}
44+
/>
45+
);
46+
47+
expect(asFragment()).toMatchSnapshot();
48+
});
49+
50+
it('Should render dark', () => {
51+
const { container } = render(
52+
<MarkdownRender
53+
dark
54+
value={`
55+
\`\`\`sql
56+
-- desc
57+
select * from employees
58+
\`\`\`
59+
`}
60+
/>
61+
);
62+
63+
const renderBody = container.querySelector<HTMLDivElement>('.dtc-markdown-render-body');
64+
65+
expect(renderBody).not.toBeNull();
66+
expect(renderBody?.className).toContain('dtc-vs-dark');
67+
});
68+
69+
it('Should detect language by highlight', () => {
70+
const { asFragment } = render(
71+
<MarkdownRender
72+
dark
73+
value={`
74+
\`\`\`
75+
console.log('test');
76+
\`\`\`
77+
`}
78+
/>
79+
);
80+
expect(asFragment()).toMatchSnapshot();
81+
});
82+
83+
it('Should render empty value', () => {
84+
const { container } = render(<MarkdownRender />);
85+
expect(container.querySelector('.dtc-markdown-render-body')?.innerHTML).toBe('');
86+
});
87+
});

src/markdownRender/demos/basic.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import React, { useEffect, useState } from 'react';
2+
import { MarkdownRender } from 'dt-react-component';
3+
4+
export default () => {
5+
const [value, setValue] = useState('');
6+
7+
useEffect(() => {
8+
fetch('https://cdn.jsdelivr.net/npm/[email protected]/CHANGELOG.md', {
9+
method: 'get',
10+
})
11+
.then((res) => res.text())
12+
.then(setValue);
13+
}, []);
14+
15+
return (
16+
<div style={{ maxHeight: 200, overflow: 'auto', marginBottom: 16 }}>
17+
<MarkdownRender value={value} />
18+
</div>
19+
);
20+
};

src/markdownRender/demos/dark.tsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React, { useEffect, useState } from 'react';
2+
import { MarkdownRender } from 'dt-react-component';
3+
4+
const md = `
5+
以下是一段 sql 语法
6+
7+
\`\`\`sql
8+
select count(*) from a;
9+
-- name sqltest
10+
-- type sql
11+
-- create time 2022-11-09 16:13:45
12+
-- desc
13+
14+
15+
-- create table employees(name string);
16+
insert into employees values('1111');
17+
18+
19+
select * from employees
20+
\`\`\`
21+
`;
22+
23+
export default () => {
24+
const [value, setValue] = useState('');
25+
26+
useEffect(() => {
27+
setValue(md);
28+
}, []);
29+
30+
return (
31+
<div style={{ maxHeight: 400, overflow: 'auto', marginBottom: 16 }}>
32+
<MarkdownRender dark value={value} />
33+
</div>
34+
);
35+
};

src/markdownRender/demos/sql.tsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React, { useEffect, useState } from 'react';
2+
import { MarkdownRender } from 'dt-react-component';
3+
4+
const md = `
5+
以下是一段 sql 语法
6+
7+
\`\`\`sql
8+
select count(*) from a;
9+
-- name sqltest
10+
-- type sql
11+
-- create time 2022-11-09 16:13:45
12+
-- desc
13+
14+
15+
-- create table employees(name string);
16+
insert into employees values('1111');
17+
18+
19+
select * from employees
20+
\`\`\`
21+
`;
22+
23+
export default () => {
24+
const [value, setValue] = useState('');
25+
26+
useEffect(() => {
27+
setValue(md);
28+
}, []);
29+
30+
return (
31+
<div style={{ maxHeight: 400, overflow: 'auto', marginBottom: 16 }}>
32+
<MarkdownRender value={value} />
33+
</div>
34+
);
35+
};
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import showdown from 'showdown';
2+
import hljs from 'highlight.js';
3+
import sql from 'highlight.js/lib/languages/sql';
4+
import 'highlight.js/styles/default.css';
5+
import '../theme/vs.scss';
6+
import '../theme/vs-dark.scss';
7+
8+
hljs.registerLanguage('sql', sql);
9+
10+
export default function sqlHighlightExtension(): showdown.ShowdownExtension {
11+
return {
12+
type: 'output',
13+
filter: function (text) {
14+
return showdown.helper.replaceRecursiveRegExp(
15+
text.replace(/&gt;/g, '>').replace(/&lt;/g, '<'),
16+
(_: string, match: string, left: string, right: string) => {
17+
const lang = (left.match(/class=\"([^ \"]+)/) || [])[1];
18+
19+
// Append hljs class
20+
const prefix = left.slice(0, 18) + 'hljs ' + left.slice(18);
21+
if (lang && hljs.getLanguage(lang)) {
22+
return prefix + hljs.highlight(match, { language: lang }).value + right;
23+
} else {
24+
return prefix + hljs.highlightAuto(match).value + right;
25+
}
26+
},
27+
'<pre><code\\b[^>]*>',
28+
'</code></pre>',
29+
'g'
30+
);
31+
},
32+
};
33+
}

0 commit comments

Comments
 (0)