" 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 " " 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
 (::) {{{
	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 () {{{
	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 
 (::) {{{
	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, '', 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, '', i+1)
					else
						if g:paras[i] =~ '^\s*::\s*$'
							call insert(g:paras, '', i+1)
						else
							call insert(g:paras, '', 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 =~? '\(\'
					let title = name
					let firstpar = ''
				else
					let g:paras[i] = divindent.''
					let title = substitute(tolower(medtype), '^.', '\U\0', '') 
				endif

				let title = divindent.''.title.''

				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 = ''
					endif
					let imagepart = address."\n\n"
				else
					let imagepart = "\n\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.'\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.'\n'.indent.'[\1]\n'.indent.'', '')
			let firstpar = matchstr(g:paras[i], '\zs.*')
			let firstpar = substitute(firstpar, '\(^\|\n\)\s\+', '\n', 'g')
			let firstpar = VST_Structure(split(firstpar, "\n"))
			let g:paras[i] = substitute(g:paras[i], '\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.'\n'.indent.'['.k.']\n'.indent.'', '')
			let firstpar = matchstr(g:paras[i], '\zs.*')
			let firstpar = substitute(firstpar, '\(^\|\n\)\s\+', '\n', 'g')
			let firstpar = VST_Structure(split(firstpar, "\n"))
			let g:paras[i] = substitute(g:paras[i], '\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.'\n'.indent.'['.k.']\n'.indent.'', '')
			let firstpar = matchstr(g:paras[i], '\zs.*')
			let firstpar = substitute(firstpar, '\(^\|\n\)\s\+', '\n', 'g')
			let firstpar = VST_Structure(split(firstpar, "\n"))
			let g:paras[i] = substitute(g:paras[i], '\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.'\n'.indent.'['.label.']\n'.indent.'', '')
			let firstpar = matchstr(g:paras[i], '\zs.*')
			let firstpar = substitute(firstpar, '\(^\|\n\)\s\+', '\n', 'g')
			let firstpar = VST_Structure(split(firstpar, "\n"))
			let g:paras[i] = substitute(g:paras[i], '\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] = ''.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.''
			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.''
			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.''
			let title = name
			if title != ''
				let title = divindent.''.title.''
			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.''
			let title = name
			if title != ''
				let title = divindent.''.title.''
			else
				let title = ''
			endif

			if subtitle != ''
				let title .= "\n".''.subtitle.''
			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.''
			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.'', '')
			" }}}
			elseif medtype == 'unknown'
			" Unknown multi element div {{{
			let indent = repeat(' ', g:pindent[i])
			let g:paras[i] = indent.''.g:paras[i]
			" }}}
			else
				let g:paras[i] = divindent.''
				let title = 'Unknown'
				let title = divindent.''.title.''
				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]).'', 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]).'', j)
						endif
					else
						call insert(g:paras, repeat(' ', g:pindent[j]).'', 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 (
) {{{ 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\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 () {{{ 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.''."\n".newind.'', 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]).'', 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 (
) {{{ 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".''.defterm[1].''."\n".defterm[2].''."\n".defterm[2] let g:paras[i] = defpart.VST_Structure(defpar) endif let i += 1 endwhile endif " }}} " Prepare quoted literal paragraphs (:: ' \."\n".g:paras[i]."\n".'' else let g:paras[i] = ''."\n".g:paras[i] \."\n".'' 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.''."\n".newind.'', 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]).'', 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\2\3\n\1\n\1', '') let g:paras[i] = substitute(g:paras[i], '\n\(\s*\)\(--\|-\|/\|:\|+\)\(\S.\{-}\) ', '\n\1\2\3\n\1\n\1', 'g') let g:paras[i] = substitute(g:paras[i], '$', '', '') 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*:', '', '') let parlines[j] = substitute(parlines[j], '\(vim\)\@', '') let parlines[j] .= ''."\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:', 'class="field fdedication">Dedication','') let parlines[j] = substitute(parlines[j], 'class="field">Abstract:', 'class="field fabstract">Abstract','') let j += 1 endfor let g:paras[i] = join(parlines, "\n") let g:paras[i] = ''.g:paras[i] let g:paras[i] = substitute(g:paras[i], '\(Address:\)\(.\{-}\)', '\=submatch(1)."".substitute(submatch(2), "\\(^\\|\\n\\)\\s\\+", "\\n", "g").""','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] .= '' 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] = ''.substitute(g:paras[i], '^\s*\.\. 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] = ''.substitute(g:paras[i], '\s*\.\. rubric::', '', '').'' else let g:paras[i] = ''.substitute(g:paras[i], '\s*\.\. 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.''."\n".newind.'', 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]).'', 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] = ''.join(elements, "\n") 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]).''.repeat(' ' , g:pindent[j]).'', 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]).'', 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] = ''.join(elements, "\n") 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".''."\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 = ''.matchstr(g:paras[i], '::\s*\zs.\{-}\ze\(\n\|$\)')."<\/vim:p>\n" else let toc = "Contents<\/vim:p>\n" endif let toc .= "\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).''.stitle.'' let toc .= tocli."\n" endif let j += 1 endwhile let toc .= "<\/vim:ul class=\"toc\">\n" 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.*$', '', '') let g:paras[i] = substitute(g:paras[i], '^\s*', '\0', '') 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], '\n".VST_ProtectLiteral(g:paras[i])."\n" 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] = "\n".VST_ProtectLiteral(g:paras[i])."\n" endif let i += 1 endwhile endif " }}} " Create raw both paragraph (next after .. raw:: ) {{{ if string(g:ptype) =~ "'rawbothcontent'" let i = 0 while i < len(g:paras) if g:ptype[i] == 'rawbothcontent' let g:paras[i] = "\n".g:paras[i]."\n" 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', '') let g:paras[i] = substitute(g:paras[i], '^\(\s*\)\.\. latexonly::\s*\n', '\n\1\n', '') let g:paras[i] = substitute(g:paras[i], '^\(\s*\)\.\. latexonly::', '\n\1\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', '') let g:paras[i] = substitute(g:paras[i], '^\(\s*\)\.\. htmlonly::\s*\n', '\n\1\n', '') let g:paras[i] = substitute(g:paras[i], '^\(\s*\)\.\. htmlonly::', '\n\1\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]).'', 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]).'', 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] .= '' let usedthead = 1 endif if headfoot_counter > 1 && !exists('usedtfoot') let g:taba[-1][-1] .= '' 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 .= '' 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 .= "".g:taba[tl][cn]."" else let g:ctable .= "".g:taba[tl][cn]."" endif else let g:ctable .= "".g:taba[tl][cn]."" endif let tcc += k break else let k += 1 continue endif endwhile let tcc += 1 let cn += 1 endwhile let g:ctable .= "\n" 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 = "\n".g:ctable."" if headfoot_counter > 0 let ttable = substitute(ttable, ']*>', '\0\n', '') let ttable = substitute(ttable, '\(\)\(\n\)', '\2\n\1\n', '') endif if headfoot_counter == 2 let ttable = substitute(ttable, '<.vim:table>', '\n\0', '') let ttable = substitute(ttable, '\(\)\(\n\)', '\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]).''."\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])."\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])."\n".g:paras[i] let g:paras[i] .= "\n".repeat(' ', g:pindent[i])."\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] = '\n" " insert thead at the beginning if usethead > 0 let g:paras[i] .= "\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\n" let usedthead = 1 continue endif if usethead > 1 && exists("usedthead") && join(row, '') =~ '^\(-vst-thfelem-\)\+$' let g:paras[i] .= "\n\n" unlet usedthead let usedtfoot = 1 continue endif let g:paras[i] .= ''.join(row, '').''."\n" endfor if exists("usedtfoot") unlet usedtfoot let g:paras[i] .= "\n\n" endif unlet! usedthead unlet! usedtfoot unlet! usethead let g:paras[i] .= '' 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])."\n".g:paras[i] else let class = VST_AddClass(i,1, ' ', '') let g:paras[i] = "\n".repeat(' ', g:pindent[i])."\n".g:paras[i] endif let g:paras[i] .= "\n".repeat(' ', g:pindent[i])."\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*]*>') 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, '.\{-}', '', '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, '\_s\{-}', '', 'g') " Remove li to embed lists let file = substitute(file, '\(\_s\{-}\_.\{-}\_s*\_s*\_s*\_s*', '', 'g') let file = substitute(file, '\_s*\_s*', '', 'g') let file = substitute(file, '', '', 'g') " Removing redundant \n let file = substitute(file, '\_s*', '\n\n', 'g') let file = substitute(file, '\n\n\n\(\s*\)', '', 'g') " Remove double :: at the end of paragraphs indicating code in next. let file = substitute(file, '::\(\_s*\)', ':\1', 'g') " Remove double :: when it was the only element after list indicator let file = substitute(file, '\s*:', '', 'g') " Remove empty pre paragraphs let file = substitute(file, ']\{-}>\n', '', 'g') " Remove links created inside of image src let file = substitute(file, '<\(vim:\)\?img\([^>]\{-}\)src="\([^<]*\)"', \ '<\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\(\)', '\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 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 .= '' 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 ', '\n
', '')
		else
			let @z = substitute(@z, '.*', '\n
', '')
		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] .= '['.k.']'
		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\{-}\)]_', '[\1]', '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*|\( *\)', '\="-vst-new-line-".repeat(" ", len(submatch(1)))', 'g')
	let par = substitute(par, '^\s*|\( *\)', '\="-vst-new-line-".repeat(" ", len(submatch(1)))', 'g')
	let par .= "\n"
	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)
	" \ -> 
	" \-	   ->  
	"
	" To escape backslash, use backslash:
	" \\*, \\, \\-
	
	" Remove single escaping backslash before letters and digits which can form
	" lists enumerators:
	let par = substitute(par, '\\\@
	let par = substitute(par, '\\\@ 0
		let par = ''.a:text.''
	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\+\)]$', '\0', '')
		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, "[-  '\"([{]\\@<=`\<\\(.\\{-1,}\\)\>`__[\\]<\\-  '\")}>/\\:\\.,;!?]\\@=", '\="".VST_ProtectLiteral(submatch(1)).""', 'g')
		let par = substitute(par, "[-  '\"([{]\\@<=`\\([^[:space:] `]\\)\\([^`]\\{-}\\) \<\\(.\\{-1,}\\)\>`__[\\]<\\-  '\")}>/\\:\\.,;!?]\\@=", '\="".submatch(1).submatch(2).""', 'g')
		" Multi word anon hyperlink (enclosed in backticks)
		let par = substitute(par, "[-  '\"([{]\\@<=`\\([^[:space:] `]\\)\\([^`]\\{-}\\)`__[\\]<\\-  '\")}>/\\:\\.,;!?]\\@=", '\="".submatch(1).submatch(2).""', 'g')
		" One word anon hyperlink
		let par = substitute(par, "[-  '\"([{]\\@<=\\([[:alnum:]._-]\\{-2,}\\)__[\\]<\\-  '\")}>/\\:\\.,;!?]\\@=", '\1', 'g')
		let par = substitute(par, "[-  '\"([{]\\@<=\\(\\k\\{-1,}\\)__[\\]<\\-  '\")}>/\\:\\.,;!?]\\@=", '\1', 'g')
	endif
	" Embedded hyperlinks
	let par = substitute(par, "[-  '\"([{]\\@<=`\<\\([^`]\\{-1,}\\)\>`_[\\]<\\-  '\")}>/\\:\\.,;!?]\\@=", '\="".VST_ProtectLiteral(submatch(1)).""', 'g')
	let par = substitute(par, "[-  '\"([{]\\@<=`\\([^[:space:] `]\\)\\([^`]\\{-}\\) \<\\(.\\{-1,}\\)\>`_[\\]<\\-  '\")}>/\\:\\.,;!?]\\@=", '\="".submatch(1).submatch(2).""', 'g')
	" Multi word hyperlink (enclosed in backticks)
	let par = substitute(par, "[-  '\"([{]\\@<=`\\([^[:space:] `]\\)\\([^`]\\{-}\\)`_[\\]<\\-  '\")}>/\\:\\.,;!?]\\@=", '\="".submatch(1).submatch(2).""', 'g')
	" One word hyperlink
	let par = substitute(par, "[-  '\"([{]\\@<=\\([[:alnum:]._-]\\{-2,}\\)_[\\]<\\-  '\")}>/\\:\\.,;!?]\\@=", '\1', 'g')
	let par = substitute(par, "[-  '\"([{]\\@<=\\(\\k\\{-1,}\\)_[\\]<\\-  '\")}>/\\:\\.,;!?]\\@=", '\1', '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 = ''
			endif
			let para = address.nl."".nl.""
		else
			let para = "\n".nl
		endif
	else
		let para = ''
	endif
	if a:full == 1
		return "\n".para."\n"
	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.']_', '['.k.']', '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, '\\\@ ]\\)", '\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, "[-  '\"([{~]\\@<=\\*\\* \\@/\\:\\.,;!?]\\@=", '\1', 'g')
	"" *emph*
	let par = substitute(par, "[-  '\"([{~]\\@<=\\* \\@/\\\:.,;!?]\\@=", '\1', 'g')
	"" ``literal`` ( like), ``code``, Note: space after :space: is
	" nonbreaking space, not included into :space:
	let par = substitute(par, "[-  '\"([{~]\\@<=``\\([^[:space:] ]\\)\\(.\\{-}\\)``[\\]<\\-  '\")}>/\\\:.,;!?]\\@=", '\="".VST_ProtectLiteral(submatch(1).submatch(2)).""', '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 = ''.replace.''
			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, "[-  `'\"([{]\\@<=:sub:`\\([^`]\\{-1,}\\)`[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	let par = substitute(par, "[-  `'\"([{]\\@<=`\\([^`]\\{-1,}\\)`:sub:[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	let par = substitute(par, "[-  `'\"([{]\\@<=:subscript:`\\([^`]\\{-1,}\\)`[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	let par = substitute(par, "[-  `'\"([{]\\@<=`\\([^`]\\{-1,}\\)`:subscript:[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	" :sup:`text` and `text`:sup:
	let par = substitute(par, "[-  `'\"([{]\\@<=:sup:`\\([^`]\\{-1,}\\)`[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	let par = substitute(par, "[-  `'\"([{]\\@<=`\\([^`]\\{-1,}\\)`:sup:[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	let par = substitute(par, "[-  `'\"([{]\\@<=:superscript:`\\([^`]\\{-1,}\\)`[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	let par = substitute(par, "[-  `'\"([{]\\@<=`\\([^`]\\{-1,}\\)`:superscript:[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	" :strong:`text` and `text`:strong:
	let par = substitute(par, "[-  `'\"([{]\\@<=:strong:`\\([^`]\\{-1,}\\)`[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	let par = substitute(par, "[-  `'\"([{]\\@<=`\\([^`]\\{-1,}\\)`:strong:[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	" :emphasis:`text` and `text`:emphasis:
	let par = substitute(par, "[-  `'\"([{]\\@<=:emphasis:`\\([^`]\\{-1,}\\)`[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	let par = substitute(par, "[-  `'\"([{]\\@<=`\\([^`]\\{-1,}\\)`:emphasis:[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	" :literal:`text` and `text`:literal:
	let par = substitute(par, "[-  `'\"([{]\\@<=:literal:`\\([^`]\\{-1,}\\)`[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	let par = substitute(par, "[-  `'\"([{]\\@<=`\\([^`]\\{-1,}\\)`:literal:[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	" :big:`text` and `text`:big:
	let par = substitute(par, "[-  `'\"([{]\\@<=:big:`\\([^`]\\{-1,}\\)`[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	let par = substitute(par, "[-  `'\"([{]\\@<=`\\([^`]\\{-1,}\\)`:big:[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	" :small:`text` and `text`:small:
	let par = substitute(par, "[-  `'\"([{]\\@<=:small:`\\([^`]\\{-1,}\\)`[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	let par = substitute(par, "[-  `'\"([{]\\@<=`\\([^`]\\{-1,}\\)`:small:[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	" :title-reference:, :title:, :t:
	let par = substitute(par, "[-  `'\"([{]\\@<=:title-reference:`\\([^`]\\{-1,}\\)`[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	let par = substitute(par, "[-  `'\"([{]\\@<=:title:`\\([^`]\\{-1,}\\)`[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	let par = substitute(par, "[-  `'\"([{]\\@<=:t:`\\([^`]\\{-1,}\\)`[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	let par = substitute(par, "[-  `'\"([{]\\@<=`\\([^`]\\{-1,}\\)`:title-reference:[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	let par = substitute(par, "[-  `'\"([{]\\@<=`\\([^`]\\{-1,}\\)`:title:[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	let par = substitute(par, "[-  `'\"([{]\\@<=`\\([^`]\\{-1,}\\)`:t:[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	" any other role
	let par = substitute(par, "[-  `'\"([{]\\@<=:\\(\\S\\+\\):`\\([^`]\\{-1,}\\)`[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\=VST_ExtraRoles(submatch(1), submatch(2))', 'g')
	let par = substitute(par, "[-  `'\"([{]\\@<=`\\([^`]\\{-1,}\\)`:\\(\\S\\+\\):[\\]\\-  '\")}<>/\\\:.,;!?]\\@=", '\=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], "[-  '\"([{;]\\@<=`\\([^[:space:] `]\\)\\(.\\{-}\\)`[`\\]<\\-  '\")}>/\\:\\.,;!?]\\@=", '\1\2', 'g')
	else
		for i in range(len(split_file))

			if i == 0
				let split_file[i] = substitute(split_file[i], "[- '\"([{;]\\@<=`\\([^[:space:]`]\\)\\(.\\{-}\\)`[`\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '\1\2', '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:] `]\\)\\([^`]\\{-}\\)`[`\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '\1\2', 'g')
				elseif role =~ '^sup\(erscript\)\?$'
					let split_file[i] = substitute(split_file[i], "[- '\"([{;]\\@<=`\\([^[:space:] `]\\)\\([^`]\\{-}\\)`[`\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '\1\2', 'g')
				elseif role =~ '^sub\(script\)\?$'
					let split_file[i] = substitute(split_file[i], "[- '\"([{;]\\@<=`\\([^[:space:] `]\\)\\([^`]\\{-}\\)`[`\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '\1\2', 'g')
				elseif role =~ '^strong$'
					let split_file[i] = substitute(split_file[i], "[- '\"([{;]\\@<=`\\([^[:space:] `]\\)\\([^`]\\{-}\\)`[`\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '\1\2', 'g')
				elseif role =~ '^emphasis$'
					let split_file[i] = substitute(split_file[i], "[- '\"([{;]\\@<=`\\([^[:space:] `]\\)\\([^`]\\{-}\\)`[`\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '\1\2', 'g')
				elseif role =~ '^literal$'
					let split_file[i] = substitute(split_file[i], "[- '\"([{;]\\@<=`\\([^[:space:] `]\\)\\([^`]\\{-}\\)`[`\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '\1\2', 'g')
				elseif role =~ '^big$'
					let split_file[i] = substitute(split_file[i], "[- '\"([{;]\\@<=`\\([^[:space:] `]\\)\\([^`]\\{-}\\)`[`\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '\1\2', 'g')
				elseif role =~ '^small$'
					let split_file[i] = substitute(split_file[i], "[- '\"([{;]\\@<=`\\([^[:space:] `]\\)\\([^`]\\{-}\\)`[`\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '\1\2', 'g')
				else
					let role = VST_IdMaker(role)
					let split_file[i] = substitute(split_file[i], "[- '\"([{;]\\@<=`\\([^[:space:] `]\\)\\([^`]\\{-}\\)`[`\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '\1\2', '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 .
" 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./%&@#:;?=_-]\+\)>\(`_\)\@!', '\="\<".VST_ProtectLiteral(submatch(1))."\>"', 'g')
	let par = substitute(par, '<\(s\?ftp://[a-zA-Z0-9./%&#@:;?=_-]\+\)>\(`_\)\@!', '\="\<".VST_ProtectLiteral(submatch(1))."\>"', 'g')
	let par = substitute(par, '<mailto:\([a-zA-Z0-9@&#.;?=_-]\+\)>\(`_\)\@!', '\="\<".VST_ProtectLiteral(submatch(1))."\>"', 'g')

	let par = substitute(par, '\(href="\|<\)\@".VST_ProtectLiteral(submatch(0)).""', 'g')
	let par = substitute(par, '\(href="\|<\)\@".VST_ProtectLiteral(submatch(0)).""', 'g')
	let par = substitute(par, '\(href="\|<\)\@".VST_ProtectLiteral(submatch(2)).""', 'g')

	" Remove doubled links caused by http regexps.
	let par = substitute(par, '\(\)\1', '\1', 'g')
	let par = substitute(par, '', '', '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, '\([.?!;,]\+\)', '\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  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:] `]\\)\\(.\\{-}\\)`[\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '\1\2', 'g')
	let par = substitute(par, "[- '\"([{]\\@<=_\\([[:alnum:]._-]\\{-2,}\\)[\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '\1', 'g')
	let par = substitute(par, "[- '\"([{]\\@<=_\\(\\k\\{-1,}\\)[\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '\1', '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:
"   )  
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, '\"' ]\\)", '\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:] ]\)__\(\k*\)__\([[:punct:][:space:] ]\?\)', '\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, '_', '_', 'g')
		" Sometimes regexps are catching \` as link. Remove such glitches
		let file = substitute(file, '\\`', '\\`', '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, '\[\zs\d\+\ze\]')
			let content = matchstr(fn, '\zs.\{-}\ze\_s*')
			let g:vst_footnotedb[number] = content
			let fn = strpart(fn, 2)
		endwhile
		let fn = file
		while stridx(fn, '\[\zs\k\+\ze\]')
			let content = matchstr(fn, '\zs.\{-}\ze\_s*')
			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 = ''
		endif

		if g:vst_css_default == '' && g:vst_css_user != ''
			let css = ''
			let 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 = ''."\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 = ''."\n"
			else
				let css = "\n"
			endif
			let 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 = '\n"
		endif
		if has_key(g:vst_fielddb, 'title')
			let metatitle = '\n"
		endif
		if has_key(g:vst_fielddb, 'keywords')
			let metakeywords = '\n"
		endif
		if has_key(g:vst_fielddb, 'subject')
			let metasubject = '\n"
		endif
		if has_key(g:vst_fielddb, 'date')
			if g:vst_fielddb['date'] != 'NONE'
				let metadate = '\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 = ''."\n"
			elseif key =~ '^description \(lang\|scheme\|dir\)'
				let item = substitute(key, 'description \(lang\|scheme\|dir\)=\(.*\)', 'name="description" \1="\2", '')
				let element = ''."\n"
			else
				let element = ''."\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*\_s*', '', '')
				let s5foot = substitute(s5foot, '\_s*\_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 = ''
					\.''."\n"
					\.''."\n"
					\.''."\n"
					\.''."\n"
					\.''."\n"
					\.''."\n"
					\.''."\n"
					\.''."\n"
					\.''."\n"
					\.''."\n"
					\.''."\n"
					\.''."\n"
					\.''."\n"
			let s5body = ''
					\.'
'."\n" \.'
'."\n" \.'
'."\n" \.''."\n" \.''."\n" \.'
'."\n" \.'
' let s5body2 = "
\n" else let s5body = '' let s5head = '' let s5body2 = '' endif " }}} let metainfo .= metadata if file =~ ']*start="' let g:zzz = 1 let doctype = \ ''."\n" "\ ' '."\n" else let doctype = \ ''."\n" "\ ''."\n" endif let header = \ doctype \.''."\n" \.''."\n" \.''."\n" \.''.htmltitle.''."\n" \.''."\n" \.metainfo."\n" \.css."\n" \.s5head."\n" \.''."\n" \.''."\n" let closing = ''."\n".'' let file = header."\n".s5body."\n".file."\n".s5body2."\n".closing let file = substitute(file, '\)_', '\1', 'g') " let file = substitute(file, '\(\[#\]
\)_', '\1', 'g') " Create comment tags let file = substitute(file, '', ' -->', 'g') let file = substitute(file, '', '', '\n\\tableofcontents', '') " Replace new line tags let file = substitute(file, '\n\s*\s*\n', '\n\n', "g") let file = substitute(file, '', '\\\\', "g") " Title let file = substitute(file, '\_s*\(.\{-}\)', '\\title{\1}\n\\maketitle', "g") " Sections let file = substitute(file, '', '\\hypertarget{\1}{}\n\\section{', "g") let file = substitute(file, '', '\\hypertarget{\1}{}\n\\subsection{', "g") let file = substitute(file, '', '\\hypertarget{\1}{}\n\\subsubsection{', "g") let file = substitute(file, '', '\\hypertarget{\1}{}\n\\paragraph{', "g") let file = substitute(file, '', '\\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, '', '% Begin rawlatex', "g") let file = substitute(file, '<.vim:rawlatex>', '% End rawlatex', "g") " And the same for latexonly let file = substitute(file, '', '% Begin rawlatex', "g") let file = substitute(file, '<.vim:latexonly>', '% End rawlatex', "g") " And the same for rawboth let file = substitute(file, '', '% Begin rawlatex', "g") let file = substitute(file, '<.vim:rawboth>', '% End rawlatex', "g") " Lists let file = substitute(file, '', '\\item ', 'g') let file = substitute(file, '<.vim:li>', "", "g") let file = substitute(file, '', '\\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, '', '\\begin{enumerate}[label=\\alph*.,start=\1]', "g") let file = substitute(file, '', '\\begin{enumerate}[label=\\Alph*.,start=\1]', "g") let file = substitute(file, '', '\\begin{enumerate}[label=\\roman*.,start=\1]', "g") let file = substitute(file, '', '\\begin{enumerate}[label=\\Roman*.,start=\1]', "g") let file = substitute(file, '', '\\begin{enumerate}[label=\\arabic*.,start=\1]', "g") let file = substitute(file, '', '\\begin{enumerate}[label=\\arabic*.]', "g") let listings = 'enumitem' else let file = substitute(file, '', '\\begin{enumerate}[1.]', "g") let listings = 'enumerate' endif let file = substitute(file, '<.vim:ol>', '\\end{enumerate}', "g") " Field lists let file = substitute(file, '\(.\{-}\)', '\\item[\1]', 'g') let file = substitute(file, '", '\\end{deflist}', 'g') " Option lists let file = substitute(file, '', '\\begin{optlist}{longoptionslist}\n', 'g') let file = substitute(file, '\(.\{-}\)', '\\item[\1]', 'g') let file = substitute(file, '\(.\{-}\)', '\\item[\1]', 'g') let file = substitute(file, '', '', 'g') let file = substitute(file, '', '', 'g') let file = substitute(file, "", '\\end{optlist}', 'g') " Definition lists let file = substitute(file, '', '\\begin{deflist}{iii}', 'g') let file = substitute(file, '\(.\{-}\)', '\\item[\1]', 'g') let file = substitute(file, '', '', 'g') let file = substitute(file, '', '', 'g') "let file = substitute(file, "", '\\end{deflist}', 'g') " " Rubric let file = substitute(file, '', '\\rubric{ ', "g") let file = substitute(file, "", ' }', "g") " Pull-quote let file = substitute(file, '', '\\begin{pullquote}', "g") let file = substitute(file, "", '\\end{pullquote}', "g") " Blockquote let file = substitute(file, "", '\\begin{quotation}', "g") let file = substitute(file, "", '\\end{quotation}', "g") " Text styles let file = substitute(file, '', '\\emph{', "g") let file = substitute(file, "", "}", "g") let file = substitute(file, '', '\\textbf{', "g") let file = substitute(file, "", "}", "g") let file = substitute(file, '', '\\texttt{', "g") let file = substitute(file, "", "}", "g") " Tables let file = substitute(file, '', '\\setlongtables\n\\begin{center}\n\\begin{longtable}[c]{\1coln\2}\\hline\n', "g") let file = substitute(file, "", '', "g") let file = substitute(file, "", '\\endhead', "g") let file = substitute(file, "", '', "g") let file = substitute(file, "", '', "g") let file = substitute(file, "", '\\end{longtable}\n\\end{center}', "g") let file = substitute(file, '\n\?', '', "g") let file = substitute(file, '', ' \& ', "g") let file = substitute(file, "", ' \\\\ \\hline', "g") let file = substitute(file, '\n\?\(.\{-}\)\_s*', '\n\\multicolumn{\1}{|p{0.\2\\textwidth}|}{\3}', "g") let file = substitute(file, '\(.\{-}\)\_s*', ' \& \\multicolumn{\1}{p{0.\2\\textwidth}|}{\3}', "g") let file = substitute(file, "", '', "g") " Line " \transition allows for easy change of transition display, eg. for " fancy graphics let file = substitute(file, "", '\\transition', "g") " Comment let file = substitute(file, "\(.\{-}\)', '\\href{\2}{\3}', 'g') let file = substitute(file, '\(.\{-}\)', '\\hypertarget{\1}{\2}', 'g') " Subscript, superscript let file = substitute(file, '\(.\{-}\)', '\\subs{\1}', 'g') let file = substitute(file, '\(.\{-}\)', '\\sups{\1}', 'g') " Fix address special field let file = substitute(file, '\(.\{-}\)', '\1', 'g') " Replace unknown with pre elements in frame let file = substitute(file, '', 'Unknown element\n', 'g') let file = substitute(file, '', '', 'g') " Title-reference role () let file = substitute(file, '', '\\emph{', 'g') let file = substitute(file, '', '}', 'g') " Class big, small let file = substitute(file, '', '{\\small ', 'g') let file = substitute(file, '', '}', 'g') " Figure let file = substitute(file, '', '\\begin{center}\n\\begin{minipage}{0.6\\textwidth}', 'g') let file = substitute(file, '', '\\end{minipage}\n\\end{center}', 'g') " Create ghost commands for custom block directives let file = substitute(file, '', '\\vst\1{', 'g') let file = substitute(file, '', '}', 'g') " Create ghost commands for custom container directives let file = substitute(file, '', '\\vst\1{', 'g') let file = substitute(file, '', '}', 'g') " Topic let file = substitute(file, '', '\\hfill\\begin{minipage}{0.9\\textwidth}', 'g') let file = substitute(file, '', '\\end{minipage}', 'g') " Sidebar let file = substitute(file, '', '\\hfill\\begin{minipage}{0.9\\textwidth}', 'g') let file = substitute(file, '', '\\end{minipage}', 'g') " Divs let file = substitute(file, '', '\\begin{center}\n\\fbox{\\begin{minipage}{0.8\\textwidth}', 'g') let file = substitute(file, '', '\\end{minipage}}\n\\end{center}', 'g') " Div titles ( was already replaced) let file = substitute(file, '\(.\{-}\)}', '\\textbf{\\sffamily\\large \1}\n\\vspace{2mm}', 'g') " Remove rest of vim:span " let file = substitute(file, '', '\\emph{', 'g') let file = substitute(file, '', '\\vst\1{', 'g') " Replace empty vim:p tags when hypertargets let file = substitute(file, '', '\\hypertarget{\1}{}', "g") " Ignore all other 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>', '\=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 {{{ silent call cursor(1,1) while search('+'.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* 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\|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/ /\~/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 o =VST_Ornaments() "noremap o =VST_RotateOrnaments() endfunction " vim:fdm=marker:ff=unix:noet:ts=4:sw=4:nowrap