603 lines
15 KiB
Text
603 lines
15 KiB
Text
= Vim ❤️ Asciidoctor
|
|
:author: Maxim Kim
|
|
:experimental:
|
|
:toc: left
|
|
:toclevels: 3
|
|
:icons: font
|
|
:autofit-option:
|
|
:source-highlighter: rouge
|
|
:rouge-style: github
|
|
:source-linenums-option:
|
|
:revdate: 2018-11-19
|
|
:imagesdir: images
|
|
|
|
image::image1.png[]
|
|
|
|
== Intro
|
|
|
|
Vim has syntax highlighting for asciidoc out of the box. And it is/was really
|
|
slow for me, probably because it tries to be very smart about syntax.
|
|
|
|
This plugin:
|
|
|
|
- has different syntax highlighting;
|
|
- is way faster (your vim lags less :) );
|
|
- has folding;
|
|
- has commands to compile documents (html, pdf, docx).
|
|
|
|
|
|
== Installation
|
|
|
|
=== Vim8 built in packages
|
|
|
|
You can use git command on your command line:
|
|
[source,bash]
|
|
--------
|
|
|
|
git clone https://github.com/habamax/vim-asciidoctor.git ~/.vim/pack/my-packages/start/vim-asciidoctor
|
|
|
|
--------
|
|
|
|
For windows users you should change `~/.vim` to `%USERPROFILE%/vimfiles`
|
|
[source,cmd]
|
|
--------
|
|
|
|
git clone https://github.com/habamax/vim-asciidoctor.git %USERPROFILE%/vimfiles/pack/my-packages/start/vim-asciidoctor
|
|
|
|
--------
|
|
|
|
or `minpac` package manager (to add to your `.vimrc`):
|
|
|
|
[source,vim]
|
|
--------
|
|
|
|
call minpac#add('habamax/vim-asciidoctor')
|
|
|
|
--------
|
|
|
|
|
|
=== vim-plug
|
|
|
|
.Add to your .vimrc next to your other plugs
|
|
[source,vim]
|
|
--------
|
|
|
|
Plug 'habamax/vim-asciidoctor'
|
|
|
|
--------
|
|
|
|
|
|
== Setup
|
|
|
|
NOTE: To use basic asciidoctor with vim you don't have to setup anything in vim. At
|
|
least this was the intention. :)
|
|
|
|
The following is an example setup. Part of it might not work for you if you don't have
|
|
asciidoctor extensions installed. Or you don't have custom PDF themes and fonts.
|
|
|
|
.asciidoctor
|
|
[source,vim]
|
|
--------
|
|
|
|
" What to use for HTML, default `asciidoctor`.
|
|
let g:asciidoctor_executable = 'asciidoctor'
|
|
|
|
" What extensions to use for HTML, default `[]`.
|
|
let g:asciidoctor_extensions = ['asciidoctor-diagram', 'asciidoctor-rouge']
|
|
|
|
" Path to the custom css
|
|
let g:asciidoctor_css_path = '~/docs/AsciiDocThemes'
|
|
|
|
" Custom css name to use instead of built-in
|
|
let g:asciidoctor_css = 'haba-asciidoctor.css'
|
|
|
|
--------
|
|
|
|
.asciidoctor-pdf
|
|
[source,vim]
|
|
--------
|
|
|
|
" What to use for PDF, default `asciidoctor-pdf`.
|
|
let g:asciidoctor_pdf_executable = 'asciidoctor-pdf'
|
|
|
|
" What extensions to use for PDF, default `[]`.
|
|
let g:asciidoctor_pdf_extensions = ['asciidoctor-diagram']
|
|
|
|
" Path to PDF themes, default `''`.
|
|
let g:asciidoctor_pdf_themes_path = '~/docs/AsciiDocThemes'
|
|
|
|
" Path to PDF fonts, default `''`.
|
|
let g:asciidoctor_pdf_fonts_path = '~/docs/AsciiDocThemes/fonts'
|
|
|
|
--------
|
|
|
|
.asciidoctor-docx
|
|
[source,vim]
|
|
--------
|
|
|
|
" What to use for DOCX, default `pandoc`.
|
|
" The DOCX 'compilation' process is to generate `docbook` using
|
|
" `g:asciidoctor_executable` and then to generate DOCX out of `docbook`
|
|
" using `pandoc`.
|
|
let g:asciidoctor_pandoc_executable = 'pandoc'
|
|
|
|
"" --data-dir
|
|
let g:asciidoctor_pandoc_data_dir = '~/docs/.pandoc'
|
|
|
|
" Other parameters you want to feed pandoc
|
|
let g:asciidoctor_pandoc_other_params = '--toc'
|
|
|
|
" Reference document to reuse styles
|
|
" If not set up asciidoctor looks for the theme name
|
|
" :pdf-style: mytheme
|
|
" in the first 30 lines and generate reference-doc filename:
|
|
" g:asciidoctor_pandoc_data_dir + mytheme + '-reference.docx'
|
|
" for example: ~/docs/.pandoc/mytheme-reference.docx
|
|
let g:asciidoctor_pandoc_reference_doc = 'custom-reference.docx'
|
|
|
|
--------
|
|
|
|
.folding
|
|
[source,vim]
|
|
--------
|
|
|
|
" Fold sections, default `0`.
|
|
let g:asciidoctor_folding = 1
|
|
|
|
" Fold options, default `0`.
|
|
let g:asciidoctor_fold_options = 1
|
|
|
|
--------
|
|
|
|
.syntax
|
|
[source,vim]
|
|
--------
|
|
|
|
" Conceal *bold*, _italic_, `code` and urls in lists and paragraphs, default `0`.
|
|
" See limitations in end of the README
|
|
let g:asciidoctor_syntax_conceal = 1
|
|
|
|
" Highlight indented text, default `1`.
|
|
let g:asciidoctor_syntax_indented = 0
|
|
|
|
--------
|
|
|
|
.syntax highlighting for languages in [source] blocks
|
|
[source,vim]
|
|
--------
|
|
|
|
" List of filetypes to highlight, default `[]`
|
|
let g:asciidoctor_fenced_languages = ['python', 'c', 'javascript']
|
|
|
|
--------
|
|
|
|
.default mappings... there are no default mappings
|
|
[source,vim]
|
|
--------
|
|
|
|
" Function to create buffer local mappings and add default compiler
|
|
fun! AsciidoctorMappings()
|
|
nnoremap <buffer> <leader>oo :AsciidoctorOpenRAW<CR>
|
|
nnoremap <buffer> <leader>op :AsciidoctorOpenPDF<CR>
|
|
nnoremap <buffer> <leader>oh :AsciidoctorOpenHTML<CR>
|
|
nnoremap <buffer> <leader>ox :AsciidoctorOpenDOCX<CR>
|
|
nnoremap <buffer> <leader>ch :Asciidoctor2HTML<CR>
|
|
nnoremap <buffer> <leader>cp :Asciidoctor2PDF<CR>
|
|
nnoremap <buffer> <leader>cx :Asciidoctor2DOCX<CR>
|
|
nnoremap <buffer> <leader>p :AsciidoctorPasteImage<CR>
|
|
" :make will build pdfs
|
|
compiler asciidoctor2pdf
|
|
endfun
|
|
|
|
" Call AsciidoctorMappings for all `*.adoc` and `*.asciidoc` files
|
|
augroup asciidoctor
|
|
au!
|
|
au BufEnter *.adoc,*.asciidoc call AsciidoctorMappings()
|
|
augroup END
|
|
|
|
--------
|
|
|
|
|
|
== Commands
|
|
|
|
All commands are buffer local -- available only for asciidoctor files (`set filetype=asciidoctor`)
|
|
|
|
* `Asciidoctor2HTML` -- convert current file to `HTML`.
|
|
* `Asciidoctor2PDF` -- convert current file to `PDF`.
|
|
* `Asciidoctor2DOCX` -- convert current file to `DOCX`.
|
|
* `AsciidoctorOpenRAW` -- open current file in a browser. Chrome and Firefox has extentsions to render barebone `adoc` files.
|
|
* `AsciidoctorOpenPDF` -- open `PDF` of the current file using default PDF viewer.
|
|
* `AsciidoctorOpenHTML` -- open `HTML` of the current file using default web browser.
|
|
* `AsciidoctorOpenDOCX` -- open `DOCX` of the current file using default DOCX
|
|
viewer. (I haven't tried it with LibreOffice or whatever else there might be.
|
|
Also haven't tried it on linux and OSX...)
|
|
|
|
[NOTE]
|
|
======
|
|
Commands: `Asciidoctor2HTML`, `Asciidoctor2PDF` should convert files
|
|
if link:https://asciidoctor.org/docs/user-manual/#installing-the-asciidoctor-ruby-gem[asciidoctor] and link:https://github.com/asciidoctor/asciidoctor-pdf#getting-started[asciidoctor-pdf] are installed.
|
|
|
|
Command `Asciidoctor2DOCX` should also have link:https://pandoc.org/installing.html[pandoc] installed.
|
|
======
|
|
|
|
|
|
== Usage
|
|
|
|
1. Open `~/test.adoc`
|
|
2. Enter:
|
|
+
|
|
[literal]
|
|
.........
|
|
|
|
= Asciidoctor Title: Hanging around
|
|
|
|
This is the first para and it will be rendered with bigger text.
|
|
|
|
== Section 1
|
|
|
|
Text of section 1
|
|
|
|
== Section 2
|
|
|
|
Text of section 2
|
|
|
|
.........
|
|
|
|
3. Save it and export to `HTML`
|
|
+
|
|
[literal]
|
|
.........
|
|
|
|
:w<CR>
|
|
:Asciidoctor2HTML<CR>
|
|
|
|
.........
|
|
|
|
4. Open the `HTML` file:
|
|
+
|
|
[literal]
|
|
.........
|
|
|
|
:AsciidoctorOpenHTML<CR>
|
|
|
|
.........
|
|
|
|
// pics
|
|
|
|
|
|
=== HTML output
|
|
That should look something like this:
|
|
|
|
.HTML output
|
|
image::test_html.png[]
|
|
|
|
|
|
=== DOCX output
|
|
|
|
If you use `:Asciidoctor2DOCX` and `:AsciidoctorOpenDOCX` commands instead, you
|
|
should see something like this (provided you have `pandoc` and `MSWord`
|
|
installed:)
|
|
|
|
.DOCX output
|
|
image::test_docx.png[]
|
|
|
|
|
|
=== PDF output
|
|
|
|
And if you use `:Asciidoctor2PDF` and `:AsciidoctorOpenPDF` commands, you
|
|
should see something like this (I have my own default theme and fonts, so you
|
|
probably see it a bit different) :
|
|
|
|
.PDF title page output
|
|
image::test_pdf1.png[]
|
|
|
|
.PDF first page output
|
|
image::test_pdf2.png[]
|
|
|
|
// add some short youtube videos
|
|
|
|
|
|
== Paste images from clipboard
|
|
|
|
Vim can't access graphical part of clipboard thus an external tool should be used to save clipboard image to a png file.
|
|
|
|
* For Windows I use GraphicsMagic (could be installed using `scoop`)
|
|
* For OSX I use `pngpaste` (could be installed using `brew`)
|
|
* For Linux -- `xclip` could be used (thx Matthias Fulz @mfulz)
|
|
|
|
image::https://github.com/habamax/habamax.github.io/blob/master/assets/gifs/asciidoctor-pasteimg.gif[animated screen with image pasting]
|
|
|
|
.setup
|
|
[source,vim]
|
|
--------
|
|
" first `%s` is a path
|
|
" second `%s` is an image file name
|
|
" this is default for windows
|
|
let g:asciidoctor_img_paste_command = 'gm convert clipboard: %s%s'
|
|
|
|
" for osx
|
|
" let g:asciidoctor_img_paste_command = 'pngpaste %s%s'
|
|
|
|
" for linux
|
|
" let g:asciidoctor_img_paste_command = 'xclip -selection clipboard -t image/png -o > %s%s'
|
|
|
|
|
|
|
|
" first `%s` is a base document name:
|
|
" (~/docs/hello-world.adoc => hello-world)
|
|
" second `%s` is a number of the image.
|
|
let g:asciidoctor_img_paste_pattern = 'img_%s_%s.png'
|
|
--------
|
|
|
|
If there is `:imagesdir:` as an option set up in a document, clipboard image
|
|
is saved there (relative to the document). Otherwise image is saved in the documents directory.
|
|
|
|
The name of the image is generated according to the pattern. By default it is
|
|
|
|
img_ + document_base_name + next_image_number + .png
|
|
|
|
|
|
== Bibliography completion
|
|
|
|
There is initial support for bibliography completion. Works with `*.bib` files
|
|
placed to the same folder as file being edited.
|
|
|
|
No setup is needed although additional setting for a base bibtex folder might
|
|
be added in the future.
|
|
|
|
It uses vim's `completefunc` which is usually called in insert mode with
|
|
kbd:[<C-X><C-U>], and it works for
|
|
|
|
[source]
|
|
----
|
|
cite:[<C-X><C-U>
|
|
cite:[cit<C-X><C-U>
|
|
citenp:[cit<C-X><C-U>
|
|
----
|
|
|
|
[NOTE]
|
|
======
|
|
To create bibliography in asciidoctor, i.e., to put it into PDF or HTML you
|
|
should install
|
|
https://github.com/asciidoctor/asciidoctor-bibtex[asciidoctor-bibtex]
|
|
extension and provide it to vim-asciidoctor extension list(s):
|
|
|
|
[source,vim]
|
|
" For asciidoctor backend
|
|
let g:asciidoctor_extensions = ['asciidoctor-bibtex']
|
|
" For asciidoctor-pdf backend
|
|
let g:asciidoctor_pdf_extensions = ['asciidoctor-bibtex']
|
|
|
|
======
|
|
|
|
|
|
== Misc
|
|
|
|
=== Generate HTML on file save
|
|
|
|
Add following snippet to your vim config to generate an HTML file upon saving:
|
|
[source,vim]
|
|
--------
|
|
augroup ON_ASCIIDOCTOR_SAVE | au!
|
|
au BufWritePost *.adoc :Asciidoctor2HTML
|
|
augroup end
|
|
--------
|
|
|
|
If you want to add text files to the mix you can have something similar to:
|
|
|
|
[source,vim]
|
|
--------
|
|
func! ConvertAsciidoctorToHTML()
|
|
" Text file with asciidoctor contents?
|
|
if &filetype == 'text' && getline(1) =~ '^= .*$'
|
|
" text files have no asciidoctor commands
|
|
set filetype=asciidoctor
|
|
Asciidoctor2HTML
|
|
set filetype=text
|
|
elseif &filetype == 'asciidoctor'
|
|
Asciidoctor2HTML
|
|
endif
|
|
endfunc
|
|
augroup ON_ASCIIDOCTOR_SAVE | au!
|
|
au BufWritePost *.adoc,*.txt call ConvertAsciidoctorToHTML()
|
|
augroup end
|
|
--------
|
|
|
|
NOTE: if you have link:https://github.com/tpope/vim-dispatch[vim-dispatch]
|
|
installed HTML conversion would be done in background.
|
|
|
|
|
|
=== Highlight group names
|
|
|
|
Colorschemes can use following highlight groups to redefine default highlighting:
|
|
|
|
[cols=".^1,.^1", options="header"]
|
|
|===
|
|
| Highlight Group Name
|
|
| Default Value
|
|
|
|
|asciidoctorTitle |Title
|
|
|asciidoctorSetextHeader |Title
|
|
|asciidoctorH1 |Title
|
|
|asciidoctorH2 |Title
|
|
|asciidoctorH3 |Title
|
|
|asciidoctorH4 |Title
|
|
|asciidoctorH5 |Title
|
|
|asciidoctorH6 |Title
|
|
|asciidoctorTitleDelimiter |Type
|
|
|asciidoctorH1Delimiter |Type
|
|
|asciidoctorH2Delimiter |Type
|
|
|asciidoctorH3Delimiter |Type
|
|
|asciidoctorH4Delimiter |Type
|
|
|asciidoctorH5Delimiter |Type
|
|
|asciidoctorH6Delimiter |Type
|
|
|asciidoctorSetextHeaderDelimiter |Type
|
|
|asciidoctorListMarker |Delimiter
|
|
|asciidoctorOrderedListMarker |asciidoctorListMarker
|
|
|asciidoctorListContinuation |PreProc
|
|
|asciidoctorComment |Comment
|
|
|asciidoctorIndented |Comment
|
|
|asciidoctorPlus |PreProc
|
|
|asciidoctorPageBreak |PreProc
|
|
|asciidoctorCallout |Float
|
|
|asciidoctorCalloutDesc |String
|
|
|asciidoctorListingBlock |Comment
|
|
|asciidoctorLiteralBlock |Comment
|
|
|asciidoctorFile |Underlined
|
|
|asciidoctorUrl |Underlined
|
|
|asciidoctorEmail |Underlined
|
|
|asciidoctorUrlAuto |Underlined
|
|
|asciidoctorEmailAuto |Underlined
|
|
|asciidoctorUrlDescription |String
|
|
|asciidoctorLink |Underlined
|
|
|asciidoctorAnchor |Underlined
|
|
|asciidoctorAttribute |Identifier
|
|
|asciidoctorCode |Constant
|
|
|asciidoctorOption |PreProc
|
|
|asciidoctorBlock |PreProc
|
|
|asciidoctorBlockOptions |PreProc
|
|
|asciidoctorTableSep |PreProc
|
|
|asciidoctorTableCell |PreProc
|
|
|asciidoctorTableEmbed |PreProc
|
|
|asciidoctorInlineAnchor |PreProc
|
|
|asciidoctorMacro |Macro
|
|
|asciidoctorIndexTerm |Macro
|
|
|asciidoctorBold |gui=bold cterm=bold
|
|
|asciidoctorItalic |gui=italic cterm=italic
|
|
|asciidoctorBoldItalic |gui=bold,italic cterm=bold,italic
|
|
|===
|
|
|
|
If you want to change highlight yourself for existing colorscheme without
|
|
touching it, add the following to you vimrc:
|
|
|
|
[source,vim]
|
|
--------
|
|
func! AsciidoctorHighlight()
|
|
" Highlight asciidoctor syntax with colors you like.
|
|
" For solarized8 colorscheme
|
|
if get(g:, "colors_name", "default") == "solarized8"
|
|
hi asciidoctorTitle guifg=#ff0000 gui=bold ctermfg=red cterm=bold
|
|
hi asciidoctorOption guifg=#00ff00 ctermfg=green
|
|
hi link asciidoctorH1 Directory
|
|
elseif get(g:, "colors_name", "default") == "default"
|
|
hi link asciidoctorIndented PreProc
|
|
endif
|
|
endfunc
|
|
augroup ASCIIDOCTOR_COLORS | au!
|
|
au Colorscheme * call AsciidoctorHighlight()
|
|
au BufNew,BufRead *.adoc call AsciidoctorHighlight()
|
|
augroup end
|
|
--------
|
|
|
|
|
|
== Limitations
|
|
|
|
=== Indented text is highlighted for all table cells
|
|
|
|
Works for all table cells, although should only be applied to `a|` cells.
|
|
|
|
[source]
|
|
--------
|
|
[cols=".^1,.^2", options="header"]
|
|
|===
|
|
| header1
|
|
| header1
|
|
|
|
| Regular table cell
|
|
|
|
Indented text is highlighted as indented
|
|
which is kind of incorrect
|
|
|
|
a| Asciidoctor cell
|
|
|
|
Indented text is highlighted as indented
|
|
which is correct
|
|
|
|
|===
|
|
--------
|
|
|
|
|
|
=== Setext-style headers highlighting
|
|
|
|
Proper setext-style highlighting should have equal numbers of underlined chars:
|
|
|
|
----
|
|
This Header level 1
|
|
===================
|
|
|
|
This Header level 2
|
|
-------------------
|
|
|
|
This Header level 3
|
|
~~~~~~~~~~~~~~~~~~~
|
|
|
|
This Header level 4
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
This Header level 5
|
|
+++++++++++++++++++
|
|
|
|
----
|
|
|
|
Vim can't do it so setext-style headers are highlighted no matter if there is
|
|
matched underline or not.
|
|
|
|
----
|
|
This Header level 1
|
|
======================
|
|
|
|
This Header level 2
|
|
-----
|
|
|
|
This Header level 3
|
|
~~~~~~~~~~~~~~~~
|
|
|
|
This Header level 4
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
This Header level 5
|
|
+++++++++++++
|
|
|
|
----
|
|
|
|
You can also use following mappings:
|
|
|
|
[source,vim]
|
|
--------
|
|
" Underline current line
|
|
func! s:underline(chars)
|
|
let nextnr = line('.') + 1
|
|
let underline = repeat(a:chars[0], strchars(getline('.')))
|
|
if index(a:chars, trim(getline(nextnr))[0]) != -1
|
|
call setline(nextnr, underline)
|
|
else
|
|
call append('.', underline)
|
|
endif
|
|
endfunc
|
|
nnoremap <leader>- :call <SID>underline(['-', '=', '~', '^', '+'])<CR>
|
|
nnoremap <leader>= :call <SID>underline(['=', '-', '~', '^', '+'])<CR>
|
|
nnoremap <leader>~ :call <SID>underline(['~', '=', '-', '^', '+'])<CR>
|
|
nnoremap <leader>^ :call <SID>underline(['^', '=', '-', '~', '+'])<CR>
|
|
nnoremap <leader>+ :call <SID>underline(['+', '=', '-', '~', '^'])<CR>
|
|
--------
|
|
|
|
|
|
=== URL Conceal
|
|
|
|
Links with additional attributes are not concealed to description:
|
|
|
|
https://discuss.asciidoctor.org[Discuss Asciidoctor,role=external,window=_blank]
|
|
https://discuss.asciidoctor.org[Discuss Asciidoctor^]
|
|
https://example.org["Google, Yahoo, Bing^",role=teal]
|
|
|
|
With `set conceallevel=3` looks like:
|
|
|
|
Discuss Asciidoctor,role=external,window=_blank
|
|
Discuss Asciidoctor^
|
|
"Google, Yahoo, Bing^",role=teal
|
|
|
|
Although it should look like:
|
|
|
|
Discuss Asciidoctor
|
|
Discuss Asciidoctor
|
|
Google, Yahoo, Bing
|