31d7b9a3d8700de2db851174c4e9453ea0a9d1d4
[dotfiles/vim.git] / .vim / plugin / vimfootnotes.vim
1 " Author:       Mikolaj Machowski <mikmach@wp.pl>
2 " Version:      0.6
3 " Description:  Footnotes in Vim
4 " Installation: See below
5 " Last change: pon wrz 30 09:00  2002 C
6
7 " Help part:
8 " Inspired by Emmanuel Touzery tip:
9 " http://vim.sourceforge.net/tip_view.php?tip_id=332 
10 " and discussion below (thanks to Luc for pluginization hints) 
11 " I added functions and turned it into vim script.
12 "
13 " Installation: Drop it to your plugin directory but you can declare your
14 "      favorite types of footnotes in your ftplugins.
15 "
16 "
17 " Commands:
18 " <Leader>f (in insert mode) - inserts footnotemark, opens at bottom window where
19 "     footnotemark is also inserted and you are ready to type in your
20 "     footnotetext.
21 " <Leader>r (in insert mode) - closes footnote window and returns to the text in
22 "     proper place. 
23 "
24 " You can change them by placing in your vimrc:
25 "  imap your_map <Plug>AddVimFootnote
26 "  imap your_map <Plug>ReturnFromFootnote
27 "
28 "
29 "    Footnotes are placed at the end of the file but above signature delimiter
30 "    (if one exists). 
31 "
32 " Settings:
33 " b:vimfootnotetype - possible values:
34 "       arabic (default) - [1] [2] [3] ...
35 "       alpha  - [a] [b] ... [z] [aa] [bb] ... [zz] [a] ...
36 "   Alpha  - as above but uppercase [A] ...
37 "   roman  - [i] [ii] [iii] displayed properly up to 89
38 "   Roman  - as above but uppercase [I] ... 
39 "   star   - [*] [**] [***] ... 
40 "
41 " Additional commands:
42 " FootnoteNumber:
43 "       You can change current footnote number (one obligatory argument)
44 "   :FootnoteNumber 5   
45 " FootnoteNumberRestore:
46 "       You can restore old footnote number  
47 "       :FootnoteNumberRestore  
48 " FootnoteUndo: 
49 "       Decrease footnote counter by 1
50 "       :FootnoteUndo    
51 " FootnoteMeta:
52 "       Change type of the footnotes and restart counter (1, a, A, i, I, *)
53 "       :FootnoteMeta
54 "               If your previous footnote type was alpha, Alpha, roman, Roman or star
55 "               new type will be arabic.
56 "               If your previous footnote type was arabic new type will be alpha.
57 "       :FootnoteMeta name_of_the_type
58 "               Change footnote type to name_of_the_type. If name_of_the_type is the
59 "               same as your current footnote type nothing would be changed.
60 "               You can change your default type of footnote before inserting first
61 "               footnote.       
62 " FootnoteRestore:
63 "       Restore previous footnote type and counter. Unfortunately there is no easy
64 "       way to sort footnotes at the end of file without handmade :!sort on marked
65 "       lines (it doesn't work for 'star' type).
66 "       :FootnoteRestore        
67 "
68 " For easier work with this commands I would suggest place this lines in your
69 " vimrc (they offer very nice completion of Vim commands):      
70 "       set laststatus=2
71 "       set wildmode=longest,list
72 "       set wildmenu
73 "
74 " And/or map :FootnoteComs for something you like.
75 "
76 """""""""""""""""""""""""""""""""""""""""""""""""""
77
78 if exists("b:loaded_footnote_vim") | finish | endif
79         let b:loaded_footnote_vim = 1
80
81 let s:cpo_save = &cpo
82 set cpo&vim
83
84 if !exists("g:vimfootnotetype")
85         let g:vimfootnotetype = "arabic"
86 endif
87 if !exists("g:vimfootnotenumber")
88         let g:vimfootnotenumber = 0
89 endif
90
91 " Mappings
92 if !hasmapto('<Plug>AddVimFootnote', 'i')
93         imap <Leader>f <Plug>AddVimFootnote
94 endif
95 if !hasmapto('<Plug>AddVimFootnote', 'n')
96     nmap <Leader>f <Plug>AddVimFootnote
97 endif
98
99 if !hasmapto('<Plug>ReturnFromFootnote', 'i')
100     imap <Leader>r <Plug>ReturnFromFootnote
101 endif
102 if !hasmapto('<Plug>ReturnFromFootnote', 'n')
103     nmap <Leader>r <Plug>ReturnFromFootnote
104 endif
105
106 nnoremap <Plug>AddVimFootnote :call <SID>VimFootnotes('a')<CR>
107 inoremap <Plug>AddVimFootnote <C-O>:call <SID>VimFootnotes('a')<CR>
108
109 inoremap <Plug>ReturnFromFootnote <C-O>:q<CR><Right>
110 noremap <Plug>ReturnFromFootnote :q<CR><Right>
111
112 " :Footnote commands
113 command! -nargs=1 FootnoteNumber call <sid>VimFootnoteNumber(<q-args>)
114 command! -nargs=0 FootnoteNumberRestore call <sid>VimFootnoteNumberRestore()
115 command! -nargs=0 FootnoteUndo let g:vimfootnotenumber = g:vimfootnotenumber - 1
116 command! -nargs=? FootnoteMeta call <sid>VimFootnoteMeta(<f-args>)
117 command! -nargs=0 FootnoteRestore call <sid>VimFootnoteRestore()
118
119 function! s:VimFootnoteNumber(newnumber)
120         let g:oldvimfootnotenumber = g:vimfootnotenumber
121         let g:vimfootnotenumber = a:newnumber - 1
122 endfunction
123
124 function! s:VimFootnoteNumberRestore()
125         if exists(g:oldvimfootnotenumber)
126                 let g:vimfootnotenumber = g:oldvimfootnotenumber
127         else
128                 return 0
129         endif
130 endfunction
131
132 function! s:VimFootnoteMeta(...)
133         let g:oldvimfootnotetype = g:vimfootnotetype
134         let g:oldvimfootnotenumber = g:vimfootnotenumber
135         if a:0 == "0"
136                 if (g:vimfootnotetype == "arabic")
137                         let g:vimfootnotetype = "alpha"
138                 else
139                         let g:vimfootnotetype = "arabic"
140                 endif
141         else
142                 if (a:1 == g:vimfootnotetype)
143                         echomsg "You have chosen the same footnote type! Command won't affect."
144                         return 0
145                 else
146                         let g:vimfootnotetype = a:1
147                 endif
148         endif
149         let g:vimfootnotenumber = 0
150 endfunction
151
152 function! s:VimFootnoteRestore()
153         if exists("g:oldvimfootnotenumber")
154                 let oldvimfootnotetype2 = g:vimfootnotetype
155                 let oldvimfootnotenumber2 = g:vimfootnotenumber
156                 let g:vimfootnotetype = g:oldvimfootnotetype
157                 let g:vimfootnotenumber = g:oldvimfootnotenumber
158                 let g:oldvimfootnotetype = oldvimfootnotetype2
159                 let g:oldvimfootnotenumber = oldvimfootnotenumber2
160         else
161                 echomsg "You didn't change footnote type. Yet."
162                 return 0
163         endif
164 endfunction
165         
166 function! s:VimFootnoteType(footnumber)
167         if (g:vimfootnotetype =~ "alpha\\|Alpha")
168                 if (g:vimfootnotetype == "alpha")
169                         let upper = "0"
170                 else
171                         let upper = "-32"
172                 endif
173                 if (a:footnumber <= 26)
174                         let ftnumber = nr2char(a:footnumber+96+upper)
175                 elseif (a:footnumber <= 52)
176                         let ftnumber = nr2char(a:footnumber+70+upper).nr2char(a:footnumber+70+upper)
177                 else
178                         let g:vimfootnotenumber = 1
179                         let ftnumber = nr2char(97+upper)
180                 endif
181         elseif (g:vimfootnotetype == "star")
182                 let starnumber = 1
183                 let ftnumber = ""
184                 while (starnumber <= a:footnumber)
185                         let ftnumber = ftnumber . '*'
186                         let starnumber = starnumber + 1
187                 endwhile
188         elseif (g:vimfootnotetype =~ "roman\\|Roman")
189                 let ftnumber = ""
190                 let oneroman = ""
191                 let counter = g:vimfootnotenumber
192                 if (counter >= 50)
193                         let ftnumber = "l"
194                         let counter = counter - 50
195                 endif
196                 if (counter > 39 && counter < 50)
197                         let ftnumber = "xl"
198                         let counter = counter - 40
199                 endif
200                 if (counter > 10)
201                         let tenmodulo = counter % 10
202                         let number_roman_ten = (counter - tenmodulo) / 10
203                         let romanten = 1
204                         while (romanten <= number_roman_ten)
205                                 let ftnumber = ftnumber.'x'
206                                 let romanten = romanten + 1
207                         endwhile
208                 elseif (counter == 10)
209                         let ftnumber = ftnumber.'x'
210                         let tenmodulo = ""
211                 else
212                         let tenmodulo = counter
213                 endif
214                 if (tenmodulo == 1)
215                         let oneroman = 'i'
216                 elseif (tenmodulo == 2)
217                         let oneroman = 'ii'
218                 elseif (tenmodulo == 3)
219                         let oneroman = 'iii'
220                 elseif (tenmodulo == 4)
221                         let oneroman = 'iv'
222                 elseif (tenmodulo == 5)
223                         let oneroman = 'v'
224                 elseif (tenmodulo == 6)
225                         let oneroman = 'vi'
226                 elseif (tenmodulo == 7)
227                         let oneroman = 'vii'
228                 elseif (tenmodulo == 8)
229                         let oneroman = 'viii'
230                 elseif (tenmodulo == 9)
231                         let oneroman = 'ix'
232                 elseif (tenmodulo == 0)
233                         let oneroman = ''
234                 endif
235                 let ftnumber = ftnumber . oneroman
236                 if (g:vimfootnotetype == "Roman")
237                         let ftnumber = substitute(ftnumber, ".*", "\\U\\0", "g")
238                 endif
239         else
240                 let ftnumber = a:footnumber
241         endif
242         return ftnumber
243 endfunction
244
245 function! s:VimFootnotes(appendcmd)
246         if (g:vimfootnotenumber != 0)
247                 let g:vimfootnotenumber = g:vimfootnotenumber + 1
248                 let g:vimfootnotemark = <sid>VimFootnoteType(g:vimfootnotenumber)
249                 let cr = ""
250         else
251                 let g:vimfootnotenumber = 1
252                 let g:vimfootnotemark = <sid>VimFootnoteType(g:vimfootnotenumber)
253                 let cr = "\<cr>"
254         endif
255         exe "normal ".a:appendcmd."[".g:vimfootnotemark."]\<esc>" 
256         :below 4split
257         normal G
258         if search("^-- $", "bW")
259                 exe "normal O \<esc> kki".cr."[".g:vimfootnotemark."] "
260         else
261                 exe "normal o".cr."[".g:vimfootnotemark."] "
262         endif
263         startinsert!
264 endfunction
265
266 let &cpo = s:cpo_save