Feature: Markdown: Support SetExt Heading (Issue #209)
Like these ========== See: https://spec.commonmark.org/0.29/#setext-headings Note: work for follow_link and VimwikiTOC
This commit is contained in:
parent
40f02293bf
commit
fc056cfeca
@ -727,7 +727,7 @@ function! s:normalize_anchor(anchor, ...) abort
|
|||||||
let anchor = substitute(anchor, punctuation_rx, '', 'g')
|
let anchor = substitute(anchor, punctuation_rx, '', 'g')
|
||||||
|
|
||||||
" 3 Change any space to a hyphen
|
" 3 Change any space to a hyphen
|
||||||
let anchor = substitute(anchor, ' ', '-', 'g')
|
let anchor = substitute(anchor, ' \+', '-', 'g')
|
||||||
|
|
||||||
" 4 Append '-1', '-2', '-3',... to make it unique <= If that not unique
|
" 4 Append '-1', '-2', '-3',... to make it unique <= If that not unique
|
||||||
if has_key(previous_anchors, anchor)
|
if has_key(previous_anchors, anchor)
|
||||||
@ -777,7 +777,7 @@ function! s:unnormalize_anchor(anchor) abort
|
|||||||
for char in split(anchor, '\zs')
|
for char in split(anchor, '\zs')
|
||||||
" 3 Change any space to a hyphen
|
" 3 Change any space to a hyphen
|
||||||
if char ==# '-'
|
if char ==# '-'
|
||||||
let anchor_loop .= '[ \-]'
|
let anchor_loop .= '[ \-]\+'
|
||||||
" 2 Remove anything that is not a letter, number, CJK character, hyphen or space
|
" 2 Remove anything that is not a letter, number, CJK character, hyphen or space
|
||||||
" -- So add puncutation regex at each char
|
" -- So add puncutation regex at each char
|
||||||
else
|
else
|
||||||
@ -816,13 +816,13 @@ function! s:jump_to_anchor(anchor) abort
|
|||||||
|
|
||||||
let anchor_header = s:safesubstitute(
|
let anchor_header = s:safesubstitute(
|
||||||
\ vimwiki#vars#get_syntaxlocal('header_match'),
|
\ vimwiki#vars#get_syntaxlocal('header_match'),
|
||||||
\ '__Header__', segment_re, '')
|
\ '__Header__', segment_re, 'g')
|
||||||
let anchor_bold = s:safesubstitute(
|
let anchor_bold = s:safesubstitute(
|
||||||
\ vimwiki#vars#get_syntaxlocal('bold_match'),
|
\ vimwiki#vars#get_syntaxlocal('bold_match'),
|
||||||
\ '__Text__', segment_re, '')
|
\ '__Text__', segment_re, 'g')
|
||||||
let anchor_tag = s:safesubstitute(
|
let anchor_tag = s:safesubstitute(
|
||||||
\ vimwiki#vars#get_syntaxlocal('tag_match'),
|
\ vimwiki#vars#get_syntaxlocal('tag_match'),
|
||||||
\ '__Tag__', segment_re, '')
|
\ '__Tag__', segment_re, 'g')
|
||||||
|
|
||||||
" Go: Move cursor: maybe more than onces (see markdown suffix)
|
" Go: Move cursor: maybe more than onces (see markdown suffix)
|
||||||
let success_nb = 0
|
let success_nb = 0
|
||||||
@ -840,7 +840,10 @@ function! s:jump_to_anchor(anchor) abort
|
|||||||
if success_nb < segment_nb-1 | let pos += 1 | endif
|
if success_nb < segment_nb-1 | let pos += 1 | endif
|
||||||
call cursor(pos, 1)
|
call cursor(pos, 1)
|
||||||
let success_nb += 1
|
let success_nb += 1
|
||||||
else
|
" Do not move
|
||||||
|
" But maybe suffix -2 is not the segment number but the real header suffix
|
||||||
|
" TODO make this more robust
|
||||||
|
elseif i == 0
|
||||||
" Next segment (default syntax)
|
" Next segment (default syntax)
|
||||||
call setpos('.', oldpos)
|
call setpos('.', oldpos)
|
||||||
let fail = 1
|
let fail = 1
|
||||||
@ -1048,6 +1051,8 @@ function! vimwiki#base#edit_file(command, filename, anchor, ...) abort
|
|||||||
call vimwiki#u#ft_set()
|
call vimwiki#u#ft_set()
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
" Goto anchor
|
||||||
if a:anchor !=? ''
|
if a:anchor !=? ''
|
||||||
call s:jump_to_anchor(a:anchor)
|
call s:jump_to_anchor(a:anchor)
|
||||||
endif
|
endif
|
||||||
@ -2154,8 +2159,12 @@ endfunction
|
|||||||
" Returns: all the headers in the current buffer as a list of the form
|
" Returns: all the headers in the current buffer as a list of the form
|
||||||
" [[line_number, header_level, header_text], [...], [...], ...]
|
" [[line_number, header_level, header_text], [...], [...], ...]
|
||||||
function! s:collect_headers() abort
|
function! s:collect_headers() abort
|
||||||
|
" Init loop variables
|
||||||
let is_inside_pre_or_math = 0 " 1: inside pre, 2: inside math, 0: outside
|
let is_inside_pre_or_math = 0 " 1: inside pre, 2: inside math, 0: outside
|
||||||
let headers = []
|
let headers = []
|
||||||
|
let rxHeader = vimwiki#vars#get_syntaxlocal('rxHeader')
|
||||||
|
|
||||||
|
" For all lines in file
|
||||||
for lnum in range(1, line('$'))
|
for lnum in range(1, line('$'))
|
||||||
let line_content = getline(lnum)
|
let line_content = getline(lnum)
|
||||||
if (is_inside_pre_or_math == 1 && line_content =~# vimwiki#vars#get_syntaxlocal('rxPreEnd')) ||
|
if (is_inside_pre_or_math == 1 && line_content =~# vimwiki#vars#get_syntaxlocal('rxPreEnd')) ||
|
||||||
@ -2174,17 +2183,31 @@ function! s:collect_headers() abort
|
|||||||
let is_inside_pre_or_math = 2
|
let is_inside_pre_or_math = 2
|
||||||
continue
|
continue
|
||||||
endif
|
endif
|
||||||
if line_content !~# vimwiki#vars#get_syntaxlocal('rxHeader')
|
|
||||||
|
" Check SetExt Header
|
||||||
|
" TODO mutualise SetExt line (for consistency)
|
||||||
|
" TODO replace regex with =\+ or -\+
|
||||||
|
if line_content =~# '\s\{0,3}[=-][=-]\+$'
|
||||||
|
let header_level = stridx(line_content, '=') != -1 ? 1 : 2
|
||||||
|
let header_text = getline(lnum-1)
|
||||||
|
" Maybe ATX header
|
||||||
|
else
|
||||||
|
" Clause: Must match rxHeader
|
||||||
|
if line_content !~# rxHeader
|
||||||
continue
|
continue
|
||||||
endif
|
endif
|
||||||
|
" Clause: markdown headers must start in the first column
|
||||||
if vimwiki#vars#get_wikilocal('syntax') ==# 'markdown'
|
if vimwiki#vars#get_wikilocal('syntax') ==# 'markdown'
|
||||||
if stridx(line_content, vimwiki#vars#get_syntaxlocal('rxH')) > 0
|
\ && stridx(line_content, vimwiki#vars#get_syntaxlocal('rxH')) > 0
|
||||||
continue " markdown headers must start in the first column
|
continue
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
" Get header level && text
|
||||||
let header_level = vimwiki#u#count_first_sym(line_content)
|
let header_level = vimwiki#u#count_first_sym(line_content)
|
||||||
let header_text =
|
let header_text = matchstr(line_content, rxHeader)
|
||||||
\ vimwiki#u#trim(matchstr(line_content, vimwiki#vars#get_syntaxlocal('rxHeader')))
|
endif
|
||||||
|
|
||||||
|
" Clean && Append to res
|
||||||
|
let header_text = vimwiki#u#trim(header_text)
|
||||||
call add(headers, [lnum, header_level, header_text])
|
call add(headers, [lnum, header_level, header_text])
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
@ -2294,6 +2317,7 @@ endfunction
|
|||||||
" a:create == 1: creates or updates TOC in current file
|
" a:create == 1: creates or updates TOC in current file
|
||||||
" a:create == 0: update if TOC exists
|
" a:create == 0: update if TOC exists
|
||||||
function! vimwiki#base#table_of_contents(create) abort
|
function! vimwiki#base#table_of_contents(create) abort
|
||||||
|
" Collect headers
|
||||||
let headers = s:collect_headers()
|
let headers = s:collect_headers()
|
||||||
let toc_header_text = vimwiki#vars#get_wikilocal('toc_header')
|
let toc_header_text = vimwiki#vars#get_wikilocal('toc_header')
|
||||||
|
|
||||||
|
@ -638,6 +638,7 @@ function! vimwiki#vars#populate_syntax_vars(syntax) abort
|
|||||||
\ '^\s*\('.header_symbol.'\{1,6}\)\zs[^'.header_symbol.'].*[^'.header_symbol.']\ze\1\s*$'
|
\ '^\s*\('.header_symbol.'\{1,6}\)\zs[^'.header_symbol.'].*[^'.header_symbol.']\ze\1\s*$'
|
||||||
else
|
else
|
||||||
" asymmetric
|
" asymmetric
|
||||||
|
" Note: For markdown rxH=# and asymetric
|
||||||
for i in range(1,6)
|
for i in range(1,6)
|
||||||
let syntax_dic['rxH'.i.'_Template'] =
|
let syntax_dic['rxH'.i.'_Template'] =
|
||||||
\ repeat(header_symbol, i).' __Header__'
|
\ repeat(header_symbol, i).' __Header__'
|
||||||
@ -650,8 +651,11 @@ function! vimwiki#vars#populate_syntax_vars(syntax) abort
|
|||||||
let syntax_dic['rxH'.i.'_End'] =
|
let syntax_dic['rxH'.i.'_End'] =
|
||||||
\ '^\s*'.header_symbol.'\{1,'.i.'}[^'.header_symbol.'].*$'
|
\ '^\s*'.header_symbol.'\{1,'.i.'}[^'.header_symbol.'].*$'
|
||||||
endfor
|
endfor
|
||||||
let syntax_dic.rxHeader =
|
" Define header regex
|
||||||
\ '^\s*\('.header_symbol.'\{1,6}\)\zs[^'.header_symbol.'].*\ze$'
|
" -- ATX heading := preceed by #*
|
||||||
|
let atx_heading = '^\s*\%('.header_symbol.'\{1,6}\)'
|
||||||
|
let atx_heading .= '\zs[^'.header_symbol.'].*\ze$'
|
||||||
|
let syntax_dic.rxHeader = atx_heading
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let syntax_dic.rxPreStart =
|
let syntax_dic.rxPreStart =
|
||||||
|
@ -3717,6 +3717,8 @@ http://code.google.com/p/vimwiki/issues/list. They may be accessible from
|
|||||||
https://github.com/vimwiki-backup/vimwiki/issues.
|
https://github.com/vimwiki-backup/vimwiki/issues.
|
||||||
|
|
||||||
New:~
|
New:~
|
||||||
|
|
||||||
|
* Issue #209: Feature: Markdown: Support SetExt Heading
|
||||||
* Issue #847 #640: Feature: Markdown anchor
|
* Issue #847 #640: Feature: Markdown anchor
|
||||||
normalize and unormalize: better follow_link and |VimwikiTOC|
|
normalize and unormalize: better follow_link and |VimwikiTOC|
|
||||||
* Commit 5408d74b3: Syntax: Html support nested, concealable tag
|
* Commit 5408d74b3: Syntax: Html support nested, concealable tag
|
||||||
|
@ -186,6 +186,18 @@ for s:i in range(1,6)
|
|||||||
\ '/me=s-1 transparent fold'
|
\ '/me=s-1 transparent fold'
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
|
" SetExt header
|
||||||
|
" TODO mutualise SetExt Regexp
|
||||||
|
let setex_header1_re = '^\s\{0,3}[^>].*\n\s\{0,3}==\+$'
|
||||||
|
let setex_header2_re = '^\s\{0,3}[^>].*\n\s\{0,3}--\+$'
|
||||||
|
execute 'syntax match VimwikiHeader1'
|
||||||
|
\ . ' /'. setex_header1_re . '/ '
|
||||||
|
\ 'contains=VimwikiTodo,VimwikiHeaderChar,VimwikiNoExistsLink,VimwikiCode,'.
|
||||||
|
\ 'VimwikiLink,@Spell'
|
||||||
|
execute 'syntax match VimwikiHeader2'
|
||||||
|
\ . ' /'. setex_header2_re . '/ ' .
|
||||||
|
\ 'contains=VimwikiTodo,VimwikiHeaderChar,VimwikiNoExistsLink,VimwikiCode,'.
|
||||||
|
\ 'VimwikiLink,@Spell'
|
||||||
|
|
||||||
|
|
||||||
let s:options = ' contained transparent contains=NONE'
|
let s:options = ' contained transparent contains=NONE'
|
||||||
|
@ -63,8 +63,25 @@ let s:markdown_syntax.rxMultilineCommentEnd = ''
|
|||||||
let s:markdown_syntax.rxComment = '^\s*%%.*$\|<!--[^>]*-->'
|
let s:markdown_syntax.rxComment = '^\s*%%.*$\|<!--[^>]*-->'
|
||||||
let s:markdown_syntax.rxTags = '\%(^\|\s\)\@<=:\%([^:[:space:]]\+:\)\+\%(\s\|$\)\@='
|
let s:markdown_syntax.rxTags = '\%(^\|\s\)\@<=:\%([^:[:space:]]\+:\)\+\%(\s\|$\)\@='
|
||||||
|
|
||||||
let s:markdown_syntax.header_search = '^\s*\(#\{1,6}\)\([^#].*\)$'
|
|
||||||
let s:markdown_syntax.header_match = '^\s*\(#\{1,6}\)#\@!\s*__Header__\s*$'
|
" Used in code (base.vim)
|
||||||
|
"""""""""""""""""""""""""
|
||||||
|
|
||||||
|
" Header
|
||||||
|
" TODO mutualise with rxHeader in vars.vim := Define atx_regex only onces
|
||||||
|
" TODO regex_or function => (1|2)
|
||||||
|
let atx_header_search = '^\s*\(#\{1,6}\)\([^#].*\)$'
|
||||||
|
let atx_header_match = '^\s*\(#\{1,6}\)#\@!\s*__Header__\s*$'
|
||||||
|
|
||||||
|
let setex_header_search = '^\s\{0,3}\zs[^>].*\ze\n'
|
||||||
|
let setex_header_search .= '^\s\{0,3}[=-]\{2,}$'
|
||||||
|
|
||||||
|
let setex_header_match = '^\s\{0,3}>\@!__Header__\n'
|
||||||
|
let setex_header_match .= '^\s\{0,3}[=-][=-]\+$'
|
||||||
|
|
||||||
|
let s:markdown_syntax.header_search = '\%(' . atx_header_search . '\|' . setex_header_search . '\)'
|
||||||
|
let s:markdown_syntax.header_match = '\%(' . atx_header_match . '\|' . setex_header_match . '\)'
|
||||||
|
|
||||||
let s:markdown_syntax.bold_search = '\%(^\|\s\|[[:punct:]]\)\@<=\*\zs'.
|
let s:markdown_syntax.bold_search = '\%(^\|\s\|[[:punct:]]\)\@<=\*\zs'.
|
||||||
\ '\%([^*`[:space:]][^*`]*[^*`[:space:]]\|[^*`[:space:]]\)\ze\*\%([[:punct:]]\|\s\|$\)\@='
|
\ '\%([^*`[:space:]][^*`]*[^*`[:space:]]\|[^*`[:space:]]\)\ze\*\%([[:punct:]]\|\s\|$\)\@='
|
||||||
let s:markdown_syntax.bold_match = '\%(^\|\s\|[[:punct:]]\)\@<=\*__Text__\*'.
|
let s:markdown_syntax.bold_match = '\%(^\|\s\|[[:punct:]]\)\@<=\*__Text__\*'.
|
||||||
|
@ -29,6 +29,60 @@
|
|||||||
# Start {{{1
|
# Start {{{1
|
||||||
|
|
||||||
|
|
||||||
|
Given vimwiki (Underline header (SetExt) (#209) {{{1):
|
||||||
|
First with spaces
|
||||||
|
=====
|
||||||
|
|
||||||
|
toto
|
||||||
|
|
||||||
|
Second
|
||||||
|
-------
|
||||||
|
toto
|
||||||
|
|
||||||
|
Third
|
||||||
|
-----
|
||||||
|
toto
|
||||||
|
|
||||||
|
Four
|
||||||
|
=====
|
||||||
|
toto
|
||||||
|
Last
|
||||||
|
----
|
||||||
|
|
||||||
|
Execute (Set syntax markdown && Set sw=8):
|
||||||
|
call SetSyntax('markdown')
|
||||||
|
set sw=8
|
||||||
|
VimwikiTOC
|
||||||
|
|
||||||
|
Expect (Heading SetExt created):
|
||||||
|
# Contents
|
||||||
|
|
||||||
|
- [First with spaces](#first-with-spaces)
|
||||||
|
- [Second](#second)
|
||||||
|
- [Third](#third)
|
||||||
|
- [Four](#four)
|
||||||
|
- [Last](#last)
|
||||||
|
|
||||||
|
First with spaces
|
||||||
|
=====
|
||||||
|
|
||||||
|
toto
|
||||||
|
|
||||||
|
Second
|
||||||
|
-------
|
||||||
|
toto
|
||||||
|
|
||||||
|
Third
|
||||||
|
-----
|
||||||
|
toto
|
||||||
|
|
||||||
|
Four
|
||||||
|
=====
|
||||||
|
toto
|
||||||
|
Last
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Given vimwiki (Two same heading (#968) {{{1):
|
Given vimwiki (Two same heading (#968) {{{1):
|
||||||
# One
|
# One
|
||||||
|
@ -1,8 +1,58 @@
|
|||||||
# Link internal to a file
|
# Link internal to a file
|
||||||
# See issue #666 for anchor support (then internal links)
|
# See issue #666 for anchor support (then internal links)
|
||||||
|
# Preambule set file onces and for all {{{1
|
||||||
|
# Otherwise the bash script is freezing
|
||||||
|
Given vimwiki (a):
|
||||||
|
a
|
||||||
|
|
||||||
|
Execute (Set filename wiki_test.md):
|
||||||
|
file wiki_test.md
|
||||||
|
|
||||||
# Link to anchor with spaces {{{!
|
Expect (a):
|
||||||
|
a
|
||||||
|
|
||||||
|
# Link to anchor in SetExt {{{1
|
||||||
|
# Like that
|
||||||
|
# -----
|
||||||
|
# Issue: #209
|
||||||
|
|
||||||
|
Given vimwiki (Anchor SetExt):
|
||||||
|
[jump](#frst-one)
|
||||||
|
|
||||||
|
F!rst One
|
||||||
|
=========
|
||||||
|
|
||||||
|
Execute (Set filename wiki_test.md):
|
||||||
|
call SetSyntax('markdown')
|
||||||
|
|
||||||
|
Do (Enter link):
|
||||||
|
\<Cr>
|
||||||
|
A__HERE__\<Esc>
|
||||||
|
|
||||||
|
Expect (Cursor jumped SetExt):
|
||||||
|
[jump](#frst-one)
|
||||||
|
|
||||||
|
F!rst One__HERE__
|
||||||
|
=========
|
||||||
|
|
||||||
|
Given vimwiki (Bad Anchor SetExt):
|
||||||
|
[jump](#frst-one)
|
||||||
|
|
||||||
|
F!rst One
|
||||||
|
|
||||||
|
Execute (Set filename wiki_test.md):
|
||||||
|
call SetSyntax('markdown')
|
||||||
|
|
||||||
|
Do (Enter link):
|
||||||
|
\<Cr>
|
||||||
|
A__HERE__\<Esc>
|
||||||
|
|
||||||
|
Expect (Cursor stayed (not jumped) SetExt):
|
||||||
|
[jump](#frst-one)__HERE__
|
||||||
|
|
||||||
|
F!rst One
|
||||||
|
|
||||||
|
# Link to anchor with spaces {{{1
|
||||||
# PR #840
|
# PR #840
|
||||||
# Issues: #831
|
# Issues: #831
|
||||||
|
|
||||||
@ -15,7 +65,6 @@ Given vimwiki (Internal links zith spaces):
|
|||||||
One line here
|
One line here
|
||||||
|
|
||||||
Execute (Set filename wiki_test.md):
|
Execute (Set filename wiki_test.md):
|
||||||
file wiki_test.md
|
|
||||||
call SetSyntax('markdown')
|
call SetSyntax('markdown')
|
||||||
|
|
||||||
Do (Enter link):
|
Do (Enter link):
|
||||||
|
@ -328,6 +328,20 @@ Execute (Assert Syntax link):
|
|||||||
|
|
||||||
# 3 Header {{{1
|
# 3 Header {{{1
|
||||||
###############
|
###############
|
||||||
|
Given vimwiki (Markdown SetExt Headers):
|
||||||
|
One
|
||||||
|
===
|
||||||
|
two
|
||||||
|
---
|
||||||
|
|
||||||
|
Execute (Set syntax markdown):
|
||||||
|
call SetSyntax('markdown')
|
||||||
|
|
||||||
|
Execute (Assert Syntax Header SetExt):
|
||||||
|
AssertEqual 'VimwikiHeader1', SyntaxAt(1, 1)
|
||||||
|
AssertEqual 'VimwikiHeader1', SyntaxAt(2, 1)
|
||||||
|
AssertEqual 'VimwikiHeader2', SyntaxAt(3, 1)
|
||||||
|
AssertEqual 'VimwikiHeader2', SyntaxAt(4, 1)
|
||||||
|
|
||||||
Given vimwiki (Wiki Headers):
|
Given vimwiki (Wiki Headers):
|
||||||
= Header level 1 =
|
= Header level 1 =
|
||||||
|
Loading…
Reference in New Issue
Block a user