Skip to content

Real nesting and MathJax highlighting #118

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 74 additions & 35 deletions syntax/markdown.vim
Original file line number Diff line number Diff line change
Expand Up @@ -30,40 +30,72 @@ unlet! s:type
syn sync minlines=10
syn case ignore

syn match markdownValid '[<>]\c[a-z/$!]\@!'
syn match markdownValid '&\%(#\=\w*;\)\@!'
syn match markdown "^" nextgroup=@markdownBlockL0
syn cluster markdownInline contains=markdownLineBreak,markdownLinkText,markdownItalic,markdownBold,markdownCode,markdownEscape,@htmlTop,markdownError,markdownHighlighttex,markdownAutomaticLink

syn match markdownLineStart "^[<@]\@!" nextgroup=@markdownBlock,htmlSpecialChar
syn match markdownLineBreak " \{2,}$"

syn cluster markdownBlock contains=markdownH1,markdownH2,markdownH3,markdownH4,markdownH5,markdownH6,markdownBlockquote,markdownListMarker,markdownOrderedListMarker,markdownCodeBlock,markdownRule
syn cluster markdownInline contains=markdownLineBreak,markdownLinkText,markdownItalic,markdownBold,markdownCode,markdownEscape,@htmlTop,markdownError

syn match markdownH1 "^.\+\n=\+$" contained contains=@markdownInline,markdownHeadingRule,markdownAutomaticLink
syn match markdownH2 "^.\+\n-\+$" contained contains=@markdownInline,markdownHeadingRule,markdownAutomaticLink
if !exists('g:markdown_list_nesting_depth')
let g:markdown_list_nesting_depth = 2
endif
let s:nesting = g:markdown_list_nesting_depth
while s:nesting >= 0
let s:indent_num = s:nesting * &tabstop
let s:indent_pat = ' \{' . s:indent_num . ',' . (s:indent_num + &tabstop - 1) . '}'
if s:nesting == 0
exe 'syn cluster markdownBlockL' . s:nesting . ' contains=markdownList,markdownParagraphL' . s:nesting . ',markdownRuleL' . s:nesting . ',markdownBlockquoteL' . s:nesting . ',markdownCodeBlockL' . s:nesting . ',@markdownHeadingL' . s:nesting
else
exe 'syn cluster markdownBlockL' . s:nesting . ' contains=markdownListItemBlockL' . s:nesting . ',markdownParagraphL' . s:nesting . ',markdownRuleL' . s:nesting . ',markdownBlockquoteL' . s:nesting . ',markdownCodeBlockL' . s:nesting . ',@markdownHeadingL' . s:nesting
endif

syn match markdownHeadingRule "^[=-]\+$" contained
exe 'syn region markdownParagraphL' . s:nesting . ' start="^' . s:indent_pat . '\%(#.\+\)\@!\S" end="^\s*$\|\%(\n' . s:indent_pat . '\%(#.\+\|>\s*\)\)\@=" keepend contains=@markdownInline contained'

syn region markdownH1 matchgroup=markdownHeadingDelimiter start="##\@!" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained
syn region markdownH2 matchgroup=markdownHeadingDelimiter start="###\@!" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained
syn region markdownH3 matchgroup=markdownHeadingDelimiter start="####\@!" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained
syn region markdownH4 matchgroup=markdownHeadingDelimiter start="#####\@!" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained
syn region markdownH5 matchgroup=markdownHeadingDelimiter start="######\@!" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained
syn region markdownH6 matchgroup=markdownHeadingDelimiter start="#######\@!" end="#*\s*$" keepend oneline contains=@markdownInline,markdownAutomaticLink contained
exe 'syn match markdownRuleL' . s:nesting . ' "' . s:indent_pat . '\* *\* *\*[ *]*$" contained'
exe 'syn match markdownRuleL' . s:nesting . ' "' . s:indent_pat . '- *- *-[ -]*$" contained'

syn match markdownBlockquote ">\%(\s\|$\)" contained nextgroup=@markdownBlock
exe 'syn region markdownBlockquoteL' . s:nesting . ' matchgroup=markdownBlockquoteDelimiter start="' . s:indent_pat . '>\%(\s\|$\)" end="$" contains=@markdownInline contained'

syn region markdownCodeBlock start=" \|\t" end="$" contained
exe 'syn region markdownCodeBlockL' . s:nesting . ' start=" \{' . (s:indent_num + &tabstop) . '}" end="$" contained'

" TODO: real nesting
syn match markdownListMarker "\%(\t\| \{0,4\}\)[-*+]\%(\s\+\S\)\@=" contained
syn match markdownOrderedListMarker "\%(\t\| \{0,4}\)\<\d\+\.\%(\s\+\S\)\@=" contained
exe 'syn cluster markdownHeadingL' . s:nesting . ' contains=markdownH1L' . s:nesting . ',markdownH2L' . s:nesting . ',markdownH3L' . s:nesting . ',markdownH4L' . s:nesting . ',markdownH5L' . s:nesting . ',markdownH6L' . s:nesting
exe 'syn match markdownH1L' . s:nesting . ' "\%(\%(^\s*\n\)\@<=\|\%^\) \{' . s:indent_num . '}\s*\S.*\n \{' . s:indent_num . '}=\+\s*$" contains=@markdownInline,markdownHeadingRuleL' . s:nesting . ' contained'
exe 'syn match markdownH2L' . s:nesting . ' "\%(\%(^\s*\n\)\@<=\|\%^\) \{' . s:indent_num . '}\s*\S.*\n \{' . s:indent_num . '}-\+\s*$" contains=@markdownInline,markdownHeadingRuleL' . s:nesting . ' contained'
exe 'syn match markdownHeadingRuleL' . s:nesting . ' "^ \{' . s:indent_num . '}[=-]\+\s*$" contained'
exe 'syn region markdownH1L' . s:nesting . ' matchgroup=markdownHeadingDelimiter start="^ \{' . s:indent_num . '}##\@!" end="$" keepend oneline contains=@markdownInline contained'
exe 'syn region markdownH2L' . s:nesting . ' matchgroup=markdownHeadingDelimiter start="^ \{' . s:indent_num . '}###\@!" end="$" keepend oneline contains=@markdownInline contained'
exe 'syn region markdownH3L' . s:nesting . ' matchgroup=markdownHeadingDelimiter start="^ \{' . s:indent_num . '}####\@!" end="$" keepend oneline contains=@markdownInline contained'
exe 'syn region markdownH4L' . s:nesting . ' matchgroup=markdownHeadingDelimiter start="^ \{' . s:indent_num . '}#####\@!" end="$" keepend oneline contains=@markdownInline contained'
exe 'syn region markdownH5L' . s:nesting . ' matchgroup=markdownHeadingDelimiter start="^ \{' . s:indent_num . '}######\@!" end="$" keepend oneline contains=@markdownInline contained'
exe 'syn region markdownH6L' . s:nesting . ' matchgroup=markdownHeadingDelimiter start="^ \{' . s:indent_num . '}#######\@!" end="$" keepend oneline contains=@markdownInline contained'

syn match markdownRule "\* *\* *\*[ *]*$" contained
syn match markdownRule "- *- *-[ -]*$" contained
if s:nesting == 0
exe 'syn region markdownList start="\%(\%(^\s*\n\)\@<=\|\%^\)' . s:indent_pat . '\%([*+-]\|\d\+\.\)\s\+\S" end="^\s*\%(\n' . s:indent_pat . '\S\)\@=\n" contained keepend contains=markdownListItemBlockL' . s:nesting
endif

syn match markdownLineBreak " \{2,\}$"
exe 'syn region markdownListItemBlockL' . s:nesting . ' start="^' . s:indent_pat . '\%([*+-]\|\d\+\.\)\s\+\S" end="\n\%(' . s:indent_pat . '\%([*+-]\|\d\+\.\)\s\+\S\)\@=\|^\s*\%(\n' . s:indent_pat . '\S\)\@=\n" contained keepend contains=markdownListItemL' . s:nesting . ',markdownListMarkerL' . s:nesting . ',@markdownBlockL' . (s:nesting + 1)
exe 'syn match markdownListMarkerL' . s:nesting . ' "\%(^' . s:indent_pat . '\)\@<=\%([*+-]\|\d\+\.\)\%(\s\+\S\)\@=" contained'
exe 'syn match markdownListItemL' . s:nesting . ' "\%(^' . s:indent_pat . '\%([*+-]\|\d\+\.\)\s\+\)\@<=\S.*\%(\n\%( *\%([*+-]\|\d\+\.\)\s\+\S\)\@!\s*\S.*\)*$" contained keepend contains=@markdownInline'

exe 'hi def link markdownBlockL' . s:nesting . ' markdownBlock'
exe 'hi def link markdownParagraphL' . s:nesting . ' markdownParagraph'
exe 'hi def link markdownRuleL' . s:nesting . ' markdownRule'
exe 'hi def link markdownBlockquoteL' . s:nesting . ' markdownBlockquote'
exe 'hi def link markdownCodeBlockL' . s:nesting . ' markdownCodeBlock'
exe 'hi def link markdownHeadingL' . s:nesting . ' markdownHeading'
exe 'hi def link markdownHeadingRuleL' . s:nesting . ' markdownHeadingRule'
exe 'hi def link markdownH1L' . s:nesting . ' markdownH1'
exe 'hi def link markdownH2L' . s:nesting . ' markdownH2'
exe 'hi def link markdownH3L' . s:nesting . ' markdownH3'
exe 'hi def link markdownH4L' . s:nesting . ' markdownH4'
exe 'hi def link markdownH5L' . s:nesting . ' markdownH5'
exe 'hi def link markdownH6L' . s:nesting . ' markdownH6'
exe 'hi def link markdownListItemBlockL' . s:nesting . ' markdownListItemBlock'
exe 'hi def link markdownListMarkerL' . s:nesting . ' markdownListMarker'
exe 'hi def link markdownListItemL' . s:nesting . ' markdownListItem'

let s:nesting -= 1
endwhile

syn region markdownIdDeclaration matchgroup=markdownLinkDelimiter start="^ \{0,3\}!\=\[" end="\]:" oneline keepend nextgroup=markdownUrl skipwhite
syn match markdownUrl "\S\+" nextgroup=markdownUrlTitle skipwhite contained
syn region markdownUrl matchgroup=markdownUrlDelimiter start="<" end=">" oneline keepend nextgroup=markdownUrlTitle skipwhite contained
syn region markdownUrlTitle matchgroup=markdownUrlTitleDelimiter start=+"+ end=+"+ keepend contained
Expand All @@ -73,15 +105,14 @@ syn region markdownUrlTitle matchgroup=markdownUrlTitleDelimiter start=+(+ end=+
syn region markdownLinkText matchgroup=markdownLinkTextDelimiter start="!\=\[\%(\_[^]]*]\%( \=[[(]\)\)\@=" end="\]\%( \=[[(]\)\@=" nextgroup=markdownLink,markdownId skipwhite contains=@markdownInline,markdownLineStart
syn region markdownLink matchgroup=markdownLinkDelimiter start="(" end=")" contains=markdownUrl keepend contained
syn region markdownId matchgroup=markdownIdDelimiter start="\[" end="\]" keepend contained
syn region markdownAutomaticLink matchgroup=markdownUrlDelimiter start="<\%(\w\+:\|[[:alnum:]_+-]\+@\)\@=" end=">" keepend oneline
syn region markdownAutomaticLink matchgroup=markdownUrlDelimiter start="<\%(\w\+:\|[[:alnum:]_+-]\+@\)\@=" end=">" keepend oneline contained

let s:concealends = has('conceal') ? ' concealends' : ''
exe 'syn region markdownItalic matchgroup=markdownItalicDelimiter start="\S\@<=\*\|\*\S\@=" end="\S\@<=\*\|\*\S\@=" keepend contains=markdownLineStart' . s:concealends
exe 'syn region markdownItalic matchgroup=markdownItalicDelimiter start="\S\@<=_\|_\S\@=" end="\S\@<=_\|_\S\@=" keepend contains=markdownLineStart' . s:concealends
exe 'syn region markdownBold matchgroup=markdownBoldDelimiter start="\S\@<=\*\*\|\*\*\S\@=" end="\S\@<=\*\*\|\*\*\S\@=" keepend contains=markdownLineStart,markdownItalic' . s:concealends
exe 'syn region markdownBold matchgroup=markdownBoldDelimiter start="\S\@<=__\|__\S\@=" end="\S\@<=__\|__\S\@=" keepend contains=markdownLineStart,markdownItalic' . s:concealends
exe 'syn region markdownBoldItalic matchgroup=markdownBoldItalicDelimiter start="\S\@<=\*\*\*\|\*\*\*\S\@=" end="\S\@<=\*\*\*\|\*\*\*\S\@=" keepend contains=markdownLineStart' . s:concealends
exe 'syn region markdownBoldItalic matchgroup=markdownBoldItalicDelimiter start="\S\@<=___\|___\S\@=" end="\S\@<=___\|___\S\@=" keepend contains=markdownLineStart' . s:concealends
syn region markdownItalic matchgroup=markdownItalicDelimiter start="\S\@<=\*\|\*\S\@=" end="\S\@<=\*\|\*\S\@=" keepend contained contains=markdownLineStart
syn region markdownItalic matchgroup=markdownItalicDelimiter start="\S\@<=_\|_\S\@=" end="\S\@<=_\|_\S\@=" keepend contained contains=markdownLineStart
syn region markdownBold matchgroup=markdownBoldDelimiter start="\S\@<=\*\*\|\*\*\S\@=" end="\S\@<=\*\*\|\*\*\S\@=" keepend contained contains=markdownLineStart,markdownItalic
syn region markdownBold matchgroup=markdownBoldDelimiter start="\S\@<=__\|__\S\@=" end="\S\@<=__\|__\S\@=" keepend contained contains=markdownLineStart,markdownItalic
syn region markdownBoldItalic matchgroup=markdownBoldItalicDelimiter start="\S\@<=\*\*\*\|\*\*\*\S\@=" end="\S\@<=\*\*\*\|\*\*\*\S\@=" keepend contained contains=markdownLineStart
syn region markdownBoldItalic matchgroup=markdownBoldItalicDelimiter start="\S\@<=___\|___\S\@=" end="\S\@<=___\|___\S\@=" keepend contained contains=markdownLineStart

syn region markdownCode matchgroup=markdownCodeDelimiter start="`" end="`" keepend contains=markdownLineStart
syn region markdownCode matchgroup=markdownCodeDelimiter start="`` \=" end=" \=``" keepend contains=markdownLineStart
Expand All @@ -100,6 +131,13 @@ endif
syn match markdownEscape "\\[][\\`*_{}()#+.!-]"
syn match markdownError "\w\@<=_\w\@="

let g:tex_no_error=1
syn include syntax/tex.vim
syn region markdownHighlighttex matchgroup=markdownCodeDelimiter start="\\\\(\ze[^ \n]" end="[^ \n]\zs\\\\)" keepend contains=@texMathZoneGroup
syn region markdownHighlighttex matchgroup=markdownCodeDelimiter start="\\\\\[" end="\\\\\]" keepend contains=@texMathZoneGroup
syn region markdownHighlighttex matchgroup=markdownCodeDelimiter start="\$\ze[^ \n]" end="[^ \n]\zs\$" keepend contains=@texMathZoneGroup
syn region markdownHighlighttex matchgroup=markdownCodeDelimiter start="\$\$" end="\$\$" keepend contains=@texMathZoneGroup

hi def link markdownH1 htmlH1
hi def link markdownH2 htmlH2
hi def link markdownH3 htmlH3
Expand All @@ -108,9 +146,10 @@ hi def link markdownH5 htmlH5
hi def link markdownH6 htmlH6
hi def link markdownHeadingRule markdownRule
hi def link markdownHeadingDelimiter Delimiter
hi def link markdownOrderedListMarker markdownListMarker
hi def link markdownListMarker htmlTagName
hi def link markdownBlockquote Comment
hi def link markdownListMarkerL1 htmlTagName
hi def link markdownListMarkerL2 htmlTagName
hi def link markdownBlockquoteDelimiter Comment
hi link markdownBlockquote Normal
hi def link markdownRule PreProc

hi def link markdownFootnote Typedef
Expand Down