Skip to content

Instantly share code, notes, and snippets.

@joswr1ght
Created September 9, 2022 14:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joswr1ght/6aa7218dd3d05a159f2d27674cf25aa8 to your computer and use it in GitHub Desktop.
Save joswr1ght/6aa7218dd3d05a159f2d27674cf25aa8 to your computer and use it in GitHub Desktop.
VIM settings for Asciidoctor ease-of-use and quality-of-life
" 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/&lt;/</eg'
execute range . 'sno/&gt;/>/eg'
execute range . 'sno/&#95;/_/eg'
execute range . 'sno/&#96;/`/eg'
execute range . 'sno/&#42;/*/eg'
execute range . 'sno/&#35;/#/eg'
execute range . 'sno/&amp;/&/eg'
else " must convert &
" Do
execute range . 'sno/&/&amp;/eg'
execute range . 'sno/#/gJgAJuaBfEnApSQFCzhn/eg'
execute range . 'sno/<</&lt;&lt;/eg'
execute range . 'sno/>>/&gt;&gt;/eg'
execute range . 'sno/_/&#95;/eg'
execute range . 'sno/`/&#96;/eg'
execute range . 'sno/#/&#35;/eg'
execute range . 'sno/gJgAJuaBfEnApSQFCzhn/&#35;/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