diff --git a/pack/acp/start/vim-asciidoctor/.gitignore b/pack/acp/start/vim-asciidoctor/.gitignore new file mode 100644 index 0000000..926ccaa --- /dev/null +++ b/pack/acp/start/vim-asciidoctor/.gitignore @@ -0,0 +1 @@ +doc/tags diff --git a/pack/acp/start/vim-asciidoctor/LICENSE b/pack/acp/start/vim-asciidoctor/LICENSE new file mode 100644 index 0000000..28a597a --- /dev/null +++ b/pack/acp/start/vim-asciidoctor/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Maxim Kim + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/pack/acp/start/vim-asciidoctor/README.adoc b/pack/acp/start/vim-asciidoctor/README.adoc new file mode 100644 index 0000000..2906c57 --- /dev/null +++ b/pack/acp/start/vim-asciidoctor/README.adoc @@ -0,0 +1,603 @@ += 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 oo :AsciidoctorOpenRAW + nnoremap op :AsciidoctorOpenPDF + nnoremap oh :AsciidoctorOpenHTML + nnoremap ox :AsciidoctorOpenDOCX + nnoremap ch :Asciidoctor2HTML + nnoremap cp :Asciidoctor2PDF + nnoremap cx :Asciidoctor2DOCX + nnoremap p :AsciidoctorPasteImage + " :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 +:Asciidoctor2HTML + +......... + +4. Open the `HTML` file: ++ +[literal] +......... + +:AsciidoctorOpenHTML + +......... + +// 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:[], and it works for + +[source] +---- +cite:[ +cite:[cit +citenp:[cit +---- + +[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 - :call underline(['-', '=', '~', '^', '+']) +nnoremap = :call underline(['=', '-', '~', '^', '+']) +nnoremap ~ :call underline(['~', '=', '-', '^', '+']) +nnoremap ^ :call underline(['^', '=', '-', '~', '+']) +nnoremap + :call underline(['+', '=', '-', '~', '^']) +-------- + + +=== 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 diff --git a/pack/acp/start/vim-asciidoctor/autoload/asciidoctor.vim b/pack/acp/start/vim-asciidoctor/autoload/asciidoctor.vim new file mode 100644 index 0000000..3756cdf --- /dev/null +++ b/pack/acp/start/vim-asciidoctor/autoload/asciidoctor.vim @@ -0,0 +1,391 @@ +" Maintainer: Maxim Kim (habamax@gmail.com) +" vim: et sw=4 + +if exists("g:loaded_asciidoctor_autoload") + finish +endif +let g:loaded_asciidoctor_autoload = 1 + + +"" Trim string +" Unfortunately built-in trim is not widely available yet +" return trimmed string +func! s:trim(str) abort + return substitute(a:str, '^\s*\|\s*$', '', 'g') +endfunc + +"" Return name of an image directory. +" +" It is either +" * '' (empty) +" * or value of :imagesdir: (stated at the top of the buffer, first 50 lines) +func! s:asciidoctorImagesDir() + let imagesdirs = filter(getline(1, 50), {k,v -> v =~ '^:imagesdir:.*'}) + if len(imagesdirs)>0 + return matchstr(imagesdirs[0], ':imagesdir:\s*\zs\f\+\ze$').'/' + else + return '' + endif +endfunc + +"" Return full path of an image +" +" It is 'current buffer path'/:imagesdir: +func! s:asciidoctorImagesPath() + return expand('%:p:h').'/'.s:asciidoctorImagesDir() +endfunc + +"" Return list of generated images for the current buffer. +" +" If buffer name is `document.adoc`, search in a given path for the file +" pattern `g:asciidoctor_img_paste_pattern`. +" +" Example: +" `img_document_1.png` +" `img_document_2.png` +func! s:asciidoctorListImages(path) + let rxpattern = '\V\[\\/]'.printf(g:asciidoctor_img_paste_pattern, expand('%:t:r'), '\d\+').'\$' + let images = globpath(a:path, '*.png', 1, 1) + return filter(images, {k,v -> v =~ rxpattern}) +endfunc + +"" Return index of the image file name +" +" `img_document_23.png` --> 23 +" `img_document.png` --> 0 +" `any other` --> 0 +func! s:asciidoctorExtractIndex(filename) + let rxpattern = '\V\[\\/]'.printf(g:asciidoctor_img_paste_pattern, expand('%:t:r'), '\zs\d\+\ze').'\$' + let index = matchstr(a:filename, rxpattern) + if index == '' + let index = '0' + endif + return str2nr(index) +endfunc + +"" Return new image name +" +" Having the list of images in a give path: +" `img_document_1.png` +" `img_document_2.png` +" ... +" Generate a new image name: +" `img_document_3.png +func! s:asciidoctorGenerateImageName(path) + let index = max(map(s:asciidoctorListImages(a:path), + \{k,v -> s:asciidoctorExtractIndex(v)})) + 1 + return printf(g:asciidoctor_img_paste_pattern, expand('%:t:r'), index) +endfunc + +"" Paste image from the clipboard. +" +" * Save image as png file to the :imagesdir: +" * Insert `image::link.png[]` at cursor position +func! asciidoctor#pasteImage() abort + let path = s:asciidoctorImagesPath() + if !isdirectory(path) + echoerr 'Image directory '.path.' doesn''t exist!' + return + endif + + let fname = s:asciidoctorGenerateImageName(path) + + let cmd = printf(g:asciidoctor_img_paste_command, path, fname) + + let res = system(cmd) + if v:shell_error + echohl Error | echomsg s:trim(res) | echohl None + return + endif + + let sav_reg_x = @x + let @x = printf('image::%s[]', fname) + put x + let @x = sav_reg_x +endfunc + + +"" Check header (20 lines) of the file for default source language +func! asciidoctor#detect_source_language() + for line in getline(1, 20) + let m = matchlist(line, '^:source-language: \(.*\)$') + if !empty(m) + let src_lang = s:trim(m[1]) + if src_lang != '' + let b:asciidoctor_source_language = s:trim(m[1]) + break + endif + endif + endfor +endfunc + +"" Refresh highlighting for default source language. +" +" Should be called on buffer write. +func! asciidoctor#refresh_source_language_hl() + let cur_b_source_language = get(b:, "asciidoctor_source_language", "NONE") + + call asciidoctor#detect_source_language() + + if cur_b_source_language != get(b:, "asciidoctor_source_language", "NONE") + syn enable + endif +endfunc + +"" Test bibliography completefunc +func! asciidoctor#complete_bibliography(findstart, base) + if a:findstart + let prefix = strpart(getline('.'), 0, col('.')-1) + let m = match(prefix, 'cite\%(np\)\?:\[\zs[[:alnum:]]*$') + if m != -1 + return m + else + return -3 + endif + else + " return filtered list of + " [{"word": "citation1", "menu": "article"}, {"word": "citation2", "menu": "book"}, ...] + " if "word" matches with a:base + return filter( + \ map(s:read_all_bibtex(), {_, val -> {'word': matchstr(val, '{\zs.\{-}\ze,'), 'menu': matchstr(val, '@\zs.\{-}\ze{')}}), + \ {_, val -> val['word'] =~ '^'.a:base.'.*'}) + endif +endfunc + +"" Read bibtex file +" +" Return list of citations +func! s:read_bibtex(file) + let citation_types = '@book\|@article\|@booklet\|@conference\|@inbook' + \.'\|@incollection\|@inproceedings\|@manual\|@mastersthesis' + \.'\|@misc\|@phdthesis\|@proceedings\|@techreport\|@unpublished' + let citations = filter(readfile(a:file), {_, val -> val =~ citation_types}) + + return citations +endfunc + +"" Read all bibtex files from a current file's path +" +" Return list of citations +func! s:read_all_bibtex() + let citations = [] + for bibfile in globpath(expand('%:p:h'), '*.bib', 0, 1) + call extend(citations, s:read_bibtex(bibfile)) + endfor + return citations +endfunc + + + +"" Check header (30 lines) of the file for theme name +" return theme name +func! asciidoctor#detect_pdf_theme() + let result = '' + for line in getline(1, 30) + let m = matchlist(line, '^:pdf-theme: \(.*\)$') + if !empty(m) + let result = s:trim(m[1]) + if result != '' + return result + endif + endif + endfor +endfunc + + +"" asciidoctor header text object +" * inner object is the text between prev section header(excluded) and the next +" section of the same level(excluded) or end of file. +" Except for `= Title`: text between title(excluded) and first `== Section`(excluded) or end of file. +" * an object is the text between prev section header(included) and the next section of the same +" level(excluded) or end of file. +" Except for `= Title`: text between title(included) and first `== Section`(excluded) or end of file. +func! asciidoctor#header_textobj(inner) abort + let lnum_start = search('^=\+\s\+[^[:space:]=]', "ncbW") + if lnum_start + let lvlheader = matchstr(getline(lnum_start), '^=\+') + let lnum_end = search('^=\{2,'..len(lvlheader)..'}\s', "nW") + if !lnum_end + let lnum_end = search('\%$', 'cnW') + else + let lnum_end -= 1 + endif + if a:inner && getline(lnum_start + 1) !~ '^=\+\s\+[^[:space:]=]' + let lnum_start += 1 + endif + + exe lnum_end + normal! V + exe lnum_start + endif +endfunc + + + +"" asciidoctor delimited block text object +" * inner object is the text between delimiters +" * an object is the text between between delimiters plus delimiters included. +func! asciidoctor#delimited_block_textobj(inner) abort + let lnum_start = search('^\(\(-\{2,}\)\|\(=\{4,}\)\|\(_\{4,}\)\|\(\*\{4,}\)\|\(\.\{4,}\)\)\s*$', "ncbW") + if lnum_start + let delim = getline(lnum_start) + let lnum_end = search('^'..delim[0]..'\{'..len(delim)..'}\s*$', "nW") + if lnum_end + if a:inner + let lnum_start += 1 + let lnum_end -= 1 + endif + exe lnum_end + normal! V + exe lnum_start + endif + endif +endfunc + + + +"" Return Windows path from WSL +func! s:wsl_to_windows_path(path) abort + if !exists("$WSLENV") + return a:path + endif + + if !executable('wslpath') + return a:path + endif + + let res = systemlist('wslpath -w ' . a:path) + if !empty(res) + return res[0] + else + return a:path + endif +endfunc + + +func! asciidoctor#open_file(filename) + if filereadable(a:filename) + if exists("$WSLENV") + exe g:asciidoctor_opener . ' ' + \ . shellescape(s:wsl_to_windows_path(a:filename)) + else + exe g:asciidoctor_opener . ' ' . shellescape(a:filename) + endif + else + echom a:filename . " doesn't exist!" + endif +endfunc + + +"" to open URLs/files with gx/gf mappings +func! asciidoctor#open_url(...) abort + let cmd = get(a:, 1, g:asciidoctor_opener) + + " by default check WORD under cursor + let word = expand("") + + " But if cursor is surrounded by [ ], like for http://ya.ru[yandex search] + " take a cWORD from first char before [ + let save_cursor = getcurpos() + let line = getline('.') + if searchpair('\[', '', '\]', 'b', '', line('.')) + let word = expand("") + endif + call setpos('.', save_cursor) + + " Check asciidoc URL http://bla-bla.com[desc + let aURL = matchstr(word, '\%(\%(http\|ftp\|irc\)s\?\|file\)://\S\+\ze\[') + if aURL != "" + exe cmd . ' "' . escape(aURL, '#%!') . '"' + return + endif + + " Check asciidoc link link:file.txt[desc + let aLNK = matchstr(word, 'link:/*\zs\S\+\ze\[') + if aLNK != "" + execute "lcd ". expand("%:p:h") + exe cmd . ' ' . fnameescape(fnamemodify(aLNK, ":p")) + lcd - + return + endif + + " Check asciidoc URL http://bla-bla.com + let URL = matchstr(word, '\%(\%(http\|ftp\|irc\)s\?\|file\)://\S\+') + if URL != "" + exe cmd . ' "' . escape(URL, '#%!') . '"' + return + endif + + " probably path? + if word =~ '^[~.$].*' + exe cmd . ' ' . expand(word) + return + endif + + try + exe "normal! gf" + catch /E447/ + echohl Error + echomsg matchstr(v:exception, 'Vim(normal):\zs.*$') + echohl None + endtry +endfunc + + +"" Promote sections including subsections +"" * Doesn't check for the real syntax sections (might fail with "pseudo" sections +"" embedded into source blocks) +"" * Doesn't work for underlined sections. +func! asciidoctor#promote_section() abort + let save = winsaveview() + try + if search('^=\+\s\+\S', 'cbW') + let lvl = len(matchstr(getline('.'), '^=\+')) + if lvl > 5 + return + endif + let next_lvl = lvl + 1 + while lvl < next_lvl + call setline('.', '='..getline('.')) + if search('^=\{'..(lvl + 1)..',}\s\+\S', 'W') + let next_lvl = len(matchstr(getline('.'), '^=\+')) + else + break + endif + endwhile + endif + finally + call winrestview(save) + endtry +endfunc + + +"" Demote sections including subsections +"" * Doesn't check for the real syntax sections (might fail with "pseudo" sections +"" embedded into source blocks) +"" * Doesn't work for underlined sections. +func! asciidoctor#demote_section() abort + let save = winsaveview() + try + if search('^=\+\s\+\S', 'cbW') + let lvl = len(matchstr(getline('.'), '^=\+')) + let parent_section = search('^=\{1,'..max([(lvl - 1), 1])..'}\s\+\S', 'nbW') + let parent_lvl = len(matchstr(getline(parent_section), '^=\+')) + let next_lvl = lvl + 1 + while lvl < next_lvl && (lvl > parent_lvl+1) + if lvl == 1 + break + else + call setline('.', getline('.')[1:]) + endif + if search('^=\{'..(lvl + 1)..',}\s\+\S', 'W') + let next_lvl = len(matchstr(getline('.'), '^=\+')) + else + break + endif + endwhile + endif + finally + call winrestview(save) + endtry +endfunc diff --git a/pack/acp/start/vim-asciidoctor/compiler/asciidoctor2docx.vim b/pack/acp/start/vim-asciidoctor/compiler/asciidoctor2docx.vim new file mode 100644 index 0000000..e707d8e --- /dev/null +++ b/pack/acp/start/vim-asciidoctor/compiler/asciidoctor2docx.vim @@ -0,0 +1,74 @@ +" Vim compiler file +" Compiler: Asciidoctor 2 DOCX using docbook intermediate format and pandoc +" Maintainer: Maxim Kim (habamax@gmail.com) +" vim: et sw=4 + +if exists("current_compiler") + finish +endif +let current_compiler = "Asciidoctor2DOCX" +let s:keepcpo= &cpo +set cpo&vim + +if get(g:, 'asciidoctor_extensions', []) == [] + let s:extensions = "" +else + let s:extensions = "-r ".join(g:asciidoctor_extensions, ' -r ') +endif + +let s:asciidoctor_executable = get(g:, 'asciidoctor_executable', 'asciidoctor') + +let s:asciidoctor_pandoc_executable = get(g:, 'asciidoctor_pandoc_executable', 'pandoc') + +let s:asciidoctor_pandoc_data_dir = get(g:, 'asciidoctor_pandoc_data_dir', '') +if s:asciidoctor_pandoc_data_dir != '' + let data_dir_param = " --data-dir=" . shellescape(fnamemodify(s:asciidoctor_pandoc_data_dir, ':p:h')) +else + let data_dir_param = '' +endif + +let s:asciidoctor_pandoc_reference_doc = get(g:, 'asciidoctor_pandoc_reference_doc', '') +if s:asciidoctor_pandoc_reference_doc != '' + let reference_doc_param = ' --reference-doc=' . s:asciidoctor_pandoc_reference_doc +else + " search for the theme name in first 30 lines of the file + " generate reference doc name as `data-dir path + theme-reference.docx` + " test if file exists and set the name, empty string otherwise + let theme_name = asciidoctor#detect_pdf_theme() + let file_name = theme_name . '-reference.docx' + let full_path = expand(s:asciidoctor_pandoc_data_dir . '/' . file_name, 1) + + if glob(full_path, 1) != '' + let reference_doc_param = ' --reference-doc=' . shellescape(full_path) + else + let reference_doc_param = '' + endif + +endif + +let s:asciidoctor_pandoc_other_params = get(g:, 'asciidoctor_pandoc_other_params', '') +if s:asciidoctor_pandoc_other_params != '' + let other_params = ' ' . s:asciidoctor_pandoc_other_params +else + let other_params = '' +endif + +let s:make_docbook = s:asciidoctor_executable . " " . s:extensions + \. " -a docdate=" . strftime("%Y-%m-%d") + \. " -a doctime=" . strftime("%T") + \. " -b docbook" + \. " " . shellescape(expand("%:p")) + +let s:make_docx = s:asciidoctor_pandoc_executable + \. other_params + \. data_dir_param + \. reference_doc_param + \. " -f docbook -t docx" + \. " -o " . shellescape(expand("%:p:r") . ".docx") + \. " " . shellescape(expand("%:p:r") . ".xml") + +let s:cd = "cd ".shellescape(expand("%:p:h")) +let &l:makeprg = s:make_docbook . " && " . s:cd ." && ". s:make_docx + +let &cpo = s:keepcpo +unlet s:keepcpo diff --git a/pack/acp/start/vim-asciidoctor/compiler/asciidoctor2html.vim b/pack/acp/start/vim-asciidoctor/compiler/asciidoctor2html.vim new file mode 100644 index 0000000..d7859a8 --- /dev/null +++ b/pack/acp/start/vim-asciidoctor/compiler/asciidoctor2html.vim @@ -0,0 +1,43 @@ +" Vim compiler file +" Compiler: Asciidoctor2HTML +" Maintainer: Maxim Kim (habamax@gmail.com) +" vim: et sw=4 + +if exists("current_compiler") + finish +endif +let current_compiler = "Asciidoctor2HTML" +let s:keepcpo= &cpo +set cpo&vim + +if get(g:, 'asciidoctor_extensions', []) == [] + let s:extensions = "" +else + let s:extensions = "-r ".join(g:asciidoctor_extensions, ' -r ') +endif + +if get(g:, 'asciidoctor_css_path', '') == '' + let s:css_path = "" +else + let s:css_path = '-a stylesdir='.shellescape(fnamemodify(g:asciidoctor_css_path, ":p:h")) +endif + +if get(g:, 'asciidoctor_css', '') == '' + let s:css_name = "" +else + let s:css_name = '-a stylesheet='.shellescape(g:asciidoctor_css) +endif + +let s:asciidoctor_executable = get(g:, 'asciidoctor_executable', 'asciidoctor') + +let s:filename = shellescape(get(g:, 'asciidoctor_use_fullpath', v:true) ? expand("%:p") : expand("%:t")) + +let &l:makeprg = s:asciidoctor_executable . " " . s:extensions + \. " -a docdate=".strftime("%Y-%m-%d") + \. " -a doctime=".strftime("%T") . " " + \. s:css_path . " " + \. s:css_name . " " + \. s:filename + +let &cpo = s:keepcpo +unlet s:keepcpo diff --git a/pack/acp/start/vim-asciidoctor/compiler/asciidoctor2pdf.vim b/pack/acp/start/vim-asciidoctor/compiler/asciidoctor2pdf.vim new file mode 100644 index 0000000..a5c7cf6 --- /dev/null +++ b/pack/acp/start/vim-asciidoctor/compiler/asciidoctor2pdf.vim @@ -0,0 +1,57 @@ +" Vim compiler file +" Compiler: Asciidoctor2PDF +" Maintainer: Maxim Kim (habamax@gmail.com) +" vim: et sw=4 + +if exists("current_compiler") + finish +endif +let current_compiler = "Asciidoctor2PDF" +let s:keepcpo= &cpo +set cpo&vim + +"" check first non-empty lines of the asciidoctor buffer if theme +"" is set up in file options +"" if not, don't provide themes and styles path to compiler to avoid errors +let s:use_pdf_paths = 0 +for line in getline(1, 50) + if line =~ "^\s*$" + break + endif + if line =~ "^:pdf-theme:.*$" + let s:use_pdf_paths = 1 + break + endif +endfor + +if get(g:, 'asciidoctor_pdf_themes_path', '') == '' || !get(s:, 'use_pdf_paths', 0) + let s:pdf_themes_path = "" +else + let s:pdf_themes_path = '-a pdf-themesdir='.shellescape(fnamemodify(g:asciidoctor_pdf_themes_path, ':p:h')) +endif + +if get(g:, 'asciidoctor_pdf_fonts_path', '') == '' || !get(s:, 'use_pdf_paths', 0) + let s:pdf_fonts_path = "" +else + let s:pdf_fonts_path = '-a pdf-fontsdir='.shellescape(fnamemodify(g:asciidoctor_pdf_fonts_path, ':p:h')) +endif + +if get(g:, 'asciidoctor_pdf_extensions', []) == [] + let s:extensions = "" +else + let s:extensions = "-r ".join(g:asciidoctor_pdf_extensions, ' -r ') +endif + +let s:asciidoctor_pdf_executable = get(g:, 'asciidoctor_pdf_executable', 'asciidoctor-pdf') + +let s:filename = shellescape(get(g:, 'asciidoctor_use_fullpath', v:true) ? expand("%:p") : expand("%:t")) + +let &l:makeprg = s:asciidoctor_pdf_executable . " " . s:extensions + \. " -a docdate=" . strftime("%Y-%m-%d") + \. " -a doctime=" . strftime("%H:%M:%S") . " " + \. s:pdf_themes_path . " " + \. s:pdf_fonts_path . " " + \. s:filename + +let &cpo = s:keepcpo +unlet s:keepcpo diff --git a/pack/acp/start/vim-asciidoctor/doc/asciidoctor.txt b/pack/acp/start/vim-asciidoctor/doc/asciidoctor.txt new file mode 100644 index 0000000..bdb1669 --- /dev/null +++ b/pack/acp/start/vim-asciidoctor/doc/asciidoctor.txt @@ -0,0 +1,462 @@ +*asciidoctor.txt* Vim :heart: Asciidoctor + +Author: Maxim Kim +URL: https://github.com/habamax/vim-asciidoctor +License: MIT + + +INTRODUCTION *asciidoctor* + + +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). + + +SETTINGS *asciidoctor-settings* + +It should work out of the box (at least it was the intention). But sometimes +one needs settings to set. + + +*g:asciidoctor_executable* What to use for HTML. + Default: asciidoctor + Example: > + + let g:asciidoctor_executable = '~/projects/asciidoctor/bin/asciidoctor' + + +*g:asciidoctor_extensions* What extensions to use with HTML. + Default: [] + Example: > + + let g:asciidoctor_extensions = ['asciidoctor-diagram', 'asciidoctor-rouge'] + + +*g:asciidoctor_css_path* Path to custom CSS to use with HTML. + Default: '' + Example: > + + let g:asciidoctor_css_path = '~/docs/ascidoctor-themes/' + + +*g:asciidoctor_css* Custom CSS file name to use with HTML. + Default: '' + Example: > + + let g:asciidoctor_css = 'mytheme.css' + + +*g:asciidoctor_pdf_executable* What to use for PDF. + Default: asciidoctor-pdf + Example: > + + let g:asciidoctor_pdf_executable = '~/asciidoctor-pdf/bin/asciidoctor-pdf' + + +*g:asciidoctor_use_fullpath* Use full path when pass a file for a + compilation. + Default: v:true + Example: > + + let g:asciidoctor_use_fullpath = v:false + +Might be useful if for some reason file passed for a compilation should not +have full path. For example asciidoctor-pdf in docker might use the following +setup to be able to create PDFs: > + + let g:asciidoctor_pdf_executable = 'docker run --rm -v $(pwd):/documents/ asciidoctor/docker-asciidoctor asciidoctor-pdf' + +Note that you might need to have proper current working directory. +Available for |:Asciidoctor2HTML| and |:Asciidoctor2PDF| commands only. + + +*g:asciidoctor_pdf_extensions* What extensions to use with PDF. + Default: [] + Example: > + + let g:asciidoctor_pdf_extensions = ['asciidoctor-diagram'] + + +*g:asciidoctor_pdf_themes_path* Path to custom themes. + Default: '' + Example: > + + let g:asciidoctor_pdf_themes_path = '~/docs/ascidoctor-themes/' + + +*g:asciidoctor_pdf_fonts_path* Path to fonts used in themes. + Default: '' + Example: > + + let g:asciidoctor_pdf_fonts_path = '~/docs/fonts/' + + +*g:asciidoctor_pandoc_executable* What to use for DOCX. The process is to + convert ADOC to DOCBOOK with + |g:asciidoctor_executable| and then + DOCBOOK to DOCX with pandoc. + Default: 'pandoc' + Example: > + + let g:asciidoctor_pandoc_executable = '~/bin/pandoc' + + +*g:asciidoctor_pandoc_data_dir* Set --data-dir for pandoc. + Default: '' + Example: > + + let g:asciidoctor_pandoc_data_dir = '~/docs/.pandoc' + + +*g:asciidoctor_pandoc_reference_doc* Set --reference-doc for pandoc. + What docx file to use as a reference + document (use styles defined there) + Default: '' + Example: > + + let g:asciidoctor_pandoc_referenc_doc = 'custom-reference.docx' + + +*g:asciidoctor_pandoc_other_params* Set additional parameteres for pandoc. + Default: '' + Example: > + + let g:asciidoctor_pandoc_other_params = '--toc' + + +*g:asciidoctor_folding* Fold sections (headers). + Default: 0 + Example: > + + let g:asciidoctor_folding = 1 + +if enabled all sections would be foldable. Title has the same fold level as +sections level 1, higher level sections would have higher fold level (folded +under section level-1): > + + = Title + == Section 1 + === Section 2 + === Section 2 + == Section 1 + +When folded: > + + = Title ----------------------------------- + == Section 1 ------------------------------ + == Section 1 ------------------------------ + + +*g:asciidoctor_foldnested* Fold nested sections. + Default: 1 + Example: > + + let g:asciidoctor_foldnested = 0 + +if disabled all sections would have the same foldlevel (=1) no matter what +section level is. + +Then > + + = Title + hello world + == Section 1 + hello world + === Section 2 + hello world + === Section 2 + hello world + == Section 1 + hello world + +Would be folded to: > + + = Title ----------------------------------- + == Section 1 ------------------------------ + === Section 2 ----------------------------- + === Section 2 ----------------------------- + == Section 1 ------------------------------ + + +*g:asciidoctor_foldtitle_as_h1* Fold title as level 1 sections. + Default: 1 + + Example: > + + let g:asciidoctor_foldtitle_as_h1 = 0 + +When on, following > + + = Title + hello world + == Section 1 + hello world + === Section 2 + hello world + +would be folded to: > + + = Title ----------------------------------- + == Section 1 ------------------------------ + +Otherwise to > + + = Title ----------------------------------- + + +*g:asciidoctor_syntax_indented* Enable highlight for indented blocks. + Default: 1 + Example: > + + let g:asciidoctor_syntax_indented = 0 + + +*g:asciidoctor_syntax_conceal* Enable concealable syntax. + Currently only bold, italic, bolditaclic, + code and links are concealed. + Default: 0 + Example: > + + let g:asciidoctor_syntax_conceal = 1 + +NOTE: It doesn't automatically set conceallevel. + + +*g:asciidoctor_fold_options* Fold options (usually under the title). + Default: 0 + Example: > + + let g:asciidoctor_fold_options = 1 + +if enabled asciidoctor options would be foldable: > + + = Title + :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 + +When folded: > + + = Title + :author: Maxim Kim ------------------------ + + +*g:asciidoctor_fenced_languages* Highlight syntax of source blocks + Default: [] + Example: > + + let g:asciidoctor_fenced_languages = ['python', 'c', 'javascript'] + +Then in your asciidoctor document: > + + [source,python] + ---- + def hello(): + print("hello world") + ---- + +should be highlighted with python syntax. + + +*g:asciidoctor_img_paste_command* Command to save clipboard image to a + file. + Default: 'gm convert clipboard: %s%s' + Where first %s is a path, second %s is an + image file name. + Example: > + + " 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' + + +*g:asciidoctor_img_paste_pattern* Pattern of the saved clipboard image file. + Default: 'img_%s_%s.png' + Where first %s is a document base name, + second %s is an image number. + Example: > + + let g:asciidoctor_img_paste_pattern = '%s_img_%s.png' + +So if you edit 'README.adoc` document and paste a clipboard image there it +would have name 'README_img_1.png'. Next one would have name +'README_img_2.png' etc. + + +*g:asciidoctor_opener* Shell command to open asciidoctor files. + Used in |:AsciidoctorOpenRAW|, + |:AsciidoctorOpenPDF|, + |:AsciidoctorOpenHTML| and + |:AsciidoctorOpenDOCX| commands. + Default Windows: ':!start' + Default Linux: ':!xdg-open' + Default OSX: ':!open' + Example: > + + let g:asciidoctor_opener = ':!firefox' + + + + +COMMANDS *asciidoctor-commands* + +These commands are local to the asciidoctor buffers. + + + *:Asciidoctor2HTML* +:Asciidoctor2HTML Convert current file to HTML. + Uses |g:asciidoctor_executable|. + + + *:Asciidoctor2PDF* +:Asciidoctor2PDF Convert current file to PDF. + Uses |g:asciidoctor_pdf_executable|. + + + *:Asciidoctor2DOCX* +:Asciidoctor2DOCX Convert current file to DOCX. + Uses combination of |g:asciidoctor_executable| to + generate docbook file and + |g:asciidoctor_pandoc_executable| to generate + result DOCX file. + + + *:AsciidoctorOpenRAW* +:AsciidoctorOpenRAW Open current file in Web browser. Chrome and + Firefox have extension to render barebone .adoc + files. Uses |g:asciidoctor_opener|. + + + *:AsciidoctorOpenHTML* +:AsciidoctorOpenHTML Open HTML file of the current file. It should exist + (created first with |:Asciidoctor2HTML| command). + Uses |g:asciidoctor_opener|. + + + *:AsciidoctorOpenPDF* +:AsciidoctorOpenPDF Open PDF file of the current file. It should exist + (created first with |:Asciidoctor2PDF| command). + Uses |g:asciidoctor_opener|. + + + *:AsciidoctorOpenDOCX* +:AsciidoctorOpenDOCX Open DOCX file of the current file. It should exist + (created first with |:Asciidoctor2DOCX| command). + Uses |g:asciidoctor_opener|. + + + *:AsciidoctorPasteImage* +:AsciidoctorPasteImage "Paste" image from clipboard into buffer. + 1. Image file name is generated according to + |g:asciidoctor_img_paste_pattern|. + 2. Clipboard image is saved in :imagesdir: + directory (asciidoctor option defined in a + document) or in the directory of the buffer. + 3. Image file name is inserted into the buffer. + 4. External dependency should be set up, see + |g:asciidoctor_img_paste_command|. + + + +MAPPINGS *asciidoctor-mappings* + +*(AsciidoctorFold)* Fold sections in a special way. + +If +* no count is provided, toggle current fold; +* count is n, open folds up to foldlevel n. + + +*(AsciidoctorPromoteSection)* Promote section including subsections. + +This > + + = Title + [cursor] + == Section 1 + === Section 2 + == Section 3 + +Would become > + + == Title + [cursor] + === Section 1 + ==== Section 2 + === Section 3 + +*(AsciidoctorDemoteSection)* Demote section including subsections. + +This > + + == Title + [cursor] + === Section 1 + ==== Section 2 + === Section 3 + +Would become > + + = Title + [cursor] + == Section 1 + === Section 2 + == Section 3 + + + +DEFAULT MAPPINGS + +There are no default mappings. You can setup yours with: > + + + " Function to create buffer local mappings + fun! AsciidoctorMappings() + nnoremap oo :AsciidoctorOpenRAW + nnoremap op :AsciidoctorOpenPDF + nnoremap oh :AsciidoctorOpenHTML + nnoremap ox :AsciidoctorOpenDOCX + nnoremap ch :Asciidoctor2HTML + nnoremap cp :Asciidoctor2PDF + nnoremap cx :Asciidoctor2DOCX + nmap (AsciidoctorFold) + endfun + + " Call AsciidoctorMappings for all `*.adoc` and `*.asciidoc` files + augroup asciidoctor + au! + au BufEnter *.adoc,*.asciidoc call AsciidoctorMappings() + augroup END + + +BIBLIOGRAPHY COMPLETION *asciidoctor-completion* + +There is initial support for bibtex citation added. + +Usage: + +Place your bibtex files next to your asciidoctor file (to the same path). Then +completion would be available for: > + + cite:[cit + citenp:[cit + + + vim:tw=78:et:ft=help:norl: diff --git a/pack/acp/start/vim-asciidoctor/ftdetect/asciidoctor.vim b/pack/acp/start/vim-asciidoctor/ftdetect/asciidoctor.vim new file mode 100644 index 0000000..32afa43 --- /dev/null +++ b/pack/acp/start/vim-asciidoctor/ftdetect/asciidoctor.vim @@ -0,0 +1 @@ +autocmd BufNewFile,BufRead *.adoc,*.asciidoc set ft=asciidoctor diff --git a/pack/acp/start/vim-asciidoctor/ftplugin/asciidoctor.vim b/pack/acp/start/vim-asciidoctor/ftplugin/asciidoctor.vim new file mode 100644 index 0000000..55e1f99 --- /dev/null +++ b/pack/acp/start/vim-asciidoctor/ftplugin/asciidoctor.vim @@ -0,0 +1,305 @@ +" Vim filetype plugin +" Language: asciidoctor +" Maintainer: Maxim Kim +" Filenames: *.adoc +" vim: et sw=4 + +if exists("b:did_ftplugin") + finish +endif +let b:did_ftplugin = 1 + +let s:undo_opts = "setl cms< com< fo< flp< inex< efm< cfu< fde< fdm<" +let s:undo_cmds = "| delcommand Asciidoctor2PDF" + \. "| delcommand Asciidoctor2HTML" + \. "| delcommand Asciidoctor2DOCX" + \. "| delcommand AsciidoctorOpenRAW" + \. "| delcommand AsciidoctorOpenPDF" + \. "| delcommand AsciidoctorOpenHTML" + \. "| delcommand AsciidoctorOpenDOCX" + \. "| delcommand AsciidoctorPasteImage" +let s:undo_maps = "| execute 'nunmap ]]'" + \. "| execute 'nunmap [['" + \. "| execute 'xunmap ]]'" + \. "| execute 'xunmap [['" + \. "| execute 'ounmap ih'" + \. "| execute 'ounmap ah'" + \. "| execute 'xunmap ih'" + \. "| execute 'xunmap ah'" + \. "| execute 'ounmap il'" + \. "| execute 'ounmap al'" + \. "| execute 'xunmap il'" + \. "| execute 'xunmap al'" + \. "| execute 'nunmap gx'" + \. "| execute 'nunmap gf'" + \. "| execute 'nunmap (AsciidoctorFold)'" + \. "| execute 'nunmap (AsciidoctorSectionPromote)'" + \. "| execute 'nunmap (AsciidoctorSectionDemote)'" +let s:undo_vars = "| unlet! b:commentary_startofline" + +if exists('b:undo_ftplugin') + let b:undo_ftplugin .= "|" . s:undo_opts . s:undo_cmds . s:undo_maps . s:undo_vars +else + let b:undo_ftplugin = s:undo_opts . s:undo_cmds . s:undo_maps . s:undo_vars +endif + + +" see https://github.com/asciidoctor/asciidoctor-pdf/issues/1273 +setlocal errorformat=asciidoctor:\ ERROR:\ %f:\ line\ %l:\ %m + +" gf to open include::file.ext[] and link:file.ext[] files +setlocal includeexpr=substitute(v:fname,'\\(link:\\\|include::\\)\\(.\\{-}\\)\\[.*','\\2','g') +setlocal comments= +setlocal commentstring=//\ %s +" vim-commentary plugin setup +let b:commentary_startofline = 1 + +setlocal formatoptions+=cqn +setlocal formatlistpat=^\\s* +setlocal formatlistpat+=[ +setlocal formatlistpat+=\\[({]\\? +setlocal formatlistpat+=\\( +setlocal formatlistpat+=[0-9]\\+ +setlocal formatlistpat+=\\\| +setlocal formatlistpat+=[a-zA-Z] +setlocal formatlistpat+=\\) +setlocal formatlistpat+=[\\]:.)} +setlocal formatlistpat+=] +setlocal formatlistpat+=\\s\\+ +setlocal formatlistpat+=\\\| +setlocal formatlistpat+=^\\s*-\\s\\+ +setlocal formatlistpat+=\\\| +setlocal formatlistpat+=^\\s*[*]\\+\\s\\+ +setlocal formatlistpat+=\\\| +setlocal formatlistpat+=^\\s*[.]\\+\\s\\+ + +setlocal completefunc=asciidoctor#complete_bibliography + + +""" +""" Commands +""" +" Use vim-dispatch if available +if exists(':Make') == 2 + let s:make = ':Make' +else + let s:make = ':make' +endif + +exe 'command! -buffer Asciidoctor2PDF :compiler asciidoctor2pdf | ' . s:make +exe 'command! -buffer Asciidoctor2HTML :compiler asciidoctor2html | ' . s:make +exe 'command! -buffer Asciidoctor2DOCX :compiler asciidoctor2docx | ' . s:make + +command! -buffer AsciidoctorOpenRAW call asciidoctor#open_file(s:get_fname()) +command! -buffer AsciidoctorOpenPDF call asciidoctor#open_file(s:get_fname(".pdf")) +command! -buffer AsciidoctorOpenHTML call asciidoctor#open_file(s:get_fname(".html")) +command! -buffer AsciidoctorOpenDOCX call asciidoctor#open_file(s:get_fname(".docx")) + +command! -buffer AsciidoctorPasteImage :call asciidoctor#pasteImage() + + + +""" +""" Mappings +""" +nnoremap ]] :call section(0, v:count1) +nnoremap [[ :call section(1, v:count1) +xmap ]] "\".v:count1.']]m>gv' +xmap [[ "\".v:count1.'[[m>gv' + +"" header textobject +onoremap ih :call asciidoctor#header_textobj(v:true) +onoremap ah :call asciidoctor#header_textobj(v:false) +xnoremap ih :call asciidoctor#header_textobj(v:true) +xnoremap ah :call asciidoctor#header_textobj(v:false) + +"" delimited bLock textobject +onoremap il :call asciidoctor#delimited_block_textobj(v:true) +onoremap al :call asciidoctor#delimited_block_textobj(v:false) +xnoremap il :call asciidoctor#delimited_block_textobj(v:true) +xnoremap al :call asciidoctor#delimited_block_textobj(v:false) + +nnoremap gx :call asciidoctor#open_url() +nnoremap gf :call asciidoctor#open_url("edit") + +"" Useful with +"" let g:asciidoctor_folding = 1 +"" let g:asciidoctor_foldnested = 0 +"" let g:asciidoctor_foldtitle_as_h1 = 1 +"" Fold up to count foldlevel in a special way: +"" * no count is provided, toggle current fold; +"" * count is n, open folds of up to foldlevel n. +func! s:asciidoctor_fold(count) abort + if !get(g:, 'asciidoctor_folding', 0) + return + endif + if a:count == 0 + normal! za + else + let &foldlevel = a:count + endif +endfunc + +"" fold up to v:count foldlevel in a special way +nnoremap (AsciidoctorFold) :call asciidoctor_fold(v:count) + +"" promote/demote sections +nnoremap (AsciidoctorSectionPromote) :call asciidoctor#promote_section() +nnoremap (AsciidoctorSectionDemote) :call asciidoctor#demote_section() + + + +""" +""" Global options processing +""" +if get(g:, 'asciidoctor_opener', '') == '' + if has("win32") || has("win32unix") + if has("nvim") + let g:asciidoctor_opener = ':silent !start ""' + else + let g:asciidoctor_opener = ':silent !start' + endif + elseif has("osx") + let g:asciidoctor_opener = ":!open" + elseif exists("$WSLENV") + let g:asciidoctor_opener = ":silent !cmd.exe /C start" + else + let g:asciidoctor_opener = ":!xdg-open" + endif +endif + + +if has("folding") && get(g:, 'asciidoctor_folding', 0) + function! AsciidoctorFold() "{{{ + let line = getline(v:lnum) + + if (v:lnum == 1) && (line =~ '^----*$') + return ">1" + endif + + let nested = get(g:, "asciidoctor_foldnested", v:true) + + " Regular headers + let depth = match(line, '\(^=\+\)\@<=\( .*$\)\@=') + + " Do not fold nested regular headers + if depth > 1 && !nested + let depth = 1 + endif + + " Setext style headings + if depth < 0 + let prevline = getline(v:lnum - 1) + let nextline = getline(v:lnum + 1) + + if (line =~ '^.\+$') && (nextline =~ '^=\+$') && (prevline =~ '^\s*$') + let depth = nested ? 2 : 1 + endif + + if (line =~ '^.\+$') && (nextline =~ '^-\+$') && (prevline =~ '^\s*$') + let depth = nested ? 3 : 1 + endif + + if (line =~ '^.\+$') && (nextline =~ '^\~\+$') && (prevline =~ '^\s*$') + let depth = nested ? 4 : 1 + endif + + if (line =~ '^.\+$') && (nextline =~ '^^\+$') && (prevline =~ '^\s*$') + let depth = nested ? 5 : 1 + endif + + if (line =~ '^.\+$') && (nextline =~ '^+\+$') && (prevline =~ '^\s*$') + let depth = nested ? 5 : 1 + endif + endif + + + if depth > 0 + " fold all sections under title + if depth > 1 && get(g:, "asciidoctor_foldtitle_as_h1", v:true) + let depth -= 1 + endif + " check syntax, it should be asciidoctorTitle or asciidoctorH + let syncode = synstack(v:lnum, 1) + if len(syncode) > 0 && synIDattr(syncode[0], 'name') =~ 'asciidoctor\%(H[1-6]\)\|Title\|SetextHeader' + return ">" . depth + endif + endif + + " Fold options + if s:asciidoctor_fold_options + let opt_regex = '^:[[:alnum:]-!]\{-}:.*$' + if (line =~ opt_regex) + let prevline = getline(v:lnum - 1) + let nextline = getline(v:lnum + 1) + if (prevline !~ opt_regex) && (nextline =~ opt_regex) + return "a1" + endif + if (nextline !~ opt_regex) && (prevline =~ opt_regex) + return "s1" + endif + endif + endif + + return "=" + endfunction "}}} + + setlocal foldexpr=AsciidoctorFold() + setlocal foldmethod=expr + let s:asciidoctor_fold_options = get(g:, 'asciidoctor_fold_options', 0) +endif + + +if get(g:, 'asciidoctor_img_paste_command', '') == '' + " first `%s` is a path + " second `%s` is an image file name + if has('win32') + let g:asciidoctor_img_paste_command = 'gm convert clipboard: %s%s' + elseif has('osx') + let g:asciidoctor_img_paste_command = 'pngpaste %s%s' + else " there is probably a better tool for linux? + let g:asciidoctor_img_paste_command = 'gm convert clipboard: %s%s' + endif +endif + + +if get(g:, 'asciidoctor_img_paste_pattern', '') == '' + " 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' +endif + + + +""" +""" Detect default source code language +""" +call asciidoctor#detect_source_language() + +augroup asciidoctor_source_language + au! + au bufwrite *.adoc,*.asciidoc call asciidoctor#refresh_source_language_hl() +augroup END + + + +""" +""" Helper functions +""" +func! s:get_fname(...) + let ext = get(a:, 1, '') + if ext == '' + return expand("%") + else + return expand("%:r").ext + endif +endfunc + + +"" Next/Previous section mappings +func! s:section(back, cnt) + for n in range(a:cnt) + call search('^=\+\s\+\S\+\|\_^\%(\n\|\%^\)\@<=\k.*\n\%(==\+\|\-\-\+\|\~\~\+\|\^\^\+\|++\+\)$', a:back ? 'bW' : 'W') + endfor +endfunc diff --git a/pack/acp/start/vim-asciidoctor/images/image1.png b/pack/acp/start/vim-asciidoctor/images/image1.png new file mode 100644 index 0000000..0a0c5d6 Binary files /dev/null and b/pack/acp/start/vim-asciidoctor/images/image1.png differ diff --git a/pack/acp/start/vim-asciidoctor/images/test_docx.png b/pack/acp/start/vim-asciidoctor/images/test_docx.png new file mode 100644 index 0000000..7fd0f5c Binary files /dev/null and b/pack/acp/start/vim-asciidoctor/images/test_docx.png differ diff --git a/pack/acp/start/vim-asciidoctor/images/test_html.png b/pack/acp/start/vim-asciidoctor/images/test_html.png new file mode 100644 index 0000000..df3f25e Binary files /dev/null and b/pack/acp/start/vim-asciidoctor/images/test_html.png differ diff --git a/pack/acp/start/vim-asciidoctor/images/test_pdf1.png b/pack/acp/start/vim-asciidoctor/images/test_pdf1.png new file mode 100644 index 0000000..52c233f Binary files /dev/null and b/pack/acp/start/vim-asciidoctor/images/test_pdf1.png differ diff --git a/pack/acp/start/vim-asciidoctor/images/test_pdf2.png b/pack/acp/start/vim-asciidoctor/images/test_pdf2.png new file mode 100644 index 0000000..64cccc6 Binary files /dev/null and b/pack/acp/start/vim-asciidoctor/images/test_pdf2.png differ diff --git a/pack/acp/start/vim-asciidoctor/indent/asciidoctor.vim b/pack/acp/start/vim-asciidoctor/indent/asciidoctor.vim new file mode 100644 index 0000000..d9106e2 --- /dev/null +++ b/pack/acp/start/vim-asciidoctor/indent/asciidoctor.vim @@ -0,0 +1,15 @@ +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +let s:undo_opts = "setl inde<" + +if exists('b:undo_indent') + let b:undo_indent .= "|" . s:undo_opts +else + let b:undo_indent = s:undo_opts +endif + +" prevent incorrect indentation with == +setlocal indentexpr=-1 diff --git a/pack/acp/start/vim-asciidoctor/syntax/asciidoctor.vim b/pack/acp/start/vim-asciidoctor/syntax/asciidoctor.vim new file mode 100644 index 0000000..7418133 --- /dev/null +++ b/pack/acp/start/vim-asciidoctor/syntax/asciidoctor.vim @@ -0,0 +1,318 @@ +" Vim syntax file +" Language: asciidoctor +" Maintainer: Maxim Kim +" Filenames: *.adoc +" vim: et sw=4 + +if exists("b:current_syntax") + finish +endif + +syntax spell toplevel + +if !exists('main_syntax') + let main_syntax = 'asciidoctor' +endif + +if !exists('g:asciidoctor_fenced_languages') + let g:asciidoctor_fenced_languages = [] +endif +for s:type in g:asciidoctor_fenced_languages + [get(b:, "asciidoctor_source_language", "NONE")] + if s:type ==# "NONE" + continue + endif + exe 'syn include @asciidoctorSourceHighlight'.s:type.' syntax/'.s:type.'.vim' + unlet! b:current_syntax +endfor +unlet! s:type + +if globpath(&rtp, "syntax/plantuml.vim") != '' + syn include @asciidoctorPlantumlHighlight syntax/plantuml.vim + unlet! b:current_syntax +endif + +" Check :h syn-sync-fourth +syn sync maxlines=100 + +syn case ignore + +syn match asciidoctorOption "^:[[:alnum:]!-]\{-}:" +syn match asciidoctorListContinuation "^+\s*$" +syn match asciidoctorPageBreak "^<<<\+\s*$" + +syn cluster asciidoctorBlock contains=asciidoctorTitle,asciidoctorH1,asciidoctorH2,asciidoctorH3,asciidoctorH4,asciidoctorH5,asciidoctorH6,asciidoctorSetextHeader,asciidoctorSetextHeaderDelimiter,asciidoctorBlockquote,asciidoctorListMarker,asciidoctorOrderedListMarker,asciidoctorCodeBlock,asciidoctorAdmonition,asciidoctorAdmonitionBlock +syn cluster asciidoctorInnerBlock contains=asciidoctorBlockquote,asciidoctorListMarker,asciidoctorOrderedListMarker,asciidoctorCodeBlock,asciidoctorDefList,asciidoctorAdmonition,asciidoctorAdmonitionBlock +syn cluster asciidoctorInline contains=asciidoctorItalic,asciidoctorBold,asciidoctorCode,asciidoctorBoldItalic,asciidoctorUrl,asciidoctorUrlAuto,asciidoctorLink,asciidoctorAnchor,asciidoctorMacro,asciidoctorAttribute,asciidoctorInlineAnchor +syn cluster asciidoctorUrls contains=asciidoctorUrlDescription,asciidoctorFile,asciidoctorUrlAuto,asciidoctorEmailAuto + +syn region asciidoctorTitle matchgroup=asciidoctorTitleDelimiter start="^=\s" end="$" oneline keepend contains=@asciidoctorInline,@Spell +syn region asciidoctorH1 matchgroup=asciidoctorH1Delimiter start="^==\s" end="$" oneline keepend contains=@asciidoctorInline,@Spell +syn region asciidoctorH2 matchgroup=asciidoctorH2Delimiter start="^===\s" end="$" oneline keepend contains=@asciidoctorInline,@Spell +syn region asciidoctorH3 matchgroup=asciidoctorH3Delimiter start="^====\s" end="$" oneline keepend contains=@asciidoctorInline,@Spell +syn region asciidoctorH4 matchgroup=asciidoctorH4Delimiter start="^=====\s" end="$" oneline keepend contains=@asciidoctorInline,@Spell +syn region asciidoctorH5 matchgroup=asciidoctorH5Delimiter start="^======\s" end="$" oneline keepend contains=@asciidoctorInline,@Spell +syn region asciidoctorH6 matchgroup=asciidoctorH6Delimiter start="^=======\s" end="$" oneline keepend contains=@asciidoctorInline,@Spell + +syn match asciidoctorSetextHeader '^\%(\n\|\%^\)\k.*\n\%(==\+\|\-\-\+\|\~\~\+\|\^\^\+\|++\+\)$' contains=@Spell,asciidoctorSetextHeaderDelimiter +syn match asciidoctorSetextHeaderDelimiter "^==\+\|\-\-\+\|\~\~\+\|\^\^\+\|++\+$" contained containedin=asciidoctorSetextHeader + +syn sync clear +syn sync match syncH1 grouphere NONE "^==\s.*$" +syn sync match syncH2 grouphere NONE "^===\s.*$" +syn sync match syncH3 grouphere NONE "^====\s.*$" +syn sync match syncH4 grouphere NONE "^=====\s.*$" +syn sync match syncH5 grouphere NONE "^======\s.*$" +syn sync match syncH6 grouphere NONE "^=======\s.*$" + +syn match asciidoctorAttribute "{[[:alpha:]][[:alnum:]-_:]\{-}}" + +" a Macro is a generic pattern that has no default highlight, but it could contain a link/image/url/xref/mailto/etc, and naked URLs as well + +syn match asciidoctorMacro "\<\l\{-1,}://\S\+" contains=asciidoctorUrlAuto,asciidoctorCode +syn match asciidoctorMacro "\<\w\S\{-}@\w\+\.\w\+" contains=asciidoctorEmailAuto,asciidoctorCode +syn match asciidoctorMacro "\<\l\{-1,}::\?\S*\[.\{-}\]" keepend contains=asciidoctorUrl,asciidoctorLink,asciidoctorEmail,asciidoctorCode + +syn match asciidoctorFile "\f\+" contained +syn match asciidoctorUrlDescription "\[[^]]\{-}\]" contained containedin=asciidoctorLink +syn match asciidoctorUrlAuto "\%(file\|http\|ftp\|irc\)s\?://\S\+\%(\[.\{-}\]\)\?" contained contains=asciidoctorUrl +syn match asciidoctorEmailAuto "[a-zA-Z0-9._%+-]\{-1,}@\w\+\%(\.\w\+\)\+" contained + +if get(g:, 'asciidoctor_syntax_conceal', 0) + " the pattern \[\ze\%(\s*[^ ]\+\s*\)\+]\+ means: a brackets pair, inside of which at least one non-space character, possibly with spaces + syn region asciidoctorLink matchgroup=Conceal start="\%(link\|xref\|mailto\|irc\):[^:][^\[]\{-}\[\ze\%(\s*[^ \]]\+\s*\)\+\]\+" end="\]" concealends oneline keepend skipwhite contained + syn region asciidoctorLink matchgroup=Conceal start="\%(link\|xref\|mailto\|irc\):\ze[^:][^\[]\{-}\[\s*\]" end="\ze\[\s*\]" concealends oneline keepend skipwhite contained nextgroup=asciidoctorUrlDescription contains=asciidoctorUrl,asciidoctorFile + + syn region asciidoctorUrl matchgroup=Conceal start="\%(file\|http\|ftp\|irc\)s\?://\S\+\[\ze\%(\s*[^ ]\+\s*\)\+]\+" end="\]" concealends oneline keepend skipwhite contained + + if get(g:, 'asciidoctor_compact_media_links', 0) + " conceal also the address of an image/video, if the description is not empty + syn region asciidoctorLink matchgroup=Conceal start="\%(video\|image\)::\ze.*" end="\ze\[\s*\]" concealends oneline keepend skipwhite contained nextgroup=asciidoctorUrlDescription contains=asciidoctorUrl,asciidoctorFile + syn region asciidoctorLink matchgroup=Conceal start="\%(video\|image\)::.*\[\ze\%(\s*[^ ]\+\s*\)\+]\+" end="\]" concealends oneline keepend skipwhite contained + else + syn region asciidoctorLink matchgroup=Conceal start="\%(video\|image\)::\?\ze.*" end="\ze\[.*\]" concealends oneline keepend skipwhite contained nextgroup=asciidoctorUrlDescription contains=asciidoctorFile + endif + + syn region asciidoctorAnchor matchgroup=Conceal start="<<\%([^>]\{-},\s*\)\?\ze.\{-}>>" end=">>" concealends oneline + + syn region asciidoctorBold matchgroup=Conceal start=/\m\*\*/ end=/\*\*/ contains=@Spell concealends oneline + syn region asciidoctorBold matchgroup=Conceal start=/\m\%(^\|[[:punct:][:space:]]\@<=\)\*\ze[^* ].\{-}\S/ end=/\*\%([[:punct:][:space:]]\@=\|$\)/ contains=@Spell concealends oneline + + syn region asciidoctorItalic matchgroup=Conceal start=/\m__/ end=/__/ contains=@Spell concealends oneline + syn region asciidoctorItalic matchgroup=Conceal start=/\m\%(^\|[[:punct:][:space:]]\@<=\)_\ze[^_ ].\{-}\S/ end=/_\%([[:punct:][:space:]]\@=\|$\)/ contains=@Spell concealends oneline + + syn region asciidoctorBoldItalic matchgroup=Conceal start=/\m\*\*_/ end=/_\*\*/ contains=@Spell concealends oneline + syn region asciidoctorBoldItalic matchgroup=Conceal start=/\m\%(^\|[[:punct:][:space:]]\@<=\)\*_\ze[^*_ ].\{-}\S/ end=/_\*\%([[:punct:][:space:]]\@=\|$\)/ contains=@Spell concealends oneline + + syn region asciidoctorCode matchgroup=Conceal start=/\m``/ end=/``/ contains=@Spell concealends oneline + syn region asciidoctorCode matchgroup=Conceal start=/\m\%(^\|[[:punct:][:space:]]\@<=\)`\ze[^` ].\{-}\S/ end=/`\%([[:punct:][:space:]]\@=\|$\)/ contains=@Spell concealends oneline +else + syn region asciidoctorLink start="\%(link\|xref\|mailto\):\zs[^:].\{-}\ze\[" end="\[.\{-}\]" oneline keepend skipwhite contained + syn region asciidoctorLink start="\%(video\|image\)::\?\zs.\{-}\ze\[" end="\[.\{-}\]" oneline keepend skipwhite contained + syn match asciidoctorUrl "\%(file\|http\|ftp\|irc\)s\?://\S\+\ze\%(\[.\{-}\]\)" nextgroup=asciidoctorUrlDescription + + syn match asciidoctorAnchor "<<.\{-}>>" + + syn match asciidoctorBold /\%(^\|[[:punct:][:space:]]\@<=\)\*[^* ].\{-}\S\*\%([[:punct:][:space:]]\@=\|$\)/ contains=@Spell + " single char *b* bold + syn match asciidoctorBold /\%(^\|[[:punct:][:space:]]\@<=\)\*[^* ]\*\%([[:punct:][:space:]]\@=\|$\)/ contains=@Spell + syn match asciidoctorBold /\*\*\S.\{-}\*\*/ contains=@Spell + + syn match asciidoctorItalic /\%(^\|[[:punct:][:space:]]\@<=\)_[^_ ].\{-}\S_\%([[:punct:][:space:]]\@=\|$\)/ contains=@Spell + " single char _b_ italic + syn match asciidoctorItalic /\%(^\|[[:punct:][:space:]]\@<=\)_[^_ ]_\%([[:punct:][:space:]]\@=\|$\)/ contains=@Spell + syn match asciidoctorItalic /__\S.\{-}__/ contains=@Spell + + syn match asciidoctorBoldItalic /\%(^\|[[:punct:][:space:]]\@<=\)\*_[^*_ ].\{-}\S_\*\%([[:punct:][:space:]]\@=\|$\)/ contains=@Spell + " single char *_b_* bold+italic + syn match asciidoctorBoldItalic /\%(^\|[[:punct:][:space:]]\@<=\)\*_[^*_ ]_\*\%([[:punct:][:space:]]\@=\|$\)/ contains=@Spell + syn match asciidoctorBoldItalic /\*\*_\S.\{-}_\*\*/ contains=@Spell + + syn match asciidoctorCode /\%(^\|[[:punct:][:space:]]\@<=\)`[^` ].\{-}\S`\%([[:punct:][:space:]]\@=\|$\)/ + " single char `c` code + syn match asciidoctorCode /\%(^\|[[:punct:][:space:]]\@<=\)`[^` ]`\%([[:punct:][:space:]]\@=\|$\)/ + syn match asciidoctorCode /``.\{-}``/ +endif + +syn match asciidoctorUppercase /^\ze\u\+:/ nextgroup=asciidoctorAdmonition +syn match asciidoctorAdmonition /\C^\%(NOTE:\)\|\%(TIP:\)\|\%(IMPORTANT:\)\|\%(CAUTION:\)\|\%(WARNING:\)\s/ contained + +syn match asciidoctorListMarker "^\s*\(-\|\*\+\|\.\+\)\%(\s\+\[[Xx ]\]\+\s*\)\?\%(\s\+\S\)\@=" +syn match asciidoctorOrderedListMarker "^\s*\%(\d\+\|\a\)\.\%(\s\+\S\)\@=" +syn match asciidoctorDefList "^.\{-}::\%(\s\|$\)" contains=@Spell + +syn match asciidoctorCallout "\s\+\zs<\%(\.\|\d\+\)>\ze\s*$" contained +syn match asciidoctorCalloutDesc "^\s*\zs<\%(\.\|\d\+\)>\ze\s\+" + + +syn match asciidoctorCaption "^\.[^.[:space:]].*$" contains=@asciidoctorInline,@Spell + +syn match asciidoctorBlockOptions "^\[.\{-}\]\s*$" + +if get(g:, 'asciidoctor_syntax_indented', 1) + syn match asciidoctorPlus '^+\n\s' contained + syn match asciidoctorIndented '^+\?\n\%(\s\+\(-\|[*.]\+\|\d\+\.\|\a\.\)\s\)\@!\(\s.*\n\)\+' contains=asciidoctorPlus +endif + +syn match asciidoctorInlineAnchor "\[\[.\{-}\]\]" + +syn match asciidoctorIndexTerm "((.\{-}))" +syn match asciidoctorIndexTerm "(((.\{-})))" + +" Open block +" -- +" Should be highlighted as usual asciidoctor +" Except (at least) headings +" -- +syn region asciidoctorOpenBlock matchgroup=asciidoctorBlock start="^--\s*$" end="^--\s*$" contains=@asciidoctorInnerBlock,@asciidoctorInline,@Spell,asciidoctorComment,asciidoctorIndented + +" Listing block +" ---- +" block that will not be +" highlighted +" ---- +syn region asciidoctorListingBlock matchgroup=asciidoctorBlock start="^----\+\s*$" end="^----\s*$" + +" General [source] block +syn region asciidoctorSourceBlock matchgroup=asciidoctorBlock start="^\[source\%(,.*\)*\]\s*$" end="^\s*$" keepend +syn region asciidoctorSourceBlock matchgroup=asciidoctorBlock start="^\[source\%(,.*\)*\]\s*\n\z(--\+\)\s*$" end="^.*\n\zs\z1\s*$" keepend +syn region asciidoctorSourceBlock matchgroup=asciidoctorBlock start="^```\%(\w\+\)\?\s*$" end="^.*\n\?\zs```\s*$" keepend + +" Source highlighting with programming languages +if main_syntax ==# 'asciidoctor' + + "" if :source-language: is set up + "" b:asciidoctor_source_language should be set up in ftplugin -- reading + "" first 20(?) rows of a file + if get(b:, "asciidoctor_source_language", "NONE") != "NONE" + " :source-language: python + "[source] + " for i in ... + " + exe 'syn region asciidoctorSourceHighlightDefault'.b:asciidoctor_source_language.' matchgroup=asciidoctorBlock start="^\[source\]\s*$" end="^\s*$" keepend contains=asciidoctorCallout,@asciidoctorSourceHighlight'.b:asciidoctor_source_language + + " :source-language: python + "[source] + "---- + " for i in ... + "---- + exe 'syn region asciidoctorSourceHighlightDefault'.b:asciidoctor_source_language.' matchgroup=asciidoctorBlock start="^\[source\]\s*\n\z(--\+\)\s*$" end="^.*\n\zs\z1\s*$" keepend contains=asciidoctorCallout,@asciidoctorSourceHighlight'.b:asciidoctor_source_language + + " :source-language: python + "```lang + "for i in ... + "``` + exe 'syn region asciidoctorSourceHighlightDefault'.b:asciidoctor_source_language.' matchgroup=asciidoctorBlock start="^```\s*$" end="^.*\n\?\zs```\s*$" keepend contains=asciidoctorCallout,@asciidoctorSourceHighlight'.b:asciidoctor_source_language + endif + + "" Other languages + for s:type in g:asciidoctor_fenced_languages + [get(b:, "asciidoctor_source_language", "NONE")] + if s:type ==# "NONE" + continue + endif + "[source,lang] + " for i in ... + " + exe 'syn region asciidoctorSourceHighlight'.s:type.' matchgroup=asciidoctorBlock start="^\[\%(source\)\?,\s*'.s:type.'\%(,.*\)*\]\s*$" end="^\s*$" keepend contains=asciidoctorCallout,@asciidoctorSourceHighlight'.s:type + + "[source,lang] + "---- + "for i in ... + "---- + exe 'syn region asciidoctorSourceHighlight'.s:type.' matchgroup=asciidoctorBlock start="^\[\%(source\)\?,\s*'.s:type.'\%(,.*\)*\]\s*\n\z(--\+\)\s*$" end="^.*\n\zs\z1\s*$" keepend contains=asciidoctorCallout,@asciidoctorSourceHighlight'.s:type + + "```lang + "for i in ... + "``` + exe 'syn region asciidoctorSourceHighlightDefault'.s:type.' matchgroup=asciidoctorBlock start="^```'.s:type.'\s*$" end="^.*\n\?\zs```\s*$" keepend contains=asciidoctorCallout,@asciidoctorSourceHighlight'.s:type + + + endfor + unlet! s:type +endif + +" Contents of plantuml blocks should be highlighted with plantuml syntax... +" There is no built in plantuml syntax as far as I know. +" Tested with https://github.com/aklt/plantuml-syntax +syn region asciidoctorPlantumlBlock matchgroup=asciidoctorBlock start="^\[plantuml.\{-}\]\s*\n\z(\.\.\.\.\+\)\s*$" end="^.*\n\zs\z1\s*$" keepend contains=@asciidoctorPlantumlHighlight +syn region asciidoctorPlantumlBlock matchgroup=asciidoctorBlock start="^\[plantuml.\{-}\]\s*\n\z(--\+\)\s*$" end="^.*\n\zs\z1\s*$" keepend contains=@asciidoctorPlantumlHighlight + +" Contents of literal blocks should not be highlighted +" TODO: make [literal] works with paragraph +syn region asciidoctorLiteralBlock matchgroup=asciidoctorBlock start="^\z(\.\.\.\.\+\)\s*$" end="^\z1\s*$" contains=@Spell,asciidoctorComment +syn region asciidoctorExampleBlock matchgroup=asciidoctorBlock start="^\z(====\+\)\s*$" end="^\z1\s*$" contains=@asciidoctorInnerBlock,@asciidoctorInline,@Spell,asciidoctorComment,asciidoctorIndented +syn region asciidoctorSidebarBlock matchgroup=asciidoctorBlock start="^\z(\*\*\*\*\+\)\s*$" end="^\z1\s*$" contains=@asciidoctorInnerBlock,@asciidoctorInline,@Spell,asciidoctorComment,asciidoctorIndented +syn region asciidoctorQuoteBlock matchgroup=asciidoctorBlock start="^\z(____\+\)\s*$" end="^\z1\s*$" contains=@asciidoctorInnerBlock,@asciidoctorInline,@Spell,asciidoctorComment,asciidoctorIndented + +syn region asciidoctorAdmonitionBlock matchgroup=asciidoctorBlock start="^\[\u\+\]\n\z(====\+\)\s*$" end="^\z1\s*$" contains=@asciidoctorInnerBlock,@asciidoctorInline,@Spell,asciidoctorComment,asciidoctorIndented + +" Table blocks +syn match asciidoctorTableCell "\(^\|\s\)\@<=[.+*<^>aehlmdsv[:digit:]]\+|\||" contained containedin=asciidoctorTableBlock +syn region asciidoctorTableBlock matchgroup=asciidoctorBlock start="^|\z(===\+\)\s*$" end="^|\z1\s*$" keepend contains=asciidoctorTableCell,asciidoctorIndented,@asciidoctorInnerBlock,@asciidoctorInline,@Spell,asciidoctorComment +syn region asciidoctorTableBlock matchgroup=asciidoctorBlock start="^,\z(===\+\)\s*$" end="^,\z1\s*$" keepend +syn region asciidoctorTableBlock matchgroup=asciidoctorBlock start="^;\z(===\+\)\s*$" end="^;\z1\s*$" keepend + +syn match asciidoctorComment "^//.*$" contains=@Spell +syn region asciidoctorComment start="^////.*$" end="^////.*$" contains=@Spell + +hi def link asciidoctorTitle Title +hi def link asciidoctorSetextHeader Title +hi def link asciidoctorH1 Title +hi def link asciidoctorH2 Title +hi def link asciidoctorH3 Title +hi def link asciidoctorH4 Title +hi def link asciidoctorH5 Title +hi def link asciidoctorH6 Title +hi def link asciidoctorTitleDelimiter Type +hi def link asciidoctorH1Delimiter Type +hi def link asciidoctorH2Delimiter Type +hi def link asciidoctorH3Delimiter Type +hi def link asciidoctorH4Delimiter Type +hi def link asciidoctorH5Delimiter Type +hi def link asciidoctorH6Delimiter Type +hi def link asciidoctorSetextHeaderDelimiter Type +hi def link asciidoctorListMarker Delimiter +hi def link asciidoctorOrderedListMarker asciidoctorListMarker +hi def link asciidoctorListContinuation PreProc +hi def link asciidoctorComment Comment +hi def link asciidoctorIndented Comment +hi def link asciidoctorPlus PreProc +hi def link asciidoctorPageBreak PreProc +hi def link asciidoctorCallout Float +hi def link asciidoctorCalloutDesc String + +hi def link asciidoctorListingBlock Comment +hi def link asciidoctorLiteralBlock Comment + +hi def link asciidoctorFile Underlined +hi def link asciidoctorUrl Underlined +hi def link asciidoctorEmail Underlined +hi def link asciidoctorUrlAuto Underlined +hi def link asciidoctorEmailAuto Underlined +hi def link asciidoctorUrlDescription String + +hi def link asciidoctorLink Underlined +hi def link asciidoctorAnchor Underlined +hi def link asciidoctorAttribute Identifier +hi def link asciidoctorCode Constant +hi def link asciidoctorOption PreProc +hi def link asciidoctorBlock PreProc +hi def link asciidoctorBlockOptions PreProc +hi def link asciidoctorTableSep PreProc +hi def link asciidoctorTableCell PreProc +hi def link asciidoctorTableEmbed PreProc +hi def link asciidoctorInlineAnchor PreProc +hi def link asciidoctorMacro Macro +hi def link asciidoctorIndexTerm Macro + +hi def asciidoctorBold gui=bold cterm=bold +hi def asciidoctorItalic gui=italic cterm=italic +hi def asciidoctorBoldItalic gui=bold,italic cterm=bold,italic + +hi def link asciidoctorDefList asciidoctorBold +hi def link asciidoctorCaption Statement +hi def link asciidoctorAdmonition asciidoctorBold + +let b:current_syntax = "asciidoctor" +if main_syntax ==# 'asciidoctor' + unlet main_syntax +endif diff --git a/plugins.md b/plugins.md index fed4591..f178862 100644 --- a/plugins.md +++ b/plugins.md @@ -16,5 +16,6 @@ Git submodules are slow, so handle this manually. * [mom.vim](http://git.savannah.gnu.org/cgit/groff.git/plain/contrib/mom/examples/mom.vim) * [tempus-themes-vim](https://gitlab.com/protesilaos/tempus-themes-vim) * [vim-actodo](https://github.com/acperkins/vim-actodo) +* [vim-asciidoctor](https://github.com/habamax/vim-asciidoctor) * [vim-speeddating](https://github.com/tpope/vim-speeddating) * [vim-surround](https://github.com/tpope/vim-surround)