1" Vim syntax file 2" Language: reStructuredText documentation format 3" Maintainer: Marshall Ward <[email protected]> 4" Previous Maintainer: Nikolai Weibull <[email protected]> 5" Website: https://github.com/marshallward/vim-restructuredtext 6" Latest Revision: 2018-12-29 7 8if exists("b:current_syntax") 9 finish 10endif 11 12let s:cpo_save = &cpo 13set cpo&vim 14 15syn case ignore 16 17syn match rstTransition /^[=`:.'"~^_*+#-]\{4,}\s*$/ 18 19syn cluster rstCruft contains=rstEmphasis,rstStrongEmphasis, 20 \ rstInterpretedText,rstInlineLiteral,rstSubstitutionReference, 21 \ rstInlineInternalTargets,rstFootnoteReference,rstHyperlinkReference 22 23syn region rstLiteralBlock matchgroup=rstDelimiter 24 \ start='::\_s*\n\ze\z(\s\+\)' skip='^$' end='^\z1\@!' 25 \ contains=@NoSpell 26 27syn region rstQuotedLiteralBlock matchgroup=rstDelimiter 28 \ start="::\_s*\n\ze\z([!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]\)" 29 \ end='^\z1\@!' contains=@NoSpell 30 31syn region rstDoctestBlock oneline display matchgroup=rstDelimiter 32 \ start='^>>>\s' end='^$' 33 34syn region rstTable transparent start='^\n\s*+[-=+]\+' end='^$' 35 \ contains=rstTableLines,@rstCruft 36syn match rstTableLines contained display '|\|+\%(=\+\|-\+\)\=' 37 38syn 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*\)\@>\)\+\)\@>$' 46 47syn cluster rstDirectives contains=rstFootnote,rstCitation, 48 \ rstHyperlinkTarget,rstExDirective 49 50syn match rstExplicitMarkup '^\s*\.\.\_s' 51 \ nextgroup=@rstDirectives,rstComment,rstSubstitutionDefinition 52 53" "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:]]\+\)*' 57 58syn keyword rstTodo contained FIXME TODO XXX NOTE 59 60execute 'syn region rstComment contained' . 61 \ ' start=/.*/' 62 \ ' skip=+^$+' . 63 \ ' end=/^\s\@!/ contains=rstTodo' 64 65execute '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=+^$+' . 87 \ ' end=+^\s\@!+ contains=@rstCruft,rstLiteralBlock' 88 89execute 'syn match rstSubstitutionDefinition contained' . 90 \ ' /|.*|\_s\+/ nextgroup=@rstDirectives' 91 92function! s:DefineOneInlineMarkup(name, start, middle, end, char_left, char_right) 93 execute 'syn region rst' . a:name . 94 \ ' start=+' . a:char_left . '\zs' . a:start . 95 \ '\ze[^[:space:]' . a:char_right . a:start[strlen(a:start) - 1] . ']+' . 96 \ a:middle . 97 \ ' end=+\S' . a:end . '\ze\%($\|\s\|[''"’)\]}>/:.,;!?\\-]\)+' 98endfunction 99 100function! s:DefineInlineMarkup(name, start, middle, end) 101 let middle = a:middle != "" ? 102 \ (' skip=+\\\\\|\\' . a:middle . '+') : 103 \ "" 104 105 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, '{', '}') 110 call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '<', '>') 111 call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '’', '’') 112 " TODO: Additional Unicode Pd, Po, Pi, Pf, Ps characters 113 114 call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '\%(^\|\s\|\%ua0\|[/:]\)', '') 115 116 execute 'syn match rst' . a:name . 117 \ ' +\%(^\|\s\|\%ua0\|[''"([{</:]\)\zs' . a:start . 118 \ '[^[:space:]' . a:start[strlen(a:start) - 1] . ']' 119 \ a:end . '\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)+' 120 121 execute 'hi def link rst' . a:name . 'Delimiter' . ' rst' . a:name 122endfunction 123 124call s:DefineInlineMarkup('Emphasis', '\*', '\*', '\*') 125call s:DefineInlineMarkup('StrongEmphasis', '\*\*', '\*', '\*\*') 126call s:DefineInlineMarkup('InterpretedTextOrHyperlinkReference', '`', '`', '`_\{0,2}') 127call s:DefineInlineMarkup('InlineLiteral', '``', "", '``') 128call s:DefineInlineMarkup('SubstitutionReference', '|', '|', '|_\{0,2}') 129call s:DefineInlineMarkup('InlineInternalTargets', '_`', '`', '`') 130 131" Sections are identified through their titles, which are marked up with 132" adornment: "underlines" below the title text, or underlines and matching 133" "overlines" above the title. An underline/overline is a single repeated 134" punctuation character that begins in column 1 and forms a line extending at 135" least as far as the right edge of the title text. 136" 137" It is difficult to count characters in a regex, but we at least special-case 138" the case where the title has at least three characters to require the 139" adornment to have at least three characters as well, in order to handle 140" properly the case of a literal block: 141" 142" this is the end of a paragraph 143" :: 144" this is a literal block 145syn match rstSections "\v^%(([=`:.'"~^_*+#-])\1+\n)?.{1,2}\n([=`:.'"~^_*+#-])\2+$" 146 \ contains=@Spell 147syn match rstSections "\v^%(([=`:.'"~^_*+#-])\1{2,}\n)?.{3,}\n([=`:.'"~^_*+#-])\2{2,}$" 148 \ contains=@Spell 149 150" TODO: Can’t remember why these two can’t be defined like the ones above. 151execute 'syn match rstFootnoteReference contains=@NoSpell' . 152 \ ' +\%(\s\|^\)\[\%(\d\+\|#\%(' . s:ReferenceName . '\)\=\|\*\)\]_+' 153 154execute 'syn match rstCitationReference contains=@NoSpell' . 155 \ ' +\%(\s\|^\)\[' . s:ReferenceName . '\]_\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)+' 156 157execute 'syn match rstHyperlinkReference' . 158 \ ' /\<' . s:ReferenceName . '__\=\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)/' 159 160syn match rstStandaloneHyperlink contains=@NoSpell 161 \ "\<\%(\%(\%(https\=\|file\|ftp\|gopher\)://\|\%(mailto\|news\):\)[^[:space:]'\"<>]\+\|www[[:alnum:]_-]*\.[[:alnum:]_-]\+\.[^[:space:]'\"<>]\+\)[[:alnum:]/]" 162 163syn region rstCodeBlock contained matchgroup=rstDirective 164 \ start=+\%(sourcecode\|code\%(-block\)\=\)::\s\+.*\_s*\n\ze\z(\s\+\)+ 165 \ skip=+^$+ 166 \ end=+^\z1\@!+ 167 \ contains=@NoSpell 168syn cluster rstDirectives add=rstCodeBlock 169 170if !exists('g:rst_syntax_code_list') 171 " A mapping from a Vim filetype to a list of alias patterns (pattern 172 " branches to be specific, see ':help /pattern'). E.g. given: 173 " 174 " let g:rst_syntax_code_list = { 175 " \ 'cpp': ['cpp', 'c++'], 176 " \ } 177 " 178 " then the respective contents of the following two rST directives: 179 " 180 " .. code:: cpp 181 " 182 " auto i = 42; 183 " 184 " .. code:: C++ 185 " 186 " auto i = 42; 187 " 188 " will both be highlighted as C++ code. As shown by the latter block 189 " pattern matching will be case-insensitive. 190 let g:rst_syntax_code_list = { 191 \ 'vim': ['vim'], 192 \ 'java': ['java'], 193 \ 'cpp': ['cpp', 'c++'], 194 \ 'lisp': ['lisp'], 195 \ 'php': ['php'], 196 \ 'python': ['python'], 197 \ 'perl': ['perl'], 198 \ 'sh': ['sh'], 199 \ } 200elseif type(g:rst_syntax_code_list) == type([]) 201 " backward compatibility with former list format 202 let s:old_spec = g:rst_syntax_code_list 203 let g:rst_syntax_code_list = {} 204 for s:elem in s:old_spec 205 let g:rst_syntax_code_list[s:elem] = [s:elem] 206 endfor 207endif 208 209for s:filetype in keys(g:rst_syntax_code_list) 210 unlet! b:current_syntax 211 " guard against setting 'isk' option which might cause problems (issue #108) 212 let prior_isk = &l:iskeyword 213 let s:alias_pattern = '' 214 \.'\%(' 215 \.join(g:rst_syntax_code_list[s:filetype], '\|') 216 \.'\)' 217 218 exe 'syn include @rst'.s:filetype.' syntax/'.s:filetype.'.vim' 219 exe 'syn region rstDirective'.s:filetype 220 \.' matchgroup=rstDirective fold' 221 \.' start="\c\%(sourcecode\|code\%(-block\)\=\)::\s\+'.s:alias_pattern.'\_s*\n\ze\z(\s\+\)"' 222 \.' skip=#^$#' 223 \.' end=#^\z1\@!#' 224 \.' contains=@NoSpell,@rst'.s:filetype 225 exe 'syn cluster rstDirectives add=rstDirective'.s:filetype 226 227 " reset 'isk' setting, if it has been changed 228 if &l:iskeyword !=# prior_isk 229 let &l:iskeyword = prior_isk 230 endif 231 unlet! prior_isk 232endfor 233 234" Enable top level spell checking 235syntax spell toplevel 236 237" TODO: Use better syncing. 238syn sync minlines=50 linebreaks=2 239 240hi def link rstTodo Todo 241hi def link rstComment Comment 242hi def link rstSections Title 243hi def link rstTransition rstSections 244hi def link rstLiteralBlock String 245hi def link rstQuotedLiteralBlock String 246hi def link rstDoctestBlock PreProc 247hi def link rstTableLines rstDelimiter 248hi def link rstSimpleTableLines rstTableLines 249hi def link rstExplicitMarkup rstDirective 250hi def link rstDirective Keyword 251hi def link rstFootnote String 252hi def link rstCitation String 253hi def link rstHyperlinkTarget String 254hi def link rstExDirective String 255hi def link rstSubstitutionDefinition rstDirective 256hi def link rstDelimiter Delimiter 257hi def link rstInterpretedTextOrHyperlinkReference Identifier 258hi def link rstInlineLiteral String 259hi def link rstSubstitutionReference PreProc 260hi def link rstInlineInternalTargets Identifier 261hi def link rstFootnoteReference Identifier 262hi def link rstCitationReference Identifier 263hi def link rstHyperLinkReference Identifier 264hi def link rstStandaloneHyperlink Identifier 265hi def link rstCodeBlock String 266if exists('g:rst_use_emphasis_colors') 267 " TODO: Less arbitrary color selection 268 hi def rstEmphasis ctermfg=13 term=italic cterm=italic gui=italic 269 hi def rstStrongEmphasis ctermfg=1 term=bold cterm=bold gui=bold 270else 271 hi def rstEmphasis term=italic cterm=italic gui=italic 272 hi def rstStrongEmphasis term=bold cterm=bold gui=bold 273endif 274 275let b:current_syntax = "rst" 276 277let &cpo = s:cpo_save 278unlet s:cpo_save 279