markdown.vim 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. " Vim syntax file
  2. " Language: Markdown
  3. " Maintainer: Ben Williams <benw@plasticboy.com>
  4. " URL: http://plasticboy.com/markdown-vim-mode/
  5. " Remark: Uses HTML syntax file
  6. " TODO: Handle stuff contained within stuff (e.g. headings within blockquotes)
  7. " Read the HTML syntax to start with
  8. if version < 600
  9. so <sfile>:p:h/html.vim
  10. else
  11. runtime! syntax/html.vim
  12. if exists('b:current_syntax')
  13. unlet b:current_syntax
  14. endif
  15. endif
  16. if version < 600
  17. syntax clear
  18. elseif exists("b:current_syntax")
  19. finish
  20. endif
  21. " don't use standard HiLink, it will not work with included syntax files
  22. if version < 508
  23. command! -nargs=+ HtmlHiLink hi link <args>
  24. else
  25. command! -nargs=+ HtmlHiLink hi def link <args>
  26. endif
  27. syn spell toplevel
  28. syn case ignore
  29. syn sync linebreaks=1
  30. let s:conceal = ''
  31. let s:concealends = ''
  32. let s:concealcode = ''
  33. if has('conceal') && get(g:, 'vim_markdown_conceal', 1)
  34. let s:conceal = ' conceal'
  35. let s:concealends = ' concealends'
  36. endif
  37. if has('conceal') && get(g:, 'vim_markdown_conceal_code_blocks', 1)
  38. let s:concealcode = ' concealends'
  39. endif
  40. " additions to HTML groups
  41. if get(g:, 'vim_markdown_emphasis_multiline', 1)
  42. let s:oneline = ''
  43. else
  44. let s:oneline = ' oneline'
  45. endif
  46. syn region mkdItalic matchgroup=mkdItalic start="\%(\*\|_\)" end="\%(\*\|_\)"
  47. syn region mkdBold matchgroup=mkdBold start="\%(\*\*\|__\)" end="\%(\*\*\|__\)"
  48. syn region mkdBoldItalic matchgroup=mkdBoldItalic start="\%(\*\*\*\|___\)" end="\%(\*\*\*\|___\)"
  49. execute 'syn region htmlItalic matchgroup=mkdItalic start="\%(^\|\s\)\zs\*\ze[^\\\*\t ]\%(\%([^*]\|\\\*\|\n\)*[^\\\*\t ]\)\?\*\_W" end="[^\\\*\t ]\zs\*\ze\_W" keepend contains=@Spell' . s:oneline . s:concealends
  50. execute 'syn region htmlItalic matchgroup=mkdItalic start="\%(^\|\s\)\zs_\ze[^\\_\t ]" end="[^\\_\t ]\zs_\ze\_W" keepend contains=@Spell' . s:oneline . s:concealends
  51. execute 'syn region htmlBold matchgroup=mkdBold start="\%(^\|\s\)\zs\*\*\ze\S" end="\S\zs\*\*" keepend contains=@Spell' . s:oneline . s:concealends
  52. execute 'syn region htmlBold matchgroup=mkdBold start="\%(^\|\s\)\zs__\ze\S" end="\S\zs__" keepend contains=@Spell' . s:oneline . s:concealends
  53. execute 'syn region htmlBoldItalic matchgroup=mkdBoldItalic start="\%(^\|\s\)\zs\*\*\*\ze\S" end="\S\zs\*\*\*" keepend contains=@Spell' . s:oneline . s:concealends
  54. execute 'syn region htmlBoldItalic matchgroup=mkdBoldItalic start="\%(^\|\s\)\zs___\ze\S" end="\S\zs___" keepend contains=@Spell' . s:oneline . s:concealends
  55. " [link](URL) | [link][id] | [link][] | ![image](URL)
  56. syn region mkdFootnotes matchgroup=mkdDelimiter start="\[^" end="\]"
  57. execute 'syn region mkdID matchgroup=mkdDelimiter start="\[" end="\]" contained oneline' . s:conceal
  58. execute 'syn region mkdURL matchgroup=mkdDelimiter start="(" end=")" contained oneline' . s:conceal
  59. execute 'syn region mkdLink matchgroup=mkdDelimiter start="\\\@<!!\?\[\ze[^]\n]*\n\?[^]\n]*\][[(]" end="\]" contains=@mkdNonListItem,@Spell nextgroup=mkdURL,mkdID skipwhite' . s:concealends
  60. " Autolink without angle brackets.
  61. " mkd inline links: protocol optional user:pass@ sub/domain .com, .co.uk, etc optional port path/querystring/hash fragment
  62. " ------------ _____________________ ----------------------------- _________________________ ----------------- __
  63. syn match mkdInlineURL /https\?:\/\/\(\w\+\(:\w\+\)\?@\)\?\([A-Za-z0-9][-_0-9A-Za-z]*\.\)\{1,}\(\w\{2,}\.\?\)\{1,}\(:[0-9]\{1,5}\)\?\S*/
  64. " Autolink with parenthesis.
  65. syn region mkdInlineURL matchgroup=mkdDelimiter start="(\(https\?:\/\/\(\w\+\(:\w\+\)\?@\)\?\([A-Za-z0-9][-_0-9A-Za-z]*\.\)\{1,}\(\w\{2,}\.\?\)\{1,}\(:[0-9]\{1,5}\)\?\S*)\)\@=" end=")"
  66. " Autolink with angle brackets.
  67. syn region mkdInlineURL matchgroup=mkdDelimiter start="\\\@<!<\ze[a-z][a-z0-9,.-]\{1,22}:\/\/[^> ]*>" end=">"
  68. " Link definitions: [id]: URL (Optional Title)
  69. syn region mkdLinkDef matchgroup=mkdDelimiter start="^ \{,3}\zs\[\^\@!" end="]:" oneline nextgroup=mkdLinkDefTarget skipwhite
  70. syn region mkdLinkDefTarget start="<\?\zs\S" excludenl end="\ze[>[:space:]\n]" contained nextgroup=mkdLinkTitle,mkdLinkDef skipwhite skipnl oneline
  71. syn region mkdLinkTitle matchgroup=mkdDelimiter start=+"+ end=+"+ contained
  72. syn region mkdLinkTitle matchgroup=mkdDelimiter start=+'+ end=+'+ contained
  73. syn region mkdLinkTitle matchgroup=mkdDelimiter start=+(+ end=+)+ contained
  74. "HTML headings
  75. syn region htmlH1 matchgroup=mkdHeading start="^\s*#" end="$" contains=mkdLink,mkdInlineURL,@Spell
  76. syn region htmlH2 matchgroup=mkdHeading start="^\s*##" end="$" contains=mkdLink,mkdInlineURL,@Spell
  77. syn region htmlH3 matchgroup=mkdHeading start="^\s*###" end="$" contains=mkdLink,mkdInlineURL,@Spell
  78. syn region htmlH4 matchgroup=mkdHeading start="^\s*####" end="$" contains=mkdLink,mkdInlineURL,@Spell
  79. syn region htmlH5 matchgroup=mkdHeading start="^\s*#####" end="$" contains=mkdLink,mkdInlineURL,@Spell
  80. syn region htmlH6 matchgroup=mkdHeading start="^\s*######" end="$" contains=mkdLink,mkdInlineURL,@Spell
  81. syn match htmlH1 /^.\+\n=\+$/ contains=mkdLink,mkdInlineURL,@Spell
  82. syn match htmlH2 /^.\+\n-\+$/ contains=mkdLink,mkdInlineURL,@Spell
  83. "define Markdown groups
  84. syn match mkdLineBreak / \+$/
  85. syn region mkdBlockquote start=/^\s*>/ end=/$/ contains=mkdLink,mkdInlineURL,mkdLineBreak,@Spell
  86. execute 'syn region mkdCode matchgroup=mkdCodeDelimiter start=/\(\([^\\]\|^\)\\\)\@<!`/ end=/`/' . s:concealcode
  87. execute 'syn region mkdCode matchgroup=mkdCodeDelimiter start=/\(\([^\\]\|^\)\\\)\@<!``/ skip=/[^`]`[^`]/ end=/``/' . s:concealcode
  88. execute 'syn region mkdCode matchgroup=mkdCodeDelimiter start=/^\s*\z(`\{3,}\)[^`]*$/ end=/^\s*\z1`*\s*$/' . s:concealcode
  89. execute 'syn region mkdCode matchgroup=mkdCodeDelimiter start=/\(\([^\\]\|^\)\\\)\@<!\~\~/ end=/\(\([^\\]\|^\)\\\)\@<!\~\~/' . s:concealcode
  90. execute 'syn region mkdCode matchgroup=mkdCodeDelimiter start=/^\s*\z(\~\{3,}\)\s*[0-9A-Za-z_+-]*\s*$/ end=/^\s*\z1\~*\s*$/' . s:concealcode
  91. execute 'syn region mkdCode matchgroup=mkdCodeDelimiter start="<pre[^>]*\\\@<!>" end="</pre>"' . s:concealcode
  92. execute 'syn region mkdCode matchgroup=mkdCodeDelimiter start="<code[^>]*\\\@<!>" end="</code>"' . s:concealcode
  93. syn region mkdFootnote start="\[^" end="\]"
  94. syn match mkdCode /^\s*\n\(\(\s\{8,}[^ ]\|\t\t\+[^\t]\).*\n\)\+/
  95. syn match mkdCode /\%^\(\(\s\{4,}[^ ]\|\t\+[^\t]\).*\n\)\+/
  96. syn match mkdCode /^\s*\n\(\(\s\{4,}[^ ]\|\t\+[^\t]\).*\n\)\+/ contained
  97. syn match mkdListItem /^\s*\%([-*+]\|\d\+\.\)\ze\s\+/ contained
  98. syn region mkdListItemLine start="^\s*\%([-*+]\|\d\+\.\)\s\+" end="$" oneline contains=@mkdNonListItem,mkdListItem,@Spell
  99. syn region mkdNonListItemBlock start="\(\%^\(\s*\([-*+]\|\d\+\.\)\s\+\)\@!\|\n\(\_^\_$\|\s\{4,}[^ ]\|\t+[^\t]\)\@!\)" end="^\(\s*\([-*+]\|\d\+\.\)\s\+\)\@=" contains=@mkdNonListItem,@Spell
  100. syn match mkdRule /^\s*\*\s\{0,1}\*\s\{0,1}\*\(\*\|\s\)*$/
  101. syn match mkdRule /^\s*-\s\{0,1}-\s\{0,1}-\(-\|\s\)*$/
  102. syn match mkdRule /^\s*_\s\{0,1}_\s\{0,1}_\(_\|\s\)*$/
  103. " YAML frontmatter
  104. if get(g:, 'vim_markdown_frontmatter', 0)
  105. syn include @yamlTop syntax/yaml.vim
  106. syn region Comment matchgroup=mkdDelimiter start="\%^---$" end="^\(---\|\.\.\.\)$" contains=@yamlTop keepend
  107. unlet! b:current_syntax
  108. endif
  109. if get(g:, 'vim_markdown_toml_frontmatter', 0)
  110. try
  111. syn include @tomlTop syntax/toml.vim
  112. syn region Comment matchgroup=mkdDelimiter start="\%^+++$" end="^+++$" transparent contains=@tomlTop keepend
  113. unlet! b:current_syntax
  114. catch /E484/
  115. syn region Comment matchgroup=mkdDelimiter start="\%^+++$" end="^+++$"
  116. endtry
  117. endif
  118. if get(g:, 'vim_markdown_json_frontmatter', 0)
  119. try
  120. syn include @jsonTop syntax/json.vim
  121. syn region Comment matchgroup=mkdDelimiter start="\%^{$" end="^}$" contains=@jsonTop keepend
  122. unlet! b:current_syntax
  123. catch /E484/
  124. syn region Comment matchgroup=mkdDelimiter start="\%^{$" end="^}$"
  125. endtry
  126. endif
  127. if get(g:, 'vim_markdown_math', 0)
  128. syn include @tex syntax/tex.vim
  129. syn region mkdMath start="\\\@<!\$" end="\$" skip="\\\$" contains=@tex keepend
  130. syn region mkdMath start="\\\@<!\$\$" end="\$\$" skip="\\\$" contains=@tex keepend
  131. endif
  132. " Strike through
  133. if get(g:, 'vim_markdown_strikethrough', 0)
  134. execute 'syn region mkdStrike matchgroup=htmlStrike start="\%(\~\~\)" end="\%(\~\~\)"' . s:concealends
  135. HtmlHiLink mkdStrike htmlStrike
  136. endif
  137. syn cluster mkdNonListItem contains=@htmlTop,htmlItalic,htmlBold,htmlBoldItalic,mkdFootnotes,mkdInlineURL,mkdLink,mkdLinkDef,mkdLineBreak,mkdBlockquote,mkdCode,mkdRule,htmlH1,htmlH2,htmlH3,htmlH4,htmlH5,htmlH6,mkdMath,mkdStrike
  138. "highlighting for Markdown groups
  139. HtmlHiLink mkdString String
  140. HtmlHiLink mkdCode String
  141. HtmlHiLink mkdCodeDelimiter String
  142. HtmlHiLink mkdCodeStart String
  143. HtmlHiLink mkdCodeEnd String
  144. HtmlHiLink mkdFootnote Comment
  145. HtmlHiLink mkdBlockquote Comment
  146. HtmlHiLink mkdListItem Identifier
  147. HtmlHiLink mkdRule Identifier
  148. HtmlHiLink mkdLineBreak Visual
  149. HtmlHiLink mkdFootnotes htmlLink
  150. HtmlHiLink mkdLink htmlLink
  151. HtmlHiLink mkdURL htmlString
  152. HtmlHiLink mkdInlineURL htmlLink
  153. HtmlHiLink mkdID Identifier
  154. HtmlHiLink mkdLinkDef mkdID
  155. HtmlHiLink mkdLinkDefTarget mkdURL
  156. HtmlHiLink mkdLinkTitle htmlString
  157. HtmlHiLink mkdDelimiter Delimiter
  158. let b:current_syntax = "mkd"
  159. delcommand HtmlHiLink
  160. " vim: ts=8