Repository navigation
Expand file tree
/
Copy pathFormattedText.tsx
More file actions
64 lines (53 loc) · 2.2 KB
/
Copy pathFormattedText.tsx
File metadata and controls
64 lines (53 loc) · 2.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import * as MarkdownIt from 'markdown-it';
import * as React from 'react';
export interface IFormattedTextProps {
text: string,
format: string,
onImageLoad: () => void
}
export const FormattedText = (props: IFormattedTextProps) => {
if (!props.text || props.text === '')
return null;
switch (props.format) {
case "xml":
case "plain":
return renderPlainText(props.text);
default:
return renderMarkdown(props.text, props.onImageLoad);
}
}
const renderPlainText = (text: string) => {
const lines = text.replace('\r', '').split('\n');
const elements = lines.map((line, i) => <span key={i}>{line}<br /></span>);
return <span className="format-plain">{elements}</span>;
}
const markdownIt = new MarkdownIt({ html: false, linkify: true, typographer: true });
//configure MarkdownIt to open links in new tab
//from https://github.com/markdown-it/markdown-it/blob/master/docs/architecture.md#renderer
// Remember old renderer, if overriden, or proxy to default renderer
const defaultRender = markdownIt.renderer.rules.link_open || ((tokens, idx, options, env, self) => {
return self.renderToken(tokens, idx, options);
});
markdownIt.renderer.rules.link_open = (tokens, idx, options, env, self) => {
// If you are sure other plugins can't add `target` - drop check below
const targetIndex = tokens[idx].attrIndex('target');
if (targetIndex < 0) {
tokens[idx].attrPush(['target', '_blank']); // add new attribute
} else {
tokens[idx].attrs[targetIndex][1] = '_blank'; // replace value of existing attr
}
// pass token to default renderer.
return defaultRender(tokens, idx, options, env, self);
};
const renderMarkdown = (
text: string,
onImageLoad: () => void
) => {
const src = text
// convert <br> tags to blank lines for markdown
.replace(/<br\s*\/?>/ig, '\r\n\r\n')
// URL encode all links
.replace(/\[(.*?)\]\((.*?)\)/ig, (match, text, url) => `[${text}](${markdownIt.normalizeLink(url)})`);
const __html = markdownIt.render(src);
return <div className="format-markdown" dangerouslySetInnerHTML={{ __html }} />;
}