From 210de650077bbc00a714682894e49d2341e0c537 Mon Sep 17 00:00:00 2001 From: Derik Ramirez Date: Fri, 17 Jul 2020 13:53:01 -0600 Subject: [PATCH] Adds support for new option to create anchors on headings Currently, when the Table of Contents is created the links are built in the table of contents but no anchor is created on the titles. This pull requests contains an optional feature that allows us to create an anchor with the following format: ``` ``` The anchor is enclosed in the `fence-text` so it can be updated if the `g:vmt_auto_update_on_save` option is enabled. So it can be deleted and updated in the same manner as the Table of Contents. To activate the new anchor creation options we do it by setting the variable: ``` g:vmt_insert_anchors = 1 ``` Developer notes: To implement this new feature we modify the return value of the folllowing function: function! s:GetHeadingLines() Now we return an array containing a touple(represented by an array) with the following content: ["heading", lineNum] The lineNum represents the position of this heading, so we can later decide to insert the anchor before the title. The anchor option supports auto update when enabled. --- ftplugin/markdown.vim | 50 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/ftplugin/markdown.vim b/ftplugin/markdown.vim index de58409..dc03de2 100644 --- a/ftplugin/markdown.vim +++ b/ftplugin/markdown.vim @@ -42,6 +42,10 @@ if !exists("g:vmt_include_headings_before") let g:vmt_include_headings_before = 0 endif +if !exists("g:vmt_insert_anchors") + let g:vmt_insert_anchors = 0 +endif + let g:GFMHeadingIds = {} let s:supportMarkdownStyles = ['GFM', 'Redcarpet', 'GitLab', 'Marked'] @@ -129,7 +133,7 @@ function! s:GetHeadingLines() endif " === - call add(l:headingLines, l:line) + call add(l:headingLines, [l:line, l:lineNum]) endif let l:flags = "W" endwhile @@ -255,6 +259,20 @@ function! GetHeadingLinkTest(headingLine, markdownStyle) return GetHeadingLink(l:headingName, a:markdownStyle) endfunction +function! s:GenerateAnchor(headingLine, line, markdownStyle, isModeline) + let l:anchorText = [] + if g:vmt_dont_insert_fence == 0 + call add(l:anchorText, GetBeginFence(a:markdownStyle, a:isModeline)) + call add(l:anchorText, "") "Add newline + endif + call add(l:anchorText, "") + call add(l:anchorText, "") "Add newline + if g:vmt_dont_insert_fence == 0 + call add(l:anchorText, GetEndFence()) + endif + call append(a:line, l:anchorText) +endfunction + function! s:GenToc(markdownStyle) call GenTocInner(a:markdownStyle, 0) endfunction @@ -265,12 +283,15 @@ function! s:GenTocInner(markdownStyle, isModeline) return endif - let l:headingLines = GetHeadingLines() + let l:fullHeadingLines = GetHeadingLines() + let l:headingLines = deepcopy(l:fullHeadingLines) + call map(l:headingLines, {_, val -> val[0]}) let l:levels = [] let l:listItemChars = [g:vmt_list_item_char] + let l:currentOffset = line('.') let g:GFMHeadingIds = {} - + for headingLine in l:headingLines call add(l:levels, GetHeadingLevel(headingLine)) endfor @@ -312,6 +333,16 @@ function! s:GenTocInner(markdownStyle, isModeline) if g:vmt_dont_insert_fence == 0 silent put =GetEndFence() endif + + let l:currentOffset = line('.') - l:currentOffset - 1 + + if g:vmt_insert_anchors == 1 + call reverse(l:fullHeadingLines) + for headingLine in l:fullHeadingLines + let l:offset = headingLine[1] + l:currentOffset + call GenerateAnchor(headingLine[0], l:offset, a:markdownStyle, a:isModeline) + endfor + endif endfunction function! s:GetIndentText() @@ -406,7 +437,7 @@ function! s:DeleteExistingToc() keepjumps normal! gg0 let l:markdownStyle = GetMarkdownStyleInModeline() - + let l:isModeline = 0 if index(s:supportMarkdownStyles, l:markdownStyle) != -1 @@ -454,6 +485,17 @@ function! s:DeleteExistingToc() echom "Cannot find toc begin fence" endif + "Delete anchors + while search(l:tocBeginPattern, "Wc") != 0 + let l:anchorBeginLineNumber = line(".") + if search(l:tocEndPattern, "W") != 0 + let l:anchorEndLineNumber = line(".") + silent execute l:anchorBeginLineNumber. "," . l:anchorEndLineNumber. "delete_" + else + echom "Cannot find toc end fence" + endif + endwhile + call winrestview(l:winview) return [l:markdownStyle, l:beginLineNumber, l:endLineNumber, l:isModeline]