blob: f849af97d268148bb65bb462ceca84f1155b0e2d [file] [log] [blame]
Bram Moolenaardd60c362023-02-27 15:49:53 +00001" Language: Markdown with chunks of R, Python and other languages
2" Maintainer: Jakson Aquino <jalvesaq@gmail.com>
Bram Moolenaar77cdfd12016-03-12 12:57:59 +01003" Homepage: https://github.com/jalvesaq/R-Vim-runtime
Bram Moolenaardd60c362023-02-27 15:49:53 +00004" Last Change: Fri Feb 24, 2023 08:28AM
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +02005"
6" For highlighting pandoc extensions to markdown like citations and TeX and
7" many other advanced features like folding of markdown sections, it is
8" recommended to install the vim-pandoc filetype plugin as well as the
9" vim-pandoc-syntax filetype plugin from https://github.com/vim-pandoc.
Bram Moolenaarfc65cab2018-08-28 22:58:02 +020010
Bram Moolenaardb6ea062014-07-10 22:01:47 +020011
Bram Moolenaar77cdfd12016-03-12 12:57:59 +010012if exists("b:current_syntax")
Bram Moolenaardb6ea062014-07-10 22:01:47 +020013 finish
14endif
15
Bram Moolenaardd60c362023-02-27 15:49:53 +000016let s:cpo_save = &cpo
17set cpo&vim
18
Bram Moolenaar11e3c5b2021-04-21 18:09:37 +020019" Highlight the header of the chunks as R code
20let g:rmd_syn_hl_chunk = get(g:, 'rmd_syn_hl_chunk', 0)
Bram Moolenaarfc65cab2018-08-28 22:58:02 +020021
22" Pandoc-syntax has more features, but it is slower.
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +020023" https://github.com/vim-pandoc/vim-pandoc-syntax
Bram Moolenaardd60c362023-02-27 15:49:53 +000024
25" Don't waste time loading syntax that will be discarded:
26let s:save_pandoc_lngs = get(g:, 'pandoc#syntax#codeblocks#embeds#langs', [])
27let g:pandoc#syntax#codeblocks#embeds#langs = []
28
29" Step_1: Source pandoc.vim if it is installed:
Bram Moolenaardb6ea062014-07-10 22:01:47 +020030runtime syntax/pandoc.vim
31if exists("b:current_syntax")
Bram Moolenaardd60c362023-02-27 15:49:53 +000032 if hlexists('pandocDelimitedCodeBlock')
33 syn clear pandocDelimitedCodeBlock
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +020034 endif
Bram Moolenaardd60c362023-02-27 15:49:53 +000035
36 if len(s:save_pandoc_lngs) > 0 && !exists('g:rmd_fenced_languages')
37 let g:rmd_fenced_languages = deepcopy(s:save_pandoc_lngs)
38 endif
39
40 " Recognize inline R code
41 syn region rmdrInline matchgroup=rmdInlineDelim start="`r " end="`" contains=@Rmdr containedin=pandocLaTeXRegion,yamlFlowString keepend
Bram Moolenaarfc65cab2018-08-28 22:58:02 +020042else
Bram Moolenaardd60c362023-02-27 15:49:53 +000043 " Step_2: Source markdown.vim if pandoc.vim is not installed
44
45 " Configuration if not using pandoc syntax:
46 " Add syntax highlighting of YAML header
47 let g:rmd_syn_hl_yaml = get(g:, 'rmd_syn_hl_yaml', 1)
48 " Add syntax highlighting of citation keys
49 let g:rmd_syn_hl_citations = get(g:, 'rmd_syn_hl_citations', 1)
50
51 " R chunks will not be highlighted by syntax/markdown because their headers
52 " follow a non standard pattern: "```{lang" instead of "^```lang".
53 " Make a copy of g:markdown_fenced_languages to highlight the chunks later:
54 if exists('g:markdown_fenced_languages') && !exists('g:rmd_fenced_languages')
55 let g:rmd_fenced_languages = deepcopy(g:markdown_fenced_languages)
56 endif
57
58 if exists('g:markdown_fenced_languages') && len(g:markdown_fenced_languages) > 0
59 let s:save_mfl = deepcopy(g:markdown_fenced_languages)
60 endif
61 " Don't waste time loading syntax that will be discarded:
62 let g:markdown_fenced_languages = []
63 runtime syntax/markdown.vim
64 if exists('s:save_mfl') > 0
65 let g:markdown_fenced_languages = deepcopy(s:save_mfl)
66 unlet s:save_mfl
67 endif
68 syn region rmdrInline matchgroup=rmdInlineDelim start="`r " end="`" contains=@Rmdr keepend
69
70 " Step_2a: Add highlighting for both YAML and citations which are pandoc
71 " specific, but also used in Rmd files
72
73 " You don't need this if either your markdown/syntax.vim already highlights
74 " the YAML header or you are writing standard markdown
75 if g:rmd_syn_hl_yaml
76 " Basic highlighting of YAML header
77 syn match rmdYamlFieldTtl /^\s*\zs\w\%(-\|\w\)*\ze:/ contained
78 syn match rmdYamlFieldTtl /^\s*-\s*\zs\w\%(-\|\w\)*\ze:/ contained
79 syn region yamlFlowString matchgroup=yamlFlowStringDelimiter start='"' skip='\\"' end='"' contains=yamlEscape,rmdrInline contained
80 syn region yamlFlowString matchgroup=yamlFlowStringDelimiter start="'" skip="''" end="'" contains=yamlSingleEscape,rmdrInline contained
81 syn match yamlEscape contained '\\\%([\\"abefnrtv\^0_ NLP\n]\|x\x\x\|u\x\{4}\|U\x\{8}\)'
82 syn match yamlSingleEscape contained "''"
83 syn match yamlComment /#.*/ contained
84 " A second colon is a syntax error, unles within a string or following !expr
85 syn match yamlColonError /:\s*[^'^"^!]*:/ contained
86 if &filetype == 'quarto'
87 syn region pandocYAMLHeader matchgroup=rmdYamlBlockDelim start=/\%(\%^\|\_^\s*\n\)\@<=\_^-\{3}\ze\n.\+/ end=/^---$/ keepend contains=rmdYamlFieldTtl,yamlFlowString,yamlComment,yamlColonError
88 else
89 syn region pandocYAMLHeader matchgroup=rmdYamlBlockDelim start=/\%(\%^\|\_^\s*\n\)\@<=\_^-\{3}\ze\n.\+/ end=/^\([-.]\)\1\{2}$/ keepend contains=rmdYamlFieldTtl,yamlFlowString,yamlComment,yamlColonError
90 endif
91 hi def link rmdYamlBlockDelim Delimiter
92 hi def link rmdYamlFieldTtl Identifier
93 hi def link yamlFlowString String
94 hi def link yamlComment Comment
95 hi def link yamlColonError Error
96 endif
97
98 " You don't need this if either your markdown/syntax.vim already highlights
99 " citations or you are writing standard markdown
100 if g:rmd_syn_hl_citations
101 " From vim-pandoc-syntax
102 " parenthetical citations
103 syn match pandocPCite /\^\@<!\[[^\[\]]\{-}-\{0,1}@[[:alnum:]_][[:alnum:]à-öø-ÿÀ-ÖØ-ß_:.#$%&\-+?<>~\/]*.\{-}\]/ contains=pandocEmphasis,pandocStrong,pandocLatex,pandocCiteKey,@Spell,pandocAmpersandEscape display
104 " in-text citations with location
105 syn match pandocICite /@[[:alnum:]_][[:alnum:]à-öø-ÿÀ-ÖØ-ß_:.#$%&\-+?<>~\/]*\s\[.\{-1,}\]/ contains=pandocCiteKey,@Spell display
106 " cite keys
107 syn match pandocCiteKey /\(-\=@[[:alnum:]_][[:alnum:]à-öø-ÿÀ-ÖØ-ß_:.#$%&\-+?<>~\/]*\)/ containedin=pandocPCite,pandocICite contains=@NoSpell display
108 syn match pandocCiteAnchor /[-@]/ contained containedin=pandocCiteKey display
109 syn match pandocCiteLocator /[\[\]]/ contained containedin=pandocPCite,pandocICite
110 hi def link pandocPCite Operator
111 hi def link pandocICite Operator
112 hi def link pandocCiteKey Label
113 hi def link pandocCiteAnchor Operator
114 hi def link pandocCiteLocator Operator
115 endif
Bram Moolenaardb6ea062014-07-10 22:01:47 +0200116endif
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +0200117
Bram Moolenaardd60c362023-02-27 15:49:53 +0000118" Step_3: Highlight code blocks.
119
120syn region rmdCodeBlock matchgroup=rmdCodeDelim start="^\s*```\s*{.*}$" matchgroup=rmdCodeDelim end="^\s*```\ze\s*$" keepend
121syn region rmdCodeBlock matchgroup=rmdCodeDelim start="^\s*```.+$" matchgroup=rmdCodeDelim end="^```$" keepend
122hi link rmdCodeBlock Special
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +0200123
Bram Moolenaarfc65cab2018-08-28 22:58:02 +0200124" Now highlight chunks:
Bram Moolenaardd60c362023-02-27 15:49:53 +0000125syn region knitrBodyOptions start='^#| ' end='$' contained containedin=rComment,pythonComment contains=knitrBodyVar,knitrBodyValue transparent
126syn match knitrBodyValue ': \zs.*\ze$' keepend contained containedin=knitrBodyOptions
127syn match knitrBodyVar '| \zs\S\{-}\ze:' contained containedin=knitrBodyOptions
128
129let g:rmd_fenced_languages = get(g:, 'rmd_fenced_languages', ['r'])
Bram Moolenaarfc65cab2018-08-28 22:58:02 +0200130for s:type in g:rmd_fenced_languages
131 if s:type =~ '='
Bram Moolenaara6c27c42019-05-09 19:16:22 +0200132 let s:ft = substitute(s:type, '.*=', '', '')
133 let s:nm = substitute(s:type, '=.*', '', '')
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +0200134 else
Bram Moolenaara6c27c42019-05-09 19:16:22 +0200135 let s:ft = s:type
Bram Moolenaarfc65cab2018-08-28 22:58:02 +0200136 let s:nm = s:type
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +0200137 endif
Bram Moolenaarfc65cab2018-08-28 22:58:02 +0200138 unlet! b:current_syntax
Bram Moolenaara6c27c42019-05-09 19:16:22 +0200139 exe 'syn include @Rmd'.s:nm.' syntax/'.s:ft.'.vim'
Bram Moolenaarfc65cab2018-08-28 22:58:02 +0200140 if g:rmd_syn_hl_chunk
Bram Moolenaardd60c362023-02-27 15:49:53 +0000141 exe 'syn match knitrChunkDelim /```\s*{\s*'.s:nm.'/ contained containedin=knitrChunkBrace contains=knitrChunkLabel'
142 exe 'syn match knitrChunkLabelDelim /```\s*{\s*'.s:nm.',\=\s*[-[:alnum:]]\{-1,}[,}]/ contained containedin=knitrChunkBrace'
143 syn match knitrChunkDelim /}\s*$/ contained containedin=knitrChunkBrace
144 exe 'syn match knitrChunkBrace /```\s*{\s*'.s:nm.'.*$/ contained containedin=rmd'.s:nm.'Chunk contains=knitrChunkDelim,knitrChunkLabelDelim,@Rmd'.s:nm
145 exe 'syn region rmd'.s:nm.'Chunk start="^\s*```\s*{\s*=\?'.s:nm.'\>.*$" matchgroup=rmdCodeDelim end="^\s*```\ze\s*$" keepend contains=knitrChunkBrace,@Rmd'.s:nm
146
147 hi link knitrChunkLabel Identifier
148 hi link knitrChunkDelim rmdCodeDelim
149 hi link knitrChunkLabelDelim rmdCodeDelim
Bram Moolenaarfc65cab2018-08-28 22:58:02 +0200150 else
Bram Moolenaardd60c362023-02-27 15:49:53 +0000151 exe 'syn region rmd'.s:nm.'Chunk matchgroup=rmdCodeDelim start="^\s*```\s*{\s*=\?'.s:nm.'\>.*$" matchgroup=rmdCodeDelim end="^\s*```\ze\s*$" keepend contains=@Rmd'.s:nm
Bram Moolenaarfc65cab2018-08-28 22:58:02 +0200152 endif
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +0200153endfor
Bram Moolenaarfc65cab2018-08-28 22:58:02 +0200154unlet! s:type
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +0200155
Bram Moolenaardd60c362023-02-27 15:49:53 +0000156" Step_4: Highlight code recognized by pandoc but not defined in pandoc.vim yet:
157syn match pandocDivBegin '^:::\+ {.\{-}}' contains=pandocHeaderAttr
158syn match pandocDivEnd '^:::\+$'
Bram Moolenaar11e3c5b2021-04-21 18:09:37 +0200159
Bram Moolenaardd60c362023-02-27 15:49:53 +0000160hi def link knitrBodyVar PreProc
161hi def link knitrBodyValue Constant
162hi def link knitrBodyOptions rComment
163hi def link pandocDivBegin Delimiter
164hi def link pandocDivEnd Delimiter
Bram Moolenaarfc65cab2018-08-28 22:58:02 +0200165hi def link rmdInlineDelim Delimiter
166hi def link rmdCodeDelim Delimiter
Bram Moolenaardb6ea062014-07-10 22:01:47 +0200167
Bram Moolenaardd60c362023-02-27 15:49:53 +0000168if len(s:save_pandoc_lngs)
169 let g:pandoc#syntax#codeblocks#embeds#langs = s:save_pandoc_lngs
Bram Moolenaardb6ea062014-07-10 22:01:47 +0200170endif
Bram Moolenaardd60c362023-02-27 15:49:53 +0000171unlet s:save_pandoc_lngs
Bram Moolenaarfc65cab2018-08-28 22:58:02 +0200172let &cpo = s:cpo_save
173unlet s:cpo_save
174
Bram Moolenaardd60c362023-02-27 15:49:53 +0000175let b:current_syntax = "rmd"
176
Bram Moolenaardb6ea062014-07-10 22:01:47 +0200177" vim: ts=8 sw=2