# -*- tcl -*-
#
# fmt.latex
#
# (c) 2001 Andreas Kupries <andreas_kupries@sourceforge.net>
#
# [mpexpand] definitions to convert a tcl based manpage definition into
# a manpage based upon LaTeX markup.
#
################################################################

##
## This engine needs a rewrite for a better handling
## of characters special to TeX / LaTeX.
##

dt_source _common.tcl   ; # Shared code

global _in_example
set    _in_example 0

# Called to handle plain text from the input
proc fmt_plain_text {text} {
    global _in_example
    if {$_in_example} {
	return $text
    }
    return [texEscape $text]
}

proc Year {} {clock format [clock seconds] -format %Y}

c_holdBuffers require

################################################################
## Backend for LaTeX markup

c_pass 1 fmt_manpage_begin {title section version} NOP
c_pass 2 fmt_manpage_begin {title section version} {
    set module      [dt_module]
    set shortdesc   [c_get_module]
    set description [c_get_title]
    set copyright   [c_get_copyright]

    set     hdr ""
    append  hdr [Comment [c_provenance]] \n
    if {$copyright != {}} {
	append  hdr [Comment $copyright] \n
    }
    append  hdr [Comment "CVS: \$Id\$ $title.$section"] \n
    append  hdr \n
    append  hdr "\\documentclass\{article\}" \n
    append  hdr "\\begin\{document\}" \n
    append  hdr "\\author\{[dt_user]\}" \n

    set    titletext ""
    append titletext "$module / $title \\\\"
    append titletext "$shortdesc : $description"

    append  hdr "\\title\{[texEscape $titletext]\}" \n
    append  hdr "\\maketitle" \n
    return $hdr
}

c_pass 1 fmt_moddesc   {desc} {c_set_module $desc}
c_pass 2 fmt_moddesc   {desc} NOP

c_pass 1 fmt_titledesc {desc} {c_set_title $desc}
c_pass 2 fmt_titledesc {desc} NOP

c_pass 1 fmt_copyright {desc} {c_set_copyright [texEscape $desc]}
c_pass 2 fmt_copyright {desc} NOP

c_pass 1 fmt_manpage_end {} NOP
c_pass 2 fmt_manpage_end {} {
    set    res ""

    set sa [c_xref_seealso]
    set kw [c_xref_keywords]
    set ct [c_get_copyright]

    if {[llength $sa] > 0} {
	append res [fmt_section {SEE ALSO}] \n
	append res [join [lsort $sa] ", "] \n
    }
    if {[llength $kw] > 0} {
	append res [fmt_section KEYWORDS] \n
	append res [join [lsort $kw] ", "] \n
    }
    if {$ct != {}} {
	append res [fmt_section COPYRIGHT] \n
	append res \\begin\{flushleft\} \n
	append res [join [split $ct \n] \\linebreak\n] \\linebreak\n
	append res \\end\{flushleft\} \n
    }
    append  res "\\end\{document\}"
    return $res
}



proc fmt_section {name} {return "\\section\{$name\}"}
proc fmt_para    {}     {return \n\n}

c_pass 2 fmt_require {pkg {version {}}} NOP
c_pass 1 fmt_require {pkg {version {}}} {
    if {$version != {}} {
	set res "package require [Bold "$pkg $version"]\n"
    } else {
	set res "package require [Bold $pkg]\n"
    }
    c_hold require $res
    return
}

c_pass 2 fmt_usage {cmd args} NOP
c_pass 1 fmt_usage {cmd args} {c_hold synopsis "\\item\[\] $cmd [join $args " "]"}

c_pass 2 fmt_call {cmd args} {return "[fmt_lst_item "$cmd [join $args " "]"]"}
c_pass 1 fmt_call {cmd args} {c_hold synopsis "\\item\[\] $cmd [join $args " "]"}

c_pass 1 fmt_description {} NOP
c_pass 2 fmt_description {} {
    set res ""
    set req [c_held require]
    set syn [c_held synopsis]
    if {$req != {} || $syn != {}} {
	append res [fmt_section SYNOPSIS]\n
	if {$req != {}} {
	    append res \\begin\{flushleft\} \n
	    append res $req \n
	    append res \\end\{flushleft\} \n
	}
	if {$syn != {}} {
	    append res "\\begin\{itemize\}" \n
	    append res ${syn} \n\n
	    append res "\\end\{itemize\}" \n
	}
    }
    append res [fmt_section DESCRIPTION]
    return $res
}

################################################################

global    list_state
array set list_state {level -1}

proc fmt_list_begin  {what {hint {}}} {
    # ignoring hints
    global list_state
    incr list_state(level)
    set  list_state(l,$list_state(level)) $what
    set  list_state(l,$list_state(level),item) 0

    switch -exact -- $what {
	enum {
	    return \\begin\{enumerate\}
	}
	bullet - arg - opt - cmd - tkoption - definitions {
	    return \\begin\{itemize\}
	}
	default {
	    return -code error "Must not happen"
	}
    }
}

proc fmt_list_end {} {
    global list_state

    set what $list_state(l,$list_state(level))
    set item $list_state(l,$list_state(level),item)

    catch {unset list_state(l,$list_state(level))}
    catch {unset list_state(l,$list_state(level),item)}

    incr list_state(level) -1

    switch -exact -- $what {
	enum {
	    return \\end\{enumerate\}
	}
	bullet {
	    return \\end\{itemize\}
	}
	definitions - arg - opt - cmd - tkoption {
	    if {$item} {
		return \\end\{quote\}\n\\end\{itemize\}
	    } else {
		return \\end\{itemize\}
	    }
	}
	default {
	    return -code error "Must not happen"
	}
    }
}

proc fmt_bullet {} {return "\\item\n"}
proc fmt_enum   {} {return "\\item\n"}

proc fmt_lst_item {text} {
    global list_state

    set item $list_state(l,$list_state(level),item)
    set list_state(l,$list_state(level),item) 1

    ## set text [texEscape $text]
    if {$item} {
	return "\\end\{quote\}\n\\item\[\] $text\n\\begin\{quote\}\n"
    } else {
	return "\\item\[\] $text\n\\begin\{quote\}\n"
    }
}

proc fmt_arg_def {type name {mode {}}} {
    global list_state

    set item $list_state(l,$list_state(level),item)
    set list_state(l,$list_state(level),item) 1

    set    text ""
    append text [fmt_arg $name]
    append text " $type"
    if {$mode != {}} {append text " ($mode)"}

    if {$item} {
	return "\\end\{quote\}\n\\item\[\] $text\n\\begin\{quote\}\n"
    } else {
	return "\\item\[\] $text\n\\begin\{quote\}\n"
    }
}

proc fmt_cmd_def {command} {
    global list_state

    set item $list_state(l,$list_state(level),item)
    set list_state(l,$list_state(level),item) 1

    set text [fmt_cmd $command]

    if {$item} {
	return "\\end\{quote\}\n\\item\[\] $text\n\\begin\{quote\}\n"
    } else {
	return "\\item\[\] $text\n\\begin\{quote\}\n"
    }
}

proc fmt_opt_def {name {arg {}}} {
    global list_state

    set item $list_state(l,$list_state(level),item)
    set list_state(l,$list_state(level),item) 1

    set text [fmt_option $name]
    if {$arg != {}} {append text " $arg"}

    if {$item} {
	return "\\end\{quote\}\n\\item\[\] $text\n\\begin\{quote\}\n"
    } else {
	return "\\item\[\] $text\n\\begin\{quote\}\n"
    }
}

proc fmt_tkoption_def {name dbname dbclass} {
    global list_state

    set item $list_state(l,$list_state(level),item)
    set list_state(l,$list_state(level),item) 1

    set    text ""
    append text "Command-Line Switch:	[Bold $name]\\\\\n"
    append text "Database Name:	[Bold $dbname]\\\\\n"
    append text "Database Class:	[Bold $dbclass]\\\\\n"

    if {$item} {
	return "\\end\{quote\}\n\\item\[\] $text\n\\begin\{quote\}\n"
    } else {
	return "\\item\[\] $text\n\\begin\{quote\}\n"
    }
}

################################################################

proc fmt_example_begin {} {
    global _in_example
    set    _in_example 1
    return {\begin{verbatim}}
}
proc fmt_example_end   {} {
    global _in_example
    set    _in_example 0
    return {\end{verbatim}}
}
# No mapping of special characters
proc fmt_example {code} { return "\\begin\{verbatim\}\n${code}\n\\end\{verbatim\}\n" }

proc fmt_nl     {}     {return}
proc fmt_arg    {text} {Underline $text}
proc fmt_cmd    {text} {Bold      $text}
proc fmt_emph   {text} {Italic    $text}
proc fmt_opt    {text} {return   ?$text?}

proc fmt_comment {text} {
    set res [list]
    foreach l [split $text \n] {
	lappend res [Comment $l]
    }
    return [join $res \n]
}
proc fmt_sectref {text} {Bold $text}
proc fmt_syscmd  {text} {Bold $text}
proc fmt_method  {text} {Bold $text}
proc fmt_option  {text} {Bold $text}
proc fmt_widget  {text} {Bold $text}
proc fmt_fun     {text} {Bold $text}
proc fmt_type    {text} {Bold $text}
proc fmt_package {text} {Bold $text}
proc fmt_class   {text} {Bold $text}
proc fmt_var     {text} {Bold $text}
proc fmt_file    {text} {return "\"[Italic $text]\""}
proc fmt_namespace     {text} {Bold $text}
proc fmt_uri     {text {label {}}} {
    if {$label == {}} {
	# Without label we use the link directly as part of the text.
	return [Underline $text]
    } else {
	# Label is used in the text, refered link is delegated into a
	# footnote.
	return "[Underline $label] \\footnote\{[texEscape $text]\}"
    }
}
proc fmt_term    {text} {Italic $text}
proc fmt_const   {text} {Bold $text}


################################################################
# latex specific commands

proc Comment   {text} {return "% [join [split $text \n] "\n% "]"}
proc Bold      {text} {return "\{\\bf [texEscape $text]\}"}
proc Italic    {text} {return "\{\\it [texEscape $text]\}"}
proc Underline {text} {return "\\underline\{[texEscape $text]\}"}

################################################################

proc texEscape {text} {
    string map {_ \\_ % \\% $ \\$ < $<$ > $>$ # \\# & \\&} $text
}

################################################################
