summaryrefslogtreecommitdiff
path: root/runtime/syntax/rmd.vim
blob: cccd4110f560aabcfb400c309ef1973af7151202 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
" markdown Text with R statements
" Language: markdown with R code chunks
" Homepage: https://github.com/jalvesaq/R-Vim-runtime
" Last Change: Wed Apr 21, 2021  09:55AM
"
"   For highlighting pandoc extensions to markdown like citations and TeX and
"   many other advanced features like folding of markdown sections, it is
"   recommended to install the vim-pandoc filetype plugin as well as the
"   vim-pandoc-syntax filetype plugin from https://github.com/vim-pandoc.


if exists("b:current_syntax")
  finish
endif

" Highlight the header of the chunks as R code
let g:rmd_syn_hl_chunk = get(g:, 'rmd_syn_hl_chunk', 0)

" Pandoc-syntax has more features, but it is slower.
" https://github.com/vim-pandoc/vim-pandoc-syntax
let g:pandoc#syntax#codeblocks#embeds#langs = get(g:, 'pandoc#syntax#codeblocks#embeds#langs', ['r'])
runtime syntax/pandoc.vim
if exists("b:current_syntax")
  " Recognize inline R code
  syn region rmdrInline matchgroup=rmdInlineDelim start="`r "  end="`" contains=@R containedin=pandocLaTeXRegion,yamlFlowString keepend
  hi def link rmdInlineDelim Delimiter

  " Fix recognition of language chunks (code adapted from pandoc, 2021-03-28)
  " Knitr requires braces in the block's header
  for s:lng in g:pandoc#syntax#codeblocks#embeds#langs
    let s:nm = matchstr(s:lng, '^[^=]*')
    exe 'syn clear pandocDelimitedCodeBlock_'.s:nm
    exe 'syn clear pandocDelimitedCodeBlockinBlockQuote_'.s:nm
    if g:rmd_syn_hl_chunk
      exe 'syn region rmd'.s:nm.'ChunkDelim matchgroup=rmdCodeDelim start="^\s*```\s*{\s*'.s:nm.'\>" matchgroup=rmdCodeDelim end="}$" keepend containedin=rmd'.s:nm.'Chunk contains=@R'
      exe 'syn region rmd'.s:nm.'Chunk start="^\s*```\s*{\s*'.s:nm.'\>.*$" matchgroup=rmdCodeDelim end="^\s*```\ze\s*$" keepend contains=rmd'.s:nm.'ChunkDelim,@'.toupper(s:nm)
    else
      exe 'syn region rmd'.s:nm.'Chunk matchgroup=rmdCodeDelim start="^\s*```\s*{\s*'.s:nm.'\>.*$" matchgroup=rmdCodeDelim end="^\s*```\ze\s*$" keepend contains=@'.toupper(s:nm)
    endif
  endfor
  unlet s:lng
  unlet s:nm
  hi def link rmdInlineDelim Delimiter
  hi def link rmdCodeDelim Delimiter
  let b:current_syntax = "rmd"
  finish
endif

" Configuration if not using pandoc syntax:
" Add syntax highlighting of YAML header
let g:rmd_syn_hl_yaml = get(g:, 'rmd_syn_hl_yaml', 1)
" Add syntax highlighting of citation keys
let g:rmd_syn_hl_citations = get(g:, 'rmd_syn_hl_citations', 1)

let s:cpo_save = &cpo
set cpo&vim

" R chunks will not be highlighted by syntax/markdown because their headers
" follow a non standard pattern: "```{lang" instead of "^```lang".
" Make a copy of g:markdown_fenced_languages to highlight the chunks later:
if exists('g:markdown_fenced_languages')
  if !exists('g:rmd_fenced_languages')
    let g:rmd_fenced_languages = deepcopy(g:markdown_fenced_languages)
    let g:markdown_fenced_languages = []
  endif
else
  let g:rmd_fenced_languages = ['r']
endif

runtime syntax/markdown.vim

" Now highlight chunks:
for s:type in g:rmd_fenced_languages
  if s:type =~ '='
    let s:ft = substitute(s:type, '.*=', '', '')
    let s:nm = substitute(s:type, '=.*', '', '')
  else
    let s:ft = s:type
    let s:nm  = s:type
  endif
  unlet! b:current_syntax
  exe 'syn include @Rmd'.s:nm.' syntax/'.s:ft.'.vim'
  if g:rmd_syn_hl_chunk
    exe 'syn region rmd'.s:nm.'ChunkDelim matchgroup=rmdCodeDelim start="^\s*```\s*{\s*'.s:nm.'\>" matchgroup=rmdCodeDelim end="}$" keepend containedin=rmd'.s:nm.'Chunk contains=@Rmdr'
    exe 'syn region rmd'.s:nm.'Chunk start="^\s*```\s*{\s*'.s:nm.'\>.*$" matchgroup=rmdCodeDelim end="^\s*```\ze\s*$" keepend contains=rmd'.s:nm.'ChunkDelim,@Rmd'.s:nm
  else
    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
  endif
endfor
unlet! s:type

" Recognize inline R code
syn region rmdrInline matchgroup=rmdInlineDelim start="`r "  end="`" contains=@Rmdr keepend

hi def link rmdInlineDelim Delimiter
hi def link rmdCodeDelim Delimiter

" You don't need this if either your markdown/syntax.vim already highlights
" the YAML header or you are writing standard markdown
if g:rmd_syn_hl_yaml
  " Minimum highlighting of yaml header
  syn match rmdYamlFieldTtl /^\s*\zs\w*\ze:/ contained
  syn match rmdYamlFieldTtl /^\s*-\s*\zs\w*\ze:/ contained
  syn region yamlFlowString matchgroup=yamlFlowStringDelimiter start='"' skip='\\"' end='"' contains=yamlEscape,rmdrInline contained
  syn region yamlFlowString matchgroup=yamlFlowStringDelimiter start="'" skip="''"  end="'" contains=yamlSingleEscape,rmdrInline contained
  syn match  yamlEscape contained '\\\%([\\"abefnrtv\^0_ NLP\n]\|x\x\x\|u\x\{4}\|U\x\{8}\)'
  syn match  yamlSingleEscape contained "''"
  syn region pandocYAMLHeader matchgroup=rmdYamlBlockDelim start=/\%(\%^\|\_^\s*\n\)\@<=\_^-\{3}\ze\n.\+/ end=/^\([-.]\)\1\{2}$/ keepend contains=rmdYamlFieldTtl,yamlFlowString
  hi def link rmdYamlBlockDelim Delimiter
  hi def link rmdYamlFieldTtl Identifier
  hi def link yamlFlowString String
endif

" You don't need this if either your markdown/syntax.vim already highlights
" citations or you are writing standard markdown
if g:rmd_syn_hl_citations
  " From vim-pandoc-syntax
  " parenthetical citations
  syn match pandocPCite /\^\@<!\[[^\[\]]\{-}-\{0,1}@[[:alnum:]_][[:alnum:]à-öø-ÿÀ-ÖØ-ß_:.#$%&\-+?<>~\/]*.\{-}\]/ contains=pandocEmphasis,pandocStrong,pandocLatex,pandocCiteKey,@Spell,pandocAmpersandEscape display
  " in-text citations with location
  syn match pandocICite /@[[:alnum:]_][[:alnum:]à-öø-ÿÀ-ÖØ-ß_:.#$%&\-+?<>~\/]*\s\[.\{-1,}\]/ contains=pandocCiteKey,@Spell display
  " cite keys
  syn match pandocCiteKey /\(-\=@[[:alnum:]_][[:alnum:]à-öø-ÿÀ-ÖØ-ß_:.#$%&\-+?<>~\/]*\)/ containedin=pandocPCite,pandocICite contains=@NoSpell display
  syn match pandocCiteAnchor /[-@]/ contained containedin=pandocCiteKey display
  syn match pandocCiteLocator /[\[\]]/ contained containedin=pandocPCite,pandocICite
  hi def link pandocPCite Operator
  hi def link pandocICite Operator
  hi def link pandocCiteKey Label
  hi def link pandocCiteAnchor Operator
  hi def link pandocCiteLocator Operator
endif

let b:current_syntax = "rmd"

let &cpo = s:cpo_save
unlet s:cpo_save

" vim: ts=8 sw=2