mirror of
https://github.com/gryf/.vim.git
synced 2025-12-17 19:40:29 +01:00
6152 lines
208 KiB
VimL
6152 lines
208 KiB
VimL
" Vim reStructured Text
|
||
" (c) Mikolaj Machowski 2006
|
||
" Author: Mikolaj Machowski ( mikmach AT wp DOT pl )
|
||
" Last Change: 4 Nov 2006
|
||
" Version: 1.4
|
||
" License:
|
||
" Copyright (C) 2006 Mikolaj Machowski <mikmach@wp.pl>
|
||
"
|
||
" This script is free software; you can redistribute it and/or
|
||
" modify it under the terms of the GNU Library General Public
|
||
" License as published by the Free Software Foundation; either
|
||
" version 2 of the License, or (at your option) any later version.
|
||
"
|
||
" This library is distributed in the hope that it will be useful,
|
||
" but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
" Library General Public License for more details.
|
||
"
|
||
" You should have received a copy of the GNU Library General Public License
|
||
" along with this library; see the file COPYING.LIB. If not, write to
|
||
" the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
" Boston, MA 02110-1301, USA.
|
||
"
|
||
|
||
" Preamble {{{
|
||
"
|
||
" Note: This script relies on indentation of elements. You
|
||
" should set it to at least 4.
|
||
"
|
||
"
|
||
if &compatible == 1
|
||
set nocompatible
|
||
endif
|
||
|
||
scriptencoding iso-8859-2
|
||
|
||
" Initiate some variables. Not really necessary but makes possible to use
|
||
" command line completion when doing temporary modifications.
|
||
" VST version (for debugging:
|
||
let s:vst_ver = '140'
|
||
" Write export immediately
|
||
if !exists("g:vst_write_export")
|
||
let g:vst_write_export = 0
|
||
endif
|
||
if !exists("g:vst_included")
|
||
let g:vst_included = split(&rtp, ',')[0].'/autoload/vst/include/'
|
||
endif
|
||
if !exists("g:vst_css_user")
|
||
let g:vst_css_user = ''
|
||
endif
|
||
if !exists("g:vst_css_default")
|
||
let g:vst_css_default = ''
|
||
endif
|
||
if !exists("g:vst_tex_preamble")
|
||
let g:vst_tex_preamble = ''
|
||
endif
|
||
if !exists("g:vst_pdf_view")
|
||
let g:vst_user_css = 0
|
||
endif
|
||
if !exists("g:vst_pdf_clean")
|
||
let g:vst_pdf_clean = 0
|
||
endif
|
||
if !exists("g:vst_tex_post")
|
||
let g:vst_tex_post = ''
|
||
endif
|
||
if !exists("g:vst_html_post")
|
||
let g:vst_html_post = ''
|
||
endif
|
||
if !exists("g:vst_containers")
|
||
let g:vst_containers = []
|
||
endif
|
||
|
||
" Placeholders:
|
||
" LISTDEF: list definitions
|
||
" HEADDEF: sections detection
|
||
" This is ideal:
|
||
" ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~
|
||
" And is implemented! Also for transitions.
|
||
"
|
||
" HEADDEF:
|
||
let s:vst_headdef = '\(=\{3,}\|+\{3,}\|\*\{3,}\|\^\{3,}\|%\{3,}\|\$\{3,}\|#\{3,}\|@\{3,}\|;\{3,}\|"\{3,}\|\.\{3,}\|,\{3,}\|`\{3,}\|\~\{3,}\|-\{3,}\|!\{3,}\|(\{3,}\|)\{3,}\|:\{3,}\|_\{3,}\|&\{3,}\|}\{3,}\|{\{3,}\||\{3,}\|?\{3,}\|<\{3,}\|>\{3,}\|\\\{3,}\|\[\{3,}\|\]\{3,}\|\/\{3,}\|''\{3,}\)'
|
||
let s:vst_headchars = '[][=+*^%$#@;".,`~!():_&{}|?<>/\\''-]'
|
||
" LISTDEF:
|
||
let s:vst_bulletdef = '[\u2022\u2023\u2043\u204c\u204d\u25d8\u25e6\u2619\u2765\u2767*+-]'
|
||
let s:vst_bulletchars = '[\u2022\u2023\u2043\u204c\u204d\u25d8\u25e6\u2619\u2765\u2767*+-]'
|
||
"
|
||
" }}}
|
||
|
||
" VST_InstantWrapper: Write export file immediately without changing {{{
|
||
" manually g:vst_write_export variable.
|
||
" Description: Save value of g:vst_write_export var, set it to 1, call
|
||
" VST_Export, and restore old value of variable.
|
||
" line1 - beginning of range (1st line by default)
|
||
" line2 - end of range (last line by default)
|
||
" format - format of export
|
||
function! vst#vst#VST_InstantWrapper(line1, line2, format)
|
||
let temp_write_export = g:vst_write_export
|
||
let g:vst_write_export = 1
|
||
call vst#vst#VST_Export(a:line1, a:line2, a:format)
|
||
let g:vst_write_export = temp_write_export
|
||
return
|
||
endfunction
|
||
" }}}
|
||
" VST_Headers: Filter out only section titles from other elements {{{
|
||
" Description: get only real info about headers/section titles, these are
|
||
" bastardized versions of routines from VST_Structure but full scan was too
|
||
" slow, had to cut everything what was not necessary.
|
||
" text: text of whole file in List form
|
||
function! VST_Headers(text)
|
||
|
||
let doc = a:text
|
||
|
||
" Initiate arrays and variables {{{
|
||
let ltype = []
|
||
let lindent = []
|
||
|
||
let g:paras = []
|
||
let g:ptype = []
|
||
let g:pindent = []
|
||
let g:plinen = []
|
||
|
||
" }}}
|
||
" Detect and create line types {{{
|
||
let lendoc = len(doc)
|
||
for i in range(lendoc)
|
||
if i == lendoc - 1
|
||
let nextline = i - 1
|
||
else
|
||
let nextline = i + 1
|
||
endif
|
||
if doc[i] =~ '^\s*$'
|
||
let ltype += ['blank']
|
||
elseif doc[i] =~ '^\s*\.\. 2html::'
|
||
let ltype += ['2html']
|
||
elseif doc[i] =~ '^\s*\.\. |'
|
||
let ltype += ['replacement']
|
||
elseif doc[i] =~ '^\s*\.\. [[|]\?\w\+:'
|
||
" Names of most directives aren't important for header detection
|
||
" Comment is potential error.
|
||
let ltype += ['nonimp']
|
||
elseif doc[i] =~ '^\s*:.\{-1,}:\s\+'
|
||
let ltype += ['field']
|
||
elseif doc[i] =~ '^\s*(\(\d\+\|[a-zA-Z]\|[icvlxmICVLXM]\+\|#\))\s'
|
||
" LISTDEF: enum embraced in parenthesis
|
||
let cind = len(matchstr(doc[i], '^\s*'))
|
||
let nind = len(matchstr(doc[nextline], '^\s*'))
|
||
if nind > cind
|
||
let ltype += ['oli']
|
||
elseif nind == cind && doc[nextline] =~ '^\s*(\(\d\+\|[a-zA-Z]\|[icdvlmxICDVLMX]\+\|#\))\s'
|
||
let ltype += ['oli']
|
||
elseif doc[nextline] =~ '^\s*$'
|
||
let ltype += ['oli']
|
||
else
|
||
let ltype += ['p']
|
||
endif
|
||
elseif doc[i] =~ '^\s*\(\d\+\|[a-zA-Z]\|[icvlxmICVLXM]\+\|#\)[\]:.)}]\s'
|
||
" LISTDEF:
|
||
let cind = len(matchstr(doc[i], '^\s*'))
|
||
let nind = len(matchstr(doc[nextline], '^\s*'))
|
||
if nind > cind
|
||
let ltype += ['oli']
|
||
elseif nind == cind && doc[nextline] =~ '^\s*\(\d\+\|[a-zA-Z]\|[icdvlmxICDVLMX]\+\|#\)[\]:.)}]\s'
|
||
let ltype += ['oli']
|
||
elseif doc[nextline] =~ '^\s*$'
|
||
let ltype += ['oli']
|
||
else
|
||
let ltype += ['p']
|
||
endif
|
||
elseif doc[i] =~ '^\s*'.s:vst_bulletdef.'\s'
|
||
" LISTDEF:
|
||
let cind = len(matchstr(doc[i], '^\s*'))
|
||
let nind = len(matchstr(doc[nextline], '^\s*'))
|
||
if nind > cind
|
||
let ltype += ['uli']
|
||
elseif nind == cind && doc[nextline] =~ '^\s*'.s:vst_bulletdef.'\s'
|
||
let ltype += ['uli']
|
||
elseif doc[nextline] =~ '^\s*$'
|
||
let ltype += ['uli']
|
||
else
|
||
let ltype += ['p']
|
||
endif
|
||
elseif doc[i] =~ '^\s*\(--\|-\|/\|:\|+\)\S.\{-}\( \|$\)' && doc[i] !~ '^\s*\(--\s\|:\S\+:`\)'
|
||
if lendoc == 1
|
||
let ltype += ['p']
|
||
else
|
||
let ltype += ['optlist']
|
||
endif
|
||
elseif doc[i] =~ '^\s*::\s*$'
|
||
let ltype += ['emptypre']
|
||
elseif doc[i] =~ '^\s*+[=-]\{3,}'
|
||
let ltype += ['table']
|
||
else
|
||
let ltype += ['p']
|
||
endif
|
||
" Check indentation of each line
|
||
let lindent += [strlen(matchstr(doc[i], '^\s*'))]
|
||
endfor
|
||
" }}}
|
||
" Create false 'blank' line number 0 to make looping easier. {{{
|
||
call insert(ltype, 'blank')
|
||
call insert(lindent, 0)
|
||
call insert(doc, '')
|
||
" Create false 'blank' line to the end
|
||
call add(ltype, 'blank')
|
||
call add(lindent, 0)
|
||
call add(doc, '')
|
||
" }}}
|
||
" Create paragraphs from line types {{{
|
||
"
|
||
let i = 0
|
||
let parcounter = -1
|
||
for line in doc
|
||
if ltype[i] == 'blank'
|
||
let i += 1
|
||
continue
|
||
else
|
||
if ltype[i-1] == 'blank'
|
||
let parcounter += 1
|
||
let g:paras += [doc[i]]
|
||
let g:ptype += [ltype[i]]
|
||
let g:pindent += [lindent[i]]
|
||
let g:plinen += [g:vst_reallines[i]]
|
||
else
|
||
let g:paras[parcounter] .= "\n".doc[i]
|
||
endif
|
||
endif
|
||
|
||
let i += 1
|
||
endfor
|
||
" }}}
|
||
" Create false 'blank' para number 0 to make looping easier. {{{
|
||
call insert(g:ptype, 'blank')
|
||
call insert(g:pindent, 0)
|
||
call insert(g:paras, '')
|
||
call insert(g:plinen, 0)
|
||
" Create false 'blank' para on the end
|
||
call add(g:ptype, 'blank')
|
||
call add(g:pindent, 0)
|
||
call add(g:paras, '')
|
||
call add(g:plinen, 0)
|
||
" }}}
|
||
" Check and embrace paragraphs in pre tags <pre> (::) {{{
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
" Remove trailing spaces from the end of paragraph. They are meaningless
|
||
" and can cause problems.
|
||
let g:paras[i] = substitute(g:paras[i], '\s\+$', '', '')
|
||
if strpart(g:paras[i], strlen(g:paras[i])-2) == '::' && g:paras[i] !~ '^\s*\.\. [a-zA-Z0-9_-]\+::\s*$' || g:ptype[i] == '2html'
|
||
" For proper embedding of pre into lists I have to set indentation
|
||
" level not to indentation of paragraph (including
|
||
" enumeration/leading character) but indentation of last line.
|
||
let plines = split(g:paras[i], '\n')
|
||
if g:ptype[i] == 'oli'
|
||
if plines[-1] =~ '^\s*(\?\(\d\+\|[a-zA-Z]\|[icdvlmxICDVLMX]\+\|#\)[\]:.)}]\s*\ze'
|
||
" LISTDEF:
|
||
let initind = strlen(matchstr(plines[-1], '^\s*(\?\(\d\+\|[a-zA-Z]\|[icdvlmxICDVLMX]\+\|#\)[\]:.)}]\s*\ze'))
|
||
else
|
||
let initind = strlen(matchstr(plines[-1], '^\s*'))
|
||
endif
|
||
elseif g:ptype[i] == 'uli'
|
||
" LISTDEF:
|
||
if plines[-1] =~ '^\s*\zs'.s:vst_bulletdef.'\s*\ze'
|
||
let initind = strlen(matchstr(plines[-1], '^\s*\zs'.s:vst_bulletdef.'\s*\ze'))
|
||
else
|
||
let initind = strlen(matchstr(plines[-1], '^\s*'))
|
||
endif
|
||
elseif g:ptype[i] == 'optlist' || g:ptype[i] == 'dl'
|
||
let initind = strlen(matchstr(plines[-1], '^\s*'))
|
||
elseif g:ptype[i] =~ '^MED'
|
||
if plines[-1] =~ '^\s*\.\. '
|
||
let initind = strlen(matchstr(plines[-1], '^\s*\.\. \ze'))
|
||
else
|
||
let initind = strlen(matchstr(plines[-1], '^\s*'))
|
||
endif
|
||
else
|
||
let initind = g:pindent[i]
|
||
endif
|
||
let j = i + 1
|
||
while j < len(g:paras)
|
||
if initind >= g:pindent[j] || g:ptype[j] == 'notend' || g:ptype[j] == 'blank'
|
||
call insert(g:paras, '', j)
|
||
call insert(g:pindent, g:pindent[j-1], j)
|
||
call insert(g:ptype, 'prend', j)
|
||
call insert(g:plinen, 0, j)
|
||
|
||
if g:ptype[i] == '2html'
|
||
let g:paras[i] = ''
|
||
call insert(g:paras, '', i+1)
|
||
else
|
||
call insert(g:paras, '', i+1)
|
||
endif
|
||
call insert(g:pindent, g:pindent[i+1], i+1)
|
||
call insert(g:ptype, 'prebegin', i+1)
|
||
call insert(g:plinen, 0, i+1)
|
||
|
||
" Don't allow for checking inside embraced fragment for
|
||
" pre start conditions
|
||
let i = j
|
||
|
||
break
|
||
else
|
||
if g:ptype[j] == 'anonlink'
|
||
let parlines = split(g:paras[j], '\n')
|
||
for line in parlines
|
||
call filter(g:vst_anonhlinkdb, 'v:val !~ "'.line.'"')
|
||
endfor
|
||
endif
|
||
let g:ptype[j] = 'pre'
|
||
let g:paras[j] = substitute(g:paras[j], '`', '\`', 'g')
|
||
let g:paras[j] = substitute(g:paras[j], '_', '\_', 'g')
|
||
let g:paras[j] = substitute(g:paras[j], '\[', '\[', 'g')
|
||
let g:paras[j] = substitute(g:paras[j], '\.', '\.', 'g')
|
||
let g:paras[j] = substitute(g:paras[j], '|', '\|', 'g')
|
||
|
||
endif
|
||
let j += 1
|
||
endwhile
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
" }}}
|
||
" Build databases NOW. {{{
|
||
" For this we have to glue together g:paras,
|
||
" split it along \n and perform other footnote detection actions.
|
||
" But we want to make it only once on first parsing, not inside of tables
|
||
if !exists('b:vst_first_parsing')
|
||
|
||
" Some actions should be taken only first time when parsing whole file (not in
|
||
" tables cells). Set this variable and unlet it when returning from export
|
||
"let b:vst_first_parsing = 1
|
||
|
||
" Build here also other databases?
|
||
let fntext = split(join(g:paras, "\n\n"), "\n")
|
||
|
||
call VST_CreateDBs(fntext)
|
||
|
||
"let g:vst_anonhlinkdb = filter(copy(fntext), 'v:val =~ "^\\s*\\(\\.\\. __:\\|__ \\)"')
|
||
|
||
endif
|
||
" }}}
|
||
" Build replacement database. {{{
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'replacement'
|
||
let from = matchstr(g:paras[i], '^\s*\.\. |\zs.\{-}\ze|')
|
||
let into = matchstr(g:paras[i], '^\s*\.\. |.\{-}|\s\+\zs.*')
|
||
let g:vst_replacedb[from] = into
|
||
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
" }}}
|
||
" Detect if par is a header (<hx>) {{{
|
||
let i = 0
|
||
let h1 = ''
|
||
let h2 = ''
|
||
let h3 = ''
|
||
let h4 = ''
|
||
let h5 = ''
|
||
while i < len(g:paras)
|
||
if g:ptype[i] !~ '^pre'
|
||
if g:paras[i] =~ '\n\s*'.s:vst_headdef.'\s*\(\n\|$\)' && g:ptype[i] !~ 'table'
|
||
let parlines = split(g:paras[i], '\n')
|
||
if parlines[1] =~ '^\s*'.s:vst_headdef.'\s*$'
|
||
let double = ' '
|
||
elseif parlines[0] == parlines[2] && parlines[0] =~ '^\s*'.s:vst_headdef.'\s*$'
|
||
let double = 'd'
|
||
call remove(parlines, 0)
|
||
endif
|
||
let lchar = matchstr(parlines[1], '.\ze\s*$').double
|
||
if lchar =~ s:vst_headchars
|
||
if h1 == '' || lchar == h1
|
||
let h1 = lchar
|
||
let g:ptype[i] = 'h1'
|
||
elseif h2 == '' || lchar == h2
|
||
let h2 = lchar
|
||
let g:ptype[i] = 'h2'
|
||
elseif h3 == '' || lchar == h3
|
||
let h3 = lchar
|
||
let g:ptype[i] = 'h3'
|
||
elseif h4 == '' || lchar == h4
|
||
let h4 = lchar
|
||
let g:ptype[i] = 'h4'
|
||
elseif h5 == '' || lchar == h5
|
||
let h5 = lchar
|
||
let g:ptype[i] = 'h5'
|
||
else
|
||
let g:ptype[i] = 'h6'
|
||
endif
|
||
let modlchar = substitute(lchar, '[d ]', '', 'g')
|
||
let g:vst_headers[g:ptype[i]] = repeat(modlchar, 9).double
|
||
" Everything after ornament put into next paragraph
|
||
" p type. Ugly but prevents worse things.
|
||
"
|
||
if len(parlines) > 2
|
||
let g:paras[i] = join(parlines[0:1], "\n")
|
||
call insert(g:paras, join(parlines[2:], "\n"), i+1)
|
||
call insert(g:pindent, g:pindent[i], i+1)
|
||
call insert(g:plinen, 0, i+1)
|
||
|
||
if parlines[2] =~ '^\s*:.\{-1,}:\s\+'
|
||
call insert(g:ptype, 'field', i+1)
|
||
else
|
||
call insert(g:ptype, 'sub'.g:ptype[i], i+1)
|
||
endif
|
||
else
|
||
let g:paras[i] = join(parlines, "\n")
|
||
endif
|
||
endif
|
||
endif
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
" }}}
|
||
|
||
endfunction
|
||
" }}}
|
||
|
||
" VST_Structure: Analyze of text structure
|
||
" Description: Take given table and analyze it
|
||
" - text: text in form of List
|
||
function! VST_Structure(text)
|
||
|
||
let doc = a:text
|
||
|
||
" Initiate arrays and variables {{{
|
||
let ltype = []
|
||
let lindent = []
|
||
|
||
if !exists("g:vst_recursion")
|
||
let g:vst_recursion = 0
|
||
else
|
||
let g:vst_recursion += 1
|
||
endif
|
||
|
||
if exists("g:paras")
|
||
let g:paras_rez += [g:paras]
|
||
let g:paras = []
|
||
else
|
||
let g:paras_rez = []
|
||
let g:paras = []
|
||
endif
|
||
if exists("g:ptype")
|
||
let g:ptype_rez += [g:ptype]
|
||
let g:ptype = []
|
||
else
|
||
let g:ptype_rez = []
|
||
let g:ptype = []
|
||
endif
|
||
if exists("g:pindent")
|
||
let g:pindent_rez += [g:pindent]
|
||
let g:pindent = []
|
||
else
|
||
let g:pindent_rez = []
|
||
let g:pindent = []
|
||
endif
|
||
if exists("g:plinen")
|
||
let g:plinen_rez += [g:plinen]
|
||
let g:plinen = []
|
||
else
|
||
let g:plinen_rez = []
|
||
let g:plinen = []
|
||
endif
|
||
|
||
let toc = ''
|
||
" }}}
|
||
" Detect and create line types {{{
|
||
let lendoc = len(doc)
|
||
for line in range(lendoc)
|
||
if line == lendoc - 1
|
||
let nextline = line - 1
|
||
else
|
||
let nextline = line + 1
|
||
endif
|
||
if doc[line] =~ '^\s*$'
|
||
let ltype += ['blank']
|
||
elseif doc[line] =~ '^\s*\.\. _.*:\s*$'
|
||
let ltype += ['intlink']
|
||
elseif doc[line] =~ '^\s*\.\. __:'
|
||
let ltype += ['anonlink']
|
||
elseif doc[line] =~ '^\s*__'
|
||
let ltype += ['anonlink']
|
||
elseif doc[line] =~ '^\s*\.\. _'
|
||
let ltype += ['link']
|
||
elseif doc[line] =~ '^\s*\.\. image::'
|
||
let ltype += ['img']
|
||
elseif doc[line] =~? '^\s*\.\. \(note\|tip\|warning\|attention\|caution\|danger\|error\|hint\|important\|admonition\)::'
|
||
let ltype += ['MED']
|
||
elseif doc[line] =~? '^\s*\.\. figure::'
|
||
let ltype += ['MED-figure']
|
||
elseif doc[line] =~ '^\s*\.\. \[\d\+\]'
|
||
let ltype += ['MED-footnote']
|
||
elseif doc[line] =~ '^\s*\.\. \[#\]'
|
||
let ltype += ['MED-autofootnote']
|
||
elseif doc[line] =~ '^\s*\.\. \[#\k\+\]'
|
||
let ltype += ['MED-labelfootnote']
|
||
elseif doc[line] =~ '^\s*\.\. \[\k\+\]'
|
||
let ltype += ['MED-citation']
|
||
elseif doc[line] =~ '^\s*\.\. pull-quote::'
|
||
let ltype += ['MED-pullquote']
|
||
elseif doc[line] =~ '^\s*\.\. block::'
|
||
let ltype += ['MED-block']
|
||
elseif doc[line] =~ '^\s*\.\. container::'
|
||
let ltype += ['MED-container']
|
||
elseif doc[line] =~ '^\s*\.\. topic::'
|
||
let ltype += ['MED-topic']
|
||
elseif doc[line] =~ '^\s*\.\. sidebar::'
|
||
let ltype += ['MED-sidebar']
|
||
elseif doc[line] =~ '^\s*\.\. compound::'
|
||
let ltype += ['MED-compound']
|
||
elseif doc[line] =~ '^\s*\.\. class::'
|
||
let ltype += ['MED-class']
|
||
elseif doc[line] =~ '^\s*\.\. raw::\s*\(la\)\?tex\s\+html'
|
||
let ltype += ['rawboth']
|
||
elseif doc[line] =~ '^\s*\.\. raw::\s*html\s\+\(la\)\?tex'
|
||
let ltype += ['rawboth']
|
||
elseif doc[line] =~ '^\s*\.\. raw::\s*\(la\)\?tex'
|
||
let ltype += ['rawlatex']
|
||
elseif doc[line] =~ '^\s*\.\. raw::\s*html'
|
||
let ltype += ['rawhtml']
|
||
elseif doc[line] =~ '^\s*\.\. role::'
|
||
let ltype += ['role']
|
||
elseif doc[line] =~ '^\s*\.\. default-role::'
|
||
let ltype += ['defaultr']
|
||
elseif doc[line] =~ '^\s*\.\. latexonly::'
|
||
let ltype += ['latexonly']
|
||
elseif doc[line] =~ '^\s*\.\. htmlonly::'
|
||
let ltype += ['htmlonly']
|
||
elseif doc[line] =~ '^\s*\.\. contents::\s*:local'
|
||
let ltype += ['empty']
|
||
elseif doc[line] =~ '^\s*\.\. contents::'
|
||
let ltype += ['toc']
|
||
elseif doc[line] =~ '^\s*\.\. comment::'
|
||
let ltype += ['comment']
|
||
elseif doc[line] =~ '^\s*\.\. title::'
|
||
let ltype += ['title']
|
||
elseif doc[line] =~ '^\s*\.\. rubric::'
|
||
let ltype += ['rubric']
|
||
elseif doc[line] =~ '^\s*\.\. 2html::'
|
||
let ltype += ['2html']
|
||
elseif doc[line] =~ '^\s*\.\. meta::'
|
||
let ltype += ['meta']
|
||
elseif doc[line] =~ '^\s*\.\. |'
|
||
let ltype += ['replacement']
|
||
elseif doc[line] =~ '^\s*\.\. [a-zA-Z-]\+::' && doc[line] !~ 'header\|footer'
|
||
" Unknown directives treated as pre
|
||
" it doesn't cover contents of these paragraphs, they are
|
||
" processed normally.
|
||
let ltype += ['MED-unknown']
|
||
elseif doc[line] =~ '^\s*\.\.\(\s\|$\)'
|
||
" Everything else beginning with double dot will be treated as
|
||
" comment and completely removed from output. If you want to only
|
||
" hid this use one doc[line] comments
|
||
let ltype += ['MED-comment']
|
||
elseif doc[line] =~ '^\s*(\(\d\+\|[a-zA-Z]\|[icdvlmxICDVLMX]\+\|#\))\s'
|
||
" LISTDEF: enum embraced in parenthesis
|
||
let cind = len(matchstr(doc[line], '^\s*'))
|
||
let nind = len(matchstr(doc[nextline], '^\s*'))
|
||
if nind > cind
|
||
let ltype += ['oli']
|
||
elseif nind == cind && doc[nextline] =~ '^\s*(\(\d\+\|[a-zA-Z]\|[icdvlmxICDVLMX]\+\|#\))\s'
|
||
let ltype += ['oli']
|
||
elseif doc[nextline] =~ '^\s*$'
|
||
let ltype += ['oli']
|
||
else
|
||
let ltype += ['p']
|
||
endif
|
||
elseif doc[line] =~ '^\s*\(\d\+\|[a-zA-Z]\|[icdvlmxICDVLMX]\+\|#\)[\]:.)}]\s'
|
||
" LISTDEF:
|
||
let cind = len(matchstr(doc[line], '^\s*'))
|
||
let nind = len(matchstr(doc[nextline], '^\s*'))
|
||
if nind > cind
|
||
let ltype += ['oli']
|
||
elseif nind == cind && doc[nextline] =~ '^\s*\(\d\+\|[a-zA-Z]\|[icdvlmxICDVLMX]\+\|#\)[\]:.)}]\s'
|
||
let ltype += ['oli']
|
||
elseif doc[nextline] =~ '^\s*$'
|
||
let ltype += ['oli']
|
||
else
|
||
let ltype += ['p']
|
||
endif
|
||
elseif doc[line] =~ '^\s*'.s:vst_bulletdef.'\s'
|
||
" LISTDEF:
|
||
let cind = len(matchstr(doc[line], '^\s*'))
|
||
let nind = len(matchstr(doc[nextline], '^\s*'))
|
||
if nind > cind
|
||
let ltype += ['uli']
|
||
elseif nind == cind && doc[nextline] =~ '^\s*'.s:vst_bulletdef.'\s'
|
||
let ltype += ['uli']
|
||
elseif doc[nextline] =~ '^\s*$'
|
||
let ltype += ['uli']
|
||
else
|
||
let ltype += ['p']
|
||
endif
|
||
elseif doc[line] =~ '^\s*:.\{-1,}:\(\s\+\|$\)'
|
||
let ltype += ['field']
|
||
elseif doc[line] =~ '^\s*::\s*$'
|
||
let ltype += ['emptypre']
|
||
elseif doc[line] =~ '^\s*| '
|
||
let ltype += ['verse']
|
||
elseif doc[line] =~ '^\s*+-\{3,}'
|
||
let ltype += ['table']
|
||
elseif doc[line] =~ '^\s*+=\{3,}'
|
||
let ltype += ['bltable']
|
||
elseif doc[line] =~ '^\s*\(--\|-\|/\|:\|+\)\S.\{-}\( \|$\)' && doc[line] !~ '^\s*\(--\s\|:\S\+:`\)'
|
||
if lendoc == 1
|
||
let ltype += ['p']
|
||
else
|
||
let ltype += ['optlist']
|
||
endif
|
||
elseif doc[line] =~ '^\s*>>>'
|
||
let ltype += ['doctest']
|
||
elseif doc[line] =~ '^\s*=\{2,}\s\+=\{2,}'
|
||
let ltype += ['simpletbl']
|
||
else
|
||
let ltype += ['p']
|
||
" Remove backslash escaping special meaning for verse paragraphs
|
||
let doc[line] = substitute(doc[line], '^\(\s*\)\\|', '\1|', '')
|
||
endif
|
||
" Check indentation of each doc[line]
|
||
let lindent += [strlen(matchstr(doc[line], '^\s*'))]
|
||
endfor
|
||
" }}}
|
||
" Create false 'blank' line number 0 to make looping easier. {{{
|
||
call insert(ltype, 'blank')
|
||
call insert(lindent, 0)
|
||
call insert(doc, '')
|
||
" Create false 'blank' line to the end
|
||
call add(ltype, 'blank')
|
||
call add(lindent, 0)
|
||
call add(doc, '')
|
||
" }}}
|
||
" Create paragraphs from line types {{{
|
||
"
|
||
let i = 0
|
||
let parcounter = -1
|
||
for line in doc
|
||
if ltype[i] == 'blank'
|
||
let i += 1
|
||
continue
|
||
else
|
||
if ltype[i-1] == 'blank'
|
||
let parcounter += 1
|
||
let g:paras += [doc[i]]
|
||
let g:ptype += [ltype[i]]
|
||
let g:pindent += [lindent[i]]
|
||
let g:plinen += [g:vst_reallines[i]]
|
||
else
|
||
let g:paras[parcounter] .= "\n".doc[i]
|
||
endif
|
||
endif
|
||
|
||
let i += 1
|
||
endfor
|
||
" }}}
|
||
" Create false 'blank' para number 0 to make looping easier. {{{
|
||
call insert(g:ptype, 'blank')
|
||
call insert(g:pindent, 0)
|
||
call insert(g:paras, '')
|
||
call insert(g:plinen, 0)
|
||
" Create false 'blank' para on the end
|
||
call add(g:ptype, 'blank')
|
||
call add(g:pindent, 0)
|
||
call add(g:paras, '')
|
||
call add(g:plinen, 0)
|
||
" }}}
|
||
" Loop through paragraphs to concatenate simple tables. {{{
|
||
if string(g:ptype) =~ "'simpletbl'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'simpletbl'
|
||
" Check if last line matches simple table syntax
|
||
if g:paras[i] !~ '\n\s*=\{2,}\(\s\+=\{2,}\)\+\s*$' && i < len(g:paras)-1
|
||
let g:paras[i] = g:paras[i]."\n\n".g:paras[i+1]
|
||
" Remove elements from appropriate tables
|
||
call remove(g:paras, i+1)
|
||
call remove(g:pindent, i+1)
|
||
call remove(g:ptype, i+1)
|
||
call remove(g:plinen, i+1)
|
||
let i -= 1
|
||
endif
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Loop through empty paragraphs to make them really empty. {{{
|
||
if string(g:ptype) =~ "'empty'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'empty'
|
||
let g:paras[i] = ''
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Loop through rawlatex paragraphs correct next paragraphs. {{{
|
||
if string(g:ptype) =~ "'rawlatex'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'rawlatex'
|
||
if g:pindent[i+1] > g:pindent[i]
|
||
let g:ptype[i+1] = 'rawlatexcontent'
|
||
endif
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Loop through rawboth paragraphs correct next paragraphs. {{{
|
||
if string(g:ptype) =~ "'rawboth'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'rawboth'
|
||
if g:pindent[i+1] > g:pindent[i]
|
||
let g:ptype[i+1] = 'rawbothcontent'
|
||
endif
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Loop through rawhtml paragraphs correct next paragraphs. {{{
|
||
if string(g:ptype) =~ "'rawhtml'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'rawhtml'
|
||
if g:pindent[i+1] > g:pindent[i]
|
||
let g:ptype[i+1] = 'rawhtmlcontent'
|
||
endif
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Loop through p paragraphs to sort out additional types (dl). {{{
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'p'
|
||
let parlines = split(g:paras[i], '\n')
|
||
if len(parlines) > 1 && g:paras[i] !~ '^\s*--\?'
|
||
let dlpindent1 = strlen(matchstr(parlines[0], '^\s*'))
|
||
let dlpindent2 = strlen(matchstr(parlines[1], '^\s*'))
|
||
if dlpindent2 > dlpindent1
|
||
let g:ptype[i] = 'dl'
|
||
endif
|
||
endif
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
" }}}
|
||
" Loop through paragraphs to sort out prequoted type. {{{
|
||
" This par type could be catched only in second par, so we don't have to
|
||
" start from 0
|
||
let i = 1
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'p' || g:ptype[i] == 'verse' || g:ptype[i] =~ 'li'
|
||
if g:paras[i] =~ "^\\s*[][<>!:;=|()\"#%'*+$\&,./\?@^_`{}\~-]"
|
||
if g:paras[i-1] =~ '::\s*$' && g:paras[i-1] !~ '^\s*\.\. \w\+::\s*$' && g:pindent[i] == g:pindent[i-1]
|
||
if g:ptype[i] == 'anonlink'
|
||
let parlines = split(g:paras[i], '\n')
|
||
for line in parlines
|
||
call filter(g:vst_anonhlinkdb, 'v:val !~ "'.line.'"')
|
||
endfor
|
||
endif
|
||
let g:ptype[i] = 'prequoted'
|
||
let g:paras[i] = substitute(g:paras[i], '\[', '\[', 'g')
|
||
let g:paras[i] = substitute(g:paras[i], '_', '\_', 'g')
|
||
"let g:paras[i-1] = substitute(g:paras[i-1], '::\s*$', ':', '')
|
||
endif
|
||
endif
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
" }}}
|
||
" Create auto numbered footnotes database {{{
|
||
let g:autofootnotes = []
|
||
if string(g:ptype) =~ "'autofootnote'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'autofootnote'
|
||
let g:autofootnotes += [g:paras[i]]
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Check and embrace paragraphs in pre tags <pre> (::) {{{
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
" Remove trailing spaces from the end of paragraph. They are meaningless
|
||
" and can cause problems.
|
||
let g:paras[i] = substitute(g:paras[i], '\s\+$', '', '')
|
||
if strpart(g:paras[i], strlen(g:paras[i])-2) == '::' && g:paras[i] !~ '^\s*\.\. [a-zA-Z0-9_-]\+::\s*$' || g:ptype[i] == '2html'
|
||
" For proper embedding of pre into lists I have to set indentation
|
||
" level not to indentation of paragraph (including
|
||
" enumeration/leading character) but indentation of last line.
|
||
let plines = split(g:paras[i], '\n')
|
||
if g:ptype[i] == 'oli'
|
||
" LISTDEF:
|
||
if plines[-1] =~ '^\s*(\?\(\d\+\|[a-zA-Z]\|[icdvlmxICDVLMX]\+\|#\)[\]:.)}]\s*'
|
||
let initind = strlen(matchstr(plines[-1], '^\s*(\?\(\d\+\|[a-zA-Z]\|[icdvlmxICDVLMX]\+\|#\)[\]:.)}]\s*\ze'))
|
||
else
|
||
let initind = strlen(matchstr(plines[-1], '^\s*'))
|
||
endif
|
||
elseif g:ptype[i] == 'uli'
|
||
" LISTDEF:
|
||
if plines[-1] =~ '^\s*\zs'.s:vst_bulletdef.'\s*'
|
||
let initind = strlen(matchstr(plines[-1], '^\s*\zs'.s:vst_bulletdef.'\s\+\ze'))
|
||
else
|
||
let initind = strlen(matchstr(plines[-1], '^\s*'))
|
||
endif
|
||
elseif g:ptype[i] == 'dl'
|
||
let initind = strlen(matchstr(plines[-1], '^\s*'))
|
||
elseif g:ptype[i] == 'optlist'
|
||
let initind = strlen(matchstr(plines[-1], '^\s*'))
|
||
elseif g:ptype[i] =~ '^MED'
|
||
if plines[-1] =~ '^\s*\.\. '
|
||
let initind = strlen(matchstr(plines[-1], '^\s*\.\. \ze'))
|
||
else
|
||
let initind = strlen(matchstr(plines[-1], '^\s*'))
|
||
endif
|
||
else
|
||
let initind = g:pindent[i]
|
||
endif
|
||
let j = i + 1
|
||
while j < len(g:paras)
|
||
if initind >= g:pindent[j] || g:ptype[j] == 'notend' || g:ptype[j] == 'blank'
|
||
call insert(g:paras, '</vim:pre>', j)
|
||
call insert(g:pindent, g:pindent[j-1], j)
|
||
call insert(g:ptype, 'prend', j)
|
||
call insert(g:plinen, 0, j)
|
||
|
||
if g:ptype[i] == '2html'
|
||
let g:paras[i] = VST_FirstLine(g:paras[i])
|
||
let g:paras[i] = substitute(g:paras[i], '\s\+', ' ', 'g')
|
||
let darray = split(g:paras[i], ' ')
|
||
let data = ''
|
||
if len(darray) > 2
|
||
let data .= darray[2]
|
||
if len(darray) > 3
|
||
" Looks strange but need something not likely
|
||
" to occur in colorscheme name and acceptable
|
||
" as class name
|
||
let data .= '----'.darray[3]
|
||
endif
|
||
endif
|
||
let g:paras[i] = ''
|
||
call insert(g:paras, '<vim:pre class="tohtml-'.data.'">', i+1)
|
||
else
|
||
if g:paras[i] =~ '^\s*::\s*$'
|
||
call insert(g:paras, '<vim:pre'.VST_AddClass(i, 1, ' ', '').'>', i+1)
|
||
else
|
||
call insert(g:paras, '<vim:pre>', i+1)
|
||
endif
|
||
endif
|
||
call insert(g:pindent, g:pindent[i+1], i+1)
|
||
call insert(g:ptype, 'prebegin', i+1)
|
||
call insert(g:plinen, 0, i+1)
|
||
|
||
" Don't allow for checking inside embraced fragment for
|
||
" pre start conditions
|
||
let i = j
|
||
|
||
break
|
||
else
|
||
if g:ptype[j] == 'anonlink'
|
||
let parlines = split(g:paras[j], '\n')
|
||
for line in parlines
|
||
call filter(g:vst_anonhlinkdb, 'v:val !~ "'.line.'"')
|
||
endfor
|
||
endif
|
||
let g:ptype[j] = 'pre'
|
||
let g:paras[j] = substitute(g:paras[j], '$', '\n', '')
|
||
" In pre paragraphs special characters also have to be
|
||
" escaped.
|
||
let g:paras[j] = VST_SpecCharacter(g:paras[j])
|
||
" Prevent splitting for auto footnotes and hyperlinks or
|
||
" special treatment of backslashes
|
||
let g:paras[j] = substitute(g:paras[j], '`', '\`', 'g')
|
||
let g:paras[j] = substitute(g:paras[j], '\.', '\.', 'g')
|
||
let g:paras[j] = substitute(g:paras[j], '\[', '\[', 'g')
|
||
let g:paras[j] = substitute(g:paras[j], '\\', '\\', 'g')
|
||
let g:paras[j] = substitute(g:paras[j], '_', '\_', 'g')
|
||
let g:paras[j] = substitute(g:paras[j], '|', '\|', 'g')
|
||
|
||
endif
|
||
let j += 1
|
||
endwhile
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
" }}}
|
||
" Build databases NOW. {{{
|
||
" For this we have to glue together g:paras,
|
||
" split it along \n and perform other footnote detection actions.
|
||
" But we want to make it only once on first parsing, not inside of tables
|
||
if !exists('b:vst_first_parsing')
|
||
|
||
" Some actions should be taken only first time when parsing whole file (not in
|
||
" tables cells). Set this variable and unlet it when returning from export
|
||
let b:vst_first_parsing = 1
|
||
|
||
let fntext = split(join(g:paras, "\n\n"), "\n")
|
||
|
||
" Create hyperlink and other databases
|
||
call VST_CreateDBs(fntext)
|
||
|
||
" Check how many numbered footnotes are in file
|
||
let numberedfnotes = filter(copy(fntext), 'v:val =~ "^\\s*\\.\\. \\[\\d\\+\\]"')
|
||
let fnotesnumbers = []
|
||
for line in numberedfnotes
|
||
let fnotesnumbers += [matchstr(line, '^\s*\.\. \[\zs\d\+\ze]')]
|
||
endfor
|
||
let s:maxfnumber = max(fnotesnumbers)
|
||
|
||
" Check how many labeled footnotes is in file and build labels db
|
||
" Dictionary with key -> text label, value -> number of footnote
|
||
let g:labeledfnotes = filter(copy(fntext), 'v:val =~ "\\[#\\k\\+\\]_"')
|
||
let g:lfnotes = {}
|
||
let k = s:maxfnumber + 1
|
||
let i = 0
|
||
while i < len(g:labeledfnotes)
|
||
let label = matchstr(g:labeledfnotes[i], '\[#\zs\k\+\ze]_')
|
||
let g:lfnotes[label] = k
|
||
let i += 1
|
||
let k += 1
|
||
endwhile
|
||
let s:maxlnumber = len(g:labeledfnotes)
|
||
|
||
" Build citation database, only list of citation labels:
|
||
let citlabels = filter(copy(fntext), 'v:val =~ "\\[\\k\\+\\]_"')
|
||
let g:clabels = []
|
||
let i = 0
|
||
while i < len(citlabels)
|
||
let g:clabels += [matchstr(citlabels[i], '\[\zs\k\+\ze]_')]
|
||
let i += 1
|
||
endwhile
|
||
|
||
endif
|
||
" }}}
|
||
" Build replacement database. {{{
|
||
if string(g:ptype) =~ "'replacement'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'replacement'
|
||
let from = matchstr(g:paras[i], '^\s*\.\. |\zs.\{-}\ze|')
|
||
let into = matchstr(g:paras[i], '^\s*\.\. |.\{-}|\s\+\zs.*')
|
||
let g:vst_replacedb[from] = into
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Detect and create multi element directives (MED) {{{
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] =~ '^MED'
|
||
let firstpar = matchstr(g:paras[i], '^\s*\.\. \w\+::\s*\zs.*')
|
||
" Header of MED {{{
|
||
if g:ptype[i] == 'MED'
|
||
let medtype = matchstr(g:paras[i], '^\s*\.\. \zs\w\+\ze::')
|
||
elseif g:ptype[i] =~ '-footnote$'
|
||
let medtype = 'footnote'
|
||
elseif g:ptype[i] =~ '-figure$'
|
||
let medtype = 'figure'
|
||
elseif g:ptype[i] =~ '-autofootnote$'
|
||
let medtype = 'autofootnote'
|
||
elseif g:ptype[i] =~ '-citation$'
|
||
let medtype = 'citation'
|
||
elseif g:ptype[i] =~ '-class$'
|
||
let medtype = 'class'
|
||
elseif g:ptype[i] =~ '-compound$'
|
||
let medtype = 'compound'
|
||
elseif g:ptype[i] =~ '-comment$'
|
||
let medtype = 'comment'
|
||
elseif g:ptype[i] =~ '-container$'
|
||
let medtype = 'container'
|
||
elseif g:ptype[i] =~ '-labelfootnote$'
|
||
let medtype = 'labelfootnote'
|
||
elseif g:ptype[i] =~ '-pullquote$'
|
||
let medtype = 'pullquote'
|
||
elseif g:ptype[i] =~ '-block$'
|
||
let medtype = 'block'
|
||
elseif g:ptype[i] =~ '-topic$'
|
||
let medtype = 'topic'
|
||
elseif g:ptype[i] =~ '-sidebar$'
|
||
let medtype = 'sidebar'
|
||
elseif g:ptype[i] =~ '-unknown$'
|
||
let medtype = 'unknown'
|
||
endif
|
||
|
||
let divindent = repeat(' ', g:pindent[i])
|
||
if medtype =~? '\(\<note\|tip\|warning\|attention\|caution\|danger\|error\|hint\|important\|admonition\)'
|
||
if medtype == 'admonition'
|
||
if firstpar =~ '\n\s*:class:'
|
||
let class = VST_IdMaker(matchstr(firstpar, '\n\s*:class:\s*\zs.*\ze\s*'))
|
||
let name = matchstr(firstpar, '^.*\ze\s*\n')
|
||
else
|
||
let name = matchstr(firstpar, '^.*\ze\s*$')
|
||
let class = 'note'
|
||
endif
|
||
let g:paras[i] = divindent.'<vim:div class="'.tolower(class).VST_AddClass(i,0,' ','').'">'
|
||
let title = name
|
||
let firstpar = ''
|
||
else
|
||
let g:paras[i] = divindent.'<vim:div class="'.tolower(medtype).VST_AddClass(i,0,' ','').'">'
|
||
let title = substitute(tolower(medtype), '^.', '\U\0', '')
|
||
endif
|
||
|
||
let title = divindent.'<vim:p><vim:span class="notetitle">'.title.'</vim:span></vim:p>'
|
||
|
||
if firstpar != ''
|
||
let firstpar = substitute(firstpar, '\(^\|\n\)\s\+', '\n', 'g')
|
||
let g:paras[i] = g:paras[i]."\n".title.VST_Structure(split(firstpar, "\n"))
|
||
else
|
||
let g:paras[i] = g:paras[i]."\n".title."\n"
|
||
endif
|
||
|
||
let medtype = 'div'
|
||
|
||
elseif medtype == 'figure'
|
||
" figure MED {{{
|
||
" supported sub-directives: alt, height, width, scale, align,
|
||
" target, class, identify, figwidth, figclass
|
||
let src = ''
|
||
let width = ''
|
||
let height = ''
|
||
let alt = ''
|
||
let title = ''
|
||
let identify = ''
|
||
let scale = ''
|
||
let target = ''
|
||
let class = ''
|
||
let align = ''
|
||
let figalign = ''
|
||
let figwidth = ''
|
||
let figclass = ''
|
||
let parlines = split(g:paras[i], '\n')
|
||
for parline in parlines
|
||
let parline = substitute(parline, '^\s*', '', '')
|
||
if src == ''
|
||
let src = matchstr(parline, '\.\. figure::\s*\zs.\{-}\ze\s*$')
|
||
if !filereadable(escape(src, ' \%#'))
|
||
let noimage = 1
|
||
let g:vst_error .= "No image: ".src."\n"
|
||
else
|
||
let noimage = 0
|
||
endif
|
||
endif
|
||
if width == ''
|
||
let width = matchstr(parline, ':width:\s*\zs.\{-}\ze\s*$')
|
||
endif
|
||
if height == ''
|
||
let height = matchstr(parline, ':height:\s*\zs.\{-}\ze\s*$')
|
||
endif
|
||
if alt == ''
|
||
let alt = matchstr(parline, ':alt:\s*\zs.\{-}\ze\s*$')
|
||
endif
|
||
if title == ''
|
||
let title = matchstr(parline, ':title:\s*\zs.\{-}\ze\s*$')
|
||
endif
|
||
if align == ''
|
||
let align = matchstr(parline, ':align:\s*\zs.\{-}\ze\s*$')
|
||
endif
|
||
if figwidth == ''
|
||
let figwidth = matchstr(parline, ':figwidth:\s*\zs.\{-}\ze\s*$')
|
||
endif
|
||
if figclass == ''
|
||
let figclass = matchstr(parline, ':figclass:\s*\zs.\{-}\ze\s*$')
|
||
endif
|
||
if figalign == ''
|
||
let figalign = matchstr(parline, ':figalign:\s*\zs.\{-}\ze\s*$')
|
||
endif
|
||
if scale == ''
|
||
let scale = matchstr(parline, ':scale:\s*\zs.\{-}\ze\s*$')
|
||
if scale =~ '\D'
|
||
let scale = ''
|
||
endif
|
||
endif
|
||
if target == ''
|
||
let target = matchstr(parline, ':target:\s*\zs.\{-}\ze\s*$')
|
||
if target == 'self' && src != ''
|
||
let target = src
|
||
endif
|
||
while target =~ '_\s*$'
|
||
let title = matchstr(target, '^\s*\(`\?\)\zs.*\ze\1_\s*$')
|
||
" If ends in _ it is probably indirect link, process it
|
||
if has_key(g:vst_hlinkdb, title) && g:vst_hlinkdb[title] != ''
|
||
let target = escape(g:vst_hlinkdb[title], '&\~')
|
||
else
|
||
let target = '#l'.tolower(VST_IdMaker(title))
|
||
endif
|
||
endwhile
|
||
endif
|
||
if class == ''
|
||
let class = matchstr(parline, ':class:\s*\zs.\{-}\ze\s*$')
|
||
endif
|
||
if identify == ''
|
||
let identify = matchstr(parline, ':identify:')
|
||
if identify != ''
|
||
if executable('identify') && noimage == 0
|
||
let [width, height] = VST_IdentifyImage(src, parline)
|
||
else
|
||
let [width, height] = ['', '']
|
||
endif
|
||
endif
|
||
endif
|
||
endfor
|
||
|
||
if src != ''
|
||
let src = 'src="'.VST_ProtectLiteral(src).'"'
|
||
endif
|
||
if scale != ''
|
||
if width != ''
|
||
let width = width*scale/100
|
||
endif
|
||
if height != ''
|
||
let height = height*scale/100
|
||
endif
|
||
endif
|
||
if width != ''
|
||
let width = 'width="'.width.'"'
|
||
endif
|
||
if height != ''
|
||
let height = 'height="'.height.'"'
|
||
endif
|
||
if alt != ''
|
||
let alt = 'alt="'.alt.'"'
|
||
endif
|
||
if title != ''
|
||
let title = 'title="'.title.'"'
|
||
endif
|
||
" reST compatibility, if there is no figalign option but align
|
||
" is defined it is probably reST document not supporting
|
||
" figalign.
|
||
if figalign == '' && align != ''
|
||
let figalign = align
|
||
let align = ''
|
||
endif
|
||
if class != ''
|
||
if align == ''
|
||
let class = 'class="'.class.'"'
|
||
else
|
||
let class = 'class="'.class.' vst'.align.'"'
|
||
endif
|
||
else
|
||
if align == ''
|
||
let class = ''
|
||
else
|
||
let class = 'class="vst'.align.'"'
|
||
endif
|
||
endif
|
||
if target != ''
|
||
if target =~ '_\s*$'
|
||
let address = matchstr(VST_Hyperlink(target), '^.\{-}>\ze')
|
||
else
|
||
let address = '<vim:a href="'.VST_ProtectLiteral(target).'">'
|
||
endif
|
||
let imagepart = address."\n<vim:img ".src.' '.width.' '.height.' '.class.' '.alt.' '.title." />\n</vim:a>"
|
||
else
|
||
let imagepart = "\n<vim:img ".src.' '.width.' '.height.' '.class.' '.alt.' '.title." />\n"
|
||
endif
|
||
|
||
if figclass != ''
|
||
if figalign == ''
|
||
let figclass = 'class="'.figclass.'"'
|
||
else
|
||
let figclass = 'class="'.figclass.' vst'.figalign.'"'
|
||
endif
|
||
else
|
||
if figalign == ''
|
||
let figclass = 'class="figure"'
|
||
else
|
||
let figclass = 'class="figure vst'.figalign.'"'
|
||
endif
|
||
endif
|
||
|
||
if figwidth != ''
|
||
if figwidth == 'image'
|
||
if exists('width')
|
||
let figw = matchstr(width, '\d\+')
|
||
let figwidth = 'style="width:'.figw.'px"'
|
||
endif
|
||
else
|
||
let figwidth = 'style="width:'.figwidth.'px"'
|
||
endif
|
||
endif
|
||
let g:paras[i] = divindent.'<vim:figure '.figclass.' '.figwidth.">\n".divindent.imagepart
|
||
" }}}
|
||
elseif medtype == 'footnote'
|
||
" Footnote \[\d\+\] {{{
|
||
let g:paras[i] = VST_SpecCharacter(g:paras[i])
|
||
let indent = repeat(' ', g:pindent[i])
|
||
let g:paras[i] =
|
||
\ substitute(g:paras[i], '^\s*\.\. \[\(\d\+\)\]', indent.'<vim:footnote>\n'.indent.'<vim:div class="fnumber"><vim:a href="#target-\1" name="footnote-\1">[\1]</vim:a></vim:div>\n'.indent.'<vim:div class="ftext">', '')
|
||
let firstpar = matchstr(g:paras[i], '<vim:div class="ftext">\zs.*')
|
||
let firstpar = substitute(firstpar, '\(^\|\n\)\s\+', '\n', 'g')
|
||
let firstpar = VST_Structure(split(firstpar, "\n"))
|
||
let g:paras[i] = substitute(g:paras[i], '<vim:div class="ftext">\zs.*', '', '')
|
||
let g:paras[i] .= firstpar
|
||
" }}}
|
||
elseif medtype == 'autofootnote'
|
||
" Footnote \[#\] {{{
|
||
let g:paras[i] = VST_SpecCharacter(g:paras[i])
|
||
let indent = repeat(' ', g:pindent[i])
|
||
if !exists('b:vst_afs')
|
||
let g:autofnote = s:maxfnumber + s:maxlnumber + 1
|
||
let b:vst_afs = 1
|
||
endif
|
||
let k = g:autofnote
|
||
let g:paras[i] =
|
||
\ substitute(g:paras[i], '^\s*\.\. \[#\]', indent.'<vim:footnote>\n'.indent.'<vim:div class="fnumber"><vim:a href="#target-'.k.'" name="footnote-'.k.'">['.k.']</vim:a></vim:div>\n'.indent.'<vim:div class="ftext">', '')
|
||
let firstpar = matchstr(g:paras[i], '<vim:div class="ftext">\zs.*')
|
||
let firstpar = substitute(firstpar, '\(^\|\n\)\s\+', '\n', 'g')
|
||
let firstpar = VST_Structure(split(firstpar, "\n"))
|
||
let g:paras[i] = substitute(g:paras[i], '<vim:div class="ftext">\zs.*', '', '')
|
||
let g:paras[i] .= firstpar
|
||
let g:autofnote += 1
|
||
let medtype = 'footnote'
|
||
" }}}
|
||
elseif medtype == 'labelfootnote'
|
||
" Footnote \[#\k\+\] {{{
|
||
let g:paras[i] = VST_SpecCharacter(g:paras[i])
|
||
let indent = repeat(' ', g:pindent[i])
|
||
let label = matchstr(g:paras[i], '^\s*\.\. \[#\zs\k\+\ze\]')
|
||
let k = g:lfnotes[label]
|
||
let g:paras[i] =
|
||
\ substitute(g:paras[i], '^\s*\.\. \[#\k\+\]', indent.'<vim:footnote>\n'.indent.'<vim:div class="fnumber"><vim:a href="#target-'.k.'" name="footnote-'.k.'">['.k.']</vim:a></vim:div>\n'.indent.'<vim:div class="ftext">', '')
|
||
let firstpar = matchstr(g:paras[i], '<vim:div class="ftext">\zs.*')
|
||
let firstpar = substitute(firstpar, '\(^\|\n\)\s\+', '\n', 'g')
|
||
let firstpar = VST_Structure(split(firstpar, "\n"))
|
||
let g:paras[i] = substitute(g:paras[i], '<vim:div class="ftext">\zs.*', '', '')
|
||
let g:paras[i] .= firstpar
|
||
let medtype = 'footnote'
|
||
" }}}
|
||
elseif medtype == 'citation'
|
||
" Citation \[\k\+\] {{{
|
||
let g:paras[i] = VST_SpecCharacter(g:paras[i])
|
||
let indent = repeat(' ', g:pindent[i])
|
||
let label = matchstr(g:paras[i], '^\s*\.\. \[\zs\k\+\ze\]')
|
||
let g:paras[i] =
|
||
\ substitute(g:paras[i], '^\s*\.\. \[\k\+\]', indent.'<vim:citation>\n'.indent.'<vim:div class="cnumber"><vim:a href="#ctarget-'.label.'" name="citation-'.label.'">['.label.']</vim:a></vim:div>\n'.indent.'<vim:div class="ctext">', '')
|
||
let firstpar = matchstr(g:paras[i], '<vim:div class="ctext">\zs.*')
|
||
let firstpar = substitute(firstpar, '\(^\|\n\)\s\+', '\n', 'g')
|
||
let firstpar = VST_Structure(split(firstpar, "\n"))
|
||
let g:paras[i] = substitute(g:paras[i], '<vim:div class="ctext">\zs.*', '', '')
|
||
let g:paras[i] .= firstpar
|
||
" }}}
|
||
elseif medtype == 'class'
|
||
" Multi element class {{{
|
||
" We don't need to change content of par, it is purely virtual MED
|
||
let classname = matchstr(g:paras[i], '^\s*\.\. class::\s*\zs.*\ze\s*$')
|
||
let g:paras[i] = VST_IdMaker(classname)
|
||
let indent = repeat(' ', g:pindent[i])
|
||
" }}}
|
||
elseif medtype == 'comment'
|
||
" Multi element comment {{{
|
||
let indent = repeat(' ', g:pindent[i])
|
||
let g:paras[i] = '<vim:comment>'.g:paras[i]
|
||
" }}}
|
||
elseif medtype == 'compound'
|
||
" Multi element compound {{{
|
||
let indent = repeat(' ', g:pindent[i])
|
||
if firstpar =~ '\n\s*:class:'
|
||
let class = 'vstcompound '.VST_IdMaker(matchstr(firstpar, '\n\s*:class:\s*\zs.*\ze\s*\(\n\|$\)'))
|
||
else
|
||
let class = 'vstcompound'
|
||
endif
|
||
let g:paras[i] = indent.'<vim:block id="id-'.i.'" class="'.tolower(class).'">'
|
||
let g:vst_containers += [tolower(class)]
|
||
|
||
let medtype = 'block'
|
||
|
||
" }}}
|
||
elseif medtype == 'container'
|
||
" Multi line div {{{
|
||
let indent = repeat(' ', g:pindent[i])
|
||
let class = matchstr(g:paras[i], '^\s*\.\. container::\s*\zs.*\ze\s*')
|
||
let class = VST_IdMaker(class)
|
||
let g:paras[i] = indent.'<vim:container id="id-'.i.'" class="'.tolower(class).'">'
|
||
let g:vst_containers += [tolower(class)]
|
||
" }}}
|
||
elseif medtype == 'topic'
|
||
" Multi element topic {{{
|
||
let indent = repeat(' ', g:pindent[i])
|
||
if firstpar =~ '\n\s*:class:'
|
||
let class = 'topic '.VST_IdMaker(matchstr(firstpar, '\n\s*:class:\s*\zs.*\ze\s*'))
|
||
let name = matchstr(firstpar, '^.*\ze\s*\n')
|
||
else
|
||
let name = matchstr(firstpar, '^.*\ze\s*$')
|
||
let class = 'topic'
|
||
endif
|
||
let g:paras[i] = divindent.'<vim:topic class="'.tolower(class).'">'
|
||
let title = name
|
||
if title != ''
|
||
let title = divindent.'<vim:p><vim:span class="notetitle">'.title.'</vim:span></vim:p>'
|
||
else
|
||
let title = ''
|
||
endif
|
||
let firstpar = ''
|
||
|
||
let g:paras[i] .= "\n".title
|
||
" }}}
|
||
elseif medtype == 'sidebar'
|
||
" Multi element sidebar {{{
|
||
let indent = repeat(' ', g:pindent[i])
|
||
if firstpar =~ '\n\s*:class:'
|
||
let class = 'vstsidebar '.VST_IdMaker(matchstr(firstpar, '\n\s*:class:\s*\zs.*\ze\s*\(\n\|$\)'))
|
||
else
|
||
let class = 'vstsidebar'
|
||
endif
|
||
let name = matchstr(firstpar, '^.*\ze\s*\n')
|
||
if firstpar =~ ':subtitle:'
|
||
let subtitle = matchstr(firstpar, ':subtitle:\s*\zs.\{-}\ze\s*\(\n\|$\)')
|
||
else
|
||
let subtitle = ''
|
||
endif
|
||
let g:paras[i] = divindent.'<vim:sidebar class="'.tolower(class).'">'
|
||
let title = name
|
||
if title != ''
|
||
let title = divindent.'<vim:p><vim:span class="notetitle">'.title.'</vim:span></vim:p>'
|
||
else
|
||
let title = ''
|
||
endif
|
||
|
||
if subtitle != ''
|
||
let title .= "\n".'<vim:p class="notesubtitle">'.subtitle.'</vim:p>'
|
||
endif
|
||
let firstpar = ''
|
||
|
||
let g:paras[i] .= "\n".title
|
||
" }}}
|
||
elseif medtype == 'block'
|
||
" Multi line div {{{
|
||
let indent = repeat(' ', g:pindent[i])
|
||
let class = matchstr(g:paras[i], '^\s*\.\. block::\s*\zs.*\ze\s*')
|
||
let class = VST_IdMaker(class)
|
||
let g:paras[i] = indent.'<vim:block id="id-'.i.'" class="'.tolower(class).'">'
|
||
let g:vst_containers += [tolower(class)]
|
||
" }}}
|
||
elseif medtype == 'pullquote'
|
||
" Bigger blockquote {{{
|
||
let g:paras[i] = VST_SpecCharacter(g:paras[i])
|
||
let indent = repeat(' ', g:pindent[i])
|
||
let g:paras[i] =
|
||
\ substitute(g:paras[i], '^\s*\.\. pull-quote::', indent.'<vim:pullquote'.VST_AddClass(i,1,' ','').'>', '')
|
||
" }}}
|
||
elseif medtype == 'unknown'
|
||
" Unknown multi element div {{{
|
||
let indent = repeat(' ', g:pindent[i])
|
||
let g:paras[i] = indent.'<vim:unknown>'.g:paras[i]
|
||
" }}}
|
||
else
|
||
let g:paras[i] = divindent.'<vim:div class="note">'
|
||
let title = 'Unknown'
|
||
let title = divindent.'<vim:p><vim:span class="notetitle">'.title.'</vim:span></vim:p>'
|
||
if firstpar != ''
|
||
let firstpar = substitute(firstpar, '\(^\|\n\)\s\+', '', 'g')
|
||
let g:paras[i] = g:paras[i]."\n".title.VST_Structure(split(firstpar, "\n"))
|
||
else
|
||
let g:paras[i] = g:paras[i]."\n".title."\n"
|
||
endif
|
||
endif
|
||
|
||
" }}}
|
||
let j = i + 1
|
||
while j < len(g:paras)
|
||
let noteindent = g:pindent[j] - g:pindent[i]
|
||
if g:pindent[i] >= g:pindent[j] || g:ptype[j] == 'notend' || g:ptype[j] == 'blank'
|
||
if medtype =~ 'footnote\|citation'
|
||
call insert(g:paras, repeat(' ', g:pindent[j]).'</vim:div></vim:'.medtype.'>', j)
|
||
elseif medtype == 'class'
|
||
if j - i == 1
|
||
call insert(g:paras, repeat(' ', g:pindent[j]).'', j)
|
||
else
|
||
call insert(g:paras, repeat(' ', g:pindent[j]).'<vim:class'.classname.' />', j)
|
||
endif
|
||
else
|
||
call insert(g:paras, repeat(' ', g:pindent[j]).'</vim:'.medtype.'>', j)
|
||
endif
|
||
call insert(g:pindent, g:pindent[i], j)
|
||
"call insert(g:pindent, g:pindent[j-1], j)
|
||
call insert(g:ptype, 'notend', j)
|
||
call insert(g:plinen, 0, j)
|
||
break
|
||
else
|
||
"if g:pindent[j] == noteindent
|
||
if g:ptype[j] == 'blockquote' && g:pindent[j] == noteindent
|
||
let g:ptype[j] = 'p'
|
||
endif
|
||
endif
|
||
let j += 1
|
||
endwhile
|
||
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
" }}}
|
||
" Detect and create transitions (<hr>) {{{
|
||
let i = 0
|
||
for par in g:paras
|
||
if i < len(g:paras)
|
||
if g:paras[i] !~ '\n' && g:paras[i] =~ '^\s*'.s:vst_headdef.'\s*$'
|
||
if g:ptype[i] !~ '^pre'
|
||
let g:ptype[i] = 'hr'
|
||
let class = VST_AddClass(i, 1, '', '')
|
||
let g:paras[i] = substitute(g:paras[i], '.*', '\n<vim:hr '.class.'/>\n', '')
|
||
endif
|
||
endif
|
||
endif
|
||
let i += 1
|
||
endfor
|
||
" }}}
|
||
" Detect blockquote paragraphs {{{
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'p' && g:pindent[i] > g:pindent[i-1]
|
||
if g:ptype[i] !~ '^pre' && g:ptype[i-1] !~ '^MED' && g:ptype[i-1] !~ 'optlist'
|
||
let g:ptype[i] = 'blockquote'
|
||
endif
|
||
if g:ptype[i-1] =~ '^MED' && g:pindent[i] > g:pindent[i-1] + 3
|
||
let g:ptype[i] = 'blockquote'
|
||
endif
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
" }}}
|
||
" Detect if par is a header (<hx>) {{{
|
||
let i = 0
|
||
let h1 = ''
|
||
let h2 = ''
|
||
let h3 = ''
|
||
let h4 = ''
|
||
let h5 = ''
|
||
while i < len(g:paras)
|
||
if g:ptype[i] !~ '^pre'
|
||
if g:paras[i] =~ '\n\s*'.s:vst_headdef.'\s*\(\n\|$\)' && g:ptype[i] !~ 'table' && g:paras[i] !~ 'vim:comment'
|
||
let parlines = split(g:paras[i], '\n')
|
||
if parlines[1] =~ '^\s*'.s:vst_headdef.'\s*$'
|
||
let double = ' '
|
||
elseif parlines[0] == parlines[2] && parlines[0] =~ '^\s*'.s:vst_headdef.'\s*$'
|
||
let double = 'd'
|
||
call remove(parlines, 0)
|
||
endif
|
||
let lchar = matchstr(parlines[1], '.\ze\s*$').double
|
||
if lchar =~ s:vst_headchars
|
||
if h1 == '' || lchar == h1
|
||
let h1 = lchar
|
||
let g:ptype[i] = 'h1'
|
||
elseif h2 == '' || lchar == h2
|
||
let h2 = lchar
|
||
let g:ptype[i] = 'h2'
|
||
elseif h3 == '' || lchar == h3
|
||
let h3 = lchar
|
||
let g:ptype[i] = 'h3'
|
||
elseif h4 == '' || lchar == h4
|
||
let h4 = lchar
|
||
let g:ptype[i] = 'h4'
|
||
elseif h5 == '' || lchar == h5
|
||
let h5 = lchar
|
||
let g:ptype[i] = 'h5'
|
||
else
|
||
let g:ptype[i] = 'h6'
|
||
endif
|
||
let modlchar = substitute(lchar, '[d ]', '', 'g')
|
||
let g:vst_headers[g:ptype[i]] = repeat(modlchar, 9).double
|
||
|
||
if len(parlines) > 2
|
||
let g:paras[i] = join(parlines[0:1], "\n")
|
||
call insert(g:paras, join(parlines[2:], "\n"), i+1)
|
||
call insert(g:pindent, g:pindent[i], i+1)
|
||
call insert(g:plinen, 0, i+1)
|
||
|
||
if parlines[2] =~ '^\s*(\(\d\+\|[a-zA-Z]\|[icdvlmxICDVLMX]\+\|#\))\s'
|
||
" LISTDEF:
|
||
call insert(g:ptype, 'oli', i+1)
|
||
elseif parlines[2] =~ '^\s*\(\d\+\|[a-zA-Z]\|[icdvlmxICDVLMX]\+\|#\)[\]:.)}]\s'
|
||
" LISTDEF:
|
||
call insert(g:ptype, 'oli', i+1)
|
||
elseif parlines[2] =~ '^\s*'.s:vst_bulletdef.'\s'
|
||
call insert(g:ptype, 'uli', i+1)
|
||
elseif parlines[2] =~ '^\s*:.\{-1,}:\(\s\+\|$\)'
|
||
call insert(g:ptype, 'field', i+1)
|
||
elseif parlines[2] =~ '^\s*::\s*$'
|
||
call insert(g:ptype, 'emptypre', i+1)
|
||
elseif parlines[2] =~ '^\s*| '
|
||
call insert(g:ptype, 'verse', i+1)
|
||
elseif parlines[2] =~ '^\s*+-\{3,}'
|
||
call insert(g:ptype, 'table', i+1)
|
||
elseif parlines[2] =~ '^\s*+=\{3,}'
|
||
call insert(g:ptype, 'bltable', i+1)
|
||
elseif parlines[2] =~ '^\s*\(--\|-\|/\|:\|+\)\S.\{-}\( \|$\)' && doc[line] !~ '^\s*\(--\s\|:\S\+:`\)'
|
||
call insert(g:ptype, 'optlist', i+1)
|
||
elseif parlines[2] =~ '^\s*>>>'
|
||
call insert(g:ptype, 'doctest', i+1)
|
||
elseif parlines[2] =~ '^\s*=\{2,}\s\+=\{2,}'
|
||
call insert(g:ptype, 'simpletbl', i+1)
|
||
else
|
||
" Everything after ornament put into next
|
||
" paragraph sub type. Ugly but prevents worse
|
||
" things.
|
||
call insert(g:ptype, 'sub'.g:ptype[i], i+1)
|
||
endif
|
||
else
|
||
let g:paras[i] = join(parlines, "\n")
|
||
endif
|
||
endif
|
||
endif
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
" }}}
|
||
" Formatting
|
||
" Create dl paragraph {{{
|
||
if string(g:ptype) =~ "'dl'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'dl'
|
||
"let initind = strlen(matchstr(g:paras[i], '\n\zs\s*\ze.\{-}'))
|
||
let parlines = split(g:paras[i], '\n')
|
||
let initind = strlen(matchstr(parlines[-1], '^\s*'))
|
||
let j = i + 1
|
||
while j < len(g:paras)
|
||
if g:pindent[j] < initind || g:ptype[j] == 'blank'
|
||
let newind = repeat(' ', g:pindent[j])
|
||
call insert(g:paras, newind.'</vim:dd>'."\n".newind.'</vim:dl>', j)
|
||
call insert(g:pindent, g:pindent[i], j)
|
||
call insert(g:ptype, 'dlend', j)
|
||
call insert(g:plinen, 0, j)
|
||
|
||
call insert(g:paras, repeat(' ', g:pindent[i]).'<vim:dl'.VST_AddClass(i,1,' ','').'>', i)
|
||
call insert(g:pindent, g:pindent[i], i)
|
||
call insert(g:ptype, 'dlbegin', i)
|
||
call insert(g:plinen, 0, i)
|
||
|
||
" Recompensate paragraph inserted before current position.
|
||
let i += 1
|
||
|
||
break
|
||
else
|
||
if g:ptype[j] == 'blockquote'
|
||
if g:pindent[j] == initind
|
||
let g:ptype[j] = 'p'
|
||
endif
|
||
endif
|
||
|
||
endif
|
||
let j += 1
|
||
endwhile
|
||
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Detect and pre-prepare definition list (<dl>) {{{
|
||
if string(g:ptype) =~ "'dl'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'dl'
|
||
let defterm = matchlist(g:paras[i], '^\(.\{-}\n\)\(\s*\)\(.*\)')
|
||
let defpar = split(substitute(defterm[3], '\n\s*', '\n', 'g'), "\n")
|
||
let defterm[1] = VST_SpecCharacter(defterm[1])
|
||
let defpart = "\n".'<vim:dt class="normal">'.defterm[1].'</vim:dt>'."\n".defterm[2].'<vim:dd class="normal">'."\n".defterm[2]
|
||
let g:paras[i] = defpart.VST_Structure(defpar)
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Prepare quoted literal paragraphs (:: <! etc.) {{{
|
||
" This can be only one paragraph so don't worry about other pre troubles
|
||
if string(g:ptype) =~ "'prequoted'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'prequoted'
|
||
" In pre paragraphs special characters also have to be
|
||
" escaped.
|
||
let g:paras[i] = VST_SpecCharacter(g:paras[i])
|
||
" Prevent splitting for auto footnotes and hyperlinks
|
||
let g:paras[i] = substitute(g:paras[i], '\[', '\[', 'g')
|
||
let g:paras[i] = substitute(g:paras[i], '_', '\_', 'g')
|
||
|
||
if g:paras[i-3] =~ '^\s*::\s*$'
|
||
let g:paras[i] = '<vim:pre class="quoted'.VST_AddClass(i-3, 0, ' ', '').'">'
|
||
\."\n".g:paras[i]."\n".'</vim:pre>'
|
||
else
|
||
let g:paras[i] = '<vim:pre class="quoted">'."\n".g:paras[i]
|
||
\."\n".'</vim:pre>'
|
||
endif
|
||
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Create option list paragraph {{{
|
||
if string(g:ptype) =~ "'optlist'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'optlist'
|
||
" Detect indentation of option list
|
||
let listindent = strlen(matchstr(g:paras[i], '^\s*\zs\(--\|-\|/\|:\|+\)\S.\{-} \s*'))
|
||
let j = i + 1
|
||
while j < len(g:paras)
|
||
if g:pindent[j] <= g:pindent[i] || g:ptype[j] == 'blank'
|
||
let newind = repeat(' ', g:pindent[j])
|
||
call insert(g:paras, newind.'</vim:dd>'."\n".newind.'</vim:dl class="option'.VST_AddClass(i,0, ' ','').'">', j)
|
||
call insert(g:pindent, g:pindent[i], j)
|
||
call insert(g:ptype, 'optend', j)
|
||
call insert(g:plinen, 0, j)
|
||
|
||
call insert(g:paras, repeat(' ' , g:pindent[i]).'<vim:dl class="option'.VST_AddClass(i,0, ' ','').'">', i)
|
||
call insert(g:pindent, g:pindent[i], i)
|
||
call insert(g:ptype, 'optbegin', i)
|
||
call insert(g:plinen, 0, i)
|
||
|
||
" Recompensate inserted paragraph before current position.
|
||
let i += 1
|
||
|
||
break
|
||
else
|
||
if g:ptype[j] == 'blockquote'
|
||
if g:pindent[j] == g:pindent[i] + listindent
|
||
let g:ptype[j] = 'p'
|
||
endif
|
||
endif
|
||
|
||
endif
|
||
let j += 1
|
||
endwhile
|
||
|
||
let g:paras[i] = VST_SpecCharacter(g:paras[i])
|
||
let g:paras[i] = substitute(g:paras[i], '^\(\s*\)\(--\|-\|/\|:\|+\)\(\S.\{-}\) ', '\n<vim:dt class="option">\2\3</vim:dt>\n\1<vim:dd class="option">\n\1<vim:p>', '')
|
||
let g:paras[i] = substitute(g:paras[i], '\n\(\s*\)\(--\|-\|/\|:\|+\)\(\S.\{-}\) ', '</vim:p></vim:dd>\n\1<vim:dt class="option">\2\3</vim:dt>\n\1<vim:dd class="option">\n\1<vim:p>', 'g')
|
||
let g:paras[i] = substitute(g:paras[i], '$', '</vim:p>', '')
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Create field list {{{
|
||
if string(g:ptype) =~ "'field'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'field'
|
||
let g:paras[i] = VST_SpecCharacter(g:paras[i])
|
||
let parlines = split(g:paras[i], '\(^\s*\|\n\s*\):\@=')
|
||
let j = 0
|
||
for parline in parlines
|
||
let fkey = tolower(matchstr(parlines[j], '^\s*:\zs.\{-}\ze:'))
|
||
let fcontent = matchstr(parlines[j], '^\s*:.\{-}:\s*\zs.*')
|
||
if fkey == 'date' && fcontent == 'NONE'
|
||
let parlines[j] = ''
|
||
endif
|
||
if fkey != ''
|
||
let g:vst_fielddb[fkey] = fcontent
|
||
endif
|
||
let parlines[j] = substitute(parlines[j], '^\s*:', '<vim:dt class="field">', '')
|
||
let parlines[j] = substitute(parlines[j], '\(vim\)\@<!:', ':</vim:dt><vim:dd class="field">', '')
|
||
let parlines[j] .= '</vim:dd>'."\n"
|
||
let parlines[j] = substitute(parlines[j], '\c\(class="field">\)\(organization\|date\|status\|revision\|version\|dedication\|abstract\|copyright\)', '\1\u\2', 'g')
|
||
" Adjustments for special types of fields: dedication, abstract
|
||
" Has to wait for fixing MEDding of field lists
|
||
let parlines[j] = substitute(parlines[j], 'class="field">Dedication:</vim:dt><vim:dd class="field">', 'class="field fdedication">Dedication</vim:dt><vim:dd class="field fdedication">','')
|
||
let parlines[j] = substitute(parlines[j], 'class="field">Abstract:</vim:dt><vim:dd class="field">', 'class="field fabstract">Abstract</vim:dt><vim:dd class="field fabstract">','')
|
||
let j += 1
|
||
endfor
|
||
let g:paras[i] = join(parlines, "\n")
|
||
let g:paras[i] = '<vim:dl class="field'.VST_AddClass(i,0, ' ', '').'">'.g:paras[i]
|
||
let g:paras[i] = substitute(g:paras[i], '\(Address:</vim:dt><vim:dd class="field">\)\(.\{-}\)</vim:dd>', '\=submatch(1)."<vim:pre class=\"address\">".substitute(submatch(2), "\\(^\\|\\n\\)\\s\\+", "\\n", "g")."</vim:pre></vim:dd>"','g')
|
||
if has('unix')
|
||
" On unices above substitute leaves ^M intead of new line, replace
|
||
" it with real new line
|
||
let g:paras[i] = substitute(g:paras[i], '\%d13', '\n', 'g')
|
||
endif
|
||
let g:paras[i] .= '</vim:dl>'
|
||
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Parse meta paragraphs (.. meta::) {{{
|
||
" Loop creates database, it will be parsed in exports accordingly to its
|
||
" syntax
|
||
if string(g:ptype) =~ "'meta'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'meta'
|
||
let parlines = split(g:paras[i], '\(^\s*\|\n\s*\):\@=')
|
||
let j = 0
|
||
for parline in parlines
|
||
let mkey = tolower(matchstr(parlines[j], '^\s*:\zs.\{-}\ze:'))
|
||
let mcontent = matchstr(parlines[j], '^\s*:.\{-}:\s*\zs.*')
|
||
if mkey != ''
|
||
let g:vst_metadb[mkey] = mcontent
|
||
endif
|
||
let j += 1
|
||
endfor
|
||
let g:paras[i] = ''
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Create image paragraphs (.. image::) {{{
|
||
if string(g:ptype) =~ "'img'"
|
||
let i = 0
|
||
while i < len(g:paras)-1
|
||
if g:ptype[i] == 'img'
|
||
let g:paras[i] = VST_ImagePar(g:paras[i], 1)
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Create comment paragraph - comment (.. comment::) {{{
|
||
if string(g:ptype) =~ "'comment'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'comment'
|
||
let g:paras[i] = '<vim:comment>'.substitute(g:paras[i], '^\s*\.\. comment::', '', '').'</vim:comment>'
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Create rubric paragraph (.. rubric::) {{{
|
||
if string(g:ptype) =~ "'rubric'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'rubric'
|
||
if g:paras[i] =~ ':class:'
|
||
let class = matchstr(g:paras[i], ':class:\s*\zs.*\ze\s*$')
|
||
let g:paras[i] = substitute(g:paras[i], '\s*:class:.*$', '', '')
|
||
let g:paras[i] = '<vim:rubric class="'.class.'">'.substitute(g:paras[i], '\s*\.\. rubric::', '', '').'</vim:rubric>'
|
||
else
|
||
let g:paras[i] = '<vim:rubric'.VST_AddClass(i, 1, ' ', '').'>'.substitute(g:paras[i], '\s*\.\. rubric::', '', '').'</vim:rubric>'
|
||
endif
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Create ul paragraph {{{
|
||
if string(g:ptype) =~ "'uli'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'uli'
|
||
" LISTDEF:
|
||
" Detect style of unordered list
|
||
let style = matchstr(g:paras[i], '^\s*\zs'.s:vst_bulletdef.'\s\+')
|
||
let listindent = strlen(matchstr(g:paras[i], '^\s*\zs'.s:vst_bulletdef.'\s\+'))
|
||
if style =~ '+'
|
||
let ustyle = 'square'
|
||
elseif style =~ '\*'
|
||
let ustyle = 'circle'
|
||
elseif style =~ '-'
|
||
let ustyle = 'disc'
|
||
else
|
||
let ustyle = 'disc'
|
||
endif
|
||
let j = i + 1
|
||
while j < len(g:paras)
|
||
if g:pindent[j] <= g:pindent[i] || g:ptype[j] == 'blank' || g:ptype[j] == 'hr'
|
||
let newind = repeat(' ', g:pindent[j])
|
||
call insert(g:paras, newind.'</vim:li>'."\n".newind.'</vim:ul class="'.ustyle.VST_AddClass(i,0,' ','').'">', j)
|
||
call insert(g:pindent, g:pindent[i], j)
|
||
call insert(g:ptype, 'ulend', j)
|
||
call insert(g:plinen, 0, j)
|
||
|
||
call insert(g:paras, repeat(' ' , g:pindent[i]).'<vim:ul class="'.ustyle.VST_AddClass(i,0,' ','').'">', i)
|
||
call insert(g:pindent, g:pindent[i], i)
|
||
call insert(g:ptype, 'ulbegin', i)
|
||
call insert(g:plinen, 0, i)
|
||
|
||
" Recompensate inserted paragraph before current position.
|
||
let i += 1
|
||
|
||
break
|
||
else
|
||
if g:ptype[j] == 'blockquote'
|
||
if g:pindent[j] == g:pindent[i] + listindent
|
||
let g:ptype[j] = 'p'
|
||
endif
|
||
endif
|
||
|
||
endif
|
||
let j += 1
|
||
endwhile
|
||
|
||
if ustyle == 'disc'
|
||
" Potential danger: this also includes * and +
|
||
let elements = split(g:paras[i], '\(^\|\n\)\s*[\u2022\u2023\u2043\u204c\u204d\u25d8\u25e6\u2619\u2765\u2767-]\s\+')
|
||
elseif ustyle == 'circle'
|
||
let elements = split(g:paras[i], '\(^\|\n\)\s*\*\s\+')
|
||
elseif ustyle == 'square'
|
||
let elements = split(g:paras[i], '\(^\|\n\)\s*+\s\+')
|
||
endif
|
||
for inc in range(len(elements))
|
||
let s:vst_bulletdef = '[\u2022\u2023\u2043\u204c\u204d\u25d8\u25e6\u2619\u2765\u2767*+-]'
|
||
let elements[inc] = substitute(elements[inc], '\n\s*', '\n', 'g')
|
||
let elements[inc] = VST_Structure(split(elements[inc], "\n"))
|
||
endfor
|
||
let g:paras[i] = '<vim:li>'.join(elements, "</vim:li>\n<vim:li>")
|
||
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Create ol paragraph {{{
|
||
if string(g:ptype) =~ "'oli'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'oli'
|
||
" Detect style of ordered list
|
||
" LISTDEF:
|
||
let style = matchstr(g:paras[i], '^\s*(\?\zs\(\d\+\|[a-zA-Z]\|[icdvlmxICDVLMX]\+\|#\)\ze[\]:.)}]\s*')
|
||
let listindent = strlen(matchstr(g:paras[i], '^\s*(\?\zs\(\d\+\|[a-zA-Z]\|[icdvlmxICDVLMX]\+\|#\)[\]:.)}]\s*'))
|
||
if style =~ '^\(I\|[ICDVLMX]\{2,}\)$'
|
||
let ostyle = 'upperroman'
|
||
elseif style =~ '^\(i\|[icdvlmx]\{2,}\)$'
|
||
let ostyle = 'lowerroman'
|
||
elseif style =~ '[a-z]'
|
||
let ostyle = 'loweralpha'
|
||
elseif style =~ '[A-Z]'
|
||
let ostyle = 'upperalpha'
|
||
elseif style =~ '[0-9#]'
|
||
let ostyle = 'decimal'
|
||
endif
|
||
let j = i + 1
|
||
while j < len(g:paras)
|
||
if g:pindent[j] <= g:pindent[i] || g:ptype[j] == 'blank' || g:ptype[j] == 'hr'
|
||
call insert(g:paras, repeat(' ' , g:pindent[j]).'</vim:li>'.repeat(' ' , g:pindent[j]).'</vim:ol class="'.ostyle.VST_AddClass(i,0,' ','').'">', j)
|
||
call insert(g:pindent, g:pindent[i], j)
|
||
call insert(g:ptype, 'olend', j)
|
||
call insert(g:plinen, 0, j)
|
||
|
||
" Get number of first element
|
||
" LISTDEF:
|
||
let start = tolower(matchstr(g:paras[i], '^\s*(\?\zs\(\d\+\|[icdvlmxICDVLMX]\+\|[a-zA-Z]\|#\)\ze'))
|
||
if start == '1' || start == 'a' || start == '#' || start == 'i'
|
||
let number = ''
|
||
elseif start =~ '[0-9]'
|
||
let number = ' start="'.start.'"'
|
||
elseif start =~ '[icdvlmx][icdvlmx]'
|
||
let rtable = split(start, '\ze.')
|
||
let j = 0
|
||
while j < len(rtable)
|
||
if rtable[j] == 'i'
|
||
let rtable[j] = 1
|
||
elseif rtable[j] == 'v'
|
||
let rtable[j] = 5
|
||
elseif rtable[j] == 'x'
|
||
let rtable[j] = 10
|
||
elseif rtable[j] == 'l'
|
||
let rtable[j] = 50
|
||
elseif rtable[j] == 'c'
|
||
let rtable[j] = 100
|
||
elseif rtable[j] == 'd'
|
||
let rtable[j] = 500
|
||
elseif rtable[j] == 'm'
|
||
let rtable[j] = 1000
|
||
endif
|
||
let j += 1
|
||
endwhile
|
||
let j = 0
|
||
while j < len(rtable)
|
||
if get(rtable, j+1) != 0 && rtable[j] < rtable[j+1]
|
||
let rtable[j] = rtable[j] * -1
|
||
endif
|
||
let j += 1
|
||
endwhile
|
||
|
||
exe 'let total = '.join(rtable, '+')
|
||
let number = ' start="'.total.'"'
|
||
else
|
||
let number = ' start="'.(char2nr(start)-96).'"'
|
||
endif
|
||
|
||
call insert(g:paras, repeat(' ' , g:pindent[i]).'<vim:ol class="'.ostyle.VST_AddClass(i,0,' ','').'"'.number.'>', i)
|
||
call insert(g:pindent, g:pindent[i], i)
|
||
call insert(g:ptype, 'olbegin', i)
|
||
call insert(g:plinen, 0, i)
|
||
|
||
" Recompensate inserted paragraph before current position.
|
||
let i += 1
|
||
|
||
break
|
||
else
|
||
if g:ptype[j] == 'blockquote'
|
||
if g:pindent[j] == g:pindent[i] + listindent
|
||
let g:ptype[j] = 'p'
|
||
endif
|
||
endif
|
||
endif
|
||
let j += 1
|
||
endwhile
|
||
|
||
" LISTDEF:
|
||
|
||
let space = matchstr(g:paras[i], '^\s*')
|
||
if ostyle == 'upperroman'
|
||
let elements = split(g:paras[i], '\(^\|\n\)\s*(\?\(I\|[ICDVLMX]\{2,}\|#\)[\]:.)}]\s*')
|
||
elseif ostyle == 'lowerroman'
|
||
let elements = split(g:paras[i], '\(^\|\n\)\s*(\?\(i\|[icdvlmx]\{2,}\|#\)[\]:.)}]\s*')
|
||
elseif ostyle == 'loweralpha'
|
||
" Allow max 2 characters for "head" of alpha lists. It will give
|
||
" enough combinations withoug allowing for messing with content
|
||
let elements = split(g:paras[i], '\(^\|\n\)\s*(\?[a-z#]\{,2}[\]:.)}]\s*')
|
||
elseif ostyle == 'upperalpha'
|
||
let elements = split(g:paras[i], '\(^\|\n\)\s*(\?[A-Z#]\{,2}[\]:.)}]\s*')
|
||
elseif ostyle == 'decimal'
|
||
let elements = split(g:paras[i], '\(^\|\n\)\s*(\?[0-9#]\+[\]:.)}]\s*')
|
||
endif
|
||
for inc in range(len(elements))
|
||
let elements[inc] = substitute(elements[inc], '\n\s*', '\n', 'g')
|
||
let elements[inc] = VST_Structure(split(elements[inc], "\n"))
|
||
endfor
|
||
let g:paras[i] = '<vim:li>'.join(elements, "</vim:li>\n<vim:li>")
|
||
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Create internal anchors - intlink (.. _blah blah:){{{
|
||
if string(g:ptype) =~ "'intlink'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'intlink'
|
||
" Testing for links broken into multiple lines
|
||
if len(substitute(g:paras[i], '^\s*\.\. _.\{-}:\_s*', '', '')) == 0
|
||
let title = tolower(matchstr(g:paras[i], '^\s*\.\. _\zs.\{-}\ze:'))
|
||
let g:paras[i] = "\n".'<vim:p id="l'.VST_IdMaker(title).'"></vim:p>'."\n"
|
||
else
|
||
let g:paras[i] = ''
|
||
endif
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Create table of contents - toc (.. contents::) {{{
|
||
if string(g:ptype) =~ "'toc'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'toc'
|
||
let b:IsTOC = 1
|
||
if matchstr(g:paras[i], '\n\s*:depth:') != ''
|
||
" This juggling is necessary to make corrections on different
|
||
" treating of TOC levels in LaTeX and HTML.
|
||
let depth = matchstr(g:paras[i], '\n\s*:depth:\s*\zs\d\+\ze') + 1
|
||
let s:vst_tocdepth = depth - 1
|
||
let g:paras[i] = substitute(g:paras[i], '\s*:depth:.\{-}\(\n\|$\)', '', 'g')
|
||
endif
|
||
if matchstr(g:paras[i], '\n\s*:class:') != ''
|
||
let tocclass = 'toc '.VST_IdMaker(matchstr(g:paras[i], '\n\s*:class:\s*\zs.\{-1,}\ze\s*\(\n\|$\)'))
|
||
let g:paras[i] = substitute(g:paras[i], '\s*:class:.\{-}\(\n\|$\)', '', 'g')
|
||
else
|
||
let tocclass = 'toc'
|
||
endif
|
||
if matchstr(g:paras[i], '::\s*\zs.\{-}\ze\(\n\|$\)') != ''
|
||
" Alternative title of toc
|
||
let toc = '<vim:p id="tocheader" class="'.tocclass.'">'.matchstr(g:paras[i], '::\s*\zs.\{-}\ze\(\n\|$\)')."<\/vim:p>\n"
|
||
else
|
||
let toc = "<vim:p id=\"tocheader\" class=\"".tocclass."\">Contents<\/vim:p>\n"
|
||
endif
|
||
let toc .= "<vim:ul class=\"".tocclass."\">\n"
|
||
let j = 0
|
||
while j < len(g:paras)
|
||
if g:ptype[j] =~ '^h\d'
|
||
let hdepth = strpart(g:ptype[j], '1')
|
||
if exists('depth') && depth != ''
|
||
if hdepth > depth
|
||
let j += 1
|
||
continue
|
||
endif
|
||
endif
|
||
let g:paras[j] = VST_SpecCharacter(g:paras[j])
|
||
let stitle = matchstr(g:paras[j], '^\s*\zs.*\ze\n')
|
||
let htitle = VST_IdMaker(tolower(stitle))
|
||
let tocli = repeat(' ', hdepth).'<vim:li class="'.g:ptype[j].'" id="toc-l'.htitle.'"><vim:a href="#l'.htitle.'">'.stitle.'</vim:a></vim:li>'
|
||
let toc .= tocli."\n"
|
||
endif
|
||
let j += 1
|
||
endwhile
|
||
let toc .= "<\/vim:ul class=\"toc\">\n<vim:!--.. comment:: end of toc -->"
|
||
let g:paras[i] = toc
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Create h[1-6] paragraphs {{{
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] =~ '^h\d'
|
||
if g:ptype[i] == 'h1' && !exists("g:vst_doc_title")
|
||
let g:vst_doc_title = substitute(g:paras[i], '^.*\zs\n.*$', '', '')
|
||
endif
|
||
let g:paras[i] = VST_SpecCharacter(g:paras[i])
|
||
let stitle = tolower(matchstr(g:paras[i], '^\s*\zs.*\ze\n'))
|
||
let stitle = VST_IdMaker(stitle)
|
||
let g:paras[i] = substitute(g:paras[i], '^.*\zs\n.*$', '</vim:'.g:ptype[i].'>', '')
|
||
let g:paras[i] = substitute(g:paras[i], '^\s*', '\0<vim:'.g:ptype[i].VST_AddClass(i,1,' ','').' id="l'.stitle.'">', '')
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
" }}}
|
||
" Create document title (.. title::) {{{
|
||
if string(g:ptype) =~ "'title'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'title'
|
||
let g:vst_doc_title = substitute(g:paras[i], '^\s*\.\. title::\s*', '', '')
|
||
let g:paras[i] = ''
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Create verse paragraphs ("| ") {{{
|
||
if string(g:ptype) =~ "'verse'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'verse'
|
||
let g:paras[i] = VST_SpecCharacter(g:paras[i])
|
||
let g:paras[i] = VST_CreateVerse(g:paras[i])
|
||
|
||
let g:paras[i] = substitute(g:paras[i], '<vim:p class="verse', '\0'.VST_AddClass(i,0, ' ',''), '')
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Create raw LaTeX paragraph (next after .. raw:: latex) {{{
|
||
if string(g:ptype) =~ "'rawlatexcontent'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'rawlatexcontent'
|
||
let class = VST_AddClass(i,1, ' ', '')
|
||
let g:paras[i] = "<vim:rawlatex".class.">\n".VST_ProtectLiteral(g:paras[i])."\n</vim:rawlatex>"
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Create raw HTML paragraph (next after .. raw:: html) {{{
|
||
if string(g:ptype) =~ "'rawhtmlcontent'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'rawhtmlcontent'
|
||
let g:paras[i] = "<vim:rawhtml>\n".VST_ProtectLiteral(g:paras[i])."\n</vim:rawhtml>"
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Create raw both paragraph (next after .. raw:: <both>) {{{
|
||
if string(g:ptype) =~ "'rawbothcontent'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'rawbothcontent'
|
||
let g:paras[i] = "<vim:rawboth>\n".g:paras[i]."\n</vim:rawboth>"
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Create LaTeX only paragraph - latexonly (.. raw:: latex) {{{
|
||
if string(g:ptype) =~ "'latexonly'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'latexonly'
|
||
let g:paras[i] = substitute(g:paras[i], '\(\s*\)$', '\n\1</vim:latexonly>', '')
|
||
let g:paras[i] = substitute(g:paras[i], '^\(\s*\)\.\. latexonly::\s*\n', '\n\1<vim:latexonly>\n', '')
|
||
let g:paras[i] = substitute(g:paras[i], '^\(\s*\)\.\. latexonly::', '\n\1<vim:latexonly>\n', '')
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Create HTML only paragraph - htmlonly (.. raw:: html) {{{
|
||
if string(g:ptype) =~ "'htmlonly'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'htmlonly'
|
||
let g:paras[i] = substitute(g:paras[i], '\(\s*\)$', '\n\1</vim:htmlonly>', '')
|
||
let g:paras[i] = substitute(g:paras[i], '^\(\s*\)\.\. htmlonly::\s*\n', '\n\1<vim:htmlonly>\n', '')
|
||
let g:paras[i] = substitute(g:paras[i], '^\(\s*\)\.\. htmlonly::', '\n\1<vim:htmlonly>\n', '')
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Check and embrace paragraphs in blockquote tags {{{
|
||
if string(g:ptype) =~ "'blockquote'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'blockquote'
|
||
let j = i + 1
|
||
while j < len(g:paras)
|
||
let noteindent = g:pindent[j] - g:pindent[i]
|
||
if g:pindent[i] > g:pindent[j] || g:ptype[j] == 'blank' || g:ptype[j] == 'notend'
|
||
call insert(g:paras, repeat(' ' , g:pindent[i]).'</vim:blockquote>', j)
|
||
call insert(g:pindent, g:pindent[i], j)
|
||
call insert(g:ptype, 'blockend', j)
|
||
call insert(g:plinen, 0, j)
|
||
|
||
call insert(g:paras, repeat(' ' , g:pindent[i]).'<vim:blockquote'.VST_AddClass(i,1,' ', '').'>', i)
|
||
call insert(g:pindent, g:pindent[i], i)
|
||
call insert(g:ptype, 'blockbegin', i)
|
||
call insert(g:plinen, 0, i)
|
||
|
||
" Recompensate inserted paragraph before current position.
|
||
let i += 1
|
||
|
||
" Region embraced , now I have to take care about paragraph
|
||
let g:ptype[i] = 'p'
|
||
|
||
break
|
||
|
||
endif
|
||
let j += 1
|
||
endwhile
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Create table {{{
|
||
if string(g:ptype) =~ "'table'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] =~ 'table'
|
||
let g:tclen = []
|
||
let g:thash = {}
|
||
let g:tabb = []
|
||
let g:taba = []
|
||
|
||
let lines = split(g:paras[i], '\n')
|
||
let newrow = 0
|
||
unlet! trow
|
||
|
||
let line_count = 0
|
||
let headfoot_counter = 0
|
||
unlet! usedthead
|
||
unlet! usedtfoot
|
||
|
||
for line in lines
|
||
let row = substitute(line, '^\s*\|\s*$', '', 'g')
|
||
if row =~ '^+'
|
||
if exists('trow')
|
||
|
||
let g:tabb += [deepcopy(trow)]
|
||
|
||
let rl = 0
|
||
while rl < len(trow)
|
||
let trow[rl] = VST_SpecCharacter(trow[rl])
|
||
let cell = split(trow[rl], "\n")
|
||
let trow[rl] = VST_Structure(cell)
|
||
let rl += 1
|
||
endwhile
|
||
|
||
let g:taba += [trow]
|
||
|
||
endif
|
||
if row =~ '^+=' && line_count > 0
|
||
let headfoot_counter += 1
|
||
endif
|
||
" Add head/foot structure elements to the end of last cell in
|
||
" row. Later switch order of elements by regexps.
|
||
if headfoot_counter > 0 && !exists('usedthead') && !exists('usedtfoot')
|
||
let g:taba[-1][-1] .= '</vim:thead>'
|
||
let usedthead = 1
|
||
endif
|
||
if headfoot_counter > 1 && !exists('usedtfoot')
|
||
let g:taba[-1][-1] .= '<vim:tfoot>'
|
||
let usedtfoot = 1
|
||
endif
|
||
let g:hf = headfoot_counter
|
||
let newrow = 1
|
||
let g:thash[len(split(row, '+'))] = split(row, '+')
|
||
continue
|
||
else
|
||
if newrow == 1
|
||
let trow = split(row, '\(^\| \)|\( \|$\)')
|
||
let newrow = 0
|
||
else
|
||
let tmprow = split(row, '\(^\| \)|\( \|$\)')
|
||
let rl = 0
|
||
while rl < len(tmprow)
|
||
let trow[rl] .= "\n".tmprow[rl]
|
||
let rl += 1
|
||
endwhile
|
||
endif
|
||
endif
|
||
let line_count += 1
|
||
endfor
|
||
|
||
|
||
" Get lengths of most standard cells in table, need this for testing
|
||
" of cells for length if they are longer
|
||
let g:tstandard = g:thash[max(keys(g:thash))]
|
||
let tl = 0
|
||
while tl < len(g:tstandard)
|
||
let g:tclen += [len(g:tstandard[tl])]
|
||
let tl += 1
|
||
endwhile
|
||
|
||
" Check relative sizes of table columns
|
||
" I need this to declare widths of columns in LaTeX export
|
||
exe 'let g:sum = '.join(g:tclen, '+')
|
||
let g:sizes = []
|
||
for col in g:tclen
|
||
let colwidth = col*90/g:sum
|
||
if len(colwidth) == 1
|
||
let colwidth = '0'.colwidth
|
||
endif
|
||
let g:sizes += [colwidth]
|
||
endfor
|
||
|
||
" insertion of columns size for proper breaking of text in table cells
|
||
let colnumber = join(g:sizes, '+').'+'
|
||
|
||
let tl = 0
|
||
let g:ctable = ''
|
||
while tl < len(g:tabb)
|
||
let trow = g:tabb[tl]
|
||
let g:ctable .= '<vim:tr>'
|
||
let cn = 0
|
||
let tcc = cn
|
||
while cn < len(trow)
|
||
let cll = trow[cn]
|
||
if stridx(cll, "\n") != -1
|
||
let g:celllength = strlen(matchstr(cll, '^.\{-}\ze\n')) + 2
|
||
else
|
||
let g:celllength = strlen(cll) + 2
|
||
endif
|
||
let k = 0
|
||
let tempst = 0
|
||
while 1
|
||
if k < 2
|
||
let tempst += g:tclen[tcc+k] + k
|
||
else
|
||
let tempst += g:tclen[tcc+k] + 1
|
||
endif
|
||
if g:celllength == tempst
|
||
if k > 0
|
||
let tccplus = tcc + k
|
||
exe 'let g:summa = '.join(g:sizes[tcc : tccplus], '+')
|
||
if exists("g:vst_center_multicol") && g:vst_center_multicol != 1
|
||
let g:ctable .= "<vim:td colspan=\"".(k+1)."\" summary=\"".g:summa."\">".g:taba[tl][cn]."</vim:td>"
|
||
else
|
||
let g:ctable .= "<vim:td colspan=\"".(k+1)."\" style=\"text-align: center;\" summary=\"".g:summa."\">".g:taba[tl][cn]."</vim:td>"
|
||
endif
|
||
else
|
||
let g:ctable .= "<vim:td>".g:taba[tl][cn]."</vim:td>"
|
||
endif
|
||
let tcc += k
|
||
break
|
||
else
|
||
let k += 1
|
||
continue
|
||
endif
|
||
endwhile
|
||
let tcc += 1
|
||
let cn += 1
|
||
endwhile
|
||
let g:ctable .= "\n</vim:tr>"
|
||
let tl += 1
|
||
endwhile
|
||
|
||
|
||
" Check if table is borderless
|
||
if g:ptype[i] == 'bltable'
|
||
let class = 'vstbless'
|
||
else
|
||
let class = 'vstborder'
|
||
endif
|
||
" Info about borders is awful abuse of summary...
|
||
let ttable = "<vim:table class=\"".class.VST_AddClass(i,0,' ','')."\" summary=\"".class."coln".colnumber."\">\n".g:ctable."</vim:table>"
|
||
|
||
if headfoot_counter > 0
|
||
let ttable = substitute(ttable, '<vim:table[^>]*>', '\0\n<vim:thead>', '')
|
||
let ttable = substitute(ttable, '\(</vim:thead>\)\(</vim:td>\n</vim:tr>\)', '\2\n\1\n', '')
|
||
endif
|
||
if headfoot_counter == 2
|
||
let ttable = substitute(ttable, '<.vim:table>', '</vim:tfoot>\n\0', '')
|
||
let ttable = substitute(ttable, '\(<vim:tfoot>\)\(</vim:td>\n</vim:tr>\)', '\2\n\1\n', '')
|
||
endif
|
||
|
||
let g:paras[i] = ttable
|
||
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
unlet! trow
|
||
unlet! row
|
||
endif
|
||
" }}}
|
||
" Create subtitle paragraphs {{{
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] =~ 'subh\d'
|
||
let g:paras[i] = VST_SpecCharacter(g:paras[i])
|
||
let g:paras[i] = "\n".repeat(' ', g:pindent[i]).'<vim:p class="'.g:ptype[i].'">'."\n".g:paras[i]
|
||
" Remove last line of subtitle if this is ornament.
|
||
" Treatment of headers in reST is weird.
|
||
let g:paras[i] = substitute(g:paras[i], '\n\s*'.s:vst_headdef.'\s*$', '', '')
|
||
let g:paras[i] .= "\n".repeat(' ', g:pindent[i])."</vim:p>\n"
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
" }}}
|
||
" Doctest paragraphs {{{
|
||
if string(g:ptype) =~ "'doctest'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'doctest'
|
||
let class = VST_AddClass(i,1, ' ', '')
|
||
let g:paras[i] = VST_SpecCharacter(g:paras[i])
|
||
let g:paras[i] = "\n".repeat(' ', g:pindent[i])."<vim:pre".class.">\n".g:paras[i]
|
||
let g:paras[i] .= "\n".repeat(' ', g:pindent[i])."</vim:pre>\n"
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Simple table paragraphs {{{
|
||
if string(g:ptype) =~ "'simpletbl'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
|
||
if g:ptype[i] == 'simpletbl'
|
||
|
||
unlet! usedthead
|
||
unlet! usedtfoot
|
||
unlet! usethead
|
||
|
||
let plines = split(g:paras[i], '\n')
|
||
let header = substitute(plines[0], '^\s\+', '', '')
|
||
" Remove framing === === lines
|
||
let plines = plines[1:-2]
|
||
let usethead = 0
|
||
for j in range(len(plines))
|
||
let plines[j] = substitute(plines[j], '^\s\{'.g:pindent[i].'}', '', '')
|
||
if plines[j] =~ '^\(=\{2,}\s*\)\+$'
|
||
let usethead += 1
|
||
endif
|
||
endfor
|
||
" Get width of cols {{{
|
||
let cols = []
|
||
for k in split(header, '[^=]=')
|
||
let cols += [len(matchstr(header, '^=*\s*'))]
|
||
let header = substitute(header, '^=*\s*', '', '')
|
||
endfor
|
||
" Due to nature of formatting last column may seem narrower than rest.
|
||
" Add 1 to slightly recompense that.
|
||
let cols[-1] += 1
|
||
" Calculate percentage widths of columns.
|
||
exe 'let total_width = '.join(cols, '+')
|
||
let sizes = []
|
||
for col in cols
|
||
let colwidth = col*90/total_width
|
||
if len(colwidth) == 1
|
||
let colwidth = '0'.colwidth
|
||
endif
|
||
let sizes += [colwidth]
|
||
endfor
|
||
let col_desc = join(sizes, '+').'+'
|
||
" }}}
|
||
" Split plines into separate cells {{{
|
||
let table = []
|
||
for line in plines
|
||
|
||
let trow = []
|
||
|
||
for k in range(len(cols))
|
||
if k == len(cols)-1
|
||
let trow += [line]
|
||
else
|
||
let trow += [line[0:(cols[k]-1)]]
|
||
let line = line[(cols[k]):]
|
||
endif
|
||
endfor
|
||
|
||
let table += [trow]
|
||
|
||
endfor
|
||
" }}}
|
||
" Now create real, multiline if necessary, cells {{{
|
||
let rtable = []
|
||
for k in range(len(table))
|
||
|
||
let row = table[k]
|
||
|
||
if k == 0
|
||
let prevrow = ['-----']
|
||
else
|
||
let prevrow = table[k-1]
|
||
endif
|
||
|
||
if row[0] =~ '^\s*$'
|
||
if prevrow[0] =~ '[-=]\{2,}'
|
||
let addrow = 0
|
||
else
|
||
let addrow = 1
|
||
endif
|
||
else
|
||
let addrow = 0
|
||
endif
|
||
|
||
if addrow == 0
|
||
let temprow = []
|
||
for j in range(len(cols))
|
||
if row[j] !~ '^[=-]\{2,}'
|
||
let temprow += [row[j]]
|
||
elseif row[j] =~ '^=\{2,}'
|
||
let temprow += ['-vst-thfelem-']
|
||
endif
|
||
endfor
|
||
let rtable += [temprow]
|
||
elseif addrow == 1
|
||
for j in range(len(cols))
|
||
if row[j] !~ '^[=-]\{2,}'
|
||
let temprow[j] .= "\n".row[j]
|
||
elseif row[j] =~ '^=\{2,}'
|
||
let temprow += ['-vst-thfelem-']
|
||
endif
|
||
endfor
|
||
endif
|
||
|
||
endfor
|
||
" }}}
|
||
|
||
" Translate data structure into Vim reStructured Text markup
|
||
" Go through cells, call Structure function, join().
|
||
let class = VST_AddClass(i,0, ' ', '')
|
||
let g:paras[i] = '<vim:table class="vstborder'.class."\" summary=\"vstbordercoln".col_desc."\">\n"
|
||
|
||
" insert thead at the beginning
|
||
if usethead > 0
|
||
let g:paras[i] .= "<vim:thead>\n"
|
||
endif
|
||
|
||
for k in range(len(rtable))
|
||
let row = rtable[k]
|
||
|
||
if row == []
|
||
let k += 1
|
||
continue
|
||
endif
|
||
|
||
" Interpret text inside of cells looking for structures {{{
|
||
for j in range(len(row))
|
||
if row[j] =~ '^-vst-thfelem-$'
|
||
let j += 1
|
||
continue
|
||
else
|
||
let row[j] = VST_SpecCharacter(row[j])
|
||
let cellt = split(row[j], "\n")
|
||
" Remove in-frontal space from one-line cells to avoid
|
||
" interpretation of text as blockquote
|
||
"if len(cellt) == 1
|
||
" let cellt[0] = substitute(cellt[0], '^\s\+', '', '')
|
||
"endif
|
||
let row[j] = VST_Structure(cellt)
|
||
endif
|
||
endfor
|
||
" }}}
|
||
|
||
" Create marked text and add thead and tfoot when appropriate
|
||
if usethead > 0 && !exists("usedthead") && join(row, '') =~ '^\(-vst-thfelem-\)\+$'
|
||
let g:paras[i] .= "\n</vim:thead>\n"
|
||
let usedthead = 1
|
||
continue
|
||
endif
|
||
if usethead > 1 && exists("usedthead") && join(row, '') =~ '^\(-vst-thfelem-\)\+$'
|
||
let g:paras[i] .= "\n<vim:tfoot>\n"
|
||
unlet usedthead
|
||
let usedtfoot = 1
|
||
continue
|
||
endif
|
||
|
||
let g:paras[i] .= '<vim:tr><vim:td>'.join(row, '</vim:td><vim:td>').'</vim:td></vim:tr>'."\n"
|
||
|
||
|
||
endfor
|
||
|
||
if exists("usedtfoot")
|
||
unlet usedtfoot
|
||
let g:paras[i] .= "\n</vim:tfoot>\n"
|
||
endif
|
||
|
||
unlet! usedthead
|
||
unlet! usedtfoot
|
||
unlet! usethead
|
||
|
||
let g:paras[i] .= '</vim:table>'
|
||
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Create p paragraph {{{
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'p'
|
||
let g:paras[i] = VST_SpecCharacter(g:paras[i])
|
||
if g:paras[i] =~ '^\s\+---\?\s.*\S' && g:ptype[i+1] == 'blockend'
|
||
let class = VST_AddClass(i,0, '', '')
|
||
let g:paras[i] = "\n".repeat(' ', g:pindent[i])."<vim:p class=\"attribution".class."\">\n".g:paras[i]
|
||
else
|
||
let class = VST_AddClass(i,1, ' ', '')
|
||
let g:paras[i] = "\n".repeat(' ', g:pindent[i])."<vim:p".class.">\n".g:paras[i]
|
||
endif
|
||
let g:paras[i] .= "\n".repeat(' ', g:pindent[i])."</vim:p>\n"
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
" }}}
|
||
" Insert raw files placeholders {{{
|
||
if string(g:ptype) =~ "'raw\(latex\|html\|both\)'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] =~ '^raw\(latex\|html\|both\)$'
|
||
if g:paras[i] =~ ':file:'
|
||
let file = matchstr(g:paras[i], ':file:\s*\zs.*')
|
||
let g:paras[i] = '-vst-raw-file-placeholder:'.VST_ProtectLiteral(file)
|
||
else
|
||
let g:paras[i] = ''
|
||
endif
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Insert MED-classes {{{
|
||
if string(g:ptype) =~ "'MED-class'"
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if i == len(doc) - 1
|
||
let nextline = i - 1
|
||
else
|
||
let nextline = i + 1
|
||
endif
|
||
if g:ptype[i] == 'MED-class' && g:ptype[nextline] != 'notend'
|
||
let name = g:paras[i]
|
||
let j = i + 1
|
||
while j < len(g:paras)
|
||
if g:ptype[j] == 'notend' && g:pindent[j] == g:pindent[i] && g:paras[j] =~ '^\s*<vim:class'.name
|
||
let g:paras[j] = ''
|
||
break
|
||
else
|
||
if g:ptype[j] !~ '^[uo]li$'
|
||
let initial = matchstr(g:paras[j], '^\_s*\zs<vim:\w\+[^>]*>')
|
||
if initial !~ 'class\s*=\s*[''"]'
|
||
let final = substitute(initial, '\(/\)\?>', ' class="'.name.'" \1>', '')
|
||
elseif initial =~ 'class\s*=\s*[''"]'
|
||
let final = substitute(initial, '\(class\s*=\s*\)\([''"]\)\(.\{-}\)\2', '\1\2\3 '.name.'\2', '')
|
||
endif
|
||
let g:paras[j] = substitute(g:paras[j], initial, final, '')
|
||
endif
|
||
let j += 1
|
||
endif
|
||
endwhile
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
" }}}
|
||
" Nuke auxiliary elements {{{
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
if g:ptype[i] == 'link'
|
||
let g:paras[i] = ''
|
||
elseif g:ptype[i] == 'anonlink'
|
||
let g:paras[i] = ''
|
||
elseif g:ptype[i] == 'replacement'
|
||
let g:paras[i] = ''
|
||
elseif g:ptype[i] == 'rawhtml'
|
||
let g:paras[i] = ''
|
||
elseif g:ptype[i] == 'rawlatex'
|
||
let g:paras[i] = ''
|
||
elseif g:ptype[i] == 'rawboth'
|
||
let g:paras[i] = ''
|
||
elseif g:ptype[i] == 'emptypre'
|
||
let g:paras[i] = ''
|
||
elseif g:ptype[i] == 'role'
|
||
let g:paras[i] = ''
|
||
elseif g:ptype[i] == 'MED-class'
|
||
let g:paras[i] = ''
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
" }}}
|
||
" Create markup {{{
|
||
let i = 0
|
||
while i < len(g:paras)
|
||
" Careful checking if given construct exists in paragraph.
|
||
" BIG speed gains.
|
||
if g:ptype[i] !~ '^pre\|^hr\|^blank'
|
||
if g:paras[i] =~ '|'
|
||
let g:paras[i] = VST_Replacement(g:paras[i])
|
||
endif
|
||
if g:paras[i] =~ '[*`=]'
|
||
let g:paras[i] = VST_Markup(g:paras[i])
|
||
endif
|
||
if g:paras[i] =~ ':`' || g:paras[i] =~ '`:'
|
||
let g:paras[i] = VST_Roles(g:paras[i])
|
||
endif
|
||
if g:paras[i] =~ '\[\d\+\]_'
|
||
let g:paras[i] = VST_Footnotes(g:paras[i])
|
||
endif
|
||
if g:paras[i] =~ 'http' || g:paras[i] =~ 'mailto' || g:paras[i] =~ 'ftp'
|
||
let g:paras[i] = VST_SA_Hyperlink(g:paras[i])
|
||
endif
|
||
if g:paras[i] =~ '\[#\k\+\]_'
|
||
let g:paras[i] = VST_LabelFootnote(g:paras[i])
|
||
endif
|
||
if g:paras[i] =~ '\[\k\+\]_'
|
||
let g:paras[i] = VST_Citations(g:paras[i])
|
||
endif
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
" }}}
|
||
" Fixing! {{{
|
||
"
|
||
let file = join(g:paras, "\n")
|
||
" Remove commented content
|
||
" let file = substitute(file, '<vim:comment>.\{-}</vim:comment>', '', 'g')
|
||
" Remove replacement placeholders
|
||
let file = substitute(file, '{-vst-replace-{', '', 'g')
|
||
let file = substitute(file, '}-vst-replace-}', '', 'g')
|
||
" Glueing together dl
|
||
let file = substitute(file, '</vim:dl>\_s\{-}<vim:dl.\{-}>', '', 'g')
|
||
" Remove li to embed lists
|
||
let file = substitute(file, '</vim:li>\(\_s\{-}<vim:[uo]l\)', '\1', 'g')
|
||
" Glueing ol and ul
|
||
let file = substitute(file, '\(<vim:li><vim:p class="\)firstli\(">\_.\{-}</vim:p>\_s*</vim:li>\_s*<vim:li\)', '\1onlyli\2', 'g')
|
||
let file = substitute(file, '</vim:ul class="\([^"]*\)">\_s*<vim:ul class="\1[^>]*>', '', 'g')
|
||
let file = substitute(file, '</vim:ul class="\(\w\+\)[^"]\{-}">\_s*<vim:ul class="\1[^>]*>', '', 'g')
|
||
let file = substitute(file, '</vim:ul class="\%(circle\|square\|disc\)">', '</vim:ul>', 'g')
|
||
let file = substitute(file, '</vim:ol class="\([^"]*\)">\_s*<vim:ol class="\1[^>]*>', '', 'g')
|
||
" This one can have bad influence on consecutive ol lists with different
|
||
" numbering
|
||
let file = substitute(file, '</vim:ol class="\(\w\+\)[^"]\{-}">\_s*<vim:ol class="\1[^>]*>', '', 'g')
|
||
let file = substitute(file, '</vim:ol class=".\{-}>', '</vim:ol>', 'g')
|
||
let file = substitute(file, '</vim:ul class=".\{-}">', '</vim:ul>', 'g')
|
||
" Removing redundant \n
|
||
let file = substitute(file, '\_s*</vim:pre>', '\n</vim:pre>\n', 'g')
|
||
let file = substitute(file, '\n\n\n\(\s*\)<vim:p', '\n\n\1<vim:p', 'g')
|
||
let file = substitute(file, '\n\n\n\(\s*\)<vim:pre', '\n\n\1<vim:pre', 'g')
|
||
let file = substitute(file, '\n\s*</vim:dt>', '</vim:dt>', 'g')
|
||
" Remove double :: at the end of paragraphs indicating code in next.
|
||
let file = substitute(file, '::\(\_s*</vim:p>\)', ':\1', 'g')
|
||
" Remove double :: when it was the only element after list indicator
|
||
let file = substitute(file, '<vim:li><vim:p class="\%(first\|only\)li">\s*:</vim:p>', '<vim:li>', 'g')
|
||
" Remove empty pre paragraphs
|
||
let file = substitute(file, '<vim:pre[^>]\{-}>\n</vim:pre>', '', 'g')
|
||
" Remove links created inside of image src
|
||
let file = substitute(file, '<\(vim:\)\?img\([^>]\{-}\)src="<vim:a href=".\{-}">\([^<]*\)</vim:a>"',
|
||
\ '<\1img\2src="\3"', 'g')
|
||
" let file = substitute(file, ' \n', '', 'g')
|
||
" Remove too much of empty space at the end of footnotes
|
||
let file = substitute(file, '\n\(</vim:div></vim:footnote>\)', '\1', 'g')
|
||
|
||
|
||
" }}}
|
||
" Restore structure from temporary variables {{{
|
||
if len(g:paras_rez) > 0
|
||
let g:paras = g:paras_rez[-1]
|
||
call remove(g:paras_rez, -1)
|
||
endif
|
||
if len(g:ptype_rez) > 0
|
||
let g:ptype = g:ptype_rez[-1]
|
||
call remove(g:ptype_rez, -1)
|
||
endif
|
||
if len(g:pindent_rez) > 0
|
||
let g:pindent = g:pindent_rez[-1]
|
||
call remove(g:pindent_rez, -1)
|
||
endif
|
||
if len(g:plinen_rez) > 0
|
||
let g:plinen = g:plinen_rez[-1]
|
||
call remove(g:plinen_rez, -1)
|
||
endif
|
||
" }}}
|
||
|
||
return file
|
||
|
||
" End of VST_Structure
|
||
endfunction
|
||
|
||
function! vst#vst#VST_Export(line1, line2, format) range " {{{
|
||
|
||
" VST_DictTable: creation of nice looking table from dictionary {{{
|
||
" Description: Go through all key value pairs and create nicely looking table
|
||
" db: dictionary itself
|
||
" key: header of key column
|
||
" value: header of value column
|
||
" sort: 0/1 sort table or not
|
||
function! VST_DictTable(db, key, value, sort)
|
||
|
||
let valmargin = 20
|
||
let dict = a:db
|
||
let table = a:key.repeat(' ', valmargin-strlen(a:key)).a:value."\n"
|
||
if a:sort == 0
|
||
for key in keys(dict)
|
||
if dict[key] !~ '^\s*$'
|
||
if valmargin - strlen(key) < 1
|
||
let table .= key."\n".repeat(' ', valmargin).substitute(dict[key], '\n', ' ', 'g')."\n"
|
||
else
|
||
let table .= key.repeat(' ', valmargin - strlen(key)).substitute(dict[key], '\n', ' ', 'g')."\n"
|
||
endif
|
||
endif
|
||
endfor
|
||
else
|
||
for key in sort(keys(dict))
|
||
if dict[key] !~ '^\s*$'
|
||
if valmargin - strlen(key) < 1
|
||
let table .= key."\n".repeat(' ', valmargin).substitute(dict[key], '\n', ' ', 'g')."\n"
|
||
else
|
||
let table .= key.repeat(' ', valmargin - strlen(key)).substitute(dict[key], '\n', ' ', 'g')."\n"
|
||
endif
|
||
endif
|
||
endfor
|
||
endif
|
||
|
||
"return table
|
||
call input(table)
|
||
"echo table
|
||
|
||
endfunction
|
||
" }}}
|
||
" VST_TocTable: creation of nice looking table of contents {{{
|
||
" Description: Go through all 3 element items in list and render them in
|
||
" nicely looking table
|
||
" list: list itself
|
||
" fcol: header of first column
|
||
" scol: header of second column
|
||
" tcol: header of third column
|
||
" sinfo: special info
|
||
function! VST_TocTable(list, fcol, scol, tcol, sinfo)
|
||
|
||
let secmargin = 15
|
||
let thdmargin = 40
|
||
let table = a:fcol.repeat(' ', secmargin-len(a:fcol))
|
||
\ .a:scol.repeat(' ',thdmargin-len(a:scol)).a:tcol."\n"
|
||
|
||
let i = 0
|
||
while i < len(a:list)
|
||
let [level, title, line] = a:list[i]
|
||
let title = substitute(title, '\n.\{-}$', '', '')
|
||
" Add a markers around name of section were cursor is
|
||
if !exists("a:list[i+1]")
|
||
let nextsection = line('$')
|
||
else
|
||
let nextsection = a:list[i+1][2]
|
||
endif
|
||
let title = b:vst_toc_numbers[title].' '.substitute(title, '^\s\+', '', '')
|
||
if a:sinfo >= line && a:sinfo < nextsection
|
||
let title = '[[[ '.title.' ]]]'
|
||
endif
|
||
let table .= level.' '.g:vst_headers[level].' '
|
||
\ .repeat(' ', secmargin-len(level.g:vst_headers[level].' '))
|
||
\ .title.repeat(' ', thdmargin-len(title)).' '.line."\n"
|
||
let i += 1
|
||
endwhile
|
||
|
||
return table
|
||
|
||
endfunction
|
||
" }}}
|
||
" VST_CreateDBs: creation of databases {{{
|
||
function! VST_CreateDBs(table)
|
||
" Preprocess table to get class of role into the same line
|
||
" Preprocessing here is nice idea for links, they don't have to be changed
|
||
" physically in document, no messing with adding/removing lines. It slow
|
||
" things down but more precise processing is Good Thing(tm)
|
||
" table: text to analyze in List form
|
||
let preproc = a:table
|
||
let i = 0
|
||
while i < len(preproc)
|
||
if i == len(preproc) - 1
|
||
let nextline = i - 1
|
||
else
|
||
let nextline = i + 1
|
||
endif
|
||
if preproc[i] =~ '^\s*\.\. role:'
|
||
if preproc[nextline] =~ '^\s*:class:'
|
||
let preproc[i] = preproc[i].' -vst-role-'.preproc[nextline]
|
||
else
|
||
let preproc[i] = preproc[i].' -vst-role-'
|
||
endif
|
||
endif
|
||
" Connect multiline link definitions
|
||
if preproc[i] =~ '^\s*\(\.\. _\|__ \)'
|
||
if preproc[nextline] !~ '^\s*\(\.\. _\|__ \)' && preproc[nextline] !~ '^\s*$'
|
||
let findent = strlen(matchstr(preproc[i], '^\s*'))
|
||
let sindent = strlen(matchstr(preproc[nextline], '^\s*'))
|
||
if (findent + 3) <= sindent
|
||
let preproc[i] = substitute(preproc[i], '\s\+$', '', '')
|
||
\.substitute(preproc[nextline], '^\s\+', '', '')
|
||
call remove(preproc, nextline)
|
||
" Turn counter down to process more than 2 lines
|
||
let i -= 1
|
||
endif
|
||
endif
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
|
||
for i in range(len(preproc))
|
||
if preproc[i] =~ '^\s*\.\. _'
|
||
" Hyperlink database
|
||
let title = tolower(matchstr(preproc[i], '_\zs.\{-}\ze:'))
|
||
let url = matchstr(preproc[i], '_.\{-}:\s*\zs.*')
|
||
let k = 1
|
||
while url == '' && len(preproc) > (i+k) && stridx(preproc[i+k], '_') > -1
|
||
let url = matchstr(preproc[i+k], '_.\{-}:\s*\zs.*')
|
||
let k += 1
|
||
endwhile
|
||
unlet! k
|
||
if url =~ '@' && url !~ '^http\|^s\?ftp'
|
||
let url = 'mailto:'.url
|
||
endif
|
||
if title != '' && title != '_'
|
||
let g:vst_hlinkdb[title] = url
|
||
endif
|
||
elseif preproc[i] =~ '^\s*\.\. role'
|
||
let rolekey = matchstr(preproc[i], 'role::\s*\zs.\{-}\ze\s*-vst-role-')
|
||
let rolevalue = matchstr(preproc[i], '-vst-role-\s*:class:\s*\zs.*\ze\s*$')
|
||
if rolevalue == ''
|
||
let rolevalue = rolekey
|
||
endif
|
||
let g:vst_roledb[rolekey] = rolevalue
|
||
endif
|
||
endfor
|
||
" Add embedded reusable URIs
|
||
" I have to join and split file again to avoid problems with: links
|
||
" splitted across lines and more than one link in line
|
||
let dbfile = join(a:table)
|
||
" This is done only for links, compress white space
|
||
let dbfile = substitute(dbfile, '\s\+', ' ', 'g')
|
||
let dbtable = split(dbfile, '>`_[^_]')
|
||
let i = 0
|
||
while i < len(dbtable)-1
|
||
" Hyperlink database
|
||
let expr= matchstr(dbtable[i], '.*`\zs.\{-}$')
|
||
if expr =~ '^<'
|
||
let title = tolower(matchstr(expr, '<\zs.*'))
|
||
else
|
||
let title = tolower(matchstr(expr, '\zs.\{-}\ze <.*$'))
|
||
endif
|
||
let url = matchstr(expr, ' <\zs.\{-}$')
|
||
if url =~ '@' && url !~ '^http\|^ftp'
|
||
let url = 'mailto:'.url
|
||
endif
|
||
if title != ''
|
||
let g:vst_hlinkdb[title] = url
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
|
||
endfunction
|
||
" }}}
|
||
" VST_FoldText: Create text for folds {{{
|
||
function! VST_FoldText()
|
||
let text = getline(v:foldstart)
|
||
let length = v:foldend - v:foldstart
|
||
let indent = '+'.v:folddashes.repeat(' ', 5-len(length)).length
|
||
\ .' lines: '
|
||
let line = b:vst_fold_numbers[text].' '.substitute(text, '^\s\+', '', '')
|
||
let symbol = repeat(' ', 50-len(line)).'('
|
||
\ .matchstr(getline(v:foldstart+1), '^\s*\zs...\ze').')'
|
||
return indent.repeat(' ', 15-len(indent)).line.symbol.' '
|
||
endfunction
|
||
" }}}
|
||
" VST_ColNumbers: Create <col /> tags for HTML {{{
|
||
" numbers - values for width of columns, String with + to separate numbers
|
||
function! VST_ColNumbers(numbers)
|
||
let widths = split(a:numbers, '+')
|
||
let col_string = ''
|
||
for width in widths
|
||
let col_string .= '<col width="'.width.'%" />'
|
||
endfor
|
||
return col_string
|
||
endfunction
|
||
" }}}
|
||
|
||
" Auxiliary functions: {{{
|
||
" Unicode2Char: Return char according to hex code {{{
|
||
" nr - decimal value of Unicode character
|
||
function! Unicode2Char(nr)
|
||
let n = join(reverse(split(tolower(a:nr), '.\zs')), '')
|
||
|
||
let r = 0
|
||
let i = 0
|
||
while i <= len(n)
|
||
if n[i] == 'a'
|
||
let p = 10
|
||
elseif n[i] == 'b'
|
||
let p = 11
|
||
elseif n[i] == 'c'
|
||
let p = 12
|
||
elseif n[i] == 'd'
|
||
let p = 13
|
||
elseif n[i] == 'e'
|
||
let p = 14
|
||
elseif n[i] == 'f'
|
||
let p = 15
|
||
else
|
||
let p = n[i]
|
||
endif
|
||
|
||
if p == 0
|
||
let fp = 0
|
||
else
|
||
exe 'let fp = '.repeat('16*', i).p
|
||
endif
|
||
|
||
let r += fp
|
||
|
||
let i += 1
|
||
endwhile
|
||
return nr2char(r)
|
||
endfunction
|
||
" }}}
|
||
" VST_2html: Parse 2html directive {{{
|
||
" Description: Go through document looking for 2html directives, copy text of
|
||
" directive to new buffer and process it there with 2html.vim, at the end
|
||
" replace original text with colored text and additional <style> declaration.
|
||
function! VST_2html()
|
||
silent call cursor(1,1)
|
||
syntax on
|
||
" Backup of important elements
|
||
let bufnumber = bufnr('%')
|
||
let z_rez = @z
|
||
let y_rez = @y
|
||
let @z = ''
|
||
let @y = ''
|
||
if exists('g:colors_name')
|
||
let col_scheme = g:colors_name
|
||
else
|
||
let col_scheme = 'default'
|
||
endif
|
||
" Saving 2html.vim options {{{
|
||
if exists('g:html_number_lines')
|
||
let h_number_lines = g:html_number_lines
|
||
else
|
||
let h_number_lines = 2
|
||
endif
|
||
if exists('g:html_use_css')
|
||
let h_use_css = g:html_use_css
|
||
else
|
||
let h_use_css = 2
|
||
endif
|
||
if exists('g:html_no_pre')
|
||
let h_no_pre = g:html_no_pre
|
||
else
|
||
let h_no_pre = 2
|
||
endif
|
||
if exists('g:use_xhtml')
|
||
let h_use_xhtml = g:use_xhtml
|
||
else
|
||
let h_use_xhtml = 2
|
||
endif
|
||
" }}}
|
||
" And set values necessary for good work
|
||
let g:html_number_lines = 0
|
||
let g:html_use_css = 1
|
||
let g:html_no_pre = 0
|
||
let g:use_xhtml = 1
|
||
if &compatible == 1
|
||
set nocompatible
|
||
endif
|
||
if &splitbelow == 0
|
||
let splitb = 0
|
||
set splitbelow
|
||
else
|
||
let splitb = 1
|
||
endif
|
||
|
||
while search('<pre class="tohtml-[^"]\+">', 'W')
|
||
let @z = ''
|
||
let @y = ''
|
||
let line = line('.')
|
||
" Retrieve filetype and colorscheme data
|
||
let data = matchstr(getline('.'), '<pre class="tohtml-\zs.\{-}\ze">')
|
||
let darray = split(data, '----')
|
||
let filetype = darray[0]
|
||
if len(darray) > 1
|
||
let cscheme = darray[1]
|
||
endif
|
||
let line2 = search('<\/pre>', 'W')
|
||
" There may be situation, by an user error, omission, etc. 2html
|
||
" directive will be empty. In that case silently quit.
|
||
if line + 1 == line2
|
||
return
|
||
endif
|
||
silent exe (line+1).','.(line2-1).' delete z'
|
||
silent below 1new tmp-2html
|
||
silent 0put z
|
||
silent exe 'setlocal ft='.filetype
|
||
if exists('cscheme')
|
||
silent! exe 'colorscheme '.cscheme
|
||
endif
|
||
" I have to revert special characters because TOhtml will do it once
|
||
" again destroing & entities
|
||
" list: <, >, ©
|
||
" How to prevent massacre of user used entities?
|
||
" How probably they are in pre?
|
||
%s/</</ge
|
||
%s/>/>/ge
|
||
%s/&/\&/ge
|
||
" @-entity was treated literally by 2html.vim
|
||
%s/@/@/ge
|
||
silent runtime syntax/2html.vim
|
||
" Remove html headers, I don't need them inside of file
|
||
" Still problem with style inside of body
|
||
silent g+<!DOCTYPE\|</\?html\|</\?head>\|</\?pre>\|</\?body>\|</\?p>\|<title>\|<meta +d
|
||
silent g+<?xml+d
|
||
if exists('cscheme')
|
||
silent exe 'g+^body+s+^body+.tohtml-'.filetype.'----'.cscheme.'+e'
|
||
else
|
||
silent exe 'g+^body+s+^body+.tohtml-'.filetype.'+e'
|
||
endif
|
||
" 2html.vim in full auto _always_ use html_no_pre = 1. Weird.
|
||
silent %s/ / /ge
|
||
silent %s/<br\/>//ge
|
||
" Restore @ -> @ to prevent mail harvesting
|
||
silent %s/@/\@/ge
|
||
silent call cursor(1,1)
|
||
silent /<style/,/<\/style/yank y
|
||
let style = split(@y, '\n')
|
||
let main_style = style[-3:-3]
|
||
let main_style_name = split(main_style[0], ' ')[0]
|
||
let style = style[2:-4]
|
||
silent call map(style, "main_style_name.' '.v:val")
|
||
let style = main_style + style
|
||
if exists('g:vst_2html_css')
|
||
let g:vst_2html_css += style
|
||
else
|
||
let g:vst_2html_css = style
|
||
endif
|
||
silent call cursor(1,1)
|
||
silent normal! "zyG
|
||
silent bwipeout! tmp-2html.html
|
||
silent bwipeout! tmp-2html
|
||
let @z = substitute(@z, '\n\+$', '', '')
|
||
if exists('cscheme')
|
||
let @z = substitute(@z, '.*</style>', '\n<pre class="tohtml-'.filetype.'----'.cscheme.'">', '')
|
||
else
|
||
let @z = substitute(@z, '.*</style>', '\n<pre class="tohtml-'.filetype.'">', '')
|
||
endif
|
||
silent exe 'buffer! '.bufnumber
|
||
silent exe line
|
||
silent! put z
|
||
let line3 = line('.') - 1
|
||
silent exe line
|
||
silent delete
|
||
silent exe line3
|
||
unlet! cscheme
|
||
endwhile
|
||
|
||
" Restore settings
|
||
let @z = z_rez
|
||
let @y = y_rez
|
||
if splitb == 0
|
||
set nosplitbelow
|
||
endif
|
||
silent exe 'buffer! '.bufnumber
|
||
silent exe 'colorscheme '.col_scheme
|
||
" Restoring 2html.vim options {{{
|
||
if h_number_lines == 2
|
||
unlet g:html_number_lines
|
||
else
|
||
let g:html_number_lines = h_number_lines
|
||
endif
|
||
if h_use_css == 2
|
||
unlet g:html_use_css
|
||
else
|
||
let g:html_use_css = h_use_css
|
||
endif
|
||
if h_no_pre == 2
|
||
unlet g:html_no_pre
|
||
else
|
||
let g:html_no_pre = h_no_pre
|
||
endif
|
||
" }}}
|
||
|
||
endfunction
|
||
" }}}
|
||
" VST_AddClass: Return class string if prev par is class (.. class::) {{{
|
||
" Description: Check previous paragraph and in case it is class return string
|
||
" class="classname", classname or ''.
|
||
" parnumber - number of described paragraph
|
||
" full - check if return full declaration or name only
|
||
" 1 - full declaration class="classname"
|
||
" 0 - name only
|
||
" pre - prefix
|
||
" post - suffix
|
||
function! VST_AddClass(parnumber, full, pre, post)
|
||
" Escaping of special characters
|
||
if g:ptype[a:parnumber-1] == 'notend' && g:ptype[a:parnumber-2] == 'MED-class'
|
||
|
||
"let name = matchstr(g:paras[a:parnumber-2], '^\s*\.\. class::\s*\zs.\{-1,}\ze\s*$')
|
||
let name = VST_IdMaker(g:paras[a:parnumber-2])
|
||
if a:full == 1
|
||
let class = 'class="'.name.'"'
|
||
else
|
||
let class = name
|
||
endif
|
||
let class = a:pre.class.a:post
|
||
else
|
||
let class = ''
|
||
endif
|
||
|
||
return class
|
||
|
||
endfunction
|
||
" }}}
|
||
" VST_AnonHyperlink: Create anonymous hyperlinks {{{
|
||
function! VST_AnonHyperlink(text)
|
||
let parlines = split(a:text, '-vst-anon-hyperlink-')
|
||
let i = 0
|
||
let g:a0 = []
|
||
while i < len(g:vst_anonhlinkdb)
|
||
if g:vst_anonhlinkdb[i] =~ '_\s*$'
|
||
let href = g:vst_anonhlinkdb[i]
|
||
let title = tolower(matchstr(href, '\(\.\. __ :\|__\)\s*\(`\?\)\zs.*\ze\2_\s*$'))
|
||
while href =~ '_\s*$'
|
||
" If ends in _ it is probably indirect link, process it.
|
||
if has_key(g:vst_hlinkdb, title) && g:vst_hlinkdb[title] != ''
|
||
let href = escape(g:vst_hlinkdb[title], '&\~')
|
||
else
|
||
let href = '#l'.VST_IdMaker(title)
|
||
endif
|
||
endwhile
|
||
else
|
||
let href = matchstr(g:vst_anonhlinkdb[i], '^\s*\(\.\. __:\|__\)\s*\zs.*')
|
||
endif
|
||
let g:a0 += [href]
|
||
if i < len(parlines) - 1
|
||
let parlines[i] .= href
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
let par = join(parlines, '')
|
||
|
||
return par
|
||
|
||
endfunction
|
||
" }}}
|
||
" VST_AutoFootnote: Create auto-numbered footnotes [#]_ {{{
|
||
function! VST_AutoFootnote(text)
|
||
let parlines = split(a:text, '\[#]_')
|
||
let i = 0
|
||
let k = s:maxfnumber + s:maxlnumber + 1
|
||
while i < len(parlines)-1
|
||
let parlines[i] .= '<vim:a href="#footnote-'.k.'" name="target-'.k.'">['.k.']</vim:a>'
|
||
let i += 1
|
||
let k += 1
|
||
endwhile
|
||
let par = join(parlines, '')
|
||
|
||
return par
|
||
|
||
endfunction
|
||
" }}}
|
||
" VST_Citations: Create citations [first]_ {{{
|
||
function! VST_Citations(text)
|
||
let par = substitute(a:text, '\[\(\k\{-}\)]_', '<vim:a href="#citation-\1" name="ctarget-\1">[\1]</vim:a>', 'g')
|
||
|
||
return par
|
||
endfunction
|
||
" }}}
|
||
" VST_CreateVerse: Create verse paragraph ("| ") {{{
|
||
" Description:
|
||
function! VST_CreateVerse(text)
|
||
" Escaping of special characters
|
||
let par = substitute(a:text, '\n\s*|\( *\)', '\="<vim:br />-vst-new-line-".repeat(" ", len(submatch(1)))', 'g')
|
||
let par = substitute(par, '^\s*|\( *\)', '\="<vim:p class=\"verse\">-vst-new-line-".repeat(" ", len(submatch(1)))', 'g')
|
||
let par .= "\n</vim:p>"
|
||
let par = substitute(par, '-vst-new-line-', '\n', 'g')
|
||
|
||
return par
|
||
endfunction
|
||
" }}}
|
||
" VST_EscapingSlash: Remove escaping backslashes {{{
|
||
function! VST_EscapingSlash(text)
|
||
let par = substitute(a:text, '\n', ' -vst-new-line- ', 'g')
|
||
|
||
" Special constructs for escaping:
|
||
" \* -> *
|
||
" \` -> `
|
||
" \= -> = (commented)
|
||
" \<Space> -> <Nop>
|
||
" \- ->
|
||
"
|
||
" To escape backslash, use backslash:
|
||
" \\*, \\<Space>, \\-
|
||
|
||
" Remove single escaping backslash before letters and digits which can form
|
||
" lists enumerators:
|
||
let par = substitute(par, '\\\@<!\\\([A-Za-z0-9#][\]:.)}]\)', '\1', 'g')
|
||
|
||
" Remove single escaping backslash befor | at the beginning of paragraph
|
||
" let par = substitute(par, '^\(\s*\)\\|', '\1|', 'g')
|
||
|
||
" Take care about \*
|
||
let par = substitute(par, '\\\@<!\\\*', '*', 'g')
|
||
" And remove escaping \
|
||
let par = substitute(par, '\\\\\*', '\\*', 'g')
|
||
|
||
" Take care about \`
|
||
let par = substitute(par, '\\\@<!\\`', '`', 'g')
|
||
" And remove escaping \
|
||
let par = substitute(par, '\\\\`', '\\`', 'g')
|
||
|
||
" Take care about \=
|
||
" let par = substitute(par, '\\\@<!\\=', '=', 'g')
|
||
" And remove escaping \
|
||
" let par = substitute(par, '\\\\=', '\\=', 'g')
|
||
|
||
" Take care about \<Space>
|
||
let par = substitute(par, '\\\@<!\\ \(-vst-new-line-\)\@!', '', 'g')
|
||
" And remove escaping \
|
||
let par = substitute(par, '\\\\ \(-vst-new-line-\)\@!', '\\ ', 'g')
|
||
" At last get rid of artificial new lines
|
||
let par = substitute(par, ' -vst-new-line- ', '\n', 'g')
|
||
|
||
" Take care about \-
|
||
let par = substitute(par, '\\\@<!\\-', '\ ', 'g')
|
||
" And remove escaping \
|
||
let par = substitute(par, '\\\\-', '\\-', 'g')
|
||
|
||
|
||
return par
|
||
endfunction
|
||
" }}}
|
||
" VST_ExtraRoles: Change text :roles: into proper tags " {{{
|
||
function! VST_ExtraRoles(name, text)
|
||
|
||
if len(filter(copy(keys(g:vst_roledb)), "v:val == a:name")) > 0
|
||
let par = '<vim:span class="'.VST_IdMaker(g:vst_roledb[a:name]).'">'.a:text.'</vim:span>'
|
||
else
|
||
let par = a:text
|
||
endif
|
||
|
||
return par
|
||
endfunction
|
||
" }}}
|
||
" VST_FirstLine: Returns first and only first line " {{{
|
||
" without trailing spaces of given text
|
||
function! VST_FirstLine(text)
|
||
return matchstr(a:text, '^\s*\ze.\{-}\ze\s*\(\n\|$\)')
|
||
|
||
endfunction
|
||
" }}}
|
||
" VST_Footnotes: Create footnotes [\d\+]_ {{{
|
||
function! VST_Footnotes(text)
|
||
let parlines = split(a:text, '\(\[\d\+\]\)\@<=_')
|
||
let j = 0
|
||
for parline in parlines
|
||
let parlines[j] = substitute(parlines[j], '\[\(\d\+\)]$', '<vim:a href="#footnote-\1" name="target-\1">\0</vim:a>', '')
|
||
let j += 1
|
||
endfor
|
||
let par = join(parlines, '')
|
||
|
||
return par
|
||
|
||
endfunction
|
||
" }}}
|
||
" VST_Hyperlink: Create inline `markup of hyperlinks`_ " {{{
|
||
function! VST_Hyperlink(text)
|
||
let par = substitute(a:text, '\n', ' -vst-new-line- ', 'g')
|
||
" Technical spaces
|
||
" Adding spaces at the end and start of paragraph isn't elegant but
|
||
" catching of ^ and $ in regexps by \| is very expensive.
|
||
let par = ' '.par.' '
|
||
" `Inline external anchors`_
|
||
if par =~ '__'
|
||
" Embedded anonymous hyperlinks, Note: second space is nonbreaking
|
||
" space \x160
|
||
let par = substitute(par, "[- <20>'\"([{</:>]\\@<=`\<\\(.\\{-1,}\\)\>`__[\\]<\\- <20>'\")}>/\\:\\.,;!?]\\@=", '\="<vim:a href=\"".VST_ProtectLiteral(submatch(1))."\" title=\"".VST_ProtectLiteral(submatch(1))."\">".VST_ProtectLiteral(submatch(1))."</vim:a>"', 'g')
|
||
let par = substitute(par, "[- <20>'\"([{</:>]\\@<=`\\([^[:space:]<5D>`]\\)\\([^`]\\{-}\\) \<\\(.\\{-1,}\\)\>`__[\\]<\\- <20>'\")}>/\\:\\.,;!?]\\@=", '\="<vim:a href=\"".VST_ProtectLiteral(submatch(3))."\" title=\"".submatch(1).submatch(2)."\">".submatch(1).submatch(2)."</vim:a>"', 'g')
|
||
" Multi word anon hyperlink (enclosed in backticks)
|
||
let par = substitute(par, "[- <20>'\"([{</:>]\\@<=`\\([^[:space:]<5D>`]\\)\\([^`]\\{-}\\)`__[\\]<\\- <20>'\")}>/\\:\\.,;!?]\\@=", '\="<vim:a href=\"-vst-anon-hyperlink-\" title=\"".VST_RemoveTags(submatch(1).submatch(2))."\">".submatch(1).submatch(2)."</vim:a>"', 'g')
|
||
" One word anon hyperlink
|
||
let par = substitute(par, "[- <20>'\"([{</:>]\\@<=\\([[:alnum:]._-]\\{-2,}\\)__[\\]<\\- <20>'\")}>/\\:\\.,;!?]\\@=", '<vim:a href="-vst-anon-hyperlink-" title="\1">\1</vim:a>', 'g')
|
||
let par = substitute(par, "[- <20>'\"([{</:>]\\@<=\\(\\k\\{-1,}\\)__[\\]<\\- <20>'\")}>/\\:\\.,;!?]\\@=", '<vim:a href="-vst-anon-hyperlink-" title="\1">\1</vim:a>', 'g')
|
||
endif
|
||
" Embedded hyperlinks
|
||
let par = substitute(par, "[- <20>'\"([{</:>]\\@<=`\<\\([^`]\\{-1,}\\)\>`_[\\]<\\- <20>'\")}>/\\:\\.,;!?]\\@=", '\="<vim:a href=\"".VST_ProtectLiteral(submatch(1))."\" title=\"".VST_ProtectLiteral(submatch(1))."\">".VST_ProtectLiteral(submatch(1))."</vim:a>"', 'g')
|
||
let par = substitute(par, "[- <20>'\"([{</:>]\\@<=`\\([^[:space:]<5D>`]\\)\\([^`]\\{-}\\) \<\\(.\\{-1,}\\)\>`_[\\]<\\- <20>'\")}>/\\:\\.,;!?]\\@=", '\="<vim:a href=\"".VST_ProtectLiteral(submatch(3))."\" title=\"".submatch(1).submatch(2)."\">".submatch(1).submatch(2)."</vim:a>"', 'g')
|
||
" Multi word hyperlink (enclosed in backticks)
|
||
let par = substitute(par, "[- <20>'\"([{</:>]\\@<=`\\([^[:space:]<5D>`]\\)\\([^`]\\{-}\\)`_[\\]<\\- <20>'\")}>/\\:\\.,;!?]\\@=", '\="<vim:a hrefext=\"".VST_RemoveTags(submatch(1).submatch(2))."\" title=\"".VST_RemoveTags(submatch(1).submatch(2))."\">".submatch(1).submatch(2)."</vim:a>"', 'g')
|
||
" One word hyperlink
|
||
let par = substitute(par, "[- <20>'\"([{</:>]\\@<=\\([[:alnum:]._-]\\{-2,}\\)_[\\]<\\- <20>'\")}>/\\:\\.,;!?]\\@=", '<vim:a hrefext="\1" title="\1">\1</vim:a>', 'g')
|
||
let par = substitute(par, "[- <20>'\"([{</:>]\\@<=\\(\\k\\{-1,}\\)_[\\]<\\- <20>'\")}>/\\:\\.,;!?]\\@=", '<vim:a hrefext="\1" title="\1">\1</vim:a>', 'g')
|
||
|
||
" Strange splitting is necessary to be sure it will be unique and only one
|
||
" hyperlink per element.
|
||
let parlines = split(par, 'vim:a h')
|
||
let j = 0
|
||
for parline in parlines
|
||
if parline =~ '^refext='
|
||
let title = tolower(matchstr(parlines[j], '^refext="\zs.\{-}\ze"'))
|
||
let title = substitute(title, '\s\+-vst-new-line-\s\+', ' ', 'g')
|
||
" There was already some processing in text, while data in hlinkdb
|
||
" is in its crude form. I need to reverse some changes to match
|
||
" them:
|
||
let title = substitute(title, '&', '\&', 'g')
|
||
let title = substitute(title, '<', '<', 'g')
|
||
let title = substitute(title, '>', '>', 'g')
|
||
let title = substitute(title, '©', '(c)', 'g')
|
||
let title = substitute(title, '@', '@', 'g')
|
||
|
||
if has_key(g:vst_hlinkdb, title) && g:vst_hlinkdb[title] != ''
|
||
let href = escape(g:vst_hlinkdb[title], '&\~')
|
||
if href =~ '_\s*$'
|
||
while href =~ '_\s*$'
|
||
" If ends in _ it is probably indirect link, process it
|
||
" We need to remove _ from the end to get proper key name.
|
||
let shref = tolower(matchstr(href, '^\s*\(`\?\)\zs.*\ze\1_\s*$'))
|
||
if has_key(g:vst_hlinkdb, shref) && g:vst_hlinkdb[shref] != ''
|
||
let href = escape(g:vst_hlinkdb[shref], '&\~')
|
||
else
|
||
let href = '#l'.tolower(VST_IdMaker(shref))
|
||
endif
|
||
endwhile
|
||
else
|
||
let href = escape(g:vst_hlinkdb[title], '&\~')
|
||
endif
|
||
else
|
||
let href = '#l'.VST_IdMaker(title)
|
||
endif
|
||
let parlines[j] = substitute(parlines[j], '^refext=".\{-}"', 'ref="'.href.'"', 'g')
|
||
let parlines[j] = substitute(parlines[j], 'title="\(.\{-}\)"', '\="title=\"".substitute(submatch(1), " -vst-new-line-\s*", " ", "g")."\""', 'g')
|
||
endif
|
||
let j += 1
|
||
endfor
|
||
let par = join(parlines, 'vim:a h')
|
||
|
||
let par = substitute(par, '^ ', '', '')
|
||
let par = substitute(par, ' $', '', '')
|
||
let par = substitute(par, ' -vst-new-line- ', '\n', 'g')
|
||
" Without this regexp new line placeholders wouldn't be removed from
|
||
" broken embedded URIs
|
||
let par = substitute(par, ' -vst-new-line-\(\S\)', '\1', 'g')
|
||
|
||
return par
|
||
endfunction
|
||
" }}}
|
||
" VST_IdentifyImage: Return dimensions of image {{{
|
||
function! VST_IdentifyImage(imagename, line)
|
||
let iscale = matchstr(a:line, ':identify:\s*\zs.\{-}\ze\s*$')
|
||
let istring = system('identify -format %wx%h "'.a:imagename.'"')
|
||
if istring =~ '^identify'
|
||
let width = ''
|
||
let height = ''
|
||
endif
|
||
" identify may return new line char at the end breaking some regexps in
|
||
" final stage.
|
||
let istring = substitute(istring, '\n', '', 'g')
|
||
let dimensions = split(istring, 'x')
|
||
if iscale != '' && iscale !~ '\D'
|
||
let width = dimensions[0]*iscale/100
|
||
let height = dimensions[1]*iscale/100
|
||
else
|
||
let [width, height] = dimensions
|
||
endif
|
||
|
||
return [width, height]
|
||
|
||
endfunction
|
||
" }}}
|
||
" VST_IdMaker: Create strings used in name and href {{{
|
||
" arguments of links
|
||
" Description: Split string to list (necessary to escape unholy mess with
|
||
" utf-8 && multibyte characters) and iterate through elements:
|
||
" When char is \w or - leave unchanged,
|
||
" when \s change to -,
|
||
" when other use built-in char2nr() function.
|
||
function! VST_IdMaker(str)
|
||
" Changing to list is necessary to escape mess with utf-8 characters
|
||
let link = split(a:str, '.\zs')
|
||
let out = ''
|
||
let ix = 0
|
||
while ix < len(link)
|
||
if link[ix] =~ '[a-zA-Z0-9_-]'
|
||
let out .= link[ix]
|
||
elseif link[ix] =~ '\s'
|
||
let out .= '-'
|
||
else
|
||
let out .= char2nr(link[ix])
|
||
endif
|
||
let ix += 1
|
||
endwhile
|
||
return out
|
||
endfunction
|
||
" }}}
|
||
" VST_ImagePar: Process image par and return image {{{
|
||
" Description: Process image paragraph checking options and composing vim:img
|
||
" tag
|
||
" par - image paragraph
|
||
" full - is this standalone image or replacement
|
||
" 1 - standalone image, put tag in new line
|
||
" 0 - tag inline, add inline class
|
||
function! VST_ImagePar(par, full)
|
||
if a:full == 1
|
||
let nl = "\n"
|
||
let inline = ''
|
||
else
|
||
" This will be inline image. No need for new line at the end of tag
|
||
" and we have to declare inlininess of it
|
||
let nl = ''
|
||
let inline = ' inline'
|
||
endif
|
||
let src = ''
|
||
let width = ''
|
||
let height = ''
|
||
let alt = ''
|
||
let title = ''
|
||
let identify = ''
|
||
let align = ''
|
||
let scale = ''
|
||
let target = ''
|
||
let class = ''
|
||
let parlines = split(a:par, '\n')
|
||
for parline in parlines
|
||
let parline = substitute(parline, '^\s*', '', '')
|
||
if src == ''
|
||
let src = matchstr(parline, '\(\.\. \)\?image::\s*\zs.\{-}\ze\s*$')
|
||
if !filereadable(escape(src, ' \#%'))
|
||
let noimage = 1
|
||
let g:vst_error .= "No image: ".src."\n"
|
||
else
|
||
let noimage = 0
|
||
endif
|
||
endif
|
||
if width == ''
|
||
let width = matchstr(parline, ':width:\s*\zs.\{-}\ze\s*$')
|
||
endif
|
||
if height == ''
|
||
let height = matchstr(parline, ':height:\s*\zs.\{-}\ze\s*$')
|
||
endif
|
||
if alt == ''
|
||
let alt = matchstr(parline, ':alt:\s*\zs.\{-}\ze\s*$')
|
||
endif
|
||
if title == ''
|
||
let title = matchstr(parline, ':title:\s*\zs.\{-}\ze\s*$')
|
||
endif
|
||
if align == ''
|
||
let align = matchstr(parline, ':align:\s*\zs.\{-}\ze\s*$')
|
||
endif
|
||
if scale == ''
|
||
let scale = matchstr(parline, ':scale:\s*\zs.\{-}\ze\s*$')
|
||
if scale =~ '\D'
|
||
let scale = ''
|
||
endif
|
||
endif
|
||
if target == ''
|
||
let target = matchstr(parline, ':target:\s*\zs.\{-}\ze\s*$')
|
||
if target == 'self' && src != ''
|
||
let target = src
|
||
endif
|
||
while target =~ '_\s*$'
|
||
" If ends in _ it is probably indirect link, process it
|
||
let title = matchstr(target, '^\s*\(`\?\)\zs.*\ze\1_\s*$')
|
||
if has_key(g:vst_hlinkdb, title) && g:vst_hlinkdb[title] != ''
|
||
let href = escape(g:vst_hlinkdb[title], '&\~')
|
||
else
|
||
let href = '#l'.tolower(VST_IdMaker(title))
|
||
endif
|
||
endwhile
|
||
endif
|
||
if class == ''
|
||
let class = matchstr(parline, ':class:\s*\zs.\{-}\ze\s*$')
|
||
endif
|
||
if identify == ''
|
||
let identify = matchstr(parline, ':identify:')
|
||
if identify != ''
|
||
if executable('identify') && noimage == 0
|
||
let [width, height] = VST_IdentifyImage(src, parline)
|
||
else
|
||
let [width, height] = ['', '']
|
||
endif
|
||
endif
|
||
endif
|
||
endfor
|
||
if src != ''
|
||
let tempsrc = VST_ProtectLiteral(src)
|
||
let src = 'src="'.tempsrc.'"'
|
||
endif
|
||
if scale != ''
|
||
if width != ''
|
||
let width = width*scale/100
|
||
endif
|
||
if height != ''
|
||
let height = height*scale/100
|
||
endif
|
||
endif
|
||
if width != ''
|
||
let width = ' width="'.width.'"'
|
||
endif
|
||
if height != ''
|
||
let height = ' height="'.height.'"'
|
||
endif
|
||
if alt != ''
|
||
let alt = ' alt="'.alt.'"'
|
||
else
|
||
let alt = ' alt="'.tempsrc.'"'
|
||
endif
|
||
if title != ''
|
||
let title = ' title="'.title.'"'
|
||
endif
|
||
if class != ''
|
||
if align == ''
|
||
let class = ' class="'.class.inline.'"'
|
||
else
|
||
let class = ' class="'.class.inline.' vst'.align.'"'
|
||
endif
|
||
else
|
||
if align == ''
|
||
if inline != ''
|
||
let class = ' class="inline"'
|
||
else
|
||
let class = ' '
|
||
endif
|
||
else
|
||
let class = ' class="vst'.align.'"'
|
||
endif
|
||
endif
|
||
|
||
if src != ''
|
||
if target != ''
|
||
if target =~ '_\s*$'
|
||
let address = matchstr(VST_Hyperlink(target), '^.\{-}>\ze')
|
||
else
|
||
let address = '<vim:a href="'.VST_ProtectLiteral(target).'">'
|
||
endif
|
||
let para = address.nl."<vim:img ".src.width.height.class.alt.title." />".nl."</vim:a>"
|
||
else
|
||
let para = "\n<vim:img ".src.width.height.class.alt.title." />".nl
|
||
endif
|
||
else
|
||
let para = '<vim:!-- '.a:par.' -->'
|
||
endif
|
||
if a:full == 1
|
||
return "<vim:p>\n".para."\n</vim:p>"
|
||
else
|
||
return para
|
||
endif
|
||
endfunction
|
||
" }}}
|
||
" VST_LabelFootnote: Create auto-numbered footnotes [#first]_ {{{
|
||
function! VST_LabelFootnote(text)
|
||
let par = a:text
|
||
for label in keys(g:lfnotes)
|
||
let k = g:lfnotes[label]
|
||
let par = substitute(par, '\[#'.label.']_', '<vim:a href="#footnote-'.k.'" name="target-'.k.'">['.k.']</vim:a>', 'g')
|
||
endfor
|
||
|
||
unlet! k
|
||
|
||
return par
|
||
|
||
endfunction
|
||
" }}}
|
||
" VST_Markup: Create inline markup of text styles " {{{
|
||
function! VST_Markup(text)
|
||
let par = substitute(a:text, '\n', ' -vst-new-line- ', 'g')
|
||
" Technical spaces
|
||
let par = ' '.par.' '
|
||
" Take care about escaping of asterisk
|
||
let par = substitute(par, '\\\@<!\\\*', '-vst-escape-asterisk-', 'g')
|
||
" Take care about single asterisk
|
||
let par = substitute(par, ' \* ', ' \* ', 'g')
|
||
" Take care about single asterisk inside of (), {}, [], '', ""
|
||
let par = substitute(par, "\\([[({<]\\)\\*\\([])}> ]\\)", '\1\*\2', 'g')
|
||
let par = substitute(par, "\\(['\"]\\)\\*\\([\"']\\)", '\1\*\2', 'g')
|
||
" Take care about double asterisk inside of (), {}, [], '', ""
|
||
let par = substitute(par, "\\([[({<]\\)\\*\\*\\([])}> ]\\)", '\1\*\*\2', 'g')
|
||
let par = substitute(par, "\\(['\"]\\)\\*\\*\\([\"']\\)", '\1\*\*\2', 'g')
|
||
" Take care about backticks inside of (), {}, [], '', ""
|
||
let par = substitute(par, "\\([[({<]\\)`\\([])}> ]\\)", '\1\`\2', 'g')
|
||
let par = substitute(par, "\\(['\"]\\)`\\([\"']\\)", '\1\`\2', 'g')
|
||
" Take care about double backticks inside of (), {}, [], '', ""
|
||
let par = substitute(par, "\\([[({<]\\)``\\([])}> ]\\)", '\1\`\`\2', 'g')
|
||
let par = substitute(par, "\\(['\"]\\)``\\([\"']\\)", '\1\`\`\2', 'g')
|
||
"" **strong**, Note: second space in next 3 LOC is nonbreaking space - \x160
|
||
let par = substitute(par, "[- <20>'\"([{</:>~]\\@<=\\*\\* \\@<!\\(.\\{-}\\)\\*\\*[\\]<\\- <20>'\")}>/\\:\\.,;!?]\\@=", '<vim:strong>\1</vim:strong>', 'g')
|
||
"" *emph*
|
||
let par = substitute(par, "[- <20>'\"([{</:>~]\\@<=\\* \\@<!\\(.\\{-1,}\\)\\*[\\]<\\- <20>'\")}>/\\\:.,;!?]\\@=", '<vim:em>\1</vim:em>', 'g')
|
||
"" ``literal`` (<code> like), ``code``, Note: space after :space: is
|
||
" nonbreaking space, not included into :space:
|
||
let par = substitute(par, "[- <20>'\"([{</:>~]\\@<=``\\([^[:space:]<5D>]\\)\\(.\\{-}\\)``[\\]<\\- <20>'\")}>/\\\:.,;!?]\\@=", '\="<vim:code>".VST_ProtectLiteral(submatch(1).submatch(2))."</vim:code>"', 'g')
|
||
|
||
let par = substitute(par, ' -vst-new-line- ', '\n', 'g')
|
||
|
||
" Restore escaped asterisk
|
||
let par = substitute(par, '-vst-escape-asterisk-', '\\*', 'g')
|
||
" Restore asterisks
|
||
let par = substitute(par, '*', '*', 'g')
|
||
" Restore backticks
|
||
let par = substitute(par, '`', '`', 'g')
|
||
" Remove technical spaces
|
||
let par = substitute(par, ' $', '', '')
|
||
let par = substitute(par, '^ ', '', '')
|
||
|
||
|
||
return par
|
||
endfunction
|
||
" }}}
|
||
" VST_ProtectLiteral: Change special chars inside of literals into entities {{{
|
||
" Description: take text from submatch and change meaningful characters into
|
||
" entities.
|
||
function! VST_ProtectLiteral(text)
|
||
" Escaping of special characters
|
||
"let par = substitute(a:text, "[[`\_|:]", '\="\&#".char2nr(submatch(0)).";"', 'g')
|
||
let par = substitute(a:text, '`', '\`', 'g')
|
||
let par = substitute(par, '[', '\[', 'g')
|
||
let par = substitute(par, '\', '\\', 'g')
|
||
let par = substitute(par, '_', '\_', 'g')
|
||
let par = substitute(par, '|', '\|', 'g')
|
||
" : is required part of raw links, if we don't want to convert them,
|
||
" "remove" colon
|
||
let par = substitute(par, ':', '\:', 'g')
|
||
|
||
return par
|
||
endfunction
|
||
" }}}
|
||
" VST_RemoveTags: Returns given string without vim tags {{{
|
||
function! VST_RemoveTags(text)
|
||
return substitute(a:text, '<.\?vim:[^>]\{-}>', '', 'g')
|
||
|
||
endfunction
|
||
" }}}
|
||
" VST_Replacement: Resolve |replacements| into full text {{{
|
||
function! VST_Replacement(text)
|
||
|
||
let par = a:text
|
||
" Loop through entries in replacedb
|
||
" keys and values have to be proper Vim regexp constructs
|
||
for key in keys(g:vst_replacedb)
|
||
let replace = g:vst_replacedb[key]
|
||
"let replace = escape(g:vst_replacedb[key], '\&~')
|
||
" [^:] blocks processing of reST style image replacement
|
||
if replace =~ '^image:[^:]'
|
||
" Old style image, deprecated {{{
|
||
" Create image. We have here one line of pairs term:definition,
|
||
" but definition can be a string with spaces embraced in quotes.
|
||
" image:src with:420 alt:"this image"
|
||
let img = substitute(replace, '\(\w\+\):', ',"\1":', 'g')
|
||
let img = substitute(img, ':\([^"].\{-}\)\( \|$\)', ':"\1"', 'g')
|
||
let img = '{'.substitute(img, '^\s*,', '', 'g').'}'
|
||
unlet! g:image
|
||
let g:image = eval(img)
|
||
let replace = '<vim:img class="inline" '
|
||
for attr in keys(g:image)
|
||
if attr == 'image'
|
||
let item = 'src="'.g:image[attr].'" '
|
||
let replace .= item
|
||
elseif attr == 'identify' || attr == 'target'
|
||
continue
|
||
else
|
||
let item = attr.'="'.g:image[attr].'" '
|
||
let replace .= item
|
||
endif
|
||
endfor
|
||
let replace .= '/>'
|
||
if has_key(g:image, 'target')
|
||
if g:image['target'] == 'self'
|
||
let ttarget = g:image['image']
|
||
endif
|
||
let replace = '<vim:a href="'.g:image['image'].'">'.replace.'</vim:a>'
|
||
endif
|
||
let par = substitute(par, '|'.key.'|', replace, 'g')
|
||
" }}}
|
||
elseif replace =~ '^replace::'
|
||
" Plain replace {{{
|
||
if replace =~ ':ltrim:'
|
||
let ltrim = '\s*'
|
||
let rtrim = ''
|
||
elseif replace =~ ':trim:'
|
||
let ltrim = '\s*'
|
||
let rtrim = '\s*'
|
||
elseif replace =~ ':rtrim:'
|
||
let ltrim = ''
|
||
let rtrim = '\s*'
|
||
else
|
||
let ltrim = ''
|
||
let rtrim = ''
|
||
endif
|
||
" Process special characters in key: lt, gt, amp
|
||
" They were already processed in text
|
||
let key = substitute(key, '&', '\&', 'g')
|
||
let key = substitute(key, '<', '\<', 'g')
|
||
let key = substitute(key, '>', '\>', 'g')
|
||
let replace = matchstr(replace, '^replace::\s*\zs.\{-}\ze\_s*\(\.\. \|:trim:\|:ltrim:\|:rtrim:\|$\)')
|
||
"let replace = matchstr(replace, '^replace::\s*\zs.\{-}\ze\s*$')
|
||
let replace = escape(VST_SpecCharacter(replace), '&~\')
|
||
if par =~ '|_'
|
||
" Placeholder necessary to later trigger markup commands
|
||
let par = substitute(par, ltrim.'|'.key.'|__'.rtrim, '`{-vst-replace-{'.replace.'}-vst-replace-}`__', 'g')
|
||
let par = substitute(par, ltrim.'|'.key.'|_'.rtrim, '`{-vst-replace-{'.replace.'}-vst-replace-}`_', 'g')
|
||
if has_key(g:vst_hlinkdb, key)
|
||
" replace can contain markup - in text it will be proceed,
|
||
" in db no. Force
|
||
let proceed = VST_Markup(replace)
|
||
let proceed = VST_Roles(proceed)
|
||
let proceed = VST_EscapingSlash(proceed)
|
||
" And remove tags!
|
||
let proceed = substitute(proceed, '<.\?vim:[^>]\{-}>', '', 'g')
|
||
let g:vst_hlinkdb[tolower(proceed)] = g:vst_hlinkdb[key]
|
||
endif
|
||
endif
|
||
let par = substitute(par, ltrim.'|'.key.'|'.rtrim, replace, 'g')
|
||
" }}}
|
||
elseif replace =~ '^unicode::'
|
||
" Unicode {{{
|
||
if replace =~ ':ltrim:'
|
||
let ltrim = '\s*'
|
||
let rtrim = ''
|
||
elseif replace =~ ':trim:'
|
||
let ltrim = '\s*'
|
||
let rtrim = '\s*'
|
||
elseif replace =~ ':rtrim:'
|
||
let ltrim = ''
|
||
let rtrim = '\s*'
|
||
else
|
||
let ltrim = ''
|
||
let rtrim = ''
|
||
endif
|
||
let g:vst_encoding = "utf-8"
|
||
" We need this interference - without that character would be
|
||
" inserted improperly
|
||
let origenc = &encoding
|
||
set encoding=utf-8
|
||
let key = substitute(key, '&', '\&', 'g')
|
||
let key = substitute(key, '<', '\<', 'g')
|
||
let key = substitute(key, '>', '\>', 'g')
|
||
let replace = matchstr(replace, '^unicode::\s*\zs.\{-}\ze\s*\(\.\. \|:trim:\|:ltrim:\|:rtrim:\|$\)')
|
||
let replace = substitute(replace, '\(0x\|x\|\\x\|U+\|u\|\\u\|&#x\)\([0-9a-fA-F]\+\)', '\=Unicode2Char(submatch(2))', 'g')
|
||
let replace = substitute(replace, '\_s' , '', 'g')
|
||
let replace = escape(VST_SpecCharacter(replace), '&~\')
|
||
if par =~ '|_'
|
||
let par = substitute(par, '|'.key.'|__', '`'.replace.'`__', 'g')
|
||
let par = substitute(par, '|'.key.'|_', '`'.replace.'`_', 'g')
|
||
if has_key(g:vst_hlinkdb, key)
|
||
" replace can contain markup - in text it will be proceed,
|
||
" in db no. Force
|
||
let proceed = VST_Markup(replace)
|
||
let proceed = VST_Roles(proceed)
|
||
let proceed = VST_EscapingSlash(proceed)
|
||
" And remove tags!
|
||
let proceed = substitute(proceed, '<.\?vim:[^>]\{-}>', '', 'g')
|
||
let g:vst_hlinkdb[tolower(proceed)] = g:vst_hlinkdb[key]
|
||
endif
|
||
endif
|
||
"let par = substitute(par, ltrim.'|'.key.'|__'.rtrim, '`'.replace.'`__', 'g')
|
||
"let par = substitute(par, ltrim.'|'.key.'|_'.rtrim, '`'.replace.'`_', 'g')
|
||
let par = substitute(par, ltrim.'|'.key.'|'.rtrim, replace, 'g')
|
||
let &encoding = origenc
|
||
" }}}
|
||
elseif replace =~ '^image::'
|
||
" Image replacement {{{
|
||
let replace = VST_ImagePar(replace, 0)
|
||
let replace = escape(replace, '&~\')
|
||
let par = substitute(par, '|'.key.'|', replace, 'g')
|
||
" }}}
|
||
elseif replace =~ '^date::'
|
||
" Date replacement {{{
|
||
let replace = matchstr(replace, 'date::\s*\zs.*$')
|
||
let replace = substitute(replace, '\s*$', '', '')
|
||
if exists("*strftime")
|
||
if replace == ''
|
||
let replace = strftime("%Y-%m-%d")
|
||
else
|
||
let replace = strftime(replace)
|
||
endif
|
||
else
|
||
let replace = localtime()
|
||
endif
|
||
|
||
let replace = escape(replace, '&~\')
|
||
let par = substitute(par, '|'.key.'|', replace, 'g')
|
||
" }}}
|
||
elseif replace =~ '^\w\+::'
|
||
" Don't perform replacement of reST style replacement directives.
|
||
" This can cause big mess.
|
||
continue
|
||
endif
|
||
endfor
|
||
|
||
|
||
return par
|
||
endfunction
|
||
" }}}
|
||
" VST_Roles: Change text :roles: into proper tags " {{{
|
||
function! VST_Roles(text)
|
||
let par = substitute(a:text, '\n', ' -vst-new-line- ', 'g')
|
||
" Technical spaces
|
||
let par = ' '.par.' '
|
||
" :sub:`text` and `text`:sub:
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=:sub:`\\([^`]\\{-1,}\\)`[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:sub>\1</vim:sub>', 'g')
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=`\\([^`]\\{-1,}\\)`:sub:[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:sub>\1</vim:sub>', 'g')
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=:subscript:`\\([^`]\\{-1,}\\)`[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:sub>\1</vim:sub>', 'g')
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=`\\([^`]\\{-1,}\\)`:subscript:[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:sub>\1</vim:sub>', 'g')
|
||
" :sup:`text` and `text`:sup:
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=:sup:`\\([^`]\\{-1,}\\)`[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:sup>\1</vim:sup>', 'g')
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=`\\([^`]\\{-1,}\\)`:sup:[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:sup>\1</vim:sup>', 'g')
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=:superscript:`\\([^`]\\{-1,}\\)`[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:sup>\1</vim:sup>', 'g')
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=`\\([^`]\\{-1,}\\)`:superscript:[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:sup>\1</vim:sup>', 'g')
|
||
" :strong:`text` and `text`:strong:
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=:strong:`\\([^`]\\{-1,}\\)`[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:strong>\1</vim:strong>', 'g')
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=`\\([^`]\\{-1,}\\)`:strong:[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:strong>\1</vim:strong>', 'g')
|
||
" :emphasis:`text` and `text`:emphasis:
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=:emphasis:`\\([^`]\\{-1,}\\)`[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:em>\1</vim:em>', 'g')
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=`\\([^`]\\{-1,}\\)`:emphasis:[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:em>\1</vim:em>', 'g')
|
||
" :literal:`text` and `text`:literal:
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=:literal:`\\([^`]\\{-1,}\\)`[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:code>\1</vim:code>', 'g')
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=`\\([^`]\\{-1,}\\)`:literal:[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:code>\1</vim:code>', 'g')
|
||
" :big:`text` and `text`:big:
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=:big:`\\([^`]\\{-1,}\\)`[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:span class="big">\1</vim:span>', 'g')
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=`\\([^`]\\{-1,}\\)`:big:[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:span class="big">\1</vim:span>', 'g')
|
||
" :small:`text` and `text`:small:
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=:small:`\\([^`]\\{-1,}\\)`[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:span class="small">\1</vim:span>', 'g')
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=`\\([^`]\\{-1,}\\)`:small:[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:span class="small">\1</vim:span>', 'g')
|
||
" :title-reference:, :title:, :t:
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=:title-reference:`\\([^`]\\{-1,}\\)`[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:cite>\1</vim:cite>', 'g')
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=:title:`\\([^`]\\{-1,}\\)`[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:cite>\1</vim:cite>', 'g')
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=:t:`\\([^`]\\{-1,}\\)`[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:cite>\1</vim:cite>', 'g')
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=`\\([^`]\\{-1,}\\)`:title-reference:[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:cite>\1</vim:cite>', 'g')
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=`\\([^`]\\{-1,}\\)`:title:[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:cite>\1</vim:cite>', 'g')
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=`\\([^`]\\{-1,}\\)`:t:[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '<vim:cite>\1</vim:cite>', 'g')
|
||
" any other role
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=:\\(\\S\\+\\):`\\([^`]\\{-1,}\\)`[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '\=VST_ExtraRoles(submatch(1), submatch(2))', 'g')
|
||
let par = substitute(par, "[- <20>`'\"([{</:>]\\@<=`\\([^`]\\{-1,}\\)`:\\(\\S\\+\\):[\\]\\- <20>'\")}<>/\\\:.,;!?]\\@=", '\=VST_ExtraRoles(submatch(1), submatch(2))', 'g')
|
||
|
||
let par = substitute(par, ' -vst-new-line- ', '\n', 'g')
|
||
" Remove technical spaces
|
||
let par = substitute(par, ' $', '', '')
|
||
let par = substitute(par, '^ ', '', '')
|
||
|
||
return par
|
||
endfunction
|
||
" }}}
|
||
" VST_DefaultRole: Change `default roles` into proper tags " {{{
|
||
function! VST_DefaultRole(text)
|
||
|
||
let par = substitute(a:text, '\n', ' -vst-new-line- ', 'g')
|
||
" Technical spaces
|
||
let par = ' '.par.' '
|
||
|
||
" Take care about backticks inside of (), {}, [], '', ""
|
||
let par = substitute(par, "\\([['\"({<]\\)`\\([])}>\"']\\)", '\1\`\2', 'g')
|
||
|
||
let split_file = split(par, '\(^\|-vst-new-line-\)\s*\.\. default-role::\s*')
|
||
|
||
if len(split_file) == 1
|
||
let roled = substitute(split_file[0], "[- <20>'\"([{</:>;]\\@<=`\\([^[:space:]<5D>`]\\)\\(.\\{-}\\)`[`\\]<\\- <20>'\")}>/\\:\\.,;!?]\\@=", '<vim:cite>\1\2</vim:cite>', 'g')
|
||
else
|
||
for i in range(len(split_file))
|
||
|
||
if i == 0
|
||
let split_file[i] = substitute(split_file[i], "[- '\"([{</:>;]\\@<=`\\([^[:space:]`]\\)\\(.\\{-}\\)`[`\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '<vim:cite>\1\2</vim:cite>', 'g')
|
||
else
|
||
let role = matchstr(split_file[i], '^.\{-}\ze\s\+-vst-new-line- ')
|
||
let split_file[i] = substitute(split_file[i], '^.\{-}-vst-new-line- ', '', '')
|
||
if role =~ '^\(t\|title\|title-reference\)$'
|
||
let split_file[i] = substitute(split_file[i], "[- '\"([{</:>;]\\@<=`\\([^[:space:]<5D>`]\\)\\([^`]\\{-}\\)`[`\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '<vim:cite>\1\2</vim:cite>', 'g')
|
||
elseif role =~ '^sup\(erscript\)\?$'
|
||
let split_file[i] = substitute(split_file[i], "[- '\"([{</:>;]\\@<=`\\([^[:space:]<5D>`]\\)\\([^`]\\{-}\\)`[`\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '<vim:sup>\1\2</vim:sup>', 'g')
|
||
elseif role =~ '^sub\(script\)\?$'
|
||
let split_file[i] = substitute(split_file[i], "[- '\"([{</:>;]\\@<=`\\([^[:space:]<5D>`]\\)\\([^`]\\{-}\\)`[`\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '<vim:sub>\1\2</vim:sub>', 'g')
|
||
elseif role =~ '^strong$'
|
||
let split_file[i] = substitute(split_file[i], "[- '\"([{</:>;]\\@<=`\\([^[:space:]<5D>`]\\)\\([^`]\\{-}\\)`[`\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '<vim:strong>\1\2</vim:strong>', 'g')
|
||
elseif role =~ '^emphasis$'
|
||
let split_file[i] = substitute(split_file[i], "[- '\"([{</:>;]\\@<=`\\([^[:space:]<5D>`]\\)\\([^`]\\{-}\\)`[`\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '<vim:em>\1\2</vim:em>', 'g')
|
||
elseif role =~ '^literal$'
|
||
let split_file[i] = substitute(split_file[i], "[- '\"([{</:>;]\\@<=`\\([^[:space:]<5D>`]\\)\\([^`]\\{-}\\)`[`\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '<vim:code>\1\2</vim:code>', 'g')
|
||
elseif role =~ '^big$'
|
||
let split_file[i] = substitute(split_file[i], "[- '\"([{</:>;]\\@<=`\\([^[:space:]<5D>`]\\)\\([^`]\\{-}\\)`[`\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '<vim:span class="big">\1\2</vim:span>', 'g')
|
||
elseif role =~ '^small$'
|
||
let split_file[i] = substitute(split_file[i], "[- '\"([{</:>;]\\@<=`\\([^[:space:]<5D>`]\\)\\([^`]\\{-}\\)`[`\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '<vim:span class="small">\1\2</vim:span>', 'g')
|
||
else
|
||
let role = VST_IdMaker(role)
|
||
let split_file[i] = substitute(split_file[i], "[- '\"([{</:>;]\\@<=`\\([^[:space:]<5D>`]\\)\\([^`]\\{-}\\)`[`\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '<vim:span class="'.role.'">\1\2</vim:span>', 'g')
|
||
endif
|
||
endif
|
||
endfor
|
||
let roled = join(split_file, "\n")
|
||
endif
|
||
|
||
let par = substitute(roled, ' -vst-new-line- ', '\n', 'g')
|
||
" Restore backticks
|
||
let par = substitute(par, '`', '`', 'g')
|
||
" Remove technical spaces
|
||
let par = substitute(par, ' $', '', '')
|
||
let par = substitute(par, '^ ', '', '')
|
||
|
||
return par
|
||
endfunction
|
||
" }}}
|
||
" VST_SA_Hyperlink: Process explicit hyperlinks {{{
|
||
" Description: Find text following rules of certain protocol and change it
|
||
" into <a href>.
|
||
" Supported: http, https, ftp, sftp, mailto
|
||
function! VST_SA_Hyperlink(text)
|
||
|
||
function! VST_PunctTrap(link)
|
||
let punctless = a:link
|
||
if punctless =~ '[.?!;,]$'
|
||
let punctless = matchstr(punctless, '.*\ze.$')
|
||
endif
|
||
return VST_ProtectLiteral(punctless)
|
||
endfunction
|
||
|
||
let par = a:text
|
||
" Handle standalone links in <> brackets.
|
||
let par = substitute(par, '<\(https\?://[a-zA-Z0-9./%&@#:;?=_-]\+\)>\(`_\)\@!', '\="\<<vim:a href=\"".VST_PunctTrap(submatch(1))."\">".VST_ProtectLiteral(submatch(1))."</vim:a>\>"', 'g')
|
||
let par = substitute(par, '<\(s\?ftp://[a-zA-Z0-9./%&#@:;?=_-]\+\)>\(`_\)\@!', '\="\<<vim:a href=\"".VST_PunctTrap(submatch(1))."\">".VST_ProtectLiteral(submatch(1))."</vim:a>\>"', 'g')
|
||
let par = substitute(par, '<mailto:\([a-zA-Z0-9@&#.;?=_-]\+\)>\(`_\)\@!', '\="\<<vim:a href=\"mailto:".VST_PunctTrap(submatch(1))."\">".VST_ProtectLiteral(submatch(1))."</vim:a>\>"', 'g')
|
||
|
||
let par = substitute(par, '\(href="\|<\)\@<!https\?://[a-zA-Z0-9./%&@#:;?=_-]\+', '\="<vim:a href=\"".VST_PunctTrap(submatch(0))."\">".VST_ProtectLiteral(submatch(0))."</vim:a>"', 'g')
|
||
let par = substitute(par, '\(href="\|<\)\@<!s\?ftp://[a-zA-Z0-9./%&#@:;?=_-]\+', '\="<vim:a href=\"".VST_PunctTrap(submatch(0))."\">".VST_ProtectLiteral(submatch(0))."</vim:a>"', 'g')
|
||
let par = substitute(par, '\(href="\|<\)\@<!mailto:\([a-zA-Z0-9@&#.;?=_-]\+\)', '\="<vim:a href=\"".VST_PunctTrap(submatch(0))."\">".VST_ProtectLiteral(submatch(2))."</vim:a>"', 'g')
|
||
|
||
" Remove doubled links caused by http regexps.
|
||
let par = substitute(par, '\(<vim:a href=".\{-}">\)\1', '\1', 'g')
|
||
let par = substitute(par, '</vim:a></vim:a>', '</vim:a>', 'g')
|
||
" In 99% of causes some punct chars at the end of link (.?!;,) shouldn't be
|
||
" there and was already catched by VST_PunctTrap
|
||
let par = substitute(par, '\([.?!;,]\+\)</vim:a>', '</vim:a>\1', 'g')
|
||
|
||
return par
|
||
endfunction
|
||
" }}}
|
||
" VST_SpecCharacter: Change special chars into entities {{{
|
||
" Supported: &, <, >, (c)
|
||
function! VST_SpecCharacter(text)
|
||
" Escaping of special characters
|
||
let par = substitute(a:text, '&\([#a-z0-9]\+;\)\@!', '\&', 'g')
|
||
let par = substitute(par, '\\&[#a-z0-9]', '\&#', 'g')
|
||
let par = substitute(par, '(c)', '\©', 'g')
|
||
let par = substitute(par, '@', '\@', 'g')
|
||
let par = substitute(par, '<', '\<', 'g')
|
||
let par = substitute(par, '>', '\>', 'g')
|
||
return par
|
||
endfunction
|
||
" }}}
|
||
" VST_Target: Create <span id> tags for _`inline targets` {{{
|
||
function! VST_Target(text)
|
||
let par = substitute(a:text, '\n', ' -vst-new-line- ', 'g')
|
||
" Technical spaces
|
||
let par = ' '.par.' '
|
||
" _`Inline internal targets`
|
||
let par = substitute(par, "[- '\"([{</:>]\\@<=_`\\([^[:space:]<5D>`]\\)\\(.\\{-}\\)`[\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '<vim:span targetid="\1\2" title="\1\2" class="target">\1\2</vim:span>', 'g')
|
||
let par = substitute(par, "[- '\"([{</:>]\\@<=_\\([[:alnum:]._-]\\{-2,}\\)[\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '<vim:span targetid="\1" title="\1" class="target">\1</vim:span>', 'g')
|
||
let par = substitute(par, "[- '\"([{</:>]\\@<=_\\(\\k\\{-1,}\\)[\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '<vim:span targetid="\1" title="\1" class="target">\1</vim:span>', 'g')
|
||
" Strange splitting is necessary to be sure it will be unique and only one
|
||
" hyperlink per element.
|
||
let parlines = split(par, 'vim:span targeti')
|
||
let j = 0
|
||
for parline in parlines
|
||
if parline =~ '^d='
|
||
let title = tolower(matchstr(parlines[j], '^d="\zs.\{-}\ze"'))
|
||
let href = VST_IdMaker(substitute(title, '\s\+-vst-new-line-\s\+', ' ', 'g'))
|
||
let parlines[j] = substitute(parlines[j], '^d=".\{-}"', 'd="l'.href.'"', 'g')
|
||
endif
|
||
let j += 1
|
||
endfor
|
||
let par = join(parlines, 'vim:span i')
|
||
|
||
let par = substitute(par, '^ ', '', '')
|
||
let par = substitute(par, ' $', '', '')
|
||
|
||
let par = substitute(par, ' -vst-new-line- ', '\n', 'g')
|
||
|
||
return par
|
||
endfunction
|
||
" }}}
|
||
" VST_FoldExpr: Folding expression {{{
|
||
" lnum - current line to evaluate fold level
|
||
function! VST_FoldExpr(lnum)
|
||
if getline(a:lnum) =~ "'"
|
||
let line = substitute(getline(a:lnum), "'", "''", 'g')
|
||
else
|
||
let line = getline(a:lnum)
|
||
endif
|
||
if b:vst_fold_lvl =~ 'r'
|
||
if string(b:vst_flvl_1) =~? "[[ ]'".escape(line, '.*\[~&^$')."'[],]"
|
||
return '>1'
|
||
elseif string(b:vst_flvl_2) =~? "[[ ]'".escape(line, '.*\[~&^$')."'[],]"
|
||
return '>2'
|
||
elseif string(b:vst_flvl_3) =~? "[[ ]'".escape(line, '.*\[~&^$')."'[],]"
|
||
return '>3'
|
||
elseif string(b:vst_flvl_4) =~? "[[ ]'".escape(line, '.*\[~&^$')."'[],]"
|
||
return '>4'
|
||
elseif string(b:vst_flvl_5) =~? "[[ ]'".escape(line, '.*\[~&^$')."'[],]"
|
||
return '>5'
|
||
elseif string(b:vst_flvl_6) =~? "[[ ]'".escape(line, '.*\[~&^$')."'[],]"
|
||
return '>6'
|
||
else
|
||
return '='
|
||
endif
|
||
endif
|
||
"let list = keys(b:vst_fold)
|
||
let list = keys(b:vst_fold_list)
|
||
if string(list) =~? "[[ ]'".escape(line, '.*\[~&^$')."'[],]"
|
||
return '>1'
|
||
else
|
||
return '1'
|
||
endif
|
||
endfunction
|
||
" }}}
|
||
" VST_D: simple debug {{{
|
||
" Description: echo structure of document in form of list:
|
||
" <par number>) <par indentation> <par type>
|
||
function! VD()
|
||
for i in range(len(g:paras))
|
||
"echo i.') '.g:pindent[i].' '.g:ptype[i].' '.split(g:paras[i], "\n")[0]."\n"
|
||
echo i.') '.g:pindent[i].' '.g:ptype[i].' '."\n"
|
||
endfor
|
||
endfunction
|
||
" }}}
|
||
" VST_End: remove unnecessary global variables and other garbage {{{
|
||
" Description: function unlet! g:vars which may clash in next calls of VST
|
||
" functions
|
||
function! VST_End()
|
||
unlet! g:paras g:paras_rez
|
||
unlet! g:pindent g:pindent_rez
|
||
"unlet! g:ptype g:ptype_rez
|
||
unlet! g:plinen g:plinen_rez
|
||
unlet! g:vst_recursion
|
||
unlet! g:vst_doc_title
|
||
endfunction
|
||
" }}}
|
||
" }}}
|
||
|
||
" Initialize error message
|
||
let g:vst_error = ''
|
||
|
||
" Source project file
|
||
if filereadable("vstrc.vim")
|
||
source vstrc.vim
|
||
endif
|
||
|
||
" We don't need freaking tabs!
|
||
setlocal expandtab
|
||
retab
|
||
|
||
" For proper working of script nocompatible has to be set but setting it
|
||
" explicitly may break other settings which usually don't disturb
|
||
if &compatible == 1
|
||
set nocompatible
|
||
endif
|
||
|
||
let format = tolower(a:format)
|
||
|
||
if format == ''
|
||
let format = 'html'
|
||
endif
|
||
|
||
let text = getline(a:line1, a:line2)
|
||
|
||
" Include external files before anything else will be done {{{
|
||
" But only for "real" export
|
||
if ',pdf,xml,html,s5,latex,tex,preproc,' =~ ','.format.','
|
||
let rec_counter = 0
|
||
while rec_counter < &maxfuncdepth/2
|
||
" if len(filter(copy(text), 'v:val =~ "^\\s*\\.\\. \\(header\\|include\\|footer\\)::"')) > 0
|
||
" Tried to do in one regexp, but its alternative was sometimes working, sometimes not
|
||
" Note: it always works... even inside of preformatted text
|
||
let isinclude = len(filter(copy(text), 'v:val =~ "^\\s*\\.\\. include::"'))
|
||
let isheader = len(filter(copy(text), 'v:val =~ "^\\s*\\.\\. header::"'))
|
||
let isfooter = len(filter(copy(text), 'v:val =~ "^\\s*\\.\\. footer::"'))
|
||
" End loop when there are no including commands, save up to 100
|
||
" filtering
|
||
if isinclude == 0 && isheader == 0 && isfooter == 0
|
||
break
|
||
endif
|
||
if isinclude > 0 || isheader > 0 || isfooter > 0
|
||
let i = 0
|
||
while i < len(text)
|
||
if text[i] =~ '^\s*\.\. \(header\|include\|footer\)::'
|
||
let include = matchlist(text[i], '^\(\s*\)\.\. \(header\|include\|footer\)::\s*\(.*\)\s*$')
|
||
" Do nothing if file isn't readable, general VST policy:
|
||
" silently ignore all author errors.
|
||
|
||
if include[3] =~ '^<' && include[3] =~ '>$'
|
||
let include[3] = matchstr(include[3], '^.\zs.*\ze.$')
|
||
let include[3] = g:vst_included.'/'.include[3]
|
||
endif
|
||
" let inc_indent = len(include[1])
|
||
" EXPERIMENTAL: change \ into / - windows separator into
|
||
" unix separator and vice versa depending on running
|
||
" system
|
||
if has("win16") || has("win32") || has("win64") || has("win95") || has("dos16") || has("dos32")
|
||
let include[3] = substitute(include[3], '/', '\\', 'g')
|
||
else
|
||
let include[3] = substitute(include[3], '\\', '/', 'g')
|
||
endif
|
||
if filereadable(include[3])
|
||
let included = readfile(include[3])
|
||
call map(included, 'include[1].v:val')
|
||
if include[2] == 'header'
|
||
let text[i] = ''
|
||
let included += ['']
|
||
call extend(text, included, 0)
|
||
elseif include[2] == 'footer'
|
||
let text[i] = ''
|
||
let included = [''] + included
|
||
call extend(text, included)
|
||
else
|
||
let text[i] = ''
|
||
call extend(text, included, i+1)
|
||
endif
|
||
elseif include[3] == 'vstfooter' || include[3] == ''
|
||
if exists("*strftime")
|
||
let date = strftime("%c")
|
||
else
|
||
let date = "Unknown"
|
||
endif
|
||
let included = ['.. block:: vstfooter', '', ' -----------------------',
|
||
\ '', ' Vim reStructured Text document. Generated: '.date
|
||
\.'. `View VST source`_', '',
|
||
\ ' .. _view VST source: '.expand("%"),'']
|
||
call extend(text, included)
|
||
let text[i] = ''
|
||
elseif include[2] =~ 'header\|footer' && text[i-2] !~ '::\s*$'
|
||
" Second part of above condition is hack to allow for
|
||
" proper compilation of f/h examples. Simple test should
|
||
" cover most of them.
|
||
if include[2] == 'footer'
|
||
let text[i] = ''
|
||
if format !~ 's5'
|
||
let included = ['.. block:: vstfooter','', ' ------------------------',
|
||
\ '', ' '.VST_ProtectLiteral(include[3]), '']
|
||
call extend(text, included)
|
||
else
|
||
let s5footer = VST_ProtectLiteral(include[3])
|
||
endif
|
||
elseif include[2] == 'header'
|
||
let text[i] = ''
|
||
let included = ['.. block:: vstfooter','', ' '.VST_ProtectLiteral(include[3]),
|
||
\ '', ' ------------------------', '']
|
||
call extend(text, included, 0)
|
||
endif
|
||
else
|
||
if include[3] !~ '^{.*}$'
|
||
let text[i] = ''
|
||
let included = [include[1].'.. Unknown file: '.VST_ProtectLiteral(include[3]),
|
||
\ '', include[1].'..']
|
||
call extend(text, included, i+1)
|
||
endif
|
||
endif
|
||
if exists('included')
|
||
let i += len(included)
|
||
endif
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
endif
|
||
let rec_counter += 1
|
||
endwhile
|
||
unlet! rec_counter
|
||
endif
|
||
" }}}
|
||
" Preprocess text to ... {{{
|
||
" But not for preproc export:
|
||
if format !~ '^pre'
|
||
" Separate preprocessing for modeline correction
|
||
" Not elegant but prevents from messing with last element in main loop
|
||
" This take care about modeline in last line
|
||
" Remove filetype setting from modeline to not confuse Vim in exported
|
||
" files
|
||
for i in range(&modelines+1) + range(len(text)-&modelines, len(text)-1)
|
||
if get(text, i) != ''
|
||
if text[i] =~ '^\s*\.\. vim:.*re\?st'
|
||
let text[i] = substitute(text[i], '\s\?\%(filetype\|ft\)=re\?st', '', 'g')
|
||
if text[i] =~ 'vim:\s*\(set\)\?\s*:\?\s*$'
|
||
let text[i] = ''
|
||
endif
|
||
endif
|
||
endif
|
||
endfor
|
||
" We need to keep track of real lines. Create hash with keys of virtual
|
||
" lines created by preprocessing and real lines
|
||
let i = 0
|
||
let g:vst_reallines = {}
|
||
let rl_correction = 0
|
||
while i < len(text)-1
|
||
" Remove control characters, some Emacs deviation
|
||
if text[i] =~ '[[:cntrl:]]'
|
||
let text[i] = substitute(text[i], '[[:cntrl:]]', '', 'g')
|
||
endif
|
||
" If comment directive is empty and following line is blank change
|
||
" it to .. comment:: directive. In this way indentation still will be
|
||
" taken into account
|
||
if text[i] =~ '^\s*\.\.\s*$' && text[i+1] =~ '^\s*$'
|
||
let text[i] = substitute(text[i], '^\(\s*\.\.\)', '\1 comment::', '')
|
||
endif
|
||
" Insert blank line between one line directives
|
||
if text[i] =~ '^\s*\(\.\.\|__\) ' && text[i+1] =~ '^\s*\(\.\.\|__\) '
|
||
let findent = strlen(matchstr(text[i], '^\s*'))
|
||
let sindent = strlen(matchstr(text[i+1], '^\s*'))
|
||
" But only if those .. are on the same level of indentation
|
||
if findent == sindent
|
||
call insert(text, '', i+1)
|
||
let rl_correction -= 1
|
||
endif
|
||
endif
|
||
" Insert blank line between option of directive and directive in next
|
||
" line
|
||
if text[i] =~ '^\s\+:\w\+:' && text[i+1] =~ '^\s*\.\. '
|
||
let findent = strlen(matchstr(text[i], '^\s*'))
|
||
let sindent = strlen(matchstr(text[i+1], '^\s*'))
|
||
" But only if option has bigger indentation than directive
|
||
if (sindent + 3) <= findent
|
||
call insert(text, '', i+1)
|
||
let rl_correction -= 1
|
||
endif
|
||
endif
|
||
" Insert blank line between named admonition and unordered|ordered
|
||
" list in next line Have to be splitted in two if's because || is
|
||
" horrible ineffective.
|
||
" LISTDEF: here is list definition which may require adjustment
|
||
if text[i] =~? '^\s*\.\. \(note\|tip\|warning\|attention\|caution\|danger\|error\|hint\|important\|admonition\)::\s*$' && text[i+1] =~ '^\s*'.s:vst_bulletdef.'\s'
|
||
let findent = strlen(matchstr(text[i], '^\s*'))
|
||
let sindent = strlen(matchstr(text[i+1], '^\s*'))
|
||
" But only if list has bigger indentation than directive
|
||
if (findent + 3) <= sindent
|
||
call insert(text, '', i+1)
|
||
let rl_correction -= 1
|
||
endif
|
||
endif
|
||
if text[i] =~? '^\s*\.\. \(note\|tip\|warning\|attention\|caution\|danger\|error\|hint\|important\|admonition\)::\s*$' && text[i+1] =~ '^\s*\(\d\+\|[a-zA-Z]\|[icdvlmxICDVLMX]\+\|#\)[\]:.)}]\s'
|
||
let findent = strlen(matchstr(text[i], '^\s*'))
|
||
let sindent = strlen(matchstr(text[i+1], '^\s*'))
|
||
" But only if list has bigger indentation than directive
|
||
if (findent + 3) <= sindent
|
||
call insert(text, '', i+1)
|
||
let rl_correction -= 1
|
||
endif
|
||
endif
|
||
let i += 1
|
||
let g:vst_reallines[i] = i + rl_correction
|
||
endwhile
|
||
" In main loop we are not interested in last item, here add correction for
|
||
" this
|
||
let g:vst_reallines[i+1] = i + 1 + rl_correction
|
||
endif
|
||
" }}}
|
||
" Initiate variables for non export specific databases: {{{
|
||
let g:vst_headers = {}
|
||
let g:vst_hlinkdb = {}
|
||
let g:vst_replacedb = {}
|
||
let g:vst_roledb = {}
|
||
|
||
" }}}
|
||
|
||
let g:vst_anonhlinkdb = filter(copy(text), 'v:val =~ "^\\s*\\(\\.\\. __:\\|__ \\)"')
|
||
if ',pdf,xml,html,s5,latex,tex,' =~ ','.format.','
|
||
let g:vst_footnotedb = {}
|
||
let g:vst_citationdb = {}
|
||
let g:vst_fielddb = {}
|
||
let g:vst_metadb = {}
|
||
|
||
unlet! g:vst_encoding
|
||
|
||
" Necessary for working of labels
|
||
if '-' !~ '\k'
|
||
let b:vst_hyphenisk = 1
|
||
set isk+=-
|
||
else
|
||
let b:vst_hyphenisk = 0
|
||
endif
|
||
|
||
" Main function
|
||
let file = VST_Structure(text)
|
||
|
||
unlet! b:vst_afs
|
||
unlet! b:vst_first_parsing
|
||
|
||
if file =~ '\[#\]_'
|
||
let file = VST_AutoFootnote(file)
|
||
endif
|
||
|
||
" Process hyperlinks {{{
|
||
let lines = split(file, '<vim:p')
|
||
let i = 0
|
||
while i < len(lines)
|
||
if lines[i] =~ '_'
|
||
" Take care about \`
|
||
let lines[i] = substitute(lines[i], '\\\@<!\\`__', '-vst-escape-backtick-ddash-', 'g')
|
||
let lines[i] = substitute(lines[i], '\\\@<!\\`_', '-vst-escape-backtick-dash-', 'g')
|
||
let lines[i] = substitute(lines[i], '\\\@<!\\`', '-vst-escape-backtick-', 'g')
|
||
" Take care about quoted backtick quoted backtics
|
||
let lines[i] = substitute(lines[i], "\\([['\"({<]\\)`\\([])}>\"' ]\\)", '\1\`\2', 'g')
|
||
let lines[i] = substitute(lines[i], "\\([['\"({<]\\)_`\\([])}>\"' ]\\)", '\1_\`\2', 'g')
|
||
" Take care about "``"
|
||
let lines[i] = substitute(lines[i], '"``"', '-vst-quot-dbacktick-', 'g')
|
||
" Take care about alone _ and __
|
||
let lines[i] = substitute(lines[i], ' _ ', ' \_ ', 'g')
|
||
let lines[i] = substitute(lines[i], ' __ ', ' \_\_ ', 'g')
|
||
" Take care about __ in programmer expressions __init__ like (shaky)
|
||
let lines[i] = substitute(lines[i], '\([[:punct:][:space:]<5D>]\)__\(\k*\)__\([[:punct:][:space:]<5D>]\?\)', '\1\_\_\2\_\_\3', 'g')
|
||
" Ugly, ugly, prevent from linkination of ".. __:" in text
|
||
let lines[i] = substitute(lines[i], ' __\(\S\)', ' \_\_\1', 'g')
|
||
" Take care about anonymous references
|
||
let lines[i] = substitute(lines[i], "\\([['\"({<]\\)__\\([])}>\"' ]\\)", '\1\_\_\2', 'g')
|
||
" Take care about "``"
|
||
|
||
" Main hyperlink processing
|
||
let lines[i] = VST_Hyperlink(lines[i])
|
||
let lines[i] = VST_Target(lines[i])
|
||
|
||
" Restore \`
|
||
let lines[i] = substitute(lines[i], '-vst-escape-backtick-ddash-', '\\`__', 'g')
|
||
let lines[i] = substitute(lines[i], '-vst-escape-backtick-dash-', '\\`_', 'g')
|
||
let lines[i] = substitute(lines[i], '-vst-escape-backtick-', '\\`', 'g')
|
||
" Take care about "``"
|
||
let lines[i] = substitute(lines[i], '-vst-quot-dbacktick-', '"``"', 'g')
|
||
" Restore ` and _
|
||
let lines[i] = substitute(lines[i], '`', '`', 'g')
|
||
let lines[i] = substitute(lines[i], '_', '_', 'g')
|
||
|
||
endif
|
||
"if lines[i] =~ '\\'
|
||
" let lines[i] = VST_EscapingSlash(lines[i])
|
||
"endif
|
||
let i += 1
|
||
endwhile
|
||
let file = join(lines, '<vim:p')
|
||
" Sometimes regexps are catching single _ as link. Remove such glitches
|
||
let file = substitute(file, '<vim:a href="#l_" title="_">_</vim:a>', '_', 'g')
|
||
" Sometimes regexps are catching \` as link. Remove such glitches
|
||
let file = substitute(file, '<vim:a href="#l\\`" title="\\`">\\`</vim:a>', '\\`', 'g')
|
||
" }}}
|
||
" Create footnote and citation dbs: {{{
|
||
" Go with stridx and strpart cutting file and retrieve information.
|
||
" Necessary for LaTeX export.
|
||
let fn = file
|
||
while stridx(fn, '<vim:footnote') != -1
|
||
let index = stridx(fn, '<vim:footnote')
|
||
let fn = strpart(fn, index)
|
||
let number = matchstr(fn, '<vim:div class="fnumber"><vim:a href="#target-\d\+" name="footnote-\d\+">\[\zs\d\+\ze\]</vim:a></vim:div>')
|
||
let content = matchstr(fn, '<vim:div class="ftext">\zs.\{-}\ze\_s*</vim:div>')
|
||
let g:vst_footnotedb[number] = content
|
||
let fn = strpart(fn, 2)
|
||
endwhile
|
||
let fn = file
|
||
while stridx(fn, '<vim:citation') != -1
|
||
let index = stridx(fn, '<vim:citation')
|
||
let fn = strpart(fn, index)
|
||
let label = matchstr(fn, '<vim:div class="cnumber"><vim:a href="#ctarget-\k\+" name="citation-\k\+">\[\zs\k\+\ze\]</vim:a></vim:div>')
|
||
let content = matchstr(fn, '<vim:div class="ctext">\zs.\{-}\ze\_s*</vim:div>')
|
||
let g:vst_citationdb[label] = '['.label.'] '.content
|
||
let fn = strpart(fn, 2)
|
||
endwhile
|
||
" }}}
|
||
|
||
if len(g:vst_anonhlinkdb) > 0
|
||
let file = VST_AnonHyperlink(file)
|
||
endif
|
||
|
||
" Process default roles
|
||
let file = VST_DefaultRole(file)
|
||
" Remove escaping slashes.
|
||
let file = VST_EscapingSlash(file)
|
||
|
||
" Removing - from 'isk'
|
||
if b:vst_hyphenisk == 1
|
||
set isk-=-
|
||
endif
|
||
unlet! b:vst_hyphenisk
|
||
|
||
" Replace ` with `
|
||
let file = substitute(file, '`', '`', 'g')
|
||
" Replace [ with [
|
||
let file = substitute(file, '[', '[', 'g')
|
||
" Replace \ with \
|
||
let file = substitute(file, '\', '\\', 'g')
|
||
" Replace _ with _
|
||
let file = substitute(file, '_', '_', 'g')
|
||
" Replace . with .
|
||
let file = substitute(file, '.', '.', 'g')
|
||
" Replace | with |
|
||
let file = substitute(file, '|', '|', 'g')
|
||
" Replace : with :
|
||
let file = substitute(file, ':', ':', 'g')
|
||
|
||
" VST_URIMaker: Create real, properly encrypted URIs. {{{
|
||
function! VST_URIMaker(uri)
|
||
" Auxiliary functions lifted from eval.txt {{{
|
||
" The function Nr2Hex() returns the Hex string of a number.
|
||
func! Nr2Hex(nr)
|
||
let n = a:nr
|
||
let r = ""
|
||
while n
|
||
let r = '0123456789ABCDEF'[n % 16] . r
|
||
let n = n / 16
|
||
endwhile
|
||
return r
|
||
endfunc
|
||
" The function String2Hex() converts each character in a string to a two
|
||
" character Hex string.
|
||
func! String2Hex(str)
|
||
let out = ''
|
||
let ix = 0
|
||
while ix < strlen(a:str)
|
||
let out = out . Nr2Hex(char2nr(a:str[ix]))
|
||
let ix = ix + 1
|
||
endwhile
|
||
return out
|
||
endfunc " }}}
|
||
let uri = a:uri
|
||
if uri =~ '^#'
|
||
return uri
|
||
endif
|
||
" URI:
|
||
if uri =~ '^[-_!~*():?;@&=+$.,/a-zA-Z0-9#]*$'
|
||
return uri
|
||
else
|
||
let elements = split(uri, '#')
|
||
let first = elements[0]
|
||
if len(elements) > 1
|
||
let rest = '#'.join(elements[1:-1], '#')
|
||
else
|
||
let rest = ''
|
||
endif
|
||
let link = split(first, '.\zs')
|
||
let out = ''
|
||
let ix = 0
|
||
while ix < len(link)
|
||
if link[ix] =~ '[-_!~*():?;@&=+$.,/a-zA-Z0-9#]'
|
||
let out .= link[ix]
|
||
elseif link[ix] =~ '%'
|
||
" Bold assumption: all escape sequences I saw on the net
|
||
" were uppercased
|
||
if link[ix+1] =~ '[A-F0-9]' && link[ix+2] =~ '[A-F0-9]'
|
||
let out .= link[ix] . link[ix+1] . link[ix+2]
|
||
let ix = ix + 2
|
||
else
|
||
let out .= '%'.String2Hex('%')
|
||
endif
|
||
else
|
||
let out .= '%'.String2Hex(link[ix])
|
||
endif
|
||
let ix += 1
|
||
endwhile
|
||
endif
|
||
return out.rest
|
||
endfunction
|
||
" }}}
|
||
let file = substitute(file, 'vim:\(img src="\|a href="\)\(.\{-}\)"', '\="vim:".submatch(1).VST_URIMaker(submatch(2))."\""', 'g')
|
||
|
||
" Figure out proper MIME charset from the 'encoding' option. {{{
|
||
if exists("g:vst_encoding")
|
||
let encoding = g:vst_encoding
|
||
else
|
||
if &fileencoding != ''
|
||
let encoding = &fileencoding
|
||
else
|
||
let encoding = &encoding
|
||
endif
|
||
endif
|
||
if encoding =~ '^8bit\|^2byte'
|
||
let encoding = substitute(s:vim_encoding, '^8bit-\|^2byte-', '', '')
|
||
endif
|
||
if encoding == 'latin1'
|
||
let encoding = 'iso-8859-1'
|
||
elseif encoding =~ "^cp12"
|
||
let encoding = substitute(encoding, 'cp', 'windows-', '')
|
||
elseif encoding == 'sjis'
|
||
let encoding = 'Shift_JIS'
|
||
elseif encoding == 'euc-cn'
|
||
let encoding = 'GB_2312-80'
|
||
elseif encoding == 'euc-tw'
|
||
let encoding = ""
|
||
elseif encoding == 'big5'
|
||
let encoding = "Big5"
|
||
elseif encoding =~ '^euc\|^iso\|^koi'
|
||
let encoding = substitute(encoding, '.*', '\U\0', '')
|
||
elseif encoding == 'cp949'
|
||
let encoding = 'KS_C_5601-1987'
|
||
elseif encoding == 'cp936'
|
||
let encoding = 'GBK'
|
||
elseif encoding =~ '^ucs\|^utf'
|
||
let encoding = 'UTF-8'
|
||
else
|
||
let encoding = ""
|
||
endif
|
||
" }}}
|
||
let filename = expand("%:r")
|
||
endif
|
||
|
||
if format =~ '^\(html\|s5\)$'
|
||
" HTML export {{{
|
||
|
||
let language = matchstr(v:lang, '.*\ze_')
|
||
|
||
" CSS: {{{
|
||
let rtp = split(&rtp, ',')
|
||
for i in range(len(rtp))
|
||
if filereadable(rtp[i].'/autoload/vst/default.css')
|
||
let defcssfile = rtp[i].'/autoload/vst/default.css'
|
||
break
|
||
endif
|
||
endfor
|
||
|
||
let default_css = join(readfile(defcssfile), "\n")
|
||
|
||
" g:vst_css_default g:vst_css_user
|
||
if g:vst_css_default == '' && g:vst_css_user == ''
|
||
let css = '<style type="text/css">'."\n".'/*<![CDATA[*/'."\n"
|
||
\ .default_css."\n".'/*]]>*/'."\n".'</style>'
|
||
endif
|
||
|
||
if g:vst_css_default == '' && g:vst_css_user != ''
|
||
let css = '<style type="text/css">'."\n".'/*<![CDATA[*/'."\n"
|
||
\ .default_css."\n".'/*]]>*/'."\n".'</style>'
|
||
let css .= '<link rel="stylesheet" href="'.g:vst_css_user.'" type="text/css" />'."\n"
|
||
endif
|
||
|
||
if g:vst_css_default != '' && g:vst_user_css == ''
|
||
if g:vst_css_default !~ 'NONE'
|
||
let completecss = ['/* Vim reStructured Text CSS */', ''] + split(default_css, '\n')
|
||
call writefile(completecss, g:vst_css_default)
|
||
let css = '<link rel="stylesheet" href="'.g:vst_css_default.'" type="text/css" />'."\n"
|
||
else
|
||
let css = "\n"
|
||
endif
|
||
endif
|
||
|
||
if g:vst_css_default != '' && g:vst_css_user != ''
|
||
if g:vst_css_default !~ 'NONE'
|
||
let completecss = ['/* Vim reStructured Text CSS */', ''] + split(default_css, '\n')
|
||
call writefile(completecss, g:vst_css_default)
|
||
let css = '<link rel="stylesheet" href="'.g:vst_css_default.'" type="text/css" />'."\n"
|
||
else
|
||
let css = "\n"
|
||
endif
|
||
let css .= '<link rel="stylesheet" href="'.g:vst_css_user.'" type="text/css" />'."\n"
|
||
endif
|
||
" }}}
|
||
|
||
" META Info {{{
|
||
let metainfo = ''
|
||
let metaauthor = ''
|
||
let metatitle = ''
|
||
let metasubject = ''
|
||
let metakeywords = ''
|
||
let metadate = ''
|
||
if has_key(g:vst_fielddb, 'author')
|
||
let metaauthor = '<meta name="Author" content="'.g:vst_fielddb['author']."\" />\n"
|
||
endif
|
||
if has_key(g:vst_fielddb, 'title')
|
||
let metatitle = '<meta name="Title" content="'.g:vst_fielddb['title']."\" />\n"
|
||
endif
|
||
if has_key(g:vst_fielddb, 'keywords')
|
||
let metakeywords = '<meta name="Keywords" content="'.g:vst_fielddb['keywords']."\" />\n"
|
||
endif
|
||
if has_key(g:vst_fielddb, 'subject')
|
||
let metasubject = '<meta name="Subject" content="'.g:vst_fielddb['subject']."\" />\n"
|
||
endif
|
||
if has_key(g:vst_fielddb, 'date')
|
||
if g:vst_fielddb['date'] != 'NONE'
|
||
let metadate = '<meta name="Date" content="'.g:vst_fielddb['date']."\" />\n"
|
||
endif
|
||
endif
|
||
let metainfo = metaauthor.metatitle.metakeywords.metasubject.metadate
|
||
|
||
let metadata = ''
|
||
for key in keys(g:vst_metadb)
|
||
if key =~ '^http-equiv='
|
||
let item = substitute(key, 'http-equiv=\(.*\)', 'http-equiv="\1"', '')
|
||
let element = '<meta '.item.' content="'.g:vst_metadb[key].'" />'."\n"
|
||
elseif key =~ '^description \(lang\|scheme\|dir\)'
|
||
let item = substitute(key, 'description \(lang\|scheme\|dir\)=\(.*\)', 'name="description" \1="\2", '')
|
||
let element = '<meta '.item.' content="'.g:vst_metadb[key].'" />'."\n"
|
||
else
|
||
let element = '<meta name="'.key.'" content="'.g:vst_metadb[key].'" />'."\n"
|
||
endif
|
||
let metadata .= element
|
||
endfor
|
||
|
||
if exists("g:vst_doc_title")
|
||
let htmltitle = substitute(g:vst_doc_title, '^\s*', '', '')
|
||
let htmltitle = VST_SpecCharacter(htmltitle)
|
||
elseif metasubject != ''
|
||
let htmltitle = g:vst_fielddb['subject']
|
||
else
|
||
let htmltitle = expand("%")
|
||
endif
|
||
" }}}
|
||
|
||
" S5 special content {{{
|
||
if format == 's5'
|
||
if exists('s5footer')
|
||
let s5foot = VST_Structure(split(s5footer, '0000000000000000000'))
|
||
let s5foot = substitute(s5foot, '^\_s*<vim:p>\_s*', '', '')
|
||
let s5foot = substitute(s5foot, '\_s*</vim:p>\_s*$', '', '')
|
||
unlet! s5footer
|
||
else
|
||
if has_key(g:vst_fielddb, 'author')
|
||
let s5author = g:vst_fielddb['author']
|
||
else
|
||
let s5author = 'Author'
|
||
endif
|
||
if has_key(g:vst_fielddb, 'date') && g:vst_fielddb['date'] != 'NONE'
|
||
let s5date = g:vst_fielddb['date']
|
||
else
|
||
let s5date = 'Date'
|
||
endif
|
||
let s5foot = s5author.' • '.s5date
|
||
endif
|
||
let s5head = ''
|
||
\.'<!-- configuration parameters -->'."\n"
|
||
\.'<meta name="defaultView" content="slideshow" />'."\n"
|
||
\.'<meta name="controlVis" content="hidden" />'."\n"
|
||
\.'<meta name="version" content="S5 1.1" />'."\n"
|
||
\.'<!-- style sheet links -->'."\n"
|
||
\.'<link rel="stylesheet" href="s5ui/slides.css" type="text/css" media="projection" id="slideProj" />'."\n"
|
||
\.'<link rel="stylesheet" href="s5ui/outline.css" type="text/css" media="screen" id="outlineStyle" />'."\n"
|
||
\.'<link rel="stylesheet" href="s5ui/print.css" type="text/css" media="print" id="slidePrint" />'."\n"
|
||
\.'<link rel="stylesheet" href="s5ui/opera.css" type="text/css" media="projection" id="operaFix" />'."\n"
|
||
\.'<!-- S5 JS -->'."\n"
|
||
\.'<script src="s5ui/slides.js" type="text/javascript"></script>'."\n"
|
||
\.'<!-- VST-S5 -->'."\n"
|
||
\.'<style type="text/css">'."\n"
|
||
\.'/*<![CDATA[*/'."\n"
|
||
\.'h1:before, h2:before, h3:before, h4:before, h5:before, h6:before { content: "" }'."\n"
|
||
\.'/*]]>*/'."\n"
|
||
\.'</style>'."\n"
|
||
let s5body = ''
|
||
\.'<div class="layout">'."\n"
|
||
\.'<div id="controls"><!-- DO NOT EDIT --></div>'."\n"
|
||
\.'<div id="currentSlide"><!-- DO NOT EDIT --></div>'."\n"
|
||
\.'<div id="header"></div>'."\n"
|
||
\.'<div id="footer">'."\n"
|
||
\.'<h1>'.htmltitle.'</h1>'."\n"
|
||
\.'<h2>'.s5foot.'</h2>'."\n"
|
||
\.'</div>'."\n"
|
||
\.'</div>'."\n"
|
||
\.'<div class="presentation">'
|
||
let s5body2 = "</div>\n</div>"
|
||
else
|
||
let s5body = ''
|
||
let s5head = ''
|
||
let s5body2 = ''
|
||
endif
|
||
" }}}
|
||
|
||
let metainfo .= metadata
|
||
|
||
if file =~ '<vim:ol[^>]*start="'
|
||
let g:zzz = 1
|
||
let doctype =
|
||
\ '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"'."\n"
|
||
\.' "http://www.w3.org/TR/html4/loose.dtd">'."\n"
|
||
"\ '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" '."\n"
|
||
"\.' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> '."\n"
|
||
else
|
||
let doctype =
|
||
\ '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"'."\n"
|
||
\.' "http://www.w3.org/TR/html4/strict.dtd">'."\n"
|
||
"\ '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" '."\n"
|
||
"\.' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'."\n"
|
||
endif
|
||
|
||
let header =
|
||
\ doctype
|
||
\.'<html xmlns="http://www.w3.org/1999/xhtml" lang="'.language.'" '
|
||
\.'xml:lang="'.language.'">'."\n"
|
||
\.'<head>'."\n"
|
||
\.'<meta http-equiv="Content-Type" content="text/html; charset='.encoding.'" />'."\n"
|
||
\.'<title>'.htmltitle.'</title>'."\n"
|
||
\.'<meta name="Generator" content="Vim reStructured Text '.s:vst_ver.' - Vim '.v:version/100.".".v:version % 100.'" />'."\n"
|
||
\.metainfo."\n"
|
||
\.css."\n"
|
||
\.s5head."\n"
|
||
\.'</head>'."\n"
|
||
\.'<body>'."\n"
|
||
|
||
let closing = '</body>'."\n".'</html>'
|
||
|
||
let file = header."\n".s5body."\n".file."\n".s5body2."\n".closing
|
||
let file = substitute(file, '</vim:', '</', 'g')
|
||
let file = substitute(file, '<vim:', '<', 'g')
|
||
" let file = substitute(file, '\(\[\d\+\]</a>\)_', '\1', 'g')
|
||
" let file = substitute(file, '\(\[#\]</a>\)_', '\1', 'g')
|
||
|
||
" Create comment tags
|
||
let file = substitute(file, '</comment>', ' -->', 'g')
|
||
let file = substitute(file, '<comment.\{-}>', '<!-- ', 'g')
|
||
|
||
" Replace rawlatex with pre tags
|
||
"let file = substitute(file, '</rawlatex', '</pre', 'g')
|
||
"let file = substitute(file, '<rawlatex>', '<pre class="rawlatex"', 'g')
|
||
"let file = substitute(file, '<rawlatex class="\(.\{-}\)">', '<pre class="rawlatex \1">', 'g')
|
||
" Remove rawlatex content
|
||
let file = substitute(file, '<rawlatex.\{-}</rawlatex>', '', 'g')
|
||
|
||
" Remove latexonly tags and contents
|
||
let file = substitute(file, '<latexonly\.{-}>.\{-}</latexonly>', '', 'g')
|
||
|
||
" Replace footnote and citation with div class="footnote"
|
||
let file = substitute(file, '</footnote', '</div', 'g')
|
||
let file = substitute(file, '<footnote>', '<div class="footnote">', 'g')
|
||
let file = substitute(file, '<footnote class="\(.\{-}\)">', '<div class="footnote \1">', 'g')
|
||
let file = substitute(file, '</citation', '</div', 'g')
|
||
let file = substitute(file, '<citation>', '<div class="footnote">', 'g')
|
||
let file = substitute(file, '<citation class="\(.\{-}\)">', '<div class="footnote \1">', 'g')
|
||
|
||
" Replace topic with div
|
||
let file = substitute(file, '</topic', '</div', 'g')
|
||
let file = substitute(file, '<topic', '<div ', 'g')
|
||
|
||
" Replace sidebar with div
|
||
let file = substitute(file, '</sidebar', '</div', 'g')
|
||
let file = substitute(file, '<sidebar', '<div ', 'g')
|
||
|
||
" Replace figure with div
|
||
let file = substitute(file, '</figure', '</div', 'g')
|
||
let file = substitute(file, '<figure', '<div', 'g')
|
||
|
||
" Replace block with div
|
||
let file = substitute(file, '</block\>', '</div', 'g')
|
||
let file = substitute(file, '<block\>', '<div', 'g')
|
||
|
||
" Replace container with div
|
||
let file = substitute(file, '</container\>', '</div', 'g')
|
||
let file = substitute(file, '<container\>', '<div', 'g')
|
||
|
||
" Replace unknown with div and header
|
||
let file = substitute(file, '</unknown\>', '</div', 'g')
|
||
let file = substitute(file, '<unknown>', '<div class="unknown"><strong>Unknown element:</strong><br />', 'g')
|
||
|
||
" Replace pullquote with blockquote class
|
||
let file = substitute(file, '</pullquote', '</blockquote', 'g')
|
||
let file = substitute(file, '<pullquote>', '<blockquote class="pull">', 'g')
|
||
let file = substitute(file, '<pullquote class="\(.\{-}\)">', '<blockquote class="pull \1">', 'g')
|
||
|
||
" Replace rubric with span class
|
||
let file = substitute(file, '</rubric', '</p', 'g')
|
||
let file = substitute(file, '<rubric>', '<p class="rubric">', 'g')
|
||
let file = substitute(file, '<rubric class="\(.\{-}\)">', '<p class="rubric \1">', 'g')
|
||
|
||
" Turn field list (dl) into table.
|
||
" This can be expensive set of regexps so check if this element exists
|
||
" at all
|
||
if file =~ 'dt class="field'
|
||
let file = substitute(file, '<dl class="field\(.\{-}\)">', '<table class="field\1" summary="Field list">', 'g')
|
||
let file = substitute(file, '\(<dd class="field.\{-}\n\)</dl>', '\1</table>', 'g')
|
||
let file = substitute(file, '<dt class="field fabstract">Abstract<.dt><dd class="field fabstract">\(.\{-}\)<.dd>', '<tr><td class="fkey fakey" colspan="2">Abstract</td></tr><tr><td class="fval faval" colspan="2">\1</td></tr>', 'g')
|
||
let file = substitute(file, '<dt class="field fdedication">Dedication<.dt><dd class="field fdedication">\(.\{-}\)<.dd>', '<tr><td class="fkey fdkey" colspan="2">Dedication</td></tr><tr><td class="fval fdval" colspan="2">\1</td></tr>', 'g')
|
||
let file = substitute(file, '<dt class="field.\{-}>\(.\{-}\)<.dt><dd class="field.\{-}>\(.\{-}\)<.dd>', '<tr><td class="fkey">\1</td><td class="fval">\2</td></tr>', 'g')
|
||
endif
|
||
|
||
" Replace weird table summary value with proper <col /> tags
|
||
let file = substitute(file, '<table\( class="vst.\{-}summary="\).\{-}coln\(.\{-}\)">', '\="<table".submatch(1)."\">".VST_ColNumbers(submatch(2))', 'g')
|
||
" Remove class attribute from closing of dl list
|
||
let file = substitute(file, '\(</dl\) class=".\{-}"', '\1', 'g')
|
||
|
||
" Remove summary from td tags
|
||
let file = substitute(file, '\(<td[^>]*\) summary=".\{-}"', '\1', 'g')
|
||
|
||
" Remove rawhtml tags
|
||
let file = substitute(file, '</rawhtml>', '', 'g')
|
||
let file = substitute(file, '<rawhtml.\{-}>', '', 'g')
|
||
|
||
" Remove rawboth tags
|
||
let file = substitute(file, '</rawboth>', '', 'g')
|
||
let file = substitute(file, '<rawboth.\{-}>', '', 'g')
|
||
|
||
" Remove htmlonly tags
|
||
let file = substitute(file, '</htmlonly>', '', 'g')
|
||
let file = substitute(file, '<htmlonly.\{-}>', '', 'g')
|
||
|
||
" Remove consecutive empty lines
|
||
let file = substitute(file, '\n\n\{3,}', '\n\n', 'g')
|
||
|
||
" Replace --(-) with emdash entity in attributions
|
||
let file = substitute(file, '\(<p class="attribution.\{-}>\_s\{-}\)---\?', '\1\—', 'g')
|
||
|
||
" Add backlinks from section headers
|
||
if exists("b:IsTOC") && b:IsTOC == 1
|
||
let file = substitute(file, '\(<h\d id="\)\(.\{-}\)"\(.\{-}>\)', '\1\2"\3<a href="#toc-\2">', 'g')
|
||
let file = substitute(file, '<\/h\d>', '<\/a>\0', 'g')
|
||
unlet! b:IsTOC
|
||
endif
|
||
|
||
new
|
||
if &compatible == 1
|
||
set nocompatible
|
||
endif
|
||
silent! 0put =file
|
||
" Beautify HTML a bit:
|
||
" Reduce indentation inside of <pre> tags to minimum of 1 space {{{
|
||
silent call cursor(1,1)
|
||
while search('^\s*<pre', 'W')
|
||
let rawlatex = (getline('.') =~ 'class="rawlatex' ? 1 : 0)
|
||
silent normal! j
|
||
let line1 = line('.')
|
||
let indlist = []
|
||
while getline('.') !~ '</pre'
|
||
if getline('.') =~ '^\s*$'
|
||
silent normal! j
|
||
continue
|
||
endif
|
||
let preind = strlen(matchstr(getline('.'), '^\s*'))
|
||
let indlist += [preind]
|
||
silent normal! j
|
||
endwhile
|
||
let line2 = line('.')-1
|
||
" When pre is empty (closing tag is in next line after opening
|
||
" tag) don't continue
|
||
if line1 == line2 + 1
|
||
continue
|
||
endif
|
||
let lineend = line('.')
|
||
let ind = min(indlist) <= 0 ? 0 : min(indlist)
|
||
silent exe line1.','.line2.'s/^ \{'.ind.'}/ /e'
|
||
" Previously doubled \ was treated as escaped and reduced to one.
|
||
" Now it is highly probable that one \ at the end of line was
|
||
" supposed to be new line symbol.
|
||
if rawlatex == 1
|
||
silent exe line1.','.line2.'s/\\$/\\\\/e'
|
||
endif
|
||
endwhile
|
||
" }}}
|
||
" Put 2html CSS styles into head {{{
|
||
silent call cursor(1,1)
|
||
if search('<pre class="tohtml-[^"]\+">')
|
||
call VST_2html()
|
||
if exists('g:vst_2html_css')
|
||
silent call cursor(1,1)
|
||
let tohtml_css = '<style type="text/css">'."\n".'/*<![CDATA[*/'."\n"
|
||
\ .join(g:vst_2html_css, "\n")."\n".'/*]]>*/'."\n".'</style>'
|
||
call search('<\/head>')
|
||
put! =tohtml_css
|
||
unlet! g:vst_2html_css
|
||
endif
|
||
endif
|
||
redraw!
|
||
" }}}
|
||
" Insert raw files {{{
|
||
silent call cursor(1,1)
|
||
while search('-vst-raw-file-placeholder:', 'W')
|
||
let rawfile = matchstr(getline('.'), '-vst-raw-file-placeholder:\zs.*')
|
||
let g:rf = rawfile
|
||
silent s/.*//ge
|
||
if filereadable(rawfile)
|
||
exe 'silent read '.escape(rawfile, ' \#%')
|
||
endif
|
||
endwhile
|
||
" }}}
|
||
setlocal ft=html
|
||
|
||
" S5 postprocessing {{{
|
||
if format == 's5'
|
||
silent call cursor(1,1)
|
||
silent call search('<div class="presentation">')
|
||
let line = line('.')
|
||
silent exe line.',$ s/<h1/<div class="slide">\r<h1/ge'
|
||
silent exe line.',$ s/<h2/<div class="slide">\r<h1/ge'
|
||
silent exe line.',$ s/<div class="slide">/<\/div>\r\0/ge'
|
||
silent exe line.',$ s/<\/h2>/<\/h1>/ge'
|
||
"silent g/<a href="http/s/<a href=".\{-}"/\0 class="external"/ge
|
||
silent exe line
|
||
silent exe line.',$ s/\(<div class="presentation">\)\_s*<\/div>/\1/ge'
|
||
" Create s5ui directory and file structure
|
||
if !isdirectory('s5ui')
|
||
call mkdir('s5ui')
|
||
endif
|
||
let s5files = [
|
||
\ 'blank.gif',
|
||
\ 'framing.css',
|
||
\ 'iepngfix.htc',
|
||
\ 'opera.css',
|
||
\ 'outline.css',
|
||
\ 'pretty.css',
|
||
\ 'print.css',
|
||
\ 's5-core.css',
|
||
\ 'slides.css',
|
||
\ 'slides.js']
|
||
let workingdir = expand('%:p:h').'/'
|
||
for file in s5files
|
||
if !filereadable('s5ui/'.file)
|
||
let rtp = split(&rtp, ',')
|
||
for i in range(len(rtp))
|
||
if filereadable(rtp[i].'/autoload/vst/s5ui/'.file)
|
||
let s5file = rtp[i].'/autoload/vst/s5ui/'.file
|
||
break
|
||
endif
|
||
endfor
|
||
silent exe 'below 1split '.escape(s5file, ' \#%')
|
||
silent exe 'write! '.escape(workingdir' \#%').'s5ui/'.escape(file, ' \#%')
|
||
silent exe 'bw! '.escape(s5file, ' \#%')
|
||
endif
|
||
endfor
|
||
" Write file after changes
|
||
silent exe 'cd '.escape(workingdir, ' \#%')
|
||
|
||
endif
|
||
" }}}
|
||
if exists("g:vst_write_export") && g:vst_write_export != 0
|
||
silent exe 'write! '.escape(filename, ' \#%').'.html'
|
||
endif
|
||
" User postprocessing
|
||
if g:vst_html_post != '' && filereadable(g:vst_html_post)
|
||
exe 'silent! source '.escape(g:vst_html_post, ' \#%')
|
||
endif
|
||
silent call cursor(1,1)
|
||
call VST_End()
|
||
" }}}
|
||
elseif format == 'xml'
|
||
" XML export {{{
|
||
new
|
||
silent 0put =file
|
||
setlocal ft=xml
|
||
if exists("g:vst_write_export") && g:vst_write_export != 0
|
||
silent exe 'write! '.escape(filename, ' \#%').'.xml'
|
||
endif
|
||
silent call cursor(1,1)
|
||
call VST_End()
|
||
" }}}
|
||
elseif format =~? '^re\?st$'
|
||
" reST export {{{
|
||
let rest_file = getline(1, '$')
|
||
" Potential problems when size of register has limits. :help 'viminfo'
|
||
new
|
||
silent! 0put =rest_file
|
||
unlet! rest_file
|
||
silent! %s/\(^\s*\.\. \)block::/\1admonition::/ge
|
||
silent! g/^\s*:identify:/d
|
||
silent! %s/\(^\s*\)\(:\S.\{-} \)/\1--VIM, \2/ge
|
||
" <c-v>160 - non breaking space
|
||
silent! %s/\\\@<!\\-/<EFBFBD>/ge
|
||
silent! %s/\(^\s*\)\.\. 2html::.*/\1::
|
||
silent call cursor(1,1)
|
||
" }}}
|
||
elseif format =~ '^\(tex\|pdf\)$'
|
||
" LaTeX export {{{
|
||
"
|
||
function! VST_CreateTexComment(text)
|
||
let scomm = split(a:text, '\n')
|
||
let i = 0
|
||
while i < len(scomm)
|
||
let scomm[i] = substitute(scomm[i], '^', '%%', '')
|
||
let i += 1
|
||
endwhile
|
||
let par = join(scomm, '\n')
|
||
return par
|
||
endfunction
|
||
|
||
" Handle encoding and country options. {{{
|
||
let encoding = tolower(encoding)
|
||
if encoding =~ 'iso-8859-1\|iso-8859-15'
|
||
let encoding = 'latin1'
|
||
elseif encoding =~ "windows-"
|
||
let encoding = substitute(encoding, 'windows-', , 'cp', '')
|
||
elseif encoding == 'iso-8859-2'
|
||
let encoding = 'latin2'
|
||
elseif encoding == 'sjis'
|
||
let encoding = 'Shift_JIS'
|
||
elseif encoding == 'euc-cn'
|
||
let encoding = 'GB_2312-80'
|
||
elseif encoding == 'euc-tw'
|
||
let encoding = ""
|
||
elseif encoding =~ '^euc\|^iso\|^koi'
|
||
let encoding = substitute(encoding, '.*', '\U\0', '')
|
||
elseif encoding == 'cp949'
|
||
let encoding = 'KS_C_5601-1987'
|
||
elseif encoding == 'cp936'
|
||
let encoding = 'GBK'
|
||
elseif encoding =~ '^ucs\|^utf'
|
||
let encoding = 'UTF-8'
|
||
else
|
||
let encoding = ""
|
||
endif
|
||
|
||
" Country specific settings
|
||
" Automatically add polski when iso-8859-2 is used.
|
||
if encoding =~ 'latin2\|cp1250'
|
||
let countrysettings = '\usepackage{polski}'
|
||
else
|
||
let countrysettings = ''
|
||
endif
|
||
" }}}
|
||
|
||
" TOC depth
|
||
if exists("s:vst_tocdepth")
|
||
let tocdepth = '\setcounter{tocdepth}{'.s:vst_tocdepth.'}'
|
||
else
|
||
let tocdepth = ''
|
||
endif
|
||
|
||
" User defined preamble
|
||
if exists("g:vst_tex_preamble") && filereadable(g:vst_tex_preamble)
|
||
let userpreamble = "\\input{".g:vst_tex_preamble."}"
|
||
else
|
||
let userpreamble = ''
|
||
endif
|
||
|
||
let footer = '\end{document}'
|
||
|
||
"let file = substitute(file, "><", ">\n<", "g")
|
||
" Special characters I
|
||
" Here to not catch any backslashes
|
||
let file = substitute(file, '\', '$\\backslash$', 'g')
|
||
" Here to not catch footnotes
|
||
let file = substitute(file, '{', '\\{', 'g')
|
||
let file = substitute(file, '}', '\\}', 'g')
|
||
|
||
" Remove special chars catchers
|
||
let file = substitute(file, '@', '@', 'g')
|
||
let file = substitute(file, '[', '[', 'g')
|
||
let file = substitute(file, '\', '\\', 'g')
|
||
let file = substitute(file, ':', ':', 'g')
|
||
let file = substitute(file, '&\\#64;', '@', 'g')
|
||
let file = substitute(file, '&\\#91;', '[', 'g')
|
||
let file = substitute(file, '&\\#92;', '\\', 'g')
|
||
let file = substitute(file, '&\\#58;', ':', 'g')
|
||
|
||
" Footnotes have to be here to process them by other substitutions:
|
||
for fn in keys(g:vst_footnotedb)
|
||
let fnumberleft = '<vim:a href="#footnote-'.fn.'" name="target-'.fn.'">\['
|
||
let fnumberright = '\]</vim:a>'
|
||
let content = escape(g:vst_footnotedb[fn], '&/\~')
|
||
let file = substitute(file, fnumberleft.fn.fnumberright, '\\footnote{'.content.'}', '')
|
||
endfor
|
||
" Citations have to be here to process them by other substitutions:
|
||
for fn in keys(g:vst_citationdb)
|
||
let fnumberleft = '<vim:a href="#citation-'.fn.'" name="ctarget-'.fn.'">\['
|
||
let fnumberright = '\]</vim:a>'
|
||
let content = escape(g:vst_citationdb[fn], '&/\~')
|
||
let file = substitute(file, fnumberleft.fn.fnumberright, '\\footnote{'.content.'}', '')
|
||
endfor
|
||
" Remove footnotes from xml
|
||
let file = substitute(file, '<vim:footnote.\{-}</vim:footnote>', '', 'g')
|
||
" Remove citations from xml
|
||
let file = substitute(file, '<vim:citation.\{-}</vim:citation>', '', 'g')
|
||
|
||
" Replace rawhtml with pre tags
|
||
"let file = substitute(file, '<vim:rawhtml>', '<vim:pre>', 'g')
|
||
"let file = substitute(file, '<.vim:rawhtml>', '</vim:pre>', 'g')
|
||
|
||
" Replace rawhtml with htmlonly tags
|
||
let file = substitute(file, '<vim:rawhtml>', '<vim:htmlonly>', 'g')
|
||
let file = substitute(file, '<.vim:rawhtml>', '</vim:htmlonly>', 'g')
|
||
|
||
" Remove htmlonly tags and contents
|
||
let file = substitute(file, '<vim:htmlonly>.\{-}<.vim:htmlonly>', '', 'g')
|
||
|
||
|
||
" Special characters II
|
||
let file = substitute(file, '\~', '\\\~{}', 'g')
|
||
let file = substitute(file, ' ', '\~', 'g')
|
||
let file = substitute(file, '&', '\\\&', 'g')
|
||
let file = substitute(file, '<', '<', 'g')
|
||
let file = substitute(file, '>', '>', 'g')
|
||
let file = substitute(file, '©', '(c)', 'g')
|
||
let file = substitute(file, '#', '\\#', 'g')
|
||
let file = substitute(file, '\(backslash\)\@<!\$\(.backslash\)\@!', '\\$', 'g')
|
||
let file = substitute(file, '%', '\\%', 'g')
|
||
let file = substitute(file, '\^', '\\^{}', 'g')
|
||
" Hah. This will break _ in links. Problem may exists also with &
|
||
let file = substitute(file, '_', '\\_', 'g')
|
||
" TeX symbols
|
||
let file = substitute(file, 'LaTeX', '\\LaTeX{}', 'g')
|
||
let file = substitute(file, 'a\@<!TeX', '\\TeX{}', 'g')
|
||
" Very dirty hack to compile docs but should fix also other things.
|
||
" Maybe not so common but very hard to spot when proofreading text.
|
||
let file = substitute(file, '>\\<', '>\\\\<', 'g')
|
||
let file = substitute(file, '\(^\|\s\)\\\($\|\s\)', '\1\\\2', 'g')
|
||
"
|
||
let file = substitute(file, "^", '\\begin{document}'."\n", "")
|
||
|
||
" Create subtitles
|
||
let file = substitute(file, '<vim:p class="subh.\{-}>\(.\{-}\)</vim:p>', '\\subtitle{\1}', "g")
|
||
|
||
" Create verse environment
|
||
let file = substitute(file, '<vim:p class="verse.\{-}>\(.\{-}\)</vim:p>', '\\begin{verse}\n\1\n\\end{verse}', "g")
|
||
|
||
" Create attributions
|
||
let file = substitute(file, '<vim:p class="attribution.\{-}>\(.\{-}\)</vim:p>', '\\attribution{\1}', "g")
|
||
|
||
" Replace table of contents
|
||
let file = substitute(file, '<vim:p id="tocheader" \_.\{-}\.\. comment:: end of toc -->', '\n\\tableofcontents', '')
|
||
|
||
" Replace new line tags <vim:br>
|
||
let file = substitute(file, '\n\s*<vim:br.\{-}>\s*\n', '\n\n', "g")
|
||
let file = substitute(file, '<vim:br.\{-}>', '\\\\', "g")
|
||
|
||
" Title
|
||
let file = substitute(file, '<vim:h1.\{-}>\_s*\(.\{-}\)</vim:h1>', '\\title{\1}\n\\maketitle', "g")
|
||
" Sections
|
||
let file = substitute(file, '<vim:h2 id="\(.\{-}\)".\{-}>', '\\hypertarget{\1}{}\n\\section{', "g")
|
||
let file = substitute(file, '<vim:h3 id="\(.\{-}\)".\{-}>', '\\hypertarget{\1}{}\n\\subsection{', "g")
|
||
let file = substitute(file, '<vim:h4 id="\(.\{-}\)".\{-}>', '\\hypertarget{\1}{}\n\\subsubsection{', "g")
|
||
let file = substitute(file, '<vim:h5 id="\(.\{-}\)".\{-}>', '\\hypertarget{\1}{}\n\\paragraph{', "g")
|
||
let file = substitute(file, '<vim:h6 id="\(.\{-}\)".\{-}>', '\\hypertarget{\1}{}\n\\subparagraph{', "g")
|
||
let file = substitute(file, '<.vim:h[1-6]>', '}', 'g')
|
||
|
||
" Rawlatex directive
|
||
" Ha. I didn't anticipate this - special chars inside of rawlatex will be
|
||
" escaped. Operating on string is faster than going through file line
|
||
" by line so unescaping of chars in while loop similar to pre handling still
|
||
" should be faster.
|
||
let file = substitute(file, '<vim:rawlatex>', '% Begin rawlatex', "g")
|
||
let file = substitute(file, '<.vim:rawlatex>', '% End rawlatex', "g")
|
||
" And the same for latexonly
|
||
let file = substitute(file, '<vim:latexonly>', '% Begin rawlatex', "g")
|
||
let file = substitute(file, '<.vim:latexonly>', '% End rawlatex', "g")
|
||
" And the same for rawboth
|
||
let file = substitute(file, '<vim:rawboth>', '% Begin rawlatex', "g")
|
||
let file = substitute(file, '<.vim:rawboth>', '% End rawlatex', "g")
|
||
|
||
" Lists
|
||
let file = substitute(file, '<vim:li.\{-}>', '\\item ', 'g')
|
||
let file = substitute(file, '<.vim:li>', "", "g")
|
||
let file = substitute(file, '<vim:ul.\{-}>', '\\begin{itemize}', "g")
|
||
let file = substitute(file, '<.vim:ul.\{-}>', '\\end{itemize}', "g")
|
||
" Enumitem and enumerate are in conflict. It has to be one or the
|
||
" other
|
||
if file =~ 'vim:ol class="[^>]\{-}start="'
|
||
let file = substitute(file, '<vim:ol class="loweralpha[^>]\{-}start="\(\d\+\)">', '\\begin{enumerate}[label=\\alph*.,start=\1]', "g")
|
||
let file = substitute(file, '<vim:ol class="upperalpha[^>]\{-}start="\(\d\+\)">', '\\begin{enumerate}[label=\\Alph*.,start=\1]', "g")
|
||
let file = substitute(file, '<vim:ol class="lowerroman[^>]\{-}start="\(\d\+\)">', '\\begin{enumerate}[label=\\roman*.,start=\1]', "g")
|
||
let file = substitute(file, '<vim:ol class="upperroman[^>]\{-}start="\(\d\+\)">', '\\begin{enumerate}[label=\\Roman*.,start=\1]', "g")
|
||
let file = substitute(file, '<vim:ol class="decimal[^>]\{-}start="\(\d\+\)">', '\\begin{enumerate}[label=\\arabic*.,start=\1]', "g")
|
||
let file = substitute(file, '<vim:ol class="loweralpha.\{-}>', '\\begin{enumerate}[label=\\alph*.]', "g")
|
||
let file = substitute(file, '<vim:ol class="upperalpha.\{-}>', '\\begin{enumerate}[label=\\Alph*.]', "g")
|
||
let file = substitute(file, '<vim:ol class="lowerroman.\{-}>', '\\begin{enumerate}[label=\\roman*.]', "g")
|
||
let file = substitute(file, '<vim:ol class="upperroman.\{-}>', '\\begin{enumerate}[label=\\Roman*.]', "g")
|
||
let file = substitute(file, '<vim:ol.\{-}>', '\\begin{enumerate}[label=\\arabic*.]', "g")
|
||
let listings = 'enumitem'
|
||
else
|
||
let file = substitute(file, '<vim:ol class="loweralpha.\{-}>', '\\begin{enumerate}[a.]', "g")
|
||
let file = substitute(file, '<vim:ol class="upperalpha.\{-}>', '\\begin{enumerate}[A.]', "g")
|
||
let file = substitute(file, '<vim:ol class="lowerroman.\{-}>', '\\begin{enumerate}[i.]', "g")
|
||
let file = substitute(file, '<vim:ol class="upperroman.\{-}>', '\\begin{enumerate}[I.]', "g")
|
||
let file = substitute(file, '<vim:ol.\{-}>', '\\begin{enumerate}[1.]', "g")
|
||
let listings = 'enumerate'
|
||
endif
|
||
let file = substitute(file, '<.vim:ol>', '\\end{enumerate}', "g")
|
||
|
||
" Field lists
|
||
let file = substitute(file, '<vim:dl class="field.\{-}>', '\\begin{deflist}{Keywords:}\n', 'g')
|
||
let file = substitute(file, '<vim:dt class="field.\{-}>\(.\{-}\)</vim:dt>', '\\item[\1]', 'g')
|
||
let file = substitute(file, '<vim:dd class="field.\{-}>', '', 'g')
|
||
let file = substitute(file, '</vim:dd>', '', 'g')
|
||
let file = substitute(file, "</vim:dl>", '\\end{deflist}', 'g')
|
||
|
||
" Option lists
|
||
let file = substitute(file, '<vim:dl class="option">', '\\begin{optlist}{longoptionslist}\n', 'g')
|
||
let file = substitute(file, '<vim:dt>\(.\{-}\)</vim:dt>', '\\item[\1]', 'g')
|
||
let file = substitute(file, '<vim:dt class="option">\(.\{-}\)</vim:dt>', '\\item[\1]', 'g')
|
||
let file = substitute(file, '<vim:dd class="option">', '', 'g')
|
||
let file = substitute(file, '<vim:dd>', '', 'g')
|
||
let file = substitute(file, "</vim:dl class=\"option\">", '\\end{optlist}', 'g')
|
||
|
||
" Definition lists
|
||
let file = substitute(file, '<vim:dl>', '\\begin{deflist}{iii}', 'g')
|
||
let file = substitute(file, '<vim:dt class="normal">\(.\{-}\)</vim:dt>', '\\item[\1]', 'g')
|
||
let file = substitute(file, '<vim:dd class="normal">', '', 'g')
|
||
let file = substitute(file, '</vim:dd>', '', 'g')
|
||
"let file = substitute(file, "</vim:dl>", '\\end{deflist}', 'g')
|
||
"
|
||
" Rubric
|
||
let file = substitute(file, '<vim:rubric.\{-}>', '\\rubric{ ', "g")
|
||
let file = substitute(file, "</vim:rubric>", ' }', "g")
|
||
|
||
" Pull-quote
|
||
let file = substitute(file, '<vim:pullquote>', '\\begin{pullquote}', "g")
|
||
let file = substitute(file, "</vim:pullquote>", '\\end{pullquote}', "g")
|
||
|
||
" Blockquote
|
||
let file = substitute(file, "<vim:blockquote.\\{-}>", '\\begin{quotation}', "g")
|
||
let file = substitute(file, "</vim:blockquote>", '\\end{quotation}', "g")
|
||
|
||
" Text styles
|
||
let file = substitute(file, '<vim:em.\{-}>', '\\emph{', "g")
|
||
let file = substitute(file, "</vim:em>", "}", "g")
|
||
let file = substitute(file, '<vim:strong.\{-}>', '\\textbf{', "g")
|
||
let file = substitute(file, "</vim:strong>", "}", "g")
|
||
let file = substitute(file, '<vim:code.\{-}>', '\\texttt{', "g")
|
||
let file = substitute(file, "</vim:code>", "}", "g")
|
||
|
||
" Tables
|
||
let file = substitute(file, '<vim:table class="\(.\{-}\)" summary=".\{-}coln\(.\{-}\)">', '\\setlongtables\n\\begin{center}\n\\begin{longtable}[c]{\1coln\2}\\hline\n', "g")
|
||
let file = substitute(file, "<vim:thead>", '', "g")
|
||
let file = substitute(file, "</vim:thead>", '\\endhead', "g")
|
||
let file = substitute(file, "<vim:tfoot>", '', "g")
|
||
let file = substitute(file, "</vim:tfoot>", '', "g")
|
||
let file = substitute(file, "</vim:table>", '\\end{longtable}\n\\end{center}', "g")
|
||
let file = substitute(file, '<vim:tr>\n\?<vim:td>', '', "g")
|
||
let file = substitute(file, '<vim:td>', ' \& ', "g")
|
||
let file = substitute(file, "</vim:tr>", ' \\\\ \\hline', "g")
|
||
let file = substitute(file, '<vim:tr>\n\?<vim:td colspan="\(.\{-}\)".\{-} summary="\(.\{-}\)">\(.\{-}\)\_s*</vim:td>', '\n\\multicolumn{\1}{|p{0.\2\\textwidth}|}{\3}', "g")
|
||
let file = substitute(file, '<vim:td colspan="\(.\{-}\)".\{-} summary="\(.\{-}\)">\(.\{-}\)\_s*</vim:td>', ' \& \\multicolumn{\1}{p{0.\2\\textwidth}|}{\3}', "g")
|
||
let file = substitute(file, "</vim:td>", '', "g")
|
||
|
||
" Line
|
||
" \transition allows for easy change of transition display, eg. for
|
||
" fancy graphics
|
||
let file = substitute(file, "<vim:hr.\\{-}>", '\\transition', "g")
|
||
|
||
" Comment
|
||
let file = substitute(file, "<vim:!--", '% ', "g")
|
||
|
||
" Links
|
||
let file = substitute(file, '<vim:a href="\(#\)\?\(.\{-}\)".\{-}>\(.\{-}\)</vim:a>', '\\href{\2}{\3}', 'g')
|
||
let file = substitute(file, '<vim:span id="\(.\{-}\)".\{-}>\(.\{-}\)</vim:span>', '\\hypertarget{\1}{\2}', 'g')
|
||
|
||
" Subscript, superscript
|
||
let file = substitute(file, '<vim:sub.\{-}>\(.\{-}\)</vim:sub>', '\\subs{\1}', 'g')
|
||
let file = substitute(file, '<vim:sup.\{-}>\(.\{-}\)</vim:sup>', '\\sups{\1}', 'g')
|
||
|
||
" Fix address special field
|
||
let file = substitute(file, '<vim:pre class="address">\(.\{-}\)</vim:pre>', '\1', 'g')
|
||
|
||
" Replace unknown with pre elements in frame
|
||
let file = substitute(file, '<vim:unknown>', '<vim:span class="big">Unknown element</vim:span>\n<vim:pre>', 'g')
|
||
let file = substitute(file, '</vim:unknown>', '</vim:pre>', 'g')
|
||
|
||
" Title-reference role (<vim:cite>)
|
||
let file = substitute(file, '<vim:cite.\{-}>', '\\emph{', 'g')
|
||
let file = substitute(file, '</vim:cite>', '}', 'g')
|
||
|
||
" Class big, small
|
||
let file = substitute(file, '<vim:span class="big.\{-}>', '{\\large ', 'g')
|
||
let file = substitute(file, '<vim:span class="small.\{-}>', '{\\small ', 'g')
|
||
let file = substitute(file, '</vim:span>', '}', 'g')
|
||
|
||
" Figure
|
||
let file = substitute(file, '<vim:figure.\{-}>', '\\begin{center}\n\\begin{minipage}{0.6\\textwidth}', 'g')
|
||
let file = substitute(file, '</vim:figure>', '\\end{minipage}\n\\end{center}', 'g')
|
||
|
||
" Create ghost commands for custom block directives
|
||
let file = substitute(file, '<vim:block.\{-}class="\(.\{-}\)">', '\\vst\1{', 'g')
|
||
let file = substitute(file, '</vim:block>', '}', 'g')
|
||
|
||
" Create ghost commands for custom container directives
|
||
let file = substitute(file, '<vim:container.\{-}class="\(.\{-}\)">', '\\vst\1{', 'g')
|
||
let file = substitute(file, '</vim:container>', '}', 'g')
|
||
|
||
" Topic
|
||
let file = substitute(file, '<vim:topic.\{-}>', '\\hfill\\begin{minipage}{0.9\\textwidth}', 'g')
|
||
let file = substitute(file, '</vim:topic>', '\\end{minipage}', 'g')
|
||
|
||
" Sidebar
|
||
let file = substitute(file, '<vim:sidebar.\{-}>', '\\hfill\\begin{minipage}{0.9\\textwidth}', 'g')
|
||
let file = substitute(file, '</vim:sidebar>', '\\end{minipage}', 'g')
|
||
|
||
" Divs
|
||
let file = substitute(file, '<vim:div.\{-}>', '\\begin{center}\n\\fbox{\\begin{minipage}{0.8\\textwidth}', 'g')
|
||
let file = substitute(file, '</vim:div>', '\\end{minipage}}\n\\end{center}', 'g')
|
||
" Div titles (<vim:span> was already replaced)
|
||
let file = substitute(file, '<vim:span class="notetitle">\(.\{-}\)}', '\\textbf{\\sffamily\\large \1}\n\\vspace{2mm}', 'g')
|
||
|
||
" Remove rest of vim:span
|
||
" let file = substitute(file, '<vim:span.\{-}>', '\\emph{', 'g')
|
||
let file = substitute(file, '<vim:span class="\(.\{-}\)">', '\\vst\1{', 'g')
|
||
|
||
" Replace empty vim:p tags when hypertargets
|
||
let file = substitute(file, '<vim:p id="\(.\{-}\)"></vim:p>', '\\hypertarget{\1}{}', "g")
|
||
" Ignore all other <vim:p> tags
|
||
let file = substitute(file, '<.\?vim:p\>.\{-}>', "", "g")
|
||
|
||
" Make sure no (La)TeX entity is in URL address of hyperlinks
|
||
let file = substitute(file, '\\href{\([^}]\{-}\)\\\(La\)\?TeX{}', '\\href{\1\2TeX', 'g')
|
||
let file = substitute(file, '\\hypertarget{\([^}]\{-}\)\\\(La\)\?TeX{}', '\\hypertarget{\1\2TeX', 'g')
|
||
" Unescape _ from hyperlinks
|
||
let file = substitute(file, '\\href{\([^}]\{-}\)\\_', '\\href{\1_', 'g')
|
||
let file = substitute(file, '\\hypertarget{\([^}]\{-}\)\\_', '\\hypertarget{\1_', 'g')
|
||
" Prepare newcommands from roles
|
||
if exists("g:vst_roledb")
|
||
let rolenewcommands = '%% Commands for content of roles directives'."\n"
|
||
let rolekeys = keys(g:vst_roledb)
|
||
for i in range(len(rolekeys))
|
||
let name = g:vst_roledb[rolekeys[i]]
|
||
let rolenewcommands .= '\newcommand{\vst'.name.'}[1]{\textnormal{#1}}'."\n"
|
||
endfor
|
||
unlet! rolekeys
|
||
unlet! name
|
||
else
|
||
let rolenewcommands = "\n"
|
||
endif
|
||
" Prepare newcommands from containers
|
||
if len("g:vst_containers") > 0
|
||
let containernewcommands = '%% Commands for content of container directives'."\n"
|
||
let usednames = ''
|
||
for name in g:vst_containers
|
||
if usednames !~ ','.name.','
|
||
let usednames .= ','.name.','
|
||
let containernewcommands .= '\newcommand{\vst'.name.'}[1]{#1}'."\n"
|
||
endif
|
||
endfor
|
||
else
|
||
let containernewcommands = "\n"
|
||
endif
|
||
|
||
" Preamble {{{
|
||
" This one is better for deflist but has some not nice side effects
|
||
" which have to be worked out
|
||
"\.'{\renewcommand{\makelabel}[1]{\parbox[b]{\labelwidth}{\makebox[0pt][l]{\textbf{##1}}\mbox{}\\}}'."\n"
|
||
let preamble =
|
||
\ '\documentclass[12pt]{article}'."\n"
|
||
\.'%% Generated by Vim reStructured Text '.s:vst_ver.' - Vim '.v:version/100.".".v:version % 100."\n"
|
||
\.'\usepackage[a4paper,margin=2.5cm,nohead]{geometry}'."\n"
|
||
\.'\usepackage{'.listings."}\n"
|
||
\.'\usepackage{graphicx}'."\n"
|
||
\.'\usepackage{longtable}'."\n"
|
||
\.'\usepackage{tabularx}'."\n"
|
||
\.'\usepackage{amsmath}'."\n"
|
||
\.'\usepackage['.encoding."]{inputenc}\n"
|
||
\.countrysettings."\n"
|
||
\.'\newenvironment{deflist}[1]{%'."\n"
|
||
\.'\begin{list}{}'."\n"
|
||
\.'{\renewcommand{\makelabel}[1]{\textbf{##1}\hfill}'."\n"
|
||
\.'\settowidth{\labelwidth}{\textbf{#1}}'."\n"
|
||
\.'\leftmargin=\labelwidth'."\n"
|
||
\.'\advance \leftmargin\labelsep}}'."\n"
|
||
\.'{\end{list}}'."\n"
|
||
\.'\newenvironment{optlist}[1]{%'."\n"
|
||
\.'\begin{list}{}'."\n"
|
||
\.'{\renewcommand{\makelabel}[1]{\texttt{##1}\hfill}'."\n"
|
||
\.'\settowidth{\labelwidth}{\texttt{#1}}'."\n"
|
||
\.'\leftmargin=\labelwidth'."\n"
|
||
\.'\advance \leftmargin\labelsep}}'."\n"
|
||
\.'{\end{list}}'."\n"
|
||
\.'\newenvironment{pullquote}{\begin{quotation}\Large}{\end{quotation}}'."\n"
|
||
\.'\setlength{\extrarowheight}{2pt}'."\n"
|
||
\.tocdepth."\n"
|
||
\.'\newcommand{\transition}{\begin{center}\rule{.8\textwidth}{0.2pt}\end{center}}'."\n"
|
||
\.'\newcommand{\subtitle}[1]{{\large\textsc{#1}}\vskip15pt}'."\n"
|
||
\.'\newcommand{\subs}[1]{\raisebox{-0.7ex}{\footnotesize #1}}'."\n"
|
||
\.'\newcommand{\sups}[1]{\raisebox{0.7ex}{\footnotesize #1}}'."\n"
|
||
\.'\newcommand{\attribution}[1]{\raggedleft\textit{#1}}'."\n"
|
||
\.'\newcommand{\rubric}[1]{\vskip15pt{\large #1}}'."\n"
|
||
\.rolenewcommands."\n"
|
||
\.containernewcommands."\n"
|
||
\.userpreamble."\n"
|
||
\.'\usepackage[pdftex]{hyperref}'."\n"
|
||
" Additional data {{{
|
||
let author = ''
|
||
let data = ''
|
||
if has_key(g:vst_fielddb, 'author')
|
||
let author = '\author{'.g:vst_fielddb['author'].'}'."\n"
|
||
endif
|
||
if has_key(g:vst_fielddb, 'date')
|
||
if g:vst_fielddb['date'] == 'NONE'
|
||
let g:vst_fielddb['date'] = ''
|
||
endif
|
||
let data = '\date{'.g:vst_fielddb['date'].'}'."\n"
|
||
else
|
||
let data = ''
|
||
endif
|
||
" }}}
|
||
" PDF Info {{{
|
||
let pdfinfo = ''
|
||
let pdfauthor = ''
|
||
let pdftitle = ''
|
||
let pdfsubject = ''
|
||
let pdfkeywords = ''
|
||
if has_key(g:vst_fielddb, 'author')
|
||
let pdfauthor = 'pdfauthor={'.g:vst_fielddb['author']."},\n"
|
||
endif
|
||
if has_key(g:vst_fielddb, 'title')
|
||
let pdftitle = 'pdftitle={'.g:vst_fielddb['title']."},\n"
|
||
endif
|
||
if has_key(g:vst_fielddb, 'keywords')
|
||
let pdfkeywords = 'pdfkeywords={'.g:vst_fielddb['keywords']."},\n"
|
||
endif
|
||
if has_key(g:vst_fielddb, 'subject')
|
||
let pdfsubject = 'pdfsubject={'.g:vst_fielddb['subject']."}"
|
||
endif
|
||
for key in keys(g:vst_metadb)
|
||
if key =~ 'author' && pdfauthor == ''
|
||
let pdfauthor = 'pdfauthor={'.g:vst_metadb[key]."},\n"
|
||
elseif key =~ 'title' && pdftitle == ''
|
||
let pdftitle = 'pdftitle={'.g:vst_metadb[key]."},\n"
|
||
elseif key =~ 'keywords' && pdfkeywords == ''
|
||
let pdfkeywords = 'pdfkeywords={'.g:vst_metadb[key]."},\n"
|
||
elseif key =~ 'subject' && pdfsubject == ''
|
||
let pdfsubject = 'pdfsubject={'.g:vst_metadb[key]."}"
|
||
endif
|
||
endfor
|
||
|
||
if exists("g:vst_doc_title")
|
||
let pdftitle = 'pdftitle={'.substitute(g:vst_doc_title, '^\s*', '', '')."},\n"
|
||
endif
|
||
|
||
let pdfinfo = "\\hypersetup{\npdfcreator={VST, LaTeX, hyperref},\n"
|
||
\."bookmarksopen=true,\nbookmarksopenlevel=2,\n"
|
||
\."colorlinks=true,urlcolor=blue,\n"
|
||
\.pdfauthor.pdftitle.pdfkeywords.pdfsubject."}\n"
|
||
|
||
let file = preamble."\n".pdfinfo."\n".author.data."\n".file."\n".footer
|
||
" }}}
|
||
" }}}
|
||
|
||
" Create comments
|
||
let file = substitute(file, '<vim:comment>\(.\{-}\)<.vim:comment>', '\=VST_CreateTexComment(submatch(1))', 'g')
|
||
|
||
new
|
||
if &compatible == 1
|
||
set nocompatible
|
||
endif
|
||
0put =file
|
||
|
||
" Go through tables to tune them {{{
|
||
" 1. Create preamble of table
|
||
" 2. Remove \hline for borderless tables
|
||
silent call cursor(1,1)
|
||
while search('begin{longtable', 'W')
|
||
unlet! line1 line2
|
||
let line1 = line('.')
|
||
if getline('.') =~ 'vstbordercoln'
|
||
"silent exe line1.','.line2.'s/\(multicolumn{\d\+}{\)\(.\{-}\)}/\=submatch(1).substitute(submatch(2), "\\(\\d\\+\\)+", "|p{0.\\1\\\\\\\\textwidth}", "g")."}"/ge'
|
||
silent s/vstbordercoln\(.\{-}\)}/\='|'.substitute(submatch(1), '\(\d\+\)+', 'p{0.\1\\\\textwidth}|', 'g').'}'/e
|
||
call search('end{longtable', 'W')
|
||
let line2 = line('.')
|
||
"silent exe line1.','.line2.'s/\(multicolumn{\d\+}{\)\(.\{-}\)}/\=submatch(1).substitute(submatch(2), "\\(\\d\\+\\)+", "|p{0.\\1\\\\\\textwidth}", "g")."}"/ge'
|
||
"silent exe line1.','.line2.'s/\(\& \\multicolumn{\d\+}{\)|/\1/ge'
|
||
elseif getline('.') =~ 'vstblesscoln'
|
||
silent s/vstblesscoln\(.\{-}\)}/\=substitute(submatch(1), '\(\d\+\)+', 'p{0.\1\\\\textwidth} ', 'g').'}'/e
|
||
call search('end{longtable', 'W')
|
||
let line2 = line('.')
|
||
silent exe line1.','.line2.'s/\\hline\($\|\\end{longtable\)/\1/e'
|
||
silent exe line1.','.line2.'g/\\multicolumn/s/\(\\textwidth}\)|/\1/ge'
|
||
silent exe line1.','.line2.'g/\\multicolumn/s/\(\\multicolumn{\d\+}{\)|/\1/ge'
|
||
endif
|
||
" NOTE: this changes range so line1, line2 are useless after that
|
||
silent exe line1.','.line2.'s/\_s*&\_s*/\r\&\r/ge'
|
||
endwhile
|
||
" }}}
|
||
" Process <img> {{{
|
||
silent call cursor(1,1)
|
||
while search('<vim:img', 'W') != 0
|
||
let image = getline('.')
|
||
let imagelink = 0
|
||
" Detect if image is link. It requires messing with order of
|
||
" elements
|
||
if getline(line('.')-1) =~ 'href.*{$'
|
||
let imagelink = 1
|
||
let link = getline(line('.')-1)
|
||
endif
|
||
let class = matchstr(image, 'class="\zs.\{-}\ze"')
|
||
let src = matchstr(image, 'src="\zs.\{-}\ze"')
|
||
let width = matchstr(image, 'width="\zs.\{-}\ze"')
|
||
let height = matchstr(image, 'height="\zs.\{-}\ze"')
|
||
if width == '' && height == ''
|
||
let dimensions = ''
|
||
elseif width != '' && height == ''
|
||
let dimensions = '[width='.width.'pt]'
|
||
elseif height != '' && width == ''
|
||
let dimensions = '[height='.height.'pt]'
|
||
else
|
||
let dimensions = '[height='.height.'pt, width='.width.'pt]'
|
||
endif
|
||
let figure = '\\includegraphics'.dimensions.'{'.src.'}'
|
||
let alt = ''
|
||
let title = ''
|
||
let opening = ''
|
||
let caption = ''
|
||
let closing = ''
|
||
if class !~ 'inline'
|
||
let alt = matchstr(image, 'alt="\zs.\{-}\ze"')
|
||
let title = matchstr(image, 'title="\zs.\{-}\ze"')
|
||
let opening = '\\begin{figure}[ht]\\centering'
|
||
if title != ''
|
||
let caption = '\\caption{'.title.'}'
|
||
"elseif alt != ''
|
||
"let caption = '\\caption{'.alt.'}'
|
||
else
|
||
let caption = ''
|
||
endif
|
||
let closing = '\\end{figure}'
|
||
endif
|
||
if imagelink != 0
|
||
let link = escape(link, '\')
|
||
let imagestring = opening.link.figure.'}'.caption.closing
|
||
" Remove href end closing }, it require jumping between the
|
||
" lines.
|
||
silent .-1s/.*//e
|
||
silent .+2s/.*//e
|
||
silent normal! k
|
||
else
|
||
let imagestring = opening.figure.caption.closing
|
||
endif
|
||
silent exe 's+<vim:img.\{-}>+'.imagestring.'+e'
|
||
silent normal! j
|
||
endwhile
|
||
" }}}
|
||
" Processing preformatted text. {{{
|
||
" Not using verbatim because it is
|
||
" in conflict with minipages
|
||
silent call cursor(1,1)
|
||
while search('^\s*<vim:pre', 'W')
|
||
silent s+.*+\\begin{ttfamily}\\begin{flushleft}+
|
||
silent normal! j
|
||
let line1 = line('.')
|
||
let indlist = []
|
||
while getline('.') !~ '</vim:pre'
|
||
if getline('.') =~ '^\s*$'
|
||
silent normal! j
|
||
continue
|
||
endif
|
||
let preind = strlen(matchstr(getline('.'), '^\s*'))
|
||
let indlist += [preind]
|
||
silent normal! j
|
||
endwhile
|
||
let line2 = line('.')-1
|
||
if line2 < line1
|
||
let line2 = line1
|
||
endif
|
||
let lineend = line('.')
|
||
let ind = min(indlist) <= 0 ? 0 : min(indlist)
|
||
silent exe line1.','.line2.'s/^ \{'.ind.'}/ /e'
|
||
silent exe line1.','.line2.'s+^+\\mbox{+e'
|
||
silent exe line1.','.line2.'s+$+}\\\\+e'
|
||
silent exe line1.','.line2.'s/ /\~/ge'
|
||
silent exe lineend's+.*+\\end{flushleft}\\end{ttfamily}+'
|
||
endwhile
|
||
" }}}
|
||
" Unescaping special chars from rawlatex. {{{
|
||
silent call cursor(1,1)
|
||
while search('^\s*% Begin rawlatex', 'W')
|
||
silent normal! j
|
||
let line1 = line('.')
|
||
while getline('.') !~ '% End rawlatex'
|
||
silent normal! j
|
||
endwhile
|
||
let line2 = line('.')-1
|
||
silent exe line1.','.line2.'s/^\s\+//e'
|
||
silent exe line1.','.line2.'s/\$\\backslash\$/\\/ge'
|
||
silent exe line1.','.line2.'s/\\\$/$/ge'
|
||
silent exe line1.','.line2.'s/\\\({\|\}\)/\1/ge'
|
||
silent exe line1.','.line2.'s/\\\^{}/^/ge'
|
||
silent exe line1.','.line2.'s/\\\~{}/\~/ge'
|
||
silent exe line1.','.line2.'s/\\#/#/ge'
|
||
silent exe line1.','.line2.'s/\\%/%/ge'
|
||
silent exe line1.','.line2.'s/\\_/_/ge'
|
||
" Hack to workaround inner slash escaping mechanism. consider
|
||
" single backslash at the end of line as double backslash meaning
|
||
" 'new line'
|
||
silent exe line1.','.line2.'s/\\$/\\\\/ge'
|
||
endwhile
|
||
" }}}
|
||
" In lines not belonging to pre enclose < and > in $$ to show them. {{{
|
||
" \langle, \rangle would be more proper solution but they
|
||
" look too differently for my taste.
|
||
silent v/^\\mbox/s/</$<$/ge
|
||
silent v/^\\mbox/s/>/$>$/ge
|
||
silent v/^\\mbox\|begin{longtable\|multicolumn{/s/|/$|$/ge
|
||
" }}}
|
||
" Beautyfication of LaTeX output {{{
|
||
silent %s/^\s*$//
|
||
silent %s/\n\{3,}/\r\r/
|
||
silent %s/\n\+\(\n\s*\\end\)/\1/
|
||
silent %s/\(\\begin{.\{-}}\n\)\n\+/\1/
|
||
" Compressing of titles
|
||
silent %s/title{\n/title{/e
|
||
silent %s/section{\n/section{/e
|
||
silent %s/paragraph{\n/paragraph{/e
|
||
" Shorten lists
|
||
silent %s/\\item\s*\n\n/\\item\r/e
|
||
" Because multiple spaces are meaningless:
|
||
silent %s/\s\+/ /ge
|
||
" Test it
|
||
silent %s/{\_s*/{/ge
|
||
silent %s/\n\n\s*&\s*\n\n/\r\&\r/ge
|
||
silent %s/\n\n \(\\\\ \\hline\)\s*\n\n/\r\1\r/ge
|
||
" Fix vertical space in admonitions
|
||
silent %s/\(\\vspace{2mm}\n\)\(\S\)/\1\r\2/ge
|
||
" Replace lines for .. figure:: - image first, minipage later.
|
||
silent %s/\(\\begin{minipage}{0\.6\\textwidth}\)\n\(\\begin{figure.*\)/\2\r\1/ge
|
||
" Remove special chars catchers
|
||
silent %s/@/@/ge
|
||
silent %s/[/[/ge
|
||
silent %s/\/\\/ge
|
||
silent %s/:/:/ge
|
||
silent %s/&\\#64;/@/ge
|
||
silent %s/&\\#91;/[/ge
|
||
silent %s/&\\#92;/\\/ge
|
||
silent %s/&\\#58;/:/ge
|
||
" Insert new line before \item[], it causes problems in complex
|
||
" environments
|
||
silent %s/\\item\[/\r\0/ge
|
||
" But we don't like if there is more than one blank line
|
||
silent %s/\n\n\n\\item\[/\r\r\\item\[/ge
|
||
" Remove empty deflist environment
|
||
" may be a problem when :Date: NONE is the only element of field list
|
||
silent %s/\\begin{deflist}{.\{-}}\n\\end{deflist}//ge
|
||
" Replace non-breaking space characters with ~
|
||
silent %s/<2F>/\~/ge
|
||
" }}}
|
||
" Insert raw files {{{
|
||
silent call cursor(1,1)
|
||
while search('-vst-raw-file-placeholder:', 'W')
|
||
let file = matchstr(getline('.'), '-vst-raw-file-placeholder:\zs.*')
|
||
" Remove \ before _ - in most cases it was placed there by
|
||
" escaping mechanism, not user
|
||
let file = substitute(file, '\\_', '_', 'g')
|
||
silent s/.*//ge
|
||
exe 'silent read '.escape(file, ' \#%')
|
||
endwhile
|
||
" }}}
|
||
|
||
redraw!
|
||
|
||
" This is place for special CJK postprocessing
|
||
" What if &encoding=='utf-8'?
|
||
if &encoding =~? 'big5\|cp950\|euc-tw' || ( &encoding =~? '^utf' && v:ctype =~ 'big5' )
|
||
|
||
silent! g/^\\usepackage.*geometry}/s/.*/\0\r\\usepackage{CJK}/
|
||
silent! g/^\\usepackage.*inputenc}/d
|
||
silent! g/^\\usepackage.*hyperref}/s/.*/\\usepackage[CJKbookmarks,bookmarks=false,pdftex]{hyperref}
|
||
silent! g/^bookmarksopen=true,$/d
|
||
silent! g/^bookmarksopenlevel=2,$/d
|
||
if encoding == 'Big5'
|
||
silent! g/\\begin{document}/s/.*/\0\\begin{CJK}{Bg5}{}/
|
||
elseif encoding == 'UTF-8'
|
||
silent! g/\\begin{document}/s/.*/\0\\begin{CJK}{UTF8}{}/
|
||
else
|
||
silent! g/\\begin{document}/s/.*/\0\\begin{CJK}{}{}/
|
||
endif
|
||
silent! g/\\end{document}/s/.*/\\end{CJK}\0/
|
||
|
||
let cjkpreamble = '\renewcommand\CJKglue{\hskip -0.3pt plus 0.08\baselineskip}'."-cjk-newline-placeholder-"
|
||
\.'\linespread{1.382}'."-cjk-newline-placeholder-"
|
||
\.'\renewcommand{\arraystretch}{1.2}'."-cjk-newline-placeholder-"
|
||
\.'\parindent=0pt'."-cjk-newline-placeholder-"
|
||
\.'\parskip=1.382ex'."-cjk-newline-placeholder-"
|
||
\.'\renewenvironment{quote}'."-cjk-newline-placeholder-"
|
||
\.' {\list{}{\topsep 1ex\parsep 0ex\setlength\leftmargin{1.5em}%'."-cjk-newline-placeholder-"
|
||
\.' \rightmargin\leftmargin}\item\relax\linespread{1.0}\small}%'."-cjk-newline-placeholder-"
|
||
\.' {\endlist}'."-cjk-newline-placeholder-"
|
||
\.'\let\oldfootnote\footnote'."-cjk-newline-placeholder-"
|
||
\.'\renewcommand\footnote[1]{\oldfootnote{\renewcommand\baselinestretch{1.0}%'."-cjk-newline-placeholder-"
|
||
\.'\large\footnotesize\ignorespaces#1}}'."-cjk-newline-placeholder-"
|
||
\.'\addtolength{\footnotesep}{3pt}'
|
||
|
||
silent call cursor(1,1)
|
||
silent call search('^\\usepackage{amsmath}')
|
||
silent call append(line('.'), cjkpreamble)
|
||
" Placeholder stuff is necessary because no Vim function for
|
||
" inserting text like newline character.
|
||
silent! %s/-cjk-newline-placeholder-/\r/g
|
||
silent call cursor(1,1)
|
||
|
||
endif
|
||
|
||
" User postprocessing
|
||
if g:vst_tex_post != '' && filereadable(g:vst_tex_post)
|
||
exe "silent! source ".g:vst_tex_post
|
||
endif
|
||
|
||
" Handling of pdf export {{{
|
||
if format =~ 'pdf'
|
||
silent call cursor(1,1)
|
||
let file_tex = filename.'.tex'
|
||
if !exists('g:vst_pdf_command')
|
||
let g:vst_pdf_command = 'pdflatex -interaction=nonstopmode'
|
||
endif
|
||
silent exe 'write! '.escape(file_tex, ' \#%')
|
||
silent exe "call system(\"".g:vst_pdf_command." '".file_tex."'\")"
|
||
if search('\\tableofcontents', 'W')
|
||
silent exe "call system(\"".g:vst_pdf_command." '".file_tex."'\")"
|
||
endif
|
||
if v:shell_error == 0
|
||
bw! %
|
||
echomsg "Document compiled OK. You can view it in PDF viewer."
|
||
if exists("g:vst_pdf_clean") && g:vst_pdf_clean == 1
|
||
call delete(file_tex)
|
||
call delete(filename.'.log')
|
||
call delete(filename.'.out')
|
||
call delete(filename.'.aux')
|
||
endif
|
||
if exists("g:vst_pdf_view") && g:vst_pdf_view == 1
|
||
if !exists("g:vst_pdf_viewer")
|
||
if has("win32")
|
||
let g:vst_pdf_viewer = ""
|
||
elseif has("unix")
|
||
if executable("kpdf")
|
||
let g:vst_pdf_viewer = "kpdf"
|
||
elseif executable("xpdf")
|
||
let g:vst_pdf_viewer = "xpdf"
|
||
else
|
||
let g:vst_pdf_viewer = "no_pdf_viewer"
|
||
endif
|
||
endif
|
||
endif
|
||
silent exe "call system(\"".g:vst_pdf_viewer." '".filename.".pdf'\")"
|
||
silent redraw!
|
||
endif
|
||
else
|
||
echomsg "Something went wrong, check TeX code or command settings."
|
||
endif
|
||
silent call cursor(1,1)
|
||
call VST_End()
|
||
return
|
||
endif
|
||
" }}}
|
||
|
||
" Latex-Suite (or any other tex ftype settings) brokes *many*
|
||
" things. Load it at the end
|
||
setlocal ft=tex
|
||
if exists("g:vst_write_export") && g:vst_write_export != 0
|
||
silent exe 'write! '.escape(filename, ' \#%').'.tex'
|
||
endif
|
||
|
||
silent call cursor(1,1)
|
||
" }}}
|
||
" Auxiliary commands {{{
|
||
elseif format =~ '^head'
|
||
" Symbols for section titles {{{
|
||
call VST_Headers(text)
|
||
unlet! b:vst_first_parsing
|
||
call VST_DictTable(g:vst_headers, 'Level', 'Symbol', 0)
|
||
" }}}
|
||
elseif format =~ '^toc'
|
||
" Table of contents for file {{{
|
||
let line = line('.')
|
||
call VST_Headers(text)
|
||
unlet! b:vst_first_parsing
|
||
let i = 1
|
||
let tocc = []
|
||
let b:vst_toc_numbers = {}
|
||
let i1 = -1
|
||
let i2 = -1
|
||
let i3 = -1
|
||
let i4 = -1
|
||
let i5 = -1
|
||
let i6 = -1
|
||
|
||
while i < len(g:paras)
|
||
if g:ptype[i] =~ '^h\d'
|
||
" Real table
|
||
call add(tocc, [g:ptype[i], g:paras[i], g:plinen[i]])
|
||
" Header numbers
|
||
let header_text = matchstr(g:paras[i], '^.\{-}\ze\n')
|
||
let lvl = strpart(g:ptype[i], 1)
|
||
if lvl == 1
|
||
let b:vst_toc_numbers[header_text] = ''
|
||
let i2 = 0
|
||
let i3 = 0
|
||
let i4 = 0
|
||
let i5 = 0
|
||
let i6 = 0
|
||
elseif lvl == 2
|
||
let i2 += 1
|
||
let b:vst_toc_numbers[header_text] = i2.' '
|
||
let i3 = 0
|
||
let i4 = 0
|
||
let i5 = 0
|
||
let i6 = 0
|
||
elseif lvl == 3
|
||
let i3 += 1
|
||
let b:vst_toc_numbers[header_text] = i2.'.'.i3.' '
|
||
let i4 = 0
|
||
let i5 = 0
|
||
let i6 = 0
|
||
elseif lvl == 4
|
||
let i4 += 1
|
||
let b:vst_toc_numbers[header_text] = i2.'.'.i3.'.'.i4.' '
|
||
let i5 = 0
|
||
let i6 = 0
|
||
elseif lvl == 5
|
||
let i5 += 1
|
||
let b:vst_toc_numbers[header_text] = i2.'.'.i3.'.'.i4.'.'.i5.' '
|
||
let i6 = 0
|
||
elseif lvl == 6
|
||
let i6 += 1
|
||
let b:vst_toc_numbers[header_text] = i2.'.'.i3.'.'.i4.'.'.i5.'.'.i6.' '
|
||
endif
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
|
||
echo VST_TocTable(tocc, 'Nr', 'Title', ' Line', line)
|
||
" }}}
|
||
elseif format =~ '^fold'
|
||
" Folding {{{
|
||
let b:vst_fold = {}
|
||
call VST_Headers(text)
|
||
unlet! b:vst_first_parsing
|
||
" Prepare numbers of head lines {{{
|
||
let b:vst_fold_numbers = {}
|
||
let i = 0
|
||
let i1 = -1
|
||
let i2 = -1
|
||
let i3 = -1
|
||
let i4 = -1
|
||
let i5 = -1
|
||
let i6 = -1
|
||
while i < len(g:paras)
|
||
if g:ptype[i] =~ '^h\d'
|
||
let header_text = matchstr(g:paras[i], '^.\{-}\ze\n')
|
||
let lvl = strpart(g:ptype[i], 1)
|
||
if lvl == 1
|
||
let b:vst_fold_numbers[header_text] = ''
|
||
let i2 = 0
|
||
let i3 = 0
|
||
let i4 = 0
|
||
let i5 = 0
|
||
let i6 = 0
|
||
elseif lvl == 2
|
||
let i2 += 1
|
||
let b:vst_fold_numbers[header_text] = i2.' '
|
||
let i3 = 0
|
||
let i4 = 0
|
||
let i5 = 0
|
||
let i6 = 0
|
||
elseif lvl == 3
|
||
let i3 += 1
|
||
let b:vst_fold_numbers[header_text] = i2.'.'.i3.' '
|
||
let i4 = 0
|
||
let i5 = 0
|
||
let i6 = 0
|
||
elseif lvl == 4
|
||
let i4 += 1
|
||
let b:vst_fold_numbers[header_text] = i2.'.'.i3.'.'.i4.' '
|
||
let i5 = 0
|
||
let i6 = 0
|
||
elseif lvl == 5
|
||
let i5 += 1
|
||
let b:vst_fold_numbers[header_text] = i2.'.'.i3.'.'.i4.'.'.i5.' '
|
||
let i6 = 0
|
||
elseif lvl == 6
|
||
let i6 += 1
|
||
let b:vst_fold_numbers[header_text] = i2.'.'.i3.'.'.i4.'.'.i5.'.'.i6.' '
|
||
endif
|
||
|
||
let b:vst_fold[header_text] = lvl-1
|
||
endif
|
||
let i += 1
|
||
endwhile
|
||
" }}}
|
||
" Prepare fold levels {{{
|
||
let b:vst_fold_lvl = matchstr(format, '\zs.\ze\s*$')
|
||
if b:vst_fold_lvl =~ 'r'
|
||
for i in [1, 2, 3, 4, 5, 6]
|
||
let b:vst_fold_list_{i} = filter(deepcopy(b:vst_fold), 'v:val == i')
|
||
let b:vst_flvl_{i} = keys(b:vst_fold_list_{i})
|
||
endfor
|
||
else
|
||
if b:vst_fold_lvl !~ '\d'
|
||
let b:vst_fold_lvl = 0
|
||
elseif b:vst_fold_lvl =~ '\d' && b:vst_fold_lvl > 6
|
||
let b:vst_fold_lvl = 6
|
||
endif
|
||
if b:vst_fold_lvl != 0
|
||
let b:vst_fold_list = filter(deepcopy(b:vst_fold), 'v:val <= b:vst_fold_lvl')
|
||
else
|
||
let b:vst_fold_list = b:vst_fold
|
||
endif
|
||
endif
|
||
" }}}
|
||
setlocal foldmethod=expr
|
||
setlocal foldexpr=VST_FoldExpr(v:lnum)
|
||
setlocal foldtext=VST_FoldText()
|
||
" }}}
|
||
elseif format =~ '^fblank'
|
||
" Folding by blank lines {{{
|
||
let directive = matchstr(format, '^f\zs.*')
|
||
setlocal foldmethod=expr
|
||
set foldexpr=getline(v:lnum)=~'^\\s*$'&&getline(v:lnum+1)=~'\\S'?'<1':1
|
||
function! VST_FoldText()
|
||
let text = getline(v:foldstart)
|
||
let indent = '+'.v:folddashes
|
||
return indent.repeat(' ', 2).text.' '
|
||
endfunction
|
||
setlocal foldtext=VST_FoldText()
|
||
" }}}
|
||
elseif format =~ '^f'
|
||
" Folding by directive {{{
|
||
"elseif format =~ '^f\(block\|container\|image\|figure\|sidebar\|compound\|topic\|rubric\|table\|tip\|note\|warning\|admonition\|include\|pull-quote\|class\|meta\|raw\|2html\)'
|
||
let directive = matchstr(format, '^f\zs.*')
|
||
setlocal foldmethod=expr
|
||
"exe "setlocal foldexpr=getline(v:lnum)=~?'^\\\\s*\\\.\\\.\\\ ".directive."::'?'>1':1"
|
||
exe "setlocal foldexpr=getline(v:lnum)=~?'^\\\\s*\\\.\\\.\\\ ".directive."'?'>1':1"
|
||
function! VST_FoldDirective()
|
||
let text = getline(v:foldstart)
|
||
let indent = '+'.v:folddashes
|
||
let fill = 65 - (len(indent) + len(text) + 3)
|
||
if fill < 1
|
||
let fill = 1
|
||
endif
|
||
return indent.' '.text.repeat(' ', fill).v:foldstart.' ('.v:foldstart*100/line('$').'%)'
|
||
endfunction
|
||
setlocal foldtext=VST_FoldDirective()
|
||
" }}}
|
||
elseif format =~ '^link'
|
||
" Link table {{{
|
||
call VST_Headers(text)
|
||
unlet! b:vst_first_parsing
|
||
call VST_DictTable(g:vst_hlinkdb, 'Text', 'Link', 0)
|
||
" }}}
|
||
elseif format =~ '^slink'
|
||
" Sorted link table {{{
|
||
call VST_Headers(text)
|
||
unlet! b:vst_first_parsing
|
||
call VST_DictTable(g:vst_hlinkdb, 'Text', 'Link', 1)
|
||
" }}}
|
||
elseif format =~ '^rep'
|
||
" Replacement table {{{
|
||
call VST_Headers(text)
|
||
unlet! b:vst_first_parsing
|
||
call VST_DictTable(g:vst_replacedb, 'Symbol', 'Replacement', 0)
|
||
" }}}
|
||
elseif format =~ '^srep'
|
||
" Sorted replacement table {{{
|
||
call VST_Headers(text)
|
||
unlet! b:vst_first_parsing
|
||
call VST_DictTable(g:vst_replacedb, 'Symbol', 'Replacement', 1)
|
||
" }}}
|
||
elseif format =~ '^help'
|
||
" Help for commands {{{
|
||
echo
|
||
\ "Help for :Vst arguments:\n"
|
||
\."html - [default] export to HTML format\n"
|
||
\."tex - export to LaTeX format\n"
|
||
\."pdf - export to LaTeX format and compile PDF\n"
|
||
\."rest - export to reST format\n"
|
||
\."s5 - export to S5 HTML presentation\n"
|
||
\." ---------------\n"
|
||
\."toc - file table of contents\n"
|
||
\."head - show used symbols for headers\n"
|
||
\."link - show table of link declarations\n"
|
||
\."slink - show sorted table of link declarations\n"
|
||
\."rep - show table of replacements\n"
|
||
\."srep - show sorted table of replacements\n"
|
||
\."preproc - process inclusion commands (non-recursively)\n"
|
||
\."help - this message\n"
|
||
\." ---------------\n"
|
||
\."fold - (re)create folds in file\n"
|
||
\."foldr - (re)create folds recursively in file\n"
|
||
\."fold1 - (re)create folds of 1st level headers in file\n"
|
||
\."fold2 - (re)create folds up to 2nd level header in file\n"
|
||
\."fold3 - (re)create folds up to 3rd level header in file\n"
|
||
\."fold4 - (re)create folds up to 4th level header in file\n"
|
||
\."fold5 - (re)create folds up to 5th level header in file\n"
|
||
\."fold6 - (re)create folds up to 6th level header in file\n"
|
||
\." ---------------\n"
|
||
\."Additional commands:\n"
|
||
\.":Vsti - immediately write file\n"
|
||
\.":Vstm - display menus (no arguments)"
|
||
return ''
|
||
" }}}
|
||
elseif format =~ '^pre'
|
||
" Interpret all including commands and put them in file {{{
|
||
silent normal! ggdG
|
||
let jtext = join(text, "\n")
|
||
silent 0put =jtext
|
||
silent call cursor(1,1)
|
||
" }}}
|
||
" }}}
|
||
endif
|
||
|
||
call VST_End()
|
||
|
||
return ''
|
||
|
||
endfunction
|
||
" }}}
|
||
|
||
" Functions for auxiliary mappings {{{
|
||
function! vst#vst#VST_AuxiliaryMappings()
|
||
" VST_Ornaments: insert ornaments depending on position {{{
|
||
" Description: Depending on position and inserted character inserted before
|
||
" cursor fill ornaments: single section ornaments, double section ornaments,
|
||
" transition element
|
||
function! VST_Ornaments()
|
||
" Get ornament character
|
||
" HEADDEF:
|
||
let s:vst_headdef = '\(=\{3,}\|+\{3,}\|\*\{3,}\|\^\{3,}\|%\{3,}\|\$\{3,}\|#\{3,}\|@\{3,}\|;\{3,}\|"\{3,}\|\.\{3,}\|,\{3,}\|`\{3,}\|\~\{3,}\|-\{3,}\|!\{3,}\|(\{3,}\|)\{3,}\|:\{3,}\|_\{3,}\|&\{3,}\|}\{3,}\|{\{3,}\||\{3,}\|?\{3,}\|<\{3,}\|>\{3,}\|\\\{3,}\|\[\{3,}\|\]\{3,}\|\/\{3,}\|''\{3,}\)'
|
||
let s:vst_headchars2 = '\(=\|+\|\*\|\^\|%\|\$\|#\|@\|;\|"\|\.\|,\|`\|\~\|-\|!\|(\|)\|:\|_\|&\|}\|{\||\|?\|<\|>\|\\\|\[\|\]\|\/\|''\)'
|
||
let curline = getline(line('.'))
|
||
let character = curline[len(curline)-1]
|
||
if curline =~ '^\s*$'
|
||
" Temporary thing, to by-pass headchars test
|
||
let character = '-'
|
||
elseif curline !~ '^\s*'.s:vst_headchars2.'\+$'
|
||
return ''
|
||
endif
|
||
|
||
let prevline = getline(line('.')-1)
|
||
let nextline = getline(line('.')+1)
|
||
|
||
if prevline =~ '^\s*$'
|
||
let prevline_is_empty = 1
|
||
else
|
||
let prevline_is_empty = 0
|
||
endif
|
||
|
||
if nextline =~ '^\s*$'
|
||
let nextline_is_empty = 1
|
||
else
|
||
let nextline_is_empty = 0
|
||
endif
|
||
|
||
if prevline_is_empty == 1 && nextline_is_empty == 1
|
||
" We are to insert transition element
|
||
if &tw > 50
|
||
let trans_len = &tw/3
|
||
else
|
||
let trans_len = 20
|
||
endif
|
||
if curline =~ '^\s*$'
|
||
" Current line consists of only white characters. Try to find last
|
||
" used transition
|
||
let last_trans_line = search('\n\s*\n\s*'.s:vst_headdef.'\s*\n\s*\n' , 'bWn') + 2
|
||
if last_trans_line == 2
|
||
let character = '-'
|
||
else
|
||
let character = matchstr(getline(last_trans_line), '^\s*\zs.\ze')
|
||
endif
|
||
endif
|
||
return repeat(character, trans_len)
|
||
elseif prevline_is_empty == 0 && nextline_is_empty == 1
|
||
" Insert single ornament
|
||
let prevline_len = len(prevline)
|
||
if curline =~ '^\s*$'
|
||
" Current line consists of only white characters. Try to find last
|
||
" single ornament section
|
||
let last_single_ornament = search('\(\%^\|\n\s*\n\|\%^\s*\n\).\{-}\n\s*'.s:vst_headdef.'\s*\n\s*\n' , 'bWn') + 3
|
||
if last_single_ornament == 4 && getline(1) =~ '^\s*$' && getline(2) =~ '^\s*$'
|
||
let last_single_ornament = 4
|
||
elseif last_single_ornament == 4 && getline(1) =~ '^\s*$'
|
||
let last_single_ornament = 3
|
||
let real3 = 1
|
||
elseif last_single_ornament == 4
|
||
let last_single_ornament = 2
|
||
endif
|
||
if last_single_ornament == 3
|
||
if !exists('real3')
|
||
let character = '-'
|
||
else
|
||
let character = matchstr(getline(last_single_ornament), '^\s*\zs.\ze')
|
||
unlet! real3
|
||
endif
|
||
else
|
||
let character = matchstr(getline(last_single_ornament), '^\s*\zs.\ze')
|
||
endif
|
||
endif
|
||
if prevline_len < 3
|
||
let ornament_len = 3 - len(curline)
|
||
else
|
||
let ornament_len = prevline_len - len(curline)
|
||
endif
|
||
return repeat(character, ornament_len)."\n"
|
||
elseif prevline_is_empty == 1 && nextline_is_empty == 0
|
||
" Insert double ornament
|
||
let nextline_len = len(nextline)
|
||
" Unfortunately this line borks undo history
|
||
normal! 2"_dd
|
||
if curline =~ '^\s*$'
|
||
" Current line consists of only white characters. Try to find last
|
||
" used ornament
|
||
let last_double_ornament = search('\(\%^\|\n\s*\n\|\%^\s*\n\)\s*'.s:vst_headdef.'\s*\n.\{-}\n\s*\2\s*\n' , 'bWn') + 2
|
||
if last_double_ornament == 3 && getline(1) =~ '^\s*$' && getline(2) !~ '^\s*$'
|
||
let last_double_ornament = 4
|
||
endif
|
||
if last_double_ornament == 2
|
||
let character = '='
|
||
else
|
||
let character = matchstr(getline(last_double_ornament), '^\s*\zs.\ze')
|
||
endif
|
||
endif
|
||
if len(curline) == 0
|
||
let correction = 0
|
||
else
|
||
let correction = 1
|
||
endif
|
||
if nextline_len < 3
|
||
let ornament_len = 3
|
||
else
|
||
let ornament_len = nextline_len
|
||
endif
|
||
let ornament = repeat(character, ornament_len)
|
||
return ornament."\n".nextline."\n".ornament."\n"
|
||
else
|
||
return ''
|
||
endif
|
||
|
||
return ''
|
||
|
||
endfunction
|
||
" }}}
|
||
" VST_RotateOrnaments: rotate characters in ornaments {{{
|
||
" headers
|
||
function! VST_RotateOrnaments()
|
||
" HEADDEF:
|
||
let s:vst_headdef = '\(=\{3,}\|+\{3,}\|\*\{3,}\|\^\{3,}\|%\{3,}\|\$\{3,}\|#\{3,}\|@\{3,}\|;\{3,}\|"\{3,}\|\.\{3,}\|,\{3,}\|`\{3,}\|\~\{3,}\|-\{3,}\|!\{3,}\|(\{3,}\|)\{3,}\|:\{3,}\|_\{3,}\|&\{3,}\|}\{3,}\|{\{3,}\||\{3,}\|?\{3,}\|<\{3,}\|>\{3,}\|\\\{3,}\|\[\{3,}\|\]\{3,}\|\/\{3,}\|''\{3,}\)'
|
||
let s:vst_headchars2 = '\(=\|+\|\*\|\^\|%\|\$\|#\|@\|;\|"\|\.\|,\|`\|\~\|-\|!\|(\|)\|:\|_\|&\|}\|{\||\|?\|<\|>\|\\\|\[\|\]\|\/\|''\)'
|
||
" Make sure we are in position to perform any actions
|
||
" This is more general regexp, could match several
|
||
if getline('.') !~ '^\s*'.s:vst_headdef.'\s*$'
|
||
return 0
|
||
endif
|
||
|
||
" Get situation: double/single ornament, transition
|
||
let prevline = getline(line('.')-1)
|
||
let nextline = getline(line('.')+1)
|
||
|
||
if prevline =~ '^\s*$'
|
||
let prevline_is_empty = 1
|
||
else
|
||
let prevline_is_empty = 0
|
||
endif
|
||
|
||
if nextline =~ '^\s*$'
|
||
let nextline_is_empty = 1
|
||
else
|
||
let nextline_is_empty = 0
|
||
endif
|
||
|
||
if !exists("g:vst_headers")
|
||
call input('No knowledge about headers, run :Vst head')
|
||
return 0
|
||
endif
|
||
|
||
if nextline_is_empty == 1 && prevline_is_empty == 0
|
||
" Single ornament
|
||
let a = 0
|
||
endif
|
||
" Make sure we have data about headers. Note: updating of data will be
|
||
" done manually or updated at the end
|
||
endfunction
|
||
" }}}
|
||
" Auxiliary mappings
|
||
inoremap <silent> <C-B>o <C-R>=VST_Ornaments()<CR>
|
||
"noremap <silent> <C-B>o <C-R>=VST_RotateOrnaments()<CR>
|
||
endfunction
|
||
" vim:fdm=marker:ff=unix:noet:ts=4:sw=4:nowrap
|