# Hey, Emacs, this is CoST (-*- Tcl -*-) script for TEI Lite to LaTeX conversion.

# $Id: script,v 1.160 2003/07/11 13:40:33 tobotras Exp $
#
# :
#
# - <label>    <list type='Gloss'>
#
# - FIXME:      LaTeX'a
#
# - FIXME: <BYLINE> ,      .
#
# Todo:
#
# - <CELL ROWS=...>
# -    
#
# - <BIBL> might be too russian-biased (WRT spaces, for example).
#

require TEItools.tcl

debug "starting..."

require textutil.tcl
require Simple.tcl
TEItoolsSetup "tex"
require TEItoolsTeX.tcl
require TEItoolsEPN.tcl

# Check for top level element. Top levels could be divisions, if so, 
# let's generate appropriate prologue an epilogue.

debug "searching top element..."

withNode doctree child el {
    # Only div# so far...
    switch -regexp "[query gi]" {
	"(DIV)|(DIV[0-9])" {
	    setprop subdocRoot "true"
	}
    }
}

debug "loading specification..."

specification translate {
    {element MILESTONE withattval UNIT BIGCAP} {
       prefix          "\\\\huge\\\\textbf{[query attval n]}"
    }
    {element MILESTONE withattval UNIT VERSE} {
       prefix          "\\\\raisebox\\\[.5ex\\\]{\\\\scriptsize [query attval n]}"
    }
    {element MILESTONE} {
	prefix		"\\\\begin{center}\\\\texttt{*~*~*}\\\\end{center}\n"
    }
    {element EPIGRAPH} {
	prefix		{\n\\hfill\\parbox\[t\]{0.5\\linewidth}\{}
	suffix		"\}\n"
    }
    {element BIBL within EPIGRAPH} {
	prefix		"\\\\begin{flushright}\n"
	suffix		"\n\\\\end{flushright}\n"
    }
    {element TEI.2} {
	prefix		{}
	suffix		"[latexFileFooter]"
    }
    {element TEIHEADER} {
	startAction {
	    global silence
	    set silence 1
	}
	endAction {
	    global silence
	    set silence 0
	}
	prefix		{}
	after		"[latexFileHeader]"
    }
    {element FRONT} {
	prefix		"[openFront]"
	suffix		"[closeFront]"
    }
    {element BACK} {
	prefix		"[openBack]"
	suffix		"[closeBack]"
    }
    {element DOCAUTHOR in TITLEPAGE in FRONT} {
	prefix		"[authorPrefix]"
	suffix		{\}\n}
    }
    {element BYLINE in TITLEPAGE in FRONT} {
	prefix		{}
	suffix		{}
	cdataFilter	null
    }
    {element TITLEPART within TITLEPAGE} {
	prefix		"[titlepartPrefix]"
	suffix		{\\mbox{}\}\n}
    }
    {element DOCAUTHOR in BYLINE in TITLEPAGE in FRONT} {
	prefix		"[authorPrefix]"
	suffix		{\}\n}
    }
    {element DOCDATE in TITLEPAGE in FRONT} {
       prefix          {\\renewcommand\{\\TEItoolsDate\}\{}
       suffix          {\}\n}
    }
    {element DOCIMPRINT in TITLEPAGE in FRONT} {
       prefix          "[imprintPrefix]"
	suffix		{\}\n}
    }
    {element TITLEPAGE in FRONT} {
	prefix		{}
	suffix		"\\n[TitlePage]\\n"
    }
    {element DIVGEN} {
	prefix		"[divGen]"
    }
    {element EG in NOTE} {
	startAction {
	    Error "<EG> cannot be used within <NOTE>. Substitute with <HI>."
	}
	prefix		{}
	suffix		{}
	cdataFilter	null
	sdataFilter	null
    }
    {element EG} {
	prefix		[openVerbatim]
	suffix		[closeVerbatim]
	cdataFilter	verbatimFilter
	sdataFilter	verbatimFilter
    }
    {element P within SP} {
	prefix		""
	suffix		""
    }
    {element P withattval REND eg} {
	prefix		{\n\\begin\{verbatim\}\n}
	suffix		{\n\\end\{verbatim\}\n}
	cdataFilter	verbatimFilter
	sdataFilter	verbatimFilter
    }
    {element P} {
	prefix		"[openParAlign]\\n{\\\\par [openRend][numberPara]"
	suffix		"[closeRend]\\n}[closeParAlign]\\n"
    }
    {elements "IDENT"} {
	prefix		"[openRend bold]"
	suffix		"[closeRend]"
    }
    {element CODE in XREF} {
	prefix		{}
	suffix		{}
	cdataFilter	null
	sdataFilter	null
    }
    {element CODE in HEAD in LIST} {
	#FIXME:  filteredContent  
	prefix		{}
	suffix		{}
	cdataFilter	null
	sdataFilter	null
    }
    {element CODE} {
	prefix		"[openRend bold,typewriter]"
	suffix		"[closeRend]"
	cdataFilter	typewriterCdataFilter
	sdataFilter	typewriterSdataFilter
    }
    {elements "TERM MENTIONED"} {
	prefix		"[openRend italic]"
	suffix		"[closeRend]"
    }
    {element SOCALLED} {
	prefix		"[openRend quoted]"
	suffix		"[closeRend]"
    }
    {element Q in HEAD in LIST} {
	#FIXME:  filteredContent  
	prefix		{}
	suffix		{}
	cdataFilter	null
	sdataFilter	null
    }
    {element Q within EG} {
	prefix		"\""
	suffix		"\""
    }
    {element Q} {
	prefix		"[openQuote]"
	suffix		"[closeRend]"
    }
    {element LIST} {
	prefix		"\\n[listHeader [typeVal]]\\n"
	suffix		"\\n[listFooter]\\n"
    }
    {element ITEM in LIST} {
	prefix		"[listItem][openRend {} nounderline]"
	suffix		"[closeRend]"
    }
    {element LABEL in LIST} {
	#was:	prefix		"\\n\\\\item\\[[localize cyr] [openRend sans,bold]"
	#	suffix		"[closeRend]\\] "
	prefix		"[listLabel][openRend sans,bold]"
	suffix		"[closeRend] "
	startAction {
	    withNode parent {
		if { "[typeVal]" != "gloss" } {
		    Error "<LABEL>s should only be used within <LIST TYPE='Gloss'>"
		}
	    }
	}
    }
    {elements "HI EMPH"} {
	prefix		"{[openRend italic]"
	suffix		"[closeRend]}"
    }
    {element XREF withattval TYPE URL} {
	prefix		[openHyperLink]
	suffix		[closeHyperLink]
	cdataFilter	xrefFilter
    }
    {element XREF} {
	prefix		"\\\\textit{[doXref]}"
	cdataFilter	null
    }
    {element LB within TABLE} {
	prefix		"\\\\newline{}"
    }
    {element LB within FIGURE} {
	prefix		""
	startAction {
	    Warning "LB within FIGURE ignored"
	}
    }
    {element LB} {
	prefix		"\\\\mbox{}\\\\\\\\\\\\relax{}"
    }
    {element PB} {
	prefix		"\\n\\\\clearpage\\n"
    }
    {element NOTE withattval PLACE SIDE} {
	prefix		"\\\\marginpar\{\\\\leftmargini=2mm\{\}\\\\leftmargini=3mm\{\}\\\\leftmarginiii=4mm\{\}"
	suffix		"\}"
    }
    {element NOTE withattval PLACE INLINE} {
	prefix		"({[openRend]\\\\endlinechar`\ \\\\ignorespaces "
	suffix		"\\\\unskip{}[closeRend]})"
	cdataFilter	inlineNoteFilter
    }
    {element NOTE withattval PLACE INTERLINE} {
	prefix		[openInterlineNote]
	suffix		[closeInterlineNote]
    }
    {element NOTE withattval PLACE INTERLINEAR} {
	prefix		[openInterlineNote]
	suffix		[closeInterlineNote]
    }
    {element NOTE withattval PLACE END} {
	prefix		"\\\\endnote{[openRend][localize cyr]"
	suffix		"[closeRend]}"
    }
    {element NOTE} {
	prefix		"\\\\footnote{[openRend][localize cyr]"
	suffix		"[closeRend]}"
    }
    {element KW} {
	prefix		"[openRend bold,typewriter]"
	suffix		"[closeRend]"
	cdataFilter	typewriterCdataFilter
	sdataFilter	typewriterSdataFilter
    }
    {element INDEX} {
	prefix		[doIndex]
	suffix		"\}"
    }
    {element GI} {
	prefix		"[openRend bold,typewriter]\\\\textless{}"
	suffix		"\\\\textgreater{}[closeRend]"
	cdataFilter	typewriterCdataFilter
	sdataFilter	typewriterSdataFilter
    }
    {elements "DIV DIV0 DIV1 DIV2 DIV3 DIV4 DIV5 DIV6 DIV7 DIV8"} {
	prefix		"\\n[startDivision]"
	suffix		"\\n[endDivision]"
    }
    {element HEAD in FIGURE} {
	prefix		"\\n\\\\renewcommand{\\\\TEItoolsFigCaption}{[openRend][localize cyr] "
	suffix		"[closeRend]}\\n"
    }
    {element HEAD in TABLE} {
	prefix		"[openTableCaption]"
	suffix		"{}[closeRend][tableLabel]\}\\\\mbox{}\\\\\\\\\n"
    }
    {element HEAD in LIST} {
	prefix		""
	suffix		""
	cdataFilter	null
	sdataFilter	null
    }
    {element HEAD withattval TYPE SHORT} {
	prefix		""
	suffix		""
	cdataFilter	null
	sdataFilter	null
    }
    {element HEAD in DIV1} {
	prefix		"[startHead \"\\\\[sectionName 1][shortHead]{[openRend][localize cyr]\"]"
	suffix		"{}[closeRend]}[labelDivision]"
    }
    {element HEAD in DIV2} {
	prefix		"[startHead \"\\\\[sectionName 2][shortHead]{[openRend][localize cyr]\"]"
	suffix		"{}[closeRend]}[labelDivision]"
    }
    {element HEAD in DIV3} {
	prefix		"[startHead \"\\\\[sectionName 3][shortHead]{[openRend][localize cyr]\"]"
	suffix		"{}[closeRend]}[labelDivision]"
    }
    {element HEAD in DIV4} {
	prefix		"[startHead \"\\\\[sectionName 4][shortHead]{[openRend][localize cyr]\"]"
	suffix		"{}[closeRend]}[labelDivision]"
    }
    {element HEAD in DIV5} {
	prefix		"[startHead \"\\\\[sectionName 5][shortHead]{[openRend][localize cyr]\"]"
	suffix		"{}[closeRend]}[labelDivision]"
    }
    {element HEAD in DIV6} {
	prefix		"[startHead \"\\\\[sectionName 6][shortHead]{[openRend][localize cyr]\"]"
	suffix		"{}[closeRend]}[labelDivision]"
    }
    {element HEAD in DIV7} {
	prefix		"[startHead \"\\\\[sectionName 7][shortHead]{[openRend][localize cyr]\"]"
	suffix		"{}[closeRend]}[labelDivision]"
    }
    {element HEAD in DIV8} {
	prefix		"[startHead \"\\\\[sectionName 8][shortHead]{[openRend][localize cyr]\"]"
	suffix		"{}[closeRend]}[labelDivision]"
    }
    {element HEAD in DIV withattval TYPE ABSTRACT} {
	startAction {
	    Warning "HEAD of ABSTRACT is ignored"
	}
	prefix		{}
	suffix		{}
	cdataFilter	null
	sdataFilter	null
    }
    {element HEAD in DIV withattval TYPE BIBL} {
	prefix		"\\\\[sectionName [countq ancestor element DIV withattval TYPE BIBL]]\{"
	suffix		"\}\\n"
    }
    {element HEAD in DIV} {
	prefix		"[doHeadDiv][shortHead]{[openRend][localize cyr] "
	suffix		"{}[closeRend]}[labelDivision]"
    }
    {element HEAD in LISTBIBL} {
	prefix		"\\\\renewcommand{\\\\refname}\{"
	suffix		"\}[openBibliography]"
    }
    {element HEAD} {
	sdataFilter	headSdataFilter
	cdataFilter	headCdataFilter
    }
    {element REF} {
       prefix          [openRef]
       suffix          [closeRef]
    }
    {element PTR} {
	prefix		"[doPointer TARGET]"
    }
    {element XPTR} {
	prefix		"[openRend italic,quoted][doXptr NodeReferenceName]"
	suffix		"{}[closeRend]"
    }
    {element TABLE} {
	prefix		"[openTable]"
	suffix		"[closeTable]"
    }
    {element ROW in TABLE} {
	prefix		"[openRow]"
	suffix		"[closeRow]"
    }
    {element CELL in ROW in TABLE} {
	prefix		"[openCell]"
	suffix		"[closeCell]"
    }
    {element FIGURE hasatt REND} {
	prefix		"\\\\renewcommand{\\\\TEItoolsFigCaption}{}%"
	suffix		"[doFigure]"
    }
    {element FIGURE within TABLE} {
	prefix		"\n\\\\renewcommand{\\\\TEItoolsFigCaption}{}\n"
	suffix		"[doFigure]\n"
    }
    {element FIGURE} {
	prefix		"\n\\\\renewcommand{\\\\TEItoolsFigCaption}{}
\\\\begin{figure*}\\[[figPlacement]\\]\n"
	suffix		"[doFigure]\\\\end{figure*}\n"
    }
    {element FIGDESC in FIGURE} {
	prefix		{}
	cdataFilter	null
	sdataFilter	null
    }
    {element ABBR} {
	cdataFilter	toUpper
    }
    {element FOREIGN} {
       prefix          [openForeign]
       suffix          [closeForeign]
    }
    {element LISTBIBL} {
	prefix		[openBibliography]
	suffix		"\\n\\\\end{thebibliography}\\n"
    }
    {element BIBL in LISTBIBL} {
	prefix		"\\n\\\\bibitem{[attVal ID]} "
	suffix		"\\n"
    }
    {element AUTHOR in BIBL} {
	prefix		{}
	suffix		". "
    }
    {element PUBLISHER in BIBL} {
	prefix		"[localize texMdash]"
    }
    {element DATE in BIBL} {
	prefix		", "
    }
    {element BIBLSCOPE in BIBL} {
	prefix		", "
    }
    {element TITLE hasatt LEVEL in BIBL} {
	prefix		"\\\\textbf\{"
	suffix		"\}"
    }
    {element TITLE in BIBL} {
	prefix		"\\\\emph\{"
	suffix		"\}"
    }
    {element PUBPLACE in BIBL} {
	prefix		"[localize texMdash]"
	suffix		", "
    }
    {element L in LG} {
	prefix		"\\n"
	suffix		"\\\\mbox{}\\\\\\\\\\\\relax{}\\n"
    }
    {element LG} {
	prefix		"\\n\\\\begin{verse}\\n"
	suffix		"\\n\\\\end{verse}\\n"
    }
    {element ADDRESS} {
	prefix		"\\n\\\\begin{samepage}\\\\begin{quotation}\\n"
	suffix		"\\\\end{quotation}\\\\end{samepage}\\n"
    }
    {element ADDRLINE in ADDRESS} {
	prefix		{}
	suffix		"\\\\newline\\n"
    }
    {elements "TITLE HEAD"} {
	prefix		"[openTitleOrHead]"
	suffix		"[closeRend]"
    }
    {element FORMULA} {
	prefix		[formulaStart]
	suffix		[formulaEnd]
	cdataFilter	eatNLs
    }
    {elements "SEG ANCHOR FILEDESC PROFILEDESC LANGUSAGE LANGUAGE TITLESTMT PUBLICATIONSTMT SOURCEDESC TEXT DOCTITLE DOCEDITION EDITIONSTMT"} {
	#Do nothing
	prefix		{}
    }
    {element NAME within STAGE} {
	prefix		"[openRend spaced]"
    }
    {element NAME} {
	prefix		[openRend]
	suffix		[closeRend]
    }
    {element BODY} {
	prefix		[bodyStyle]
    }
    {element DEL} {
	prefix		{}
	cdataFilter	null
	sdataFilter	null
    }
    {element SP} {
	prefix		"\\n\\n\{[sp]"
	suffix		"\}"
    }
    {element SPEAKER} {
	prefix		"[openRend spaced]"
	suffix		". [closeRend]"
    }
    {element STAGE within SP} {
	prefix		"\{\\\\itshape "
	suffix		"\} "
    }
    {element STAGE} {
	prefix		"\\n\\\\begin{quotation}\\\\begin{center}\\\\small "
	suffix		"\\n\\\\end{center}\\\\end{quotation}\\n"
    }
    {el} {
	prefix		[openUnknown]
	suffix		{}
	sdataFilter	textSdataFilter
	cdataFilter	textCdataFilter
    }
    {pi} {
	piAction {
	    set content [query content]
	    Debug "piAction content: \"$content\""
	    #FIXME! Handle tabs
	    set space [string first " " $content]
	    if { $space == -1 } {
		Error "Syntax error in processing instruction `$content'"
	    }
	    set kw [string toupper [string trim [string range $content 0 $space]]]
	    if { "$kw" == "TEITOOLS" } {
		set TEItools_pi [string range $content 1 [expr [string length $content] - 1]]
		TEItools_do_PI [string trim [string range $content $space end]]
	    }
	}
    }
}

proc openInterlineNote {} {
    return "\n\\par\\textsf{\\textbf{[localize noteHead]}} "
}

proc closeInterlineNote {} {
    withNode parent el {
	if { "[query gi]" == "P" } {
	    return "\n\\mbox{}\\\\\n"
	}
    }
    return "\n"
}

proc xrefFilter { text } {
    return [textCdataFilter [trimSpaces $text]]
}

proc TEItools_PI_pageno { number } {
    output "\\setcounter{page}{$number}
\\addtocounter{page}{-1}
\\refstepcounter{page}
"
}

proc openBibliography {} {
    if { "[query gi]" == "LISTBIBL" } {
	withNode child element HEAD {
	    return
	}
    }
    return "\n\\begin{thebibliography}{99}\n"
}

proc doIndex {} {
    set idx {}
    for {set i 1} {$i < 4} {incr i} {
	set level [textSdataFilter [query attval LEVEL$i]]
	if { "$level" != "" } {
	    if { $i > 1 } {
		append idx "!"
	    }
	    append idx $level
	} else {
	    break
	}
    }
    return "\\index{$idx}\{"
}

proc bodyStyle {} {
    return
}

proc openVerbatim {} {
    return "[openRend]\n\\begin\{verbatim\}\n"
}

proc closeVerbatim {} {
    return "\n\\end\{verbatim\}\n[closeRend]\n"
}

proc openTableCaption {} {
    set tableWidth [query parent propval totalWidth]
    return "[ifMultiCol \\multicolumn{$tableWidth}{l} \\caption]\{[openRend bold]"
}

proc formulaStart {} {
    if { [attVal NOTATION] != "tex" } {
	Error "Unknown formula notation: [attVal NOTATION], only `TeX' is supported."
    }
    if { [attVal REND] == "display" || [attVal REND] == "block" } {
	setprop rend "block"
	return "\n\\begin{displaymath}\n"
    } else {
	setprop rend "inline"
	return "$"
    }
}

proc formulaEnd {} {
    if { [query propval rend] == "block" } {
	return "\n\\end{displaymath}\n"
    } else {
	return "$"
    }
}

proc authorMacro { idx } {
    withNode doctree \
	element "front" child element "titlepage" child element "docauthor" {
	    return "\\TEItoolsAuthor[string index ABCDEFGHIJKLMNOPQRSTUVWXYZ $idx]"
	}
    Error "Your style requires you to specify DocAuthor element!"
    return
}


proc titlePartMacro { idx } {
    return "\\TEItoolsTitlePart[string index ABCDEFGHIJKLMNOPQRSTUVWXYZ $idx]"
}

proc imprintMacro { idx } {
    return "\\TEItoolsImprint[string index ABCDEFGHIJKLMNOPQRSTUVWXYZ $idx]"
}

proc authorPrefix {} {
    global authorPrefix_Counter
    if { ![info exists authorPrefix_Counter] } {
	set authorPrefix_Counter 0
    } else {
	incr authorPrefix_Counter
    }
    
    if { $authorPrefix_Counter > 25 } {
	Error "*INTERNAL ERROR*: only 25 <docAuthor>s are implemented"
	exit 1
    }

    return "\\newcommand\{[authorMacro $authorPrefix_Counter]\}\{"
}

proc imprintPrefix {} {
    global imprintCounter
    if { ![info exists imprintCounter] } {
       set imprintCounter 0
    } else {
       incr imprintCounter
    }
    
    if { $imprintCounter > 25 } {
       Error "***INTERNAL ERROR: only 25 <docImprint>s are implemented"
    }

    return "\\newcommand\{[imprintMacro $imprintCounter]\}\{"
}

proc titlepartPrefix {} {
    global titlePartCounter
    if { ![info exists titlePartCounter] } {
       set titlePartCounter 0
    } else {
       incr titlePartCounter
    }
    
    if { $titlePartCounter > 25 } {
       Error "***INTERNAL ERROR: only 25 <titlePart>s are implemented"
    }

    return "\\newcommand\{[titlePartMacro $titlePartCounter]\}\{"
}

proc setTableFont {} {
    return ""
}

proc openTitleOrHead {} {
    set inline 0
    foreachNode ancestor {
	switch -regexp "[query gi]" {
	    "(BIBL)|(P)|(ITEM)|(NOTE)|(HEAD)|(CELL)" {
		set inline 1
		break
	    }
	    default {
		continue
	    }
	}
	break
    }
    
    if { $inline == 1 } {
	set ret [openRend italic]
	return $ret
    } else {
	set ret [openRend bold,slanted]
	setprop rendition "[query propval rendition]\n\\end{center}\n"
	return "\n\\begin{center}${ret}\\large "
    }
}

proc openQuote {} {
    if { "[attVal TYPE]" == "spoken" } {
	return "\cyrdash\nobreak\hskip.35em\ignorespaces"
    }
    if { "[attVal REND]" == "" || "[attVal REND]" == "\#IMPLIED" } {
	return [openRend quoted]
    } else {
	return [openRend]
    }
}

proc doXref {} {
    set text [textCdataFilter [query attval N]]
    if { $text == "" } {
	set text [filteredContent]
    }
    return $text
}

########################################################3

proc openFront {} {
    # for book style
    return "\n\\frontmatter\n"	       
}

proc closeFront {} {
    # for book style
    return "\n\\mainmatter\n"
}

proc openBack {} {
#    return
    # for book style
    return "\n\\backmatter\n"
}

proc closeBack {} {
    return
}

proc openTable {} {

    set ret {}

    set label [string tolower [query attval ID]]
    if { "$label" == "" } {
	set label [string tolower [AddrToName [query address]]]
    }
    setprop label $label
        
    set cols [query attval COLS]
    if { $cols == "" } {
 	set cols [countColsInTable]
    }

    setprop cols $cols

    foreachNode child child {
	foreach rend [split [attVal REND] " ,"] {
	    if { "$rend" == "justify" } {
		set paraCells([childNumber]) "1"
	    }
	}
    }

    set tableRend [attVal REND]

    if { [string match "*landscape*" [attVal N]] } {
	append ret "
\\begin{landscape}
"
	setprop closing "
\\end{landscape}
"
    } else {
	setprop closing ""
    }
    
    if { [isLandscapeTable] } {
	append ret "
\\setlength\\CellW{\\linewidth}
"
    } else {
	append ret "
\\setlength\\CellW{\\textwidth}
"
    }

    if { $tableRend == "" } {
	Error "Table REND should be specified"
	set tableRend "jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj"
    }

    if { [isdigit [string index $tableRend 0]] } {
	set tableRend [split $tableRend " ,"]
	set i 0
	set totalWidth 0
	foreach rend $tableRend {
	    if { [regexp "\[0-9\]*" $rend width] == 1 } {
		set paraCells($i) $width
		incr i
		incr totalWidth $width
	    } else {
		Error "Table REND item syntax error in $rend"
		return
	    }
	}
    } else {
	if { [string length $tableRend] < $cols} {
	    Error "Table REND string is shorter than needed!"
	    return
	}

	for {set i 0} {$i < [string length $tableRend]} {incr i} {
	    if { [string index $tableRend $i] == "j" } {
		set paraCells($i) "1"
	    }
	}
	set totalWidth $cols
    }

    setprop totalWidth $totalWidth
    
    set tableFormat [verticalLine]
    
    for {set i 0} {$i < $cols} {incr i} {
	if { [info exists paraCells($i)] } {
	    setprop paraCells [array get paraCells]
	    if { ![info exist paraCells($i)] } {
		set paraCells($i) 1
	    }
	    append tableFormat "p{$paraCells($i)\\CellW}[verticalLine]"
	} else {
	    append tableFormat "l[verticalLine]"
	}
    }

    append ret "
\\addtolength{\\CellW}{-[expr 2 * $cols]\\tabcolsep}
\\divide\\CellW $totalWidth
\\gdef\\TEItoolsTableHead{}
\{[setTableFont]\\begin{[ifMultiCol tabular longtable]}{$tableFormat}
"

    set longTableHeaders "\\endfirsthead"

    set t [localize endfoot]
    global TEItools_continuation_value
    if { [info exists TEItools_continuation_value] \
	     && $TEItools_continuation_value == 0 } {
	set t {}
    }
    if { $t != "" } {
	append longTableHeaders "\n\\multicolumn{$cols}{r}{$t}\\\\\n\\endfoot\n"
    }

    append longTableHeaders "\\endlastfoot\n"

    set t [localize continue_caption]
    if { $t != "" } {
        append longTableHeaders "\\caption[]{[localize cyr]$t}\\\\\n"
    }

    set t [localize endhead]
    if { [info exists TEItools_continuation_value] \
	     && $TEItools_continuation_value == 0 } {
	set t {}
    }
    if { $t != "" } {
        append longTableHeaders "\\multicolumn{$cols}{l}{$t}\\\\[horisontalLine]\n"
    }

    append longTableHeaders "\\endhead\n"
    
    return "${ret}[ifMultiCol {} $longTableHeaders]"
}

proc isLandscapeTable {} {
    if { [string match "*landscape*" [attVal N]] } {
	return 1
    }
    foreachNode ancestor el {
	if { [string match "*landscape*" [attVal REND]] } {
	    return 1
	}
    }
    return 0
}

proc countColsInTable {} {
    set maxCols 0
    foreachNode child element row {
	set N 0
	foreachNode child element cell {
	    set colSpan [query attval COLS]
	    if { $colSpan == "" } {
		set colSpan 1
	    }
	    incr N $colSpan	
	}
	if { $maxCols < $N } {
	    set maxCols $N
	}
    }
    if { $maxCols == 0 } {
	Error "What? Table without rows?? Hm..."
    }
    return $maxCols
}

proc closeTable {} {
    set ret "
\\end{[ifMultiCol tabular longtable]}\}
"

    append ret [query propval closing]

    #Don't number non-lined tables 
    if { [string match "*notlined*" [attVal N]] } {
	append ret "\\addtocounter{table}{-1}\n"
    }

    return $ret
}

proc ifMultiCol { ifYes ifNot } {
    global TEItools_twocolumn_in_use
    if { [info exists TEItools_twocolumn_in_use ] } {
	return $ifYes
    } else {
	return $ifNot
    }
}

proc tableLabel {} {
    withNode parent {
	return "\\protect{[makeLabel [query propval label]]}"
    }
}

proc openCell {} {
    set localRend [attVal REND]
    set justify ""
    set myNcol [expr 1 + [countq prev]]

    withNode ancestor element TABLE {
	if { "[query propval cols]" < $myNcol } {
	    Error "Too many cells, fix your <table>"
	    exit 1
	}
    }

    foreach re [split $localRend " ,"] {
	switch $re \
	    "left" {
		set justify "l"
	    } \
	    "right" {
		set justify "r"
	    } \
	    "center" {
		set justify "c"
	    } \
	    "justify" {
		set justify "j"
	    }
    }

    set pJustify {}
    set cellHead "\{"

    set colNo [expr [childNumber] - 1]
    foreachNode prev {
	set span [attVal COLS]
	if { $span != "" && $span > 1 } {
	    set colNo [expr $colNo + $span - 1]
	}
    }

    set rend "jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj"
    
    withNode ancestor element TABLE hasatt REND {
	set rend [attVal REND]
    }
    if { [isdigit [string index $rend 0]] } {
	set rend [lindex [split $rend " ,"] $colNo]
	if { "$rend" == "" } {
	    Error "not enough items in REND $rend"
	    return
	}
	
	if { [regexp "(\[0-9\]+)(\[lrcj\])" $rend dummy cellWidth align] == 1 } {
	    set pJustify $align
	    if { "$pJustify" == "" } {
		set pJustify "l"
	    }
	} else {
	    Error "syntax error in REND item: $rend"
	    return
	}
    } else {
	set pJustify [string index $rend $colNo]
    }
    if { "$pJustify" != "" && ![regexp "(l)|(r)|(c)|(j)" $pJustify] } {
	Error "Bad CELL alignment: $pJustify"
    }
    
    if { $justify == "" } {
	set justify $pJustify
    }

    set colSpan [query attval COLS]

    if { $colSpan == "" } {
	set colSpan 1 
    }
    
    if { $colSpan > 1 } {
#	set cellHead "\\multicolumn\{$colSpan\}\{|${justify}|\}\{"

	withNode ancestor element TABLE {
	    set paraCellsString [query propval paraCells]
	}
	if { "$paraCellsString" != "" } {
	    set spanWidth 0
	    array set paraCells $paraCellsString
	    for {set i 0} {$i < $colSpan} {incr i} {
		set idx [expr $colNo + $i]
		if { ![info exist paraCells($idx)] } {
		    set paraCells($idx) 1
		}
		set spanWidth [expr $spanWidth + $paraCells($idx)] 
	    }
	}
	# Black magic here. Yes, this is "l" intentionally.
	set cellHead "\\multicolumn\{$colSpan\}\{[verticalLine]l[verticalLine]\}\{"
    } else {
	if { [info exists cellWidth] } {
	    set spanWidth $cellWidth
	}
    }

    if { ![info exist spanWidth] } {
	set spanWidth $colSpan
    }

    if { $justify == "j" } {
	set mcolJustifyAdj "\\parbox\[t\]\{${spanWidth}\\CellW\}\{\\strut "
	prependprop closing " \\strut\}"
    } else {
	set mcolJustifyAdj ""
	switch $justify \
	    "r" {
		append cellHead "\\hfill{}"
	    } \
	    "l" {
		prependprop closing "\\hfill{}"
	    } \
	    "c" {
		append cellHead "\\hfil{}"
		prependprop closing "\\hfil{}"
	    }
    }
    set role [attVal ROLE]
    set rowRole {}
    withNode parent {
	set rowRole [attVal ROLE]
    }
    if { $role == "label" || $rowRole == "label" } {
	append cellHead "\\bfseries "
    }
    return "${cellHead}[openRend]${mcolJustifyAdj}\\noindent\\mbox{}\\hskip0pt{}"
}

proc closeCell {} {
    set tail "[query propval closing][closeRend]\}"
    withNode next {
	return "${tail}&
"
    }
    return "${tail}\\\\
"
}

proc openRow {} {
    return "[horisontalLine]\n"
}

proc closeRow {} {
    withNode next {
	return
    }
    return "[horisontalLine]\n"
}

proc horisontalLine {} {
    set N [string tolower [query ancestor element TABLE attval N]]
    if { [string match "*notlined*" $N] } {
	return
    } else {
	return "\\hline"
    }
}

# This is called from <TABLE> callback

proc verticalLine {} {
    if { "[query gi]" != "TABLE" } {
	withNode ancestor element TABLE {
	    if { [linedTable] } {
		return "|"
	    } else {
		return
	    }
	}
    }
    if { [linedTable] } {
	return "|"
    } else {
	return
    }
}

proc linedTable {} {
    if { [string match "*notlined*" [string tolower [query attval N]]] } {
	return 0
    } else {
	return 1
    }
}

proc prependprop { name value } {
    set oldValue [query propval $name]
    setprop $name "${value}${oldValue}"
}

proc openParAlign {} {
    set rend [attVal REND]
    foreach re [split $rend " ,"] {
	switch $re \
	    "center" {
		setprop closeEnvironment "center"
		return "\\begin{center}"
	    }
    }
    return
}

proc closeParAlign {} {
    set env [query propval closeEnvironment]
    if { "$env" != "" } {
	return "\\end{$env}"
    }
    return 
}

proc paragraphLabel {} {
    return [attVal ID]
}

proc numberPara {} {
    set label [paragraphLabel]
    set number [paragraphNumber]
    if { "$number" != "" } {
	set number "${number}~"
    }
    if { "$label" != "" } {
	set label "\\hypertarget{$label}{}"
    }
    return "${label}${number}"
}

proc openRend { { defaultRend "" } { nounderline "" } } {
    set rend [attVal REND]

    global parsedRend
    parseRend $defaultRend $nounderline
    set charOpen $parsedRend(charOpen)
    set charClose $parsedRend(charClose)
    set displayOpen $parsedRend(displayOpen)
    set displayClose $parsedRend(displayClose)

    if { $rend != "" } {
	parseRend $rend $nounderline
	if { $parsedRend(charOpen) != "" } {
	    set charOpen $parsedRend(charOpen)
	}
	if { $parsedRend(charClose) != "" } {
	    set charClose $parsedRend(charClose)
	}
	if { $parsedRend(displayOpen) != "" } {
	    set displayOpen $parsedRend(displayOpen)
	}
	if { $parsedRend(displayClose) != "" } {
	    set displayClose $parsedRend(displayClose)
	}
    }

    setprop rendition "${charClose}${displayClose}"
    return "${displayOpen}${charOpen}"
}

proc parseRend { rend { nounderline "" } } {

# CAUTION! GLOBAL HERE!
    global parsedRend

    set charOpen {}
    set charClose {}
    set displayOpen {}
    set displayClose {}

    foreach re [split $rend " ,"] {
	switch -regexp $re {
	    "smallcap" {
		append charOpen "\{\\\\scshape{}"
		prepend charClose "\}"
	    }
	    "underline" {
		if { $nounderline == "" } {
		    append charOpen "\\\\uline\{"
		    prepend charClose "\}"
		} else {
		    Warning "rend='underline' is not supported in this context"
		}
	    }
	    "(super)|(superscript)" {
		append charOpen "\{\\\\ensuremath\{^\{"
		prepend charClose "\}\}\}"
	    }
	    "(sub)|(subscript)" {
		append charOpen "\{\\\\ensuremath\{_\{"
		prepend charClose "\}\}\}"
	    }
	    "(bold)|(spaced)" {
		append charOpen "\{\\\\bfseries{}"
		prepend charClose "\}"
	    }
	    "italic" {
		append charOpen "\{\\\\itshape{}"
		prepend charClose "\}"
	    }
	    "sans" {
		append charOpen "\{\\\\sffamily{}"
		prepend charClose "\}"
	    }
	    "typewriter" {
		append charOpen "\{\\\\ttfamily{}"
		prepend charClose "\}"
	    }
	    "slanted" {
		append charOpen "\{\\\\slshape{}"
		prepend charClose "\}"
	    }
	    "normal" {
		append charOpen "\{\\\\rmfamily{}"
		prepend charClose "\}"
	    }
	    "small" {
		append charOpen "\{\\\\tiny{}"
		prepend charClose "\}"
	    }
	    "large" {
		append charOpen "\{\\\\large{}"
		prepend charClose "\}"
	    }
	    "(quoted)|(inline)" {
		append charOpen "[localize lq]"
		prepend charClose "[localize rq]"
	    }
	    "(block)|(display)" {
		append displayOpen "\n\\\\begin{quotation}\n"
		prepend displayClose "\n\\\\end{quotation}\n"
	    }
	    "flushleft" {
	    	append displayOpen "\n\\\\begin{raggedright}\n"
		prepend displayClose "\n\\\\end{raggedright}\n"
	    }
	    "flushright" {
                append displayOpen "\n\\\\begin{raggedleft}\n"
                prepend displayClose "\n\\\\end{raggedleft}\n"
            }
	    "landscape" {
		append displayOpen "\\\\rotatebox{90}\{"
		prepend displayClose "\\\\hspace{1mm}\}"
	    }
	}
    }

    array set parsedRend "
	charOpen	\"$charOpen\"
	charClose	\"$charClose\"
	displayOpen	\"$displayOpen\"
	displayClose	\"$displayClose\"
"
}


proc appendprop { name value } {
    set oldValue [query propval $name]
    append oldValue $value
    setprop $name $oldValue
}

proc closeRend {} {
    return [query propval rendition]
}

proc listItem {} {
    withNode parent {
	set listType [typeVal]
    }
    if { $listType == "gloss" } {
	set prev {}
	withNode prev {
	    set prev [query gi]
	}
	if { "$prev" != "LABEL" } {
	    Error "<ITEM> without <LABEL> in <LIST TYPE='Gloss'>"
	}
	# If we're in <list type='gloss'>, <label>
	# should generated \item instead. So do nothing.
	return [itemLabel]
    }
    return "[listLabel][itemLabel]"
}

proc listLabel {} {
    set n [attVal N]
    if { "$n" != "" } {
	set n "\[${n}\]"
    } else {
	set n " {}"
    }
    return "\n\\item${n} "
}    

proc itemLabel {} {
    set id [attVal ID]
    if { "$id" != "" } {
       return [makeLabel $id]
    } else {
	return
    }
}

proc doPointer { targetIDattribute } {
    set ID [attVal $targetIDattribute]

    #Pointers to bibliography items
    withNode doctree element BIBL withattval ID $ID {
	return "\\cite{$ID}"
    }

    #Pointers to numbered paragraphs
    withNode doctree element P withattval ID $ID {
	set n [paragraphNumber]
	if { "$n" != "" } {
	    return $n
	} else {
	    Error "Reference to unnumbered paragraph"
	}
    }

    #Pointers to list items
    withNode doctree element ITEM withattval ID $ID {
	set listType [query parent attval TYPE]
	if { "$listType" != "ORDERED" && "$listType" != "ALPHA" } {
	    Error "Reference to unnumbered item"
	}
    }

    #Pointers to labels (for <list gloss>, for example)
    withNode doctree element LABEL withattval ID $ID {
	return [filteredContent]
    }

    #Pointers to divisions
    withNode doctree elements "DIV DIV1 DIV2 DIV3 DIV4 DIV5 DIV6 DIV7" withattval ID $ID {
	return [doDivRef $ID]
    }
    
    #other pointers
    return "\\ref{$ID}"
}

proc doDivRef { ID } {
    return "\\ref{$ID}"
}

proc doFigure {} {
    debug "rend: [query attval rend]"
    set rend [attVal REND]
    set floatplacement ""
    set narrowFigure 0
    set inlineFigure 0
    set landscape 0
    switch "$rend" {
	"left" {
	    set floatplacement "l"
	}
	"right" {
	    set floatplacement "r"
	}
	"narrow" {
	    set narrowFigure 1
	}
	"inline" {
	    set inlineFigure 1
	}
	"landscape" {
	    set landscape 1
	}
    }

    debug "figure rend: $rend"
    
    if { "$floatplacement" != "" } {
	set floatStart "
\\sbox{\\TEItoolsFloatFigBox}{"
	set floatEnd "}
\\settowidth{\\TEItoolsFloatLen}{\\usebox{\\TEItoolsFloatFigBox}}
\\addtolength{\\TEItoolsFloatLen}{2ex plus 1ex minus .5ex}
\\begin{figure}
\\begin{floatingfigure}\[$floatplacement\]{\\TEItoolsFloatLen}
  \\usebox{\\TEItoolsFloatFigBox}
  \\caption{\\TEItoolsFigCaption{}}[labelFigure]
\\end{floatingfigure}
\\end{figure}
"
    } else {
	if { $narrowFigure } {
	    set floatStart "\\begin{figure}\[[figPlacement]\]\n"
	    set floatEnd "\\caption{\\TEItoolsFigCaption{}}[labelFigure]\n\\end{figure}\n"
	} else {
	    set floatStart "\\begin{center}\n"
	    set floatEnd "\\caption{\\TEItoolsFigCaption{}}[labelFigure]\n\\end{center}\n"
	}
    }
    set fig [insertFigEntity]
    withNode ancestor element TABLE {
	set inlineFigure 1
    }
    if { $inlineFigure == 1 } {
	set floatStart ""
	set floatEnd ""
    }
    if { $landscape } {
	set floatStart "\\begin{landscape}${floatStart}"
	set floatEnd "${floatEnd}\\end{landscape}"
    }
    return "${floatStart}${fig}${floatEnd}"
}

proc insertFigEntity {} {
    set entName [query attval ENTITY]
    if { $entName == "" } {
	Error "Figure without ENTITY to include!"
	return
    }
    withNode entity $entName {
	set fileName [query sysid]
	return [insertGraphicFile $fileName]
    }
    Error "No such entity: ${entName}!"
}

proc labelFigure {} {
    set id [attVal ID]
    if { $id != "" } {
       return "[makeLabel $id]%\n"
    }
    return
}

proc DivToOpenOnNewPage {} {
    #   ,  ,    
    #     
    withNode prev {
	if { [query gi] == "HEAD" } {
	    return 0
	}
    }
    withNode parent {
	foreachNode ancestor {
	    foreach rend [split [attVal REND] " ,"] {
		if { $rend == "continuous" } {
		    return 0
		}
	    }
	}
    }
    return 1
}

proc startDivision {} {
    puts stderr . nonewline

    checkDivType
    
    if { [query propval subdocRoot] == "true" } {
	set retHead [filePrologue]
    } else {
	set retHead {}
    }
    set retBody {}
    switch [typeVal] {
	"abstract" {
	    set retBody "\n
\\vspace*{1.5cm plus 10mm minus 5mm}
\\begin{center}
\\Large\\abstractname
\\makeatletter\\@mkboth\{\\abstractname\}\{\\abstractname\}\\makeatother
\\end{center}
\\vspace{1cm plus 5mm minus 3mm}
\{%\\sffamily
"
	    setprop closing "\}
\\clearpage
"
	}
	"appendix" {
	    set retBody "\n[StartAppendix]\n"
	}
	"colophon" {
	    set retBody "\n\\clearpage\n{ \\small\n"
	    setprop closing "\n\n}\\clearpage\n\n"
	}
    }

    global TEItools_openpage_value
    if { [info exists TEItools_openpage_value] && [firstAppendix] != 1 } {
	set val [string toupper $TEItools_openpage_value]
	if { [string range $val 0 2] != "DIV" } {
	    Error "openpage should be set only to DIVx"
	} else {
	    set level [string index $val 3]
	    set curLevel [string index [query gi] 3]
	    if { $curLevel > 0 \
		 && $curLevel <= $level \
		     && "[DivToOpenOnNewPage]" == 1 } {
		append retBody "\\clearpage{}"
	    }
	}
    }

    set divNumber [query propval divNumber]
    if { "$divNumber" != "" } {
	global splitNames
	set divLevel [string range [query gi] 3 3]
	append retBody "\\setcounter{[lindex $splitNames($divLevel) 0]}{[expr $divNumber - 1]}"
    }

    return "${retHead}${retBody}"
}

proc firstAppendix {} {
    if { [typeVal] == "appendix" } {
	global firstAppendixProcessed
	if { ![info exists firstAppendixProcessed] } {
	    set firstAppendixProcessed YES
	    return 1
	}
    }
    return 0
}

proc StartAppendix {} {
    global TEITools_appendix_header_done
    if { ![info exists TEITools_appendix_header_done] } {
	set TEITools_appendix_header_done YES
	return "

%\\cleardoublepage
%\\section*{[localize appendices]}
\\appendix

"
    }
    return ""
}

proc endDivision {} {
    if { [query propval subdocRoot] == "true" } {
	set retTail [fileEpilogue]
    } else {
	set retTail {}
    }

    if { [string match "*landscape*" [attVal REND]] } {
	set retTail "\n\\end{landscape}\n${retTail}\n"
    }

    return "\n[query propval closing]\n${retTail}\n"
}

proc filePrologue {} {
    return [latexFileHeader]
}

proc fileEpilogue {} {
    return [latexFileFooter]
}

proc doHeadDiv {} {
    withNode parent {
	set type [typeVal]
    }
    global splitNames
    
    if { $type == "appendix" } {
	return "\\section"
    }
    if { $type == "colophon" } {
	return "\\section*"
    }
    if { [lsearch $splitNames(1) $type] != -1 } {
	set section [sectionName 1]
    } elseif { [lsearch $splitNames(2) $type] != -1 } {
	set section [sectionName 2]
    } elseif { [lsearch $splitNames(3) $type] != -1 } {
	set section [sectionName 3]
    } elseif { [lsearch $splitNames(4) $type] != -1 } {
	set section [sectionName 4]
    } else {
	set section [sectionName 5]
    }
    return "\\${section}"
}

proc sectionName { level } {
    global TEItools_documentclass_value

    if { ![info exists TEItools_documentclass_value] } {
	set TEItools_documentclass_value "article"
    }

    if { $TEItools_documentclass_value != "article" } {
	incr level -1
    }

    array set names {
	0 "chapter"
	1 "section"
	2 "subsection"
	3 "subsubsection"
	4 "paragraph"
	5 "subparagraph"
	6 "subsubparagraph"
	7 "subsubsubparagraph"
	8 "subsubsubsubparagraph"
    }
    array set starredNames {
	0 "chapter*"
	1 "starredSection"
	2 "subsection*"
	3 "subsubsection*"
	4 "paragraph*"
	5 "subparagraph*"
	6 "subsubparagraph*"
	7 "subsubsubparagraph*"
	8 "subsubsubsubparagraph*"
    }

    withNode parent {
	if { [shouldBeUnnumbered] } {
	    return $starredNames($level)
	} else {
	    return $names($level)
	}
    }
}

proc shouldBeUnnumbered {} {
    set type [attVal TYPE]

    if { "$type" == "stub" || "$type" == "act" || "$type" == "scene" } {
	return 1
    }

    return 0
}

proc startHead { text } {
    withNode element prev {
	if { "[query gi]" != "HEAD" } {
	    return
	}
    }
    return $text
}

proc shortHead {} {
    set short {}
    withNode parent child element HEAD withattval TYPE SHORT {
	set short "\[[filteredContent]\]"
    }
    return $short
}

proc labelDivision {} {
    set id {}
    set ret {}
    withNode parent {
	set id [attVal ID]

	if { [regexp ".*twocolumn.*" "[attVal REND]"] } {
	    append ret "\n\\begin{multicols}{2}\n"
	    appendprop closing "\n\\end{multicols}\n"
	}
    }
    
    if { "$id" != "" } {
	append ret "\n[makeLabel $id]\n"
    }

    withNode parent {
	if { [string match "*landscape*" [attVal REND]] } {
	    append ret "\n\\begin{landscape}\n"
	}
    }

    return $ret
}

proc openHyperLink {} {
    return "\\textit{[query attval N]}\\footnote\{"
}

proc closeHyperLink {} {
    return "\}"
}

proc divGen {} {
    set genProcedure "generate[typeVal]"
    if { "[info proc $genProcedure]" != "$genProcedure" } {
        Error "Unknown divGen type: [typeVal]"
    } else {
	return [eval $genProcedure]
    }
}

proc generatetoc {} {
    return "\n\\mbox{}\\tableofcontents\\clearpage\n"
}

proc generatelot {} {
    withNode docroot descendant elements "DIV DIV0 DIV1" {
	return "\n\\mbox{}\\listoftables\\clearpage\n"
    }
    return
}

proc generatelof {} {
    withNode docroot descendant element FIGURE {
	return "\n\\mbox{}\\listoffigures\\clearpage\n"
    }
    return
}

proc generateindex {} {
    withNode docroot descendant element INDEX {
	return "\n[definePageStyle]\\printindex\\clearpage\n"
    }
    return
}

proc listHeader { type } {
    switch -regexp $type {
	"alpha" {
	    set head "\\begin{enumerate}\\renewcommand{\\theenumi}{\\asbuk{enumi}}"
	    set foot "\\end{enumerate}"
	}
	"ordered" {
	    set head "\\begin{enumerate}"
	    set foot "\\end{enumerate}"
	}
	"gloss" {
	    set head "\\begin{description}"
	    set foot "\\end{description}"
	    set labels [countq child element LABEL]
	    if { $labels < 1 } {
		Error "No LABELs inside <LIST TYPE='GLOSS'>"
	    }
	}
	"(bulleted)|(simple)|(bullets)" {
	    set head "\\begin{itemize}"
	    set foot "\\end{itemize}"
	}
	default {
	    Error "Unknown list type: $type"
	    set head "\\begin{itemize}"
	    set foot "\\end{itemize}"
	}
    }
    set theHead ""

    withNode child element HEAD {
	set headPrefix "\\begin{quotation}"
	set headSuffix "\\end{quotation}"
	if { "[query ancestor element TABLE gi]" == "TABLE" } {
	    set headPrefix ""
	    set headSuffix ""
	}
	append theHead "
$headPrefix
[openRend bold]
[filteredContent]
[closeRend]
$headSuffix
"
    }
    setprop listEnd $foot
    return "${theHead}${head}"
}

proc listFooter {} {
    return [query propval listEnd]
}

proc TitlePage {} {

    debug "TitlePage"
    
    set ret "
       \\begin\{titlepage\}%
       \\null\\vfil
       \\vskip 6cm%
       \\begin\{center\}%
       \{\\LARGE [localize cyr]"

    global titlePartCounter
    if { [info exist titlePartCounter] } {
	for {set i 0} {$i <= $titlePartCounter} {incr i} {
	    append ret "[titlePartMacro $i]\{\}\\\\"
	}
    }

    append ret "\\par\}%
       \\vskip 3cm%
       \{\\large
           \\lineskip .75em%
           \\begin\{tabular\}\[t\]\{c\}%

           [localize cyr]
       "

    global authorPrefix_Counter
    if { [info exist authorPrefix_Counter] } {
	for {set i 0} {$i <= $authorPrefix_Counter} {incr i} {
	    if { $i > 0 } {
		append ret "\\and "
	    }
           append ret "[authorMacro $i]\{\}"
	}
    }

    append ret "
       \\end\{tabular\}\\par\}%
       \\vskip 1.5em%
       \{\\large [localize cyr] \\TEItoolsDate\{\} \\par\}%
       \\end\{center\}\\par

       \\null
       \\vfill
       \\null

"
    global imprintCounter
    if { [info exist imprintCounter] } {
       append ret "
       \\begin\{center\}
"
       for {set i 0} {$i <= $imprintCounter} {incr i} {
           append ret "[imprintMacro $i]\{\}\\\\\n"
       }
       append ret "\\end\{center\}\n"
    }
    
    return "${ret}\\end\{titlepage\}\n[TitlePageHook]\n"
}

proc TitlePageHook {} {
    set ret ""
    global TEItools_firstpage_value
    if { [info exists TEItools_firstpage_value] } {
	append ret "\\setcounter{page}{$TEItools_firstpage_value}\n"
    }
    return $ret
}

proc sp {} {
    withNode child element SPEAKER {
	return
    }
    set who [attVal WHO]
    if { "$who" == "" } {
	Error "Don't know who speaks"
	return
    }
    withNode docroot descendant element NAME withattval ID $who {
	return "[openRend spaced][content][closeRend]. "
    }
    Error "No <NAME ID='$who'>"
}

proc useGeometry {} {
    return "\\geometry{[geometryArgs]}"
}

proc geometryArgs {} {
    return "a4paper"
}

proc latexFileHeader {} {
    global TEItools_documentclass_value

    if { ![info exists TEItools_documentclass_value] } {
	set TEItools_documentclass_value "article"
    }

    global TEItools_scale_value
    if { [info exists TEItools_scale_value] } {
	set magnify "\\mag=${TEItools_scale_value}\n"
    } else {
	set magnify ""
    }

    return "% Generated from TEI Lite DTD by TEItools
% See http://xtalk.msk.su/SGML/TEItools

\\documentclass\[[documentClassOptions]\]{$TEItools_documentclass_value}
${magnify}
[localize LaTeX_preamble]
[useGraphics]
\\usepackage{longtable,geometry,floatflt,lscape,multicol,textcomp}
\\usepackage{makeidx,endnotes,amssymb,ulem,fancyvrb}
\\renewcommand{\\notesname}{[localize endNotes]}
[pageLayout]
[extraPreamble]
[useGeometry]
[useHyperRef]
[TEItools_Style]
[sectionTitles]
\\begin{document}
%%dont. Conflicts with hyperref :(
%\\VerbatimFootnotes
%--
\\newlength\\CellW
\\newcommand{\\TEItoolsDate}{}
\\newcommand{\\TEItoolsFigCaption}{}
[definePageStyle]
[generateVCpage]
"
}

proc generateVCpage {} {
    withNode doctree element EDITIONSTMT {
	return "
\\cleardoublepage
[filteredContent]
\\cleardoublepage
"
    }
    return
}

proc useHyperRef {} {
    return "\\usepackage\[[hyperrefArgs]\]{hyperref}\n"
}

proc useGraphics {} {
    return "\\usepackage{graphicx}\n"
}

if { [info exist filteredContent] } {
    rename filteredContent {}
}

proc filteredContent {} {
    rename output output_filtered
    #FIXME!!!! Should be stack of these!!
    global filteredContentText
    set filteredContentText ""
    proc output { text } {
	global filteredContentText
	append filteredContentText $text
    }
    set addr [query address]
    pushMode innerMode
    translateHandler
    popMode
    selectNode node $addr
    rename output {}
    rename output_filtered output
    return $filteredContentText
}

# This is used in filteredContent
specification innerMode {
    {within TEIHEADER} {
	cdataFilter	null
	sdataFilter	null
    }
    {elements "HEAD LABEL"} {
	prefix	{}
    }
    {element CODE} {
	prefix		"[openRend bold,typewriter]"
	suffix		"[closeRend]"
	cdataFilter	typewriterCdataFilter
	sdataFilter	typewriterSdataFilter
    }
    {element Q} {
	prefix		"[openQuote]"
	suffix		"[closeRend]"
    }
    {el} {
	prefix	[innerUnknown]
	sdataFilter	textSdataFilter
	cdataFilter	textCdataFilter
    }
}

proc innerUnknown {} {
    Warning "Unknown element in inner translation specificator: [query gi]"
}

proc openForeign {} {
    return [openLang [attVal LANG]]
}

proc closeForeign {} {
    return [closeLang]
}

proc openRef {} {
    return "\\hyperlink\{[attVal TARGET]\}\{"
}

proc closeRef {} {
    return "\}"
}

proc makeLabel { label } {
    return "\\label{$label}"
}

debug "script loaded."
