Created
September 9, 2022 14:47
-
-
Save joswr1ght/6aa7218dd3d05a159f2d27674cf25aa8 to your computer and use it in GitHub Desktop.
VIM settings for Asciidoctor ease-of-use and quality-of-life
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" Insert the template file for an Asciidoc listing. This file is essentially | |
" this text: | |
" .Caption | |
" [[listing-]] | |
" [subs="+quotes,+replacements"] | |
" ---- | |
" | |
" ---- | |
" Customize the file and the file path as needed. | |
function! InsertAsciidocListing() | |
r~/.vim/templates/asciidoclisting.txt | |
endfun | |
" Create a similar file for images | |
function! InsertAsciidocImage() | |
r~/.vim/templates/asciidocimage.txt | |
endfun | |
" Create a similar file for tables | |
function! InsertAsciidocTable() | |
r~/.vim/templates/asciidoctable.txt | |
endfun | |
" I use ,l to insert a listing, ,p to insert a 'picture' (image) | |
" and ,t to insert a table | |
nnoremap ,l :call InsertAsciidocListing()<CR> | |
nnoremap ,p :call InsertAsciidocImage()<CR> | |
nnoremap ,t :call InsertAsciidocTable()<CR> | |
" This function takes the current line and formats it so the text can be used | |
" for a block Name (ID). I will generally write a caption, yank the text into the | |
" vim buffer (y$), then paste on a new line. | |
" Then I will press ,P to convert the free-form caption text into block | |
" Name-safe text with [[ ]] anchor. | |
function! ConvertToListingId() | |
" ... the first character of a Name must be a letter, colon, or underscore and | |
" the optional following characters must be a letter, colon, underscore, | |
" hyphen, period, or digit. | |
" https://docs.asciidoctor.org/asciidoc/latest/attributes/id/ | |
" | |
let line=getline('.') | |
" If the first character is a . remove it (allows for a direct caption to | |
" be used to generate the anchor | |
if line[0] == '.' | |
let line = line[1:] | |
endif | |
" Replace characters not matching rule with space | |
let line = substitute(line, '[^A-Za-z:_\-\.0-9]', ' ', 'ge') | |
" Replace consecutive whitespace with a single space | |
let line = substitute(line, '\s\+', ' ', 'ge') | |
" Replace spaces with hyphen (this is my preference, use an underscore if | |
" you like that better) | |
let line = substitute(line, ' ', '-', 'ge') | |
" Replace consecutive -- with a single - (not required, my preference) | |
let line = substitute(line, '-\+', '-', 'ge') | |
" Ensure first character is not - . or 0-9 | |
if line[0] == '-' || line[0] == '.' || line[0] =~ "[0-9]" | |
" Prepend an underscore so the line starts with a valid Name character | |
let line = '_' . line | |
endif | |
" Restore [[ and ]] to make an anchor | |
let line = substitute(line, '.*', '\[\[&\]\]', '') | |
call setline('.', line) | |
" Make it lowercase (my personal preference, but not required) | |
normal gu$ | |
endfun | |
nnoremap ,P :call ConvertToListingId()<CR> | |
" Press CTRL+e to edit the file in the `include::` statement on the selected | |
" line. (Press Ctrl+^ to go back to the previous file) | |
function! EditAdocInclude() | |
let line=getline('.') | |
" convert include::foo.adoc[] into foo.adoc | |
let includefile = split(line, '::')[1][:-3] | |
execute "e ".fnameescape(includefile) | |
endfun | |
nnoremap <c-e> :call EditAdocInclude()<CR> | |
" Convert the characters in highlighted lines to Asciidoctor entities (&#NN;) | |
" Use to prevent characters from being interpreted as markup in listings, | |
" source blocks, and other content. | |
" I use this with [subs="+quotes,+replacements"] | |
function! AdocEntities(line1, line2, action) | |
let search = @/ | |
let range = 'silent ' . a:line1 . ',' . a:line2 | |
if a:action == 0 | |
" Undo | |
execute range . 'sno/</</eg' | |
execute range . 'sno/>/>/eg' | |
execute range . 'sno/_/_/eg' | |
execute range . 'sno/`/`/eg' | |
execute range . 'sno/*/*/eg' | |
execute range . 'sno/#/#/eg' | |
execute range . 'sno/&/&/eg' | |
else " must convert & | |
" Do | |
execute range . 'sno/&/&/eg' | |
execute range . 'sno/#/gJgAJuaBfEnApSQFCzhn/eg' | |
execute range . 'sno/<</<</eg' | |
execute range . 'sno/>>/>>/eg' | |
execute range . 'sno/_/_/eg' | |
execute range . 'sno/`/`/eg' | |
execute range . 'sno/#/#/eg' | |
execute range . 'sno/gJgAJuaBfEnApSQFCzhn/#/eg' | |
endif | |
nohl | |
let @/ = search | |
endfunction | |
command! -range -nargs=1 Entities call AdocEntities(<line1>, <line2>, <args>) | |
" Press \e to encode entities | |
noremap <silent> <Leader>e :Entities 1<CR> | |
" Press \E to unencode entities | |
noremap <silent> <Leader>E :Entities 0<CR> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment