blob: 44187ff18ca44a788502547c973361964df02aae [file] [log] [blame]
Bram Moolenaar7a329912010-05-21 12:05:36 +02001" Vim syntax file
2" Language: Markdown
Bram Moolenaar3c053a12022-10-16 13:11:12 +01003" Maintainer: Tim Pope <https://github.com/tpope/vim-markdown>
Bram Moolenaar7a329912010-05-21 12:05:36 +02004" Filenames: *.markdown
Bram Moolenaar3c053a12022-10-16 13:11:12 +01005" Last Change: 2022 Oct 13
Bram Moolenaar7a329912010-05-21 12:05:36 +02006
7if exists("b:current_syntax")
8 finish
9endif
10
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020011if !exists('main_syntax')
12 let main_syntax = 'markdown'
13endif
14
Bram Moolenaar3c053a12022-10-16 13:11:12 +010015if has('folding')
16 let s:foldmethod = &l:foldmethod
17 let s:foldtext = &l:foldtext
18endif
19let s:iskeyword = &l:iskeyword
20
Bram Moolenaar7a329912010-05-21 12:05:36 +020021runtime! syntax/html.vim
22unlet! b:current_syntax
23
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020024if !exists('g:markdown_fenced_languages')
25 let g:markdown_fenced_languages = []
26endif
Bram Moolenaarc08ee742019-12-05 22:47:25 +010027let s:done_include = {}
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020028for s:type in map(copy(g:markdown_fenced_languages),'matchstr(v:val,"[^=]*$")')
Bram Moolenaarc08ee742019-12-05 22:47:25 +010029 if has_key(s:done_include, matchstr(s:type,'[^.]*'))
30 continue
31 endif
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020032 if s:type =~ '\.'
33 let b:{matchstr(s:type,'[^.]*')}_subtype = matchstr(s:type,'\.\zs.*')
34 endif
Bram Moolenaar3c053a12022-10-16 13:11:12 +010035 syn case match
36 exe 'syn include @markdownHighlight_'.tr(s:type,'.','_').' syntax/'.matchstr(s:type,'[^.]*').'.vim'
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020037 unlet! b:current_syntax
Bram Moolenaarc08ee742019-12-05 22:47:25 +010038 let s:done_include[matchstr(s:type,'[^.]*')] = 1
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020039endfor
40unlet! s:type
Bram Moolenaarc08ee742019-12-05 22:47:25 +010041unlet! s:done_include
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020042
Bram Moolenaar3c053a12022-10-16 13:11:12 +010043syn spell toplevel
44if exists('s:foldmethod') && s:foldmethod !=# &l:foldmethod
45 let &l:foldmethod = s:foldmethod
46 unlet s:foldmethod
47endif
48if exists('s:foldtext') && s:foldtext !=# &l:foldtext
49 let &l:foldtext = s:foldtext
50 unlet s:foldtext
51endif
52if s:iskeyword !=# &l:iskeyword
53 let &l:iskeyword = s:iskeyword
54endif
55unlet s:iskeyword
56
Bram Moolenaarc08ee742019-12-05 22:47:25 +010057if !exists('g:markdown_minlines')
58 let g:markdown_minlines = 50
59endif
60execute 'syn sync minlines=' . g:markdown_minlines
Bram Moolenaar3c053a12022-10-16 13:11:12 +010061syn sync linebreaks=1
Bram Moolenaar7a329912010-05-21 12:05:36 +020062syn case ignore
63
Bram Moolenaarc08ee742019-12-05 22:47:25 +010064syn match markdownValid '[<>]\c[a-z/$!]\@!' transparent contains=NONE
65syn match markdownValid '&\%(#\=\w*;\)\@!' transparent contains=NONE
Bram Moolenaar7a329912010-05-21 12:05:36 +020066
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020067syn match markdownLineStart "^[<@]\@!" nextgroup=@markdownBlock,htmlSpecialChar
Bram Moolenaar7a329912010-05-21 12:05:36 +020068
69syn cluster markdownBlock contains=markdownH1,markdownH2,markdownH3,markdownH4,markdownH5,markdownH6,markdownBlockquote,markdownListMarker,markdownOrderedListMarker,markdownCodeBlock,markdownRule
Bram Moolenaarc08ee742019-12-05 22:47:25 +010070syn cluster markdownInline contains=markdownLineBreak,markdownLinkText,markdownItalic,markdownBold,markdownCode,markdownEscape,@htmlTop,markdownError,markdownValid
Bram Moolenaar7a329912010-05-21 12:05:36 +020071
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020072syn match markdownH1 "^.\+\n=\+$" contained contains=@markdownInline,markdownHeadingRule,markdownAutomaticLink
73syn match markdownH2 "^.\+\n-\+$" contained contains=@markdownInline,markdownHeadingRule,markdownAutomaticLink
Bram Moolenaar7a329912010-05-21 12:05:36 +020074
75syn match markdownHeadingRule "^[=-]\+$" contained
76
Bram Moolenaar3c053a12022-10-16 13:11:12 +010077syn region markdownH1 matchgroup=markdownH1Delimiter start=" \{,3}#\s" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained
78syn region markdownH2 matchgroup=markdownH2Delimiter start=" \{,3}##\s" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained
79syn region markdownH3 matchgroup=markdownH3Delimiter start=" \{,3}###\s" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained
80syn region markdownH4 matchgroup=markdownH4Delimiter start=" \{,3}####\s" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained
81syn region markdownH5 matchgroup=markdownH5Delimiter start=" \{,3}#####\s" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained
82syn region markdownH6 matchgroup=markdownH6Delimiter start=" \{,3}######\s" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained
Bram Moolenaar7a329912010-05-21 12:05:36 +020083
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020084syn match markdownBlockquote ">\%(\s\|$\)" contained nextgroup=@markdownBlock
Bram Moolenaar7a329912010-05-21 12:05:36 +020085
Bram Moolenaar3c053a12022-10-16 13:11:12 +010086syn region markdownCodeBlock start="^\n\( \{4,}\|\t\)" end="^\ze \{,3}\S.*$" keepend
Bram Moolenaar7a329912010-05-21 12:05:36 +020087
88" TODO: real nesting
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020089syn match markdownListMarker "\%(\t\| \{0,4\}\)[-*+]\%(\s\+\S\)\@=" contained
90syn match markdownOrderedListMarker "\%(\t\| \{0,4}\)\<\d\+\.\%(\s\+\S\)\@=" contained
Bram Moolenaar7a329912010-05-21 12:05:36 +020091
92syn match markdownRule "\* *\* *\*[ *]*$" contained
93syn match markdownRule "- *- *-[ -]*$" contained
94
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020095syn match markdownLineBreak " \{2,\}$"
Bram Moolenaar7a329912010-05-21 12:05:36 +020096
97syn region markdownIdDeclaration matchgroup=markdownLinkDelimiter start="^ \{0,3\}!\=\[" end="\]:" oneline keepend nextgroup=markdownUrl skipwhite
98syn match markdownUrl "\S\+" nextgroup=markdownUrlTitle skipwhite contained
99syn region markdownUrl matchgroup=markdownUrlDelimiter start="<" end=">" oneline keepend nextgroup=markdownUrlTitle skipwhite contained
100syn region markdownUrlTitle matchgroup=markdownUrlTitleDelimiter start=+"+ end=+"+ keepend contained
101syn region markdownUrlTitle matchgroup=markdownUrlTitleDelimiter start=+'+ end=+'+ keepend contained
102syn region markdownUrlTitle matchgroup=markdownUrlTitleDelimiter start=+(+ end=+)+ keepend contained
103
Bram Moolenaar3c053a12022-10-16 13:11:12 +0100104syn region markdownLinkText matchgroup=markdownLinkTextDelimiter start="!\=\[\%(\_[^][]*\%(\[\_[^][]*\]\_[^][]*\)*]\%( \=[[(]\)\)\@=" end="\]\%( \=[[(]\)\@=" nextgroup=markdownLink,markdownId skipwhite contains=@markdownInline,markdownLineStart
Bram Moolenaar7a329912010-05-21 12:05:36 +0200105syn region markdownLink matchgroup=markdownLinkDelimiter start="(" end=")" contains=markdownUrl keepend contained
106syn region markdownId matchgroup=markdownIdDelimiter start="\[" end="\]" keepend contained
107syn region markdownAutomaticLink matchgroup=markdownUrlDelimiter start="<\%(\w\+:\|[[:alnum:]_+-]\+@\)\@=" end=">" keepend oneline
108
Bram Moolenaarc08ee742019-12-05 22:47:25 +0100109let s:concealends = ''
110if has('conceal') && get(g:, 'markdown_syntax_conceal', 1) == 1
111 let s:concealends = ' concealends'
112endif
Bram Moolenaar3c053a12022-10-16 13:11:12 +0100113exe 'syn region markdownItalic matchgroup=markdownItalicDelimiter start="\*\S\@=" end="\S\@<=\*\|^$" skip="\\\*" contains=markdownLineStart,@Spell' . s:concealends
114exe 'syn region markdownItalic matchgroup=markdownItalicDelimiter start="\w\@<!_\S\@=" end="\S\@<=_\w\@!\|^$" skip="\\_" contains=markdownLineStart,@Spell' . s:concealends
115exe 'syn region markdownBold matchgroup=markdownBoldDelimiter start="\*\*\S\@=" end="\S\@<=\*\*\|^$" skip="\\\*" contains=markdownLineStart,markdownItalic,@Spell' . s:concealends
116exe 'syn region markdownBold matchgroup=markdownBoldDelimiter start="\w\@<!__\S\@=" end="\S\@<=__\w\@!\|^$" skip="\\_" contains=markdownLineStart,markdownItalic,@Spell' . s:concealends
117exe 'syn region markdownBoldItalic matchgroup=markdownBoldItalicDelimiter start="\*\*\*\S\@=" end="\S\@<=\*\*\*\|^$" skip="\\\*" contains=markdownLineStart,@Spell' . s:concealends
118exe 'syn region markdownBoldItalic matchgroup=markdownBoldItalicDelimiter start="\w\@<!___\S\@=" end="\S\@<=___\w\@!\|^$" skip="\\_" contains=markdownLineStart,@Spell' . s:concealends
119exe 'syn region markdownStrike matchgroup=markdownStrikeDelimiter start="\~\~\S\@=" end="\S\@<=\~\~\|^$" contains=markdownLineStart,@Spell' . s:concealends
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200120
Bram Moolenaar543b7ef2013-06-01 14:50:56 +0200121syn region markdownCode matchgroup=markdownCodeDelimiter start="`" end="`" keepend contains=markdownLineStart
Bram Moolenaar7a329912010-05-21 12:05:36 +0200122syn region markdownCode matchgroup=markdownCodeDelimiter start="`` \=" end=" \=``" keepend contains=markdownLineStart
Bram Moolenaar3c053a12022-10-16 13:11:12 +0100123syn region markdownCodeBlock matchgroup=markdownCodeDelimiter start="^\s*\z(`\{3,\}\).*$" end="^\s*\z1\ze\s*$" keepend
124syn region markdownCodeBlock matchgroup=markdownCodeDelimiter start="^\s*\z(\~\{3,\}\).*$" end="^\s*\z1\ze\s*$" keepend
Bram Moolenaar543b7ef2013-06-01 14:50:56 +0200125
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200126syn match markdownFootnote "\[^[^\]]\+\]"
127syn match markdownFootnoteDefinition "^\[^[^\]]\+\]:"
128
Bram Moolenaar3c053a12022-10-16 13:11:12 +0100129let s:done_include = {}
130for s:type in g:markdown_fenced_languages
131 if has_key(s:done_include, matchstr(s:type,'[^.]*'))
132 continue
133 endif
134 exe 'syn region markdownHighlight_'.substitute(matchstr(s:type,'[^=]*$'),'\..*','','').' matchgroup=markdownCodeDelimiter start="^\s*\z(`\{3,\}\)\s*\%({.\{-}\.\)\='.matchstr(s:type,'[^=]*').'}\=\S\@!.*$" end="^\s*\z1\ze\s*$" keepend contains=@markdownHighlight_'.tr(matchstr(s:type,'[^=]*$'),'.','_') . s:concealends
135 exe 'syn region markdownHighlight_'.substitute(matchstr(s:type,'[^=]*$'),'\..*','','').' matchgroup=markdownCodeDelimiter start="^\s*\z(\~\{3,\}\)\s*\%({.\{-}\.\)\='.matchstr(s:type,'[^=]*').'}\=\S\@!.*$" end="^\s*\z1\ze\s*$" keepend contains=@markdownHighlight_'.tr(matchstr(s:type,'[^=]*$'),'.','_') . s:concealends
136 let s:done_include[matchstr(s:type,'[^.]*')] = 1
137endfor
138unlet! s:type
139unlet! s:done_include
140
141if get(b:, 'markdown_yaml_head', get(g:, 'markdown_yaml_head', main_syntax ==# 'markdown'))
142 syn include @markdownYamlTop syntax/yaml.vim
143 unlet! b:current_syntax
144 syn region markdownYamlHead start="\%^---$" end="^\%(---\|\.\.\.\)\s*$" keepend contains=@markdownYamlTop,@Spell
Bram Moolenaar543b7ef2013-06-01 14:50:56 +0200145endif
Bram Moolenaar7a329912010-05-21 12:05:36 +0200146
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200147syn match markdownEscape "\\[][\\`*_{}()<>#+.!-]"
Bram Moolenaar543b7ef2013-06-01 14:50:56 +0200148syn match markdownError "\w\@<=_\w\@="
Bram Moolenaar7a329912010-05-21 12:05:36 +0200149
150hi def link markdownH1 htmlH1
151hi def link markdownH2 htmlH2
152hi def link markdownH3 htmlH3
153hi def link markdownH4 htmlH4
154hi def link markdownH5 htmlH5
155hi def link markdownH6 htmlH6
156hi def link markdownHeadingRule markdownRule
Bram Moolenaarc08ee742019-12-05 22:47:25 +0100157hi def link markdownH1Delimiter markdownHeadingDelimiter
158hi def link markdownH2Delimiter markdownHeadingDelimiter
159hi def link markdownH3Delimiter markdownHeadingDelimiter
160hi def link markdownH4Delimiter markdownHeadingDelimiter
161hi def link markdownH5Delimiter markdownHeadingDelimiter
162hi def link markdownH6Delimiter markdownHeadingDelimiter
Bram Moolenaar7a329912010-05-21 12:05:36 +0200163hi def link markdownHeadingDelimiter Delimiter
164hi def link markdownOrderedListMarker markdownListMarker
165hi def link markdownListMarker htmlTagName
166hi def link markdownBlockquote Comment
167hi def link markdownRule PreProc
168
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200169hi def link markdownFootnote Typedef
170hi def link markdownFootnoteDefinition Typedef
171
Bram Moolenaar7a329912010-05-21 12:05:36 +0200172hi def link markdownLinkText htmlLink
173hi def link markdownIdDeclaration Typedef
174hi def link markdownId Type
175hi def link markdownAutomaticLink markdownUrl
176hi def link markdownUrl Float
177hi def link markdownUrlTitle String
178hi def link markdownIdDelimiter markdownLinkDelimiter
179hi def link markdownUrlDelimiter htmlTag
180hi def link markdownUrlTitleDelimiter Delimiter
181
182hi def link markdownItalic htmlItalic
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200183hi def link markdownItalicDelimiter markdownItalic
Bram Moolenaar7a329912010-05-21 12:05:36 +0200184hi def link markdownBold htmlBold
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200185hi def link markdownBoldDelimiter markdownBold
Bram Moolenaar7a329912010-05-21 12:05:36 +0200186hi def link markdownBoldItalic htmlBoldItalic
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200187hi def link markdownBoldItalicDelimiter markdownBoldItalic
Bram Moolenaar3c053a12022-10-16 13:11:12 +0100188hi def link markdownStrike htmlStrike
189hi def link markdownStrikeDelimiter markdownStrike
Bram Moolenaar7a329912010-05-21 12:05:36 +0200190hi def link markdownCodeDelimiter Delimiter
191
192hi def link markdownEscape Special
Bram Moolenaar543b7ef2013-06-01 14:50:56 +0200193hi def link markdownError Error
Bram Moolenaar7a329912010-05-21 12:05:36 +0200194
195let b:current_syntax = "markdown"
Bram Moolenaar543b7ef2013-06-01 14:50:56 +0200196if main_syntax ==# 'markdown'
197 unlet main_syntax
198endif
Bram Moolenaar7a329912010-05-21 12:05:36 +0200199
200" vim:set sw=2: