blob: d620d91f4af0b2ad01350e48da4dfa1f7b7ddcfa [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001" Vim 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 Moolenaar91f84f62018-07-29 15:07:52 +02006" Latest Revision: 2018-07-23
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
24 \ start='::\_s*\n\ze\z(\s\+\)' skip='^$' end='^\z1\@!'
25 \ 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=/.*/'
62 \ ' end=/^\s\@!/ contains=rstTodo'
Bram Moolenaar071d4272004-06-13 20:20:40 +000063
Bram Moolenaar779b74b2006-04-10 14:55:34 +000064execute 'syn region rstFootnote contained matchgroup=rstDirective' .
65 \ ' start=+\[\%(\d\+\|#\%(' . s:ReferenceName . '\)\=\|\*\)\]\_s+' .
66 \ ' skip=+^$+' .
67 \ ' end=+^\s\@!+ contains=@rstCruft,@NoSpell'
68
69execute 'syn region rstCitation contained matchgroup=rstDirective' .
70 \ ' start=+\[' . s:ReferenceName . '\]\_s+' .
71 \ ' skip=+^$+' .
72 \ ' end=+^\s\@!+ contains=@rstCruft,@NoSpell'
73
74syn region rstHyperlinkTarget contained matchgroup=rstDirective
75 \ start='_\%(_\|[^:\\]*\%(\\.[^:\\]*\)*\):\_s' skip=+^$+ end=+^\s\@!+
76
77syn region rstHyperlinkTarget contained matchgroup=rstDirective
78 \ start='_`[^`\\]*\%(\\.[^`\\]*\)*`:\_s' skip=+^$+ end=+^\s\@!+
79
80syn region rstHyperlinkTarget matchgroup=rstDirective
81 \ start=+^__\_s+ skip=+^$+ end=+^\s\@!+
82
83execute 'syn region rstExDirective contained matchgroup=rstDirective' .
84 \ ' start=+' . s:ReferenceName . '::\_s+' .
85 \ ' skip=+^$+' .
Bram Moolenaar12969c02015-09-08 23:36:10 +020086 \ ' end=+^\s\@!+ contains=@rstCruft,rstLiteralBlock'
Bram Moolenaar779b74b2006-04-10 14:55:34 +000087
88execute 'syn match rstSubstitutionDefinition contained' .
Bram Moolenaar91f84f62018-07-29 15:07:52 +020089 \ ' /|.*|\_s\+/ nextgroup=@rstDirectives'
Bram Moolenaar779b74b2006-04-10 14:55:34 +000090
91function! s:DefineOneInlineMarkup(name, start, middle, end, char_left, char_right)
92 execute 'syn region rst' . a:name .
93 \ ' start=+' . a:char_left . '\zs' . a:start .
Bram Moolenaar25394022007-05-10 19:06:20 +000094 \ '\ze[^[:space:]' . a:char_right . a:start[strlen(a:start) - 1] . ']+' .
Bram Moolenaar779b74b2006-04-10 14:55:34 +000095 \ a:middle .
Bram Moolenaar7571d552016-08-18 22:54:46 +020096 \ ' end=+\S' . a:end . '\ze\%($\|\s\|[''"’)\]}>/:.,;!?\\-]\)+'
Bram Moolenaar779b74b2006-04-10 14:55:34 +000097endfunction
98
99function! s:DefineInlineMarkup(name, start, middle, end)
100 let middle = a:middle != "" ?
101 \ (' skip=+\\\\\|\\' . a:middle . '+') :
102 \ ""
103
104 call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, "'", "'")
Bram Moolenaar7b61a542014-08-23 15:31:19 +0200105 call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '"', '"')
106 call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '(', ')')
107 call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '\[', '\]')
108 call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '{', '}')
109 call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '<', '>')
Bram Moolenaar7571d552016-08-18 22:54:46 +0200110 call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '’', '’')
111 " TODO: Additional Unicode Pd, Po, Pi, Pf, Ps characters
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000112
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200113 call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '\%(^\|\s\|\%ua0\|[/:]\)', '')
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000114
115 execute 'syn match rst' . a:name .
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200116 \ ' +\%(^\|\s\|\%ua0\|[''"([{</:]\)\zs' . a:start .
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000117 \ '[^[:space:]' . a:start[strlen(a:start) - 1] . ']'
118 \ a:end . '\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)+'
119
120 execute 'hi def link rst' . a:name . 'Delimiter' . ' rst' . a:name
121endfunction
122
123call s:DefineInlineMarkup('Emphasis', '\*', '\*', '\*')
124call s:DefineInlineMarkup('StrongEmphasis', '\*\*', '\*', '\*\*')
125call s:DefineInlineMarkup('InterpretedTextOrHyperlinkReference', '`', '`', '`_\{0,2}')
126call s:DefineInlineMarkup('InlineLiteral', '``', "", '``')
127call s:DefineInlineMarkup('SubstitutionReference', '|', '|', '|_\{0,2}')
128call s:DefineInlineMarkup('InlineInternalTargets', '_`', '`', '`')
129
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200130" Sections are identified through their titles, which are marked up with
131" adornment: "underlines" below the title text, or underlines and matching
132" "overlines" above the title. An underline/overline is a single repeated
133" punctuation character that begins in column 1 and forms a line extending at
134" least as far as the right edge of the title text.
135"
136" It is difficult to count characters in a regex, but we at least special-case
137" the case where the title has at least three characters to require the
138" adornment to have at least three characters as well, in order to handle
139" properly the case of a literal block:
140"
141" this is the end of a paragraph
142" ::
143" this is a literal block
144syn match rstSections "\v^%(([=`:.'"~^_*+#-])\1+\n)?.{1,2}\n([=`:.'"~^_*+#-])\2+$"
145 \ contains=@Spell
146syn match rstSections "\v^%(([=`:.'"~^_*+#-])\1{2,}\n)?.{3,}\n([=`:.'"~^_*+#-])\2{2,}$"
147 \ contains=@Spell
Bram Moolenaar345efa02016-01-15 20:57:49 +0100148
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000149" TODO: Cant remember why these two cant be defined like the ones above.
150execute 'syn match rstFootnoteReference contains=@NoSpell' .
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200151 \ ' +\%(\s\|^\)\[\%(\d\+\|#\%(' . s:ReferenceName . '\)\=\|\*\)\]_+'
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000152
153execute 'syn match rstCitationReference contains=@NoSpell' .
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200154 \ ' +\%(\s\|^\)\[' . s:ReferenceName . '\]_\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)+'
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000155
156execute 'syn match rstHyperlinkReference' .
Bram Moolenaar25394022007-05-10 19:06:20 +0000157 \ ' /\<' . s:ReferenceName . '__\=\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)/'
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000158
159syn match rstStandaloneHyperlink contains=@NoSpell
160 \ "\<\%(\%(\%(https\=\|file\|ftp\|gopher\)://\|\%(mailto\|news\):\)[^[:space:]'\"<>]\+\|www[[:alnum:]_-]*\.[[:alnum:]_-]\+\.[^[:space:]'\"<>]\+\)[[:alnum:]/]"
161
Bram Moolenaar97d62492012-11-15 21:28:22 +0100162syn region rstCodeBlock contained matchgroup=rstDirective
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200163 \ start=+\%(sourcecode\|code\%(-block\)\=\)::\s\+.*\_s*\n\ze\z(\s\+\)+
Bram Moolenaar97d62492012-11-15 21:28:22 +0100164 \ skip=+^$+
Bram Moolenaar7b61a542014-08-23 15:31:19 +0200165 \ end=+^\z1\@!+
Bram Moolenaar97d62492012-11-15 21:28:22 +0100166 \ contains=@NoSpell
167syn cluster rstDirectives add=rstCodeBlock
168
169if !exists('g:rst_syntax_code_list')
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200170 " A mapping from a Vim filetype to a list of alias patterns (pattern
171 " branches to be specific, see ':help /pattern'). E.g. given:
172 "
173 " let g:rst_syntax_code_list = {
174 " \ 'cpp': ['cpp', 'c++'],
175 " \ }
176 "
177 " then the respective contents of the following two rST directives:
178 "
179 " .. code:: cpp
180 "
181 " auto i = 42;
182 "
183 " .. code:: C++
184 "
185 " auto i = 42;
186 "
187 " will both be highlighted as C++ code. As shown by the latter block
188 " pattern matching will be case-insensitive.
189 let g:rst_syntax_code_list = {
190 \ 'vim': ['vim'],
191 \ 'java': ['java'],
192 \ 'cpp': ['cpp', 'c++'],
193 \ 'lisp': ['lisp'],
194 \ 'php': ['php'],
195 \ 'python': ['python'],
196 \ 'perl': ['perl'],
197 \ 'sh': ['sh'],
198 \ }
199elseif type(g:rst_syntax_code_list) == type([])
200 " backward compatibility with former list format
201 let s:old_spec = g:rst_syntax_code_list
202 let g:rst_syntax_code_list = {}
203 for s:elem in s:old_spec
204 let g:rst_syntax_code_list[s:elem] = [s:elem]
205 endfor
Bram Moolenaar97d62492012-11-15 21:28:22 +0100206endif
207
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200208for s:filetype in keys(g:rst_syntax_code_list)
Bram Moolenaar97d62492012-11-15 21:28:22 +0100209 unlet! b:current_syntax
Bram Moolenaar7d76c802014-10-15 22:51:52 +0200210 " guard against setting 'isk' option which might cause problems (issue #108)
211 let prior_isk = &l:iskeyword
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200212 let s:alias_pattern = ''
213 \.'\%('
214 \.join(g:rst_syntax_code_list[s:filetype], '\|')
215 \.'\)'
216
217 exe 'syn include @rst'.s:filetype.' syntax/'.s:filetype.'.vim'
218 exe 'syn region rstDirective'.s:filetype
219 \.' matchgroup=rstDirective fold'
220 \.' start="\c\%(sourcecode\|code\%(-block\)\=\)::\s\+'.s:alias_pattern.'\_s*\n\ze\z(\s\+\)"'
Bram Moolenaara02a5512016-06-17 12:48:11 +0200221 \.' skip=#^$#'
222 \.' end=#^\z1\@!#'
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200223 \.' contains=@NoSpell,@rst'.s:filetype
224 exe 'syn cluster rstDirectives add=rstDirective'.s:filetype
225
Bram Moolenaar7d76c802014-10-15 22:51:52 +0200226 " reset 'isk' setting, if it has been changed
227 if &l:iskeyword !=# prior_isk
228 let &l:iskeyword = prior_isk
229 endif
230 unlet! prior_isk
Bram Moolenaar97d62492012-11-15 21:28:22 +0100231endfor
232
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200233" Enable top level spell checking
234syntax spell toplevel
235
Bram Moolenaar203d04d2013-06-06 21:36:40 +0200236" TODO: Use better syncing.
237syn sync minlines=50 linebreaks=2
238
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000239hi def link rstTodo Todo
240hi def link rstComment Comment
Bram Moolenaar9b451252012-08-15 17:43:31 +0200241hi def link rstSections Title
242hi def link rstTransition rstSections
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000243hi def link rstLiteralBlock String
244hi def link rstQuotedLiteralBlock String
245hi def link rstDoctestBlock PreProc
246hi def link rstTableLines rstDelimiter
247hi def link rstSimpleTableLines rstTableLines
248hi def link rstExplicitMarkup rstDirective
249hi def link rstDirective Keyword
250hi def link rstFootnote String
251hi def link rstCitation String
252hi def link rstHyperlinkTarget String
253hi def link rstExDirective String
254hi def link rstSubstitutionDefinition rstDirective
255hi def link rstDelimiter Delimiter
Bram Moolenaar779b74b2006-04-10 14:55:34 +0000256hi def link rstInterpretedTextOrHyperlinkReference Identifier
257hi def link rstInlineLiteral String
258hi def link rstSubstitutionReference PreProc
259hi def link rstInlineInternalTargets Identifier
260hi def link rstFootnoteReference Identifier
261hi def link rstCitationReference Identifier
262hi def link rstHyperLinkReference Identifier
263hi def link rstStandaloneHyperlink Identifier
Bram Moolenaar97d62492012-11-15 21:28:22 +0100264hi def link rstCodeBlock String
Bram Moolenaar91f84f62018-07-29 15:07:52 +0200265if exists('g:rst_use_emphasis_colors')
266 " TODO: Less arbitrary color selection
267 hi def rstEmphasis ctermfg=13 term=italic cterm=italic gui=italic
268 hi def rstStrongEmphasis ctermfg=1 term=bold cterm=bold gui=bold
269else
270 hi def rstEmphasis term=italic cterm=italic gui=italic
271 hi def rstStrongEmphasis term=bold cterm=bold gui=bold
272endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000273
274let b:current_syntax = "rst"
275
Bram Moolenaar42eeac32005-06-29 22:40:58 +0000276let &cpo = s:cpo_save
277unlet s:cpo_save