]> luflow.net public git repositories - flow-web.git/blob - static/highlight/languages/markdown.js
Initial commit.
[flow-web.git] / static / highlight / languages / markdown.js
1 /*! `markdown` grammar compiled for Highlight.js 11.11.1 */
2 (function(){
3 var hljsGrammar = (function () {
4 'use strict';
5
6 /*
7 Language: Markdown
8 Requires: xml.js
9 Author: John Crepezzi <john.crepezzi@gmail.com>
10 Website: https://daringfireball.net/projects/markdown/
11 Category: common, markup
12 */
13
14 function markdown(hljs) {
15 const regex = hljs.regex;
16 const INLINE_HTML = {
17 begin: /<\/?[A-Za-z_]/,
18 end: '>',
19 subLanguage: 'xml',
20 relevance: 0
21 };
22 const HORIZONTAL_RULE = {
23 begin: '^[-\\*]{3,}',
24 end: '$'
25 };
26 const CODE = {
27 className: 'code',
28 variants: [
29 // TODO: fix to allow these to work with sublanguage also
30 { begin: '(`{3,})[^`](.|\\n)*?\\1`*[ ]*' },
31 { begin: '(~{3,})[^~](.|\\n)*?\\1~*[ ]*' },
32 // needed to allow markdown as a sublanguage to work
33 {
34 begin: '```',
35 end: '```+[ ]*$'
36 },
37 {
38 begin: '~~~',
39 end: '~~~+[ ]*$'
40 },
41 { begin: '`.+?`' },
42 {
43 begin: '(?=^( {4}|\\t))',
44 // use contains to gobble up multiple lines to allow the block to be whatever size
45 // but only have a single open/close tag vs one per line
46 contains: [
47 {
48 begin: '^( {4}|\\t)',
49 end: '(\\n)$'
50 }
51 ],
52 relevance: 0
53 }
54 ]
55 };
56 const LIST = {
57 className: 'bullet',
58 begin: '^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)',
59 end: '\\s+',
60 excludeEnd: true
61 };
62 const LINK_REFERENCE = {
63 begin: /^\[[^\n]+\]:/,
64 returnBegin: true,
65 contains: [
66 {
67 className: 'symbol',
68 begin: /\[/,
69 end: /\]/,
70 excludeBegin: true,
71 excludeEnd: true
72 },
73 {
74 className: 'link',
75 begin: /:\s*/,
76 end: /$/,
77 excludeBegin: true
78 }
79 ]
80 };
81 const URL_SCHEME = /[A-Za-z][A-Za-z0-9+.-]*/;
82 const LINK = {
83 variants: [
84 // too much like nested array access in so many languages
85 // to have any real relevance
86 {
87 begin: /\[.+?\]\[.*?\]/,
88 relevance: 0
89 },
90 // popular internet URLs
91 {
92 begin: /\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/,
93 relevance: 2
94 },
95 {
96 begin: regex.concat(/\[.+?\]\(/, URL_SCHEME, /:\/\/.*?\)/),
97 relevance: 2
98 },
99 // relative urls
100 {
101 begin: /\[.+?\]\([./?&#].*?\)/,
102 relevance: 1
103 },
104 // whatever else, lower relevance (might not be a link at all)
105 {
106 begin: /\[.*?\]\(.*?\)/,
107 relevance: 0
108 }
109 ],
110 returnBegin: true,
111 contains: [
112 {
113 // empty strings for alt or link text
114 match: /\[(?=\])/ },
115 {
116 className: 'string',
117 relevance: 0,
118 begin: '\\[',
119 end: '\\]',
120 excludeBegin: true,
121 returnEnd: true
122 },
123 {
124 className: 'link',
125 relevance: 0,
126 begin: '\\]\\(',
127 end: '\\)',
128 excludeBegin: true,
129 excludeEnd: true
130 },
131 {
132 className: 'symbol',
133 relevance: 0,
134 begin: '\\]\\[',
135 end: '\\]',
136 excludeBegin: true,
137 excludeEnd: true
138 }
139 ]
140 };
141 const BOLD = {
142 className: 'strong',
143 contains: [], // defined later
144 variants: [
145 {
146 begin: /_{2}(?!\s)/,
147 end: /_{2}/
148 },
149 {
150 begin: /\*{2}(?!\s)/,
151 end: /\*{2}/
152 }
153 ]
154 };
155 const ITALIC = {
156 className: 'emphasis',
157 contains: [], // defined later
158 variants: [
159 {
160 begin: /\*(?![*\s])/,
161 end: /\*/
162 },
163 {
164 begin: /_(?![_\s])/,
165 end: /_/,
166 relevance: 0
167 }
168 ]
169 };
170
171 // 3 level deep nesting is not allowed because it would create confusion
172 // in cases like `***testing***` because where we don't know if the last
173 // `***` is starting a new bold/italic or finishing the last one
174 const BOLD_WITHOUT_ITALIC = hljs.inherit(BOLD, { contains: [] });
175 const ITALIC_WITHOUT_BOLD = hljs.inherit(ITALIC, { contains: [] });
176 BOLD.contains.push(ITALIC_WITHOUT_BOLD);
177 ITALIC.contains.push(BOLD_WITHOUT_ITALIC);
178
179 let CONTAINABLE = [
180 INLINE_HTML,
181 LINK
182 ];
183
184 [
185 BOLD,
186 ITALIC,
187 BOLD_WITHOUT_ITALIC,
188 ITALIC_WITHOUT_BOLD
189 ].forEach(m => {
190 m.contains = m.contains.concat(CONTAINABLE);
191 });
192
193 CONTAINABLE = CONTAINABLE.concat(BOLD, ITALIC);
194
195 const HEADER = {
196 className: 'section',
197 variants: [
198 {
199 begin: '^#{1,6}',
200 end: '$',
201 contains: CONTAINABLE
202 },
203 {
204 begin: '(?=^.+?\\n[=-]{2,}$)',
205 contains: [
206 { begin: '^[=-]*$' },
207 {
208 begin: '^',
209 end: "\\n",
210 contains: CONTAINABLE
211 }
212 ]
213 }
214 ]
215 };
216
217 const BLOCKQUOTE = {
218 className: 'quote',
219 begin: '^>\\s+',
220 contains: CONTAINABLE,
221 end: '$'
222 };
223
224 const ENTITY = {
225 //https://spec.commonmark.org/0.31.2/#entity-references
226 scope: 'literal',
227 match: /&([a-zA-Z0-9]+|#[0-9]{1,7}|#[Xx][0-9a-fA-F]{1,6});/
228 };
229
230 return {
231 name: 'Markdown',
232 aliases: [
233 'md',
234 'mkdown',
235 'mkd'
236 ],
237 contains: [
238 HEADER,
239 INLINE_HTML,
240 LIST,
241 BOLD,
242 ITALIC,
243 BLOCKQUOTE,
244 CODE,
245 HORIZONTAL_RULE,
246 LINK,
247 LINK_REFERENCE,
248 ENTITY
249 ]
250 };
251 }
252
253 return markdown;
254
255 })();
256
257 hljs.registerLanguage('markdown', hljsGrammar);
258 })();