vim-restructuredtext icon indicating copy to clipboard operation
vim-restructuredtext copied to clipboard

backquotes in inline literals

Open anntzer opened this issue 8 years ago • 1 comments

This may be a bit tricky (and definitely an edge case) but

```foo```, ````foo````

get rendered by docutils as

`foo` and ``foo``

i.e. the inner backquotes do not count as delimiters, but vim-rst does not highlight the construct correctly. Looking at the spec (http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#inline-markup-recognition-rules), the start side is escaped because

The inline markup end-string must be separated by at least one character from the start-string.

and the stop side is escaped because

Inline markup end-strings must end a text block or be immediately followed by whitespace, etc

anntzer avatar Oct 07 '17 23:10 anntzer

Something like

diff --git i/syntax/rst.vim w/syntax/rst.vim
index a0e2806..9cd38ca 100644
--- i/syntax/rst.vim
+++ w/syntax/rst.vim
@@ -88,44 +88,31 @@ execute 'syn region rstExDirective contained matchgroup=rstDirective' .
 execute 'syn match rstSubstitutionDefinition contained' .
       \ ' /|.*|\_s\+/ nextgroup=@rstDirectives'
 
-function! s:DefineOneInlineMarkup(name, start, middle, end, char_left, char_right)
-  execute 'syn region rst' . a:name .
-        \ ' start=+' . a:char_left . '\zs' . a:start .
-        \ '\ze[^[:space:]' . a:char_right . a:start[strlen(a:start) - 1] . ']+' .
-        \ a:middle .
-        \ ' end=+\S' . a:end . '\ze\%($\|\s\|[''"’)\]}>/:.,;!?\\-]\)+'
+function! s:DefineInlineMarkup(name, start, end)
+  " See http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#inline-markup-recognition-rules
+  " a:start must be preceded by an atom listed in item #6.
+  " between a:start and a:end, capture nongreedily; don't allow empty lines.
+  " a:end must be followed by an atom listed in item #7.
+  exe 'syn match rst' . a:name . ' &\v' .
+        \ '(^|\s|[-:/''"<([{’])\zs' . a:start . '\S@=' .
+        \ '(.|\n[^\n]){-}' .
+        \ '\\@1<!\S@<=' . a:end . '\ze($|\s|[\-.,:;!?\\/''")\\\]}>])&'
+  " '*', "*", ... are explicitly not recognized (item #5).
+  exe "syn match rstNormal &\v'" . a:start . "'&"
+  exe 'syn match rstNormal &\v"' . a:start . '"&'
+  exe 'syn match rstNormal &\v\(' . a:start . '\)&'
+  exe 'syn match rstNormal &\v\[' . a:start . '\]&'
+  exe 'syn match rstNormal &\v\{' . a:start . '\}&'
+  exe 'syn match rstNormal &\v\<' . a:start . '\>&'
+  exe 'syn match rstNormal &\v\<' . a:start . '\>&'
 endfunction
 
-function! s:DefineInlineMarkup(name, start, middle, end)
-  let middle = a:middle != "" ?
-        \ (' skip=+\\\\\|\\' . a:middle . '+') :
-        \ ""
-
-  call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, "'", "'")
-  call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '"', '"')
-  call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '(', ')')
-  call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '\[', '\]')
-  call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '{', '}')
-  call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '<', '>')
-  call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '’', '’')
-  " TODO: Additional Unicode Pd, Po, Pi, Pf, Ps characters
-
-  call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '\%(^\|\s\|\%ua0\|[/:]\)', '')
-
-  execute 'syn match rst' . a:name .
-        \ ' +\%(^\|\s\|\%ua0\|[''"([{</:]\)\zs' . a:start .
-        \ '[^[:space:]' . a:start[strlen(a:start) - 1] . ']'
-        \ a:end . '\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)+'
-
-  execute 'hi def link rst' . a:name . 'Delimiter' . ' rst' . a:name
-endfunction
-
-call s:DefineInlineMarkup('Emphasis', '\*', '\*', '\*')
-call s:DefineInlineMarkup('StrongEmphasis', '\*\*', '\*', '\*\*')
-call s:DefineInlineMarkup('InterpretedTextOrHyperlinkReference', '`', '`', '`_\{0,2}')
-call s:DefineInlineMarkup('InlineLiteral', '``', "", '``')
-call s:DefineInlineMarkup('SubstitutionReference', '|', '|', '|_\{0,2}')
-call s:DefineInlineMarkup('InlineInternalTargets', '_`', '`', '`')
+call s:DefineInlineMarkup('Emphasis', '\*', '\*')
+call s:DefineInlineMarkup('StrongEmphasis', '\*\*', '\*\*')
+call s:DefineInlineMarkup('InterpretedTextOrHyperlinkReference', '`', '`_{0,2}')
+call s:DefineInlineMarkup('InlineLiteral', '``', '``')
+call s:DefineInlineMarkup('SubstitutionReference', '\|', '\|_{0,2}')
+call s:DefineInlineMarkup('InlineInternalTargets', '_`', '`')
 
 " Sections are identified through their titles, which are marked up with
 " adornment: "underlines" below the title text, or underlines and matching
@@ -236,6 +223,7 @@ syntax spell toplevel
 " TODO: Use better syncing.
 syn sync minlines=50 linebreaks=2
 
+hi def link rstNormal                       Normal
 hi def link rstTodo                         Todo
 hi def link rstComment                      Comment
 hi def link rstSections                     Title

fixes the issue above.

anntzer avatar Sep 08 '18 14:09 anntzer