To restore parts of the text from the original tips on vim.org, the idea is the following:
- make a visual selection of some text (in a wiki tip)
- transform this text into a clever regular expression matching the same text, but in the same format as it is in the vim.org original tip (this involves escaping some characters, replacing newlines with <br>, etc...)
- find in the vim.org tip the text matching the clever regexp
- transform this text back into what the wiki expects
- replace the visual selection with the transformed text
This is very safe, because the regular expression is extremely precise, we cannot get bad matches (or more precisely, we can, but these matches would then be identical to the good match, modulo some whitespace/end of line).
For more efficiency of the script, I provide a ready-to-use package with all the tips from vim.org, to which I applied some post-processing, detailed at the bottom of this page. In particular I have removed all the embedded \r characters (see Using vim to edit tips to understand why they are problematic).
- Download the following archive of all the vim.org tips, and extract it somewhere: http://people.via.ecp.fr/~ipkiss/vim-wiki/vimtips.tar.gz
- Add the following to the Wikipedia.vim ftplugin, or to your .vimrc:
function! GetOriginalIndent() let old_reg1 = @w let old_reg2 = @/ let old_hidden = &hidden try normal gv"wy " Get tip number let tip_line = search('^|id=\d\+$', "wn") if !tip_line echoerr "Could not find tip number" return endif let tip_num = substitute(getline(tip_line), '.*=', "", "") " Open the tip set hidden exe "e " . g:vim_tips_dir . "/tip" . tip_num " Prepend a newline and escape special regexp characters let pattern = escape("\n" . @", '\\/.*$^~') " Escape html special characters the way they are expected on " vim.org tips let pattern = substitute(pattern, '&', '\&', "g") let pattern = substitute(pattern, '"', '\"', "g") " Match vim.org html code let pattern = substitute(pattern, " *\n *", '\\s*\\%(<br>\\)*\\%(\ \\)*', "g") " Search the new pattern in the buffer from vim.org let line_num = search(pattern) if line_num let line = getline(line_num) let pos_begin = match(line, pattern) let pos_end = matchend(line, pattern, pos_begin) let html_text = line[pos_begin : pos_end - 1] else bd " echoerr "Pattern not found in the tip from vim.org: " . pattern echoerr "Pattern not found in the tip from vim.org, sorry" return endif " Transform the html back into wiki format let final_text = substitute(html_text, " ", ' ', "g") let final_text = substitute(final_text, "<br>", "\n", "g") " No need to escape quotes in the wiki... let final_text = substitute(final_text, """, '"', "g") " ... but we do need to restore & let final_text = substitute(final_text, '&\(amp;\|gt;\|lt;\|#\d\+;\)\@!', '\&', "g") let g:debug = final_text " Back to the original buffer bd " Replace selection with the final text let @w = final_text normal gv"wpdd'>ddk finally " Restore registers let @/ = old_reg2 let @w = old_reg1 let &hidden = old_hidden endtry endfunction vmap z <esc>:call GetOriginalIndent()<cr>
- Define in your .vimrc a variable indicating where you extracted the tips (adapt the path, of course):
let g:vim_tips_dir = "~/vimtips"
- Edit a tip with Vim on the wiki
- Make a visual line selection (using V)
- Do not use a character-wise or block-wise visual selection if you don't like bad surprises :)
- Do not span the selection out of the tip itself, or out of one of the comments
- Do not select the signatures in the comments
- Hit z
If the script didn't manage to find the highlighted text in the original tip, it will output an error message and do nothing. You can of course undo the action of the script using u.
- If you get the message "Could not find tip number", make sure that you have set the g:vim_tips_dir variable properly... and that you are really editing a tip migrated from vim.org!
- If you get the message "Pattern not found in the tip from vim.org, sorry":
- Make sure you did the visual selection as described in the Usage section above
- Try with a smaller selection first (use gv to reselect the previous selection, and o to go from one side of the selection to the other one)
- If there was no error, but the indentation is still bad, it's probably that the original tip on vim.org had a bad indentation already. Too bad... At least you may have fixed line spacing issues :)
- You may get an extra empty line before or after the part of the text you restored. I am not sure whether it is a bug in the script or the effect described in :help v_p. I probably won't bother fixing this issue.
- The script has been well tested, but if you detect a bug notify me and I will try to fix it.
Notes concerning the tips archive
Here is how the archive has been made:
- download all the tips using wget
- (optional) get rid of the empty ones (like this one)
- open them all in a vim instance, and run:
:sil! bufdo %s/\r//g :bufdo exe "norm gg0d/code\<cr>5i\<cr>" :bufdo exe "norm /^<!-- finish off the framework -->$\<cr>dG5o" :sil! bufdo %s/\(<br>\| \)\@<!\( \)\+/ /g :sil! wqa