" Vim reStructured Text " (c) Mikolaj Machowski 2005 " Author: Mikolaj Machowski ( mikmach AT wp DOT pl ) " Last Change: 6 Sep 2005 " Version: 1.0-beta15 " Modify by Edward G.J. Lee to use LaTeX CJK environment. 25 Nov 2005. " The default font is `cwmu'(UTF8 encoding) and no bookmarks. " License: " Copyright (C) 2005 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 {{{ " " Installation: Put this file into your plugin directory " Usage: :Vst [ {format} ] " where {format} is format of exported file. Only html " is supported at the moment. Without argument default " setting (html) will be used. " New file will be opened without name in new buffer. " " Note: This script relies on indentation of elements. You " should set it to at least 4. " " VST requires Vim7 if v:version < 700 finish endif if &compatible == 1 set nocompatible endif " Initiate some variables " 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].'/vst/' endif if !exists("g:vst_user_css") let g:vst_user_css = '' endif if !exists("g:vst_add_css") let g:vst_add_css = '' endif if !exists("g:vst_external_css") let g:vst_external_css = '' 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 " Prevent multiple loading of VST, uncomment before final release. "if exists('b:vst_loaded') " finish "endif "let b:vst_loaded = 1 " " }}} " Command :Vst " command! -nargs=? -complete=custom,VST_Args Vst call VST_Export() command! -nargs=? -complete=custom,VST_Args Vsti call VST_InstantWrapper() " VST_Args: Command line completion for :Vst command {{{ function! VST_Args(A, C, P) let args = "html,tex,latex,pdf,toc,head,fold,link,slink,rep,srep,preproc,help,rest" return substitute(args, ',', '\n', 'g') endfunction " }}} " Menus {{{ if has("gui_running") menu VreST.Export\ to\ HTML :Vst html menu VreST.Export\ to\ LaTeX :Vst tex menu VreST.Export\ to\ PDF :Vst pdf menu VreST.Export\ to\ reST :Vst rest menu VreST.Fold :Vst fold menu VreST.Headers :Vst head menu VreST.TOC :Vst toc menu VreST.Help :Vst help inoremenu VreST.Export\ to\ HTML :Vst html inoremenu VreST.Export\ to\ LaTeX :Vst tex inoremenu VreST.Export\ to\ PDF :Vst pdf inoremenu VreST.Export\ to\ reST :Vst rest inoremenu VreST.Fold :Vst fold inoremenu VreST.Headers :Vst head inoremenu VreST.TOC :Vst toc inoremenu VreST.Help :Vst help endif " }}} " 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. function! VST_InstantWrapper(format) let temp_write_export = g:vst_write_export let g:vst_write_export = 1 call VST_Export(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. 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 {{{ for line in doc if line =~ '^\s*$' let ltype += ['blank'] elseif line =~ '^\s*\.\. 2html::' let ltype += ['2html'] elseif line =~ '^\s*\.\. [[|]\?\w\+:' " Names of most directives aren't important for header detection " Comment is potential error. let ltype += ['nonimp'] elseif line =~ '^\s*:.\{-1,}:\s\+' let ltype += ['field'] elseif line =~ '^\s*\(\d\+\|[a-zA-Z]\|[icvlxmICVLXM]\+\|#\)[\]:.)}]\s' " LISTDEF: let ltype += ['oli'] elseif line =~ '^\s*[*+-]\s' let ltype += ['uli'] elseif line =~ '^\s*\(--\|-\|/\|:\|+\)\S.\{-}\( \|$\)' && line !~ '^\s*\(--\s\|:\S\+:`\)' let ltype += ['optlist'] elseif line =~ '^\s*::\s*$' let ltype += ['emptypre'] elseif line =~ '^\s*+[=-]\{3,}' let ltype += ['table'] else let ltype += ['p'] endif " Check indentation of each line let lindent += [strlen(matchstr(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) " }}} " 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*\ze'
					let initind = strlen(matchstr(plines[-1], '^\s*\zs[+*-]\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: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') 

				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")

		call VST_CreateDBs(fntext)

		"let g: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: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*[=+*^%$#@;".,`~-]\{3,}\s*\(\n\|$\)' && g:ptype[i] !~ 'table'
				let parlines = split(g:paras[i], '\n')
				if parlines[1] =~ '^\s*[=+*^%$#@;".,`~-]\{3,}\s*$'
					let double = ' '
				elseif parlines[0] == parlines[2] && parlines[0] =~ '^\s*[=+*^%$#@;".,`~-]\{3,}\s*$' 
					let double = 'd'
					call remove(parlines, 0)
				endif
				let lchar = matchstr(parlines[1], '.\ze\s*$').double
				if lchar =~ '[=+*^%$#@;".,`~-]'
					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)

" Auxiliary functions: {{{
" Unicode2Char:	  Return char according to hex code {{{
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
		exe line3
	endwhile

	" Restore settins
	let @z = z_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)
	let cpar = a:parnumber - 1
	" Escaping of special characters
	if g:ptype[cpar] == 'class'
		let name = matchstr(g:paras[cpar], '^\s*\.\. class::\s*\zs.*\ze\s*$')
		let name = VST_IdMaker(name)
		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
	while i < len(g:anonhlinkdb) 
		if g:anonhlinkdb[i] =~ '_\s*$'
			let href = g:anonhlinkdb[i]
			let title = matchstr(href, '\(\.\. __ :\|__\)\s*\(`\?\)\zs.*\ze\2_\s*$')
			while href =~ '_\s*$'
				" If ends in _ it is probably indirect link, process it.
				if has_key(g:hlinkdb, title) && g:hlinkdb[title] != ''
					let href = escape(g:hlinkdb[title], '&\~')
				else
					let href = '#l'.tolower(VST_IdMaker(title))
				endif
			endwhile
		else
			let href = matchstr(g:anonhlinkdb[i], '^\s*\(\.\. __:\|__\)\s*\zs.*')
		endif
		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
		let par = substitute(par, "[- '\"([{]\\@<=`\<\\(.\\{-1,}\\)\>`__[\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '\1', 'g')
		let par = substitute(par, "[- '\"([{]\\@<=`[[:space:]]\\@/\\:\\.,;!?]\\@=", '\1', 'g')
		" Multi word anon hyperlink (enclosed in backticks)
		let par = substitute(par, "[- '\"([{]\\@<=`[[:space:]]\\@/\\:\\.,;!?]\\@=", '\="".submatch(1).""', '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,}\\)\>`_[\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '\1', 'g')
	let par = substitute(par, "[- '\"([{]\\@<=`[[:space:]]\\@/\\:\\.,;!?]\\@=", '\1', 'g')
	" Multi word hyperlink (enclosed in backticks)
	let par = substitute(par, "[- '\"([{]\\@<=`[[:punct:][:space:]]\\@<=\\(.\\{-1,}\\)`_[\\]<\\- '\")}>/\\:\\.,;!?]\\@=", '\="".submatch(1).""', '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:hlinkdb, title) && g:hlinkdb[title] != ''
				let href = escape(g: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 = matchstr(href, '^\s*\(`\?\)\zs.*\ze\1_\s*$')
						if has_key(g:hlinkdb, shref) && g:hlinkdb[shref] != ''
							let href = escape(g:hlinkdb[shref], '&\~')
						else
							let href = '#l'.tolower(VST_IdMaker(shref))
						endif
					endwhile
				else
					let href = escape(g: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]' || link[ix] == '-'
		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(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:hlinkdb, title) && g:hlinkdb[title] != ''
					let href = escape(g: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 src = 'src="'.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
	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
	return para
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')
	" Take care about double asterisk inside of (), {}, [], '', ""
	let par = substitute(par, "\\([['\"({<]\\)\\*\\*\\([])}>\"' ]\\)", '\1\*\*\2', 'g')
	" Take care about backticks inside of (), {}, [], '', ""
	let par = substitute(par, "\\([['\"({<]\\)``\\([])}>\"' ]\\)", '\1\`\`\2', 'g')
	"" **strong**
	let par = substitute(par, "[- '\"([{]\\@<=\\*\\* \\@/\\:\\.,;!?]\\@=", '\1', 'g')
	"" *emph*
	let par = substitute(par, "[- '\"([{]\\@<=\\* \\@/\\\:.,;!?]\\@=", '\1', 'g')
	"" ``literal`` ( like)
	let par = substitute(par, "[- '\"([{]\\@<=`` \\@/\\\:.,;!?]\\@=", '\="".VST_ProtectLiteral(submatch(1)).""', '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, '[', '\[', 'g')
	let par = substitute(par, '_', '\_', 'g')
	let par = substitute(par, '|', '\|', 'g')
	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:replacedb)
		let replace = g:replacedb[key]
		"let replace = escape(g: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 {{{
			" 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.*')
			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: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:hlinkdb[tolower(proceed)] = g:hlinkdb[key]
				endif
			endif
			let par = substitute(par, '|'.key.'|', 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: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:hlinkdb[tolower(proceed)] = g: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 =~ '^\w\+::'
			" Don't perform replacement of reST style replacement directives.
			" This would 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')
	" :sup:`text` and `text`:sup:
	let par = substitute(par, "[- `'\"([{]\\@<=:sup:`\\(.\\{-1,}\\)`[\\]\\- '\")}<>/\\\:.,;!?]\\@=", '\1', 'g')
	let par = substitute(par, "[- `'\"([{]\\@<=`\\(.\\{-1,}\\)`:sup:[\\]\\- '\")}<>/\\\:.,;!?]\\@=", '\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')
	" 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_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 punctless
	endfunction

	let par = a:text
	" Handle standalone links in <> brackets.
	let par = substitute(par, '<\(https\?://[a-zA-Z0-9./%&@#;?=_-]*\)>\(`_\)\@!', '\="\<".submatch(1)."\>"', 'g')
	let par = substitute(par, '<\(s\?ftp://[a-zA-Z0-9./%&#@;?=_-]*\)>\(`_\)\@!', '\="\<".submatch(1)."\>"', 'g')
	let par = substitute(par, '<mailto:\([a-zA-Z0-9@&#.;?=_-]*\)>\(`_\)\@!', '\="\<".submatch(1)."\>"', 'g')

	let par = substitute(par, '\(href="\|<\)\@".submatch(0).""', 'g')
	let par = substitute(par, '\(href="\|<\)\@".submatch(0).""', 'g')
	let par = substitute(par, '\(href="\|<\)\@".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', '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
" }}}
" }}}

let doc = a:text

	" Initiate arrays and variables {{{
	let ltype = []
	let lindent = []

	if exists("g:paras")
		let g:paras_rez = g:paras
		let g:paras = []
	else
		let g:paras = []
	endif
	if exists("g:ptype")
		let g:ptype_rez = g:ptype
		let g:ptype = []
	else
		let g:ptype = []
	endif
	if exists("g:pindent")
		let g:pindent_rez = g:pindent
		let g:pindent = []
	else
		let g:pindent = []
	endif
	if exists("g:plinen")
		let g:plinen_rez = g:plinen
		let g:plinen = []
	else
		let g:plinen = []
	endif

	let toc = ''
	" }}}
	" Detect and create line types {{{
	for line in range(len(doc))
		if line == len(doc) - 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*\.\. 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*\.\. raw::\s*latex\s*html'
			let ltype += ['rawboth']
		elseif doc[line] =~ '^\s*\.\. raw::\s*html\s*latex'
			let ltype += ['rawboth']
		elseif doc[line] =~ '^\s*\.\. raw:: latex'
			let ltype += ['rawlatex']
		elseif doc[line] =~ '^\s*\.\. raw:: html'
			let ltype += ['rawhtml']
		elseif doc[line] =~ '^\s*\.\. role::'
			let ltype += ['role']
		elseif doc[line] =~ '^\s*\.\. class::'
			let ltype += ['class']
		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:
			let ltype += ['oli']
		elseif doc[line] =~ '^\s*[*+-]\s'
			let ltype += ['uli']
		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\+:`\)'
			let ltype += ['optlist']
		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 empty paragraphs to make them really empty. {{{
	let i = 0
	while i < len(g:paras)
		if g:ptype[i] == 'empty'
			let g:paras[i] = ''
		endif
		let i += 1
	endwhile
	" }}}
	" Loop through rawlatex paragraphs correct next paragraphs. {{{
	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
	" }}}
	" Loop through rawboth paragraphs correct next paragraphs. {{{
	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
	" }}}
	" Loop through rawhtml paragraphs correct next paragraphs. {{{
	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
	" }}}
	" 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
				let g:pindent1 = strlen(matchstr(parlines[0], '^\s*'))
				let g:pindent2 = strlen(matchstr(parlines[1], '^\s*'))
				if g:pindent2 > g:pindent1
					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: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 i = 0
	let g:autofootnotes = []
	while i < len(g:paras)
		if g:ptype[i] == 'autofootnote'
			let g:autofootnotes += [g:paras[i]]
		endif
		let i += 1
	endwhile
	" }}}
	" 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*'
					let initind = strlen(matchstr(plines[-1], '^\s*\zs[+*-]\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: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') 

				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")

		" 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.  {{{
	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:replacedb[from] = into

		endif
		let i += 1
	endwhile
" }}}
	" 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] =~ '-autofootnote$'
				let medtype = 'autofootnote'
			elseif g:ptype[i] =~ '-citation$'
				let medtype = 'citation'
			elseif g:ptype[i] =~ '-labelfootnote$'
				let medtype = 'labelfootnote'
			elseif g:ptype[i] =~ '-pullquote$'
				let medtype = 'pullquote'
			elseif g:ptype[i] =~ '-comment$'
				let medtype = 'comment'
			elseif g:ptype[i] =~ '-figure$'
				let medtype = 'figure'
			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] =~ '-compound$'
				let medtype = 'compound'
			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 g:paras[i] = g:paras[i]."\n".title."\n".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(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:hlinkdb, title) && g:hlinkdb[title] != ''
								let target = escape(g: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="'.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 g:paras[i] .= ''
			" }}}
			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 g:paras[i] .= ''
			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 g:paras[i] .= ''
			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 g:paras[i] .= ''
			" }}}
			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.'', '')
"			let g:paras[i] = 
"				\ substitute(g:paras[i], '^\s*\.\. pull-quote::', indent.'\n'.indent.'', '')
"			let g:paras[i] .= "\n".repeat(' ', indent).''
			" }}}
			elseif medtype == 'comment'
			" Multi element comment {{{
			let indent = repeat(' ', g:pindent[i])
			let g:paras[i] = ''.g:paras[i]
			" }}}
			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
			let title = divindent.''.title.''
			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
			let title = divindent.''.title.''

			if subtitle != ''
				let title .= "\n".''.subtitle.''
			endif
			let firstpar = ''

			let g:paras[i] .= "\n".title
			" }}}
			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 medtype = 'block'

			" }}}
			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.''
			" }}}
			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 g:paras[i] = g:paras[i]."\n".title."\n".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)
					else
						call insert(g:paras, repeat(' ', g:pindent[j]).'', j)
					endif
					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*$' 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*[=+*^%$#@;".,`~-]\{3,}\s*\(\n\|$\)' && g:ptype[i] !~ 'table' let parlines = split(g:paras[i], '\n') if parlines[1] =~ '^\s*[=+*^%$#@;".,`~-]\{3,}\s*$' let double = ' ' elseif parlines[0] == parlines[2] && parlines[0] =~ '^\s*[=+*^%$#@;".,`~-]\{3,}\s*$' let double = 'd' call remove(parlines, 0) endif let lchar = matchstr(parlines[1], '.\ze\s*$').double if lchar =~ '[=+*^%$#@;".,`~-]' 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 " }}} " Formatting " Detect and pre-prepare definition list (
) {{{ let i = 0 while i < len(g:paras) if g:ptype[i] == 'dl' let parlines = split(g:paras[i], '\n') let g:pindent2 = strlen(matchstr(parlines[1], '^\s*')) let g:paras[i] = VST_SpecCharacter(g:paras[i]) let g:paras[i] = substitute(g:paras[i], '^\(.\{-}\n\)\(\s*\)', '\n\1\n\2\n\2', '') let g:paras[i] = substitute(g:paras[i], '$', '\n'.repeat(' ', g:pindent2).'\n', '') endif let i += 1 endwhile " }}} " Create dl paragraph {{{ 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 inserted paragraph 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 " }}} " 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 " }}} " Create option list paragraph {{{ 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*\(--\|-\|/\|:\|+\)\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 " }}} " Create field list {{{ 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: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 " }}} " Parse meta paragraphs (.. meta::) {{{ " Loop creates database, it will be parsed in exports accordingly to its " syntax 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:metadb[mkey] = mcontent endif let j += 1 endfor let g:paras[i] = '' endif let i += 1 endwhile " }}} " Create image paragraphs () {{{ 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 " }}} " Create comment paragraph - comment (.. 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 " }}} " Create document title (.. 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 " }}} " Create rubric paragraph - comment (.. rubric::) {{{ let i = 0 while i < len(g:paras) if g:ptype[i] == 'rubric' if g:paras[i] =~ ':class:' let g:as = g:paras[i] 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 " }}} " Create ul paragraph {{{ 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*') let listindent = strlen(matchstr(g:paras[i], '^\s*[+*-]\s*')) if style =~ '+' let ustyle = 'square' elseif style =~ '\*' let ustyle = 'circle' elseif style =~ '-' 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 let g:paras[i] = VST_SpecCharacter(g:paras[i]) let g:paras[i] = substitute(g:paras[i], '^\(\s*\)[+*-]', '\1', '') let g:paras[i] = substitute(g:paras[i], '\n\(\s*\)[+*-]', '\n\1', 'g') let g:paras[i] .= '' endif let i += 1 endwhile " }}} " Create ol paragraph {{{ 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 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 let g:paras[i] = VST_SpecCharacter(g:paras[i]) " LISTDEF: let g:paras[i] = substitute(g:paras[i], '^\(\s*\)\(\d\+\|[icdvlmxICDVLMX]\+\|[a-zA-Z]\|#\)[\]:.)}]\s*', '\1', '') let g:paras[i] = substitute(g:paras[i], '\n\(\s*\)\(\d\+\|[icdvlmxICDVLMX]\+\|[a-zA-Z]\|#\)[\]:.)}]\s*', '\n\1', 'g') let g:paras[i] .= '' endif let i += 1 endwhile " }}} " Create internal anchors - intlink (.. _blah blah:){{{ let i = 0 while i < len(g:paras) if g:ptype[i] == 'intlink' let title = tolower(matchstr(g:paras[i], '^\s*\.\. _\zs.\{-}\ze:')) let title = VST_IdMaker(title) let g:paras[i] = "\n".''."\n" endif let i += 1 endwhile " }}} " Create table of contents - toc (.. contents::) {{{ let i = 0 while i < len(g:paras) if g:ptype[i] == 'toc' let g:thd = matchstr(g:paras[i], ':\s*\zs.*') 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 g:vst_tocdepth = depth - 1 let g:paras[i] = substitute(g:paras[i], '^\(.*\)\n.*', '\1', '') endif if matchstr(g:paras[i], '\n\s*:class:') != '' let tocclass = VST_IdMaker(matchstr(g:paras[i], '\n\s*:class:\s*\zs\w\+\ze')) else let tocclass = 'toc' endif if matchstr(g:paras[i], '::\s*\zs.\{-}\ze$') != '' " Alternative title of toc let g:bum = 1 let toc = ''.matchstr(g:paras[i], '::\s*\zs.\{-}\ze$')."<\/vim:span>\n" else let toc = "Contents<\/vim:span>\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 " }}} " Create h[1-6] paragraphs {{{ let i = 0 while i < len(g:paras) if g:ptype[i] =~ '^h\d' 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 aname = '\n' let g:paras[i] = substitute(g:paras[i], '^.*\zs\n.*$', '', '') let g:paras[i] = substitute(g:paras[i], '^\s*', '\0'.aname, '') endif let i += 1 endwhile " }}} " Create verse paragraphs ("| ") {{{ 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".g:paras[i]."\n" endif let i += 1 endwhile " }}} " Create raw HTML paragraph (next after .. raw:: html) {{{ let i = 0 while i < len(g:paras) if g:ptype[i] == 'rawhtmlcontent' let g:paras[i] = "\n".g:paras[i]."\n" endif let i += 1 endwhile " }}} " Create raw both paragraph (next after .. raw:: ) {{{ 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 " }}} " Create LaTeX only paragraph - latexonly (.. 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 " }}} " Create HTML only paragraph - htmlonly (.. 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 " }}} " Check and embrace paragraphs in blockquote tags {{{ 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 " }}} " Create 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 = [] let s = 0 for col in g:tclen let g:sizes += [g:tclen[s]*90/g:sum] let s += 1 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 " }}} " 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*[=+*^%$#@;".,`~-]\{3,}\s*$', '', '') let g:paras[i] .= "\n".repeat(' ', g:pindent[i])."\n" endif let i += 1 endwhile " }}} " Doctest paragraphs {{{ 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 " }}} " Simple table paragraphs {{{ 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 sizes += [col*90/total_width] 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 " }}} " 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] !~ '\n' 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 {{{ let i = 0 while i < len(g:paras) if g:ptype[i] == 'rawlatex' || g:ptype[i] == 'rawhtml' || g:ptype[i] == 'rawboth' if g:paras[i] =~ ':file:' let file = matchstr(g:paras[i], ':file:\s*\zs.*') let g:paras[i] = '-vst-raw-file-placeholder:'.file else let g:paras[i] = '' endif endif let i += 1 endwhile " }}} " 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] == 'emptypre' let g:paras[i] = '' elseif g:ptype[i] == 'role' let g:paras[i] = '' elseif g:ptype[i] == '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 can exists in paragraph. " BIG time 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') " Glueing together dl let file = substitute(file, '\_s\{-}', '', 'g') " Remove li to embed lists let file = substitute(file, '\(\_s\{-}\_.\{-}\_s*\_s*\_s*', '', 'g') let file = substitute(file, '', '', 'g') let file = substitute(file, '\_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 empty pre paragraphs let file = substitute(file, ']\{-}>\n', '', 'g') " }}} " Restore structure from temporary variables (tables processing) {{{ if exists("g:paras_rez") let g:paras = g:paras_rez endif if exists("g:ptype_rez") let g:ptype = g:ptype_rez endif if exists("g:pindent_rez") let g:pindent = g:pindent_rez endif if exists("g:plinen_rez") let g:plinen = g:plinen_rez endif " }}} return file " End of VST_Structure endfunction function! VST_Export(format) " {{{ " 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*$' let itemmargin = valmargin - strlen(key) if itemmargin < 1 let table .= key."\n".repeat(' ', valmargin).dict[key]."\n" else let table .= key.repeat(' ', itemmargin).dict[key]."\n" endif endif endfor else for key in sort(keys(dict)) if dict[key] !~ '^\s*$' let itemmargin = valmargin - strlen(key) if itemmargin < 1 let table .= key."\n".repeat(' ', valmargin).dict[key]."\n" else let table .= key.repeat(' ', itemmargin).dict[key]."\n" endif endif endfor endif return 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 if a:sinfo >= line && a:sinfo < nextsection let title = '[[[ '.title.' ]]]' endif let title = repeat(' ', matchstr(level, '.$')-1).title 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) let dbtable = filter(deepcopy(a:table), 'v:val =~ "^\\s*\\.\\. \\(_\\||\\|role\\)"') for line in dbtable " Remove common prefix let line = substitute(line, '^\s*\.\. ', '', '') if line =~ '^_' " Hyperlink database let title = tolower(matchstr(line, '^_\zs.\{-}\ze:')) let url = matchstr(line, '^_.\{-}:\s*\zs.*') if url =~ '@' && url !~ '^http\|^ftp' let url = 'mailto:'.url endif if title != '' && title != '_' let g:hlinkdb[title] = url endif elseif line =~ '^role' let g:roledb += [matchstr(line, '^role:: \zs.*\ze\s*$')] 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: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 = repeat(' ', 2*g:fold[text]).text 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 {{{ function! VST_ColNumbers(numbers) let widths = split(a:numbers, '+') let col_string = '' for width in widths let col_string .= '' endfor return col_string 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(1, '$') " Include external files before anything else will be done {{{ " if len(filter(copy(text), 'v:val =~ "^\\s*\\.\\. \\(header\\|include\\footer\\)::"')) > 0 " Tried to do in one regexp, but it alternative was sometimes working, sometimes not 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::"')) 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[2] =~ '^<' && include[2] =~ '>$' let include[2] = matchstr(include[2], '^.\zs.*\ze.$') let include[2] = g:vst_included.'/'.include[2] endif if filereadable(include[2]) let included = readfile(include[2]) if include[1] == 'header' let text[i] = '' let included += [''] call extend(text, included, 0) let i -= len(included) elseif include[1] == 'footer' let text[i] = '' let included = [''] + included call extend(text, included) else let text[i] = '' call extend(text, included, i+1) endif elseif include[2] == 'vstfooter' || include[2] == '' 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[1] =~ 'header\|footer' && include[2] !~ '{filename}' " Second part of above condition is hack to allow for doc " compilation if include[1] == 'footer' let text[i] = '' let included = ['.. block:: vstfooter','', ' ------------------------', \ '', ' '.include[2], ''] call extend(text, included) elseif include[1] == 'header' let text[i] = '' let included = ['.. block:: vstfooter','', ' '.include[2], \ '', ' ------------------------', ''] call extend(text, included, 0) let i -= len(included) endif endif endif let i += 1 endwhile endif " }}} " Preprocess text to ... {{{ " But not for preproc export: if format !~ '^pre' let i = 0 " We need to keep track of real lines. Create hash with keys of virtual " lines created by preprocessing and real lines let g:vst_reallines = {} let rl_correction = 0 let g:text = len(text) while i < len(text)-1 " Remove control characters, some Emacs deviation let text[i] = substitute(text[i], '[[:cntrl:]]', '', 'g') " 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 (findent + 3) <= sindent 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' " || text[i+1] =~ '^\s*\(\d\+\|[a-zA-Z]\)[\]:.)}]\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 " Connect multiline link definitions if text[i] =~ '^\s*\(\.\. _\|__ \)' if text[i+1] !~ '^\s*\(\.\. _\|__ \)' && text[i+1] !~ '^\s*$' let findent = strlen(matchstr(text[i], '^\s*')) let sindent = strlen(matchstr(text[i+1], '^\s*')) if (findent + 3) <= sindent let text[i] = substitute(text[i], '\s\+$', '', '') \.substitute(text[i+1], '^\s\+', '', '') call remove(text, i+1) let rl_correction += 1 " Turn counter down to process more than 2 lines let i -= 1 endif 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:hlinkdb = {} let g:replacedb = {} let g:roledb = [] " }}} let g:anonhlinkdb = filter(copy(text), 'v:val =~ "^\\s*\\(\\.\\. __:\\|__ \\)"') if ',pdf,xml,html,latex,tex,' =~ ','.format.',' let g:footnotedb = {} let g:citationdb = {} let g:fielddb = {} let g: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, '') let i = 0 while i < len(lines) if lines[i] =~ '_' " Escaping of corner cases let g:paras[i] = VST_SpecCharacter(g:paras[i]) " Take care about \` let lines[i] = substitute(lines[i], '\\\@\"' ]\\)", '\1\`\2', 'g') let lines[i] = substitute(lines[i], "\\([['\"({<]\\)_`\\([])}>\"' ]\\)", '\1_\`\2', 'g') " Take care about "``" let lines[i] = substitute(lines[i], '"``"', '-vst-quot-dbacktick-', 'g') " Take care about alone _ and __ let lines[i] = substitute(lines[i], ' _ ', ' \_ ', 'g') let lines[i] = substitute(lines[i], ' __ ', ' \_\_ ', 'g') " Take care about __ in programmer expressions __init__ like (shaky) let lines[i] = substitute(lines[i], '\([[:punct:][:space:]]\)__\(\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 "``" " Take care about " 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') " Restore ` and _ let lines[i] = substitute(lines[i], '`', '`', 'g') let lines[i] = substitute(lines[i], '_', '_', 'g') " Take care about "``" let lines[i] = substitute(lines[i], '-vst-quot-dbacktick-', '"``"', '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') let g:footnotedb[number] = content let fn = strpart(fn, 2) endwhile let fn = file while stridx(fn, '\[\zs\k\+\ze\]') let content = matchstr(fn, '\zs.\{-}\ze') let g:citationdb[label] = '['.label.'] '.content let fn = strpart(fn, 2) endwhile " }}} if len(g:anonhlinkdb) > 0 let file = VST_AnonHyperlink(file) endif " 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') " Figure out proper MIME charset from the 'encoding' option. {{{ if exists("g:vst_encoding") let encoding = g:vst_encoding else let encoding = &encoding 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 =~ '^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' " HTML export {{{ " 1. Header " 2. Encoding " 3. CSS " 4. Closing " let language = matchstr(v:lang, '.*\ze_') " CSS {{{ let internal_css = \ 'body { background-color: #fff ; margin: 0px 10% ; min-width: 720px ; font-family: sans-serif ; line-height: 140% }'."\n" \.'div.footnote { border-left: 1px solid #000 ; margin-left: 0em ; clear: both }'."\n" \.'div.ftext { position: relative ; margin-left: 50px }'."\n" \.'div.fnumber { float: left ; width: 40px ; padding: 0em ; margin-left: 0.5em ; margin-top: 0em }'."\n" \.'div.fnumber a { margin: 0px ; padding: 0px }'."\n" \.'div.ctext { position: relative ; margin-left: 100px }'."\n" \.'div.cnumber { float: left ; width: 90px ; padding: 0em ; margin-left: 0.5em ; margin-top: 0em }'."\n" \.'div.cnumber a { margin: 0px ; padding: 0px }'."\n" let internal_css .= \ 'div.tip { border: 2px solid #0d0 ; margin: 0.5em 2em 1em 2em ; margin-bottom: 1em ; padding: 0em 1em }'."\n" \.'div.warning, div.caution, div.danger, div.error { border: 2px solid #f00 ; margin: 0.5em 2em 1em 2em ; margin-bottom: 1em ; padding: 0em 1em }'."\n" \.'div.note, div.hint, div.important { border: 2px solid #000 ; margin: 0.5em 2em 1em 2em ; margin-bottom: 1em ; padding: 0em 1em }'."\n" \.'div.figure { display: block ; padding: 1em ; width: 400px ; clear: both}'."\n" \.'div.topic { margin: 2em }'."\n" \.'div.vstsidebar, div.sidebar { border: 2px solid #aaa ; background-color: #ffffee ; float: right ; width: 40% ; margin-left: 1em ; margin-right: -1em ; padding: 1em }'."\n" let internal_css .= \ 'span.strike { text-decoration: line-through }'."\n" \.'span.big { font-size: large }'."\n" \.'span.small { font-size: small }'."\n" \.'span.toc { font-size: large ; font-weight: 900 }'."\n" \.'span.notetitle { font-size: large ; font-weight: 900 ; font-family: sans-serif }'."\n" \.'p.notesubtitle { font-weight: 900 ; font-family: sans-serif }'."\n" \.'p.attribution { text-align: right ; font-style: italic }'."\n" \.'.vstright { float: right ; margin: 1em }'."\n" \.'.vstleft { float: left ; margin: 1em }'."\n" \.'.vstcenter { margin: 1em ; margin-left: auto ; margin-right: auto }'."\n" let internal_css .= \ 'blockquote.pull { font-size: large }'."\n" \.'p.rubric { font-size: large ; margin-left: 2em }'."\n" \.'dd.normal { margin-bottom: 0.5em }'."\n" \.'dt.option { float: left ; margin: 0em 0em 5px 2em ; padding: 0px ; font-family: monospace }'."\n" \.'dd.option { margin: 0px ; padding: 0px ; margin: 0em 0em 5px 10em ; text-indent: 0.5em }'."\n" \.'dd.option > p { margin: 0px }'."\n" \.'dd.normal > p { margin: 0px }'."\n" let internal_css .= \ 'table { border-collapse: collapse ; margin: 0.5em ; margin-left: 0em ; margin-right: 0em }'."\n" \.'thead, tfoot { text-align: center; font-weight: bold }'."\n" \.'td { border: 1px solid #000 ; padding: 0.25em ; _top: 0% ; vertical-align: top }'."\n" \.'table.vstbless td { border: 0px solid #000 ; padding: 0.25em ; _top: 0% ; vertical-align: top }'."\n" \.'td > p { margin: 0px }'."\n" \.'table.field { border: 0px solid #000 ; margin-left: 2em ; padding: 0.25em ; _top: 0% ; vertical-align: top }'."\n" \.'td.fkey { font-weight: 900 }'."\n" \.'td.fval { border: 0px solid #000 ; padding: 0.25em ; _top: 0% ; vertical-align: top }'."\n" \.'td.fkey { font-weight: 900 ; border: 0px solid #000 ; padding: 0.25em ; _top: 0% ; vertical-align: top }'."\n" \.'td.fdkey { text-align: center ; font-weight: 900 }'."\n" \.'td.fdval { text-align: center ; font-style: italic }'."\n" \.'td.fakey { text-align: center ; font-weight: 900 }'."\n" \.'td.faval { border: 0px solid #000 ; padding: 0.25em ; _top: 0% ; vertical-align: top }'."\n" let internal_css .= \ 'hr { width: 80% ; margin: 1.5em auto }'."\n" \.'h1 { text-align: center ; clear: both ; line-height: 120% }'."\n" \.'h2, h3, h4, h5, h6 { text-align: left ; margin-top: 1em ; clear: both ; line-height: 120% }'."\n" \.'h2 { counter-reset: section subsection subsubsection paragraph }'."\n" \.'h3 { counter-reset: subsection subsubsection paragraph }'."\n" \.'h4 { counter-reset: subsubsection paragraph }'."\n" \.'h5 { counter-reset: paragraph }'."\n" \.'p.subh1 { text-align: center ; font-size: 120% ; font-variant: small-caps }'."\n" \.'p.subh2, p.subh3, p.subh4, p.subh5, p.subh6 { text-align: left ; font-size: 120% ; font-variant: small-caps }'."\n" let internal_css .= \ 'h2:before { content: counter(chapter)" "; counter-increment: chapter }'."\n" \.'h3:before { content: counter(chapter)"."counter(section)" "; counter-increment: section }'."\n" \.'h4:before { content: counter(chapter)"."counter(section)"."counter(subsection)" "; counter-increment: subsection }'."\n" \.'h5:before { content: counter(chapter)"."counter(section)"."counter(subsection)"."counter(subsubsection)" "; counter-increment: subsubsection }'."\n" \.'h6:before { content: counter(chapter)"."counter(section)"."counter(subsection)"."counter(subsubsection)"."counter(paragraph)" "; counter-increment: paragraph}'."\n" let internal_css .= \ 'li.h1 { margin-left: 0em }'."\n" \.'li.h2 { margin-left: 1em ; counter-reset: lsection lsubsection lsubsubsection lparagraph }'."\n" \.'li.h3 { margin-left: 2em ; counter-reset: lsubsection lsubsubsection lparagraph }'."\n" \.'li.h4 { margin-left: 3em ; counter-reset: lsubsubsection lparagraph }'."\n" \.'li.h5 { margin-left: 4em ; counter-reset: lparagraph }'."\n" let internal_css .= \ 'li.h2:before { content: counter(lchapter)" "; counter-increment: lchapter }'."\n" \.'li.h3:before { content: counter(lchapter)"."counter(lsection)" "; counter-increment: lsection }'."\n" \.'li.h4:before { content: counter(lchapter)"."counter(lsection)"."counter(lsubsection)" "; counter-increment: lsubsection }'."\n" \.'li.h5:before { content: counter(lchapter)"."counter(lsection)"."counter(lsubsection)"."counter(lsubsubsection)" "; counter-increment: lsubsubsection }'."\n" \.'li.h6:before { content: counter(lchapter)"."counter(lsection)"."counter(lsubsection)"."counter(lsubsubsection)"."counter(lparagraph)" "; counter-increment: lparagraph}'."\n" \.'li.h6 { margin-left: 5em }'."\n" let internal_css .= \ 'ol, ul { margin-bottom: 0.5em ; margin-top: 0.5em }'."\n" \.'ol.loweralpha { list-style-type: lower-alpha }'."\n" \.'ol.upperalpha { list-style-type: upper-alpha }'."\n" \.'ol.lowerroman { list-style-type: lower-roman }'."\n" \.'ol.upperroman { list-style-type: upper-roman }'."\n" \.'ol.decimal { list-style-type: decimal }'."\n" \.'ul.square { list-style-type: square }'."\n" \.'ul.circle { list-style-type: circle }'."\n" \.'ul.disc { list-style-type: disc }'."\n" let internal_css .= \ 'li > p { margin: 0em }'."\n" \.'img { border: 1px solid #000 ; padding: 0em ; display: block ; margin: 1em ; margin-left: auto ; margin-right: auto }'."\n" \.'img.inline { border: 1px solid #000 ; padding: 0em ; margin: 0em ; display: inline }'."\n" \.'pre { background-color: #eee ; margin-left: 2em ; clear: both ; overflow: auto }'."\n" \.'div.unknown { font-family: monospace ; background-color: #fff ; margin: 1em ; padding: 1em ; clear: both ; border: 3px solid red}'."\n" \.'pre.quoted { background-color: #eee ; margin-left: 0em ; clear: both ; overflow: auto }'."\n" \.'pre.rawlatex { background-color: #ddd ; border: 1px solid #000 ; padding: 0.1em ; clear: both ; overflow: auto }'."\n" \.'pre.address { font-family: sans-serif ; display: inline ; margin: 0px ; background-color: #fff ; overflow: auto }'."\n" \.'span.target { text-decoration: underline }'."\n" \.'div.vstfooter hr { width: 100% ; margin: 0px ; margin-top: 0em }'."\n" \.'div.vstfooter p { margin: 0px }'."\n" " }}} let cssdone = 0 if g:vst_user_css != '' let css = ''."\n" let cssdone = 1 endif if g:vst_add_css != '' && cssdone == 0 let css .= ''."\n" let cssdone = 1 endif if g:vst_external_css != '' && cssdone == 0 if filereadable(g:vst_external_css) let usercss = readfile(g:vst_external_css) let vstcss = split(internal_css, '\n') let completecss = ['/* Vim reStructured Text CSS */', ''] \ + vstcss + ['', '/* User CSS */', ''] + usercss call writefile(completecss, 'vst-'.g:vst_external_css) let css = ''."\n" elseif g:vst_external_css == 'self' let completecss = ['/* Vim reStructured Text CSS */', ''] + split(internal_css, '\n') call writefile(completecss, "default.css") let css = ''."\n" else let css = ''."\n" endif endif if g:vst_external_css == '' && g:vst_add_css == '' && g:vst_user_css == '' let css = '' endif unlet! cssdone " META Info let metainfo = '' let metaauthor = '' let metatitle = '' let metasubject = '' let metakeywords = '' let metadate = '' if has_key(g:fielddb, 'author') let metaauthor = '\n" endif if has_key(g:fielddb, 'title') let metatitle = '\n" endif if has_key(g:fielddb, 'keywords') let metakeywords = '\n" endif if has_key(g:fielddb, 'subject') let metasubject = '\n" endif if has_key(g:fielddb, 'date') if g:fielddb['date'] != 'NONE' let metadate = '\n" endif endif let metainfo = metaauthor.metatitle.metakeywords.metasubject.metadate let metadata = '' for key in keys(g: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 let metainfo .= metadata if exists("g:vst_doc_title") let htmltitle = g:vst_doc_title elseif metasubject != '' let htmltitle = g:fielddb['subject'] else let htmltitle = expand("%") endif let header = \ ' '."\n" \.''."\n" \.''."\n" \.''."\n" \.''.htmltitle.''."\n" \.''."\n" \.metainfo."\n" \.css."\n" \.''."\n" \.''."\n" let closing = ''."\n".'' let file = header."\n".file."\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\\linespread{1.0}\\parskip=0ex\\selectfont\n\\tableofcontents\n\\linespread{1.382}\\parskip=1.382ex\\selectfont', '') " Title let file = substitute(file, '\_s*\(.\{-}\)', '\\title{\1}\n\\maketitle', "g") " Sections let file = substitute(file, '', '\\section{', "g") let file = substitute(file, '', '\\subsection{', "g") let file = substitute(file, '', '\\subsubsection{', "g") let file = substitute(file, '', '\\paragraph{', "g") let file = substitute(file, '', '\\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}\\itemsep=-1ex\\parskip=0pt', "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]\\itemsep=-1ex\\parskip=0pt', "g") let file = substitute(file, '', '\\begin{enumerate}[label=\\Alph*.,start=\1]\\itemsep=-1ex\\parskip=0pt', "g") let file = substitute(file, '', '\\begin{enumerate}[label=\\roman*.,start=\1]\\itemsep=-1ex\\parskip=0pt', "g") let file = substitute(file, '', '\\begin{enumerate}[label=\\Roman*.,start=\1]\\itemsep=-1ex\\parskip=0pt', "g") let file = substitute(file, '', '\\begin{enumerate}[label=\\arabic*.,start=\1]\\itemsep=-1ex\\parskip=0pt', "g") let file = substitute(file, '', '\\begin{enumerate}[label=\\arabic*.]\\itemsep=-1ex\\parskip=0pt', "g") let listings = 'enumitem' else let file = substitute(file, '', '\\begin{enumerate}[1.]\\itemsep=-1ex\\parskip=0pt', "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}{i}', '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, '', '{\large ', "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 " let file = substitute(file, "", '\\begin{center}\\rule{.8\\textwidth}{0.2pt}\\end{center}', "g") " \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') let file = substitute(file, '\(\\title{\)\(\\hypertarget{.\{-}}{}\)', '\2\n\1', 'g') let file = substitute(file, '\(\\section{\)\(\\hypertarget{.\{-}}{}\)', '\2\n\1', 'g') let file = substitute(file, '\(\\subsection{\)\(\\hypertarget{.\{-}}{}\)', '\2\n\1', 'g') let file = substitute(file, '\(\\subsubsection{\)\(\\hypertarget{.\{-}}{}\)', '\2\n\1', 'g') let file = substitute(file, '\(\\paragraph{\)\(\\hypertarget{.\{-}}{}\)', '\2\n\1', 'g') let file = substitute(file, '\(\\subparagraph{\)\(\\hypertarget{.\{-}}{}\)', '\2\n\1', 'g') let file = substitute(file, '\(\\subsubparagraph{\)\(\\hypertarget{.\{-}}{}\)', '\2\n\1', 'g') let file = substitute(file, '\(\\part{\)\(\\hypertarget{.\{-}}{}\)', '\2\n\1', 'g') let file = substitute(file, '\(\\chapter{\)\(\\hypertarget{.\{-}}{}\)', '\2\n\1', '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') " Class big, small let file = substitute(file, '', '\\emph{', 'g') let file = substitute(file, '', '}', 'g') let file = substitute(file, '', '{\\large ', 'g') let file = substitute(file, '', '{\\small ', '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') " Ignore block elements let file = substitute(file, '', '', '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') " Preamble {{{ let preamble = \ '\documentclass[11pt]{article}'."\n" \.'\usepackage[a4paper,margin=2.5cm,nohead]{geometry}'."\n" \.'\usepackage{CJK}'."\n" \.'\usepackage{'.listings."}\n" \.'\usepackage{graphicx}'."\n" \.'\usepackage{longtable}'."\n" \.'\usepackage{tabularx}'."\n" \.'\usepackage{amsmath}'."\n" \.countrysettings."\n" \.'\renewcommand\CJKglue{\hskip -0.3pt plus 0.08\baselineskip}'."\n" \.'\linespread{1.382}'."\n" \.'\renewcommand{\arraystretch}{1.2}'."\n" \.'\parindent=0pt'."\n" \.'\parskip=1.382ex'."\n" \.'\renewenvironment{quote}'."\n" \.' {\list{}{\topsep 1ex\parsep 0ex\setlength\leftmargin{1.5em}%'."\n" \.' \rightmargin\leftmargin}\item\relax\linespread{1.0}\small}%'."\n" \.' {\endlist}'."\n" \.'\let\oldfootnote\footnote'."\n" \.'\renewcommand\footnote[1]{\oldfootnote{\renewcommand\baselinestretch{1.0}%'."\n" \.'\large\footnotesize\ignorespaces#1}}'."\n" \.'\addtolength{\footnotesep}{3pt}'."\n" \.'\newenvironment{deflist}[1]{%'."\n" \.'\begin{list}{}'."\n" \.'{\renewcommand{\makelabel}[1]{\textbf{##1}\hfill}'."\n" \.'\settowidth{\labelwidth}{\textbf{#1}}'."\n" \.'\linespread{1.0}\parskip=0ex\parsep=0ex\selectfont'."\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" \.'\linespread{1.0}\parskip=0ex\parsep=0ex\selectfont'."\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}}}'."\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" \.userpreamble."\n" \.'\usepackage[CJKbookmarks,bookmarks=false,dvipdfm]{hyperref}'."\n" " Additional data {{{ let author = '' let data = '' if has_key(g:fielddb, 'author') let author = '\author{'.g:fielddb['author'].'}'."\n" endif if has_key(g:fielddb, 'date') if g:fielddb['date'] == 'NONE' let g:fielddb['date'] = '' endif let data = '\date{'.g:fielddb['date'].'}'."\n" else let data = '' endif " }}} " PDF Info {{{ let pdfinfo = '' let pdfauthor = '' let pdftitle = '' let pdfsubject = '' let pdfkeywords = '' if has_key(g:fielddb, 'author') let pdfauthor = 'pdfauthor={'.g:fielddb['author']."},\n" endif if has_key(g:fielddb, 'title') let pdftitle = 'pdftitle={'.g:fielddb['title']."},\n" endif if has_key(g:fielddb, 'keywords') let pdfkeywords = 'pdfkeywords={'.g:fielddb['keywords']."},\n" endif if has_key(g:fielddb, 'subject') let pdfsubject = 'pdfsubject={'.g:fielddb['subject']."}" endif for key in keys(g:metadb) if key =~ 'author' && pdfauthor == '' let pdfauthor = 'pdfauthor={'.g:metadb[key]."},\n" elseif key =~ 'title' && pdftitle == '' let pdftitle = 'pdftitle={'.g:metadb[key]."},\n" elseif key =~ 'keywords' && pdfkeywords == '' let pdfkeywords = 'pdfkeywords={'.g:metadb[key]."},\n" elseif key =~ 'subject' && pdfsubject == '' let pdfsubject = 'pdfsubject={'.g:metadb[key]."}" endif endfor if exists("g:vst_doc_title") let pdftitle = 'pdftitle={'.g:vst_doc_title."},\n" endif let pdfinfo = "\\hypersetup{\npdfcreator={VST, LaTeX, hyperref},\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 normal! gg 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 " Simple g/^\s*$/d removes also lines delimiting paragraphs... "silent exe line1.','.line2.'s/\n\n\s*&\s*\n\n/\r\&\r/ge' endwhile " }}} " Process {{{ silent normal! gg while search('+'.imagestring.'+e' silent normal! j endwhile " }}} " Processing preformatted text. {{{ " Not using verbatim because it is " in conflict with minipages silent normal! gg 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/\n\n\\item/\r\\item/ " 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/&\\#64;/@/ge silent %s/[/[/ge silent %s/&\\#91;/[/ge silent %s/\/\\/ge silent %s/&\\#92;/\\/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 " }}} " Insert raw files {{{ normal! gg while search('-vst-raw-file-placeholder:', 'bW') let file = matchstr(getline('.'), '-vst-raw-file-placeholder:\zs.*') silent s/.*//ge exe 'silent read '.file endwhile " }}} redraw! " 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' let file_tex = filename.'.tex' let file_dvi = filename.'.dvi' if !exists('g:vst_pdf_command') let g:vst_pdf_command = 'latex -interaction=nonstopmode' let g:vst_pdfx_command = 'dvipdfmx' endif silent exe 'write! '.file_tex silent exe "call system(\"".g:vst_pdf_command." '".file_tex."'\")" silent exe "call system(\"".g:vst_pdf_command." '".file_tex."'\")" if search('\\tableofcontents') silent exe "call system(\"".g:vst_pdf_command." '".file_tex."'\")" endif silent exe "call system(\"".g:vst_pdfx_command." '".file_dvi."'\")" 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("xpdf") let g:vst_pdf_viewer = "xpdf" elseif executable("kpdf") let g:vst_pdf_viewer = "kpdf" endif endif endif silent exe "call system(\"".g:vst_pdf_viewer." '".filename.".pdf'\")" endif else echomsg "Something went wrong, check TeX code or command settings." endif 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! '.filename.'.tex' endif normal! gg " }}} " Auxiliary commands {{{ elseif format =~ '^head' " Symbols for section titles {{{ call VST_Headers(text) unlet! b:vst_first_parsing echo VST_DictTable(g:vst_headers, 'Level', 'Symbol', 0) return '' " }}} 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 = [] while i < len(g:paras) if g:ptype[i] =~ '^h\d' call add(tocc, [g:ptype[i], g:paras[i], g:plinen[i]]) endif let i += 1 endwhile let g:tocc = tocc echo VST_TocTable(tocc, 'Nr', 'Title', 'Line', line) return '' " }}} elseif format =~ '^fold' " Folding {{{ call VST_Headers(text) unlet! b:vst_first_parsing let i = 0 let g:fold = {} function! VST_FoldExpr(lnum) let list = keys(g:fold) if string(list) =~? "'".escape(getline(a:lnum), '.*\[~&^$')."'" return '>1' else return '1' endif endfunction while i < len(g:paras) if g:ptype[i] =~ '^h\d' let fline = matchstr(g:paras[i], '^.\{-}\ze\n') let g:fold[fline] = strpart(g:ptype[i], 1)-1 endif let i += 1 endwhile setlocal foldmethod=expr setlocal foldexpr=VST_FoldExpr(v:lnum) setlocal foldtext=VST_FoldText() " Ancient fold systems (worth of preserving): {{{ " Full elastic folding, maybe useful on 10GHz beasts "function! VST_FoldExpr(lnum, fold) " let line = filter(copy(keys(a:fold)), 'v:val =~ "^'.getline(a:lnum).'$"') " if len(line) > 0 " return '>'.a:fold[line[0]] " else " return '=' " endif "endfunction " }}} " }}} elseif format =~ '^f\(block\|image\|figure\|sidebar\|compound\|topic\|rubric\|table\|tip\|note\|warning\|admonition\|include\|pull-quote\|class\|meta\|raw\|2html\)' " Folding by directive {{{ function! VST_FoldText() let text = getline(v:foldstart) let indent = '+'.v:folddashes return indent.repeat(' ', 15-len(indent)).text.' ' endfunction let directive = matchstr(format, '^f\zs.*') setlocal foldmethod=expr exe "setlocal foldexpr=getline(v:lnum)=~?'^\\\\s*\\\.\\\.\\\ ".directive."::'?'>1':1" 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 setlocal foldtext=VST_FoldText() " }}} elseif format =~ '^link' " Link table {{{ call VST_Headers(text) unlet! b:vst_first_parsing echo VST_DictTable(g:hlinkdb, 'Text', 'Link', 0) return '' " }}} elseif format =~ '^slink' " Sorted link table {{{ call VST_Headers(text) unlet! b:vst_first_parsing echo VST_DictTable(g:hlinkdb, 'Text', 'Link', 1) return '' " }}} elseif format =~ '^rep' " Replacement table {{{ call VST_Headers(text) unlet! b:vst_first_parsing echo VST_DictTable(g:replacedb, 'Symbol', 'Replacement', 0) return '' " }}} elseif format =~ '^srep' " Sorted replacement table {{{ call VST_Headers(text) unlet! b:vst_first_parsing echo VST_DictTable(g:replacedb, 'Symbol', 'Replacement', 1) return '' " }}} elseif format =~ '^help' " Help for commands {{{ echo \ "Help for VST commands\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" \." ---------------\n" \."fold - (re)create folds in file\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" return '' " }}} elseif format =~ '^pre' " Interpret all including commands and put them in file {{{ " Note: this is one level, does not work recursively. silent normal! ggdG let jtext = join(text, "\n") silent 0put =jtext normal! gg return '' " }}} " }}} endif endfunction " }}} " vim:fdm=marker:ff=unix:noet:ts=4:sw=4:nowrap