1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | function markdown(hljs) {
|
10 | const regex = hljs.regex;
|
11 | const INLINE_HTML = {
|
12 | begin: /<\/?[A-Za-z_]/,
|
13 | end: '>',
|
14 | subLanguage: 'xml',
|
15 | relevance: 0
|
16 | };
|
17 | const HORIZONTAL_RULE = {
|
18 | begin: '^[-\\*]{3,}',
|
19 | end: '$'
|
20 | };
|
21 | const CODE = {
|
22 | className: 'code',
|
23 | variants: [
|
24 |
|
25 | { begin: '(`{3,})[^`](.|\\n)*?\\1`*[ ]*' },
|
26 | { begin: '(~{3,})[^~](.|\\n)*?\\1~*[ ]*' },
|
27 |
|
28 | {
|
29 | begin: '```',
|
30 | end: '```+[ ]*$'
|
31 | },
|
32 | {
|
33 | begin: '~~~',
|
34 | end: '~~~+[ ]*$'
|
35 | },
|
36 | { begin: '`.+?`' },
|
37 | {
|
38 | begin: '(?=^( {4}|\\t))',
|
39 |
|
40 |
|
41 | contains: [
|
42 | {
|
43 | begin: '^( {4}|\\t)',
|
44 | end: '(\\n)$'
|
45 | }
|
46 | ],
|
47 | relevance: 0
|
48 | }
|
49 | ]
|
50 | };
|
51 | const LIST = {
|
52 | className: 'bullet',
|
53 | begin: '^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)',
|
54 | end: '\\s+',
|
55 | excludeEnd: true
|
56 | };
|
57 | const LINK_REFERENCE = {
|
58 | begin: /^\[[^\n]+\]:/,
|
59 | returnBegin: true,
|
60 | contains: [
|
61 | {
|
62 | className: 'symbol',
|
63 | begin: /\[/,
|
64 | end: /\]/,
|
65 | excludeBegin: true,
|
66 | excludeEnd: true
|
67 | },
|
68 | {
|
69 | className: 'link',
|
70 | begin: /:\s*/,
|
71 | end: /$/,
|
72 | excludeBegin: true
|
73 | }
|
74 | ]
|
75 | };
|
76 | const URL_SCHEME = /[A-Za-z][A-Za-z0-9+.-]*/;
|
77 | const LINK = {
|
78 | variants: [
|
79 |
|
80 |
|
81 | {
|
82 | begin: /\[.+?\]\[.*?\]/,
|
83 | relevance: 0
|
84 | },
|
85 |
|
86 | {
|
87 | begin: /\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/,
|
88 | relevance: 2
|
89 | },
|
90 | {
|
91 | begin: regex.concat(/\[.+?\]\(/, URL_SCHEME, /:\/\/.*?\)/),
|
92 | relevance: 2
|
93 | },
|
94 |
|
95 | {
|
96 | begin: /\[.+?\]\([./?&#].*?\)/,
|
97 | relevance: 1
|
98 | },
|
99 |
|
100 | {
|
101 | begin: /\[.*?\]\(.*?\)/,
|
102 | relevance: 0
|
103 | }
|
104 | ],
|
105 | returnBegin: true,
|
106 | contains: [
|
107 | {
|
108 |
|
109 | match: /\[(?=\])/ },
|
110 | {
|
111 | className: 'string',
|
112 | relevance: 0,
|
113 | begin: '\\[',
|
114 | end: '\\]',
|
115 | excludeBegin: true,
|
116 | returnEnd: true
|
117 | },
|
118 | {
|
119 | className: 'link',
|
120 | relevance: 0,
|
121 | begin: '\\]\\(',
|
122 | end: '\\)',
|
123 | excludeBegin: true,
|
124 | excludeEnd: true
|
125 | },
|
126 | {
|
127 | className: 'symbol',
|
128 | relevance: 0,
|
129 | begin: '\\]\\[',
|
130 | end: '\\]',
|
131 | excludeBegin: true,
|
132 | excludeEnd: true
|
133 | }
|
134 | ]
|
135 | };
|
136 | const BOLD = {
|
137 | className: 'strong',
|
138 | contains: [],
|
139 | variants: [
|
140 | {
|
141 | begin: /_{2}/,
|
142 | end: /_{2}/
|
143 | },
|
144 | {
|
145 | begin: /\*{2}/,
|
146 | end: /\*{2}/
|
147 | }
|
148 | ]
|
149 | };
|
150 | const ITALIC = {
|
151 | className: 'emphasis',
|
152 | contains: [],
|
153 | variants: [
|
154 | {
|
155 | begin: /\*(?!\*)/,
|
156 | end: /\*/
|
157 | },
|
158 | {
|
159 | begin: /_(?!_)/,
|
160 | end: /_/,
|
161 | relevance: 0
|
162 | }
|
163 | ]
|
164 | };
|
165 |
|
166 |
|
167 |
|
168 |
|
169 | const BOLD_WITHOUT_ITALIC = hljs.inherit(BOLD, { contains: [] });
|
170 | const ITALIC_WITHOUT_BOLD = hljs.inherit(ITALIC, { contains: [] });
|
171 | BOLD.contains.push(ITALIC_WITHOUT_BOLD);
|
172 | ITALIC.contains.push(BOLD_WITHOUT_ITALIC);
|
173 |
|
174 | let CONTAINABLE = [
|
175 | INLINE_HTML,
|
176 | LINK
|
177 | ];
|
178 |
|
179 | [
|
180 | BOLD,
|
181 | ITALIC,
|
182 | BOLD_WITHOUT_ITALIC,
|
183 | ITALIC_WITHOUT_BOLD
|
184 | ].forEach(m => {
|
185 | m.contains = m.contains.concat(CONTAINABLE);
|
186 | });
|
187 |
|
188 | CONTAINABLE = CONTAINABLE.concat(BOLD, ITALIC);
|
189 |
|
190 | const HEADER = {
|
191 | className: 'section',
|
192 | variants: [
|
193 | {
|
194 | begin: '^#{1,6}',
|
195 | end: '$',
|
196 | contains: CONTAINABLE
|
197 | },
|
198 | {
|
199 | begin: '(?=^.+?\\n[=-]{2,}$)',
|
200 | contains: [
|
201 | { begin: '^[=-]*$' },
|
202 | {
|
203 | begin: '^',
|
204 | end: "\\n",
|
205 | contains: CONTAINABLE
|
206 | }
|
207 | ]
|
208 | }
|
209 | ]
|
210 | };
|
211 |
|
212 | const BLOCKQUOTE = {
|
213 | className: 'quote',
|
214 | begin: '^>\\s+',
|
215 | contains: CONTAINABLE,
|
216 | end: '$'
|
217 | };
|
218 |
|
219 | return {
|
220 | name: 'Markdown',
|
221 | aliases: [
|
222 | 'md',
|
223 | 'mkdown',
|
224 | 'mkd'
|
225 | ],
|
226 | contains: [
|
227 | HEADER,
|
228 | INLINE_HTML,
|
229 | LIST,
|
230 | BOLD,
|
231 | ITALIC,
|
232 | BLOCKQUOTE,
|
233 | CODE,
|
234 | HORIZONTAL_RULE,
|
235 | LINK,
|
236 | LINK_REFERENCE
|
237 | ]
|
238 | };
|
239 | }
|
240 |
|
241 | module.exports = markdown;
|