[Tkabber-dev] [tclxmpp commit] r57 - in trunk: . doc tclxml xmpp

codesite-noreply at google.com codesite-noreply at google.com
Sun Nov 2 16:59:17 MSK 2008


Author: sgolovan
Date: Sun Nov  2 05:57:58 2008
New Revision: 57

Modified:
    trunk/ChangeLog
    trunk/doc/xmpp.man
    trunk/doc/xmpp_jid.man
    trunk/doc/xmpp_xml.man
    trunk/tclxml/pkgIndex.tcl
    trunk/tclxml/sgml.tcl
    trunk/tclxml/sgmlparser.tcl
    trunk/tclxml/tclparser.tcl
    trunk/tclxml/xml.tcl
    trunk/tclxml/xmltcl.tcl
    trunk/xmpp/register.tcl
    trunk/xmpp/xmpp.tcl

Log:
	* tclxml/*.tcl, doc/*.man, xmpp/register.tcl: Removed tabulation
	  characters from the sources and added ViM modelines which expand
	  them into spaces.

	* xmpp/xmpp.tcl: Don't add empty "to" attribute to sent IQ stanzas.

	* xmpp/register.tcl: Added support for data forms in error service
	  responses and added support for changing password.
2008-10-30  Sergei Golovan  <sgolovan at nes.ru>


Modified: trunk/ChangeLog
==============================================================================
--- trunk/ChangeLog	(original)
+++ trunk/ChangeLog	Sun Nov  2 05:57:58 2008
@@ -13,6 +13,15 @@
  	* xmpp/register.tcl, xmpp/pkgIndex.tcl: Added a new package which
  	  implements support for In-Band Registration (XEP-0077) queries.

+	* tclxml/*.tcl, doc/*.man, xmpp/register.tcl: Removed tabulation
+	  characters from the sources and added ViM modelines which expand
+	  them into spaces.
+
+	* xmpp/xmpp.tcl: Don't add empty "to" attribute to sent IQ stanzas.
+
+	* xmpp/register.tcl: Added support for data forms in error service
+	  responses and added support for changing password.
+
  2008-11-01  Sergei Golovan  <sgolovan at nes.ru>

  	* xmpp/data.tcl, xmpp/pkgIndex.tcl: Added a new package for working

Modified: trunk/doc/xmpp.man
==============================================================================
--- trunk/doc/xmpp.man	(original)
+++ trunk/doc/xmpp.man	Sun Nov  2 05:57:58 2008
@@ -15,14 +15,14 @@

  [list_begin definitions]
  [call [cmd "::xmpp::new"] \
-	[opt [arg "xlib"]] \
-	[opt [arg "-packetcommand cmd"]] \
-	[opt [arg "-messagecommand cmd"]] \
-	[opt [arg "-presencecommand cmd"]] \
-	[opt [arg "-iqcommand cmd"]] \
-	[opt [arg "-statuscommand cmd"]] \
-	[opt [arg "-errorcommand cmd"]] \
-	[opt [arg "-disconnectcommand cmd"]]]
+        [opt [arg "xlib"]] \
+        [opt [arg "-packetcommand cmd"]] \
+        [opt [arg "-messagecommand cmd"]] \
+        [opt [arg "-presencecommand cmd"]] \
+        [opt [arg "-iqcommand cmd"]] \
+        [opt [arg "-statuscommand cmd"]] \
+        [opt [arg "-errorcommand cmd"]] \
+        [opt [arg "-disconnectcommand cmd"]]]

  Create new XMPP token.

@@ -31,104 +31,104 @@
  Frees XMPP token resources.

  [call [cmd "::xmpp::connect"] \
-	[arg "xlib"] \
-	[opt [arg "host"] [opt [arg "port"]]] \
-	[opt [arg "-transport transport"]] \
-	[opt [arg "-command cmd"]] \
-	[opt [arg "args"]]]
+        [arg "xlib"] \
+        [opt "[arg "host"] [opt [arg "port"]]"] \
+        [opt [arg "-transport transport"]] \
+        [opt [arg "-command cmd"]] \
+        [opt [arg "args"]]]

  Connect to a given host.

  [call [cmd "::xmpp::openStream"] \
-	[arg "xlib"] \
-	[arg "server"] \
-	[opt [arg "-xmlns:stream uri"]] \
-	[opt [arg "-xmlns uri"]] \
-	[opt [arg "-xml:lang lang"]] \
-	[opt [arg "-version ver"]] \
-	[opt [arg "-timeout timeout"]] \
-	[opt [arg "-command cmd"]]]
+        [arg "xlib"] \
+        [arg "server"] \
+        [opt [arg "-xmlns:stream uri"]] \
+        [opt [arg "-xmlns uri"]] \
+        [opt [arg "-xml:lang lang"]] \
+        [opt [arg "-version ver"]] \
+        [opt [arg "-timeout timeout"]] \
+        [opt [arg "-command cmd"]]]

  Open XMPP stream.

  [call [cmd "::xmpp::closeStream"] \
-	[arg "xlib"]]
+        [arg "xlib"]]

  Close XMPP stream.

  [call [cmd "::xmpp::disconnect"] \
-	[arg "xlib"]]
+        [arg "xlib"]]

  Close XMPP stream and disconnect.

  [call [cmd "::xmpp::sendMessage"] \
-	[arg "xlib"] \
-	[arg "to"] \
-	[opt [arg "-from from"]] \
-	[opt [arg "-type type"]] \
-	[opt [arg "-id id"]] \
-	[opt [arg "-subject subject"]] \
-	[opt [arg "-thread thread"]] \
-	[opt [arg "-body body"]] \
-	[opt [arg "-error error"]] \
-	[opt [arg "-xlist elements"]]]
+        [arg "xlib"] \
+        [arg "to"] \
+        [opt [arg "-from from"]] \
+        [opt [arg "-type type"]] \
+        [opt [arg "-id id"]] \
+        [opt [arg "-subject subject"]] \
+        [opt [arg "-thread thread"]] \
+        [opt [arg "-body body"]] \
+        [opt [arg "-error error"]] \
+        [opt [arg "-xlist elements"]]]

  Send XMPP message stanza.

  [call [cmd "::xmpp::sendPresence"] \
-	[arg "xlib"] \
-	[opt [arg "-from from"]] \
-	[opt [arg "-to to"]] \
-	[opt [arg "-type type"]] \
-	[opt [arg "-id id"]] \
-	[opt [arg "-show show"]] \
-	[opt [arg "-status status"]] \
-	[opt [arg "-priority priority"]] \
-	[opt [arg "-error error"]] \
-	[opt [arg "-xlist elements"]]]
+        [arg "xlib"] \
+        [opt [arg "-from from"]] \
+        [opt [arg "-to to"]] \
+        [opt [arg "-type type"]] \
+        [opt [arg "-id id"]] \
+        [opt [arg "-show show"]] \
+        [opt [arg "-status status"]] \
+        [opt [arg "-priority priority"]] \
+        [opt [arg "-error error"]] \
+        [opt [arg "-xlist elements"]]]

  Send XMPP presence stanza.

  [call [cmd "::xmpp::sendIQ"] \
-	[arg "xlib"] \
-	[arg "type"] \
-	[opt [arg "-from from"]] \
-	[opt [arg "-to to"]] \
-	[opt [arg "-id id"]] \
-	[opt [arg "-query query"]] \
-	[opt [arg "-error error"]] \
-	[opt [arg "-timeout timeout"]] \
-	[opt [arg "-command cmd"]]]
+        [arg "xlib"] \
+        [arg "type"] \
+        [opt [arg "-from from"]] \
+        [opt [arg "-to to"]] \
+        [opt [arg "-id id"]] \
+        [opt [arg "-query query"]] \
+        [opt [arg "-error error"]] \
+        [opt [arg "-timeout timeout"]] \
+        [opt [arg "-command cmd"]]]

  Send XMPP info/query stanza.

  [call [cmd "::xmpp::abortIQ"] \
-	[arg "xlib"] \
-	[arg "id"] \
-	[arg "status"] \
-	[arg "error"]]
+        [arg "xlib"] \
+        [arg "id"] \
+        [arg "status"] \
+        [arg "error"]]

  Abort waiting for IQ reply.

  [call [cmd "::xmpp::outXML"] \
-	[arg "token"] \
-	[arg "xmlElement"]]
+        [arg "token"] \
+        [arg "xmlElement"]]

  Send XML element over the XMPP stream.

  [call [cmd "::xmpp::outText"] \
-	[arg "token"] \
-	[arg "text"]]
+        [arg "token"] \
+        [arg "text"]]

  Send Text over the XMPP stream.

  [call [cmd "::xmpp::ip"] \
-	[arg "xlib"]]
+        [arg "xlib"]]

  Return an IP address of an opened socket.

  [call [cmd "::xmpp::packetID"] \
-	[arg "xlib"]]
+        [arg "xlib"]]

  Return the next unused ID for XMPP packet.

@@ -138,4 +138,6 @@
  Sergei Golovan

  [keywords Tcl XMPP]
+[comment { vim:ft=tcl:ts=8:sw=4:sts=4:et
+}]
  [manpage_end]

Modified: trunk/doc/xmpp_jid.man
==============================================================================
--- trunk/doc/xmpp_jid.man	(original)
+++ trunk/doc/xmpp_jid.man	Sun Nov  2 05:57:58 2008
@@ -16,18 +16,18 @@

  [list_begin definitions]
  [call [cmd "::xmpp::jid::jid"] \
-	[arg "node"] \
-	[arg "server"] \
-	[opt [arg "resource"]]]
+        [arg "node"] \
+        [arg "server"] \
+        [opt [arg "resource"]]]

  Create JID from node, server and resource parts. If missing, resource is
  empty.

  [call [cmd "::xmpp::jid::split"] \
-	[arg "jid"] \
+        [arg "jid"] \
          [arg "nodeVar"] \
          [arg "serverVar"] \
-	[arg "resourceVar"]]
+        [arg "resourceVar"]]

  Split JID into three parts and assign the specified variables.

@@ -63,4 +63,6 @@
  Sergei Golovan

  [keywords Tcl XMPP JID]
+[comment { vim:ft=tcl:ts=8:sw=4:sts=4:et
+}]
  [manpage_end]

Modified: trunk/doc/xmpp_xml.man
==============================================================================
--- trunk/doc/xmpp_xml.man	(original)
+++ trunk/doc/xmpp_xml.man	Sun Nov  2 05:57:58 2008
@@ -18,9 +18,9 @@

  [list_begin definitions]
  [call [cmd "::xmpp::xml::new"] \
-	[arg "streamHeaderCmd"] \
-	[arg "streamTrailerCmd"] \
-	[arg "stanzaCmd"]]
+        [arg "streamHeaderCmd"] \
+        [arg "streamTrailerCmd"] \
+        [arg "stanzaCmd"]]

  Create new XMPP stream parser.

@@ -29,9 +29,9 @@
  Frees XMPP parser resources.

  [call [cmd "::xmpp::xml::parser"] \
-	[arg "token"] \
-	[arg "command"] \
-	[opt [arg "args"]]]
+        [arg "token"] \
+        [arg "command"] \
+        [opt [arg "args"]]]

  Execute a given command.

@@ -40,77 +40,77 @@
  Reset XMPP stream parser.

  [call [cmd "::xmpp::xml::parseData"] \
-	[arg "data"] \
-	[opt [arg "stanzaComd"]]]
+        [arg "data"] \
+        [opt [arg "stanzaComd"]]]

  Parse given data using a new XML parser and either return parsed XML
  or call the callback on every top level XML element.

  [call [cmd "::xmpp::xml::create"] \
-	[arg "tag"] \
-	[opt [arg "-xmlns xmlns"]] \
-	[opt [arg "-attrs attrs"]] \
-	[opt [arg "-cdata cdata"]] \
-	[opt [arg "-subelement subelement"]] \
-	[opt [arg "-subelements subelementsList"]]]
+        [arg "tag"] \
+        [opt [arg "-xmlns xmlns"]] \
+        [opt [arg "-attrs attrs"]] \
+        [opt [arg "-cdata cdata"]] \
+        [opt [arg "-subelement subelement"]] \
+        [opt [arg "-subelements subelementsList"]]]

  Create XML element.

  [call [cmd "::xmpp::xml::split"] \
-	[arg "xmlelement"] \
-	[arg "tagVar"] \
-	[arg "xmlnsVar"] \
-	[arg "attrsVar"] \
-	[arg "cdataVar"] \
-	[arg "subelsVar"] \
-	[opt [arg "nextCdataVar"]]]
+        [arg "xmlelement"] \
+        [arg "tagVar"] \
+        [arg "xmlnsVar"] \
+        [arg "attrsVar"] \
+        [arg "cdataVar"] \
+        [arg "subelsVar"] \
+        [opt [arg "nextCdataVar"]]]

  Split XML data into five or six variables.

  [call [cmd "::xmpp::xml::merge"] \
-	[arg "tag"] \
-	[arg "xmlns"] \
-	[arg "attrs"] \
-	[arg "cdata"] \
-	[arg "subels"] \
-	[opt [arg "nextCdata"]]]
+        [arg "tag"] \
+        [arg "xmlns"] \
+        [arg "attrs"] \
+        [arg "cdata"] \
+        [arg "subels"] \
+        [opt [arg "nextCdata"]]]

  Merge five or six variables into an XML element.

  [call [cmd "::xmpp::xml::isAttr"] \
-	[arg "attrList"] \
-	[arg "attrName"]]
+        [arg "attrList"] \
+        [arg "attrName"]]

  Check if a given attribute list contains a given attribute.

  [call [cmd "::xmpp::xml::getAttr"] \
-	[arg "attrList"] \
-	[arg "attrName"]]
+        [arg "attrList"] \
+        [arg "attrName"]]

  Return a given attribute value from an attribute list.

  [call [cmd "::xmpp::xml::getCdata"] \
-	[arg "xmlElement"]]
+        [arg "xmlElement"]]

  Return all character data from a given element.

  [call [cmd "::xmpp::xml::getFirstCdata"] \
-	[arg "xmlElement"]]
+        [arg "xmlElement"]]

  Return character data chunk which is located before the first XML  
subelement
  in a given element.

  [call [cmd "::xmpp::xml::getNextCdata"] \
-	[arg "xmlElement"]]
+        [arg "xmlElement"]]

  Return character data chunk which is located after the given XML element.

  [call [cmd "::xmpp::xml::streamHeader"] \
-	[arg "server"] \
-	[arg "-xmlns:stream uri"] \
-	[arg "-xmlns uri"] \
-	[opt [arg "-xml:lang lang"]] \
-	[opt [arg "-version ver"]]]
+        [arg "server"] \
+        [arg "-xmlns:stream uri"] \
+        [arg "-xmlns uri"] \
+        [opt [arg "-xml:lang lang"]] \
+        [opt [arg "-version ver"]]]

  Return XMPP stream header.

@@ -123,14 +123,14 @@
  Return XML language string derived from msgcat preferences.

  [call [cmd "::xmpp::xml::toText"] \
-	[arg "xmlElement"] \
-	[opt [arg "parentNamespace"]]]
+        [arg "xmlElement"] \
+        [opt [arg "parentNamespace"]]]

  Serialize a given XML element.

  [call [cmd "::xmpp::xml::toTabbedText"] \
-	[arg "xmlElement"] \
-	[opt [arg "parentNamespace"]]]
+        [arg "xmlElement"] \
+        [opt [arg "parentNamespace"]]]

  Serialize a given XML element adding indentations.

@@ -140,4 +140,6 @@
  Sergei Golovan

  [keywords Tcl XMPP XML]
+[comment { vim:ft=tcl:ts=8:sw=4:sts=4:et
+}]
  [manpage_end]

Modified: trunk/tclxml/pkgIndex.tcl
==============================================================================
--- trunk/tclxml/pkgIndex.tcl	(original)
+++ trunk/tclxml/pkgIndex.tcl	Sun Nov  2 05:57:58 2008
@@ -1,4 +1,6 @@
-# Tcl package index file - handcrafted
+# plkIndex.tcl --
+#
+#       Tcl package index file for TclXML
  #
  # $Id$

@@ -16,3 +18,4 @@
  package ifneeded xmldefs 2.0        [list source [file join $dir xml.tcl]]
  package ifneeded xml::tclparser 2.0 [list source [file join $dir  
tclparser.tcl]]

+# vim:ft=tcl:ts=8:sw=4:sts=4:et

Modified: trunk/tclxml/sgml.tcl
==============================================================================
--- trunk/tclxml/sgml.tcl	(original)
+++ trunk/tclxml/sgml.tcl	Sun Nov  2 05:57:58 2008
@@ -1,11 +1,11 @@
-# sgml-8.1.tcl --
+# sgml.tcl --
  #
-#	This file provides generic parsing services for SGML-based
-#	languages, namely HTML and XML.
-#	This file supports Tcl 8.1 characters and regular expressions.
+#       This file provides generic parsing services for SGML-based
+#       languages, namely HTML and XML.
+#       This file supports Tcl 8.1 characters and regular expressions.
  #
-#	NB.  It is a misnomer.  There is no support for parsing
-#	arbitrary SGML as such.
+#       NB.  It is a misnomer.  There is no support for parsing
+#       arbitrary SGML as such.
  #
  # Copyright (c) 1998-2001 Zveno Pty Ltd
  # http://www.zveno.com/
@@ -41,7 +41,7 @@

      # Convenience routine
      proc cl x {
-	return "\[$x\]"
+        return "\[$x\]"
      }

      # Define various regular expressions
@@ -70,7 +70,7 @@

      variable EntityPredef
      array set EntityPredef {
-	lt <   gt >   amp &   quot \"   apos '
+        lt <   gt >   amp &   quot \"   apos '
      }

  }
@@ -96,13 +96,13 @@

  # sgml::noop --
  #
-#	A do-nothing proc
+#       A do-nothing proc
  #
  # Arguments:
-#	args	arguments
+#       args        arguments
  #
  # Results:
-#	Nothing.
+#       Nothing.

  proc sgml::noop args {
      return 0
@@ -110,13 +110,13 @@

  # sgml::identity --
  #
-#	Identity function.
+#       Identity function.
  #
  # Arguments:
-#	a	arbitrary argument
+#       a           arbitrary argument
  #
  # Results:
-#	$a
+#       $a

  proc sgml::identity a {
      return $a
@@ -124,13 +124,13 @@

  # sgml::Error --
  #
-#	Throw an error
+#       Throw an error
  #
  # Arguments:
-#	args	arguments
+#       args        arguments
  #
  # Results:
-#	Error return condition.
+#       Error return condition.

  proc sgml::Error args {
      uplevel return -code error [list $args]
@@ -140,13 +140,13 @@

  # sgml::zapWhite --
  #
-#	Convert multiple white space into a single space.
+#       Convert multiple white space into a single space.
  #
  # Arguments:
-#	data	plain text
+#       data        plain text
  #
  # Results:
-#	As above
+#       As above

  proc sgml::zapWhite data {
      regsub -all "\[ \t\r\n\]+" $data { } data
@@ -159,3 +159,4 @@
      return $value
  }

+# vim:ft=tcl:ts=8:sw=4:sts=4:et

Modified: trunk/tclxml/sgmlparser.tcl
==============================================================================
--- trunk/tclxml/sgmlparser.tcl	(original)
+++ trunk/tclxml/sgmlparser.tcl	Sun Nov  2 05:57:58 2008
@@ -1,12 +1,12 @@
  # sgmlparser.tcl --
  #
-#	This file provides the generic part of a parser for SGML-based
-#	languages, namely HTML and XML.
+#       This file provides the generic part of a parser for SGML-based
+#       languages, namely HTML and XML.
  #
-#	NB.  It is a misnomer.  There is no support for parsing
-#	arbitrary SGML as such.
+#       NB.  It is a misnomer.  There is no support for parsing
+#       arbitrary SGML as such.
  #
-#	See sgml.tcl for variable definitions.
+#       See sgml.tcl for variable definitions.
  #
  # Copyright (c) 1998-2002 Zveno Pty Ltd
  # http://www.zveno.com/
@@ -51,11 +51,11 @@

      variable ParseEventNum
      if {![info exists ParseEventNum]} {
-	set ParseEventNum 0
+        set ParseEventNum 0
      }
      variable ParseDTDnum
      if {![info exists ParseDTDNum]} {
-	set ParseDTDNum 0
+        set ParseDTDNum 0
      }

      variable declExpr [cl $::sgml::Wsp]*([cl ^$::sgml::Wsp]+)[cl  
$::sgml::Wsp]*([cl ^>]*)
@@ -70,57 +70,57 @@

      variable StdOptions
      array set StdOptions [list \
-	-elementstartcommand		[namespace current]::noop	\
-	-elementendcommand		[namespace current]::noop	\
-	-characterdatacommand		[namespace current]::noop	\
-	-processinginstructioncommand	[namespace current]::noop	\
-	-externalentitycommand		{}				\
-	-xmldeclcommand			[namespace current]::noop	\
-	-doctypecommand			[namespace current]::noop	\
-	-commentcommand			[namespace current]::noop	\
-	-entitydeclcommand		[namespace current]::noop	\
-	-unparsedentitydeclcommand	[namespace current]::noop	\
-	-parameterentitydeclcommand	[namespace current]::noop	\
-	-notationdeclcommand		[namespace current]::noop	\
-	-elementdeclcommand		[namespace current]::noop	\
-	-attlistdeclcommand		[namespace current]::noop	\
-	-paramentityparsing		1				\
-	-defaultexpandinternalentities	1				\
-	-startdoctypedeclcommand	[namespace current]::noop	\
-	-enddoctypedeclcommand		[namespace current]::noop	\
-	-entityreferencecommand		{}				\
-	-warningcommand			[namespace current]::noop	\
-	-errorcommand			[namespace current]::Error	\
-	-final				1				\
-	-validate			0				\
-	-baseurl			{}				\
-	-name				{}				\
-	-emptyelement			[namespace current]::EmptyElement	\
-	-parseattributelistcommand	[namespace current]::noop	\
-	-parseentitydeclcommand		[namespace current]::noop	\
-	-normalize			1				\
-	-internaldtd			{}				\
-	-reportempty			0				\
+        -elementstartcommand           [namespace current]::noop         \
+        -elementendcommand             [namespace current]::noop         \
+        -characterdatacommand          [namespace current]::noop         \
+        -processinginstructioncommand  [namespace current]::noop         \
+        -externalentitycommand         {}                                \
+        -xmldeclcommand                [namespace current]::noop         \
+        -doctypecommand                [namespace current]::noop         \
+        -commentcommand                [namespace current]::noop         \
+        -entitydeclcommand             [namespace current]::noop         \
+        -unparsedentitydeclcommand     [namespace current]::noop         \
+        -parameterentitydeclcommand    [namespace current]::noop         \
+        -notationdeclcommand           [namespace current]::noop         \
+        -elementdeclcommand            [namespace current]::noop         \
+        -attlistdeclcommand            [namespace current]::noop         \
+        -paramentityparsing            1                                 \
+        -defaultexpandinternalentities 1                                 \
+        -startdoctypedeclcommand       [namespace current]::noop         \
+        -enddoctypedeclcommand         [namespace current]::noop         \
+        -entityreferencecommand        {}                                \
+        -warningcommand                [namespace current]::noop         \
+        -errorcommand                  [namespace current]::Error        \
+        -final                         1                                 \
+        -validate                      0                                 \
+        -baseurl                       {}                                \
+        -name                          {}                                \
+        -emptyelement                  [namespace current]::EmptyElement \
+        -parseattributelistcommand     [namespace current]::noop         \
+        -parseentitydeclcommand        [namespace current]::noop         \
+        -normalize                     1                                 \
+        -internaldtd                   {}                                \
+        -reportempty                   0                                 \
      ]
  }

  # sgml::tokenise --
  #
-#	Transform the given HTML/XML text into a Tcl list.
+#       Transform the given HTML/XML text into a Tcl list.
  #
  # Arguments:
-#	sgml		text to tokenize
-#	elemExpr	RE to recognise tags
-#	elemSub		transform for matched tags
-#	args		options
+#       sgml        text to tokenize
+#       elemExpr    RE to recognise tags
+#       elemSub     transform for matched tags
+#       args        options
  #
  # Valid Options:
  #       -internaldtdvariable
-#	-final		boolean		True if no more data is to be supplied
-#	-statevariable	varName		Name of a variable used to store info
+#       -final               boolean    True if no more data is to be  
supplied
+#       -statevariable       varName    Name of a variable used to store  
info
  #
  # Results:
-#	Returns a Tcl list representing the document.
+#       Returns a Tcl list representing the document.

  proc sgml::tokenise {sgml elemExpr1 elemExpr2 elemExpr3 elemSub args} {
      array set options {-final 1}
@@ -130,15 +130,15 @@
      # If the data is not final then there must be a variable to store
      # unused data.
      if {!$options(-final) && ![info exists options(-statevariable)]} {
-	return -code error {option "-statevariable" required if not final}
+        return -code error {option "-statevariable" required if not final}
      }

      if {[info exists options(-statevariable)]} {
-	# Several rewrites here to handle -final 0 option.
-	# If any cached unparsed xml (state(leftover)), prepend it.
-	upvar #0 $options(-statevariable) state
-	set sgml $state(leftover)$sgml
-	set state(leftover) {}
+        # Several rewrites here to handle -final 0 option.
+        # If any cached unparsed xml (state(leftover)), prepend it.
+        upvar #0 $options(-statevariable) state
+        set sgml $state(leftover)$sgml
+        set state(leftover) {}
      }

      # Pre-process stage
@@ -147,7 +147,7 @@

      catch {upvar #0 $options(-internaldtdvariable) dtd}
      if {[regexp {<!DOCTYPE[^[<]+\[([^]]+)\]} $sgml discard dtd]} {
-	regsub {(<!DOCTYPE[^[<]+)(\[[^]]+\])} $sgml {\1\&xml:intdtd;} sgml
+        regsub {(<!DOCTYPE[^[<]+)(\[[^]]+\])} $sgml {\1\&xml:intdtd;} sgml
      }

      # Protect Tcl special characters
@@ -160,18 +160,18 @@
      set sgml "{} {} {} \{$sgml\}"

      if {[info exists options(-statevariable)]} {
-	# Performance note (Tcl 8.0):
-	#	Use of lindex, lreplace will cause parsing to list object
+        # Performance note (Tcl 8.0):
+        #        Use of lindex, lreplace will cause parsing to list object

-	# This RE only fixes chopped inside tags, not chopped text.
-	if {[regexp {^([^<]*)(<.*$)} [lindex $sgml end] x text rest]} {
-	    set sgml [lreplace $sgml end end $text]
-	    # Mats: unmatched stuff means that it is chopped off. Cache it for  
next round.
-	    set state(leftover) $rest
-	} elseif {[regexp {^(.*)(&[^;]*$)} [lindex $sgml end] x text rest]} {
-	    set sgml [lreplace $sgml end end $text]
-	    set state(leftover) $rest
-	}
+        # This RE only fixes chopped inside tags, not chopped text.
+        if {[regexp {^([^<]*)(<.*$)} [lindex $sgml end] x text rest]} {
+            set sgml [lreplace $sgml end end $text]
+            # Mats: unmatched stuff means that it is chopped off. Cache it  
for next round.
+            set state(leftover) $rest
+        } elseif {[regexp {^(.*)(&[^;]*$)} [lindex $sgml end] x text  
rest]} {
+            set sgml [lreplace $sgml end end $text]
+            set state(leftover) $rest
+        }
      }

      return $sgml
@@ -179,58 +179,58 @@

  # sgml::parseEvent --
  #
-#	Produces an event stream for a XML/HTML document,
-#	given the Tcl list format returned by tokenise.
+#       Produces an event stream for a XML/HTML document,
+#       given the Tcl list format returned by tokenise.
  #
-#	This procedure checks that the document is well-formed,
-#	and throws an error if the document is found to be not
-#	well formed.  Warnings are passed via the -warningcommand script.
+#       This procedure checks that the document is well-formed,
+#       and throws an error if the document is found to be not
+#       well formed.  Warnings are passed via the -warningcommand script.
  #
-#	The procedure only check for well-formedness,
-#	no DTD is required.  However, facilities are provided for entity  
expansion.
+#       The procedure only check for well-formedness,
+#       no DTD is required.  However, facilities are provided for entity  
expansion.
  #
  # Arguments:
-#	sgml		Instance data, as a Tcl list.
-#	args		option/value pairs
+#       sgml        Instance data, as a Tcl list.
+#       args        option/value pairs
  #
  # Valid Options:
-#	-final			Indicates end of document data
-#	-validate		Boolean to enable validation
-#	-baseurl		URL for resolving relative URLs
-#	-elementstartcommand	Called when an element starts
-#	-elementendcommand	Called when an element ends
-#	-characterdatacommand	Called when character data occurs
-#	-entityreferencecommand	Called when an entity reference occurs
-#	-processinginstructioncommand	Called when a PI occurs
-#	-externalentitycommand	Called for an external entity reference
-#
-#	-xmldeclcommand		Called when the XML declaration occurs
-#	-doctypecommand		Called when the document type declaration occurs
-#	-commentcommand		Called when a comment occurs
-#	-entitydeclcommand	Called when a parsed entity is declared
-#	-unparsedentitydeclcommand	Called when an unparsed external entity is  
declared
-#	-parameterentitydeclcommand	Called when a parameter entity is declared
-#	-notationdeclcommand	Called when a notation is declared
-#	-elementdeclcommand	Called when an element is declared
-#	-attlistdeclcommand	Called when an attribute list is declared
-#	-paramentityparsing	Boolean to enable/disable parameter entity  
substitution
-#	-defaultexpandinternalentities	Boolean to enable/disable expansion of  
entities declared in internal DTD subset
-#
-#	-startdoctypedeclcommand	Called when the Doc Type declaration starts  
(see also -doctypecommand)
-#	-enddoctypedeclcommand	Called when the Doc Type declaration ends (see  
also -doctypecommand)
-#
-#	-errorcommand		Script to evaluate for a fatal error
-#	-warningcommand		Script to evaluate for a reportable warning
-#	-statevariable		global state variable
-#	-normalize		whether to normalize names
-#	-reportempty		whether to include an indication of empty elements
+#       -final                          Indicates end of document data
+#       -validate                       Boolean to enable validation
+#       -baseurl                        URL for resolving relative URLs
+#       -elementstartcommand            Called when an element starts
+#       -elementendcommand              Called when an element ends
+#       -characterdatacommand           Called when character data occurs
+#       -entityreferencecommand         Called when an entity reference  
occurs
+#       -processinginstructioncommand   Called when a PI occurs
+#       -externalentitycommand          Called for an external entity  
reference
+#
+#       -xmldeclcommand                 Called when the XML declaration  
occurs
+#       -doctypecommand                 Called when the document type  
declaration occurs
+#       -commentcommand                 Called when a comment occurs
+#       -entitydeclcommand              Called when a parsed entity is  
declared
+#       -unparsedentitydeclcommand      Called when an unparsed external  
entity is declared
+#       -parameterentitydeclcommand     Called when a parameter entity is  
declared
+#       -notationdeclcommand            Called when a notation is declared
+#       -elementdeclcommand             Called when an element is declared
+#       -attlistdeclcommand             Called when an attribute list is  
declared
+#       -paramentityparsing             Boolean to enable/disable  
parameter entity substitution
+#       -defaultexpandinternalentities  Boolean to enable/disable  
expansion of entities declared in internal DTD subset
+#
+#       -startdoctypedeclcommand        Called when the Doc Type  
declaration starts (see also -doctypecommand)
+#       -enddoctypedeclcommand          Called when the Doc Type  
declaration ends (see also -doctypecommand)
+#
+#       -errorcommand                   Script to evaluate for a fatal  
error
+#       -warningcommand                 Script to evaluate for a  
reportable warning
+#       -statevariable                  global state variable
+#       -normalize                      whether to normalize names
+#       -reportempty                    whether to include an indication  
of empty elements
  #
  # Results:
-#	The various callback scripts are invoked.
-#	Returns empty string.
+#       The various callback scripts are invoked.
+#       Returns empty string.
  #
  # BUGS:
-#	If command options are set to empty string then they should not be  
invoked.
+#       If command options are set to empty string then they should not be  
invoked.

  proc sgml::parseEvent {sgml args} {
      variable Wsp
@@ -246,52 +246,52 @@
      # Mats:
      # If the data is not final then there must be a variable to  
persistently store the parse state.
      if {!$options(-final) && ![info exists options(-statevariable)]} {
-	return -code error {option "-statevariable" required if not final}
+        return -code error {option "-statevariable" required if not final}
      }

      foreach {opt value} [array get options *command] {
-	if {[string compare $opt "-externalentitycommand"] && ![string length  
$value]} {
-	    set options($opt) [namespace current]::noop
-	}
+        if {[string compare $opt "-externalentitycommand"] && ![string  
length $value]} {
+            set options($opt) [namespace current]::noop
+        }
      }

      if {![info exists options(-statevariable)]} {
-	set options(-statevariable) [namespace current]::ParseEvent[incr  
ParseEventNum]
+        set options(-statevariable) [namespace current]::ParseEvent[incr  
ParseEventNum]
      }
      if {![info exists options(entities)]} {
-	set options(entities) [namespace current]::Entities$ParseEventNum
-	array set $options(entities) [array get [namespace current]::EntityPredef]
+        set options(entities) [namespace current]::Entities$ParseEventNum
+        array set $options(entities) [array get [namespace  
current]::EntityPredef]
      }
      if {![info exists options(extentities)]} {
-	set options(extentities) [namespace current]::ExtEntities$ParseEventNum
+        set options(extentities) [namespace  
current]::ExtEntities$ParseEventNum
      }
      if {![info exists options(parameterentities)]} {
-	set options(parameterentities) [namespace  
current]::ParamEntities$ParseEventNum
+        set options(parameterentities) [namespace  
current]::ParamEntities$ParseEventNum
      }
      if {![info exists options(externalparameterentities)]} {
-	set options(externalparameterentities) [namespace  
current]::ExtParamEntities$ParseEventNum
+        set options(externalparameterentities) [namespace  
current]::ExtParamEntities$ParseEventNum
      }
      if {![info exists options(elementdecls)]} {
-	set options(elementdecls) [namespace current]::ElementDecls$ParseEventNum
+        set options(elementdecls) [namespace  
current]::ElementDecls$ParseEventNum
      }
      if {![info exists options(attlistdecls)]} {
-	set options(attlistdecls) [namespace current]::AttListDecls$ParseEventNum
+        set options(attlistdecls) [namespace  
current]::AttListDecls$ParseEventNum
      }
      if {![info exists options(notationdecls)]} {
-	set options(notationdecls) [namespace  
current]::NotationDecls$ParseEventNum
+        set options(notationdecls) [namespace  
current]::NotationDecls$ParseEventNum
      }
      if {![info exists options(namespaces)]} {
-	set options(namespaces) [namespace current]::Namespaces$ParseEventNum
+        set options(namespaces) [namespace  
current]::Namespaces$ParseEventNum
      }

      # Choose an external entity resolver

      if {![string length $options(-externalentitycommand)]} {
-	if {$options(-validate)} {
-	    set options(-externalentitycommand) [namespace code ResolveEntity]
-	} else {
-	    set options(-externalentitycommand) [namespace code noop]
-	}
+        if {$options(-validate)} {
+            set options(-externalentitycommand) [namespace code  
ResolveEntity]
+        } else {
+            set options(-externalentitycommand) [namespace code noop]
+        }
      }

      upvar #0 $options(-statevariable) state
@@ -302,504 +302,504 @@
      # I've switched back to an older version here.

      if {![info exists state(line)]} {
-	# Initialise the state variable
-	array set state {
-	    mode normal
-	    haveXMLDecl 0
-	    haveDocElement 0
-	    inDTD 0
-	    context {}
-	    stack {}
-	    line 0
-	    defaultNS {}
-	    defaultNSURI {}
-	}
+        # Initialise the state variable
+        array set state {
+            mode normal
+            haveXMLDecl 0
+            haveDocElement 0
+            inDTD 0
+            context {}
+            stack {}
+            line 0
+            defaultNS {}
+            defaultNSURI {}
+        }
      }

      foreach {tag close param text} $sgml {

-	# Keep track of lines in the input
-	incr state(line) [regsub -all \n $param {} discard]
-	incr state(line) [regsub -all \n $text {} discard]
-
-	# If the current mode is cdata or comment then we must undo what the
-	# regsub has done to reconstitute the data
-
-	set empty {}
-	switch -- $state(mode) {
-	    comment {
-		# This had "[string length $param] && " as a guard -
-		# can't remember why :-(
-		if {[regexp ([cl ^-]*)--\$ $tag discard comm1]} {
-		    # end of comment (in tag)
-		    set tag {}
-		    set close {}
-		    set state(mode) normal
-		    uplevel #0 $options(-commentcommand) [list  
$state(commentdata)<$comm1]
-		    unset state(commentdata)
-		} elseif {[regexp ([cl ^-]*)--\$ $param discard comm1]} {
-		    # end of comment (in attributes)
-		    uplevel #0 $options(-commentcommand) [list  
$state(commentdata)<$close$tag>$comm1]
-		    unset state(commentdata)
-		    set tag {}
-		    set param {}
-		    set close {}
-		    set state(mode) normal
-		} elseif {[regexp ([cl ^-]*)-->(.*) $text discard comm1 text]} {
-		    # end of comment (in text)
-		    uplevel #0 $options(-commentcommand) [list  
$state(commentdata)<$close$tag$param>$comm1]
-		    unset state(commentdata)
-		    set tag {}
-		    set param {}
-		    set close {}
-		    set state(mode) normal
-		} else {
-		    # comment continues
-		    append state(commentdata) <$close$tag$param>$text
-		    continue
-		}
-	    }
-	    cdata {
-		if {[regexp ([cl ^\]]*)\]\][cl $Wsp]*\$ $tag discard cdata1]} {
-		    # end of CDATA (in tag)
-		    uplevel #0 $options(-characterdatacommand) \
-			    [list $state(cdata)<[subst -nocommand -novariable $close$cdata1]]
-		    set text [subst -novariable -nocommand $text]
-		    set tag {}
-		    unset state(cdata)
-		    set state(mode) normal
-		} elseif {[regexp ([cl ^\]]*)\]\][cl $Wsp]*\$ $param discard cdata1]} {
-		    # end of CDATA (in attributes)
-		    uplevel #0 $options(-characterdatacommand) \
-			    [list $state(cdata)<[subst -nocommand -novariable  
$close$tag$cdata1]]
-		    set text [subst -novariable -nocommand $text]
-		    set tag {}
-		    set param {}
-		    unset state(cdata)
-		    set state(mode) normal
-		} elseif {[regexp (.*)\]\][cl $Wsp]*>(.*) $text discard cdata1 text]} {
-		    # end of CDATA (in text)
-		    uplevel #0 $options(-characterdatacommand) \
-			    [list $state(cdata)<[subst -nocommand -novariable  
$close$tag$param>$cdata1]]
-		    set text [subst -novariable -nocommand $text]
-		    set tag {}
-		    set param {}
-		    set close {}
-		    unset state(cdata)
-		    set state(mode) normal
-		} else {
-		    # CDATA continues
-		    append state(cdata) [subst -nocommand -novariable  
<$close$tag$param>$text]
-		    continue
-		}
-	    }
-	    continue {
-		# We're skipping elements looking for the close tag
-		switch -glob -- [string length $tag],[regexp {^\?|!.*} $tag],$close {
-		    0,* {
-			continue
-		    }
-		    *,0, {
-			if {![string compare $tag $state(continue:tag)]} {
-			    set empty [uplevel #0 $options(-emptyelement) [list $tag $param  
$empty]]
-			    if {![string length $empty]} {
-				incr state(continue:level)
-			    }
-			}
-			continue
-		    }
-		    *,0,/ {
-			if {![string compare $tag $state(continue:tag)]} {
-			    incr state(continue:level) -1
-			}
-			if {!$state(continue:level)} {
-			    unset state(continue:tag)
-			    unset state(continue:level)
-			    set state(mode) {}
-			}
-		    }
-		    default {
-			continue
-		    }
-		}
-	    }
-	    default {
-		# The trailing slash on empty elements can't be automatically separated  
out
-		# in the RE, so we must do it here.
-		regexp (.*)(/)[cl $Wsp]*$ $param discard param empty
-	    }
-	}
-
-	# default: normal mode
-
-	# Bug: if the attribute list has a right angle bracket then the empty
-	# element marker will not be seen
-
-	set empty [uplevel #0 $options(-emptyelement) [list $tag $param $empty]]
-
-	switch -glob -- [string length $tag],[regexp {^\?|!.*}  
$tag],$close,$empty {
-
-	    0,0,, {
-		# Ignore empty tag - dealt with non-normal mode above
-	    }
-	    *,0,, {
-
-		# Start tag for an element.
-
-		# Check if the internal DTD entity is in an attribute value
-		regsub -all &xml:intdtd\; $param \[$options(-internaldtd)\] param
-
-		set code [catch {ParseEvent:ElementOpen $tag $param [array get options]}  
msg]
-		set state(haveDocElement) 1
-		switch -- $code {
-		    0 {# OK}
-		    3 {
-			# break
-			return {}
-		    }
-		    4 {
-			# continue
-			# Remember this tag and look for its close
-			set state(continue:tag) $tag
-			set state(continue:level) 1
-			set state(mode) continue
-			continue
-		    }
-		    default {
-			return -code $code -errorinfo $::errorInfo $msg
-		    }
-		}
-
-	    }
-
-	    *,0,/, {
-
-		# End tag for an element.
-
-		set code [catch {ParseEvent:ElementClose $tag [array get options]} msg]
-		switch -- $code {
-		    0 {# OK}
-		    3 {
-			# break
-			return {}
-		    }
-		    4 {
-			# continue
-			# skip sibling nodes
-			set state(continue:tag) [lindex $state(stack) end]
-			set state(continue:level) 1
-			set state(mode) continue
-			continue
-		    }
-		    default {
-			return -code $code -errorinfo $::errorInfo $msg
-		    }
-		}
-
-	    }
-
-	    *,0,,/ {
-
-		# Empty element
-
-		# The trailing slash sneaks through into the param variable
-		regsub -all /[cl $::sgml::Wsp]*\$ $param {} param
-
-		set code [catch {ParseEvent:ElementOpen $tag $param [array get options]  
-empty 1} msg]
-		set state(haveDocElement) 1
-		switch -- $code {
-		    0 {# OK}
-		    3 {
-			# break
-			return {}
-		    }
-		    4 {
-			# continue
-			# Pretty useless since it closes straightaway
-		    }
-		    default {
-			return -code $code -errorinfo $::errorInfo $msg
-		    }
-		}
-		set code [catch {ParseEvent:ElementClose $tag [array get options] -empty  
1} msg]
-		switch -- $code {
-		    0 {# OK}
-		    3 {
-			# break
-			return {}
-		    }
-		    4 {
-			# continue
-			# skip sibling nodes
-			set state(continue:tag) [lindex $state(stack) end]
-			set state(continue:level) 1
-			set state(mode) continue
-			continue
-		    }
-		    default {
-			return -code $code -errorinfo $::errorInfo $msg
-		    }
-		}
-
-	    }
-
-	    *,1,* {
-		# Processing instructions or XML declaration
-		switch -glob -- $tag {
-
-		    {\?xml} {
-			# XML Declaration
-			if {$state(haveXMLDecl)} {
-			    uplevel #0 $options(-errorcommand) \
-				    [list illegalcharacter \
-					  "unexpected characters \"<$tag\" around line $state(line)"]
-			} elseif {![regexp {\?$} $param]} {
-			    uplevel #0 $options(-errorcommand) \
-				    [list missingcharacters \
-					  "XML Declaration missing characters \"?>\" around line  
$state(line)"]
-			} else {
-
-			    # We can do the parsing in one step with Tcl 8.1 RE's
-			    # This has the benefit of performing better WF checking
-
-			    set adv_re [format {^[%s]*version[%s]*=[%s]*(\"|')(-+| 
[a-zA-Z0-9_.:]+)\1([%s]+encoding[%s]*=[%s]*("|')([A-Za-z][-A-Za-z0-9._]*)\4)?([%s]*standalone[%s]*=[%s]*("|')(yes| 
no)\7)?[%s]*\?$} $::sgml::Wsp $::sgml::Wsp $::sgml::Wsp $::sgml::Wsp  
$::sgml::Wsp $::sgml::Wsp $::sgml::Wsp $::sgml::Wsp $::sgml::Wsp  
$::sgml::Wsp]
-
-			    if {![regexp $adv_re $param discard delimiter version discard \
-							delimiter encoding discard delimiter standalone]} {
-				uplevel #0 $options(-errorcommand) \
-				    [list illformeddeclaration \
-					  "XML Declaration not well-formed around line $state(line)"]
-			    } else {
-				# Invoke the callback
-				uplevel #0 $options(-xmldeclcommand) [list $version $encoding  
$standalone]
-
-			    }
-
-			}
-
-		    }
-
-		    {\?*} {
-			# Processing instruction
-			set tag [string range $tag 1 end]
-			if {[regsub {\?$} $tag {} tag]} {
-			    if {[string length [string trim $param]]} {
-				uplevel #0 $options(-errorcommand) \
-				    [list [list unexpectedtext "unexpected text \"$param\"\
-					in processing instruction around line $state(line)"]]
-			    }
-			} elseif {![regexp ^$Name\$ $tag]} {
-			    uplevel #0 $options(-errorcommand) \
-				[list illegalcharacter "illegal character in processing instruction  
target \"$tag\""]
-			} elseif {[regexp {^[xX][mM][lL]$} $tag]} {
-			    uplevel #0 $options(-errorcommand) \
-				[list illegalcharacters "characters \"xml\" not\
-				    permitted in processing instruction target \"$tag\""]
-			} elseif {![regsub {\?$} $param {} param]} {
-			    uplevel #0 $options(-errorcommand) \
-				[list missingquestion "PI: expected '?' character around line  
$state(line)"]
-			}
-			set code [catch {
-				    uplevel #0 $options(-processinginstructioncommand) \
-					[list $tag [string trimleft $param]]
-				  } msg]
-			switch -- $code {
-			    0 {# OK}
-			    3 {
-				# break
-				return {}
-			    }
-			    4 {
-				# continue
-				# skip sibling nodes
-				set state(continue:tag) [lindex $state(stack) end]
-				set state(continue:level) 1
-				set state(mode) continue
-				continue
-			    }
-			    default {
-				return -code $code -errorinfo $::errorInfo $msg
-			    }
-			}
-		    }
-
-		    !DOCTYPE {
-			# External entity reference
-			# This should move into xml.tcl
-			# Parse the params supplied.  Looking for Name, ExternalID and  
MarkupDecl
-			set matched [regexp ^[cl $Wsp]*($Name)[cl $Wsp]*(.*) $param x  
state(doc_name) param]
-			set state(doc_name) [Normalize $state(doc_name) $options(-normalize)]
-			set externalID {}
-			set pubidlit {}
-			set systemlit {}
-			set externalID {}
-			if {[regexp -nocase ^[cl $Wsp]*(SYSTEM|PUBLIC)(.*) $param x id param]} {
-			    switch -- [string toupper $id] {
-				SYSTEM {
-				    if {[regexp ^[cl $Wsp]+\"([cl ^\"]*)\"(.*) $param x systemlit  
param] || \
-					    [regexp ^[cl $Wsp]+'([cl ^']*)'(.*) $param x systemlit param]} {
-					set externalID [list SYSTEM $systemlit] ;# "
-				    } else {
-					uplevel #0 $options(-errorcommand) \
-					    [list XXX "syntax error: SYSTEM identifier not followed by  
literal"]
-				    }
-				}
-				PUBLIC {
-				    if {[regexp ^[cl $Wsp]+\"([cl ^\"]*)\"(.*) $param x pubidlit  
param] || \
-					    [regexp ^[cl $Wsp]+'([cl ^']*)'(.*) $param x pubidlit param]} {
-					if {[regexp ^[cl $Wsp]+\"([cl ^\"]*)\"(.*) $param x systemlit param] | 
| \
-						[regexp ^[cl $Wsp]+'([cl ^']*)'(.*) $param x systemlit param]} {
-					    set externalID [list PUBLIC $pubidlit $systemlit]
-					} else {
-					    uplevel #0 $options(-errorcommand) \
-						[list syntaxerror "syntax error: PUBLIC identifier\
-						    not followed by system literal around line $state(line)"]
-					}
-				    } else {
-					uplevel #0 $options(-errorcommand) \
-					    [list syntaxerror "syntax error: PUBLIC identifier\
-						not followed by literal around line $state(line)"]
-				    }
-				}
-			    }
-			    if {[regexp -nocase ^[cl $Wsp]+NDATA[cl $Wsp]+($Name)(.*) $param x  
notation param]} {
-				lappend externalID $notation
-			    }
-			}
-
-			set state(inDTD) 1
-
-			ParseEvent:DocTypeDecl [array get options] $state(doc_name) \
-			    $pubidlit $systemlit $options(-internaldtd)
-
-			set state(inDTD) 0
-
-		    }
-
-		    !--* {
-
-			# Start of a comment
-			# See if it ends in the same tag, otherwise change the
-			# parsing mode
-
-			regexp {!--(.*)} $tag discard comm1
-			if {[regexp ([cl ^-]*)--[cl $Wsp]*\$ $comm1 discard comm1_1]} {
-			    # processed comment (end in tag)
-			    uplevel #0 $options(-commentcommand) [list $comm1_1]
-			} elseif {[regexp ([cl ^-]*)--[cl $Wsp]*\$ $param discard comm2]} {
-			    # processed comment (end in attributes)
-			    uplevel #0 $options(-commentcommand) [list $comm1$comm2]
-			} elseif {[regexp ([cl ^-]*)-->(.*) $text discard comm2 text]} {
-			    # processed comment (end in text)
-			    uplevel #0 $options(-commentcommand) [list  
$comm1$param$empty>$comm2]
-			} else {
-			    # start of comment
-			    set state(mode) comment
-			    set state(commentdata) "$comm1$param$empty>$text"
-			    continue
-			}
-		    }
-
-		    {!\[CDATA\[*} {
-
-			regexp {!\[CDATA\[(.*)} $tag discard cdata1
-			if {[regexp {(.*)]]$} $cdata1 discard cdata2]} {
-			    # processed CDATA (end in tag)
-			    uplevel #0 $options(-characterdatacommand) [list [subst -novariable  
-nocommand $cdata2]]
-			    set text [subst -novariable -nocommand $text]
-			} elseif {[regexp {(.*)]]$} $param discard cdata2]} {
-			    # processed CDATA (end in attribute)
-			    # Backslashes in param are quoted at this stage
-			    uplevel #0 $options(-characterdatacommand) \
-				[list $cdata1[subst -novariable -nocommand $cdata2]]
-			    set text [subst -novariable -nocommand $text]
-			} elseif {[regexp {(.*)]]>(.*)} $text discard cdata2 text]} {
-			    # processed CDATA (end in text)
-			    # Backslashes in param and text are quoted at this stage
-			    uplevel #0 $options(-characterdatacommand) \
-				[list $cdata1[subst -novariable -nocommand $param]$empty>[subst  
-novariable -nocommand $cdata2]]
-			    set text [subst -novariable -nocommand $text]
-			} else {
-			    # start CDATA
-			    set state(cdata) "$cdata1$param>$text"
-			    set state(mode) cdata
-			    continue
-			}
-
-		    }
-
-		    !ELEMENT -
-		    !ATTLIST -
-		    !ENTITY -
-		    !NOTATION {
-			uplevel #0 $options(-errorcommand) \
-			    [list illegaldeclaration "[string range $tag 1 end] declaration\
-				not expected in document instance around line $state(line)"]
-		    }
-
-		    default {
-			uplevel #0 $options(-errorcommand) \
-			    [list unknowninstruction "unknown processing\
-				instruction \"<$tag>\" around line $state(line)"]
-		    }
-		}
-	    }
-	    *,1,* -
-	    *,0,/,/ {
-		# Syntax error
-	    	uplevel #0 $options(-errorcommand) \
-		    [list syntaxerror "syntax error: closed/empty tag:\
-			tag $tag param $param empty $empty close $close around line  
$state(line)"]
-	    }
-	}
-
-	# Process character data
-
-	if {$state(haveDocElement) && [llength $state(stack)]} {
-
-	    # Check if the internal DTD entity is in the text
-	    regsub -all &xml:intdtd\; $text \[$options(-internaldtd)\] text
-
-	    # Look for entity references
-	    if {([array size entities] || \
-		    [string length $options(-entityreferencecommand)]) && \
-		    $options(-defaultexpandinternalentities) && \
-		    [regexp {&[^;]+;} $text]} {
-
-		# protect Tcl specials
-		# NB. braces and backslashes may already be protected
-		regsub -all {\\({|}|\\)} $text {\1} text
-		regsub -all {([][$\\{}])} $text {\\\1} text
-
-		# Mark entity references
-		regsub -all {&([^;]+);} $text \
-		    [format {%s; %s {\1} ; %s %s} \}\} \
-			[namespace code \
-			    [list Entity [array get options] \
-				  $options(-entityreferencecommand) \
-				  $options(-characterdatacommand) \
-				  $options(entities)]] \
-			[namespace code [list DeProtect $options(-characterdatacommand)]] \
-			\{\{] text
-		set text "uplevel #0 [namespace code [list DeProtect1  
$options(-characterdatacommand)]] {{$text}}"
-		eval $text
-	    } else {
-
-		# Restore protected special characters
-		regsub -all {\\([][{}\\])} $text {\1} text
-		uplevel #0 $options(-characterdatacommand) [list $text]
-	    }
-	} elseif {[string length [string trim $text]]} {
-	    uplevel #0 $options(-errorcommand) \
-		[list unexpectedtext "unexpected text \"$text\" in document prolog  
around line $state(line)"]
-	}
+        # Keep track of lines in the input
+        incr state(line) [regsub -all \n $param {} discard]
+        incr state(line) [regsub -all \n $text {} discard]
+
+        # If the current mode is cdata or comment then we must undo what  
the
+        # regsub has done to reconstitute the data
+
+        set empty {}
+        switch -- $state(mode) {
+            comment {
+                # This had "[string length $param] && " as a guard -
+                # can't remember why :-(
+                if {[regexp ([cl ^-]*)--\$ $tag discard comm1]} {
+                    # end of comment (in tag)
+                    set tag {}
+                    set close {}
+                    set state(mode) normal
+                    uplevel #0 $options(-commentcommand) [list  
$state(commentdata)<$comm1]
+                    unset state(commentdata)
+                } elseif {[regexp ([cl ^-]*)--\$ $param discard comm1]} {
+                    # end of comment (in attributes)
+                    uplevel #0 $options(-commentcommand) [list  
$state(commentdata)<$close$tag>$comm1]
+                    unset state(commentdata)
+                    set tag {}
+                    set param {}
+                    set close {}
+                    set state(mode) normal
+                } elseif {[regexp ([cl ^-]*)-->(.*) $text discard comm1  
text]} {
+                    # end of comment (in text)
+                    uplevel #0 $options(-commentcommand) [list  
$state(commentdata)<$close$tag$param>$comm1]
+                    unset state(commentdata)
+                    set tag {}
+                    set param {}
+                    set close {}
+                    set state(mode) normal
+                } else {
+                    # comment continues
+                    append state(commentdata) <$close$tag$param>$text
+                    continue
+                }
+            }
+            cdata {
+                if {[regexp ([cl ^\]]*)\]\][cl $Wsp]*\$ $tag discard  
cdata1]} {
+                    # end of CDATA (in tag)
+                    uplevel #0 $options(-characterdatacommand) \
+                            [list $state(cdata)<[subst -nocommand  
-novariable $close$cdata1]]
+                    set text [subst -novariable -nocommand $text]
+                    set tag {}
+                    unset state(cdata)
+                    set state(mode) normal
+                } elseif {[regexp ([cl ^\]]*)\]\][cl $Wsp]*\$ $param  
discard cdata1]} {
+                    # end of CDATA (in attributes)
+                    uplevel #0 $options(-characterdatacommand) \
+                            [list $state(cdata)<[subst -nocommand  
-novariable $close$tag$cdata1]]
+                    set text [subst -novariable -nocommand $text]
+                    set tag {}
+                    set param {}
+                    unset state(cdata)
+                    set state(mode) normal
+                } elseif {[regexp (.*)\]\][cl $Wsp]*>(.*) $text discard  
cdata1 text]} {
+                    # end of CDATA (in text)
+                    uplevel #0 $options(-characterdatacommand) \
+                            [list $state(cdata)<[subst -nocommand  
-novariable $close$tag$param>$cdata1]]
+                    set text [subst -novariable -nocommand $text]
+                    set tag {}
+                    set param {}
+                    set close {}
+                    unset state(cdata)
+                    set state(mode) normal
+                } else {
+                    # CDATA continues
+                    append state(cdata) [subst -nocommand -novariable  
<$close$tag$param>$text]
+                    continue
+                }
+            }
+            continue {
+                # We're skipping elements looking for the close tag
+                switch -glob -- [string length $tag],[regexp {^\?|!.*}  
$tag],$close {
+                    0,* {
+                        continue
+                    }
+                    *,0, {
+                        if {![string compare $tag $state(continue:tag)]} {
+                            set empty [uplevel #0 $options(-emptyelement)  
[list $tag $param $empty]]
+                            if {![string length $empty]} {
+                                incr state(continue:level)
+                            }
+                        }
+                        continue
+                    }
+                    *,0,/ {
+                        if {![string compare $tag $state(continue:tag)]} {
+                            incr state(continue:level) -1
+                        }
+                        if {!$state(continue:level)} {
+                            unset state(continue:tag)
+                            unset state(continue:level)
+                            set state(mode) {}
+                        }
+                    }
+                    default {
+                        continue
+                    }
+                }
+            }
+            default {
+                # The trailing slash on empty elements can't be  
automatically separated out
+                # in the RE, so we must do it here.
+                regexp (.*)(/)[cl $Wsp]*$ $param discard param empty
+            }
+        }
+
+        # default: normal mode
+
+        # Bug: if the attribute list has a right angle bracket then the  
empty
+        # element marker will not be seen
+
+        set empty [uplevel #0 $options(-emptyelement) [list $tag $param  
$empty]]
+
+        switch -glob -- [string length $tag],[regexp {^\?|!.*}  
$tag],$close,$empty {
+
+            0,0,, {
+                # Ignore empty tag - dealt with non-normal mode above
+            }
+            *,0,, {
+
+                # Start tag for an element.
+
+                # Check if the internal DTD entity is in an attribute value
+                regsub -all &xml:intdtd\; $param  
\[$options(-internaldtd)\] param
+
+                set code [catch {ParseEvent:ElementOpen $tag $param [array  
get options]} msg]
+                set state(haveDocElement) 1
+                switch -- $code {
+                    0 {# OK}
+                    3 {
+                        # break
+                        return {}
+                    }
+                    4 {
+                        # continue
+                        # Remember this tag and look for its close
+                        set state(continue:tag) $tag
+                        set state(continue:level) 1
+                        set state(mode) continue
+                        continue
+                    }
+                    default {
+                        return -code $code -errorinfo $::errorInfo $msg
+                    }
+                }
+
+            }
+
+            *,0,/, {
+
+                # End tag for an element.
+
+                set code [catch {ParseEvent:ElementClose $tag [array get  
options]} msg]
+                switch -- $code {
+                    0 {# OK}
+                    3 {
+                        # break
+                        return {}
+                    }
+                    4 {
+                        # continue
+                        # skip sibling nodes
+                        set state(continue:tag) [lindex $state(stack) end]
+                        set state(continue:level) 1
+                        set state(mode) continue
+                        continue
+                    }
+                    default {
+                        return -code $code -errorinfo $::errorInfo $msg
+                    }
+                }
+
+            }
+
+            *,0,,/ {
+
+                # Empty element
+
+                # The trailing slash sneaks through into the param variable
+                regsub -all /[cl $::sgml::Wsp]*\$ $param {} param
+
+                set code [catch {ParseEvent:ElementOpen $tag $param [array  
get options] -empty 1} msg]
+                set state(haveDocElement) 1
+                switch -- $code {
+                    0 {# OK}
+                    3 {
+                        # break
+                        return {}
+                    }
+                    4 {
+                        # continue
+                        # Pretty useless since it closes straightaway
+                    }
+                    default {
+                        return -code $code -errorinfo $::errorInfo $msg
+                    }
+                }
+                set code [catch {ParseEvent:ElementClose $tag [array get  
options] -empty 1} msg]
+                switch -- $code {
+                    0 {# OK}
+                    3 {
+                        # break
+                        return {}
+                    }
+                    4 {
+                        # continue
+                        # skip sibling nodes
+                        set state(continue:tag) [lindex $state(stack) end]
+                        set state(continue:level) 1
+                        set state(mode) continue
+                        continue
+                    }
+                    default {
+                        return -code $code -errorinfo $::errorInfo $msg
+                    }
+                }
+
+            }
+
+            *,1,* {
+                # Processing instructions or XML declaration
+                switch -glob -- $tag {
+
+                    {\?xml} {
+                        # XML Declaration
+                        if {$state(haveXMLDecl)} {
+                            uplevel #0 $options(-errorcommand) \
+                                    [list illegalcharacter \
+                                          "unexpected characters \"<$tag\"  
around line $state(line)"]
+                        } elseif {![regexp {\?$} $param]} {
+                            uplevel #0 $options(-errorcommand) \
+                                    [list missingcharacters \
+                                          "XML Declaration missing  
characters \"?>\" around line $state(line)"]
+                        } else {
+
+                            # We can do the parsing in one step with Tcl  
8.1 RE's
+                            # This has the benefit of performing better WF  
checking
+
+                            set adv_re [format  
{^[%s]*version[%s]*=[%s]*(\"|')(-+| 
[a-zA-Z0-9_.:]+)\1([%s]+encoding[%s]*=[%s]*("|')([A-Za-z][-A-Za-z0-9._]*)\4)?([%s]*standalone[%s]*=[%s]*("|')(yes| 
no)\7)?[%s]*\?$} $::sgml::Wsp $::sgml::Wsp $::sgml::Wsp $::sgml::Wsp  
$::sgml::Wsp $::sgml::Wsp $::sgml::Wsp $::sgml::Wsp $::sgml::Wsp  
$::sgml::Wsp]
+
+                            if {![regexp $adv_re $param discard delimiter  
version discard \
+                                                        delimiter encoding  
discard delimiter standalone]} {
+                                uplevel #0 $options(-errorcommand) \
+                                    [list illformeddeclaration \
+                                          "XML Declaration not well-formed  
around line $state(line)"]
+                            } else {
+                                # Invoke the callback
+                                uplevel #0 $options(-xmldeclcommand) [list  
$version $encoding $standalone]
+
+                            }
+
+                        }
+
+                    }
+
+                    {\?*} {
+                        # Processing instruction
+                        set tag [string range $tag 1 end]
+                        if {[regsub {\?$} $tag {} tag]} {
+                            if {[string length [string trim $param]]} {
+                                uplevel #0 $options(-errorcommand) \
+                                    [list [list unexpectedtext "unexpected  
text \"$param\"\
+                                        in processing instruction around  
line $state(line)"]]
+                            }
+                        } elseif {![regexp ^$Name\$ $tag]} {
+                            uplevel #0 $options(-errorcommand) \
+                                [list illegalcharacter "illegal character  
in processing instruction target \"$tag\""]
+                        } elseif {[regexp {^[xX][mM][lL]$} $tag]} {
+                            uplevel #0 $options(-errorcommand) \
+                                [list illegalcharacters "characters  
\"xml\" not\
+                                    permitted in processing instruction  
target \"$tag\""]
+                        } elseif {![regsub {\?$} $param {} param]} {
+                            uplevel #0 $options(-errorcommand) \
+                                [list missingquestion "PI: expected '?'  
character around line $state(line)"]
+                        }
+                        set code [catch {
+                                    uplevel #0  
$options(-processinginstructioncommand) \
+                                        [list $tag [string trimleft  
$param]]
+                                  } msg]
+                        switch -- $code {
+                            0 {# OK}
+                            3 {
+                                # break
+                                return {}
+                            }
+                            4 {
+                                # continue
+                                # skip sibling nodes
+                                set state(continue:tag) [lindex  
$state(stack) end]
+                                set state(continue:level) 1
+                                set state(mode) continue
+                                continue
+                            }
+                            default {
+                                return -code $code -errorinfo $::errorInfo  
$msg
+                            }
+                        }
+                    }
+
+                    !DOCTYPE {
+                        # External entity reference
+                        # This should move into xml.tcl
+                        # Parse the params supplied.  Looking for Name,  
ExternalID and MarkupDecl
+                        set matched [regexp ^[cl $Wsp]*($Name)[cl  
$Wsp]*(.*) $param x state(doc_name) param]
+                        set state(doc_name) [Normalize $state(doc_name)  
$options(-normalize)]
+                        set externalID {}
+                        set pubidlit {}
+                        set systemlit {}
+                        set externalID {}
+                        if {[regexp -nocase ^[cl $Wsp]*(SYSTEM|PUBLIC)(.*)  
$param x id param]} {
+                            switch -- [string toupper $id] {
+                                SYSTEM {
+                                    if {[regexp ^[cl $Wsp]+\"([cl  
^\"]*)\"(.*) $param x systemlit param] || \
+                                            [regexp ^[cl $Wsp]+'([cl  
^']*)'(.*) $param x systemlit param]} {
+                                        set externalID [list SYSTEM  
$systemlit] ;# "
+                                    } else {
+                                        uplevel #0 $options(-errorcommand)  
\
+                                            [list XXX "syntax error:  
SYSTEM identifier not followed by literal"]
+                                    }
+                                }
+                                PUBLIC {
+                                    if {[regexp ^[cl $Wsp]+\"([cl  
^\"]*)\"(.*) $param x pubidlit param] || \
+                                            [regexp ^[cl $Wsp]+'([cl  
^']*)'(.*) $param x pubidlit param]} {
+                                        if {[regexp ^[cl $Wsp]+\"([cl  
^\"]*)\"(.*) $param x systemlit param] || \
+                                                [regexp ^[cl $Wsp]+'([cl  
^']*)'(.*) $param x systemlit param]} {
+                                            set externalID [list PUBLIC  
$pubidlit $systemlit]
+                                        } else {
+                                            uplevel #0  
$options(-errorcommand) \
+                                                [list syntaxerror "syntax  
error: PUBLIC identifier\
+                                                    not followed by system  
literal around line $state(line)"]
+                                        }
+                                    } else {
+                                        uplevel #0 $options(-errorcommand)  
\
+                                            [list syntaxerror "syntax  
error: PUBLIC identifier\
+                                                not followed by literal  
around line $state(line)"]
+                                    }
+                                }
+                            }
+                            if {[regexp -nocase ^[cl $Wsp]+NDATA[cl  
$Wsp]+($Name)(.*) $param x notation param]} {
+                                lappend externalID $notation
+                            }
+                        }
+
+                        set state(inDTD) 1
+
+                        ParseEvent:DocTypeDecl [array get options]  
$state(doc_name) \
+                            $pubidlit $systemlit $options(-internaldtd)
+
+                        set state(inDTD) 0
+
+                    }
+
+                    !--* {
+
+                        # Start of a comment
+                        # See if it ends in the same tag, otherwise change  
the
+                        # parsing mode
+
+                        regexp {!--(.*)} $tag discard comm1
+                        if {[regexp ([cl ^-]*)--[cl $Wsp]*\$ $comm1  
discard comm1_1]} {
+                            # processed comment (end in tag)
+                            uplevel #0 $options(-commentcommand) [list  
$comm1_1]
+                        } elseif {[regexp ([cl ^-]*)--[cl $Wsp]*\$ $param  
discard comm2]} {
+                            # processed comment (end in attributes)
+                            uplevel #0 $options(-commentcommand) [list  
$comm1$comm2]
+                        } elseif {[regexp ([cl ^-]*)-->(.*) $text discard  
comm2 text]} {
+                            # processed comment (end in text)
+                            uplevel #0 $options(-commentcommand) [list  
$comm1$param$empty>$comm2]
+                        } else {
+                            # start of comment
+                            set state(mode) comment
+                            set  
state(commentdata) "$comm1$param$empty>$text"
+                            continue
+                        }
+                    }
+
+                    {!\[CDATA\[*} {
+
+                        regexp {!\[CDATA\[(.*)} $tag discard cdata1
+                        if {[regexp {(.*)]]$} $cdata1 discard cdata2]} {
+                            # processed CDATA (end in tag)
+                            uplevel #0 $options(-characterdatacommand)  
[list [subst -novariable -nocommand $cdata2]]
+                            set text [subst -novariable -nocommand $text]
+                        } elseif {[regexp {(.*)]]$} $param discard  
cdata2]} {
+                            # processed CDATA (end in attribute)
+                            # Backslashes in param are quoted at this stage
+                            uplevel #0 $options(-characterdatacommand) \
+                                [list $cdata1[subst -novariable -nocommand  
$cdata2]]
+                            set text [subst -novariable -nocommand $text]
+                        } elseif {[regexp {(.*)]]>(.*)} $text discard  
cdata2 text]} {
+                            # processed CDATA (end in text)
+                            # Backslashes in param and text are quoted at  
this stage
+                            uplevel #0 $options(-characterdatacommand) \
+                                [list $cdata1[subst -novariable -nocommand  
$param]$empty>[subst -novariable -nocommand $cdata2]]
+                            set text [subst -novariable -nocommand $text]
+                        } else {
+                            # start CDATA
+                            set state(cdata) "$cdata1$param>$text"
+                            set state(mode) cdata
+                            continue
+                        }
+
+                    }
+
+                    !ELEMENT -
+                    !ATTLIST -
+                    !ENTITY -
+                    !NOTATION {
+                        uplevel #0 $options(-errorcommand) \
+                            [list illegaldeclaration "[string range $tag 1  
end] declaration\
+                                not expected in document instance around  
line $state(line)"]
+                    }
+
+                    default {
+                        uplevel #0 $options(-errorcommand) \
+                            [list unknowninstruction "unknown processing\
+                                instruction \"<$tag>\" around line  
$state(line)"]
+                    }
+                }
+            }
+            *,1,* -
+            *,0,/,/ {
+                # Syntax error
+                    uplevel #0 $options(-errorcommand) \
+                    [list syntaxerror "syntax error: closed/empty tag:\
+                        tag $tag param $param empty $empty close $close  
around line $state(line)"]
+            }
+        }
+
+        # Process character data
+
+        if {$state(haveDocElement) && [llength $state(stack)]} {
+
+            # Check if the internal DTD entity is in the text
+            regsub -all &xml:intdtd\; $text \[$options(-internaldtd)\] text
+
+            # Look for entity references
+            if {([array size entities] || \
+                    [string length $options(-entityreferencecommand)]) && \
+                    $options(-defaultexpandinternalentities) && \
+                    [regexp {&[^;]+;} $text]} {
+
+                # protect Tcl specials
+                # NB. braces and backslashes may already be protected
+                regsub -all {\\({|}|\\)} $text {\1} text
+                regsub -all {([][$\\{}])} $text {\\\1} text
+
+                # Mark entity references
+                regsub -all {&([^;]+);} $text \
+                    [format {%s; %s {\1} ; %s %s} \}\} \
+                        [namespace code \
+                            [list Entity [array get options] \
+                                  $options(-entityreferencecommand) \
+                                  $options(-characterdatacommand) \
+                                  $options(entities)]] \
+                        [namespace code [list DeProtect  
$options(-characterdatacommand)]] \
+                        \{\{] text
+                set text "uplevel #0 [namespace code [list DeProtect1  
$options(-characterdatacommand)]] {{$text}}"
+                eval $text
+            } else {
+
+                # Restore protected special characters
+                regsub -all {\\([][{}\\])} $text {\1} text
+                uplevel #0 $options(-characterdatacommand) [list $text]
+            }
+        } elseif {[string length [string trim $text]]} {
+            uplevel #0 $options(-errorcommand) \
+                [list unexpectedtext "unexpected text \"$text\" in  
document prolog around line $state(line)"]
+        }

      }

      # If this is the end of the document, close all open containers
      if {$options(-final) && [llength $state(stack)]} {
-	eval $options(-errorcommand) \
-	    [list unclosedelement "element [lindex $state(stack) end] remains  
unclosed around line $state(line)"]
+        eval $options(-errorcommand) \
+            [list unclosedelement "element [lindex $state(stack) end]  
remains unclosed around line $state(line)"]
      }

      return {}
@@ -807,45 +807,45 @@

  # sgml::DeProtect --
  #
-#	Invoke given command after removing protecting backslashes
-#	from given text.
+#       Invoke given command after removing protecting backslashes
+#       from given text.
  #
  # Arguments:
-#	cmd	Command to invoke
-#	text	Text to deprotect
+#       cmd         Command to invoke
+#       text        Text to deprotect
  #
  # Results:
-#	Depends on command
+#       Depends on command

  proc sgml::DeProtect1 {cmd text} {
      if {[string compare {} $text]} {
-	regsub -all {\\([]$[{}\\])} $text {\1} text
-	uplevel #0 $cmd [list $text]
+        regsub -all {\\([]$[{}\\])} $text {\1} text
+        uplevel #0 $cmd [list $text]
      }
  }
  proc sgml::DeProtect {cmd text} {
      set text [lindex $text 0]
      if {[string compare {} $text]} {
-	regsub -all {\\([]$[{}\\])} $text {\1} text
-	uplevel #0 $cmd [list $text]
+        regsub -all {\\([]$[{}\\])} $text {\1} text
+        uplevel #0 $cmd [list $text]
      }
  }

  # sgml::ParserDelete --
  #
-#	Free all memory associated with parser
+#       Free all memory associated with parser
  #
  # Arguments:
-#	var	global state array
+#       var         global state array
  #
  # Results:
-#	Variables unset
+#       Variables unset

  proc sgml::ParserDelete var {
      upvar #0 $var state

      if {![info exists state]} {
-	return -code error "unknown parser"
+        return -code error "unknown parser"
      }

      catch {unset $state(entities)}
@@ -862,20 +862,20 @@

  # sgml::ParseEvent:ElementOpen --
  #
-#	Start of an element.
+#       Start of an element.
  #
  # Arguments:
-#	tag	Element name
-#	attr	Attribute list
-#	opts	Options
-#	args	further configuration options
+#       tag         Element name
+#       attr        Attribute list
+#       opts        Options
+#       args        further configuration options
  #
  # Options:
-#	-empty boolean
-#		indicates whether the element was an empty element
+#       -empty boolean
+#               indicates whether the element was an empty element
  #
  # Results:
-#	Modify state and invoke callback
+#       Modify state and invoke callback

  proc sgml::ParseEvent:ElementOpen {tag attr opts args} {
      variable Name
@@ -887,7 +887,7 @@
      array set cfg $args

      if {$options(-normalize)} {
-	set tag [string toupper $tag]
+        set tag [string toupper $tag]
      }

      # Update state
@@ -895,147 +895,147 @@

      # Parse attribute list into a key-value representation
      if {[string compare $options(-parseattributelistcommand) {}]} {
-	if {[catch {uplevel #0 $options(-parseattributelistcommand) [list $opts  
$attr]} attr]} {
-	    if {[string compare [lindex $attr 0] "unterminated attribute value"]}  
{
-		uplevel #0 $options(-errorcommand) \
-		    [list unterminatedattribute "$attr around line $state(line)"]
-		set attr {}
-	    } else {
-
-		# It is most likely that a ">" character was in an attribute value.
-		# This manifests itself by ">" appearing in the element's text.
-		# In this case the callback should return a three element list;
-		# the message "unterminated attribute value", the attribute list it
-		# did manage to parse and the remainder of the attribute list.
-
-		foreach {msg attlist brokenattr} $attr break
-
-		upvar text elemText
-		if {[string first > $elemText] >= 0} {
-
-		    # Now piece the attribute list back together
-		    regexp ($Name)[cl $Wsp]*=[cl $Wsp]*(\"|')(.*) $brokenattr discard  
attname delimiter attvalue
-		    regexp (.*)>([cl ^>]*)\$ $elemText discard remattlist elemText
-		    regexp ([cl ^$delimiter]*)${delimiter}(.*) $remattlist discard  
remattvalue remattlist
-
-		    append attvalue >$remattvalue
-		    lappend attlist $attname $attvalue
-
-		    # Complete parsing the attribute list
-		    if {[catch {
-			    uplevel #0 $options(-parseattributelistcommand) \
-				       [list $options(-statevariable) $remattlist]
-			 } attr]} {
-			uplevel #0 $options(-errorcommand) [list $attr around line $state(line)]
-			set attr {}
-			set attlist {}
-		    } else {
-			eval lappend attlist $attr
-		    }
-
-		    set attr $attlist
-
-		} else {
-		    uplevel #0 $options(-errorcommand) \
-			[list unterminatedattribute "$attr around line $state(line)"]
-		    set attr {}
-		}
-	    }
-	}
+        if {[catch {uplevel #0 $options(-parseattributelistcommand) [list  
$opts $attr]} attr]} {
+            if {[string compare [lindex $attr 0] "unterminated attribute  
value"]} {
+                uplevel #0 $options(-errorcommand) \
+                    [list unterminatedattribute "$attr around line  
$state(line)"]
+                set attr {}
+            } else {
+
+                # It is most likely that a ">" character was in an  
attribute value.
+                # This manifests itself by ">" appearing in the element's  
text.
+                # In this case the callback should return a three element  
list;
+                # the message "unterminated attribute value", the  
attribute list it
+                # did manage to parse and the remainder of the attribute  
list.
+
+                foreach {msg attlist brokenattr} $attr break
+
+                upvar text elemText
+                if {[string first > $elemText] >= 0} {
+
+                    # Now piece the attribute list back together
+                    regexp ($Name)[cl $Wsp]*=[cl $Wsp]*(\"|')(.*)  
$brokenattr discard attname delimiter attvalue
+                    regexp (.*)>([cl ^>]*)\$ $elemText discard remattlist  
elemText
+                    regexp ([cl ^$delimiter]*)${delimiter}(.*) $remattlist  
discard remattvalue remattlist
+
+                    append attvalue >$remattvalue
+                    lappend attlist $attname $attvalue
+
+                    # Complete parsing the attribute list
+                    if {[catch {
+                            uplevel #0  
$options(-parseattributelistcommand) \
+                                       [list $options(-statevariable)  
$remattlist]
+                         } attr]} {
+                        uplevel #0 $options(-errorcommand) [list $attr  
around line $state(line)]
+                        set attr {}
+                        set attlist {}
+                    } else {
+                        eval lappend attlist $attr
+                    }
+
+                    set attr $attlist
+
+                } else {
+                    uplevel #0 $options(-errorcommand) \
+                        [list unterminatedattribute "$attr around line  
$state(line)"]
+                    set attr {}
+                }
+            }
+        }
      }

      set empty {}
      if {$cfg(-empty) && $options(-reportempty)} {
-	set empty {-empty 1}
+        set empty {-empty 1}
      }

      if {$options(-namespace)} {
-	# Check for namespace declarations
-	upvar #0 $options(namespaces) namespaces
-	set nsdecls {}
-	if {[llength $attr]} {
-	    array set attrlist $attr
-	    foreach {attrName attrValue} [array get attrlist xmlns*] {
-		unset attrlist($attrName)
-		set colon [set prefix {}]
-		if {[regexp {^xmlns(:(.+))?$} $attrName discard colon prefix]} {
-		    switch -glob -- [string length $colon],[string length $prefix] {
-			*,0 -
-			0,0 {
-			    # *,0 is a HACK: Ignore empty namespace prefix
-			    # TODO: investigate it
-			    # default NS declaration
-			    lappend state(defaultNSURI) $attrValue
-			    lappend state(defaultNS) [llength $state(stack)]
-			    lappend nsdecls $attrValue {}
-			}
-			0,* {
-			    # Huh?
-			}
-			*,0 {
-			    # Error
-			    uplevel #0 $state(-warningcommand) \
-			        "no prefix specified for namespace URI \"$attrValue\" in  
element \"$tag\""
-			}
-			default {
-			    set namespaces($prefix,[llength $state(stack)]) $attrValue
-			    lappend nsdecls $attrValue $prefix
-			}
-		    }
-		}
-	    }
-	    if {[llength $nsdecls]} {
-		set nsdecls [list -namespacedecls $nsdecls]
-	    }
-	    set attr [array get attrlist]
-	}
-
-	# Check whether this element has an expanded name
-	set ns {}
-	if {[regexp {([^:]+):(.*)$} $tag discard prefix tag1]} {
-	    set nsspec [lsort -dictionary -decreasing [array names namespaces  
$prefix,*]]
-	    if {[llength $nsspec]} {
-		set tag $tag1
-		set nsuri $namespaces([lindex $nsspec 0])
-		set ns [list -namespace $nsuri]
-	    } else {
-		# HACK: ignore undeclared namespace (and replace it by default one)
-		# TODO: investigate it
-		#uplevel #0 $options(-errorcommand) \
-		#	[list namespaceundeclared "no namespace declared for prefix  
\"$prefix\" in element $tag"]
-		if {[llength $state(defaultNSURI)]} {
-		    set ns [list -namespace [lindex $state(defaultNSURI) end]]
-		}
-	    }
-	} elseif {[llength $state(defaultNSURI)]} {
-	    set ns [list -namespace [lindex $state(defaultNSURI) end]]
-	}
-
-	# Prepend attributes with XMLNS URI
-	set attr1 {}
-	foreach {key val} $attr {
-	    if {[regexp {([^:]+):(.*)$} $key discard prefix key1]} {
-		set nsspec [lsort -dictionary -decreasing [array names namespaces  
$prefix,*]]
-		if {[llength $nsspec]} {
-		    set nsuri $namespaces([lindex $nsspec 0])
-		    lappend attr1 $nsuri:$key1 $val
-		} else {
-		    # HACK: ignore undeclared namespace
-		    # TODO: investigate it
-		    #uplevel #0 $options(-errorcommand) \
-		    #	[list namespaceundeclared "no namespace declared for prefix  
\"$prefix\" in attribute $key"]
-		    lappend attr1 $key $val
-		}
-	    } else {
-		lappend attr1 $key $val
-	    }
-	}
+        # Check for namespace declarations
+        upvar #0 $options(namespaces) namespaces
+        set nsdecls {}
+        if {[llength $attr]} {
+            array set attrlist $attr
+            foreach {attrName attrValue} [array get attrlist xmlns*] {
+                unset attrlist($attrName)
+                set colon [set prefix {}]
+                if {[regexp {^xmlns(:(.+))?$} $attrName discard colon  
prefix]} {
+                    switch -glob -- [string length $colon],[string length  
$prefix] {
+                        *,0 -
+                        0,0 {
+                            # *,0 is a HACK: Ignore empty namespace prefix
+                            # TODO: investigate it
+                            # default NS declaration
+                            lappend state(defaultNSURI) $attrValue
+                            lappend state(defaultNS) [llength  
$state(stack)]
+                            lappend nsdecls $attrValue {}
+                        }
+                        0,* {
+                            # Huh?
+                        }
+                        *,0 {
+                            # Error
+                            uplevel #0 $state(-warningcommand) \
+                                "no prefix specified for namespace URI  
\"$attrValue\" in element \"$tag\""
+                        }
+                        default {
+                            set namespaces($prefix,[llength  
$state(stack)]) $attrValue
+                            lappend nsdecls $attrValue $prefix
+                        }
+                    }
+                }
+            }
+            if {[llength $nsdecls]} {
+                set nsdecls [list -namespacedecls $nsdecls]
+            }
+            set attr [array get attrlist]
+        }
+
+        # Check whether this element has an expanded name
+        set ns {}
+        if {[regexp {([^:]+):(.*)$} $tag discard prefix tag1]} {
+            set nsspec [lsort -dictionary -decreasing [array names  
namespaces $prefix,*]]
+            if {[llength $nsspec]} {
+                set tag $tag1
+                set nsuri $namespaces([lindex $nsspec 0])
+                set ns [list -namespace $nsuri]
+            } else {
+                # HACK: ignore undeclared namespace (and replace it by  
default one)
+                # TODO: investigate it
+                #uplevel #0 $options(-errorcommand) \
+                #        [list namespaceundeclared "no namespace declared  
for prefix \"$prefix\" in element $tag"]
+                if {[llength $state(defaultNSURI)]} {
+                    set ns [list -namespace [lindex $state(defaultNSURI)  
end]]
+                }
+            }
+        } elseif {[llength $state(defaultNSURI)]} {
+            set ns [list -namespace [lindex $state(defaultNSURI) end]]
+        }
+
+        # Prepend attributes with XMLNS URI
+        set attr1 {}
+        foreach {key val} $attr {
+            if {[regexp {([^:]+):(.*)$} $key discard prefix key1]} {
+                set nsspec [lsort -dictionary -decreasing [array names  
namespaces $prefix,*]]
+                if {[llength $nsspec]} {
+                    set nsuri $namespaces([lindex $nsspec 0])
+                    lappend attr1 $nsuri:$key1 $val
+                } else {
+                    # HACK: ignore undeclared namespace
+                    # TODO: investigate it
+                    #uplevel #0 $options(-errorcommand) \
+                    #        [list namespaceundeclared "no namespace  
declared for prefix \"$prefix\" in attribute $key"]
+                    lappend attr1 $key $val
+                }
+            } else {
+                lappend attr1 $key $val
+            }
+        }

-	# Invoke callback
-	set code [catch {uplevel #0 $options(-elementstartcommand) [list $tag  
$attr1] $empty $ns $nsdecls} msg]
+        # Invoke callback
+        set code [catch {uplevel #0 $options(-elementstartcommand) [list  
$tag $attr1] $empty $ns $nsdecls} msg]
      } else {
-	# Invoke callback
-	set code [catch {uplevel #0 $options(-elementstartcommand) [list $tag  
$attr] $empty} msg]
+        # Invoke callback
+        set code [catch {uplevel #0 $options(-elementstartcommand) [list  
$tag $attr] $empty} msg]
      }

      return -code $code -errorinfo $::errorInfo $msg
@@ -1043,19 +1043,19 @@

  # sgml::ParseEvent:ElementClose --
  #
-#	End of an element.
+#       End of an element.
  #
  # Arguments:
-#	tag	Element name
-#	opts	Options
-#	args	further configuration options
+#       tag         Element name
+#       opts        Options
+#       args        further configuration options
  #
  # Options:
-#	-empty boolean
-#		indicates whether the element as an empty element
+#       -empty boolean
+#               indicates whether the element as an empty element
  #
  # Results:
-#	Modify state and invoke callback
+#       Modify state and invoke callback

  proc sgml::ParseEvent:ElementClose {tag opts args} {
      array set options $opts
@@ -1065,40 +1065,40 @@

      # WF check
      if {[string compare $tag [lindex $state(stack) end]]} {
-	uplevel #0 $options(-errorcommand) \
-	    [list illegalendtag "end tag \"$tag\" does not match open\
-		element \"[lindex $state(stack) end]\" around line $state(line)"]
-	return
+        uplevel #0 $options(-errorcommand) \
+            [list illegalendtag "end tag \"$tag\" does not match open\
+                element \"[lindex $state(stack) end]\" around line  
$state(line)"]
+        return
      }

      # Check whether this element has an expanded name
      upvar #0 $options(namespaces) namespaces
      set ns {}
      if {[regexp {([^:]+):(.*)$} $tag discard prefix tag1]} {
-	set nsspec [lsort -dictionary -decreasing [array names namespaces  
$prefix,*]]
-	if {[llength $nsspec]} {
-	    set tag $tag1
-	    set nsuri $namespaces([lindex $nsspec 0])
-	    set ns [list -namespace $nsuri]
-	} else {
-	    # HACK: ignore undeclared namespace (and replace it by default one)
-	    if {[llength $state(defaultNSURI)]} {
-		set ns [list -namespace [lindex $state(defaultNSURI) end]]
-	    }
-	}
+        set nsspec [lsort -dictionary -decreasing [array names namespaces  
$prefix,*]]
+        if {[llength $nsspec]} {
+            set tag $tag1
+            set nsuri $namespaces([lindex $nsspec 0])
+            set ns [list -namespace $nsuri]
+        } else {
+            # HACK: ignore undeclared namespace (and replace it by default  
one)
+            if {[llength $state(defaultNSURI)]} {
+                set ns [list -namespace [lindex $state(defaultNSURI) end]]
+            }
+        }
      } elseif {[llength $state(defaultNSURI)]} {
-	set ns [list -namespace [lindex $state(defaultNSURI) end]]
+        set ns [list -namespace [lindex $state(defaultNSURI) end]]
      }

      # Pop namespace stacks, if any
      if {[llength $state(defaultNS)]} {
-	if {[llength $state(stack)] == [lindex $state(defaultNS) end]} {
-	    set state(defaultNS) [lreplace $state(defaultNS) end end]
-	    set state(defaultNSURI) [lreplace $state(defaultNSURI) end end]
-	}
+        if {[llength $state(stack)] == [lindex $state(defaultNS) end]} {
+            set state(defaultNS) [lreplace $state(defaultNS) end end]
+            set state(defaultNSURI) [lreplace $state(defaultNSURI) end end]
+        }
      }
      foreach nsspec [array names namespaces *,[llength $state(stack)]] {
-	unset namespaces($nsspec)
+        unset namespaces($nsspec)
      }

      # Update state
@@ -1106,7 +1106,7 @@

      set empty {}
      if {$cfg(-empty) && $options(-reportempty)} {
-	set empty {-empty 1}
+        set empty {-empty 1}
      }

      # Invoke callback
@@ -1117,116 +1117,116 @@

  # sgml::Normalize --
  #
-#	Perform name normalization if required
+#       Perform name normalization if required
  #
  # Arguments:
-#	name	name to normalize
-#	req	normalization required
+#       name        name to normalize
+#       req         normalization required
  #
  # Results:
-#	Name returned as upper-case if normalization required
+#       Name returned as upper-case if normalization required

  proc sgml::Normalize {name req} {
      if {$req} {
-	return [string toupper $name]
+        return [string toupper $name]
      } else {
-	return $name
+        return $name
      }
  }

  # sgml::Entity --
  #
-#	Resolve XML entity references (syntax: &xxx;).
+#       Resolve XML entity references (syntax: &xxx;).
  #
  # Arguments:
-#	opts		options
-#	entityrefcmd	application callback for entity references
-#	pcdatacmd	application callback for character data
-#	entities	name of array containing entity definitions.
-#	ref		entity reference (the "xxx" bit)
+#       opts         options
+#       entityrefcmd application callback for entity references
+#       pcdatacmd    application callback for character data
+#       entities     name of array containing entity definitions.
+#       ref          entity reference (the "xxx" bit)
  #
  # Results:
-#	Returns substitution text for given entity.
+#       Returns substitution text for given entity.

  proc sgml::Entity {opts entityrefcmd pcdatacmd entities ref} {
      array set options $opts
      upvar #0 $options(-statevariable) state

      if {![string length $entities]} {
-	set entities [namespace current]::EntityPredef
+        set entities [namespace current]::EntityPredef
      }

      switch -glob -- $ref {
-	%* {
-	    # Parameter entity - not recognised outside of a DTD
-	}
-	#x* {
-	    # Character entity - hex
-	    if {[catch {format %c [scan [string range $ref 2 end] %x tmp; set  
tmp]} char]} {
-		return -code error "malformed character entity \"$ref\""
-	    }
-	    uplevel #0 $pcdatacmd [list $char]
+        %* {
+            # Parameter entity - not recognised outside of a DTD
+        }
+        #x* {
+            # Character entity - hex
+            if {[catch {format %c [scan [string range $ref 2 end] %x tmp;  
set tmp]} char]} {
+                return -code error "malformed character entity \"$ref\""
+            }
+            uplevel #0 $pcdatacmd [list $char]

-	    return {}
+            return {}

-	}
-	#* {
-	    # Character entity - decimal
-	    if {[catch {format %c [scan [string range $ref 1 end] %d tmp; set  
tmp]} char]} {
-		return -code error "malformed character entity \"$ref\""
-	    }
-	    uplevel #0 $pcdatacmd [list $char]
+        }
+        #* {
+            # Character entity - decimal
+            if {[catch {format %c [scan [string range $ref 1 end] %d tmp;  
set tmp]} char]} {
+                return -code error "malformed character entity \"$ref\""
+            }
+            uplevel #0 $pcdatacmd [list $char]

-	    return {}
+            return {}

-	}
-	default {
-	    # General entity
-	    upvar #0 $entities map
-	    if {[info exists map($ref)]} {
+        }
+        default {
+            # General entity
+            upvar #0 $entities map
+            if {[info exists map($ref)]} {

-		if {![regexp {<|&} $map($ref)]} {
+                if {![regexp {<|&} $map($ref)]} {

-		    # Simple text replacement - optimise
-		    uplevel #0 $pcdatacmd [list $map($ref)]
+                    # Simple text replacement - optimise
+                    uplevel #0 $pcdatacmd [list $map($ref)]

-		    return {}
+                    return {}

-		}
+                }

-		# Otherwise an additional round of parsing is required.
-		# This only applies to XML, since HTML doesn't have general entities
+                # Otherwise an additional round of parsing is required.
+                # This only applies to XML, since HTML doesn't have  
general entities

-		# Must parse the replacement text for start & end tags, etc
-		# This text must be self-contained: balanced closing tags, and so on
+                # Must parse the replacement text for start & end tags, etc
+                # This text must be self-contained: balanced closing tags,  
and so on

-		set tokenised [tokenise $map($ref) $::xml::tokExpr1 $::xml::tokExpr2  
$::xml::tokExpr3 $::xml::substExpr]
-		set options(-final) 0
-		eval parseEvent [list $tokenised] [array get options]
+                set tokenised [tokenise $map($ref) $::xml::tokExpr1  
$::xml::tokExpr2 $::xml::tokExpr3 $::xml::substExpr]
+                set options(-final) 0
+                eval parseEvent [list $tokenised] [array get options]

-		return {}
+                return {}

-	    } elseif {[string compare $entityrefcmd "::sgml::noop"]} {
+            } elseif {[string compare $entityrefcmd "::sgml::noop"]} {

-		set result [uplevel #0 $entityrefcmd [list $ref]]
+                set result [uplevel #0 $entityrefcmd [list $ref]]

-		if {[string length $result]} {
-		    uplevel #0 $pcdatacmd [list $result]
-		}
+                if {[string length $result]} {
+                    uplevel #0 $pcdatacmd [list $result]
+                }

-		return {}
+                return {}

-	    } else {
+            } else {

-		# Reconstitute entity reference
+                # Reconstitute entity reference

-		uplevel #0 $options(-errorcommand) \
-		    [list illegalentity "undefined entity reference \"$ref\""]
+                uplevel #0 $options(-errorcommand) \
+                    [list illegalentity "undefined entity reference  
\"$ref\""]

-		return {}
+                return {}

-	    }
-	}
+            }
+        }
      }

      # If all else fails leave the entity reference untouched
@@ -1246,14 +1246,14 @@

  # sgml::ParseEvent:DocTypeDecl --
  #
-#	Entry point for DTD parsing
+#       Entry point for DTD parsing
  #
  # Arguments:
-#	opts	configuration options
-#	docEl	document element name
-#	pubId	public identifier
-#	sysId	system identifier (a URI)
-#	intSSet	internal DTD subset
+#       opts        configuration options
+#       docEl       document element name
+#       pubId       public identifier
+#       sysId       system identifier (a URI)
+#       intSSet     internal DTD subset

  proc sgml::ParseEvent:DocTypeDecl {opts docEl pubId sysId intSSet} {
      array set options {}
@@ -1261,17 +1261,17 @@

      set code [catch {uplevel #0 $options(-doctypecommand) [list $docEl  
$pubId $sysId $intSSet]} err]
      switch -- $code {
-	3 {
-	    # break
-	    return {}
-	}
-	0 -
-	4 {
-	    # continue
-	}
-	default {
-	    return -code $code $err
-	}
+        3 {
+            # break
+            return {}
+        }
+        0 -
+        4 {
+            # continue
+        }
+        default {
+            return -code $code $err
+        }
      }

      # Otherwise we'll parse the DTD and report it piecemeal
@@ -1289,7 +1289,7 @@
      # DTD data.  The application may supply its own resolver.

      if {[string length $pubId] || [string length $sysId]} {
-	uplevel #0 $options(-externalentitycommand) [list $options(-name)  
$options(-baseurl) $sysId $pubId]
+        uplevel #0 $options(-externalentitycommand) [list $options(-name)  
$options(-baseurl) $sysId $pubId]
      }

      return {}
@@ -1297,16 +1297,16 @@

  # sgml::ParseDTD:Internal --
  #
-#	Parse the internal DTD subset.
+#       Parse the internal DTD subset.
  #
-#	Parameter entities are only allowed between markup declarations.
+#       Parameter entities are only allowed between markup declarations.
  #
  # Arguments:
-#	opts	configuration options
-#	dtd	DTD data
+#       opts        configuration options
+#       dtd         DTD data
  #
  # Results:
-#	Markup declarations parsed may cause callback invocation
+#       Markup declarations parsed may cause callback invocation

  proc sgml::ParseDTD:Internal {opts dtd} {
      variable MarkupDeclExpr
@@ -1341,47 +1341,47 @@
      # Process the tokens
      foreach {decl value text} [lrange "{} {} \{$dtd\}" 3 end] {

-	# Keep track of line numbers
-	incr state(line) [regsub -all \n $text {} discard]
+        # Keep track of line numbers
+        incr state(line) [regsub -all \n $text {} discard]

-	ParseDTD:EntityMode [array get options] mode replText decl value text  
$delimiter $name $param
+        ParseDTD:EntityMode [array get options] mode replText decl value  
text $delimiter $name $param

-	ParseDTD:ProcessMarkupDecl [array get options] decl value delimiter name  
mode replText text param
+        ParseDTD:ProcessMarkupDecl [array get options] decl value  
delimiter name mode replText text param

-	# There may be parameter entity references between markup decls
+        # There may be parameter entity references between markup decls

-	if {[regexp {%.*;} $text]} {
-
-	    # Protect Tcl special characters
-	    regsub -all {([{}\\])} $text {\\\1} text
-
-	    regsub -all %($::sgml::Name)\; $text "\} {\\1} \{" text
-
-	    set PElist "\{$text\}"
-	    set PElist [lreplace $PElist end end]
-	    foreach {text entref} $PElist {
-		if {[string length [string trim $text]]} {
-		    uplevel #0 $options(-errorcommand) \
-			[list unexpectedtext "unexpected text in internal DTD subset around  
line $state(line)"]
-		}
-
-		# Expand parameter entity and recursively parse
-		# BUG: no checks yet for recursive entity references
-
-		if {[info exists PEnts($entref)]} {
-		    set externalParser [$options(-name) entityparser]
-		    $externalParser parse $PEnts($entref) -dtdsubset internal
-		} elseif {[info exists ExtPEnts($entref)]} {
-		    set externalParser [$options(-name) entityparser]
-		    $externalParser parse $ExtPEnts($entref) -dtdsubset external
-		    #$externalParser free
-		} else {
-		    uplevel #0 $options(-errorcommand) \
-			[list illegalreference "reference to undeclared parameter entity  
\"$entref\""]
-		}
-	    }
+        if {[regexp {%.*;} $text]} {
+
+            # Protect Tcl special characters
+            regsub -all {([{}\\])} $text {\\\1} text
+
+            regsub -all %($::sgml::Name)\; $text "\} {\\1} \{" text
+
+            set PElist "\{$text\}"
+            set PElist [lreplace $PElist end end]
+            foreach {text entref} $PElist {
+                if {[string length [string trim $text]]} {
+                    uplevel #0 $options(-errorcommand) \
+                        [list unexpectedtext "unexpected text in internal  
DTD subset around line $state(line)"]
+                }
+
+                # Expand parameter entity and recursively parse
+                # BUG: no checks yet for recursive entity references
+
+                if {[info exists PEnts($entref)]} {
+                    set externalParser [$options(-name) entityparser]
+                    $externalParser parse $PEnts($entref) -dtdsubset  
internal
+                } elseif {[info exists ExtPEnts($entref)]} {
+                    set externalParser [$options(-name) entityparser]
+                    $externalParser parse $ExtPEnts($entref) -dtdsubset  
external
+                    #$externalParser free
+                } else {
+                    uplevel #0 $options(-errorcommand) \
+                        [list illegalreference "reference to undeclared  
parameter entity \"$entref\""]
+                }
+            }

-	}
+        }

      }

@@ -1390,21 +1390,21 @@

  # sgml::ParseDTD:EntityMode --
  #
-#	Perform special processing for various parser modes
+#       Perform special processing for various parser modes
  #
  # Arguments:
-#	opts	configuration options
-#	modeVar	pass-by-reference mode variable
-#	replTextVar	pass-by-ref
-#	declVar	pass-by-ref
-#	valueVar	pass-by-ref
-#	textVar	pass-by-ref
-#	delimiter	delimiter currently in force
-#	name
-#	param
+#       opts        configuration options
+#       modeVar     pass-by-reference mode variable
+#       replTextVar pass-by-ref
+#       declVar     pass-by-ref
+#       valueVar    pass-by-ref
+#       textVar     pass-by-ref
+#       delimiter   delimiter currently in force
+#       name
+#       param
  #
  # Results:
-#	Depends on current mode
+#       Depends on current mode

  proc sgml::ParseDTD:EntityMode {opts modeVar replTextVar declVar valueVar  
textVar delimiter name param} {
      upvar 1 $modeVar mode
@@ -1415,81 +1415,81 @@
      array set options $opts

      switch -- $mode {
-	{} {
-	    # Pass through to normal processing section
-	}
-	entity {
-	    # Look for closing delimiter
-	    if {[regexp ([cl ^$delimiter]*)${delimiter}(.*) $decl discard val1  
remainder]} {
-		append replText <$val1
-		DTD:ENTITY [array get options] $name [string trim $param]  
$delimiter$replText$delimiter
-		set decl /
-		set text $remainder\ $value>$text
-		set value {}
-		set mode {}
-	    } elseif {[regexp ([cl ^$delimiter]*)${delimiter}(.*) $value discard  
val2 remainder]} {
-		append replText <$decl\ $val2
-		DTD:ENTITY [array get options] $name [string trim $param]  
$delimiter$replText$delimiter
-		set decl /
-		set text $remainder>$text
-		set value {}
-		set mode {}
-	    } elseif {[regexp ([cl ^$delimiter]*)${delimiter}(.*) $text discard  
val3 remainder]} {
-		append replText <$decl\ $value>$val3
-		DTD:ENTITY [array get options] $name [string trim $param]  
$delimiter$replText$delimiter
-		set decl /
-		set text $remainder
-		set value {}
-		set mode {}
-	    } else {
-
-		# Remain in entity mode
-		append replText <$decl\ $value>$text
-		return -code continue
-
-	    }
-	}
-
-	ignore {
-	    upvar #0 $options(-statevariable) state
-
-	    if {[regexp {]](.*)$} $decl discard remainder]} {
-		set state(condSections) [lreplace $state(condSections) end end]
-		set decl $remainder
-		set mode {}
-	    } elseif {[regexp {]](.*)$} $value discard remainder]} {
-		set state(condSections) [lreplace $state(condSections) end end]
-		regexp <[cl $::sgml::Wsp]*($::sgml::Name)(.*) $remainder discard decl  
value
-		set mode {}
-	    } elseif {[regexp {]]>(.*)$} $text discard remainder]} {
-		set state(condSections) [lreplace $state(condSections) end end]
-		set decl /
-		set value {}
-		set text $remainder
-		#regexp <[cl $::sgml::Wsp]*($::sgml::Name)([cl ^>]*)>(.*) $remainder  
discard decl value text
-		set mode {}
-	    } else {
-		set decl /
-	    }
-
-	}
-
-	comment {
-	    # Look for closing comment delimiter
-
-	    upvar #0 $options(-statevariable) state
-
-	    if {[regexp (.*?)--(.*)\$ $decl discard data1 remainder]} {
-	    } elseif {[regexp (.*?)--(.*)\$ $value discard data1 remainder]} {
-	    } elseif {[regexp (.*?)--(.*)\$ $text discard data1 remainder]} {
-	    } else {
-		# comment continues
-		append state(commentdata) <$decl\ $value>$text
-		set decl /
-		set value {}
-		set text {}
-	    }
-	}
+        {} {
+            # Pass through to normal processing section
+        }
+        entity {
+            # Look for closing delimiter
+            if {[regexp ([cl ^$delimiter]*)${delimiter}(.*) $decl discard  
val1 remainder]} {
+                append replText <$val1
+                DTD:ENTITY [array get options] $name [string trim $param]  
$delimiter$replText$delimiter
+                set decl /
+                set text $remainder\ $value>$text
+                set value {}
+                set mode {}
+            } elseif {[regexp ([cl ^$delimiter]*)${delimiter}(.*) $value  
discard val2 remainder]} {
+                append replText <$decl\ $val2
+                DTD:ENTITY [array get options] $name [string trim $param]  
$delimiter$replText$delimiter
+                set decl /
+                set text $remainder>$text
+                set value {}
+                set mode {}
+            } elseif {[regexp ([cl ^$delimiter]*)${delimiter}(.*) $text  
discard val3 remainder]} {
+                append replText <$decl\ $value>$val3
+                DTD:ENTITY [array get options] $name [string trim $param]  
$delimiter$replText$delimiter
+                set decl /
+                set text $remainder
+                set value {}
+                set mode {}
+            } else {
+
+                # Remain in entity mode
+                append replText <$decl\ $value>$text
+                return -code continue
+
+            }
+        }
+
+        ignore {
+            upvar #0 $options(-statevariable) state
+
+            if {[regexp {]](.*)$} $decl discard remainder]} {
+                set state(condSections) [lreplace $state(condSections) end  
end]
+                set decl $remainder
+                set mode {}
+            } elseif {[regexp {]](.*)$} $value discard remainder]} {
+                set state(condSections) [lreplace $state(condSections) end  
end]
+                regexp <[cl $::sgml::Wsp]*($::sgml::Name)(.*) $remainder  
discard decl value
+                set mode {}
+            } elseif {[regexp {]]>(.*)$} $text discard remainder]} {
+                set state(condSections) [lreplace $state(condSections) end  
end]
+                set decl /
+                set value {}
+                set text $remainder
+                #regexp <[cl $::sgml::Wsp]*($::sgml::Name)([cl ^>]*)>(.*)  
$remainder discard decl value text
+                set mode {}
+            } else {
+                set decl /
+            }
+
+        }
+
+        comment {
+            # Look for closing comment delimiter
+
+            upvar #0 $options(-statevariable) state
+
+            if {[regexp (.*?)--(.*)\$ $decl discard data1 remainder]} {
+            } elseif {[regexp (.*?)--(.*)\$ $value discard data1  
remainder]} {
+            } elseif {[regexp (.*?)--(.*)\$ $text discard data1  
remainder]} {
+            } else {
+                # comment continues
+                append state(commentdata) <$decl\ $value>$text
+                set decl /
+                set value {}
+                set text {}
+            }
+        }

      }

@@ -1498,21 +1498,21 @@

  # sgml::ParseDTD:ProcessMarkupDecl --
  #
-#	Process a single markup declaration
+#       Process a single markup declaration
  #
  # Arguments:
-#	opts	configuration options
-#	declVar	pass-by-ref
-#	valueVar	pass-by-ref
-#	delimiterVar	pass-by-ref for current delimiter in force
-#	nameVar	pass-by-ref
-#	modeVar	pass-by-ref for current parser mode
-#	replTextVar	pass-by-ref
-#	textVar	pass-by-ref
-#	paramVar	pass-by-ref
+#       opts         configuration options
+#       declVar      pass-by-ref
+#       valueVar     pass-by-ref
+#       delimiterVar pass-by-ref for current delimiter in force
+#       nameVar      pass-by-ref
+#       modeVar      pass-by-ref for current parser mode
+#       replTextVar  pass-by-ref
+#       textVar      pass-by-ref
+#       paramVar     pass-by-ref
  #
  # Results:
-#	Depends on markup declaration.  May change parser mode
+#       Depends on markup declaration.  May change parser mode

  proc sgml::ParseDTD:ProcessMarkupDecl {opts declVar valueVar delimiterVar  
nameVar modeVar replTextVar textVar paramVar} {
      upvar 1 $modeVar mode
@@ -1532,213 +1532,213 @@

      switch -glob -- $decl {

-	/ {
-	    # continuation from entity processing
-	}
-
-	!ELEMENT {
-	    # Element declaration
-	    if {[regexp $declExpr $value discard tag cmodel]} {
-		DTD:ELEMENT [array get options] $tag $cmodel
-	    } else {
-		uplevel #0 $options(-errorcommand) \
-		    [list illegaldeclaration "malformed element declaration around line  
$state(line)"]
-	    }
-	}
-
-	!ATTLIST {
-	    # Attribute list declaration
-	    variable declExpr
-	    if {[regexp $declExpr $value discard tag attdefns]} {
-		if {[catch {DTD:ATTLIST [array get options] $tag $attdefns} err]} {
-		    #puts stderr "Stack trace: $::errorInfo\n***\n"
-		    # Atttribute parsing has bugs at the moment
-		    #return -code error "$err around line $state(line)"
-		    return {}
-		}
-	    } else {
-		uplevel #0 $options(-errorcommand) \
-		    [list illegaldeclaration "malformed attribute list declaration  
around line $state(line)"]
-	    }
-	}
-
-	!ENTITY {
-	    # Entity declaration
-	    variable EntityExpr
-
-	    if {[regexp $EntityExpr $value discard param name value]} {
-
-		# Entity replacement text may have a '>' character.
-		# In this case, the real delimiter will be in the following
-		# text.  This is complicated by the possibility of there
-		# being several '<','>' pairs in the replacement text.
-		# At this point, we are searching for the matching quote delimiter.
-
-		if {[regexp $ExternalEntityExpr $value]} {
-		    DTD:ENTITY [array get options] $name [string trim $param] $value
-		} elseif {[regexp (\"|')(.*?)\\1(.*) $value discard delimiter replText  
value]} {
-
-		    if {[string length [string trim $value]]} {
-			uplevel #0 $options(-errorcommand) \
-			    [list illegaldeclaration "malformed entity declaration around line  
$state(line)"]
-		    } else {
-			DTD:ENTITY [array get options] $name [string trim $param]  
$delimiter$replText$delimiter
-		    }
-		} elseif {[regexp (\"|')(.*) $value discard delimiter replText]} {
-		    append replText >$text
-		    set text {}
-		    set mode entity
-		} else {
-		    uplevel #0 $options(-errorcommand) \
-			[list illegaldeclaration "no delimiter for entity declaration around  
line $state(line)"]
-		}
-
-	    } else {
-		uplevel #0 $options(-errorcommand) \
-		    [list illegaldeclaration "malformed entity declaration around line  
$state(line)"]
-	    }
-	}
-
-	!NOTATION {
-	    # Notation declaration
-	    if {[regexp $declExpr param discard tag notation]} {
-		DTD:ENTITY [array get options] $tag $notation
-	    } else {
-		uplevel #0 $options(-errorcommand) \
-		    [list illegaldeclaration "malformed entity declaration around line  
$state(line)"]
-	    }
-	}
-
-	!--* {
-	    # Start of a comment
-
-	    if {[regexp !--(.*?)--\$ $decl discard data]} {
-		if {[string length [string trim $value]]} {
-		    uplevel #0 $options(-errorcommand) [list unexpectedtext "unexpected  
text \"$value\""]
-		}
-		uplevel #0 $options(-commentcommand) [list $data]
-		set decl /
-		set value {}
-	    } elseif {[regexp -- ^(.*?)--\$ $value discard data2]} {
-		regexp !--(.*)\$ $decl discard data1
-		uplevel #0 $options(-commentcommand) [list $data1\ $data2]
-		set decl /
-		set value {}
-	    } elseif {[regexp (.*?)-->(.*)\$ $text discard data3 remainder]} {
-		regexp !--(.*)\$ $decl discard data1
-		uplevel #0 $options(-commentcommand) [list $data1\ $value>$data3]
-		set decl /
-		set value {}
-		set text $remainder
-	    } else {
-		regexp !--(.*)\$ $decl discard data1
-		set state(commentdata) $data1\ $value>$text
-		set decl /
-		set value {}
-		set text {}
-		set mode comment
-	    }
-	}
-
-	!*INCLUDE* -
-	!*IGNORE* {
-	    if {$state(inInternalDTD)} {
-		uplevel #0 $options(-errorcommand) \
-		    [list illegalsection "conditional section not permitted in internal  
DTD\
-			subset around line $state(line)"]
-	    }
-
-	    if {[regexp {^!\[INCLUDE\[(.*)} $decl discard remainder]} {
-		# Push conditional section stack, popped by ]]> sequence
-
-		if {[regexp {(.*?)]]$} $remainder discard r2]} {
-		    # section closed immediately
-		    if {[string length [string trim $r2]]} {
-			uplevel #0 $options(-errorcommand) \
-			    [list unexpectedtext "unexpected text \"$r2\" in conditional  
section"]
-		    }
-		} elseif {[regexp {(.*?)]](.*)} $value discard r2 r3]} {
-		    # section closed immediately
-		    if {[string length [string trim $r2]]} {
-			uplevel #0 $options(-errorcommand) \
-			    [list unexpectedtext "unexpected text \"$r2\" in conditional  
section"]
-		    }
-		    if {[string length [string trim $r3]]} {
-			uplevel #0 $options(-errorcommand) \
-			    [list "unexpected text \"$r3\" in conditional section"]
-		    }
-		} else {
-
-		    lappend state(condSections) INCLUDE
-
-		    set parser [$options(-name) entityparser]
-		    $parser parse $remainder\ $value> -dtdsubset external
-		    #$parser free
-
-		    if {[regexp {(.*?)]]>(.*)} $text discard t1 t2]} {
-			if {[string length [string trim $t1]]} {
-			    uplevel #0 $options(-errorcommand) [list unexpectedtext "unexpected  
text \"$t1\""]
-			}
-			if {![llength $state(condSections)]} {
-			    uplevel #0 $options(-errorcommand) \
-				[list illegalsection "extraneous conditional section close"]
-			}
-			set state(condSections) [lreplace $state(condSections) end end]
-			set text $t2
-		    }
-
-		}
-	    } elseif {[regexp {^!\[IGNORE\[(.*)} $decl discard remainder]} {
-		# Set ignore mode.  Still need a stack
-		set mode ignore
-
-		if {[regexp {(.*?)]]$} $remainder discard r2]} {
-		    # section closed immediately
-		    if {[string length [string trim $r2]]} {
-			uplevel #0 $options(-errorcommand) \
-			    [list unexpectedtext "unexpected text \"$r2\" in conditional  
section"]
-		    }
-		} elseif {[regexp {(.*?)]](.*)} $value discard r2 r3]} {
-		    # section closed immediately
-		    if {[string length [string trim $r2]]} {
-			uplevel #0 $options(-errorcommand) \
-			    [list unexpectedtext "unexpected text \"$r2\" in conditional  
section"]
-		    }
-		    if {[string length [string trim $r3]]} {
-			uplevel #0 $options(-errorcommand) \
-			    [list unexpectedtext "unexpected text \"$r3\" in conditional  
section"]
-		    }
-		} else {
-
-		    lappend state(condSections) IGNORE
-
-		    if {[regexp {(.*?)]]>(.*)} $text discard t1 t2]} {
-			if {[string length [string trim $t1]]} {
-			    uplevel #0 $options(-errorcommand) [list unexpectedtext "unexpected  
text \"$t1\""]
-			}
-			if {![llength $state(condSections)]} {
-			    uplevel #0 $options(-errorcommand) \
-				[list illegalsection "extraneous conditional section close"]
-			}
-			set state(condSections) [lreplace $state(condSections) end end]
-			set text $t2
-		    }
-
-		}
-	    } else {
-		uplevel #0 $options(-errorcommand) \
-		    [list illegaldeclaration "illegal markup declaration \"$decl\"  
around line $state(line)"]
-	    }
-
-	}
-
-	default {
-	    if {[regexp {^\?(.*)} $decl discard target]} {
-		# Processing instruction
-	    } else {
-		uplevel #0 $options(-errorcommand) [list illegaldeclaration "illegal  
markup declaration \"$decl\""]
-	    }
-	}
+        / {
+            # continuation from entity processing
+        }
+
+        !ELEMENT {
+            # Element declaration
+            if {[regexp $declExpr $value discard tag cmodel]} {
+                DTD:ELEMENT [array get options] $tag $cmodel
+            } else {
+                uplevel #0 $options(-errorcommand) \
+                    [list illegaldeclaration "malformed element  
declaration around line $state(line)"]
+            }
+        }
+
+        !ATTLIST {
+            # Attribute list declaration
+            variable declExpr
+            if {[regexp $declExpr $value discard tag attdefns]} {
+                if {[catch {DTD:ATTLIST [array get options] $tag  
$attdefns} err]} {
+                    #puts stderr "Stack trace: $::errorInfo\n***\n"
+                    # Atttribute parsing has bugs at the moment
+                    #return -code error "$err around line $state(line)"
+                    return {}
+                }
+            } else {
+                uplevel #0 $options(-errorcommand) \
+                    [list illegaldeclaration "malformed attribute list  
declaration around line $state(line)"]
+            }
+        }
+
+        !ENTITY {
+            # Entity declaration
+            variable EntityExpr
+
+            if {[regexp $EntityExpr $value discard param name value]} {
+
+                # Entity replacement text may have a '>' character.
+                # In this case, the real delimiter will be in the following
+                # text.  This is complicated by the possibility of there
+                # being several '<','>' pairs in the replacement text.
+                # At this point, we are searching for the matching quote  
delimiter.
+
+                if {[regexp $ExternalEntityExpr $value]} {
+                    DTD:ENTITY [array get options] $name [string trim  
$param] $value
+                } elseif {[regexp (\"|')(.*?)\\1(.*) $value discard  
delimiter replText value]} {
+
+                    if {[string length [string trim $value]]} {
+                        uplevel #0 $options(-errorcommand) \
+                            [list illegaldeclaration "malformed entity  
declaration around line $state(line)"]
+                    } else {
+                        DTD:ENTITY [array get options] $name [string trim  
$param] $delimiter$replText$delimiter
+                    }
+                } elseif {[regexp (\"|')(.*) $value discard delimiter  
replText]} {
+                    append replText >$text
+                    set text {}
+                    set mode entity
+                } else {
+                    uplevel #0 $options(-errorcommand) \
+                        [list illegaldeclaration "no delimiter for entity  
declaration around line $state(line)"]
+                }
+
+            } else {
+                uplevel #0 $options(-errorcommand) \
+                    [list illegaldeclaration "malformed entity declaration  
around line $state(line)"]
+            }
+        }
+
+        !NOTATION {
+            # Notation declaration
+            if {[regexp $declExpr param discard tag notation]} {
+                DTD:ENTITY [array get options] $tag $notation
+            } else {
+                uplevel #0 $options(-errorcommand) \
+                    [list illegaldeclaration "malformed entity declaration  
around line $state(line)"]
+            }
+        }
+
+        !--* {
+            # Start of a comment
+
+            if {[regexp !--(.*?)--\$ $decl discard data]} {
+                if {[string length [string trim $value]]} {
+                    uplevel #0 $options(-errorcommand) [list  
unexpectedtext "unexpected text \"$value\""]
+                }
+                uplevel #0 $options(-commentcommand) [list $data]
+                set decl /
+                set value {}
+            } elseif {[regexp -- ^(.*?)--\$ $value discard data2]} {
+                regexp !--(.*)\$ $decl discard data1
+                uplevel #0 $options(-commentcommand) [list $data1\ $data2]
+                set decl /
+                set value {}
+            } elseif {[regexp (.*?)-->(.*)\$ $text discard data3  
remainder]} {
+                regexp !--(.*)\$ $decl discard data1
+                uplevel #0 $options(-commentcommand) [list $data1\  
$value>$data3]
+                set decl /
+                set value {}
+                set text $remainder
+            } else {
+                regexp !--(.*)\$ $decl discard data1
+                set state(commentdata) $data1\ $value>$text
+                set decl /
+                set value {}
+                set text {}
+                set mode comment
+            }
+        }
+
+        !*INCLUDE* -
+        !*IGNORE* {
+            if {$state(inInternalDTD)} {
+                uplevel #0 $options(-errorcommand) \
+                    [list illegalsection "conditional section not  
permitted in internal DTD\
+                        subset around line $state(line)"]
+            }
+
+            if {[regexp {^!\[INCLUDE\[(.*)} $decl discard remainder]} {
+                # Push conditional section stack, popped by ]]> sequence
+
+                if {[regexp {(.*?)]]$} $remainder discard r2]} {
+                    # section closed immediately
+                    if {[string length [string trim $r2]]} {
+                        uplevel #0 $options(-errorcommand) \
+                            [list unexpectedtext "unexpected text \"$r2\"  
in conditional section"]
+                    }
+                } elseif {[regexp {(.*?)]](.*)} $value discard r2 r3]} {
+                    # section closed immediately
+                    if {[string length [string trim $r2]]} {
+                        uplevel #0 $options(-errorcommand) \
+                            [list unexpectedtext "unexpected text \"$r2\"  
in conditional section"]
+                    }
+                    if {[string length [string trim $r3]]} {
+                        uplevel #0 $options(-errorcommand) \
+                            [list "unexpected text \"$r3\" in conditional  
section"]
+                    }
+                } else {
+
+                    lappend state(condSections) INCLUDE
+
+                    set parser [$options(-name) entityparser]
+                    $parser parse $remainder\ $value> -dtdsubset external
+                    #$parser free
+
+                    if {[regexp {(.*?)]]>(.*)} $text discard t1 t2]} {
+                        if {[string length [string trim $t1]]} {
+                            uplevel #0 $options(-errorcommand) [list  
unexpectedtext "unexpected text \"$t1\""]
+                        }
+                        if {![llength $state(condSections)]} {
+                            uplevel #0 $options(-errorcommand) \
+                                [list illegalsection "extraneous  
conditional section close"]
+                        }
+                        set state(condSections) [lreplace  
$state(condSections) end end]
+                        set text $t2
+                    }
+
+                }
+            } elseif {[regexp {^!\[IGNORE\[(.*)} $decl discard remainder]}  
{
+                # Set ignore mode.  Still need a stack
+                set mode ignore
+
+                if {[regexp {(.*?)]]$} $remainder discard r2]} {
+                    # section closed immediately
+                    if {[string length [string trim $r2]]} {
+                        uplevel #0 $options(-errorcommand) \
+                            [list unexpectedtext "unexpected text \"$r2\"  
in conditional section"]
+                    }
+                } elseif {[regexp {(.*?)]](.*)} $value discard r2 r3]} {
+                    # section closed immediately
+                    if {[string length [string trim $r2]]} {
+                        uplevel #0 $options(-errorcommand) \
+                            [list unexpectedtext "unexpected text \"$r2\"  
in conditional section"]
+                    }
+                    if {[string length [string trim $r3]]} {
+                        uplevel #0 $options(-errorcommand) \
+                            [list unexpectedtext "unexpected text \"$r3\"  
in conditional section"]
+                    }
+                } else {
+
+                    lappend state(condSections) IGNORE
+
+                    if {[regexp {(.*?)]]>(.*)} $text discard t1 t2]} {
+                        if {[string length [string trim $t1]]} {
+                            uplevel #0 $options(-errorcommand) [list  
unexpectedtext "unexpected text \"$t1\""]
+                        }
+                        if {![llength $state(condSections)]} {
+                            uplevel #0 $options(-errorcommand) \
+                                [list illegalsection "extraneous  
conditional section close"]
+                        }
+                        set state(condSections) [lreplace  
$state(condSections) end end]
+                        set text $t2
+                    }
+
+                }
+            } else {
+                uplevel #0 $options(-errorcommand) \
+                    [list illegaldeclaration "illegal markup declaration  
\"$decl\" around line $state(line)"]
+            }
+
+        }
+
+        default {
+            if {[regexp {^\?(.*)} $decl discard target]} {
+                # Processing instruction
+            } else {
+                uplevel #0 $options(-errorcommand) [list  
illegaldeclaration "illegal markup declaration \"$decl\""]
+            }
+        }
      }

      return {}
@@ -1746,16 +1746,16 @@

  # sgml::ParseDTD:External --
  #
-#	Parse the external DTD subset.
+#       Parse the external DTD subset.
  #
-#	Parameter entities are allowed anywhere.
+#       Parameter entities are allowed anywhere.
  #
  # Arguments:
-#	opts	configuration options
-#	dtd	DTD data
+#       opts        configuration options
+#       dtd         DTD data
  #
  # Results:
-#	Markup declarations parsed may cause callback invocation
+#       Markup declarations parsed may cause callback invocation

  proc sgml::ParseDTD:External {opts dtd} {
      variable MarkupDeclExpr
@@ -1780,156 +1780,156 @@

      # Initialise conditional section stack
      if {![info exists state(condSections)]} {
-	set state(condSections) {}
+        set state(condSections) {}
      }
      set startCondSectionDepth [llength $state(condSections)]

      while {[string length $dtd]} {
-	set progress 0
-	set PEref {}
-	if {![string compare $mode "ignore"]} {
-	    set progress 1
-	    if {[regexp {]]>(.*)} $dtd discard dtd]} {
-		set remainder {}
-		set mode {} ;# normal
-		set state(condSections) [lreplace $state(condSections) end end]
-		continue
-	    } else {
-		uplevel #0 $options(-errorcommand) \
-		    [list missingdelimiter "IGNORE conditional section closing delimiter  
not found"]
-	    }
-	} elseif {[regexp ^(.*?)%($::sgml::Name)\;(.*)\$ $dtd discard data PEref  
remainder]} {
-	    set progress 1
-	} else {
-	    set data $dtd
-	    set dtd {}
-	    set remainder {}
-	}
-
-	# Tokenize the DTD (so far)
-
-	# Protect Tcl special characters
-	regsub -all {([{}\\])} $data {\\\1} dataP
-
-	set n [regsub -all $MarkupDeclExpr $dataP $MarkupDeclSub dataP]
-
-	if {$n} {
-	    set progress 1
-	    # All but the last markup declaration should have no text
-	    set dataP [lrange "{} {} \{$dataP\}" 3 end]
-	    if {[llength $dataP] > 3} {
-		foreach {decl value text} [lrange $dataP 0 [expr [llength $dataP] - 4]] {
-		    ParseDTD:EntityMode [array get options] mode replText decl value  
text $delimiter $name $param
-		    ParseDTD:ProcessMarkupDecl [array get options] decl value delimiter  
name mode repltextVar text param
-
-		    if {[string length [string trim $text]]} {
-			# check for conditional section close
-			if {[regexp {]]>(.*)$} $text discard text]} {
-			    if {[string length [string trim $text]]} {
-				uplevel #0 $options(-errorcommand) \
-				    [list unexpectedtext "unexpected text \"$text\""]
-			    }
-			    if {![llength $state(condSections)]} {
-				uplevel #0 $options(-errorcommand) \
-				    [list illegalsection "extraneous conditional section close"]
-			    }
-			    set state(condSections) [lreplace $state(condSections) end end]
-			    if {![string compare $mode "ignore"]} {
-				set mode {} ;# normal
-			    }
-			} else {
-			    uplevel #0 $options(-errorcommand) \
-				[list unexpectedtext "unexpected text \"$text\""]
-			}
-		    }
-		}
-	    }
-	    # Do the last declaration
-	    foreach {decl value text} [lrange $dataP [expr [llength $dataP] - 3]  
end] {
-		ParseDTD:EntityMode [array get options] mode replText decl value text  
$delimiter $name $param
-		ParseDTD:ProcessMarkupDecl [array get options] decl value delimiter name  
mode repltextVar text param
-	    }
-	}
-
-	# Now expand the PE reference, if any
-	switch -glob -- $mode,[string length $PEref],$n {
-	    ignore,0,* {
-		set dtd $text
-	    }
-	    ignore,*,* {
-		set dtd $text$remainder
-	    }
-	    *,0,0 {
-		set dtd $data
-	    }
-	    *,0,* {
-		set dtd $text
-	    }
-	    *,*,0 {
-		if {[catch {append data $PEnts($PEref)}]} {
-		    if {[info exists ExtPEnts($PEref)]} {
-			set externalParser [$options(-name) entityparser]
-			$externalParser parse $ExtPEnts($PEref) -dtdsubset external
-			#$externalParser free
-		    } else {
-			uplevel #0 $options(-errorcommand) \
-			    [list entityundeclared "parameter entity \"$PEref\" not declared"]
-		    }
-		}
-		set dtd $data$remainder
-	    }
-	    default {
-		if {[catch {append text $PEnts($PEref)}]} {
-		    if {[info exists ExtPEnts($PEref)]} {
-			set externalParser [$options(-name) entityparser]
-			$externalParser parse $ExtPEnts($PEref) -dtdsubset external
-			#$externalParser free
-		    } else {
-			uplevel #0 $options(-errorcommand) \
-			    [list entityundeclared "parameter entity \"$PEref\" not declared"]
-		    }
-		}
-		set dtd $text$remainder
-	    }
-	}
-
-	# Check whether a conditional section has been terminated
-	if {[regexp {^(.*?)]]>(.*)$} $dtd discard t1 t2]} {
-	    if {![regexp <.*> $t1]} {
-		if {[string length [string trim $t1]]} {
-		    uplevel #0 $options(-errorcommand) [list unexpectedtext "unexpected  
text \"$t1\""]
-		}
-		if {![llength $state(condSections)]} {
-		    uplevel #0 $options(-errorcommand) [list illegalsection "extraneous  
conditional section close"]
-		}
-		set state(condSections) [lreplace $state(condSections) end end]
-		if {![string compare $mode "ignore"]} {
-		    set mode {} ;# normal
-		}
-		set dtd $t2
-		set progress 1
-	    }
-	}
-
-	if {!$progress} {
-	    # No parameter entity references were found and
-	    # the text does not contain a well-formed markup declaration
-	    # Avoid going into an infinite loop
-	    upvar #0 $options(-errorcommand) \
-		[list syntaxerror "external entity does not contain well-formed markup  
declaration"]
-	    break
-	}
+        set progress 0
+        set PEref {}
+        if {![string compare $mode "ignore"]} {
+            set progress 1
+            if {[regexp {]]>(.*)} $dtd discard dtd]} {
+                set remainder {}
+                set mode {} ;# normal
+                set state(condSections) [lreplace $state(condSections) end  
end]
+                continue
+            } else {
+                uplevel #0 $options(-errorcommand) \
+                    [list missingdelimiter "IGNORE conditional section  
closing delimiter not found"]
+            }
+        } elseif {[regexp ^(.*?)%($::sgml::Name)\;(.*)\$ $dtd discard data  
PEref remainder]} {
+            set progress 1
+        } else {
+            set data $dtd
+            set dtd {}
+            set remainder {}
+        }
+
+        # Tokenize the DTD (so far)
+
+        # Protect Tcl special characters
+        regsub -all {([{}\\])} $data {\\\1} dataP
+
+        set n [regsub -all $MarkupDeclExpr $dataP $MarkupDeclSub dataP]
+
+        if {$n} {
+            set progress 1
+            # All but the last markup declaration should have no text
+            set dataP [lrange "{} {} \{$dataP\}" 3 end]
+            if {[llength $dataP] > 3} {
+                foreach {decl value text} [lrange $dataP 0 [expr [llength  
$dataP] - 4]] {
+                    ParseDTD:EntityMode [array get options] mode replText  
decl value text $delimiter $name $param
+                    ParseDTD:ProcessMarkupDecl [array get options] decl  
value delimiter name mode repltextVar text param
+
+                    if {[string length [string trim $text]]} {
+                        # check for conditional section close
+                        if {[regexp {]]>(.*)$} $text discard text]} {
+                            if {[string length [string trim $text]]} {
+                                uplevel #0 $options(-errorcommand) \
+                                    [list unexpectedtext "unexpected text  
\"$text\""]
+                            }
+                            if {![llength $state(condSections)]} {
+                                uplevel #0 $options(-errorcommand) \
+                                    [list illegalsection "extraneous  
conditional section close"]
+                            }
+                            set state(condSections) [lreplace  
$state(condSections) end end]
+                            if {![string compare $mode "ignore"]} {
+                                set mode {} ;# normal
+                            }
+                        } else {
+                            uplevel #0 $options(-errorcommand) \
+                                [list unexpectedtext "unexpected text  
\"$text\""]
+                        }
+                    }
+                }
+            }
+            # Do the last declaration
+            foreach {decl value text} [lrange $dataP [expr [llength  
$dataP] - 3] end] {
+                ParseDTD:EntityMode [array get options] mode replText decl  
value text $delimiter $name $param
+                ParseDTD:ProcessMarkupDecl [array get options] decl value  
delimiter name mode repltextVar text param
+            }
+        }
+
+        # Now expand the PE reference, if any
+        switch -glob -- $mode,[string length $PEref],$n {
+            ignore,0,* {
+                set dtd $text
+            }
+            ignore,*,* {
+                set dtd $text$remainder
+            }
+            *,0,0 {
+                set dtd $data
+            }
+            *,0,* {
+                set dtd $text
+            }
+            *,*,0 {
+                if {[catch {append data $PEnts($PEref)}]} {
+                    if {[info exists ExtPEnts($PEref)]} {
+                        set externalParser [$options(-name) entityparser]
+                        $externalParser parse $ExtPEnts($PEref) -dtdsubset  
external
+                        #$externalParser free
+                    } else {
+                        uplevel #0 $options(-errorcommand) \
+                            [list entityundeclared "parameter entity  
\"$PEref\" not declared"]
+                    }
+                }
+                set dtd $data$remainder
+            }
+            default {
+                if {[catch {append text $PEnts($PEref)}]} {
+                    if {[info exists ExtPEnts($PEref)]} {
+                        set externalParser [$options(-name) entityparser]
+                        $externalParser parse $ExtPEnts($PEref) -dtdsubset  
external
+                        #$externalParser free
+                    } else {
+                        uplevel #0 $options(-errorcommand) \
+                            [list entityundeclared "parameter entity  
\"$PEref\" not declared"]
+                    }
+                }
+                set dtd $text$remainder
+            }
+        }
+
+        # Check whether a conditional section has been terminated
+        if {[regexp {^(.*?)]]>(.*)$} $dtd discard t1 t2]} {
+            if {![regexp <.*> $t1]} {
+                if {[string length [string trim $t1]]} {
+                    uplevel #0 $options(-errorcommand) [list  
unexpectedtext "unexpected text \"$t1\""]
+                }
+                if {![llength $state(condSections)]} {
+                    uplevel #0 $options(-errorcommand) [list  
illegalsection "extraneous conditional section close"]
+                }
+                set state(condSections) [lreplace $state(condSections) end  
end]
+                if {![string compare $mode "ignore"]} {
+                    set mode {} ;# normal
+                }
+                set dtd $t2
+                set progress 1
+            }
+        }
+
+        if {!$progress} {
+            # No parameter entity references were found and
+            # the text does not contain a well-formed markup declaration
+            # Avoid going into an infinite loop
+            upvar #0 $options(-errorcommand) \
+                [list syntaxerror "external entity does not contain  
well-formed markup declaration"]
+            break
+        }
      }

      set state(inInternalDTD) $oldState

      # Check that conditional sections have been closed properly
      if {[llength $state(condSections)] > $startCondSectionDepth} {
-	uplevel #0 $options(-errorcommand) \
-	    [list syntaxerror "[lindex $state(condSections) end] conditional  
section not closed"]
+        uplevel #0 $options(-errorcommand) \
+            [list syntaxerror "[lindex $state(condSections) end]  
conditional section not closed"]
      }
      if {[llength $state(condSections)] < $startCondSectionDepth} {
-	uplevel #0 $options(-errorcommand) [list syntaxerror "too many  
conditional section closures"]
+        uplevel #0 $options(-errorcommand) [list syntaxerror "too many  
conditional section closures"]
      }

      return {}
@@ -1944,28 +1944,28 @@

  # sgml::DTD:ELEMENT --
  #
-#	<!ELEMENT ...> defines an element.
+#       <!ELEMENT ...> defines an element.
  #
-#	The content model for the element is stored in the contentmodel array,
-#	indexed by the element name.  The content model is parsed into the
-#	following list form:
-#
-#		{}	Content model is EMPTY.
-#			Indicated by an empty list.
-#		*	Content model is ANY.
-#			Indicated by an asterix.
-#		{ELEMENT ...}
-#			Content model is element-only.
-#		{MIXED {element1 element2 ...}}
-#			Content model is mixed (PCDATA and elements).
-#			The second element of the list contains the
-#			elements that may occur.  #PCDATA is assumed
-#			(ie. the list is normalised).
-#
-# Arguments:
-#	opts	configuration options
-#	name	element GI
-#	modspec	unparsed content model specification
+#       The content model for the element is stored in the contentmodel  
array,
+#       indexed by the element name.  The content model is parsed into the
+#       following list form:
+#
+#               {}        Content model is EMPTY.
+#                       Indicated by an empty list.
+#               *        Content model is ANY.
+#                       Indicated by an asterix.
+#               {ELEMENT ...}
+#                       Content model is element-only.
+#               {MIXED {element1 element2 ...}}
+#                       Content model is mixed (PCDATA and elements).
+#                       The second element of the list contains the
+#                       elements that may occur.  #PCDATA is assumed
+#                       (ie. the list is normalised).
+#
+# Arguments:
+#       opts        configuration options
+#       name        element GI
+#       modspec     unparsed content model specification

  proc sgml::DTD:ELEMENT {opts name modspec} {
      variable Wsp
@@ -1974,52 +1974,52 @@
      upvar #0 $options(elementdecls) elements

      if {$options(-validate) && [info exists elements($name)]} {
-	eval $options(-errorcommand) elementdeclared [list "element \"$name\"  
already declared"]
+        eval $options(-errorcommand) elementdeclared [list "element  
\"$name\" already declared"]
      } else {
-	switch -- $modspec {
-	    EMPTY {
-	    	set elements($name) {}
-		uplevel #0 $options(-elementdeclcommand) $name {{}}
-	    }
-	    ANY {
-	    	set elements($name) *
-		uplevel #0 $options(-elementdeclcommand) $name *
-	    }
-	    default {
-		# Don't parse the content model for now,
-		# just pass the model to the application
-		if {0 && [regexp [format {^\([%s]*#PCDATA[%s]*(\| 
([^)]+))?[%s]*\)*[%s]*$} $Wsp $Wsp $Wsp $Wsp] \
-				discard discard mtoks]} {
-		    set cm($name) [list MIXED [split $mtoks |]]
-		} elseif {0} {
-		    if {[catch {CModelParse $state(state) $value} result]} {
-			eval $options(-errorcommand) element [list $result]
-		    } else {
-			set cm($id) [list ELEMENT $result]
-		    }
-		} else {
-		    set elements($name) $modspec
-		    uplevel #0 $options(-elementdeclcommand) $name [list $modspec]
-		}
-	    }
-	}
+        switch -- $modspec {
+            EMPTY {
+                    set elements($name) {}
+                uplevel #0 $options(-elementdeclcommand) $name {{}}
+            }
+            ANY {
+                    set elements($name) *
+                uplevel #0 $options(-elementdeclcommand) $name *
+            }
+            default {
+                # Don't parse the content model for now,
+                # just pass the model to the application
+                if {0 && [regexp [format {^\([%s]*#PCDATA[%s]*(\| 
([^)]+))?[%s]*\)*[%s]*$} $Wsp $Wsp $Wsp $Wsp] \
+                                discard discard mtoks]} {
+                    set cm($name) [list MIXED [split $mtoks |]]
+                } elseif {0} {
+                    if {[catch {CModelParse $state(state) $value} result]}  
{
+                        eval $options(-errorcommand) element [list $result]
+                    } else {
+                        set cm($id) [list ELEMENT $result]
+                    }
+                } else {
+                    set elements($name) $modspec
+                    uplevel #0 $options(-elementdeclcommand) $name [list  
$modspec]
+                }
+            }
+        }
      }
  }

  # sgml::CModelParse --
  #
-#	Parse an element content model (non-mixed).
-#	A syntax tree is constructed.
-#	A transition table is built next.
+#       Parse an element content model (non-mixed).
+#       A syntax tree is constructed.
+#       A transition table is built next.
  #
-#	This is going to need alot of work!
+#       This is going to need alot of work!
  #
  # Arguments:
-#	state	state array variable
-#	value	the content model data
+#       state       state array variable
+#       value       the content model data
  #
  # Results:
-#	A Tcl list representing the content model.
+#       A Tcl list representing the content model.

  proc sgml::CModelParse {state value} {
      upvar #0 $state var
@@ -2035,28 +2035,28 @@

  # sgml::CModelMakeSyntaxTree --
  #
-#	Construct a syntax tree for the regular expression.
+#       Construct a syntax tree for the regular expression.
  #
-#	Syntax tree is represented as a Tcl list:
-#	rep {:choice|:seq {{rep list1} {rep list2} ...}}
-#	where:	rep is repetition character, *, + or ?. {} for no repetition
-#		listN is nested expression or Name
+#       Syntax tree is represented as a Tcl list:
+#       rep {:choice|:seq {{rep list1} {rep list2} ...}}
+#       where:      rep is repetition character, *, + or ?. {} for no  
repetition
+#                   listN is nested expression or Name
  #
  # Arguments:
-#	spec	Element specification
+#       spec        Element specification
  #
  # Results:
-#	Syntax tree for element spec as nested Tcl list.
+#       Syntax tree for element spec as nested Tcl list.
  #
-#	Examples:
-#	(memo)
-#		{} {:seq {{} memo}}
-#	(front, body, back?)
-#		{} {:seq {{} front} {{} body} {? back}}
-#	(head, (p | list | note)*, div2*)
-#		{} {:seq {{} head} {* {:choice {{} p} {{} list} {{} note}}} {* div2}}
-#	(p | a | ul)+
-#		+ {:choice {{} p} {{} a} {{} ul}}
+#       Examples:
+#       (memo)
+#               {} {:seq {{} memo}}
+#       (front, body, back?)
+#               {} {:seq {{} front} {{} body} {? back}}
+#       (head, (p | list | note)*, div2*)
+#               {} {:seq {{} head} {* {:choice {{} p} {{} list} {{}  
note}}} {* div2}}
+#       (p | a | ul)+
+#               + {:choice {{} p} {{} a} {{} ul}}

  proc sgml::CModelMakeSyntaxTree {state spec} {
      upvar #0 $state var
@@ -2067,14 +2067,14 @@

      # None of the Tcl special characters are allowed in a content model  
spec.
      if {[regexp {\$|\[|\]|\{|\}} $spec]} {
-	return -code error "illegal characters in specification"
+        return -code error "illegal characters in specification"
      }

      regsub -all [format {(%s)[%s]*(\?|\*|\+)?[%s]*(,|\|)?} $name $Wsp  
$Wsp] $spec \
-	[format {%sCModelSTname %s {\1} {\2} {\3}} \n $state] spec
+        [format {%sCModelSTname %s {\1} {\2} {\3}} \n $state] spec
      regsub -all {\(} $spec "\nCModelSTopenParen $state " spec
      regsub -all [format {\)[%s]*(\?|\*|\+)?[%s]*(,|\|)?} $Wsp $Wsp] $spec \
-	[format {%sCModelSTcloseParen %s {\1} {\2}} \n $state] spec
+        [format {%sCModelSTcloseParen %s {\1} {\2}} \n $state] spec

      array set var {stack {} state start}
      eval $spec
@@ -2085,20 +2085,20 @@

  # sgml::CModelSTname --
  #
-#	Processes a name in a content model spec.
+#       Processes a name in a content model spec.
  #
  # Arguments:
-#	state	state array variable
-#	name	name specified
-#	rep	repetition operator
-#	cs	choice or sequence delimiter
+#       state       state array variable
+#       name        name specified
+#       rep         repetition operator
+#       cs          choice or sequence delimiter
  #
  # Results:
-#	See CModelSTcp.
+#       See CModelSTcp.

  proc sgml::CModelSTname {state name rep cs args} {
      if {[llength $args]} {
-	return -code error "syntax error in specification: \"$args\""
+        return -code error "syntax error in specification: \"$args\""
      }

      CModelSTcp $state $name $rep $cs
@@ -2106,68 +2106,68 @@

  # sgml::CModelSTcp --
  #
-#	Process a content particle.
+#       Process a content particle.
  #
  # Arguments:
-#	state	state array variable
-#	name	name specified
-#	rep	repetition operator
-#	cs	choice or sequence delimiter
+#       state       state array variable
+#       name        name specified
+#       rep         repetition operator
+#       cs          choice or sequence delimiter
  #
  # Results:
-#	The content particle is added to the current group.
+#       The content particle is added to the current group.

  proc sgml::CModelSTcp {state cp rep cs} {
      upvar #0 $state var

      switch -glob -- [lindex $var(state) end]=$cs {
-	start= {
-	    set var(state) [lreplace $var(state) end end end]
-	    # Add (dummy) grouping, either choice or sequence will do
-	    CModelSTcsSet $state ,
-	    CModelSTcpAdd $state $cp $rep
-	}
-	:choice= -
-	:seq= {
-	    set var(state) [lreplace $var(state) end end end]
-	    CModelSTcpAdd $state $cp $rep
-	}
-	start=| -
-	start=, {
-	    set var(state) [lreplace $var(state) end end [expr {$cs  
== "," ? ":seq" : ":choice"}]]
-	    CModelSTcsSet $state $cs
-	    CModelSTcpAdd $state $cp $rep
-	}
-	:choice=| -
-	:seq=, {
-	    CModelSTcpAdd $state $cp $rep
-	}
-	:choice=, -
-	:seq=| {
-	    return -code error \
-		"syntax error in specification: incorrect delimiter\
-		 after \"$cp\", should be \"[expr {$cs == "," ? "|" : ","}]\""
-	}
-	end=* {
-	    return -code error "syntax error in specification: no delimiter  
before \"$cp\""
-	}
-	default {
-	    return -code error "syntax error"
-	}
+        start= {
+            set var(state) [lreplace $var(state) end end end]
+            # Add (dummy) grouping, either choice or sequence will do
+            CModelSTcsSet $state ,
+            CModelSTcpAdd $state $cp $rep
+        }
+        :choice= -
+        :seq= {
+            set var(state) [lreplace $var(state) end end end]
+            CModelSTcpAdd $state $cp $rep
+        }
+        start=| -
+        start=, {
+            set var(state) [lreplace $var(state) end end [expr {$cs  
== "," ? ":seq" : ":choice"}]]
+            CModelSTcsSet $state $cs
+            CModelSTcpAdd $state $cp $rep
+        }
+        :choice=| -
+        :seq=, {
+            CModelSTcpAdd $state $cp $rep
+        }
+        :choice=, -
+        :seq=| {
+            return -code error \
+                "syntax error in specification: incorrect delimiter\
+                 after \"$cp\", should be \"[expr {$cs  
== "," ? "|" : ","}]\""
+        }
+        end=* {
+            return -code error "syntax error in specification: no  
delimiter before \"$cp\""
+        }
+        default {
+            return -code error "syntax error"
+        }
      }

  }

  # sgml::CModelSTcsSet --
  #
-#	Start a choice or sequence on the stack.
+#       Start a choice or sequence on the stack.
  #
  # Arguments:
-#	state	state array
-#	cs	choice oir sequence
+#       state       state array
+#       cs          choice oir sequence
  #
  # Results:
-#	state is modified: end element of state is appended.
+#       state is modified: end element of state is appended.

  proc sgml::CModelSTcsSet {state cs} {
      upvar #0 $state var
@@ -2175,51 +2175,51 @@
      set cs [expr {$cs == "," ? ":seq" : ":choice"}]

      if {[llength $var(stack)]} {
-	set var(stack) [lreplace $var(stack) end end $cs]
+        set var(stack) [lreplace $var(stack) end end $cs]
      } else {
-	set var(stack) [list $cs {}]
+        set var(stack) [list $cs {}]
      }
  }

  # sgml::CModelSTcpAdd --
  #
-#	Append a content particle to the top of the stack.
+#       Append a content particle to the top of the stack.
  #
  # Arguments:
-#	state	state array
-#	cp	content particle
-#	rep	repetition
+#       state       state array
+#       cp          content particle
+#       rep         repetition
  #
  # Results:
-#	state is modified: end element of state is appended.
+#       state is modified: end element of state is appended.

  proc sgml::CModelSTcpAdd {state cp rep} {
      upvar #0 $state var

      if {[llength $var(stack)]} {
-	set top [lindex $var(stack) end]
-    	lappend top [list $rep $cp]
-	set var(stack) [lreplace $var(stack) end end $top]
+        set top [lindex $var(stack) end]
+            lappend top [list $rep $cp]
+        set var(stack) [lreplace $var(stack) end end $top]
      } else {
-	set var(stack) [list $rep $cp]
+        set var(stack) [list $rep $cp]
      }
  }

  # sgml::CModelSTopenParen --
  #
-#	Processes a '(' in a content model spec.
+#       Processes a '(' in a content model spec.
  #
  # Arguments:
-#	state	state array
+#       state       state array
  #
  # Results:
-#	Pushes stack in state array.
+#       Pushes stack in state array.

  proc sgml::CModelSTopenParen {state args} {
      upvar #0 $state var

      if {[llength $args]} {
-	return -code error "syntax error in specification: \"$args\""
+        return -code error "syntax error in specification: \"$args\""
      }

      lappend var(state) start
@@ -2228,21 +2228,21 @@

  # sgml::CModelSTcloseParen --
  #
-#	Processes a ')' in a content model spec.
+#       Processes a ')' in a content model spec.
  #
  # Arguments:
-#	state	state array
-#	rep	repetition
-#	cs	choice or sequence delimiter
+#       state       state array
+#       rep         repetition
+#       cs          choice or sequence delimiter
  #
  # Results:
-#	Stack is popped, and former top of stack is appended to previous element.
+#       Stack is popped, and former top of stack is appended to previous  
element.

  proc sgml::CModelSTcloseParen {state rep cs args} {
      upvar #0 $state var

      if {[llength $args]} {
-	return -code error "syntax error in specification: \"$args\""
+        return -code error "syntax error in specification: \"$args\""
      }

      set cp [lindex $var(stack) end]
@@ -2253,41 +2253,41 @@

  # sgml::CModelMakeTransitionTable --
  #
-#	Given a content model's syntax tree, constructs
-#	the transition table for the regular expression.
+#       Given a content model's syntax tree, constructs
+#       the transition table for the regular expression.
  #
-#	See "Compilers, Principles, Techniques, and Tools",
-#	Aho, Sethi and Ullman.  Section 3.9, algorithm 3.5.
+#       See "Compilers, Principles, Techniques, and Tools",
+#       Aho, Sethi and Ullman.  Section 3.9, algorithm 3.5.
  #
  # Arguments:
-#	state	state array variable
-#	st	syntax tree
+#       state       state array variable
+#       st          syntax tree
  #
  # Results:
-#	The transition table is returned, as a key/value Tcl list.
+#       The transition table is returned, as a key/value Tcl list.

  proc sgml::CModelMakeTransitionTable {state st} {
      upvar #0 $state var

      # Construct nullable, firstpos and lastpos functions
      array set var {number 0}
-    foreach {nullable firstpos lastpos} [	\
-	TraverseDepth1st $state $st {
-	    # Evaluated for leaf nodes
-	    # Compute nullable(n)
-	    # Compute firstpos(n)
-	    # Compute lastpos(n)
-	    set nullable [nullable leaf $rep $name]
-	    set firstpos [list {} $var(number)]
-	    set lastpos [list {} $var(number)]
-	    set var(pos:$var(number)) $name
-	} {
-	    # Evaluated for nonterminal nodes
-	    # Compute nullable, firstpos, lastpos
-	    set firstpos [firstpos $cs $firstpos $nullable]
-	    set lastpos  [lastpos  $cs $lastpos  $nullable]
-	    set nullable [nullable nonterm $rep $cs $nullable]
-	}	\
+    foreach {nullable firstpos lastpos} [        \
+        TraverseDepth1st $state $st {
+            # Evaluated for leaf nodes
+            # Compute nullable(n)
+            # Compute firstpos(n)
+            # Compute lastpos(n)
+            set nullable [nullable leaf $rep $name]
+            set firstpos [list {} $var(number)]
+            set lastpos [list {} $var(number)]
+            set var(pos:$var(number)) $name
+        } {
+            # Evaluated for nonterminal nodes
+            # Compute nullable, firstpos, lastpos
+            set firstpos [firstpos $cs $firstpos $nullable]
+            set lastpos  [lastpos  $cs $lastpos  $nullable]
+            set nullable [nullable nonterm $rep $cs $nullable]
+        }        \
      ] break

      set accepting [incr var(number)]
@@ -2299,9 +2299,9 @@
      # var is about to be reset, so use different arrays.

      foreach {pos symbol} [array get var pos:*] {
-	set pos [lindex [split $pos :] 1]
-	set pos2symbol($pos) $symbol
-	lappend sym2pos($symbol) $pos
+        set pos [lindex [split $pos :] 1]
+        set pos2symbol($pos) $symbol
+        lappend sym2pos($symbol) $pos
      }

      # Construct the followpos functions
@@ -2312,35 +2312,35 @@
      # Dstates is [union $marked $unmarked]
      set unmarked [list [lindex $firstpos 1]]
      while {[llength $unmarked]} {
-	set T [lindex $unmarked 0]
-	lappend marked $T
-	set unmarked [lrange $unmarked 1 end]
-
-	# Find which input symbols occur in T
-	set symbols {}
-	foreach pos $T {
-	    if {$pos != $accepting && [lsearch $symbols $pos2symbol($pos)] < 0} {
-		lappend symbols $pos2symbol($pos)
-	    }
-	}
-	foreach a $symbols {
-	    set U {}
-	    foreach pos $sym2pos($a) {
-		if {[lsearch $T $pos] >= 0} {
-		    # add followpos($pos)
-	    	    if {$var($pos) == {}} {
-	    	    	lappend U $accepting
-	    	    } else {
-	    	    	eval lappend U $var($pos)
-	    	    }
-		}
-	    }
-	    set U [makeSet $U]
-	    if {[llength $U] && [lsearch $marked $U] < 0 && [lsearch $unmarked  
$U] < 0} {
-		lappend unmarked $U
-	    }
-	    set Dtran($T,$a) $U
-	}
+        set T [lindex $unmarked 0]
+        lappend marked $T
+        set unmarked [lrange $unmarked 1 end]
+
+        # Find which input symbols occur in T
+        set symbols {}
+        foreach pos $T {
+            if {$pos != $accepting && [lsearch $symbols $pos2symbol($pos)]  
< 0} {
+                lappend symbols $pos2symbol($pos)
+            }
+        }
+        foreach a $symbols {
+            set U {}
+            foreach pos $sym2pos($a) {
+                if {[lsearch $T $pos] >= 0} {
+                    # add followpos($pos)
+                        if {$var($pos) == {}} {
+                                lappend U $accepting
+                        } else {
+                                eval lappend U $var($pos)
+                        }
+                }
+            }
+            set U [makeSet $U]
+            if {[llength $U] && [lsearch $marked $U] < 0 && [lsearch  
$unmarked $U] < 0} {
+                lappend unmarked $U
+            }
+            set Dtran($T,$a) $U
+        }

      }

@@ -2349,73 +2349,73 @@

  # sgml::followpos --
  #
-#	Compute the followpos function, using the already computed
-#	firstpos and lastpos.
+#       Compute the followpos function, using the already computed
+#       firstpos and lastpos.
  #
  # Arguments:
-#	state		array variable to store followpos functions
-#	st		syntax tree
-#	firstpos	firstpos functions for the syntax tree
-#	lastpos		lastpos functions
+#       state       array variable to store followpos functions
+#       st          syntax tree
+#       firstpos    firstpos functions for the syntax tree
+#       lastpos     lastpos functions
  #
  # Results:
-#	followpos functions for each leaf node, in name/value format
+#       followpos functions for each leaf node, in name/value format

  proc sgml::followpos {state st firstpos lastpos} {
      upvar #0 $state var

      switch -- [lindex [lindex $st 1] 0] {
-	:seq {
-	    for {set i 1} {$i < [llength [lindex $st 1]]} {incr i} {
-	    	followpos $state [lindex [lindex $st 1] $i]			\
-			[lindex [lindex $firstpos 0] [expr $i - 1]]	\
-			[lindex [lindex $lastpos 0] [expr $i - 1]]
-	    	foreach pos [lindex [lindex [lindex $lastpos 0] [expr $i - 1]] 1] {
-		    eval lappend var($pos) [lindex [lindex [lindex $firstpos 0] $i] 1]
-		    set var($pos) [makeSet $var($pos)]
-	    	}
-	    }
-	}
-	:choice {
-	    for {set i 1} {$i < [llength [lindex $st 1]]} {incr i} {
-		followpos $state [lindex [lindex $st 1] $i]			\
-			[lindex [lindex $firstpos 0] [expr $i - 1]]	\
-			[lindex [lindex $lastpos 0] [expr $i - 1]]
-	    }
-	}
-	default {
-	    # No action at leaf nodes
-	}
+        :seq {
+            for {set i 1} {$i < [llength [lindex $st 1]]} {incr i} {
+                    followpos $state [lindex [lindex $st 1]  
$i]                        \
+                        [lindex [lindex $firstpos 0] [expr $i - 1]]         
\
+                        [lindex [lindex $lastpos 0] [expr $i - 1]]
+                    foreach pos [lindex [lindex [lindex $lastpos 0] [expr  
$i - 1]] 1] {
+                    eval lappend var($pos) [lindex [lindex [lindex  
$firstpos 0] $i] 1]
+                    set var($pos) [makeSet $var($pos)]
+                    }
+            }
+        }
+        :choice {
+            for {set i 1} {$i < [llength [lindex $st 1]]} {incr i} {
+                followpos $state [lindex [lindex $st 1]  
$i]                        \
+                        [lindex [lindex $firstpos 0] [expr $i - 1]]         
\
+                        [lindex [lindex $lastpos 0] [expr $i - 1]]
+            }
+        }
+        default {
+            # No action at leaf nodes
+        }
      }

      switch -- [lindex $st 0] {
-	? {
-	    # We having nothing to do here ! Doing the same as
-	    # for * effectively converts this qualifier into the other.
-	}
-	* {
-	    foreach pos [lindex $lastpos 1] {
-		eval lappend var($pos) [lindex $firstpos 1]
-		set var($pos) [makeSet $var($pos)]
-	    }
-	}
+        ? {
+            # We having nothing to do here ! Doing the same as
+            # for * effectively converts this qualifier into the other.
+        }
+        * {
+            foreach pos [lindex $lastpos 1] {
+                eval lappend var($pos) [lindex $firstpos 1]
+                set var($pos) [makeSet $var($pos)]
+            }
+        }
      }

  }

  # sgml::TraverseDepth1st --
  #
-#	Perform depth-first traversal of a tree.
-#	A new tree is constructed, with each node computed by f.
+#       Perform depth-first traversal of a tree.
+#       A new tree is constructed, with each node computed by f.
  #
  # Arguments:
-#	state	state array variable
-#	t	The tree to traverse, a Tcl list
-#	leaf	Evaluated at a leaf node
-#	nonTerm	Evaluated at a nonterminal node
+#       state       state array variable
+#       t           The tree to traverse, a Tcl list
+#       leaf        Evaluated at a leaf node
+#       nonTerm     Evaluated at a nonterminal node
  #
  # Results:
-#	A new tree is returned.
+#       A new tree is returned.

  proc sgml::TraverseDepth1st {state t leaf nonTerm} {
      upvar #0 $state var
@@ -2425,27 +2425,27 @@
      set lastpos {}

      switch -- [lindex [lindex $t 1] 0] {
-	:seq -
-	:choice {
-	    set rep [lindex $t 0]
-	    set cs [lindex [lindex $t 1] 0]
-
-	    foreach child [lrange [lindex $t 1] 1 end] {
-		foreach {childNullable childFirstpos childLastpos} \
-			[TraverseDepth1st $state $child $leaf $nonTerm] break
-		lappend nullable $childNullable
-		lappend firstpos $childFirstpos
-		lappend lastpos  $childLastpos
-	    }
-
-	    eval $nonTerm
-	}
-	default {
-	    incr var(number)
-	    set rep [lindex [lindex $t 0] 0]
-	    set name [lindex [lindex $t 1] 0]
-	    eval $leaf
-	}
+        :seq -
+        :choice {
+            set rep [lindex $t 0]
+            set cs [lindex [lindex $t 1] 0]
+
+            foreach child [lrange [lindex $t 1] 1 end] {
+                foreach {childNullable childFirstpos childLastpos} \
+                        [TraverseDepth1st $state $child $leaf $nonTerm]  
break
+                lappend nullable $childNullable
+                lappend firstpos $childFirstpos
+                lappend lastpos  $childLastpos
+            }
+
+            eval $nonTerm
+        }
+        default {
+            incr var(number)
+            set rep [lindex [lindex $t 0] 0]
+            set name [lindex [lindex $t 1] 0]
+            eval $leaf
+        }
      }

      return [list $nullable $firstpos $lastpos]
@@ -2453,33 +2453,33 @@

  # sgml::firstpos --
  #
-#	Computes the firstpos function for a nonterminal node.
+#       Computes the firstpos function for a nonterminal node.
  #
  # Arguments:
-#	cs		node type, choice or sequence
-#	firstpos	firstpos functions for the subtree
-#	nullable	nullable functions for the subtree
+#       cs          node type, choice or sequence
+#       firstpos    firstpos functions for the subtree
+#       nullable    nullable functions for the subtree
  #
  # Results:
-#	firstpos function for this node is returned.
+#       firstpos function for this node is returned.

  proc sgml::firstpos {cs firstpos nullable} {
      switch -- $cs {
-	:seq {
-	    set result [lindex [lindex $firstpos 0] 1]
-	    for {set i 0} {$i < [llength $nullable]} {incr i} {
-	    	if {[lindex [lindex $nullable $i] 1]} {
-	    	    eval lappend result [lindex [lindex $firstpos [expr $i + 1]] 1]
-		} else {
-		    break
-		}
-	    }
-	}
-	:choice {
-	    foreach child $firstpos {
-		eval lappend result $child
-	    }
-	}
+        :seq {
+            set result [lindex [lindex $firstpos 0] 1]
+            for {set i 0} {$i < [llength $nullable]} {incr i} {
+                    if {[lindex [lindex $nullable $i] 1]} {
+                        eval lappend result [lindex [lindex $firstpos  
[expr $i + 1]] 1]
+                } else {
+                    break
+                }
+            }
+        }
+        :choice {
+            foreach child $firstpos {
+                eval lappend result $child
+            }
+        }
      }

      return [list $firstpos [makeSet $result]]
@@ -2487,34 +2487,34 @@

  # sgml::lastpos --
  #
-#	Computes the lastpos function for a nonterminal node.
-#	Same as firstpos, only logic is reversed
+#       Computes the lastpos function for a nonterminal node.
+#       Same as firstpos, only logic is reversed
  #
  # Arguments:
-#	cs		node type, choice or sequence
-#	lastpos		lastpos functions for the subtree
-#	nullable	nullable functions forthe subtree
+#       cs          node type, choice or sequence
+#       lastpos     lastpos functions for the subtree
+#       nullable    nullable functions forthe subtree
  #
  # Results:
-#	lastpos function for this node is returned.
+#       lastpos function for this node is returned.

  proc sgml::lastpos {cs lastpos nullable} {
      switch -- $cs {
-	:seq {
-	    set result [lindex [lindex $lastpos end] 1]
-	    for {set i [expr [llength $nullable] - 1]} {$i >= 0} {incr i -1} {
-		if {[lindex [lindex $nullable $i] 1]} {
-		    eval lappend result [lindex [lindex $lastpos $i] 1]
-		} else {
-		    break
-		}
-	    }
-	}
-	:choice {
-	    foreach child $lastpos {
-		eval lappend result $child
-	    }
-	}
+        :seq {
+            set result [lindex [lindex $lastpos end] 1]
+            for {set i [expr [llength $nullable] - 1]} {$i >= 0} {incr i  
-1} {
+                if {[lindex [lindex $nullable $i] 1]} {
+                    eval lappend result [lindex [lindex $lastpos $i] 1]
+                } else {
+                    break
+                }
+            }
+        }
+        :choice {
+            foreach child $lastpos {
+                eval lappend result $child
+            }
+        }
      }

      return [list $lastpos [makeSet $result]]
@@ -2522,82 +2522,82 @@

  # sgml::makeSet --
  #
-#	Turn a list into a set, ie. remove duplicates.
+#       Turn a list into a set, ie. remove duplicates.
  #
  # Arguments:
-#	s	a list
+#       s           a list
  #
  # Results:
-#	A set is returned, which is a list with duplicates removed.
+#       A set is returned, which is a list with duplicates removed.

  proc sgml::makeSet s {
      foreach r $s {
-	if {[llength $r]} {
-	    set unique($r) {}
-	}
+        if {[llength $r]} {
+            set unique($r) {}
+        }
      }
      return [array names unique]
  }

  # sgml::nullable --
  #
-#	Compute the nullable function for a node.
+#       Compute the nullable function for a node.
  #
  # Arguments:
-#	nodeType	leaf or nonterminal
-#	rep		repetition applying to this node
-#	name		leaf node: symbol for this node, nonterm node: choice or seq node
-#	subtree		nonterm node: nullable functions for the subtree
+#       nodeType    leaf or nonterminal
+#       rep         repetition applying to this node
+#       name        leaf node: symbol for this node, nonterm node: choice  
or seq node
+#       subtree     nonterm node: nullable functions for the subtree
  #
  # Results:
-#	Returns nullable function for this branch of the tree.
+#       Returns nullable function for this branch of the tree.

  proc sgml::nullable {nodeType rep name {subtree {}}} {
      switch -glob -- $rep:$nodeType {
-	:leaf -
-	+:leaf {
-	    return [list {} 0]
-	}
-	\\*:leaf -
-	\\?:leaf {
-	    return [list {} 1]
-	}
-	\\*:nonterm -
-	\\?:nonterm {
-	    return [list $subtree 1]
-	}
-	:nonterm -
-	+:nonterm {
-	    switch -- $name {
-		:choice {
-		    set result 0
-		    foreach child $subtree {
-			set result [expr $result || [lindex $child 1]]
-		    }
-		}
-		:seq {
-		    set result 1
-		    foreach child $subtree {
-			set result [expr $result && [lindex $child 1]]
-		    }
-		}
-	    }
-	    return [list $subtree $result]
-	}
+        :leaf -
+        +:leaf {
+            return [list {} 0]
+        }
+        \\*:leaf -
+        \\?:leaf {
+            return [list {} 1]
+        }
+        \\*:nonterm -
+        \\?:nonterm {
+            return [list $subtree 1]
+        }
+        :nonterm -
+        +:nonterm {
+            switch -- $name {
+                :choice {
+                    set result 0
+                    foreach child $subtree {
+                        set result [expr $result || [lindex $child 1]]
+                    }
+                }
+                :seq {
+                    set result 1
+                    foreach child $subtree {
+                        set result [expr $result && [lindex $child 1]]
+                    }
+                }
+            }
+            return [list $subtree $result]
+        }
      }
  }

  # sgml::DTD:ATTLIST --
  #
-#	<!ATTLIST ...> defines an attribute list.
+#       <!ATTLIST ...> defines an attribute list.
  #
  # Arguments:
-#	opts	configuration opions
-#	name	Element GI
-#	attspec	unparsed attribute definitions
+#       opts        configuration opions
+#       name        Element GI
+#       attspec     unparsed attribute definitions
  #
  # Results:
-#	Attribute list variables are modified.
+#       Attribute list variables are modified.

  proc sgml::DTD:ATTLIST {opts name attspec} {
      variable attlist_exp
@@ -2620,20 +2620,20 @@

  # sgml::DTDAttribute --
  #
-#	Parse definition of a single attribute.
+#       Parse definition of a single attribute.
  #
  # Arguments:
-#	callback	attribute defn callback
-#	name	element name
-#	var	array variable
-#	att	attribute name
-#	type	type of this attribute
-#	default	default value of the attribute
-#	value	other information
-#	text	other text (should be empty)
+#       callback    attribute defn callback
+#       name        element name
+#       var         array variable
+#       att         attribute name
+#       type        type of this attribute
+#       default     default value of the attribute
+#       value       other information
+#       text        other text (should be empty)
  #
  # Results:
-#	Attribute defn added to array, unless it already exists
+#       Attribute defn added to array, unless it already exists

  proc sgml::DTDAttribute args {
      # BUG: Some problems with parameter passing - deal with it later
@@ -2642,15 +2642,15 @@
      upvar #0 $var atts

      if {[string length [string trim $text]]} {
-	return -code error "unexpected text \"$text\" in attribute definition"
+        return -code error "unexpected text \"$text\" in attribute  
definition"
      }

      # What about overridden attribute defns?
      # A non-validating app may want to know about them
      # (eg. an editor)
      if {![info exists atts($name/$att)]} {
-	set atts($name/$att) [list $type $default $value]
-	uplevel #0 $callback [list $name $att $type $default $value]
+        set atts($name/$att) [list $type $default $value]
+        uplevel #0 $callback [list $name $att $type $default $value]
      }

      return {}
@@ -2658,110 +2658,110 @@

  # sgml::DTD:ENTITY --
  #
-#	<!ENTITY ...> declaration.
+#       <!ENTITY ...> declaration.
  #
-#	Callbacks:
-#	-entitydeclcommand for general entity declaration
-#	-unparsedentitydeclcommand for unparsed external entity declaration
-#	-parameterentitydeclcommand for parameter entity declaration
+#       Callbacks:
+#       -entitydeclcommand for general entity declaration
+#       -unparsedentitydeclcommand for unparsed external entity declaration
+#       -parameterentitydeclcommand for parameter entity declaration
  #
  # Arguments:
-#	opts	configuration options
-#	name	name of entity being defined
-#	param	whether a parameter entity is being defined
-#	value	unparsed replacement text
+#       opts        configuration options
+#       name        name of entity being defined
+#       param       whether a parameter entity is being defined
+#       value       unparsed replacement text
  #
  # Results:
-#	Modifies the caller's entities array variable
+#       Modifies the caller's entities array variable

  proc sgml::DTD:ENTITY {opts name param value} {

      array set options $opts

      if {[string compare % $param]} {
-	# Entity declaration - general or external
-	upvar #0 $options(entities) ents
-	upvar #0 $options(extentities) externals
-
-	if {[info exists ents($name)] || [info exists externals($name)]} {
-	    eval $options(-warningcommand) entity [list "entity \"$name\" already  
declared"]
-	} else {
-	    if {[catch {uplevel #0 $options(-parseentitydeclcommand) [list  
$value]} value]} {
-		return -code error "unable to parse entity declaration due to \"$value\""
-	    }
-	    switch -glob -- [lindex $value 0],[lindex $value 3] {
-		internal, {
-		    set ents($name) [EntitySubst [array get options] [lindex $value 1]]
-		    uplevel #0 $options(-entitydeclcommand) [list $name $ents($name)]
-		}
-		internal,* {
-		    return -code error "unexpected NDATA declaration"
-		}
-		external, {
-		    set externals($name) [lrange $value 1 2]
-		    uplevel #0 $options(-entitydeclcommand) [eval list $name [lrange  
$value 1 2]]
-		}
-		external,* {
-		    set externals($name) [lrange $value 1 3]
-		    uplevel #0 $options(-unparsedentitydeclcommand) [eval list $name  
[lrange $value 1 3]]
-		}
-		default {
-		    return -code error "internal error: unexpected parser state"
-		}
-	    }
-	}
+        # Entity declaration - general or external
+        upvar #0 $options(entities) ents
+        upvar #0 $options(extentities) externals
+
+        if {[info exists ents($name)] || [info exists externals($name)]} {
+            eval $options(-warningcommand) entity [list "entity \"$name\"  
already declared"]
+        } else {
+            if {[catch {uplevel #0 $options(-parseentitydeclcommand) [list  
$value]} value]} {
+                return -code error "unable to parse entity declaration due  
to \"$value\""
+            }
+            switch -glob -- [lindex $value 0],[lindex $value 3] {
+                internal, {
+                    set ents($name) [EntitySubst [array get options]  
[lindex $value 1]]
+                    uplevel #0 $options(-entitydeclcommand) [list $name  
$ents($name)]
+                }
+                internal,* {
+                    return -code error "unexpected NDATA declaration"
+                }
+                external, {
+                    set externals($name) [lrange $value 1 2]
+                    uplevel #0 $options(-entitydeclcommand) [eval list  
$name [lrange $value 1 2]]
+                }
+                external,* {
+                    set externals($name) [lrange $value 1 3]
+                    uplevel #0 $options(-unparsedentitydeclcommand) [eval  
list $name [lrange $value 1 3]]
+                }
+                default {
+                    return -code error "internal error: unexpected parser  
state"
+                }
+            }
+        }
      } else {
-	# Parameter entity declaration
-	upvar #0 $options(parameterentities) PEnts
-	upvar #0 $options(externalparameterentities) ExtPEnts
-
-	if {[info exists PEnts($name)] || [info exists ExtPEnts($name)]} {
-	    eval $options(-warningcommand) parameterentity [list "parameter  
entity \"$name\" already declared"]
-	} else {
-	    if {[catch {uplevel #0 $options(-parseentitydeclcommand) [list  
$value]} value]} {
-		return -code error "unable to parse parameter entity declaration due to  
\"$value\""
-	    }
-	    if {[string length [lindex $value 3]]} {
-		return -code error "NDATA illegal in parameter entity declaration"
-	    }
-	    switch -- [lindex $value 0] {
-		internal {
-		    # Substitute character references and PEs (XML: 4.5)
-		    set value [EntitySubst [array get options] [lindex $value 1]]
-
-		    set PEnts($name) $value
-		    uplevel #0 $options(-parameterentitydeclcommand) [list $name $value]
-		}
-		external -
-		default {
-		    # Get the replacement text now.
-		    # Could wait until the first reference, but easier
-		    # to just do it now.
-
-		    set token [uri::geturl [uri::resolve $options(-baseurl) [lindex  
$value 1]]]
-
-		    set ExtPEnts($name) [lindex [array get $token data] 1]
-		    uplevel #0 $options(-parameterentitydeclcommand) [eval list $name  
[lrange $value 1 2]]
-		}
-	    }
-	}
+        # Parameter entity declaration
+        upvar #0 $options(parameterentities) PEnts
+        upvar #0 $options(externalparameterentities) ExtPEnts
+
+        if {[info exists PEnts($name)] || [info exists ExtPEnts($name)]} {
+            eval $options(-warningcommand) parameterentity  
[list "parameter entity \"$name\" already declared"]
+        } else {
+            if {[catch {uplevel #0 $options(-parseentitydeclcommand) [list  
$value]} value]} {
+                return -code error "unable to parse parameter entity  
declaration due to \"$value\""
+            }
+            if {[string length [lindex $value 3]]} {
+                return -code error "NDATA illegal in parameter entity  
declaration"
+            }
+            switch -- [lindex $value 0] {
+                internal {
+                    # Substitute character references and PEs (XML: 4.5)
+                    set value [EntitySubst [array get options] [lindex  
$value 1]]
+
+                    set PEnts($name) $value
+                    uplevel #0 $options(-parameterentitydeclcommand) [list  
$name $value]
+                }
+                external -
+                default {
+                    # Get the replacement text now.
+                    # Could wait until the first reference, but easier
+                    # to just do it now.
+
+                    set token [uri::geturl [uri::resolve  
$options(-baseurl) [lindex $value 1]]]
+
+                    set ExtPEnts($name) [lindex [array get $token data] 1]
+                    uplevel #0 $options(-parameterentitydeclcommand) [eval  
list $name [lrange $value 1 2]]
+                }
+            }
+        }
      }
  }

  # sgml::EntitySubst --
  #
-#	Perform entity substitution on an entity replacement text.
-#	This differs slightly from other substitution procedures,
-#	because only parameter and character entity substitution
-#	is performed, not general entities.
-#	See XML Rec. section 4.5.
+#       Perform entity substitution on an entity replacement text.
+#       This differs slightly from other substitution procedures,
+#       because only parameter and character entity substitution
+#       is performed, not general entities.
+#       See XML Rec. section 4.5.
  #
  # Arguments:
-#	opts	configuration options
-#	value	Literal entity value
+#       opts        configuration options
+#       value       Literal entity value
  #
  # Results:
-#	Expanded replacement text
+#       Expanded replacement text

  proc sgml::EntitySubst {opts value} {
      array set options $opts
@@ -2779,48 +2779,48 @@

  # sgml::EntitySubstValue --
  #
-#	Handle a single character or parameter entity substitution
+#       Handle a single character or parameter entity substitution
  #
  # Arguments:
-#	PEvar	array variable containing PE declarations
-#	ref	character or parameter entity reference
+#       PEvar       array variable containing PE declarations
+#       ref         character or parameter entity reference
  #
  # Results:
-#	Replacement text
+#       Replacement text

  proc sgml::EntitySubstValue {PEvar ref} {
      switch -glob -- $ref {
-	&#x* {
-	    scan [string range $ref 3 end] %x hex
-	    return [format %c $hex]
-	}
-	&#* {
-	    return [format %c [string range $ref 2 end]]
-	}
-	%* {
-	    upvar #0 $PEvar PEs
-	    set ref [string range $ref 1 end]
-	    if {[info exists PEs($ref)]} {
-		return $PEs($ref)
-	    } else {
-		return -code error "parameter entity \"$ref\" not declared"
-	    }
-	}
-	default {
-	    return -code error "internal error - unexpected entity reference"
-	}
+        &#x* {
+            scan [string range $ref 3 end] %x hex
+            return [format %c $hex]
+        }
+        &#* {
+            return [format %c [string range $ref 2 end]]
+        }
+        %* {
+            upvar #0 $PEvar PEs
+            set ref [string range $ref 1 end]
+            if {[info exists PEs($ref)]} {
+                return $PEs($ref)
+            } else {
+                return -code error "parameter entity \"$ref\" not declared"
+            }
+        }
+        default {
+            return -code error "internal error - unexpected entity  
reference"
+        }
      }
      return {}
  }

  # sgml::DTD:NOTATION --
  #
-#	Process notation declaration
+#       Process notation declaration
  #
  # Arguments:
-#	opts	configuration options
-#	name	notation name
-#	value	unparsed notation spec
+#       opts        configuration options
+#       name        notation name
+#       value       unparsed notation spec

  proc sgml::DTD:NOTATION {opts name value} {
      return {}
@@ -2830,28 +2830,28 @@

      if {[regexp $notation_exp $value x scheme data] == 2} {
      } else {
-	eval $state(-errorcommand) notationvalue [list "notation value \"$value\"  
incorrectly specified"]
+        eval $state(-errorcommand) notationvalue [list "notation value  
\"$value\" incorrectly specified"]
      }
  }

  # sgml::ResolveEntity --
  #
-#	Default entity resolution routine
+#       Default entity resolution routine
  #
  # Arguments:
-#	name	name of parent parser
-#	base	base URL for relative URLs
-#	sysId	system identifier
-#	pubId	public identifier
+#       name        name of parent parser
+#       base        base URL for relative URLs
+#       sysId       system identifier
+#       pubId       public identifier

  proc sgml::ResolveEntity {name base sysId pubId} {
      variable ParseEventNum

      if {[catch {uri::resolve $base $sysId} url]} {
-	return -code error "unable to resolve system identifier \"$sysId\""
+        return -code error "unable to resolve system identifier \"$sysId\""
      }
      if {[catch {uri::geturl $url} token]} {
-	return -code error "unable to retrieve external entity \"$url\" for  
system identifier \"$sysId\""
+        return -code error "unable to retrieve external entity \"$url\"  
for system identifier \"$sysId\""
      }

      upvar #0 $token data
@@ -2863,3 +2863,5 @@

      return {}
  }
+
+# vim:ft=tcl:ts=8:sw=4:sts=4:et

Modified: trunk/tclxml/tclparser.tcl
==============================================================================
--- trunk/tclxml/tclparser.tcl	(original)
+++ trunk/tclxml/tclparser.tcl	Sun Nov  2 05:57:58 2008
@@ -1,10 +1,10 @@
-# tclparser-8.1.tcl --
+# tclparser.tcl --
  #
-#	This file provides a Tcl implementation of a XML parser.
-#	This file supports Tcl 8.1.
+#       This file provides a Tcl implementation of a XML parser.
+#       This file supports Tcl 8.1.
  #
-#	See xml-8.[01].tcl for definitions of character sets and
-#	regular expressions.
+#       See xml-8.[01].tcl for definitions of character sets and
+#       regular expressions.
  #
  # Copyright (c) 1998-2002 Zveno Pty Ltd
  # http://www.zveno.com/
@@ -43,7 +43,7 @@
  namespace eval xml::tclparser {

      namespace export create createexternal externalentity parse \
-		     configure get delete
+                     configure get delete

      # Tokenising expressions

@@ -55,44 +55,44 @@
      # Register this parser class

      ::xml::parserclass create tcl \
-	    -createcommand [namespace code create] \
-	    -createentityparsercommand [namespace code createentityparser] \
-	    -parsecommand [namespace code parse] \
-	    -configurecommand [namespace code configure] \
-	    -deletecommand [namespace code delete]
+            -createcommand [namespace code create] \
+            -createentityparsercommand [namespace code createentityparser]  
\
+            -parsecommand [namespace code parse] \
+            -configurecommand [namespace code configure] \
+            -deletecommand [namespace code delete]
  }

  # xml::tclparser::create --
  #
-#	Creates XML parser object.
+#       Creates XML parser object.
  #
  # Arguments:
-#	name	unique identifier for this instance
+#       name        unique identifier for this instance
  #
  # Results:
-#	The state variable is initialised.
+#       The state variable is initialised.

  proc xml::tclparser::create name {

      # Initialise state variable
      upvar \#0 [namespace current]::$name parser
      array set parser [list \
-	-name $name							 \
-	-final 1							 \
-	-namespace 1							 \
-	-validate 0							 \
-	-statevariable [namespace current]::$name			 \
-	-baseurl {}							 \
-	internaldtd {}							 \
-	entities [namespace current]::Entities$name			 \
-	extentities [namespace current]::ExtEntities$name		 \
-	parameterentities [namespace current]::PEntities$name		 \
-	externalparameterentities [namespace current]::ExtPEntities$name \
-	elementdecls [namespace current]::ElDecls$name			 \
-	attlistdecls [namespace current]::AttlistDecls$name		 \
-	notationdecls [namespace current]::NotDecls$name		 \
-	depth 0								 \
-	leftover {}							 \
+        -name $name                                                      \
+        -final 1                                                         \
+        -namespace 1                                                     \
+        -validate 0                                                      \
+        -statevariable [namespace current]::$name                        \
+        -baseurl {}                                                      \
+        internaldtd {}                                                   \
+        entities [namespace current]::Entities$name                      \
+        extentities [namespace current]::ExtEntities$name                \
+        parameterentities [namespace current]::PEntities$name            \
+        externalparameterentities [namespace current]::ExtPEntities$name \
+        elementdecls [namespace current]::ElDecls$name                   \
+        attlistdecls [namespace current]::AttlistDecls$name              \
+        notationdecls [namespace current]::NotDecls$name                 \
+        depth 0                                                          \
+        leftover {}                                                      \
      ]

      # Initialise entities with predefined set
@@ -103,14 +103,14 @@

  # xml::tclparser::createentityparser --
  #
-#	Creates XML parser object for an entity.
+#       Creates XML parser object for an entity.
  #
  # Arguments:
-#	name	name for the new parser
-#	parent	name of parent parser
+#       name        name for the new parser
+#       parent      name of parent parser
  #
  # Results:
-#	The state variable is initialised.
+#       The state variable is initialised.

  proc xml::tclparser::createentityparser {parent name} {
      upvar #0 [namespace current]::$parent p
@@ -120,10 +120,10 @@
      array set external [array get p]

      array set external [list \
-	-name $name					\
-	-statevariable [namespace current]::$name	\
-	internaldtd {}					\
-	line 0						\
+        -name $name                               \
+        -statevariable [namespace current]::$name \
+        internaldtd {}                            \
+        line 0                                    \
      ]
      incr external(depth)

@@ -132,14 +132,14 @@

  # xml::tclparser::configure --
  #
-#	Configures a XML parser object.
+#       Configures a XML parser object.
  #
  # Arguments:
-#	name	unique identifier for this instance
-#	args	option name/value pairs
+#       name        unique identifier for this instance
+#       args        option name/value pairs
  #
  # Results:
-#	May change values of config options
+#       May change values of config options

  proc xml::tclparser::configure {name args} {
      upvar \#0 [namespace current]::$name parser
@@ -147,39 +147,39 @@
      # BUG: very crude, no checks for illegal args
      # Mats: Should be synced with sgmlparser.tcl
      set options {
-	-elementstartcommand -elementendcommand \
-	-characterdatacommand -processinginstructioncommand \
-	-externalentitycommand -xmldeclcommand \
-	-doctypecommand -commentcommand \
-	-entitydeclcommand -unparsedentitydeclcommand \
-	-parameterentitydeclcommand -notationdeclcommand \
-	-elementdeclcommand -attlistdeclcommand \
-	-paramentityparsing -defaultexpandinternalentities \
-	-startdoctypedeclcommand -enddoctypedeclcommand \
-	-entityreferencecommand -warningcommand \
-	-errorcommand -final -namespace \
-	-validate -baseurl \
-	-name -emptyelement \
-	-parseattributelistcommand -parseentitydeclcommand \
-	-normalize -internaldtd \
-	-reportempty -ignorewhitespace \
-	-reportempty \
+        -elementstartcommand -elementendcommand \
+        -characterdatacommand -processinginstructioncommand \
+        -externalentitycommand -xmldeclcommand \
+        -doctypecommand -commentcommand \
+        -entitydeclcommand -unparsedentitydeclcommand \
+        -parameterentitydeclcommand -notationdeclcommand \
+        -elementdeclcommand -attlistdeclcommand \
+        -paramentityparsing -defaultexpandinternalentities \
+        -startdoctypedeclcommand -enddoctypedeclcommand \
+        -entityreferencecommand -warningcommand \
+        -errorcommand -final -namespace \
+        -validate -baseurl \
+        -name -emptyelement \
+        -parseattributelistcommand -parseentitydeclcommand \
+        -normalize -internaldtd \
+        -reportempty -ignorewhitespace \
+        -reportempty \
      }
      set usage [join $options ", "]
      regsub -all -- - $options {} options
      set pat ^-([join $options |])$
      foreach {flag value} $args {
-	if {[regexp $pat $flag]} {
-	    # Validate numbers
-	    if {[info exists parser($flag)] && \
-		    [string is integer -strict $parser($flag)] && \
-		    ![string is integer -strict $value]} {
-		return -code error "Bad value for $flag ($value), must be integer"
-	    }
-	    set parser($flag) $value
-	} else {
-	    return -code error "Unknown option $flag, can be: $usage"
-	}
+        if {[regexp $pat $flag]} {
+            # Validate numbers
+            if {[info exists parser($flag)] && \
+                    [string is integer -strict $parser($flag)] && \
+                    ![string is integer -strict $value]} {
+                return -code error "Bad value for $flag ($value), must be  
integer"
+            }
+            set parser($flag) $value
+        } else {
+            return -code error "Unknown option $flag, can be: $usage"
+        }
      }

      return {}
@@ -187,15 +187,15 @@

  # xml::tclparser::parse --
  #
-#	Parses document instance data
+#       Parses document instance data
  #
  # Arguments:
-#	name	parser object
-#	xml	data
-#	args	configuration options
+#       name        parser object
+#       xml         data
+#       args        configuration options
  #
  # Results:
-#	Callbacks are invoked
+#       Callbacks are invoked

  proc xml::tclparser::parse {name xml args} {

@@ -208,68 +208,68 @@

      # Mats:
      if {[llength $args]} {
-	eval {configure $name} $args
+        eval {configure $name} $args
      }

      set parseOptions [list \
-	    -emptyelement [namespace code ParseEmpty] \
-	    -parseattributelistcommand [namespace code ParseAttrs] \
-	    -parseentitydeclcommand [namespace code ParseEntity] \
-	    -normalize 0]
+            -emptyelement [namespace code ParseEmpty] \
+            -parseattributelistcommand [namespace code ParseAttrs] \
+            -parseentitydeclcommand [namespace code ParseEntity] \
+            -normalize 0]
      eval lappend parseOptions \
-	    [array get parser -*command] \
-	    [array get parser -reportempty] \
-	    [array get parser -name] \
-	    [array get parser -baseurl] \
-	    [array get parser -validate] \
-	    [array get parser -namespace] \
-	    [array get parser -final] \
-	    [array get parser -defaultexpandinternalentities] \
-	    [array get parser entities] \
-	    [array get parser extentities] \
-	    [array get parser parameterentities] \
-	    [array get parser externalparameterentities] \
-	    [array get parser elementdecls] \
-	    [array get parser attlistdecls] \
-	    [array get parser notationdecls]
+            [array get parser -*command] \
+            [array get parser -reportempty] \
+            [array get parser -name] \
+            [array get parser -baseurl] \
+            [array get parser -validate] \
+            [array get parser -namespace] \
+            [array get parser -final] \
+            [array get parser -defaultexpandinternalentities] \
+            [array get parser entities] \
+            [array get parser extentities] \
+            [array get parser parameterentities] \
+            [array get parser externalparameterentities] \
+            [array get parser elementdecls] \
+            [array get parser attlistdecls] \
+            [array get parser notationdecls]

      # Mats:
      # If -final 0 we also need to maintain the state with a  
-statevariable !
      if {!$parser(-final)} {
-	eval lappend parseOptions [array get parser -statevariable]
+        eval lappend parseOptions [array get parser -statevariable]
      }

      set dtdsubset no
      catch {set dtdsubset $options(-dtdsubset)}
      switch -- $dtdsubset {
-	internal {
-	    # Bypass normal parsing
-	    lappend parseOptions -statevariable $parser(-statevariable)
-	    array set intOptions [array get ::sgml::StdOptions]
-	    array set intOptions $parseOptions
-	    ::sgml::ParseDTD:Internal [array get intOptions] $xml
-	    return {}
-	}
-	external {
-	    # Bypass normal parsing
-	    lappend parseOptions -statevariable $parser(-statevariable)
-	    array set intOptions [array get ::sgml::StdOptions]
-	    array set intOptions $parseOptions
-	    ::sgml::ParseDTD:External [array get intOptions] $xml
-	    return {}
-	}
-	default {
-	    # Pass through to normal processing
-	}
+        internal {
+            # Bypass normal parsing
+            lappend parseOptions -statevariable $parser(-statevariable)
+            array set intOptions [array get ::sgml::StdOptions]
+            array set intOptions $parseOptions
+            ::sgml::ParseDTD:Internal [array get intOptions] $xml
+            return {}
+        }
+        external {
+            # Bypass normal parsing
+            lappend parseOptions -statevariable $parser(-statevariable)
+            array set intOptions [array get ::sgml::StdOptions]
+            array set intOptions $parseOptions
+            ::sgml::ParseDTD:External [array get intOptions] $xml
+            return {}
+        }
+        default {
+            # Pass through to normal processing
+        }
      }

      lappend tokenOptions  \
-	    -internaldtdvariable [namespace current]::${name}(internaldtd)
+            -internaldtdvariable [namespace current]::${name}(internaldtd)

      # Mats: If -final 0 we also need to maintain the state with a  
-statevariable !
      if {!$parser(-final)} {
-	eval lappend tokenOptions [array get parser -statevariable] \
-	  [array get parser -final]
+        eval lappend tokenOptions [array get parser -statevariable] \
+          [array get parser -final]
      }

      # Mats:
@@ -277,8 +277,8 @@
      # It is necessary to have the first four as well if chopped off in
      # middle of pcdata.
      set tokenised [lrange \
-	    [eval {::sgml::tokenise $xml $tokExpr1 $tokExpr2 $tokExpr3  
$substExpr} $tokenOptions] \
-	0 end]
+            [eval {::sgml::tokenise $xml $tokExpr1 $tokExpr2 $tokExpr3  
$substExpr} $tokenOptions] \
+        0 end]

      lappend parseOptions -internaldtd [list $parser(internaldtd)]
      eval ::sgml::parseEvent [list $tokenised] $parseOptions
@@ -288,70 +288,70 @@

  # xml::tclparser::ParseEmpty --  Tcl 8.1+ version
  #
-#	Used by parser to determine whether an element is empty.
-#	This is usually dead easy in XML, but as always not quite.
-#	Have to watch out for empty element syntax
+#       Used by parser to determine whether an element is empty.
+#       This is usually dead easy in XML, but as always not quite.
+#       Have to watch out for empty element syntax
  #
  # Arguments:
-#	tag	element name
-#	attr	attribute list (raw)
-#	e	End tag delimiter.
+#       tag         element name
+#       attr        attribute list (raw)
+#       e           End tag delimiter.
  #
  # Results:
-#	Return value of e
+#       Return value of e

  proc xml::tclparser::ParseEmpty {tag attr e} {
      switch -glob -- [string length $e],[regexp "/[::xml::cl  
$::xml::Wsp]*$" $attr] {
-	0,0 {
-	    return {}
-	}
-	0,* {
-	    return /
-	}
-	default {
-	    return $e
-	}
+        0,0 {
+            return {}
+        }
+        0,* {
+            return /
+        }
+        default {
+            return $e
+        }
      }
  }

  # xml::tclparser::ParseAttrs -- Tcl 8.1+ version
  #
-#	Parse element attributes.
+#       Parse element attributes.
  #
  # There are two forms for name-value pairs:
  #
-#	name="value"
-#	name='value'
+#       name="value"
+#       name='value'
  #
  # Arguments:
-#	opts	parser options
-#	attrs	attribute string given in a tag
+#       opts        parser options
+#       attrs       attribute string given in a tag
  #
  # Results:
-#	Returns a Tcl list representing the name-value pairs in the
-#	attribute string
+#       Returns a Tcl list representing the name-value pairs in the
+#       attribute string
  #
-#	A ">" occurring in the attribute list causes problems when parsing
-#	the XML.  This manifests itself by an unterminated attribute value
-#	and a ">" appearing the element text.
-#	In this case return a three element list;
-#	the message "unterminated attribute value", the attribute list it
-#	did manage to parse and the remainder of the attribute list.
+#       A ">" occurring in the attribute list causes problems when parsing
+#       the XML.  This manifests itself by an unterminated attribute value
+#       and a ">" appearing the element text.
+#       In this case return a three element list;
+#       the message "unterminated attribute value", the attribute list it
+#       did manage to parse and the remainder of the attribute list.

  proc xml::tclparser::ParseAttrs {opts attrs} {

      set result {}

      while {[string length [string trim $attrs]]} {
-	if {[regexp ($::xml::Name)[::sgml::cl $::xml::Wsp]*=[::sgml::cl  
$::xml::Wsp]*(\"|')([::sgml::cl ^<]*?)\\2(.*) \
-		    $attrs -> attrName delimiter value attrs]} {
-	    lappend result $attrName [NormalizeAttValue $opts $value]
-	} elseif {[regexp $::xml::Name[::sgml::cl $::xml::Wsp]*=[::sgml::cl  
$::xml::Wsp]*(\"|')[::sgml::cl ^<]*\$ \
-			  $attrs]} {
-	    return -code error [list {unterminated attribute value} $result  
$attrs]
-	} else {
-	    return -code error "invalid attribute list"
-	}
+        if {[regexp ($::xml::Name)[::sgml::cl $::xml::Wsp]*=[::sgml::cl  
$::xml::Wsp]*(\"|')([::sgml::cl ^<]*?)\\2(.*) \
+                    $attrs -> attrName delimiter value attrs]} {
+            lappend result $attrName [NormalizeAttValue $opts $value]
+        } elseif {[regexp $::xml::Name[::sgml::cl  
$::xml::Wsp]*=[::sgml::cl $::xml::Wsp]*(\"|')[::sgml::cl ^<]*\$ \
+                          $attrs]} {
+            return -code error [list {unterminated attribute value}  
$result $attrs]
+        } else {
+            return -code error "invalid attribute list"
+        }
      }

      return $result
@@ -359,18 +359,18 @@

  # xml::tclparser::NormalizeAttValue --
  #
-#	Perform attribute value normalisation.  This involves:
-#	. character references are appended to the value
-#	. entity references are recursively processed and replacement value  
appended
-#	. whitespace characters cause a space to be appended
-#	. other characters appended as-is
+#       Perform attribute value normalisation.  This involves:
+#       . character references are appended to the value
+#       . entity references are recursively processed and replacement  
value appended
+#       . whitespace characters cause a space to be appended
+#       . other characters appended as-is
  #
  # Arguments:
-#	opts	parser options
-#	value	unparsed attribute value
+#       opts        parser options
+#       value       unparsed attribute value
  #
  # Results:
-#	Normalised value returned.
+#       Normalised value returned.

  proc xml::tclparser::NormalizeAttValue {opts value} {

@@ -389,119 +389,119 @@

  # xml::tclparser::NormalizeAttValue:DeRef --
  #
-#	Handler to normalize attribute values
+#       Handler to normalize attribute values
  #
  # Arguments:
-#	opts	parser options
-#	ref	entity reference
+#       opts        parser options
+#       ref         entity reference
  #
  # Results:
-#	Returns character
+#       Returns character

  proc xml::tclparser::NormalizeAttValue:DeRef {opts ref} {

      switch -glob -- $ref {
-	#x* {
-	    scan [string range $ref 2 end] %x value
-	    set char [format %c $value]
-	    # Check that the char is legal for XML
-	    if {[regexp [format {^[%s]$} $::xml::Char] $char]} {
-		return $char
-	    } else {
-		return -code error "illegal character"
-	    }
-	}
-	#* {
-	    scan [string range $ref 1 end] %d value
-	    set char [format %c $value]
-	    # Check that the char is legal for XML
-	    if {[regexp [format {^[%s]$} $::xml::Char] $char]} {
-		return $char
-	    } else {
-		return -code error "illegal character"
-	    }
-	}
-	lt -
-	gt -
-	amp -
-	quot -
-	apos {
-	    array set map {lt < gt > amp & quot \" apos '}
-	    return $map($ref)
-	}
-	default {
-	    # A general entity.  Must resolve to a text value - no element  
structure.
-
-	    array set options $opts
-	    upvar #0 $options(entities) map
-
-	    if {[info exists map($ref)]} {
-
-		if {[regexp < $map($ref)]} {
-		    return -code error "illegal character \"<\" in attribute value"
-		}
-
-		if {![regexp & $map($ref)]} {
-		    # Simple text replacement
-		    return $map($ref)
-		}
-
-		# There are entity references in the replacement text.
-		# Can't use child entity parser since must catch element structures
-
-		return [NormalizeAttValue $opts $map($ref)]
-
-	    } elseif {[string compare  
$options(-entityreferencecommand) "::sgml::noop"]} {
-
-		set result [uplevel #0 $options(-entityreferencecommand) [list $ref]]
-
-		return $result
-
-	    } else {
-		return -code error "unable to resolve entity reference \"$ref\""
-	    }
-	}
+        #x* {
+            scan [string range $ref 2 end] %x value
+            set char [format %c $value]
+            # Check that the char is legal for XML
+            if {[regexp [format {^[%s]$} $::xml::Char] $char]} {
+                return $char
+            } else {
+                return -code error "illegal character"
+            }
+        }
+        #* {
+            scan [string range $ref 1 end] %d value
+            set char [format %c $value]
+            # Check that the char is legal for XML
+            if {[regexp [format {^[%s]$} $::xml::Char] $char]} {
+                return $char
+            } else {
+                return -code error "illegal character"
+            }
+        }
+        lt -
+        gt -
+        amp -
+        quot -
+        apos {
+            array set map {lt < gt > amp & quot \" apos '}
+            return $map($ref)
+        }
+        default {
+            # A general entity.  Must resolve to a text value - no element  
structure.
+
+            array set options $opts
+            upvar #0 $options(entities) map
+
+            if {[info exists map($ref)]} {
+
+                if {[regexp < $map($ref)]} {
+                    return -code error "illegal character \"<\" in  
attribute value"
+                }
+
+                if {![regexp & $map($ref)]} {
+                    # Simple text replacement
+                    return $map($ref)
+                }
+
+                # There are entity references in the replacement text.
+                # Can't use child entity parser since must catch element  
structures
+
+                return [NormalizeAttValue $opts $map($ref)]
+
+            } elseif {[string compare  
$options(-entityreferencecommand) "::sgml::noop"]} {
+
+                set result [uplevel #0 $options(-entityreferencecommand)  
[list $ref]]
+
+                return $result
+
+            } else {
+                return -code error "unable to resolve entity reference  
\"$ref\""
+            }
+        }
      }
  }

  # xml::tclparser::ParseEntity --
  #
-#	Parse general entity declaration
+#       Parse general entity declaration
  #
  # Arguments:
-#	data	text to parse
+#       data        text to parse
  #
  # Results:
-#	Tcl list containing entity declaration
+#       Tcl list containing entity declaration

  proc xml::tclparser::ParseEntity data {
      set data [string trim $data]
      if {[regexp $::sgml::ExternalEntityExpr $data \
-		-> type delimiter1 id1 discard delimiter2 id2 optNDATA ndata]} {
-	switch -- $type {
-	    PUBLIC {
-		return [list external $id2 $id1 $ndata]
-	    }
-	    SYSTEM {
-		return [list external $id1 {} $ndata]
-	    }
-	}
+                -> type delimiter1 id1 discard delimiter2 id2 optNDATA  
ndata]} {
+        switch -- $type {
+            PUBLIC {
+                return [list external $id2 $id1 $ndata]
+            }
+            SYSTEM {
+                return [list external $id1 {} $ndata]
+            }
+        }
      } elseif {[regexp {^(\"|')(.*?)\1$} $data discard delimiter value]} {
-	return [list internal $value]
+        return [list internal $value]
      } else {
-	return -code error "badly formed entity declaration"
+        return -code error "badly formed entity declaration"
      }
  }

  # xml::tclparser::delete --
  #
-#	Destroy parser data
+#       Destroy parser data
  #
  # Arguments:
-#	name	parser object
+#       name        parser object
  #
  # Results:
-#	Parser data structure destroyed
+#       Parser data structure destroyed

  proc xml::tclparser::delete name {
      upvar \#0 [namespace current]::$name parser
@@ -512,71 +512,71 @@

  # xml::tclparser::get --
  #
-#	Retrieve additional information from the parser
+#       Retrieve additional information from the parser
  #
  # Arguments:
-#	name	parser object
-#	method	info to retrieve
-#	args	additional arguments for method
+#       name        parser object
+#       method      info to retrieve
+#       args        additional arguments for method
  #
  # Results:
-#	Depends on method
+#       Depends on method

  proc xml::tclparser::get {name method args} {
      upvar #0 [namespace current]::$name parser

      switch -- $method {

-	elementdecl {
-	    switch -- [llength $args] {
+        elementdecl {
+            switch -- [llength $args] {

-		0 {
-		    # Return all element declarations
-		    upvar #0 $parser(elementdecls) elements
-		    return [array get elements]
-		}
-
-		1 {
-		    # Return specific element declaration
-		    upvar #0 $parser(elementdecls) elements
-		    if {[info exists elements([lindex $args 0])]} {
-			return [array get elements [lindex $args 0]]
-		    } else {
-			return -code error "element \"[lindex $args 0]\" not\
-					    declared"
-		    }
-		}
-
-		default {
-		    return -code error "wrong number of arguments:

==============================================================================
Diff truncated at 200k characters


More information about the Tkabber-dev mailing list