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-07-23 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 \ ' end=/^\s\@!/ contains=rstTodo' 63 64execute '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=+^$+' . 86 \ ' end=+^\s\@!+ contains=@rstCruft,rstLiteralBlock' 87 88execute 'syn match rstSubstitutionDefinition contained' . 89 \ ' /|.*|\_s\+/ nextgroup=@rstDirectives' 90 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 . 94 \ '\ze[^[:space:]' . a:char_right . a:start[strlen(a:start) - 1] . ']+' . 95 \ a:middle . 96 \ ' end=+\S' . a:end . '\ze\%($\|\s\|[''"’)\]}>/:.,;!?\\-]\)+' 97endfunction 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, "'", "'") 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 " TODO: Additional Unicode Pd, Po, Pi, Pf, Ps characters 112 113 call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '\%(^\|\s\|\%ua0\|[/:]\)', '') 114 115 execute 'syn match rst' . a:name . 116 \ ' +\%(^\|\s\|\%ua0\|[''"([{</:]\)\zs' . a:start . 117 \ '[^[: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 130" 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 148 149" TODO: Can’t remember why these two can’t be defined like the ones above. 150execute 'syn match rstFootnoteReference contains=@NoSpell' . 151 \ ' +\%(\s\|^\)\[\%(\d\+\|#\%(' . s:ReferenceName . '\)\=\|\*\)\]_+' 152 153execute 'syn match rstCitationReference contains=@NoSpell' . 154 \ ' +\%(\s\|^\)\[' . s:ReferenceName . '\]_\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)+' 155 156execute 'syn match rstHyperlinkReference' . 157 \ ' /\<' . s:ReferenceName . '__\=\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)/' 158 159syn match rstStandaloneHyperlink contains=@NoSpell 160 \ "\<\%(\%(\%(https\=\|file\|ftp\|gopher\)://\|\%(mailto\|news\):\)[^[:space:]'\"<>]\+\|www[[:alnum:]_-]*\.[[:alnum:]_-]\+\.[^[:space:]'\"<>]\+\)[[:alnum:]/]" 161 162syn region rstCodeBlock contained matchgroup=rstDirective 163 \ start=+\%(sourcecode\|code\%(-block\)\=\)::\s\+.*\_s*\n\ze\z(\s\+\)+ 164 \ skip=+^$+ 165 \ end=+^\z1\@!+ 166 \ contains=@NoSpell 167syn cluster rstDirectives add=rstCodeBlock 168 169if !exists('g:rst_syntax_code_list') 170 " 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 206endif 207 208for s:filetype in keys(g:rst_syntax_code_list) 209 unlet! b:current_syntax 210 " guard against setting 'isk' option which might cause problems (issue #108) 211 let prior_isk = &l:iskeyword 212 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\+\)"' 221 \.' skip=#^$#' 222 \.' end=#^\z1\@!#' 223 \.' contains=@NoSpell,@rst'.s:filetype 224 exe 'syn cluster rstDirectives add=rstDirective'.s:filetype 225 226 " 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 231endfor 232 233" Enable top level spell checking 234syntax spell toplevel 235 236" TODO: Use better syncing. 237syn sync minlines=50 linebreaks=2 238 239hi def link rstTodo Todo 240hi def link rstComment Comment 241hi def link rstSections Title 242hi def link rstTransition rstSections 243hi 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 256hi 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 264hi def link rstCodeBlock String 265if 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 273 274let b:current_syntax = "rst" 275 276let &cpo = s:cpo_save 277unlet s:cpo_save 278