├── .github └── workflows │ ├── reviewdog.yml │ └── vint.yml ├── README.md ├── assets └── footnotes.png ├── autoload └── markdownfootnotes.vim ├── doc └── markdownfootnotes.txt └── ftplugin ├── markdown └── markdownfootnotes.vim ├── pandoc └── rmd /.github/workflows/reviewdog.yml: -------------------------------------------------------------------------------- 1 | name: Reviewdog 2 | 3 | on: [ pull_request ] 4 | 5 | jobs: 6 | vint: 7 | strategy: 8 | fail-fast: false 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v3 13 | - name: Lint Vimscript in PR changes 14 | uses: reviewdog/action-vint@v1 15 | with: 16 | github_token: ${{ secrets.github_token }} 17 | reporter: github-pr-review 18 | level: info 19 | -------------------------------------------------------------------------------- /.github/workflows/vint.yml: -------------------------------------------------------------------------------- 1 | name: Vint 2 | 3 | on: [ push ] 4 | 5 | jobs: 6 | vint: 7 | strategy: 8 | fail-fast: false 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v3 13 | - name: Set up Python 14 | uses: actions/setup-python@v3 15 | - name: Setup dependencies 16 | run: pip install vim-vint 17 | - name: Lint Vimscript 18 | run: vint . 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## VimFootnotes for Markdown 2 | 3 | [![Vint](https://github.com/vim-pandoc/vim-markdownfootnotes/workflows/Vint/badge.svg)](https://github.com/vim-pandoc/vim-markdownfootnotes/actions?workflow=Vint) 4 | 5 | This fork is a slight tweak of the venerable [vimfootnotes][], for use 6 | with extended markdown. 7 | 8 | The new script inserts footnotes in the widely supported extended markdown 9 | syntax: 10 | 11 | ```markdown 12 | Here is some text.[^1] 13 | 14 | [^1]: Here is a note. 15 | ``` 16 | 17 | The footnote number gets determined by an automatic counter whenever a new 18 | footnote gets inserted. The counter works with the default arabic numerals 19 | and all other settings provided by `b:vimfootnotetype`. The automatic counter 20 | code is based on the code for the counting of HTML footnotes in [this post by 21 | Nick Coleman][3], adjusted slightly to work with Markdown footnotes. 22 | 23 | The script defines two mappings, 24 | 25 | ```viml 26 | f " Insert a new footnote 27 | r " Return from footnote 28 | ``` 29 | 30 | To insert a footnote, type `f`. A footnote mark will be inserted 31 | after the cursor. A matching footnote mark will be inserted at the end 32 | of the file. A new buffer will open in a split window at the bottom of 33 | your screen, ready to edit the new footnote. When you are done, type 34 | `r` to close the split and return to the main text. 35 | 36 | ![Screenshot][5] 37 | 38 | ## Installation 39 | 40 | Extract to your plugins directory or use any common vim plugin manager. 41 | 42 | ```viml 43 | " vim-plug 44 | Plug 'vim-pandoc/vim-markdownfootnotes' 45 | 46 | " vundle 47 | Plugin 'vim-pandoc/vim-markdownfootnotes' 48 | ``` 49 | 50 | ```bash 51 | # pathogen 52 | $ cd ~/.vim/bundle 53 | $ git clone https://github.com/vim-pandoc/vim-markdownfootnotes.git 54 | ``` 55 | 56 | ```lua 57 | -- packer 58 | use("vim-pandoc/vim-markdownfootnotes") 59 | ``` 60 | 61 | ## Settings 62 | 63 | By default, footnote ids are arabic numerals. You can change this by 64 | setting `b:vimfootnotetype`: 65 | 66 | + `arabic`: 1, 2, 3... 67 | + `alpha`: a, b, c, aa, bb..., zz, a... 68 | + `Alpha`: A, B, C, AA, BB..., ZZ, A... 69 | + `roman`: i, ii, iii... (displayed properly up to 89) 70 | + `Roman`: I, II, III... 71 | + `star`: \*, \*\*, \*\*\*... 72 | 73 | You can optionally disable line breaks before each footnote by setting `g:vimfootnotelinebreak = 0`. 74 | 75 | ## Commands 76 | 77 | `AddVimFootnote` 78 | : inserts footnotemark at cursor location, inserts footnotemark on new 79 | line at end of file, opens a split window all ready for you to enter in 80 | the footnote. 81 | 82 | `ReturnFromFootnote` 83 | : closes the split window and returns to the text in proper place. 84 | 85 | These are mapped to `f` and `r` respectively. 86 | 87 | `FootnoteNumber` 88 | : Change the current footnote number (one obligatory argument) 89 | :FootnoteNumber 5 90 | 91 | `FootnoteNumberRestore` 92 | : Restore old footnote number 93 | 94 | `FootnoteUndo` 95 | : Decrease footnote counter by 1 96 | 97 | `FootnoteMeta []` 98 | : Change type of the footnotes and restart counter (1, a, A, i, I, *) 99 | 100 | The `` argument is optional. If omitted, and your previous 101 | footnote type was not `arabic`, the new type will be `arabic`; if it was 102 | arabic, the new type will be `alpha`. If the new type is the same as the 103 | previous type, then the counter will not be restarted. 104 | 105 | 106 | `FootnoteRestore` 107 | : Restore previous footnote type and counter. 108 | 109 | [1]: https://github.com/vim-pandoc/vim-markdownfootnotes/ 110 | [2]: http://www.vim.org/scripts/script.php?script_id=431 111 | [3]: http://www.nickcoleman.org/blog/index.cgi?post=footnotevim%21201102211201%21programming 112 | [5]: https://raw.github.com/vim-pandoc/vim-markdownfootnotes/master/assets/footnotes.png 113 | -------------------------------------------------------------------------------- /assets/footnotes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vim-pandoc/vim-markdownfootnotes/2b288149f48cfaf7465d25bb094ed62898f5e5b0/assets/footnotes.png -------------------------------------------------------------------------------- /autoload/markdownfootnotes.vim: -------------------------------------------------------------------------------- 1 | scriptencoding utf-8 2 | 3 | function! markdownfootnotes#VimFootnoteNumber(newnumber) abort 4 | let g:oldvimfootnotenumber = g:vimfootnotenumber 5 | let g:vimfootnotenumber = a:newnumber - 1 6 | endfunction 7 | 8 | function! markdownfootnotes#VimFootnoteNumberRestore() abort 9 | if exists(g:oldvimfootnotenumber) 10 | let g:vimfootnotenumber = g:oldvimfootnotenumber 11 | else 12 | return 0 13 | endif 14 | endfunction 15 | 16 | function! markdownfootnotes#VimFootnoteMeta(...) abort 17 | let g:oldvimfootnotetype = g:vimfootnotetype 18 | let g:oldvimfootnotenumber = g:vimfootnotenumber 19 | if a:0 ==# '0' 20 | if (g:vimfootnotetype ==? 'arabic') 21 | let g:vimfootnotetype = 'alpha' 22 | else 23 | let g:vimfootnotetype = 'arabic' 24 | endif 25 | else 26 | if (a:1 == g:vimfootnotetype) 27 | echomsg 'You have chosen the same footnote type! Command won’t affect.' 28 | return 0 29 | else 30 | let g:vimfootnotetype = a:1 31 | endif 32 | endif 33 | let g:vimfootnotenumber = 0 34 | endfunction 35 | 36 | function! markdownfootnotes#VimFootnoteRestore() abort 37 | if exists('g:oldvimfootnotenumber') 38 | let oldvimfootnotetype2 = g:vimfootnotetype 39 | let oldvimfootnotenumber2 = g:vimfootnotenumber 40 | let g:vimfootnotetype = g:oldvimfootnotetype 41 | let g:vimfootnotenumber = g:oldvimfootnotenumber 42 | let g:oldvimfootnotetype = oldvimfootnotetype2 43 | let g:oldvimfootnotenumber = oldvimfootnotenumber2 44 | else 45 | echomsg "You didn't change footnote type. Yet." 46 | return 0 47 | endif 48 | endfunction 49 | 50 | function! markdownfootnotes#VimFootnoteType(footnumber) abort 51 | if (g:vimfootnotetype =~? 'alpha') 52 | if (g:vimfootnotetype ==# 'alpha') 53 | let upper = 0 54 | else 55 | let upper = -32 56 | endif 57 | if (a:footnumber <= 26) 58 | let ftnumber = nr2char(a:footnumber+96+upper) 59 | elseif (a:footnumber <= 52) 60 | let ftnumber = nr2char(a:footnumber+70+upper).nr2char(a:footnumber+70+upper) 61 | else 62 | let g:vimfootnotenumber = 1 63 | let ftnumber = nr2char(97+upper) 64 | endif 65 | elseif (g:vimfootnotetype ==? 'star') 66 | let starnumber = 1 67 | let ftnumber = '' 68 | while (starnumber <= a:footnumber) 69 | let ftnumber = ftnumber . '*' 70 | let starnumber = starnumber + 1 71 | endwhile 72 | elseif (g:vimfootnotetype =~? 'roman') 73 | let ftnumber = '' 74 | let oneroman = '' 75 | let counter = g:vimfootnotenumber 76 | if (counter >= 50) 77 | let ftnumber = 'l' 78 | let counter = counter - 50 79 | endif 80 | if (counter > 39 && counter < 50) 81 | let ftnumber = 'xl' 82 | let counter = counter - 40 83 | endif 84 | if (counter > 10) 85 | let tenmodulo = counter % 10 86 | let number_roman_ten = (counter - tenmodulo) / 10 87 | let romanten = 1 88 | while (romanten <= number_roman_ten) 89 | let ftnumber = ftnumber.'x' 90 | let romanten = romanten + 1 91 | endwhile 92 | elseif (counter == 10) 93 | let ftnumber = ftnumber.'x' 94 | let tenmodulo = '' 95 | else 96 | let tenmodulo = counter 97 | endif 98 | if (tenmodulo == 1) 99 | let oneroman = 'i' 100 | elseif (tenmodulo == 2) 101 | let oneroman = 'ii' 102 | elseif (tenmodulo == 3) 103 | let oneroman = 'iii' 104 | elseif (tenmodulo == 4) 105 | let oneroman = 'iv' 106 | elseif (tenmodulo == 5) 107 | let oneroman = 'v' 108 | elseif (tenmodulo == 6) 109 | let oneroman = 'vi' 110 | elseif (tenmodulo == 7) 111 | let oneroman = 'vii' 112 | elseif (tenmodulo == 8) 113 | let oneroman = 'viii' 114 | elseif (tenmodulo == 9) 115 | let oneroman = 'ix' 116 | elseif (tenmodulo == 0) 117 | let oneroman = '' 118 | endif 119 | let ftnumber = ftnumber . oneroman 120 | if (g:vimfootnotetype ==# 'Roman') 121 | let ftnumber = substitute(ftnumber, '.*', "\\U\\0", 'g') 122 | endif 123 | else 124 | let ftnumber = a:footnumber 125 | endif 126 | return ftnumber 127 | endfunction 128 | 129 | function! markdownfootnotes#VimFootnotes(appendcmd) abort 130 | " save current position 131 | let s:cur_pos = getpos('.') 132 | " Define search pattern for footnote definitions 133 | let l:pattern = '\v^\[\^(.+)\]:' 134 | let l:flags = 'eW' 135 | call cursor(1,1) 136 | " get first match 137 | let g:vimfootnotenumber = search(l:pattern, l:flags) 138 | if (g:vimfootnotenumber != 0) 139 | let l:temp = 1 140 | " count subsequent matches 141 | while search(l:pattern, l:flags) != 0 142 | let l:temp += 1 143 | endwhile 144 | let g:vimfootnotenumber = l:temp + 1 145 | " Return to position 146 | call setpos('.', s:cur_pos) 147 | let g:vimfootnotemark = markdownfootnotes#VimFootnoteType(g:vimfootnotenumber) 148 | else 149 | let g:vimfootnotenumber = 1 150 | " Return to position 151 | call setpos('.', s:cur_pos) 152 | let g:vimfootnotemark = markdownfootnotes#VimFootnoteType(g:vimfootnotenumber) 153 | endif 154 | let cr = g:vimfootnotelinebreak ? "\" : '' 155 | 156 | exe 'normal! '.a:appendcmd.'[^'.g:vimfootnotemark."]\" 157 | :below 4split 158 | normal! G 159 | exe "normal! o\[^".g:vimfootnotemark.']: ' 160 | startinsert! 161 | endfunction 162 | -------------------------------------------------------------------------------- /doc/markdownfootnotes.txt: -------------------------------------------------------------------------------- 1 | *markdownfootnotes.txt* Plugin to ease creation of *markdown-footnotes* 2 | 3 | 4 | INTRODUCTION *markdownfootnotes-intro* 5 | 6 | To insert a footnote, type `f`. A footnote mark will be inserted 7 | after the cursor. A matching footnote mark will be inserted at the end 8 | of the file. A new buffer will open in a split window at the bottom of 9 | your screen, ready to edit the new footnote. When you are done, type 10 | `r` to close the split and return to the main text. 11 | 12 | 13 | COMMANDS *markdownfootnotes-commands* 14 | 15 | `AddVimFootnote` 16 | : inserts footnotemark at cursor location, inserts footnotemark on new 17 | line at end of file, opens a split window all ready for you to enter in 18 | the footnote. 19 | 20 | `ReturnFromFootnote` 21 | : closes the split window and returns to the text in proper place. 22 | 23 | These are mapped to `f` and `r` respectively. 24 | 25 | `FootnoteNumber` 26 | : Change the current footnote number (one obligatory argument) 27 | :FootnoteNumber 5 28 | 29 | `FootnoteNumberRestore` 30 | : Restore old footnote number 31 | 32 | `FootnoteUndo` 33 | : Decrease footnote counter by 1 34 | 35 | `FootnoteMeta []` 36 | : Change type of the footnotes and restart counter (1, a, A, i, I, *) 37 | 38 | The `` argument is optional. If omitted, and your previous 39 | footnote type was not `arabic`, the new type will be `arabic`; if it was 40 | arabic, the new type will be `alpha`. If the new type is the same as the 41 | previous type, then the counter will not be restarted. 42 | 43 | `FootnoteRestore` 44 | : Restore previous footnote type and counter. 45 | 46 | 47 | CONFIG *markdownfootnotes-config* 48 | 49 | By default, footnote ids are arabic numerals. You can change this by 50 | setting `b:vimfootnotetype` in ~/.vim/ftplugin/markdown.vim: 51 | 52 | + `arabic`: 1, 2, 3... 53 | + `alpha`: a, b, c, aa, bb..., zz, a... 54 | + `Alpha`: A, B, C, AA, BB..., ZZ, A... 55 | + `roman`: i, ii, iii... (displayed properly up to 89) 56 | + `Roman`: I, II, III... 57 | + `star`: \*, \*\*, \*\*\*... 58 | 59 | vim:tw=78:ts=8:noet:ft=help:fdm=marker 60 | -------------------------------------------------------------------------------- /ftplugin/markdown/markdownfootnotes.vim: -------------------------------------------------------------------------------- 1 | " Maintainer: David Sanson 2 | " Description: Extended Markdown Footnotes in Vim 3 | " Version: 1.0 4 | " URL: https://github.com/vim-pandoc/vim-markdownfootnotes 5 | " 6 | " I've taken the original and modified the output to fit the widely 7 | " supported extended markdown format for footnotes.[^note] 8 | " 9 | " [^note]: Like this. 10 | " 11 | " The original script either puts notes at the end, or before your 12 | " email sig line (i.e., if there is a line that consists of two dashes, 13 | " it puts the notes before that line). This version just puts them at 14 | " the end. 15 | " 16 | " Based On: 17 | " VimFootnotes 18 | " Author: Mikolaj Machowski 19 | " Version: 0.6 20 | " Description: Footnotes in Vim 21 | " Installation: See below 22 | " Last Change: pon wrz 30 09:00 2002 C 23 | " URL: http://www.vim.org/scripts/script.php?script_id=431 24 | " Help Part: 25 | " Inspired by Emmanuel Touzery tip: 26 | " http://vim.sourceforge.net/tip_view.php?tip_id=332 27 | " and discussion below (thanks to Luc for pluginization hints) 28 | " I added functions and turned it into vim script. 29 | " 30 | " Installation: Drop it to your plugin directory or use pathogen. 31 | " 32 | " Settings: 33 | " 34 | " By default, footnote ids are arabic numerals. You can change this by 35 | " setting b:vimfootnotetype, 36 | " 37 | " arabic (default) - [1] [2] [3] ... 38 | " alpha - [a] [b] ... [z] [aa] [bb] ... [zz] [a] ... 39 | " Alpha - as above but uppercase [A] ... 40 | " roman - [i] [ii] [iii] displayed properly up to 89 41 | " Roman - as above but uppercase [I] ... 42 | " star - [*] [**] [***] ... 43 | " 44 | " Commands: 45 | " 46 | " Those mappings correspond to two commands that you can use in your own 47 | " mappings: 48 | " 49 | " AddVimFootnote 50 | " ~ inserts footnotemark at cursor location, inserts footnotemark on new 51 | " line at end of file, opens a split window all ready for you to enter in 52 | " the footnote. 53 | 54 | " ReturnFromFootnote 55 | " ~ closes the split window and returns to the text in proper place. 56 | " 57 | " These are mapped to f and r respectively. 58 | " 59 | " FootnoteNumber 60 | " ~ Change the current footnote number (one obligatory argument) 61 | " :FootnoteNumber 5 62 | " 63 | " FootnoteNumberRestore 64 | " ~ Restore old footnote number 65 | 66 | " FootnoteUndo 67 | " ~ Decrease footnote counter by 1 68 | " 69 | " FootnoteMeta 70 | " ~ Change type of the footnotes and restart counter (1, a, A, i, I, *) 71 | " :FootnoteMeta 72 | " If your previous footnote type was alpha, Alpha, roman, Roman or star 73 | " new type will be arabic. 74 | " If your previous footnote type was arabic new type will be alpha. 75 | " :FootnoteMeta name_of_the_type 76 | " Change footnote type to name_of_the_type. If name_of_the_type is the 77 | " same as your current footnote type nothing would be changed. 78 | " You can change your default type of footnote before inserting first 79 | " footnote. 80 | " 81 | " FootnoteRestore 82 | " ~ Restore previous footnote type and counter. Unfortunately there is no easy 83 | " way to sort footnotes at the end of file without handmade :!sort on marked 84 | " lines (it doesn't work for 'star' type). 85 | " :FootnoteRestore 86 | " 87 | """"""""""""""""""""""""""""""""""""""""""""""""""" 88 | 89 | if exists('b:loaded_footnote_vim') | finish | endif 90 | let b:loaded_footnote_vim = 1 91 | 92 | let s:cpo_save = &cpo 93 | set cpo&vim 94 | 95 | if !exists('g:vimfootnotetype') 96 | let g:vimfootnotetype = 'arabic' 97 | endif 98 | 99 | if !exists('g:vimfootnotenumber') 100 | let g:vimfootnotenumber = 0 101 | endif 102 | 103 | if !exists('g:vimfootnotelinebreak') 104 | let g:vimfootnotelinebreak = 1 105 | endif 106 | 107 | " Mappings 108 | if !hasmapto('AddVimFootnote', 'i') && mapcheck('f', 'i') is# '' 109 | imap f AddVimFootnote 110 | endif 111 | if !hasmapto('AddVimFootnote', 'n') && mapcheck('f', 'n') is# '' 112 | nmap f AddVimFootnote 113 | endif 114 | 115 | if !hasmapto('ReturnFromFootnote', 'i') && mapcheck('r', 'i') is# '' 116 | imap r ReturnFromFootnote 117 | endif 118 | if !hasmapto('ReturnFromFootnote', 'n') && mapcheck('r', 'n') is# '' 119 | nmap r ReturnFromFootnote 120 | endif 121 | 122 | nnoremap AddVimFootnote :call markdownfootnotes#VimFootnotes('a') 123 | inoremap AddVimFootnote :call markdownfootnotes#VimFootnotes('a') 124 | 125 | inoremap ReturnFromFootnote :q 126 | nnoremap ReturnFromFootnote :q 127 | 128 | " :Footnote commands 129 | command! -buffer -nargs=1 FootnoteNumber call markdownfootnotes#VimFootnoteNumber() 130 | command! -buffer -nargs=0 FootnoteNumberRestore call markdownfootnotes#VimFootnoteNumberRestore() 131 | command! -buffer -nargs=0 FootnoteUndo let g:vimfootnotenumber = g:vimfootnotenumber - 1 132 | command! -buffer -nargs=? FootnoteMeta call markdownfootnotes#VimFootnoteMeta() 133 | command! -buffer -nargs=0 FootnoteRestore call markdownfootnotes#VimFootnoteRestore() 134 | 135 | let &cpo = s:cpo_save 136 | -------------------------------------------------------------------------------- /ftplugin/pandoc: -------------------------------------------------------------------------------- 1 | markdown -------------------------------------------------------------------------------- /ftplugin/rmd: -------------------------------------------------------------------------------- 1 | markdown --------------------------------------------------------------------------------