1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-04-13 13:10:39 +08:00

pref(markdown): use bundle vim-markdown-toc

This commit is contained in:
wsdjeg 2022-04-23 16:16:52 +08:00
parent 421fcf273d
commit 9c6875396b
10 changed files with 1097 additions and 1 deletions

View File

@ -70,7 +70,7 @@ function! SpaceVim#layers#lang#markdown#plugins() abort
let plugins = []
call add(plugins, ['SpaceVim/vim-markdown',{ 'on_ft' : 'markdown'}])
call add(plugins, ['joker1007/vim-markdown-quote-syntax',{ 'on_ft' : 'markdown'}])
call add(plugins, ['mzlogin/vim-markdown-toc',{ 'on_ft' : 'markdown'}])
call add(plugins, [g:_spacevim_root_dir . 'bundle/vim-markdown-toc', {'merged' : 0}])
call add(plugins, ['iamcco/mathjax-support-for-mkdp',{ 'on_ft' : 'markdown'}])
call add(plugins, ['lvht/tagbar-markdown',{'merged' : 0}])
" check node package managers to ensure building of 2 plugins below

View File

@ -0,0 +1,13 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
custom: https://mazhuang.org/donate/

3
bundle/vim-markdown-toc/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.swp
.DS_Store
tags

View File

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 Zhuang Ma
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,227 @@
# vim-markdown-toc
A vim 7.4+ plugin to generate table of contents for Markdown files.
[中文版使用指南][7]
## Table of Contents
<!-- vim-markdown-toc GFM -->
* [Features](#features)
* [Installation](#installation)
* [vim-plug](#vim-plug)
* [Vundle](#vundle)
* [Usage](#usage)
* [Generate table of contents](#generate-table-of-contents)
* [Update existing table of contents](#update-existing-table-of-contents)
* [Remove table of contents](#remove-table-of-contents)
* [Options](#options)
* [Screenshots](#screenshots)
* [References](#references)
<!-- vim-markdown-toc -->
## Features
* Generate table of contents for Markdown files.
Supported Markdown parsers:
- [x] GFM (GitHub Flavored Markdown)
- [x] GitLab
- [x] Redcarpet
* Update existing table of contents.
* Auto update existing table of contents on save.
## Installation
Suggest to manage your vim plugins via [vim-plug][8] or [Vundle][4], so you can install it simply three steps:
### vim-plug
1. add the following line to your vimrc file
```
Plug 'mzlogin/vim-markdown-toc'
```
2. `:so $MYVIMRC`
3. `:PlugInstall`
### Vundle
1. add the following line to your vimrc file
```
Plugin 'mzlogin/vim-markdown-toc'
```
2. `:so $MYVIMRC`
3. `:PluginInstall`
## Usage
### Generate table of contents
Move the cursor to the line you want to append table of contents, then type a command below suit you. The command will generate **headings after the cursor** into table of contents.
1. `:GenTocGFM`
Generate table of contents in [GFM][2] link style.
This command is suitable for Markdown files in GitHub repositories, like `README.md`, and Markdown files for GitBook.
2. `:GenTocRedcarpet`
Generate table of contents in [Redcarpet][3] link style.
This command is suitable for Jekyll or anywhere else use Redcarpet as its Markdown parser.
3. `:GenTocGitLab`
Generate table of contents in [GitLab][9] link style.
This command is suitable for GitLab repository and wiki.
4. `:GenTocMarked`
Generate table of contents for [iamcco/markdown-preview.vim][10] which use [Marked][11] markdown parser.
You can view [here][1] to know differences between *GFM* and *Redcarpet* style toc links.
### Update existing table of contents
Generally you don't need to do this manually, existing table of contents will auto update on save by default.
The `:UpdateToc` command, which is designed to update toc manually, can only work when `g:vmt_auto_update_on_save` turned off, and keep insert fence.
### Remove table of contents
`:RemoveToc` command will do this for you, just remember keep insert fence option by default.
## Options
1. `g:vmt_auto_update_on_save`
default: 1
This plugin will update existing table of contents on save automatic.
You can close this feature by add the following line to your vimrc file:
```viml
let g:vmt_auto_update_on_save = 0
```
2. `g:vmt_dont_insert_fence`
default: 0
By default, the `:GenTocXXX` commands will add `<!-- vim-markdown-toc -->` fence to the table of contents, it is designed for feature of auto update table of contents on save and `:UpdateToc` command, it won't effect what your Markdown file looks like after parse.
If you don't like this, you can remove the fence by add the following line to your vimrc file:
```viml
let g:vmt_dont_insert_fence = 1
```
But then you will lose the convenience of auto update tables of contents on save and `:UpdateToc` command. When you want to update toc, you need to remove existing toc manually and rerun `:GenTocXXX` commands.
3. `g:vmt_fence_text`
default: `vim-markdown-toc`
Inner text of the fence marker for the table of contents, see `g:vmt_dont_insert_fence`.
4. `g:vmt_fence_closing_text`
default: `g:vmt_fence_text`
Inner text of the closing fence marker. E.g., you could `let g:vmt_fence_text = 'TOC'` and `let g:vmt_fence_closing_text = '/TOC'` to get
```
<!-- TOC -->
[TOC]
<!-- /TOC -->
```
5. `g:vmt_fence_hidden_markdown_style`
default: `''`
By default, _vim-markdown-toc_ will add the markdown style into the fence of the text for the table of contents. You can avoid this and set a default markdown style with `g:vmt_fence_hidden_markdown_style` that is applied if a fence is found containing the `g:vmt_fence_text` without any markdown style. Obviously, `g:vmt_fence_hidden_markdown_style` has to be supported, i.e. currently one of `['GFM', 'Redcarpet', 'GitLab', 'Marked']`.
6. `g:vmt_cycle_list_item_markers`
default: 0
By default, `*` is used to denote every level of a list:
```
* [Level 1](#level-1)
* [Level 1-1](#level-1-1)
* [Level 1-2](#level-1-2)
* [Level 1-2-1](#level-1-2-1)
* [Level 2](level-2)
```
If you set:
```viml
let g:vmt_cycle_list_item_markers = 1
```
every level will instead cycle between the valid list item markers `*`, `-` and `+`:
```
* [Level 1](#level-1)
- [Level 1-1](#level-1-1)
- [Level 1-2](#level-1-2)
+ [Level 1-2-1](#level-1-2-1)
* [Level 2](level-2)
```
This renders the same according to Markdown rules, but might appeal to those who care about readability of the source.
7. `g:vmt_list_item_char`
default: `*`
The list item marker, it can be `*`, `-` or `+`.
8. `g:vmt_include_headings_before`
default: `0`
Include headings before the position you are inserting Table of Contents.
## Screenshots
* [online demo in English][5]
![](./screenshots/english.gif)
* [online demo in Chinese][6]
![](./screenshots/chinese.gif)
## References
* <https://github.com/ajorgensen/vim-markdown-toc>
[1]: http://mazhuang.org/2015/12/05/diff-between-gfm-and-redcarpet/
[2]: https://github.github.com/gfm/
[3]: https://github.com/vmg/redcarpet
[4]: http://github.com/VundleVim/Vundle.Vim
[5]: https://github.com/mzlogin/chinese-copywriting-guidelines/blob/Simplified/README.en.md
[6]: https://github.com/mzlogin/awesome-adb
[7]: http://mazhuang.org/2015/12/19/vim-markdown-toc/
[8]: https://github.com/junegunn/vim-plug
[9]: https://docs.gitlab.com/ee/user/markdown.html
[10]:https://github.com/iamcco/markdown-preview.vim
[11]:https://github.com/markedjs/marked

View File

@ -0,0 +1 @@
au BufRead,BufNewFile *.{md,mdown,mkd,mkdn,markdown,mdwn,mdx} set filetype=markdown

View File

@ -0,0 +1,492 @@
if exists("g:loaded_MarkdownTocPlugin")
finish
elseif v:version < 704
finish
endif
let g:loaded_MarkdownTocPlugin = 1
if !exists("g:vmt_auto_update_on_save")
let g:vmt_auto_update_on_save = 1
endif
if !exists("g:vmt_dont_insert_fence")
let g:vmt_dont_insert_fence = 0
endif
if !exists("g:vmt_fence_text")
let g:vmt_fence_text = 'vim-markdown-toc'
endif
if !exists("g:vmt_fence_closing_text")
let g:vmt_fence_closing_text = g:vmt_fence_text
endif
if !exists("g:vmt_fence_hidden_markdown_style")
let g:vmt_fence_hidden_markdown_style = ''
endif
if !exists("g:vmt_list_item_char")
let g:vmt_list_item_char = '*'
endif
if !exists("g:vmt_list_indent_text")
let g:vmt_list_indent_text = ''
endif
if !exists("g:vmt_cycle_list_item_markers")
let g:vmt_cycle_list_item_markers = 0
endif
if !exists("g:vmt_include_headings_before")
let g:vmt_include_headings_before = 0
endif
if !exists("g:vmt_link")
let g:vmt_link = 1
endif
if !exists("g:vmt_min_level")
let g:vmt_min_level = 1
endif
if !exists("g:vmt_max_level")
let g:vmt_max_level = 6
endif
let g:GFMHeadingIds = {}
let s:supportMarkdownStyles = ['GFM', 'Redcarpet', 'GitLab', 'Marked']
let s:GFM_STYLE_INDEX = 0
let s:REDCARPET_STYLE_INDEX = 1
let s:GITLAB_STYLE_INDEX = 2
let s:MARKED_STYLE_INDEX = 3
function! s:HeadingLineRegex()
return '\v(^.+$\n^\=+$|^.+$\n^\-+$|^#{1,6})'
endfunction
function! s:GetSections(beginRegex, endRegex)
let l:winview = winsaveview()
let l:sections = {}
keepjumps normal! gg0
let l:flags = "Wc"
let l:beginLine = 0
let l:regex = a:beginRegex
while search(l:regex, l:flags)
let l:lineNum = line(".")
if l:beginLine == 0
let l:beginLine = l:lineNum
let l:regex = a:endRegex
else
let l:sections[l:beginLine] = l:lineNum
let l:beginLine = 0
let l:regex = a:beginRegex
endif
let l:flags = "W"
endwhile
call winrestview(l:winview)
return l:sections
endfunction
function! s:GetCodeSections()
let l:codeSections = {}
call extend(l:codeSections, <SID>GetSections("^```", "^```"))
call extend(l:codeSections, <SID>GetSections("^\\~\\~\\~", "^\\~\\~\\~"))
call extend(l:codeSections, <SID>GetSections("^{% highlight", "^{% endhighlight"))
return l:codeSections
endfunction
function! s:IsLineInCodeSections(codeSections, lineNum)
for beginLine in keys(a:codeSections)
if a:lineNum >= str2nr(beginLine)
if a:lineNum <= a:codeSections[beginLine]
return 1
endif
endif
endfor
return 0
endfunction
function! s:GetHeadingLines()
let l:winview = winsaveview()
let l:headingLines = []
let l:codeSections = <SID>GetCodeSections()
let l:flags = "W"
if g:vmt_include_headings_before == 1
keepjumps normal! gg0
let l:flags = "Wc"
endif
let l:headingLineRegex = <SID>HeadingLineRegex()
while search(l:headingLineRegex, l:flags) != 0
let l:line = getline(".")
let l:lineNum = line(".")
if <SID>IsLineInCodeSections(l:codeSections, l:lineNum) == 0
" === compatible with Setext Style headings
let l:nextLine = getline(l:lineNum + 1)
if matchstr(l:nextLine, '\v^\=+$') != ""
let l:line = "# " . l:line
elseif matchstr(l:nextLine, '\v^\-+$') != ""
let l:line = "## " . l:line
endif
" ===
call add(l:headingLines, l:line)
endif
let l:flags = "W"
endwhile
call winrestview(l:winview)
return l:headingLines
endfunction
function! s:GetHeadingLevel(headingLine)
return match(a:headingLine, '[^#]')
endfunction
function! s:GetHeadingLinkGFM(headingName)
let l:headingLink = tr(a:headingName, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")
" \_^ : start of line
" _\+ : one of more underscore _
" \| : OR
" _\+ : one of more underscore _
" \_$ : end of line
let l:headingLink = substitute(l:headingLink, "\\_^_\\+\\|_\\+\\_$", "", "g")
" Characters that are not alphanumeric, latin1 extended (for accents) and
" chinese/korean chars are removed.
" \\%#=0: allow this pattern to use the regexp engine he wants. Having
" `set re=1` in the vimrc could break this behavior. cf. issue #19
let l:headingLink = substitute(l:headingLink, "\\%#=0[^[:alnum:]\u00C0-\u00FF\u0400-\u04ff\u4e00-\u9fbf\u3040-\u309F\u30A0-\u30FF\uAC00-\uD7AF _-]", "", "g")
let l:headingLink = substitute(l:headingLink, " ", "-", "g")
if l:headingLink ==# ""
let l:nullKey = "<null>"
if has_key(g:GFMHeadingIds, l:nullKey)
let g:GFMHeadingIds[l:nullKey] += 1
let l:headingLink = l:headingLink . "-" . g:GFMHeadingIds[l:nullKey]
else
let g:GFMHeadingIds[l:nullKey] = 0
endif
elseif has_key(g:GFMHeadingIds, l:headingLink)
let g:GFMHeadingIds[l:headingLink] += 1
let l:headingLink = l:headingLink . "-" . g:GFMHeadingIds[l:headingLink]
else
let g:GFMHeadingIds[l:headingLink] = 0
endif
return l:headingLink
endfunction
" suppport for GitLab, fork of GetHeadingLinkGFM
" it's dirty to copy & paste code but more clear for maintain
function! s:GetHeadingLinkGitLab(headingName)
let l:headingLink = tolower(a:headingName)
let l:headingLink = substitute(l:headingLink, "\\_^_\\+\\|_\\+\\_$", "", "g")
let l:headingLink = substitute(l:headingLink, "\\%#=0[^[:alnum:]\u00C0-\u00FF\u0400-\u04ff\u4e00-\u9fbf _-]", "", "g")
let l:headingLink = substitute(l:headingLink, " ", "-", "g")
let l:headingLink = substitute(l:headingLink, "-\\{2,}", "-", "g")
if l:headingLink ==# ""
let l:nullKey = "<null>"
if has_key(g:GFMHeadingIds, l:nullKey)
let g:GFMHeadingIds[l:nullKey] += 1
let l:headingLink = l:headingLink . "-" . g:GFMHeadingIds[l:nullKey]
else
let g:GFMHeadingIds[l:nullKey] = 0
endif
elseif has_key(g:GFMHeadingIds, l:headingLink)
let g:GFMHeadingIds[l:headingLink] += 1
let l:headingLink = l:headingLink . "-" . g:GFMHeadingIds[l:headingLink]
else
let g:GFMHeadingIds[l:headingLink] = 0
endif
return l:headingLink
endfunction
function! s:GetHeadingLinkRedcarpet(headingName)
let l:headingLink = tolower(a:headingName)
let l:headingLink = substitute(l:headingLink, "<[^>]\\+>", "", "g")
let l:headingLink = substitute(l:headingLink, "&", "&amp;", "g")
let l:headingLink = substitute(l:headingLink, "\"", "&quot;", "g")
let l:headingLink = substitute(l:headingLink, "'", "&#39;", "g")
let l:headingLink = substitute(l:headingLink, "[ \\-&+\\$,/:;=?@\"#{}|\\^\\~\\[\\]`\\*()%.!']\\+", "-", "g")
let l:headingLink = substitute(l:headingLink, "-\\{2,}", "-", "g")
let l:headingLink = substitute(l:headingLink, "\\%^[\\-_]\\+\\|[\\-_]\\+\\%$", "", "g")
return l:headingLink
endfunction
function! s:GetHeadingLinkMarked(headingName)
let l:headingLink = tolower(a:headingName)
let l:headingLink = substitute(l:headingLink, "[ ]\\+", "-", "g")
return l:headingLink
endfunction
function! s:GetHeadingName(headingLine)
let l:headingName = substitute(a:headingLine, '^#*\s*', "", "")
let l:headingName = substitute(l:headingName, '\s*#*$', "", "")
let l:headingName = substitute(l:headingName, '\[\([^\[\]]*\)\]([^()]*)', '\1', "g")
let l:headingName = substitute(l:headingName, '\[\([^\[\]]*\)\]\[[^\[\]]*\]', '\1', "g")
return l:headingName
endfunction
function! s:GetHeadingLink(headingName, markdownStyle)
if a:markdownStyle ==# s:supportMarkdownStyles[s:GFM_STYLE_INDEX]
return <SID>GetHeadingLinkGFM(a:headingName)
elseif a:markdownStyle ==# s:supportMarkdownStyles[s:REDCARPET_STYLE_INDEX]
return <SID>GetHeadingLinkRedcarpet(a:headingName)
elseif a:markdownStyle ==# s:supportMarkdownStyles[s:GITLAB_STYLE_INDEX]
return <SID>GetHeadingLinkGitLab(a:headingName)
elseif a:markdownStyle ==# s:supportMarkdownStyles[s:MARKED_STYLE_INDEX]
return <SID>GetHeadingLinkMarked(a:headingName)
endif
endfunction
function! GetHeadingLinkTest(headingLine, markdownStyle)
let l:headingName = <SID>GetHeadingName(a:headingLine)
return <SID>GetHeadingLink(l:headingName, a:markdownStyle)
endfunction
function! s:GenToc(markdownStyle)
call <SID>GenTocInner(a:markdownStyle, 0)
endfunction
function! s:GenTocInner(markdownStyle, isModeline)
if index(s:supportMarkdownStyles, a:markdownStyle) == -1
echom "Unsupport markdown style: " . a:markdownStyle
return
endif
let l:headingLines = <SID>GetHeadingLines()
let l:levels = []
let l:listItemChars = [g:vmt_list_item_char]
let g:GFMHeadingIds = {}
for headingLine in l:headingLines
call add(l:levels, <SID>GetHeadingLevel(headingLine))
endfor
let l:minLevel = max([min(l:levels),g:vmt_min_level])
if g:vmt_dont_insert_fence == 0
silent put =<SID>GetBeginFence(a:markdownStyle, a:isModeline)
endif
if g:vmt_cycle_list_item_markers == 1
let l:listItemChars = ['*', '-', '+']
endif
let l:i = 0
" a black line before toc
if !empty(l:headingLines)
silent put =''
endif
for headingLine in l:headingLines
let l:headingName = <SID>GetHeadingName(headingLine)
" only add line if less than max level and greater than min level
if l:levels[i] <= g:vmt_max_level && l:levels[i] >= g:vmt_min_level
let l:headingIndents = l:levels[i] - l:minLevel
let l:listItemChar = l:listItemChars[(l:levels[i] + 1) % len(l:listItemChars)]
" make link if desired, otherwise just bullets
if g:vmt_link
let l:headingLink = <SID>GetHeadingLink(l:headingName, a:markdownStyle)
let l:heading = repeat(s:GetIndentText(), l:headingIndents)
let l:heading = l:heading . l:listItemChar
let l:heading = l:heading . " [" . l:headingName . "]"
let l:heading = l:heading . "(#" . l:headingLink . ")"
else
let l:heading = repeat(s:GetIndentText(), l:headingIndents)
let l:heading = l:heading . l:listItemChar
let l:heading = l:heading . " " . l:headingName
endif
silent put =l:heading
endif
let l:i += 1
endfor
" a blank line after toc to avoid effect typo of content below
silent put =''
if g:vmt_dont_insert_fence == 0
silent put =<SID>GetEndFence()
endif
endfunction
function! s:GetIndentText()
if !empty(g:vmt_list_indent_text)
return g:vmt_list_indent_text
endif
if &expandtab
return repeat(" ", &shiftwidth)
else
return "\t"
endif
endfunction
function! s:GetBeginFence(markdownStyle, isModeline)
if a:isModeline != 0
return "<!-- " . g:vmt_fence_text . " -->"
else
return "<!-- ". g:vmt_fence_text . " " . a:markdownStyle . " -->"
endif
endfunction
function! s:GetEndFence()
return "<!-- " . g:vmt_fence_closing_text . " -->"
endfunction
function! s:GetBeginFencePattern(isModeline)
if a:isModeline != 0
return "<!-- " . g:vmt_fence_text . " -->"
else
return "<!-- " . g:vmt_fence_text . " \\([[:alpha:]]\\+\\)\\? \\?-->"
endif
endfunction
function! s:GetEndFencePattern()
return "<!-- " . g:vmt_fence_closing_text . " -->"
endfunction
function! s:GetMarkdownStyleInModeline()
let l:myFileType = &filetype
let l:lst = split(l:myFileType, "\\.")
if len(l:lst) == 2 && l:lst[1] ==# "markdown"
return l:lst[0]
else
return "Unknown"
endif
endfunction
function! s:UpdateToc()
let l:winview = winsaveview()
let l:totalLineNum = line("$")
let [l:markdownStyle, l:beginLineNumber, l:endLineNumber, l:isModeline] = <SID>DeleteExistingToc()
if l:markdownStyle ==# ""
echom "Cannot find existing toc"
elseif l:markdownStyle ==# "Unknown"
echom "Find unsupported style toc"
else
let l:isFirstLine = (l:beginLineNumber == 1)
if l:beginLineNumber > 1
let l:beginLineNumber -= 1
endif
if l:isFirstLine != 0
call cursor(l:beginLineNumber, 1)
put! =''
endif
call cursor(l:beginLineNumber, 1)
call <SID>GenTocInner(l:markdownStyle, l:isModeline)
if l:isFirstLine != 0
call cursor(l:beginLineNumber, 1)
delete _
endif
" fix line number to avoid shake
if l:winview['lnum'] > l:endLineNumber
let l:diff = line("$") - l:totalLineNum
let l:winview['lnum'] += l:diff
let l:winview['topline'] += l:diff
endif
endif
call winrestview(l:winview)
endfunction
function! s:DeleteExistingToc()
let l:winview = winsaveview()
keepjumps normal! gg0
let l:markdownStyle = <SID>GetMarkdownStyleInModeline()
let l:isModeline = 0
if index(s:supportMarkdownStyles, l:markdownStyle) != -1
let l:isModeline = 1
endif
let l:tocBeginPattern = <SID>GetBeginFencePattern(l:isModeline)
let l:tocEndPattern = <SID>GetEndFencePattern()
let l:beginLineNumber = -1
let l:endLineNumber= -1
if search(l:tocBeginPattern, "Wc") != 0
let l:beginLine = getline(".")
let l:beginLineNumber = line(".")
if search(l:tocEndPattern, "W") != 0
if l:isModeline == 0
let l:markdownStyle = matchlist(l:beginLine, l:tocBeginPattern)[1]
endif
let l:doDelete = 0
if index(s:supportMarkdownStyles, l:markdownStyle) == -1
if l:markdownStyle ==# "" && index(s:supportMarkdownStyles, g:vmt_fence_hidden_markdown_style) != -1
let l:markdownStyle = g:vmt_fence_hidden_markdown_style
let l:isModeline = 1
let l:doDelete = 1
else
let l:markdownStyle = "Unknown"
endif
else
let l:doDelete = 1
endif
if l:doDelete == 1
let l:endLineNumber = line(".")
silent execute l:beginLineNumber. "," . l:endLineNumber. "delete_"
end
else
let l:markdownStyle = ""
echom "Cannot find toc end fence"
endif
else
let l:markdownStyle = ""
echom "Cannot find toc begin fence"
endif
call winrestview(l:winview)
return [l:markdownStyle, l:beginLineNumber, l:endLineNumber, l:isModeline]
endfunction
command! GenTocGFM :call <SID>GenToc(s:supportMarkdownStyles[s:GFM_STYLE_INDEX])
command! GenTocGitLab :call <SID>GenToc(s:supportMarkdownStyles[s:GITLAB_STYLE_INDEX])
command! GenTocRedcarpet :call <SID>GenToc(s:supportMarkdownStyles[s:REDCARPET_STYLE_INDEX])
command! GenTocMarked :call <SID>GenToc(s:supportMarkdownStyles[s:MARKED_STYLE_INDEX])
command! GenTocModeline :call <SID>GenTocInner(<SID>GetMarkdownStyleInModeline(), 1)
command! UpdateToc :call <SID>UpdateToc()
command! RemoveToc :call <SID>DeleteExistingToc()
if g:vmt_auto_update_on_save == 1
autocmd BufWritePre *.{md,mdown,mkd,mkdn,markdown,mdwn} if !&diff | exe 'silent! UpdateToc' | endif
endif

View File

@ -0,0 +1,56 @@
<!-- vim-markdown-toc GFM -->
* [heading1](#heading1)
* [heading2](#heading2)
* [chapter 1](#chapter-1)
* [chapter two](#chapter-------two)
* [第三章!](#第三章)
* [heading without space behind hashes](#heading-without-space-behind-hashes)
* [heading with trailing hashes](#heading-with-trailing-hashes)
* [heading with trailing hashes nested with spaces #](#heading-with-trailing-hashes-nested-with-spaces-)
* [heading with trailing hashes nested with spaces # #](#heading-with-trailing-hashes-nested-with-spaces--)
* [1.1 heading with dot 2.1](#11-heading-with-dot-21)
* [1.1](#11)
* [heading with some "special" (yes, special) chars: les caractères unicodes](#heading-with-some-special-yes-special-chars-les-caractères-unicodes)
* [heading with Cyrillic Б б](#heading-with-cyrillic-Б-б)
<!-- vim-markdown-toc -->
heading1
===
not heading1
===ha
heading2
--
not heading2
---ha
===
---
# chapter 1
# chapter two
# 第三章!
##heading without space behind hashes
## heading with trailing hashes ##
## heading with trailing hashes nested with spaces # #
## heading with trailing hashes nested with spaces # #
## 1.1 heading with dot 2.1
## 1.1
### heading with some "special" (yes, special) chars: les caractères unicodes
## heading with Cyrillic Б б

View File

@ -0,0 +1,173 @@
# Hi There ~
<!-- vim-markdown-toc Marked -->
* [Chapter One Basics ~](#chapter-one-basics-~)
* [Section 1.1 Introduction](#section-1.1-introduction)
* [Chapter Two Test More](#chapter-two-test-more)
* [Section 2.1 Don't Do This!](#section-2.1-don't-do-this!)
* [Section 2.2 If you meet problem please contact bardongong@163.com](#section-2.2-if-you-meet-problem-please-contact-bardongong@163.com)
* [Section 2.3 Do you know `Vim`?](#section-2.3-do-you-know-`vim`?)
* [Section 2.4 Carefully Use 'Symbol $' & "Symbol %"](#section-2.4-carefully-use-'symbol-$'-&-"symbol-%")
* [Section 2.5 When you write < means small, > means big](#section-2.5-when-you-write-<-means-small,->-means-big)
* [Chapter Three End of Tests](#chapter-three-end-of-tests)
* [Section 3.1 Can I use /? || \?](#section-3.1-can-i-use-/?-||-\?)
* [Section 3.2 Test @ and -](#section-3.2-test-@-and--)
* [Section 3.3 Done. Cheer Up~](#section-3.3-done.-cheer-up~)
<!-- vim-markdown-toc -->
> Actually, Marked.js replace all none "\w" characters to "-", however,
> iamcco/markdown-preview.vim replace only "\s" characters "-", make it
> clear, the rule here is for the later one.
Let's fill some lines here ~~~
Let's fill some lines here ~~~
Let's fill some lines here ~~~
Let's fill some lines here ~~~
Let's fill some lines here ~~~
Let's fill some lines here ~~~
Let's fill some lines here ~~~
Let's fill some lines here ~~~
Let's fill some lines here ~~~
Let's fill some lines here ~~~
Let's fill some lines here ~~~
## Chapter One Basics ~
Let's fill some lines here for Basics ~~~
Let's fill some lines here for Basics ~~~
Let's fill some lines here for Basics ~~~
Let's fill some lines here for Basics ~~~
### Section 1.1 Introduction
Let's fill some lines here for Basics ~~~
Let's fill some lines here for Basics ~~~
Let's fill some lines here for Basics ~~~
Let's fill some lines here for Basics ~~~
Let's fill some lines here for Basics ~~~
Let's fill some lines here for Basics ~~~
Let's fill some lines here for Basics ~~~
## Chapter Two Test More
Let's fill some lines here for more tests ~~~
Let's fill some lines here for more tests ~~~
### Section 2.1 Don't Do This!
Let's fill some lines here for more tests ~~~
Let's fill some lines here for more tests ~~~
Let's fill some lines here for more tests ~~~
### Section 2.2 If you meet problem please contact bardongong@163.com
Let's fill some lines here for more tests ~~~
Let's fill some lines here for more tests ~~~
Let's fill some lines here for more tests ~~~
### Section 2.3 Do you know `Vim`?
Let's fill some lines here for more tests ~~~
### Section 2.4 Carefully Use 'Symbol $' & "Symbol %"
Let's fill some lines here for more tests ~~~
### Section 2.5 When you write < means small, > means big
Let's fill some lines here for more tests ~~~
## Chapter Three End of Tests
Let's fill some lines here for end of tests ~~~
Let's fill some lines here for end of tests ~~~
### Section 3.1 Can I use /? || \?
Let's fill some lines here for end of tests ~~~
Let's fill some lines here for end of tests ~~~
Let's fill some lines here for end of tests ~~~
Let's fill some lines here for end of tests ~~~
Let's fill some lines here for end of tests ~~~
Let's fill some lines here for end of tests ~~~
Let's fill some lines here for end of tests ~~~
Let's fill some lines here for end of tests ~~~
Let's fill some lines here for end of tests ~~~
Let's fill some lines here for end of tests ~~~
Let's fill some lines here for end of tests ~~~
### Section 3.2 Test @ and -
That's all thx.
That's all thx.
That's all thx.
That's all thx.
That's all thx.
That's all thx.
That's all thx.
That's all thx.
That's all thx.
That's all thx.
That's all thx.
### Section 3.3 Done. Cheer Up~
YES! YOU CAN DO ALL OF ThOSE THINGS!

View File

@ -0,0 +1,109 @@
exec "silent! source " . "../ftplugin/markdown.vim"
let g:caseCount = 0
let g:passCaseCount = 0
let g:errorCaseCount = 0
function! ASSERT(var)
let g:caseCount += 1
if a:var != 0
let g:passCaseCount += 1
echo "case " . g:caseCount . " pass"
else
let g:errorCaseCount += 1
echoe "case " . g:caseCount . " error"
endif
endfunction
" GFM Test Cases {{{
let g:GFMHeadingIds = {}
call ASSERT(GetHeadingLinkTest("# 你好!", "GFM") ==# "你好")
call ASSERT(GetHeadingLinkTest("## Hello World", "GFM") ==# "hello-world")
call ASSERT(GetHeadingLinkTest("### Hello World", "GFM") ==# "hello-world-1")
call ASSERT(GetHeadingLinkTest("#### `Hello World`", "GFM") ==# "hello-world-2")
call ASSERT(GetHeadingLinkTest("##### _Hello_World_", "GFM") ==# "hello_world")
call ASSERT(GetHeadingLinkTest("###### ,", "GFM") ==# "")
call ASSERT(GetHeadingLinkTest("# ,", "GFM") ==# "-1")
call ASSERT(GetHeadingLinkTest("## No additional spaces before / after punctuation in fullwidth form", "GFM") ==# "no-additional-spaces-before--after-punctuation-in-fullwidth-form")
call ASSERT(GetHeadingLinkTest("### No additional spaces before/after punctuation in fullwidth form", "GFM") ==# "no-additional-spaces-beforeafter-punctuation-in-fullwidth-form")
call ASSERT(GetHeadingLinkTest("#### Hello Markdown ", "GFM") ==# "hello----markdown")
call ASSERT(GetHeadingLinkTest("####Heading without a space after the hashes", "GFM") ==# "heading-without-a-space-after-the-hashes")
call ASSERT(GetHeadingLinkTest("### heading with trailing hashes ###", "GFM") ==# "heading-with-trailing-hashes")
call ASSERT(GetHeadingLinkTest("### heading with trailing hashes###", "GFM") ==# "heading-with-trailing-hashes-1")
call ASSERT(GetHeadingLinkTest("### heading with trailing hashes ends with spaces ### ", "GFM") ==# "heading-with-trailing-hashes-ends-with-spaces-")
call ASSERT(GetHeadingLinkTest("### heading with trailing hashes nested with spaces # # # ", "GFM") ==# "heading-with-trailing-hashes-nested-with-spaces----")
call ASSERT(GetHeadingLinkTest("### [vim-markdown-toc](https://github.com/mzlogin/vim-markdown-toc)", "GFM") ==# "vim-markdown-toc")
call ASSERT(GetHeadingLinkTest("### [vim-markdown-toc-again][1]", "GFM") ==# "vim-markdown-toc-again")
call ASSERT(GetHeadingLinkTest("### ![vim-markdown-toc-img](/path/to/a/png)", "GFM") ==# "vim-markdown-toc-img")
call ASSERT(GetHeadingLinkTest("### ![](/path/to/a/png)", "GFM") ==# "-2")
call ASSERT(GetHeadingLinkTest("### 1.1", "GFM") ==# "11")
call ASSERT(GetHeadingLinkTest("### heading with some \"special\" \(yes, special\) chars: les caractères unicodes", "GFM") ==# "heading-with-some-special-yes-special-chars-les-caractères-unicodes")
call ASSERT(GetHeadingLinkTest("## 初音ミクV3について", "GFM") ==# "初音ミクv3について")
call ASSERT(GetHeadingLinkTest("# 안녕", "GFM") ==# "안녕")
" }}}
" GitLab Test Cases {{{
let g:GFMHeadingIds = {}
call ASSERT(GetHeadingLinkTest("# 你好!", "GitLab") ==# "你好")
call ASSERT(GetHeadingLinkTest("## Hello World", "GitLab") ==# "hello-world")
call ASSERT(GetHeadingLinkTest("### Hello World", "GitLab") ==# "hello-world-1")
call ASSERT(GetHeadingLinkTest("#### `Hello World`", "GitLab") ==# "hello-world-2")
call ASSERT(GetHeadingLinkTest("##### _Hello_World_", "GitLab") ==# "hello_world")
call ASSERT(GetHeadingLinkTest("###### ,", "GitLab") ==# "")
call ASSERT(GetHeadingLinkTest("# ,", "GitLab") ==# "-1")
call ASSERT(GetHeadingLinkTest("## No additional spaces before / after punctuation in fullwidth form", "GitLab") ==# "no-additional-spaces-before-after-punctuation-in-fullwidth-form")
call ASSERT(GetHeadingLinkTest("### No additional spaces before/after punctuation in fullwidth form", "GitLab") ==# "no-additional-spaces-beforeafter-punctuation-in-fullwidth-form")
call ASSERT(GetHeadingLinkTest("#### Hello Markdown ", "GitLab") ==# "hello-markdown")
call ASSERT(GetHeadingLinkTest("####Heading without a space after the hashes", "GitLab") ==# "heading-without-a-space-after-the-hashes")
call ASSERT(GetHeadingLinkTest("### heading with trailing hashes ###", "GitLab") ==# "heading-with-trailing-hashes")
call ASSERT(GetHeadingLinkTest("### heading with trailing hashes###", "GitLab") ==# "heading-with-trailing-hashes-1")
call ASSERT(GetHeadingLinkTest("### heading with trailing hashes ends with spaces ### ", "GitLab") ==# "heading-with-trailing-hashes-ends-with-spaces-")
call ASSERT(GetHeadingLinkTest("### heading with trailing hashes nested with spaces # # # ", "GitLab") ==# "heading-with-trailing-hashes-nested-with-spaces-")
call ASSERT(GetHeadingLinkTest("### [vim-markdown-toc](https://github.com/mzlogin/vim-markdown-toc)", "GitLab") ==# "vim-markdown-toc")
call ASSERT(GetHeadingLinkTest("### [vim-markdown-toc-again][1]", "GitLab") ==# "vim-markdown-toc-again")
call ASSERT(GetHeadingLinkTest("### ![vim-markdown-toc-img](/path/to/a/png)", "GitLab") ==# "vim-markdown-toc-img")
call ASSERT(GetHeadingLinkTest("### ![](/path/to/a/png)", "GitLab") ==# "-2")
call ASSERT(GetHeadingLinkTest("### 1.1", "GitLab") ==# "11")
call ASSERT(GetHeadingLinkTest("### heading with some \"special\" \(yes, special\) chars: les caractères unicodes", "GitLab") ==# "heading-with-some-special-yes-special-chars-les-caractères-unicodes")
call ASSERT(GetHeadingLinkTest("## heading with Cyrillic Б б", "GitLab") ==# "heading-with-cyrillic-б-б")
call ASSERT(GetHeadingLinkTest("## Ю heading starts with Cyrillic", "GitLab") ==# "ю-heading-starts-with-cyrillic")
" }}}
" Redcarpet Test Cases {{{
call ASSERT(GetHeadingLinkTest("# -Hello-World-", "Redcarpet") ==# "hello-world")
call ASSERT(GetHeadingLinkTest("## _Hello_World_", "Redcarpet") ==# "hello_world")
call ASSERT(GetHeadingLinkTest("### (Hello()World)", "Redcarpet") ==# "hello-world")
call ASSERT(GetHeadingLinkTest("#### 让 Discuz! 局域网内可访问", "Redcarpet") ==# "让-discuz-局域网内可访问")
call ASSERT(GetHeadingLinkTest('##### "你好"世界"', "Redcarpet") ==# "quot-你好-quot-世界-quot")
call ASSERT(GetHeadingLinkTest("###### '你好'世界'", "Redcarpet") ==# "39-你好-39-世界-39")
call ASSERT(GetHeadingLinkTest("# &你好&世界&", "Redcarpet") ==# "amp-你好-amp-世界-amp")
call ASSERT(GetHeadingLinkTest("## `-ms-text-autospace` to the rescue?", "Redcarpet") ==# "ms-text-autospace-to-the-rescue")
" }}}
" Marked Test Cases {{{
call ASSERT(GetHeadingLinkTest("# 你好!", "Marked") ==# "你好!")
call ASSERT(GetHeadingLinkTest("## Hello World", "Marked") ==# "hello-world")
call ASSERT(GetHeadingLinkTest("### Hello World", "Marked") ==# "hello-world")
call ASSERT(GetHeadingLinkTest("#### `Hello World`", "Marked") ==# "`hello-world`")
call ASSERT(GetHeadingLinkTest("##### _Hello_World_", "Marked") ==# "_hello_world_")
call ASSERT(GetHeadingLinkTest("###### ,", "Marked") ==# ",")
call ASSERT(GetHeadingLinkTest("# ,", "Marked") ==# ",")
call ASSERT(GetHeadingLinkTest("## No additional spaces before / after punctuation in fullwidth form", "Marked") ==# "no-additional-spaces-before-/-after-punctuation-in-fullwidth-form")
call ASSERT(GetHeadingLinkTest("### No additional spaces before/after punctuation in fullwidth form", "Marked") ==# "no-additional-spaces-before/after-punctuation-in-fullwidth-form")
call ASSERT(GetHeadingLinkTest("#### Hello Markdown ", "Marked") ==# "hello-markdown")
call ASSERT(GetHeadingLinkTest("####Heading without a space after the hashes", "Marked") ==# "heading-without-a-space-after-the-hashes")
call ASSERT(GetHeadingLinkTest("### heading with trailing hashes ###", "Marked") ==# "heading-with-trailing-hashes")
call ASSERT(GetHeadingLinkTest("### heading with trailing hashes###", "Marked") ==# "heading-with-trailing-hashes")
call ASSERT(GetHeadingLinkTest("### heading with trailing hashes ends with spaces ### ", "Marked") ==# "heading-with-trailing-hashes-ends-with-spaces")
call ASSERT(GetHeadingLinkTest("### heading with trailing hashes nested with spaces # # # ", "Marked") ==# "heading-with-trailing-hashes-nested-with-spaces-#-#")
call ASSERT(GetHeadingLinkTest("### [vim-markdown-toc](https://github.com/mzlogin/vim-markdown-toc)", "Marked") ==# "[vim-markdown-toc](https://github.com/mzlogin/vim-markdown-toc)")
call ASSERT(GetHeadingLinkTest("### [vim-markdown-toc-again][1]", "Marked") ==# "[vim-markdown-toc-again][1]")
call ASSERT(GetHeadingLinkTest("### ![vim-markdown-toc-img](/path/to/a/png)", "Marked") ==# "![vim-markdown-toc-img](/path/to/a/png)")
call ASSERT(GetHeadingLinkTest("### ![](/path/to/a/png)", "Marked") ==# "![](/path/to/a/png)")
call ASSERT(GetHeadingLinkTest("### 1.1", "Marked") ==# "1.1")
call ASSERT(GetHeadingLinkTest("### heading with some \"special\" \(yes, special\) chars: les caractères unicodes", "Marked") ==# "heading-with-some-\" special\"-\(yes,-special\)-chars:-les-caractères-unicodes")
" }}}
echo "" . g:passCaseCount . " cases pass, " . g:errorCaseCount . " cases error"