head	1.15;
access;
symbols
	tcllib-1-13:1.15
	tcllib-1-12:1.15
	tklib-0-5:1.15
	tcllib-1-11-1:1.15
	tcllib-1-11:1.15
	tcllib-1-10:1.15
	tcllib-1-9:1.15
	tcllib-1-8:1.15
	tcllib-1-7:1.15
	tcllib-1-6-1:1.14.2.1
	tcllib-1-6-branch:1.14.0.2
	tcllib-1-6:1.14
	tcllib-1-4-0:1.14
	tcllib-1-3-0:1.10
	tcllib-1-2-0:1.1.0.4
	RELEASES:1.1.0.2;
locks; strict;
comment	@# @;


1.15
date	2004.03.09.08.20.19;	author andreas_kupries;	state Exp;
branches;
next	1.14;

1.14
date	2003.01.19.07.58.44;	author andreas_kupries;	state Exp;
branches
	1.14.2.1;
next	1.13;

1.13
date	2003.01.03.02.51.03;	author davidw;	state Exp;
branches;
next	1.12;

1.12
date	2002.12.16.08.59.35;	author davidw;	state Exp;
branches;
next	1.11;

1.11
date	2002.09.23.08.03.38;	author andreas_kupries;	state Exp;
branches;
next	1.10;

1.10
date	2002.05.09.22.26.56;	author jenglish;	state Exp;
branches;
next	1.9;

1.9
date	2002.04.10.18.21.15;	author andreas_kupries;	state Exp;
branches;
next	1.8;

1.8
date	2002.04.03.05.28.53;	author andreas_kupries;	state Exp;
branches;
next	1.7;

1.7
date	2002.04.01.14.58.06;	author andreas_kupries;	state Exp;
branches;
next	1.6;

1.6
date	2002.03.27.03.05.04;	author andreas_kupries;	state Exp;
branches;
next	1.5;

1.5
date	2002.03.26.07.40.36;	author andreas_kupries;	state Exp;
branches;
next	1.4;

1.4
date	2002.03.10.02.49.52;	author andreas_kupries;	state Exp;
branches;
next	1.3;

1.3
date	2002.02.28.07.03.20;	author andreas_kupries;	state Exp;
branches;
next	1.2;

1.2
date	2002.02.12.23.00.12;	author jenglish;	state Exp;
branches;
next	1.1;

1.1
date	2001.12.14.23.10.32;	author andreas_kupries;	state Exp;
branches;
next	;

1.14.2.1
date	2004.05.24.02.58.10;	author andreas_kupries;	state Exp;
branches;
next	;


desc
@@


1.15
log
@Unified the startup header of all applications, using
suggestions made by Stuart Cassof <stwo@@telus.net>.
@
text
@#! /bin/sh
# -*- tcl -*- \
exec tclsh "$0" ${1+"$@@"}

lappend auto_path [file dirname [file dirname [info script]]]
package require doctools

# ---------------------------------------------------------------------
#  1. Handle command line options, input and output
#  2. Initialize a doctools object.
#  3. Run the input through the object.
#  4. Write output.
# ---------------------------------------------------------------------

proc usage {{exitstate 1}} {
    global argv0
    puts "Usage: $argv0\
	    ?-h|--help|-help|-??\
	    ?-help-fmt|--help-fmt?\
	    ?-module module?\
	    ?-deprecated?\
	    ?-copyright text?\
	    format in|- ?out|-?"
    exit $exitstate
}

# ---------------------------------------------------------------------

proc fmthelp {} {
    # Tcllib FR #527029: short reference of formatting commands.

    global argv0
    puts "$argv0 [doctools::help]"
    exit 0
}

# ---------------------------------------------------------------------
# 1. Handle command line options, input and output

proc cmdline {} {
    global argv0 argv format in out extmodule deprecated copyright

    set copyright ""
    set extmodule ""
    set deprecated 0

    while {[string match -* [set opt [lindex $argv 0]]]} {
	switch -exact -- $opt {
	    -module {
		set extmodule [lindex $argv 1]
		set argv [lrange $argv 2 end]
		continue
	    }
	    -copyright {
		set copyright [lindex $argv 1]
		set argv [lrange $argv 2 end]
		continue
	    }
	    -deprecated {
		set deprecated 1
		set argv [lrange $argv 1 end]
	    }
	    -help - -h - --help - -? {
		# Tcllib FR #527029
		usage 0
	    }
	    -help-fmt - --help-fmt {
		# Tcllib FR #527029
		fmthelp
	    }
	    default {
		# Unknown option
		usage
	    }
	}
    }

    if {[llength $argv] < 3} {
	usage
    }
    foreach {format in out} $argv break

    if {$format == {} || $in == {}} {
	usage
    }
    if {$out == {}} {set out -}
    return $format
}

# ---------------------------------------------------------------------
#  3. Read input. Also providing the namespace with file information.

proc get_input {} {
    global in
    if {[string equal $in -]} {
	return [read stdin]
    } else {
	set if [open $in r]
	set text [read $if]
	close $if
	return $text
    }
}

# ---------------------------------------------------------------------
# 4. Write output.

proc write_out {text} {
    global out
    if {[string equal $out -]} {
	puts -nonewline stdout $text
    } else {
	set of [open $out w]
	puts -nonewline $of $text
	close $of
    }
}


# ---------------------------------------------------------------------
# Get it all together

proc main {} {
    global format deprecated extmodule in copyright

    #if {[catch {}
	cmdline

	::doctools::new dt -format $format -deprecated $deprecated -file $in
	if {$extmodule != {}} {
	    dt configure -module $extmodule
	}
	if {$copyright != {}} {
	    dt configure -copyright $copyright
	}

	write_out [dt format [get_input]]

	set warnings [dt warnings]
	if {[llength $warnings] > 0} {
	    puts stderr [join $warnings \n]
	}

	#{} msg]} {}
	#puts stderr "Execution error: $msg"
    #{}
    return
}


# ---------------------------------------------------------------------
main
exit
@


1.14
log
@
	* More doctools changes: Command [strong] is deprecated now. Added
	  the command [copyright]. Went through all manpages to eliminate
	  [strong]. Partial setting of copyright information, where known.

	* mkInstallScripts.tcl:
	* Makefile.in (install-libraries): Added module specific
	  installation code.

	  doctools: Install message catalogs and predefined formatting
	  engines.

	  textutil: Install hyphenation files.

	* Module doctools rewritten to make it a true package +
	  application, instead of a pure application module. This means
	  that this module now truly installs some functionality useable
	  by other applications and packages.

	----------------------------------------------------------------

	* mpformats/fmt.html:  Removed 'strong' formatting. The checker
	* mpformats/fmt.latex: warns if used and warnings requested, it
	* mpformats/fmt.nroff: now also redirects the command to 'emph'.
	* mpformats/fmt.wiki:  The option -visualwarn (doctools, and
	* mpformats/fmt.null:  mpexpand) renamed to -deprecated. Message
	* mpformats/fmt.list:  'visualmarkup' removed from the catalogs,
	* mpformats/c.msg:     and 'depr_strong' added instead.
	* mpformats/en.msg:
	* mpformats/de.msg:
	* checker.tcl:
	* doctools.tcl:
	* mpexpand:

	* doctools.man:    Updated, converted [strong] to better
	* dtformat.man:    formatting commands. Ditto for all manpages
	* dtformatter.man: in tcllib containing 'strong'. 'strong' is now
	* mpexpand.man:    not present anymore.

	* mpformats/_common.tcl: Applied a patch by Joe English adding the
	* mpformats/fmt.tmml:    copyright information to the appropriate
	                         place in the TMML output. This also fixes
				 a bug in c_get_copyright where an empty
				 string resulted in a incomplete line
				 being given to the formatter.

	* mpformats/fmt.html:  Removed the phrase 'All rights reserved'
	* mpformats/fmt.latex: from the code, on recommendation by
	* mpformats/fmt.nroff: Joe English.
	* mpformats/fmt.wiki:

	* mpformats/fmt.html:  Changed to display copyright information in
	* mpformats/fmt.latex: the conversion result itself and not only
	* mpformats/fmt.nroff: embedded in comments.
	* mpformats/fmt.wiki:

	* doctools.tcl:          Added a new formatting command,
	* doctools.test:         'copyright', to declare/assign copyright
	* doctools.man:          for manpages. Updated both documentation
	* dtformat.man:          and testsuite. Extended the common code
	* checker.tcl:           base with convenience methods for storing
	* api.tcl:               and retrieving such information. The
	* mpformats/fmt.html:    retrieval operation also implements the
	* mpformats/fmt.latex:   logic giving the information in a manpage
	* mpformats/fmt.list:    precedence over information coming from the
	* mpformats/fmt.nroff:   processor. Updated all predefined engines
	* mpformats/fmt.null:    to handle the new command. TMML done only
	* mpformats/fmt.tmml:    partially, as I don't know where the copy-
	* mpformats/fmt.wiki:    right has to go.
	* mpformats/_common.tcl:
	* mpformats/_html.tcl:
	* mpformats/_nroff.tcl:
	* mpexpand:

	* mpexpand:      Moved format help into the package itself.
	* doctools.tcl:  Changed the checker. Input syntax errors are not
	* checker.tcl:   written to stderr anymore, but reported through
	* doctools.man:  an standard tcl error. Warnings are collected and
	* doctools.test: can be queried after a formatting run. Made the
	                 generic engine more robust against failures in a
			 formatting engine. Wrote documentation for the
			 package. Extended the configuration method to be
			 more standard. Wrote a testsuite.

	* mpexpand:              Nearly complete rewrite of the system.
	* mpformats/fmt.html:    The recognized input format was _not_
	* mpformats/fmt.latex:   changed.  The main functionality was
	* mpformats/fmt.list:    placed into a package, doctools.  This
	* mpformats/fmt.nroff:   package allows the creation of multiple
	* mpformats/fmt.null:    formatter objects, to be used alone or
	* mpformats/fmt.tmml:    together.  The application 'mpexpand' was
	* mpformats/fmt.wiki:    rewritten to use that package and is now
	* mpformats/_common.tcl: much simpler.  The communication between
	* mpformats/_nroff.tcl:  the various stages was made simpler, and
	* mpformats/_xml.tcl:    one slave interpreter was dropped because
	* mpformats/_html.tcl:   of this.  It might be added back if its
	* api.tcl:               existence proves to be beneficial.  The
	* checker.tcl:           API between main systen and formatter
	* doctools.tcl:          engine was changed, consequently all
	* dtformatter.man:       existing engines had to be updated.  They
	                         were also made simpler, especially in the
	                         area of list handling, because of the
				 validation done by the checker subsystem.
				 The version number is now 1.0.
@
text
@d1 1
a1 1
#!/bin/sh
@


1.14.2.1
log
@Downgraded to version 1.3.6, removed -decode extension from
this branch.

Import of ftpd bugfix by Gerald Lester.

Last commit was a bad update, caused duplicates of changes
to appear. Failed testsuite. Removed all the duplicates now.

Fixed SF Tcllib Bug 954328. Mime now adapts at runtime to
whatever version of md5 has been loaded.

Updated test for rewritten adjust which fixed the infinite
looping demonstrated by tests 2.6 and 2.7. Also fixed a var
usage typo which caused a copy of the input to appear in the
output, before the expected formatted result.

Fixed bug in the processing of multi-word section titles for
text based formats.

Fixed bug 951568, regarding the usage of Trf's generic
transform.

Fixed problems with jpeg recognition (was unable to detect a
jpeg file, if it contained exif data).

Changelog for last patch, and updates in related package.

Completed application of code for various fixes.

Rewritten text adjustment and hyphenation, fixing SF TCllib
Bug 882402.

Fixed SF Tcllib Bug 936064, and evals more robust.

Fixed SF Tcllib Bug 893516

Fixed SF Tcllib Patch 763712

Fixed SF Tcllib Patch 758742

Fixed SF Tcllib Bug 620852

Eval usage made more robust and similar.

Fixed SF Tcllib Bug 943146.

Fixed SF Tcllib Bug 940651

SF Tcllib Bug 784519 fixed.

Pat: sak.tcl update for better use of critcl.

Joe: Fix in doctools xml support.

Import bugfix by Pat Thoyts, Handling of data starting with
hyphen/dash

Import of uuencode changes by Jeff Hobbs.

Changed defaults for package 'log'. No output for the all
levels below 'error'.

Unified the startup header of all applications, using
suggestions made by Stuart Cassof <stwo@@telus.net>.

Added testcase for Tcllib SF Bug 860753. The bug itself was
already fixed for Tcllib 1.6.

Fix for bug 899204. Test data file is opened read-only, and
tests made independent of each other.

Bugfix 899152, 899209. Require Tcl 8.2 for installer, delete
file before writing over it.

Import of time fix by Pat Thoyts, patch #905132.

Cleanup fix: Snit depends on Tcl 8.4, this is documented,
however neither package index, nor testsuite enforced the
restriction, allowing for errors. This has been changed now.

Fixed typos
@
text
@d1 1
a1 1
#! /bin/sh
@


1.13
log
@Fixed spelling error.
@
text
@d5 2
a6 1
package require textutil::expander
d10 3
a12 11
#  2. Read formatting macros into a namespace
#  3. Determine if 1- or 2-pass.
#  4. Create expander object, setup with command callback to evaluate
#     everything in the namespace containing the formatting commands.
#  5. Read input
#  6. Run pre-pass-hook, optional
#  7. Pass 1 through expander.
#  8. Run pre-pass-hook, optional       | either both or none
#  9. Pass 2 through expander, optional |
# 10. Run output through post-hook, optional
# 11. Write output.
d21 2
a22 1
	    ?-visualwarn?\
d33 1
a33 47
    puts "$argv0 formatting commands\n\
	    * manpage_begin - begin of manpage\n\
	    * moddesc       - module description\n\
	    * titledesc     - manpage title\n\
	    * manpage_end   - end of manpage\n\
	    * require       - package requirement\n\
	    * description   - begin of manpage body\n\
	    * section       - begin new section of body\n\
	    * para          - begin new paragraph\n\
	    * list_begin    - begin a list\n\
	    * list_end      - end of a list\n\
	    * lst_item      - begin item of definition list\n\
	    * call          - command definition, adds to synopsis\n\
	    * usage         - see above, without adding to synopsis\n\
	    * bullet        - begin item in bulleted list\n\
	    * enum          - begin item in enumerated list\n\
	    * arg_def       - begin item in argument list\n\
	    * cmd_def       - begin item in command list\n\
	    * opt_def       - begin item in option list\n\
	    * tkoption_def  - begin item in tkoption list\n\
	    * example       - example block\n\
	    * example_begin - begin example\n\
	    * example_end   - end of example\n\
	    * see_also      - cross reference declaration\n\
	    * keywords      - keyword declaration\n\
	    * nl            - paragraph break in list items\n\
	    * arg           - semantic markup - argument\n\
	    * cmd           - semantic markup - command\n\
	    * opt           - semantic markup - optional data\n\
	    * comment       - semantic markup - comment\n\
	    * sectref       - semantic markup - section reference\n\
	    * syscmd        - semantic markup - system command\n\
	    * method        - semantic markup - object method\n\
	    * option        - semantic markup - option\n\
	    * widget        - semantic markup - widget\n\
	    * fun           - semantic markup - function\n\
	    * type          - semantic markup - data type\n\
	    * package       - semantic markup - package\n\
	    * class         - semantic markup - class\n\
	    * var           - semantic markup - variable\n\
	    * file          - semantic markup - file \n\
	    * uri           - semantic markup - uri\n\
	    * term          - semantic markup - unspecific terminology\n\
	    * const         - semantic markup - constant value\n\
	    * emph          - visual markup - light emphasis, usage is discouraged\n\
	    * strong        - visual markup - strong emphasis, usage is discouraged\n\
	    "
d41 1
a41 1
    global argv0 argv format in out extmodule visualwarn
d43 1
d45 1
a45 1
    set visualwarn 0
d54 7
a60 2
	    -visualwarn {
		set visualwarn 1
d87 1
d91 1
a91 524
#  2. Read formatting macros and setup evalution environment.

proc format_find {} {
    global format fmtfile argv0

    set _here [file dirname [file join [pwd] [info script]]]

    set fmtfile {}
    foreach p [list \
	    [file join $_here mpformats fmt.$format] \
	    [file join [file dirname $_here] lib doctools mpformats fmt.$format] \
	    ] {
	if {[file exists $p]} {
	    set fmtfile $p
	    break
	}
    }

    if {[string equal $fmtfile ""]} {
	puts "$argv0: Unknown format \"$format\""
	exit 1
    }
}

# ---------------------------------------------------------------------
#  4. Create expander object, setup with command callback to evaluate
#     everything in the namespace containing the formatting commands.

proc eval_setup {} {
    global argv0 format fmtfile mpip inip ckip passes visualwarn

    set apibase [file join [file dirname $fmtfile] _api.tcl]
    set mpip [interp create] ; # interpreter for the formatting engine
    set inip [interp create] ; # interpreter for code in the input/manpage.
    set ckip [interp create] ; # interpreter hosting the formal format checker

    $ckip eval {
	package require msgcat
	proc ::msgcat::mcunknown {locale code} {
	    return "unknown error code \"$code\""
	}
    }
    # Provide l10n
    $ckip eval [list ::msgcat::mcload [set f [file join [file dirname [info script]] mpformats]]]

    # Basic format definitions with error message. We expect that all
    # of these are overwritten by the actual format definition. Then
    # read the format itself.

    $mpip eval {rename file __file} ; # protect the original file command.
    $mpip eval [list source $apibase]
    $mpip eval [list source $fmtfile]

    # Create the expander object associated to the sub interpreter and
    # set it up so that all macros found in the input are evaluated
    # inside of the input subinterpreter.

    ::textutil::expander ::mp
    ::mp evalcmd mpEval
    ::mp textcmd __mpText__

    # Link global information commands into format and input interpreters.

    interp alias $mpip mp_pass   {} mpPass
    interp alias $mpip mp_file   {} mpFile
    interp alias $mpip mp_module {} mpModule

    interp alias $inip mp_pass   {} mpPass
    interp alias $inip mp_file   {} mpFile
    interp alias $inip mp_module {} mpModule

    # Link the formatting commands, limited access to the expander
    # object and information commands into the input interpreter.

    foreach cmd {
	cappend cget cis cname cpop cpush cset lb rb
    } {
	interp alias $inip $cmd {} ::mp $cmd
	interp alias $mpip $cmd {} ::mp $cmd
    }
    foreach cmd {
	manpage_begin moddesc titledesc manpage_end require description
	section para list_begin list_end lst_item call bullet enum
	example example_begin example_end see_also keywords nl arg cmd opt
	comment sectref syscmd method option widget fun type package
	class var file uri usage term const arg_def cmd_def opt_def
	tkoption_def
    } {
	# We link the formatter commands into the input interpreter
	# and route them to the checking commands in the checker. We
	# also link the formatter commands into the checker, so that
	# it is able to forward the accepted invocations to the
	# actual formatter.

	interp alias $inip $cmd $ckip ck_$cmd
	interp alias $ckip $cmd $mpip $cmd
    }
    if {$visualwarn} {
	# Route "visual" markup through procedures which generate warnings on stderr.
	foreach cmd {emph strong} {
	    interp alias $inip $cmd {}  __$cmd
	    interp alias $ckip $cmd $mpip $cmd
	}
    } else {
	foreach cmd {emph strong} {
	    interp alias $inip $cmd $ckip ck_$cmd
	    interp alias $ckip $cmd $mpip $cmd
	}
    }

    # Reroute the handling of plain text into the formatter
    interp alias $inip __mpText__ $ckip ck_plain_text
    interp alias $ckip HandleText $mpip HandleText

    # ---------------------------------------------------------------------
    # Now initialize the format checker (state, commands)

    $ckip eval {
	global state lstctx lstitem
	# --------------+-----------------------+----------------------
	# state		| allowed commands	| new state (if any)
	# --------------+-----------------------+----------------------
	# all except	| arg cmd opt comment	|
	#  for "done"	| syscmd method option	|
	#		| widget fun type class	|
	#		| package var file uri	|
	#		| strong emph		|
	# --------------+-----------------------+----------------------
	# manpage_begin	| manpage_begin		| header
	# --------------+-----------------------+----------------------
	# header	| moddesc titledesc	| header
	#		+-----------------------+-----------
	#		| require		| requirements
	#		+-----------------------+-----------
	#		| description		| body
	# --------------+-----------------------+----------------------
	# requirements	| require		| requirements
	#		+-----------------------+-----------
	#		| description		| body
	# --------------+-----------------------+----------------------
	# body		| section para list_end	| body
	#		| list_begin lst_item	|
	#		| call bullet usage nl	|
	#		| example see_also	|
	#		| keywords sectref enum	|
	#		| arg_def cmd_def	|
	#		| opt_def tkoption_def	|
	#		+-----------------------+-----------
	#		| example_begin		| example
	#		+-----------------------+-----------
	#		| manpage_end		| done
	# --------------+-----------------------+----------------------
	# example	| example_end		| body
	# --------------+-----------------------+----------------------
	# done		|			|
	# --------------+-----------------------+----------------------
	#
	# Additional checks
	# --------------------------------------+----------------------
	# list_begin/list_end			| Are allowed to nest.
	# --------------------------------------+----------------------
	# 	lst_item/call			| Only in 'definition list'.
	# 	enum				| Only in 'enum list'.
	# 	bullet				| Only in 'bullet list'.
	#	arg_def				| Only in 'argument list'.
	#	cmd_def				| Only in 'command list'.
	#	opt_def				| Only in 'option list'.
	#	tkoption_def			| Only in 'tkoption list'.
	#	nl				| Only in list item context.
	#	para section			| Not allowed in list context
	# --------------------------------------+----------------------

	# -------------------------------------------------------------
	# Helpers
	proc Error {code} {
	    global state lstctx lstitem

	    # Problematic command with all arguments (we strip the "ck_" prefix!)
	    # -*- future -*- count lines of input, maintain history buffer, use
	    # -*- future -*- that to provide some context here.

	    set cmd  [string range [lindex [info level 1] 0] 3 end]
	    set args [lrange [info level 1] 1 end]
	    if {$args != {}} {append cmd " [join $args]"}
	    
	    # Use a message catalog to map the error code into a legible message.
	    set msg [::msgcat::mc $code]

	    puts stderr "Manpage error ($code), \"$cmd\" : ${msg}."
	    exit 1
	    return
	}
	proc Is    {s} {global state ; return [string equal $state $s]}
	proc IsNot {s} {global state ; return [expr {![string equal $state $s]}]}
	proc Go    {s} {global state ; set state $s; return}
	proc LPush {l} {
	    global lstctx lstitem
	    set    lstctx [linsert $lstctx 0 $l $lstitem]
	    return
	}
	proc LPop {} {
	    global lstctx lstitem
	    set lstitem [lindex $lstctx 1]
	    set lstctx  [lrange $lstctx 2 end]
	    return
	}
	proc LSItem {} {global lstitem ; set lstitem 1}
	proc LIs  {l} {global lstctx ; string equal $l [lindex $lstctx 0]}
	proc LItem {} {global lstitem ; return $lstitem}
	proc LOpen {} {
	    global lstctx
	    expr {$lstctx != {}}
	}
	# -------------------------------------------------------------
	# Framing
	proc ck_initialize {} {
	    global state   ; set state manpage_begin
	    global lstctx  ; set lstctx [list]
	    global lstitem ; set lstitem 0
	    return
	}
	proc ck_complete {} {
	    if {[Is done]} {
		if {![LOpen]} {
		    return
		} else {
		    Error end/open/list
		}
	    } elseif {[Is example]} {
		Error end/open/example
	    } else {
		Error end/open/mp
	    }
	    return
	}
	# -------------------------------------------------------------
	# Plain text
	proc ck_plain_text {text} {
	    # Only in body, not between list_begin and first item.
	    # Ignore everything which is only whitespace ...

	    set redux [string map [list " " "" "\t" "" "\n" ""] $text]
	    if {$redux == {}} {return [HandleText $text]}
	    if {[IsNot body] && [IsNot example]} {Error body}
	    if {[LOpen] && ![LItem]} {Error nolisttxt}
	    return [HandleText $text]
	}
	# -------------------------------------------------------------
	# Formatting commands
	proc ck_manpage_begin {title section version} {
	    if {[IsNot manpage_begin]} {Error mpbegin}
	    Go header
	    manpage_begin $title $section $version
	}
	proc ck_moddesc {desc} {
	    if {[IsNot header]} {Error hdrcmd}
	    moddesc $desc
	}
	proc ck_titledesc {desc} {
	    if {[IsNot header]} {Error hdrcmd}
	    titledesc $desc
	}
	proc ck_manpage_end {} {
	    if {[IsNot body]} {Error bodycmd}
	    Go done
	    manpage_end
	}
	proc ck_require {pkg {version {}}} {
	    if {[IsNot header] && [IsNot requirements]} {Error reqcmd}
	    Go requirements
	    require $pkg $version
	}
	proc ck_description {} {
	    if {[IsNot header] && [IsNot requirements]} {Error reqcmd}
	    Go body
	    description
	}
	proc ck_section {name} {
	    if {[IsNot body]} {Error bodycmd}
	    if {[LOpen]}      {Error nolistcmd}
	    section $name
	}
	proc ck_para {} {
	    if {[IsNot body]} {Error bodycmd}
	    if {[LOpen]}      {Error nolistcmd}
	    para
	}
	proc ck_list_begin {what {hint {}}} {
	    if {[IsNot body]}        {Error bodycmd}
	    if {[LOpen] && ![LItem]} {Error nolisthdr}
	    LPush      $what
	    list_begin $what $hint
	}
	proc ck_list_end {} {
	    if {[IsNot body]} {Error bodycmd}
	    if {![LOpen]}     {Error listcmd}
	    LPop
	    list_end
	}
	proc ck_lst_item {{text {}}} {
	    if {[IsNot body]}       {Error bodycmd}
	    if {![LOpen]}           {Error listcmd}
	    if {![LIs definitions]} {Error deflist}
	    LSItem
	    lst_item $text
	}
	proc ck_arg_def {type name {mode {}}} {
	    if {[IsNot body]}       {Error bodycmd}
	    if {![LOpen]}           {Error listcmd}
	    if {![LIs arg]}         {Error arg_list}
	    LSItem
	    arg_def $type $name $mode
	}
	proc ck_cmd_def {command} {
	    if {[IsNot body]}       {Error bodycmd}
	    if {![LOpen]}           {Error listcmd}
	    if {![LIs cmd]}         {Error cmd_list}
	    LSItem
	    cmd_def $command
	}
	proc ck_opt_def {name {arg {}}} {
	    if {[IsNot body]}       {Error bodycmd}
	    if {![LOpen]}           {Error listcmd}
	    if {![LIs opt]}         {Error opt_list}
	    LSItem
	    opt_def $name $arg
	}
	proc ck_tkoption_def {name dbname dbclass} {
	    if {[IsNot body]}       {Error bodycmd}
	    if {![LOpen]}           {Error listcmd}
	    if {![LIs tkoption]}    {Error tkoption_list}
	    LSItem
	    tkoption_def $name $dbname $dbclass
	}
	proc ck_call {cmd args} {
	    if {[IsNot body]}       {Error bodycmd}
	    if {![LOpen]}           {Error listcmd}
	    if {![LIs definitions]} {Error deflist}
	    LSItem
	    eval [linsert $args 0 call $cmd]
	}
	proc ck_bullet {} {
	    if {[IsNot body]}  {Error bodycmd}
	    if {![LOpen]}      {Error listcmd}
	    if {![LIs bullet]} {Error bulletlist}
	    LSItem
	    bullet
	}
	proc ck_enum {} {
	    if {[IsNot body]} {Error bodycmd}
	    if {![LOpen]}     {Error listcmd}
	    if {![LIs enum]}  {Error enumlist}
	    LSItem
	    enum
	}
	proc ck_example {code} {
	    return [ck_example_begin][ck_plain_text ${code}][ck_example_end]
	}
	proc ck_example_begin {} {
	    if {[IsNot body]}        {Error bodycmd}
	    if {[LOpen] && ![LItem]} {Error nolisthdr}
	    Go example
	    example_begin
	}
	proc ck_example_end {} {
	    if {[IsNot example]} {Error examplecmd}
	    Go body
	    example_end
	}
	proc ck_see_also {args} {
	    if {[IsNot body]} {Error bodycmd}
	    if {[LOpen]}      {Error nolistcmd}
	    eval [linsert $args 0 see_also]
	}
	proc ck_keywords {args} {
	    if {[IsNot body]} {Error bodycmd}
	    if {[LOpen]}      {Error nolistcmd}
	    eval [linsert $args 0 keywords]
	}
	proc ck_nl {} {
	    if {[IsNot body]} {Error bodycmd}
	    if {![LOpen]}     {Error listcmd}
	    if {![LItem]}     {Error nolisthdr}
	    nl
	}
	proc ck_emph {text} {
	    if {[Is done]} {Error nodonecmd}
	    emph $text
	}
	proc ck_strong {text} {
	    if {[Is done]} {Error nodonecmd}
	    strong $text
	}
	proc ck_arg {text} {
	    if {[Is done]} {Error nodonecmd}
	    arg $text
	}
	proc ck_cmd {text} {
	    if {[Is done]} {Error nodonecmd}
	    cmd $text
	}
	proc ck_opt {text} {
	    if {[Is done]} {Error nodonecmd}
	    opt $text
	}
	proc ck_comment {text} {
	    if {[Is done]} {Error nodonecmd}
	    comment $text
	}
	proc ck_sectref {name} {
	    if {[IsNot body]}        {Error bodycmd}
	    if {[LOpen] && ![LItem]} {Error nolisthdr}
	    sectref $name
	}
	proc ck_syscmd {text} {
	    if {[Is done]} {Error nodonecmd}
	    syscmd $text
	}
	proc ck_method {text} {
	    if {[Is done]} {Error nodonecmd}
	    method $text
	}
	proc ck_option {text} {
	    if {[Is done]} {Error nodonecmd}
	    option $text
	}
	proc ck_widget {text} {
	    if {[Is done]} {Error nodonecmd}
	    widget $text
	}
	proc ck_fun {text} {
	    if {[Is done]} {Error nodonecmd}
	    fun $text
	}
	proc ck_type {text} {
	    if {[Is done]} {Error nodonecmd}
	    type $text
	}
	proc ck_package {text} {
	    if {[Is done]} {Error nodonecmd}
	    package $text
	}
	proc ck_class {text} {
	    if {[Is done]} {Error nodonecmd}
	    class $text
	}
	proc ck_var {text} {
	    if {[Is done]} {Error nodonecmd}
	    var $text
	}
	proc ck_file {text} {
	    if {[Is done]} {Error nodonecmd}
	    file $text
	}
	proc ck_uri {text} {
	    if {[Is done]} {Error nodonecmd}
	    uri $text
	}
	proc ck_usage {text} {
	    if {[Is done]} {Error nodonecmd}
	    usage $text
	}
	# -------------------------------------------------------------
    }

    # ---------------------------------------------------------------------
    #  3. Determine if 1- or 2-pass.

    set passes [$mpip eval {NumPasses}]
    if {![string is integer $passes] || ($passes < 1)} {
	puts "${argv0}: $format error: illegal number of passes \"$passes\""
	exit 1
    }

    return
}

# Execute a macro from the input. Special handling for the plain text
# command.

proc mpEval {macro} {
    global inip
    $inip eval $macro
}

# Define/retrieve number of current pass.
proc mpPass {{n {}}} {
    global __pass
    if {$n != {}} {
	set __pass $n
    }
    return $__pass
}

proc mpFile {} {
    global  in
    return $in
}

proc mpModule {} {
    global  in extmodule

    if {$extmodule != {}} {
	return $extmodule
    }
    return [file tail [file rootname $in]]
}

proc __strong {text} {
    global ckip
    puts stderr "\tVisual markup: \"\[strong \{$text\}\]\""
    puts stderr "\tPlease consider appropriate semantic markup instead."
    return [$ckip eval [list strong $text]]
}

proc __emph {text} {
    global ckip
    puts stderr "\tVisual markup: \"\[emph \{$text\}\]\""
    puts stderr "\tPlease consider appropriate semantic markup instead."
    return [$ckip eval [list emph $text]]
}

# ---------------------------------------------------------------------
#  5. Read input. Also providing the namespace with file information.
d94 1
a94 2
    global in text

d96 1
a96 2
	set text [read stdin]
	set in stdin
d101 1
d106 1
a106 36
#  6. Run pre-pass-hook, optional
#  7. Pass 1 through expander.
#  8. Run pre-pass-hook, optional       | either both or none
#  9. Pass 2 through expander, optional |

proc passes {} {
    global mpip ckip text expansion passes

    set n 1
    while {$passes > 0} {
	mpPass $n
	$mpip eval PassSetup

	$ckip eval ck_initialize
	set expansion [::mp expand $text]
	$ckip eval ck_complete

	incr passes -1
	incr n
    }
    return
}

# ---------------------------------------------------------------------
# 10. Run output through post-hook, optional

proc postprocess {} {
    global expansion   mpip
    set    expansion [$mpip eval [list PostProcess $expansion]]
}

# ---------------------------------------------------------------------
# 11. Write output.

proc write_expansion {} {
    global out expansion
d108 2
d111 1
a111 1
	puts -nonewline stdout $expansion
d114 1
a114 1
	puts -nonewline $of $expansion
d124 24
a147 7
    cmdline
    format_find
    eval_setup
    get_input
    passes
    postprocess
    write_expansion
@


1.12
log
@* mpexpand (format_find): Added 'argv0' as a global variable, in order
  to avoid erroring out when providing a bad format.
@
text
@d136 1
a136 1
#  2. Read formatting macros and setup evalutin environment
@


1.11
log
@
	* mpexpand: Corrected example formatting, have to run argument
	  through plain text handling.
	* mpformats/fmt.wiki: Added Wiki formatting.
@
text
@d139 1
a139 1
    global format fmtfile
@


1.10
log
@[AKU] Added new list types for arguments, options, commands, and Tk options.
@
text
@d492 1
a492 1
	    return [ck_example_begin]${code}[ck_example_end]
@


1.9
log
@
doctools
	* mpexpand: Fixed error in checker of plain text.

	* mpformats/fmt.nroff: Added newlines in front of dot commands to
	  make sure that the formatting is correct. Superfluous newlines
	  are stripped in the post processor of this format, so
	  unconditionally adding them does not hurt.

smtpd
	* smtpd.man: Added doctools manpage.
@
text
@d55 4
d221 2
a222 1
	class var file uri usage term const
d281 2
d300 4
d441 28
@


1.8
log
@
	* mpformats/en.msg:
	* mpformats/c.msg:
	* mpformats/de.msg: Added the messages required by the new code
	  below.

	* mpexpand: Added code to check that plain text is not used in
	  places where it is not allowed.
@
text
@d367 1
a367 1
	    if {$redux == {}} {return}
@


1.7
log
@
	* Committed changes to list generation (better generation of
	  whitespace for HTML, allowing hints). Only the HTML formatter
	  currently acknowledges hints.

	* tree.man: New file, doctools manpage.
@
text
@d242 2
a243 1
    interp alias $inip __mpText__ $mpip HandleText
d359 12
@


1.6
log
@
	* mpexpand: Changed the generation of error messages by the format
	  checker to use explicit error codes instead of trying to
	  construct the whole message automatically. Error codes are
	  mapped to textual messages using the message catalog facility,
	  allowing for easy i18n and l10n of mpexpand. Catalogs for the
	  locales "c", "en", and "de" are provided.

	* mpformats/fmt.html: Changed uri formatting to be a link.

	* mpformats/fmt.tmml:
	* mpformats/fmt.html:
	* mpformats/fmt.nroff:
	* mpformats/fmt.latex:
	* mpformats/fmt.list:
	* mpformats/fmt.null:
	* mpformats/_api.tcl: Added formatting commands "term" and "const"
	  to allow the structural markup of non-specific terminology and
	  of constant values.

	* mpformats/fmt.nroff (bullet): Bulleting changed, use \(bu as
	  bullet instead of *.
	  (uri): Fixed error with underlining.
@
text
@d61 18
a78 18
	    * arg           - structural markup - argument\n\
	    * cmd           - structural markup - command\n\
	    * opt           - structural markup - optional data\n\
	    * comment       - structural markup - comment\n\
	    * sectref       - structural markup - section reference\n\
	    * syscmd        - structural markup - system command\n\
	    * method        - structural markup - object method\n\
	    * option        - structural markup - option\n\
	    * widget        - structural markup - widget\n\
	    * fun           - structural markup - function\n\
	    * type          - structural markup - data type\n\
	    * package       - structural markup - package\n\
	    * class         - structural markup - class\n\
	    * var           - structural markup - variable\n\
	    * file          - structural markup - file \n\
	    * uri           - structural markup - uri\n\
	    * term          - structural markup - unspecific terminology\n\
	    * const         - structural markup - constant value\n\
d399 1
a399 1
	proc ck_list_begin {what} {
d403 1
a403 1
	    list_begin $what
@


1.5
log
@
	* doctools: Implemented FR #530059 and FR #527029.

	* Fixed minor formatting errors in several existing doctools
	  manpages.

	* mpexpand: Extended with additional code checking that the
	  formatting commands are not used out of order and in the wrong
	  context. This check is independent of the format and thus
	  implemented outside of the format. Tcllib FR #530059.

	* mpexpand: Implemented Tcllib FR #527029 (help options).
@
text
@d77 2
d168 9
d217 1
a217 1
	class var file uri usage
d298 1
a298 1
	proc Error {{what {}} {msg {}}} {
d300 14
a313 8
	    if {$what == {}} {set what error}
	    if {$msg == {}} {
		set cmd [string range [lindex [info level 1] 0] 3 end]
		set a   [lrange [info level 1] 1 end]
		if {$a != {}} {append cmd " [join $a]"}
		set msg "Command \"$cmd\" not allowed here ($state ($lstitem $lstctx))"
	    }
	    puts stderr "Manpage $what: $msg" ; exit 1
d350 1
a350 1
		    Error incomplete "\[list_end\] missing"
d353 1
a353 1
		Error incomplete "\[example_end\] missing"
d355 1
a355 1
		Error incomplete "\[manpage_end\] missing"
d362 1
a362 1
	    if {[IsNot manpage_begin]} {Error}
d367 1
a367 1
	    if {[IsNot header]} {Error}
d371 1
a371 1
	    if {[IsNot header]} {Error}
d375 1
a375 1
	    if {[IsNot body]} {Error}
d380 1
a380 1
	    if {[IsNot header] && [IsNot requirements]} {Error}
d385 1
a385 1
	    if {[IsNot header] && [IsNot requirements]} {Error}
d390 2
a391 2
	    if {[IsNot body]} {Error}
	    if {[LOpen]}      {Error}
d395 2
a396 2
	    if {[IsNot body]} {Error}
	    if {[LOpen]}      {Error}
d400 2
a401 2
	    if {[IsNot body]}        {Error}
	    if {[LOpen] && ![LItem]} {Error}
d406 2
a407 2
	    if {[IsNot body]} {Error}
	    if {![LOpen]}     {Error}
d412 3
a414 3
	    if {[IsNot body]}       {Error}
	    if {![LOpen]}           {Error}
	    if {![LIs definitions]} {Error}
d419 3
a421 3
	    if {[IsNot body]}       {Error}
	    if {![LOpen]}           {Error}
	    if {![LIs definitions]} {Error}
d426 3
a428 3
	    if {[IsNot body]}  {Error}
	    if {![LOpen]}      {Error}
	    if {![LIs bullet]} {Error}
d433 3
a435 3
	    if {[IsNot body]} {Error}
	    if {![LOpen]}     {Error}
	    if {![LIs enum]}  {Error}
d443 2
a444 2
	    if {[IsNot body]}        {Error}
	    if {[LOpen] && ![LItem]} {Error}
d449 1
a449 1
	    if {[IsNot example]} {Error}
d454 2
a455 2
	    if {[IsNot body]} {Error}
	    if {[LOpen]}      {Error}
d459 2
a460 2
	    if {[IsNot body]} {Error}
	    if {[LOpen]}      {Error}
d464 3
a466 3
	    if {[IsNot body]} {Error}
	    if {![LOpen]}     {Error}
	    if {![LItem]}     {Error}
d470 1
a470 1
	    if {[Is done]} {Error}
d474 1
a474 1
	    if {[Is done]} {Error}
d478 1
a478 1
	    if {[Is done]} {Error}
d482 1
a482 1
	    if {[Is done]} {Error}
d486 1
a486 1
	    if {[Is done]} {Error}
d490 1
a490 1
	    if {[Is done]} {Error}
d494 2
a495 2
	    if {[IsNot body]} {Error}
	    if {[LOpen] && ![LItem]} {Error}
d499 1
a499 1
	    if {[Is done]} {Error}
d503 1
a503 1
	    if {[Is done]} {Error}
d507 1
a507 1
	    if {[Is done]} {Error}
d511 1
a511 1
	    if {[Is done]} {Error}
d515 1
a515 1
	    if {[Is done]} {Error}
d519 1
a519 1
	    if {[Is done]} {Error}
d523 1
a523 1
	    if {[Is done]} {Error}
d527 1
a527 1
	    if {[Is done]} {Error}
d531 1
a531 1
	    if {[Is done]} {Error}
d535 1
a535 1
	    if {[Is done]} {Error}
d539 1
a539 1
	    if {[Is done]} {Error}
d543 1
a543 1
	    if {[Is done]} {Error}
@


1.4
log
@
	* matrix.n:
	* matrix.man:
	* matrix.test:
	* matrix.tcl: Accepted FR #524430 and added option -nocase to the
	  'search' method.

	* matrix.man: Added doctools manpage.

	* modules/doctools/format.man: Added documentation for [rb] and
	  [lb]. This partially fixes bug #527025.

	* modules/doctools/mpformats/_html.tcl: The patch for FR #527716
	  also fixes a bug in the generation of HTML escapes. The table
	  swiped from htmlparse seems to contain some non-standard
	  escapes. Which are removed now.

	* modules/doctools/format.man:
	* modules/doctools/mpexpand:
	* modules/doctools/mpformats/fmt.html:
	* modules/doctools/mpformats/fmt.latex:
	* modules/doctools/mpformats/fmt.list:
	* modules/doctools/mpformats/fmt.nroff:
	* modules/doctools/mpformats/fmt.null:
	* modules/doctools/mpformats/fmt.tmml:
	* modules/doctools/mpformats/fmt.tmml: Accepted FR #527716 by
	  Bryan Oakley <boakley@@users.sourceforge.net> which adds a
	  command [usage] to the format. It allows the specification of
	  usage information for the synopsis without the need to be
	  embedded into a definition list.
@
text
@d22 61
a88 7
    if {
	([llength $argv] > 6) ||
	([llength $argv] < 3)
    } {
	puts "Usage: $argv0 ?-module module? ?-visualwarn? format in|- ?out|-?"
	exit 1
    }
d93 22
a114 8
	if {[string equal -module $opt]} {
	    set extmodule [lindex $argv 1]
	    set argv [lrange $argv 2 end]
	    continue
	}
	if {[string equal -visualwarn $opt]} {
	    set visualwarn 1
	    set argv [lrange $argv 1 end]
d118 3
d124 1
a124 2
	puts "Usage: $argv0 ?-module module? format in|- ?out|-?"
	exit 1
d159 1
a159 1
    global argv0 format fmtfile mpip inip passes visualwarn
d162 3
a164 2
    set mpip [interp create] ; # interpreter for the format.
    set inip [interp create] ; # interpreter for code in the input.
d208 8
a215 1
	interp alias $inip $cmd $mpip $cmd
d220 2
a221 1
	    interp alias $inip $cmd {} __$cmd
d225 2
a226 1
	    interp alias $inip $cmd $mpip $cmd
d234 299
d576 1
a576 1
    global mpip
d579 1
a579 1
    return [$mpip eval [list strong $text]]
d583 1
a583 1
    global mpip
d586 1
a586 1
    return [$mpip eval [list emph $text]]
d612 1
a612 1
    global mpip text expansion passes
d618 2
d621 1
@


1.3
log
@
	* doctools: Done FR #517599. FR #520269.

	* mpformats/fmt.null: Null format, does not produce any output.

	* mpformats/fmt.tmml:
	* mpformats/fmt.nroff:
	* mpformats/fmt.latex:
	* mpformats/fmt.html:
	* mpformats/fmt.list: Implementations of the new command.

	* mpexpand: Added the commands to the processor application. Added
	  option "-visualwarn". When present the processor warn about
	  usage of visual markup. Tcllib FR #517599.

	* mpformats/_api.tcl: Added a number of semantic markup commands
	  to the api as part of Tcllib FR #517599. Also added comment
	  command, see Tcllib FR #520269.
@
text
@d135 1
a135 1
	class var file uri     
@


1.2
log
@Added [example_begin], [example_end], and [example].
@
text
@d26 1
a26 1
    global argv0 argv format in out extmodule
d29 2
a30 4
	([llength $argv] > 5) ||
	([llength $argv] < 3) ||
	(![string equal -module [lindex $argv 0]] && [llength $argv] > 3) ||
	([string  equal -module [lindex $argv 0]] && [llength $argv] != 5)
d32 1
a32 1
	puts "Usage: $argv0 ?-module module? format in|- ?out|-?"
d36 12
a47 3
    if {[string equal -module [lindex $argv 0]]} {
	set extmodule [lindex $argv 1]
	set argv [lrange $argv 2 end]
d49 1
d89 1
a89 1
    global argv0 format fmtfile mpip inip passes
d99 1
d133 3
a135 2
	example example_begin example_end
	see_also keywords nl arg cmd opt emph strong
d139 10
d196 13
@


1.1
log
@
	* Added formatter for LaTeX.

	* New module. Application module providing a simple tcl-based
	  manpage markup language and a processor for converting this
	  format to TMML, nroff and HTML. Extensible, i.e. additional
	  formats can be added without to much work (Manpages for format
	  and internal interfaces are provided).
@
text
@d124 1
@

