blob: a90c90be21a2dcc627f0a12f933fe703c4eae398 [file] [log] [blame]
Bram Moolenaard1caa942020-04-10 22:10:56 +02001" Vim reST syntax file
Bram Moolenaar7d76c802014-10-15 22:51:52 +02002" Language: reStructuredText documentation format
3" Maintainer: Marshall Ward <marshall.ward@gmail.com>
Bram Moolenaar7b61a542014-08-23 15:31:19 +02004" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
Bram Moolenaar7571d552016-08-18 22:54:46 +02005" Website: https://github.com/marshallward/vim-restructuredtext
Bram Moolenaard1caa942020-04-10 22:10:56 +02006" Latest Revision: 2020-03-31
Bram Moolenaar071d4272004-06-13 20:20:40 +00007
Bram Moolenaar42eeac32005-06-29 22:40:58 +00008if exists("b:current_syntax")
Bram Moolenaar071d4272004-06-13 20:20:40 +00009 finish
10endif
11
Bram Moolenaar42eeac32005-06-29 22:40:58 +000012let s:cpo_save = &cpo
13set cpo&vim
14
Bram Moolenaar071d4272004-06-13 20:20:40 +000015syn case ignore
16
Bram Moolenaar5c736222010-01-06 20:54:52 +010017syn match rstTransition /^[=`:.'"~^_*+#-]\{4,}\s*$/
Bram Moolenaar071d4272004-06-13 20:20:40 +000018
Bram Moolenaar779b74b2006-04-10 14:55:34 +000019syn cluster rstCruft contains=rstEmphasis,rstStrongEmphasis,
20 \ rstInterpretedText,rstInlineLiteral,rstSubstitutionReference,
21 \ rstInlineInternalTargets,rstFootnoteReference,rstHyperlinkReference
Bram Moolenaar071d4272004-06-13 20:20:40 +000022
Bram Moolenaar779b74b2006-04-10 14:55:34 +000023syn region rstLiteralBlock matchgroup=rstDelimiter
Bram Moolenaard1caa942020-04-10 22:10:56 +020024 \ start='\(^\z(\s*\).*\)\@<=::\n\s*\n' skip='^\s*$' end='^\(\z1\s\+\)\@!'
Bram Moolenaar779b74b2006-04-10 14:55:34 +000025 \ contains=@NoSpell
Bram Moolenaar071d4272004-06-13 20:20:40 +000026
Bram Moolenaar779b74b2006-04-10 14:55:34 +000027syn region rstQuotedLiteralBlock matchgroup=rstDelimiter
28 \ start="::\_s*\n\ze\z([!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]\)"
29 \ end='^\z1\@!' contains=@NoSpell
Bram Moolenaar071d4272004-06-13 20:20:40 +000030
Bram Moolenaar779b74b2006-04-10 14:55:34 +000031syn region rstDoctestBlock oneline display matchgroup=rstDelimiter
32 \ start='^>>>\s' end='^$'
Bram Moolenaar071d4272004-06-13 20:20:40 +000033
Bram Moolenaar779b74b2006-04-10 14:55:34 +000034syn region rstTable transparent start='^\n\s*+[-=+]\+' end='^$'
35 \ contains=rstTableLines,@rstCruft
36syn match rstTableLines contained display '|\|+\%(=\+\|-\+\)\='
Bram Moolenaar071d4272004-06-13 20:20:40 +000037
Bram Moolenaar779b74b2006-04-10 14:55:34 +000038syn region rstSimpleTable transparent
39 \ start='^\n\%(\s*\)\@>\%(\%(=\+\)\@>\%(\s\+\)\@>\)\%(\%(\%(=\+\)\@>\%(\s*\)\@>\)\+\)\@>$'
40 \ end='^$'
41 \ contains=rstSimpleTableLines,@rstCruft
42syn match rstSimpleTableLines contained display
43 \ '^\%(\s*\)\@>\%(\%(=\+\)\@>\%(\s\+\)\@>\)\%(\%(\%(=\+\)\@>\%(\s*\)\@>\)\+\)\@>$'
44syn match rstSimpleTableLines contained display
45 \ '^\%(\s*\)\@>\%(\%(-\+\)\@>\%(\s\+\)\@>\)\%(\%(\%(-\+\)\@>\%(\s*\)\@>\)\+\)\@>$'
Bram Moolenaar071d4272004-06-13 20:20:40 +000046
Bram Moolenaar779b74b2006-04-10 14:55:34 +000047syn cluster rstDirectives contains=rstFootnote,rstCitation,
48 \ rstHyperlinkTarget,rstExDirective
Bram Moolenaar071d4272004-06-13 20:20:40 +000049
Bram Moolenaar7b61a542014-08-23 15:31:19 +020050syn match rstExplicitMarkup '^\s*\.\.\_s'
Bram Moolenaar779b74b2006-04-10 14:55:34 +000051 \ nextgroup=@rstDirectives,rstComment,rstSubstitutionDefinition
Bram Moolenaar071d4272004-06-13 20:20:40 +000052
Bram Moolenaar91f84f62018-07-29 15:07:52 +020053" "Simple reference names are single words consisting of alphanumerics plus
54" isolated (no two adjacent) internal hyphens, underscores, periods, colons
55" and plus signs."
56let s:ReferenceName = '[[:alnum:]]\%([-_.:+]\?[[:alnum:]]\+\)*'
Bram Moolenaar071d4272004-06-13 20:20:40 +000057
Bram Moolenaar779b74b2006-04-10 14:55:34 +000058syn keyword rstTodo contained FIXME TODO XXX NOTE
Bram Moolenaar071d4272004-06-13 20:20:40 +000059
Bram Moolenaar779b74b2006-04-10 14:55:34 +000060execute 'syn region rstComment contained' .
61 \ ' start=/.*/'
Bram Moolenaar4c05fa02019-01-01 15:32:17 +010062 \ ' skip=+^$+' .
Bram Moolenaar779b74b2006-04-10 14:55:34 +000063 \ ' end=/^\s\@!/ contains=rstTodo'
Bram Moolenaar071d4272004-06-13 20:20:40 +000064
Bram Moolenaar779b74b2006-04-10 14:55:34 +000065execute 'syn region rstFootnote contained matchgroup=rstDirective' .
66 \ ' start=+\[\%(\d\+\|#\%(' . s:ReferenceName . '\)\=\|\*\)\]\_s+' .
67 \ ' skip=+^$+' .
68 \ ' end=+^\s\@!+ contains=@rstCruft,@NoSpell'
69
70execute 'syn region rstCitation contained matchgroup=rstDirective' .
71 \ ' start=+\[' . s:ReferenceName . '\]\_s+' .
72 \ ' skip=+^$+' .
73 \ ' end=+^\s\@!+ contains=@rstCruft,@NoSpell'
74
75syn region rstHyperlinkTarget contained matchgroup=rstDirective
76 \ start='_\%(_\|[^:\\]*\%(\\.[^:\\]*\)*\):\_s' skip=+^$+ end=+^\s\@!+
77
78syn region rstHyperlinkTarget contained matchgroup=rstDirective
79 \ start='_`[^`\\]*\%(\\.[^`\\]*\)*`:\_s' skip=+^$+ end=+^\s\@!+
80
81syn region rstHyperlinkTarget matchgroup=rstDirective
82 \ start=+^__\_s+ skip=+^$+ end=+^\s\@!+
83
84execute 'syn region rstExDirective contained matchgroup=rstDirective' .
85 \ ' start=+' . s:ReferenceName . '::\_s+' .
86 \ ' skip=+^$+' .
Bram Moolenaar12969c02015-09-08 23:36:10 +020087 \ ' end=+^\s\@!+ contains=@rstCruft,rstLiteralBlock'
Bram Moolenaar779b74b2006-04-10 14:55:34 +000088
89execute 'syn match rstSubstitutionDefinition contained' .
Bram Moolenaar91f84f62018-07-29 15:07:52 +020090 \ ' /|.*|\_s\+/ nextgroup=@rstDirectives'
Bram Moolenaar779b74b2006-04-10 14:55:34 +000091
92function! s:DefineOneInlineMarkup(name, start, middle, end, char_left, char_right)
Bram Moolenaard1caa942020-04-10 22:10:56 +020093 " Only escape the first char of a multichar delimiter (e.g. \* inside **)
94 if a:start[0] == '\'
95 let first = a:start[0:1]
96 else
97 let first = a:start[0]
98 endif
99
100 execute 'syn match rstEscape'.a:name.' +\\\\\|\\'.first.'+'.' contained'
101
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000102 execute 'syn region rst' . a:name .
103 \ ' start=+' . a:char_left . '\zs' . a:start .
Bram Moolenaar25394022007-05-10 19:06:20 +0000104 \ '\ze[^[:space:]' . a:char_right . a:start[strlen(a:start) - 1] . ']+' .
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000105 \ a:middle .
Bram Moolenaard1caa942020-04-10 22:10:56 +0200106 \ ' end=+' . a:end . '\ze\%($\|\s\|[''"’)\]}>/:.,;!?\\-]\)+' .
107 \ ' contains=rstEscape' . a:name
108
109 execute 'hi def link rstEscape'.a:name.' Special'
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000110endfunction
111
112function! s:DefineInlineMarkup(name, start, middle, end)
113 let middle = a:middle != "" ?
Bram Moolenaard1caa942020-04-10 22:10:56 +0200114 \ (' skip=+\\\\\|\\' . a:middle . '\|\s' . a:middle . '+') :
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000115 \ ""
116
117 call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, "'", "'")
Bram Moolenaar7b61a542014-08-23 15:31:19 +0200118 call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '"', '"')
119 call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '(', ')')
120 call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '\[', '\]')
121 call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '{', '}')
122 call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '<', '>')
Bram Moolenaar7571d552016-08-18 22:54:46 +0200123 call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '', '')
124 " TODO: Additional Unicode Pd, Po, Pi, Pf, Ps characters
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000125
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200126 call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '\%(^\|\s\|\%ua0\|[/:]\)', '')
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000127
128 execute 'syn match rst' . a:name .
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200129 \ ' +\%(^\|\s\|\%ua0\|[''"([{</:]\)\zs' . a:start .
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000130 \ '[^[:space:]' . a:start[strlen(a:start) - 1] . ']'
131 \ a:end . '\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)+'
132
133 execute 'hi def link rst' . a:name . 'Delimiter' . ' rst' . a:name
134endfunction
135
136call s:DefineInlineMarkup('Emphasis', '\*', '\*', '\*')
137call s:DefineInlineMarkup('StrongEmphasis', '\*\*', '\*', '\*\*')
138call s:DefineInlineMarkup('InterpretedTextOrHyperlinkReference', '`', '`', '`_\{0,2}')
139call s:DefineInlineMarkup('InlineLiteral', '``', "", '``')
140call s:DefineInlineMarkup('SubstitutionReference', '|', '|', '|_\{0,2}')
141call s:DefineInlineMarkup('InlineInternalTargets', '_`', '`', '`')
142
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200143" Sections are identified through their titles, which are marked up with
144" adornment: "underlines" below the title text, or underlines and matching
145" "overlines" above the title. An underline/overline is a single repeated
146" punctuation character that begins in column 1 and forms a line extending at
147" least as far as the right edge of the title text.
148"
149" It is difficult to count characters in a regex, but we at least special-case
150" the case where the title has at least three characters to require the
151" adornment to have at least three characters as well, in order to handle
152" properly the case of a literal block:
153"
154" this is the end of a paragraph
155" ::
156" this is a literal block
157syn match rstSections "\v^%(([=`:.'"~^_*+#-])\1+\n)?.{1,2}\n([=`:.'"~^_*+#-])\2+$"
158 \ contains=@Spell
159syn match rstSections "\v^%(([=`:.'"~^_*+#-])\1{2,}\n)?.{3,}\n([=`:.'"~^_*+#-])\2{2,}$"
160 \ contains=@Spell
Bram Moolenaar345efa02016-01-15 20:57:49 +0100161
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000162" TODO: Can’t remember why these two can’t be defined like the ones above.
163execute 'syn match rstFootnoteReference contains=@NoSpell' .
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200164 \ ' +\%(\s\|^\)\[\%(\d\+\|#\%(' . s:ReferenceName . '\)\=\|\*\)\]_+'
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000165
166execute 'syn match rstCitationReference contains=@NoSpell' .
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200167 \ ' +\%(\s\|^\)\[' . s:ReferenceName . '\]_\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)+'
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000168
169execute 'syn match rstHyperlinkReference' .
Bram Moolenaar25394022007-05-10 19:06:20 +0000170 \ ' /\<' . s:ReferenceName . '__\=\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)/'
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000171
172syn match rstStandaloneHyperlink contains=@NoSpell
173 \ "\<\%(\%(\%(https\=\|file\|ftp\|gopher\)://\|\%(mailto\|news\):\)[^[:space:]'\"<>]\+\|www[[:alnum:]_-]*\.[[:alnum:]_-]\+\.[^[:space:]'\"<>]\+\)[[:alnum:]/]"
174
Bram Moolenaar97d62492012-11-15 21:28:22 +0100175syn region rstCodeBlock contained matchgroup=rstDirective
Bram Moolenaard1caa942020-04-10 22:10:56 +0200176 \ start=+\%(sourcecode\|code\%(-block\)\=\)::\s*\(\S*\)\?\s*\n\%(\s*:.*:\s*.*\s*\n\)*\n\ze\z(\s\+\)+
Bram Moolenaar97d62492012-11-15 21:28:22 +0100177 \ skip=+^$+
Bram Moolenaar7b61a542014-08-23 15:31:19 +0200178 \ end=+^\z1\@!+
Bram Moolenaar97d62492012-11-15 21:28:22 +0100179 \ contains=@NoSpell
180syn cluster rstDirectives add=rstCodeBlock
181
182if !exists('g:rst_syntax_code_list')
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200183 " A mapping from a Vim filetype to a list of alias patterns (pattern
184 " branches to be specific, see ':help /pattern'). E.g. given:
185 "
186 " let g:rst_syntax_code_list = {
187 " \ 'cpp': ['cpp', 'c++'],
188 " \ }
189 "
190 " then the respective contents of the following two rST directives:
191 "
192 " .. code:: cpp
193 "
194 " auto i = 42;
195 "
196 " .. code:: C++
197 "
198 " auto i = 42;
199 "
200 " will both be highlighted as C++ code. As shown by the latter block
201 " pattern matching will be case-insensitive.
202 let g:rst_syntax_code_list = {
203 \ 'vim': ['vim'],
204 \ 'java': ['java'],
205 \ 'cpp': ['cpp', 'c++'],
206 \ 'lisp': ['lisp'],
207 \ 'php': ['php'],
208 \ 'python': ['python'],
209 \ 'perl': ['perl'],
210 \ 'sh': ['sh'],
211 \ }
212elseif type(g:rst_syntax_code_list) == type([])
213 " backward compatibility with former list format
214 let s:old_spec = g:rst_syntax_code_list
215 let g:rst_syntax_code_list = {}
216 for s:elem in s:old_spec
217 let g:rst_syntax_code_list[s:elem] = [s:elem]
218 endfor
Bram Moolenaar97d62492012-11-15 21:28:22 +0100219endif
220
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200221for s:filetype in keys(g:rst_syntax_code_list)
Bram Moolenaar97d62492012-11-15 21:28:22 +0100222 unlet! b:current_syntax
Bram Moolenaar7d76c802014-10-15 22:51:52 +0200223 " guard against setting 'isk' option which might cause problems (issue #108)
224 let prior_isk = &l:iskeyword
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200225 let s:alias_pattern = ''
226 \.'\%('
227 \.join(g:rst_syntax_code_list[s:filetype], '\|')
228 \.'\)'
229
230 exe 'syn include @rst'.s:filetype.' syntax/'.s:filetype.'.vim'
231 exe 'syn region rstDirective'.s:filetype
232 \.' matchgroup=rstDirective fold'
233 \.' start="\c\%(sourcecode\|code\%(-block\)\=\)::\s\+'.s:alias_pattern.'\_s*\n\ze\z(\s\+\)"'
Bram Moolenaara02a5512016-06-17 12:48:11 +0200234 \.' skip=#^$#'
235 \.' end=#^\z1\@!#'
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200236 \.' contains=@NoSpell,@rst'.s:filetype
237 exe 'syn cluster rstDirectives add=rstDirective'.s:filetype
238
Bram Moolenaar7d76c802014-10-15 22:51:52 +0200239 " reset 'isk' setting, if it has been changed
240 if &l:iskeyword !=# prior_isk
241 let &l:iskeyword = prior_isk
242 endif
243 unlet! prior_isk
Bram Moolenaar97d62492012-11-15 21:28:22 +0100244endfor
245
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200246" Enable top level spell checking
247syntax spell toplevel
248
Bram Moolenaar203d04d2013-06-06 21:36:40 +0200249" TODO: Use better syncing.
250syn sync minlines=50 linebreaks=2
251
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000252hi def link rstTodo Todo
253hi def link rstComment Comment
Bram Moolenaar9b451252012-08-15 17:43:31 +0200254hi def link rstSections Title
255hi def link rstTransition rstSections
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000256hi def link rstLiteralBlock String
257hi def link rstQuotedLiteralBlock String
258hi def link rstDoctestBlock PreProc
259hi def link rstTableLines rstDelimiter
260hi def link rstSimpleTableLines rstTableLines
261hi def link rstExplicitMarkup rstDirective
262hi def link rstDirective Keyword
263hi def link rstFootnote String
264hi def link rstCitation String
265hi def link rstHyperlinkTarget String
266hi def link rstExDirective String
267hi def link rstSubstitutionDefinition rstDirective
268hi def link rstDelimiter Delimiter
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000269hi def link rstInterpretedTextOrHyperlinkReference Identifier
270hi def link rstInlineLiteral String
271hi def link rstSubstitutionReference PreProc
272hi def link rstInlineInternalTargets Identifier
273hi def link rstFootnoteReference Identifier
274hi def link rstCitationReference Identifier
275hi def link rstHyperLinkReference Identifier
276hi def link rstStandaloneHyperlink Identifier
Bram Moolenaar97d62492012-11-15 21:28:22 +0100277hi def link rstCodeBlock String
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200278if exists('g:rst_use_emphasis_colors')
279 " TODO: Less arbitrary color selection
280 hi def rstEmphasis ctermfg=13 term=italic cterm=italic gui=italic
281 hi def rstStrongEmphasis ctermfg=1 term=bold cterm=bold gui=bold
282else
283 hi def rstEmphasis term=italic cterm=italic gui=italic
284 hi def rstStrongEmphasis term=bold cterm=bold gui=bold
285endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000286
287let b:current_syntax = "rst"
288
Bram Moolenaar42eeac32005-06-29 22:40:58 +0000289let &cpo = s:cpo_save
290unlet s:cpo_save