<!DOCTYPE html>
<html>
<head>
<title>oowebtools-doc.md</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">

<style>
/* https://github.com/microsoft/vscode/blob/master/extensions/markdown-language-features/media/markdown.css */
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

body {
	font-family: var(--vscode-markdown-font-family, -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif);
	font-size: var(--vscode-markdown-font-size, 14px);
	padding: 0 26px;
	line-height: var(--vscode-markdown-line-height, 22px);
	word-wrap: break-word;
}

#code-csp-warning {
	position: fixed;
	top: 0;
	right: 0;
	color: white;
	margin: 16px;
	text-align: center;
	font-size: 12px;
	font-family: sans-serif;
	background-color:#444444;
	cursor: pointer;
	padding: 6px;
	box-shadow: 1px 1px 1px rgba(0,0,0,.25);
}

#code-csp-warning:hover {
	text-decoration: none;
	background-color:#007acc;
	box-shadow: 2px 2px 2px rgba(0,0,0,.25);
}

body.scrollBeyondLastLine {
	margin-bottom: calc(100vh - 22px);
}

body.showEditorSelection .code-line {
	position: relative;
}

body.showEditorSelection .code-active-line:before,
body.showEditorSelection .code-line:hover:before {
	content: "";
	display: block;
	position: absolute;
	top: 0;
	left: -12px;
	height: 100%;
}

body.showEditorSelection li.code-active-line:before,
body.showEditorSelection li.code-line:hover:before {
	left: -30px;
}

.vscode-light.showEditorSelection .code-active-line:before {
	border-left: 3px solid rgba(0, 0, 0, 0.15);
}

.vscode-light.showEditorSelection .code-line:hover:before {
	border-left: 3px solid rgba(0, 0, 0, 0.40);
}

.vscode-light.showEditorSelection .code-line .code-line:hover:before {
	border-left: none;
}

.vscode-dark.showEditorSelection .code-active-line:before {
	border-left: 3px solid rgba(255, 255, 255, 0.4);
}

.vscode-dark.showEditorSelection .code-line:hover:before {
	border-left: 3px solid rgba(255, 255, 255, 0.60);
}

.vscode-dark.showEditorSelection .code-line .code-line:hover:before {
	border-left: none;
}

.vscode-high-contrast.showEditorSelection .code-active-line:before {
	border-left: 3px solid rgba(255, 160, 0, 0.7);
}

.vscode-high-contrast.showEditorSelection .code-line:hover:before {
	border-left: 3px solid rgba(255, 160, 0, 1);
}

.vscode-high-contrast.showEditorSelection .code-line .code-line:hover:before {
	border-left: none;
}

img {
	max-width: 100%;
	max-height: 100%;
}

a {
	text-decoration: none;
}

a:hover {
	text-decoration: underline;
}

a:focus,
input:focus,
select:focus,
textarea:focus {
	outline: 1px solid -webkit-focus-ring-color;
	outline-offset: -1px;
}

hr {
	border: 0;
	height: 2px;
	border-bottom: 2px solid;
}

h1 {
	padding-bottom: 0.3em;
	line-height: 1.2;
	border-bottom-width: 1px;
	border-bottom-style: solid;
}

h1, h2, h3 {
	font-weight: normal;
}

table {
	border-collapse: collapse;
}

table > thead > tr > th {
	text-align: left;
	border-bottom: 1px solid;
}

table > thead > tr > th,
table > thead > tr > td,
table > tbody > tr > th,
table > tbody > tr > td {
	padding: 5px 10px;
}

table > tbody > tr + tr > td {
	border-top: 1px solid;
}

blockquote {
	margin: 0 7px 0 5px;
	padding: 0 16px 0 10px;
	border-left-width: 5px;
	border-left-style: solid;
}

code {
	font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback";
	font-size: 1em;
	line-height: 1.357em;
}

body.wordWrap pre {
	white-space: pre-wrap;
}

pre:not(.hljs),
pre.hljs code > div {
	padding: 16px;
	border-radius: 3px;
	overflow: auto;
}

pre code {
	color: var(--vscode-editor-foreground);
	tab-size: 4;
}

/** Theming */

.vscode-light pre {
	background-color: rgba(220, 220, 220, 0.4);
}

.vscode-dark pre {
	background-color: rgba(10, 10, 10, 0.4);
}

.vscode-high-contrast pre {
	background-color: rgb(0, 0, 0);
}

.vscode-high-contrast h1 {
	border-color: rgb(0, 0, 0);
}

.vscode-light table > thead > tr > th {
	border-color: rgba(0, 0, 0, 0.69);
}

.vscode-dark table > thead > tr > th {
	border-color: rgba(255, 255, 255, 0.69);
}

.vscode-light h1,
.vscode-light hr,
.vscode-light table > tbody > tr + tr > td {
	border-color: rgba(0, 0, 0, 0.18);
}

.vscode-dark h1,
.vscode-dark hr,
.vscode-dark table > tbody > tr + tr > td {
	border-color: rgba(255, 255, 255, 0.18);
}

</style>

<style>
/* Tomorrow Theme */
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
/* Original theme - https://github.com/chriskempson/tomorrow-theme */

/* Tomorrow Comment */
.hljs-comment,
.hljs-quote {
	color: #8e908c;
}

/* Tomorrow Red */
.hljs-variable,
.hljs-template-variable,
.hljs-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-regexp,
.hljs-deletion {
	color: #c82829;
}

/* Tomorrow Orange */
.hljs-number,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params,
.hljs-meta,
.hljs-link {
	color: #f5871f;
}

/* Tomorrow Yellow */
.hljs-attribute {
	color: #eab700;
}

/* Tomorrow Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet,
.hljs-addition {
	color: #718c00;
}

/* Tomorrow Blue */
.hljs-title,
.hljs-section {
	color: #4271ae;
}

/* Tomorrow Purple */
.hljs-keyword,
.hljs-selector-tag {
	color: #8959a8;
}

.hljs {
	display: block;
	overflow-x: auto;
	color: #4d4d4c;
	padding: 0.5em;
}

.hljs-emphasis {
	font-style: italic;
}

.hljs-strong {
	font-weight: bold;
}
</style>

<style>
/*
 * Markdown PDF CSS
 */

 body {
	font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif, "Meiryo";
	padding: 0 12px;
}

pre {
	background-color: #f8f8f8;
	border: 1px solid #cccccc;
	border-radius: 3px;
	overflow-x: auto;
	white-space: pre-wrap;
	overflow-wrap: break-word;
}

pre:not(.hljs) {
	padding: 23px;
	line-height: 19px;
}

blockquote {
	background: rgba(127, 127, 127, 0.1);
	border-color: rgba(0, 122, 204, 0.5);
}

.emoji {
	height: 1.4em;
}

code {
	font-size: 14px;
	line-height: 19px;
}

/* for inline code */
:not(pre):not(.hljs) > code {
	color: firebrick; /* Change the old color so it seems less like an error */
	font-size: inherit;
}

/* Page Break : use <div class="page"/> to insert page break
-------------------------------------------------------- */
.page {
	page-break-after: always;
}

</style>

<script src="https://unpkg.com/mermaid/dist/mermaid.min.js"></script>
</head>
<body>
  <script>
    mermaid.initialize({
      startOnLoad: true,
      theme: document.body.classList.contains('vscode-dark') || document.body.classList.contains('vscode-high-contrast')
          ? 'dark'
          : 'default'
    });
  </script>
<!-- oowebtools-doc.md -->
<!-- version 1.0, Sat 13 Jan 2024 23:36:02 -08:00 -->
<h1 id="oowebtools"><strong>oowebtools</strong></h1>
<h2 id="description"><strong>Description</strong></h2>
<p><em><strong>oowebtools</strong></em> is an open-source TclOO (object-oriented) toolkit for constructing websites. It's designed to facilitate building web pages even if TclOO features aren't used directly. (Naturally extending <em>oowebtools</em> features will probably require deriving classes or using other TclOO capabilities. The majority of users won't need to do this.)</p>
<p><em>oowebtools</em> is the successor to jwebtools. While the purpose and general patterns of use are similar, the new toolkit leverages the recently completed <em>nxproc</em> extension and represents a thorough revision of old code along with a great many bug fixes. <em>oowebtools</em> has cleaner syntax and greater ease of use.</p>
<p>While <em>oowebtools</em> offers a number of conveniences and ready-to-use components, it works by encapsulating HTML entities making page construction more compact and flexible. Basically the toolkit enables writing page generators. Since these page generators are written in Tcl, templating can be accomplished simply by inserting Tcl procedure calls or variables.</p>
<h2 id="sample-web-page"><strong>Sample web page</strong></h2>
<p>Before getting into details, a brief example of a web page using <em>oowebtools</em>:</p>
<pre><code>proc page0 {} {
    Html: --&gt; [subst {
        [Head: -title &quot;Example page&quot; \
            -descrip &quot;Demonstrates oowebtools&quot; --&gt; [subst {
            [Preload: --&gt; {href /js/example.js as script}]
            [Preload: --&gt; {href /css/example.css as style}]
            [Link: --&gt; {href /css/example.css rel stylesheet 
                        type text/css}]
        }]]
        [Body: --&gt; [subst {
            [H1: --&gt; &quot;Example Web Page&quot;]
            [Div: --&gt; {class main} [subst {
                [Div: --&gt; {class msgdiv} \
                    {This is the message.}]
                [Div: --&gt; {id imgdiv} [subst {
                    [Img: --&gt; {src /img/big-country.jpg 
                            alt &quot;Wide open fields&quot;}]
                }]]
            }]]
        }]]
    }]
}
</code></pre>
<p>The toolkit provides commands corresponding to 42 HTML tags. These are called using a simple syntax:</p>
<p><strong>Tag: &lt;fixed args&gt; &lt;named args&gt; --&gt; {attributes} {text or element list}</strong></p>
<p>Naturally input varies depending on the tag but the pattern is consistent.</p>
<p>In the example, each tag command is called with &quot;--&gt;&quot; followed by one or two lists. The first is a an optional list of attributes. The final (or only list) is either text or list of elements &quot;owned&quot; by the tag. The result is a hierarchical list structure, exactly what HTML is about.</p>
<p>The &quot;page0&quot; command returns the result of running the Html class command. That is, an object itself a command created by &quot;Html:&quot;. This object can call the methods defined by Html. The most relevant method is &quot;write&quot;. Each tag object knows how to write itself, so when [page0] is called, the web page is written to stdout or possibly another file descriptor.</p>
<pre><code>[page0] write

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;EN-US&quot;&gt;
  &lt;head&gt;
    &lt;title&gt;Example page&lt;/title&gt;
    &lt;meta name=&quot;description&quot; 
          content=&quot;Illustrates using oowebtools&quot;&gt;    
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; 
          content=&quot;width=device-width, initial-scale=1&quot;&gt;
    &lt;link href=&quot;/js/example.js&quot; as=&quot;script&quot; rel=&quot;preload&quot;&gt;
    &lt;link href=&quot;/css/example.css&quot; as=&quot;style&quot; rel=&quot;preload&quot;&gt;
    &lt;link href=&quot;/css/example.css&quot; rel=&quot;stylesheet&quot; 
          type=&quot;text/css&quot;&gt;      
  &lt;/head&gt;
  &lt;body&gt;
    &lt;h1&gt;
      Example Web Page
    &lt;/h1&gt;
    &lt;div class=&quot;main&quot;&gt;
      &lt;div class=&quot;msgdiv&quot;&gt;
       This is the message.
      &lt;/div&gt;
      &lt;div id=&quot;imgdiv&quot;&gt;
        &lt;img src=&quot;/img/big-country.jpg&quot; 
             alt=&quot;Wide open fields&quot;&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<h3 id="defined-tags"><em><strong>Defined tags</strong></em></h3>
<p>Here is the complete list of HTML classes in the toolkit. Note that these all have upper case first letter.</p>
<pre><code>A Area Article Audio B Base Bdi Blockquote Body Button Canvas Charset Code Datalist Del Description Details Div Em Embed Fieldset Figcaption Figure Footer Form H1 H2 H3 H4 H5 H6 Head Header Hr Html Iframe Img Input Ins Label Legend Li Link Main Map Meta Meter Nav Ol Optgroup Option P Picture Pre Preload Script ScriptSrc Select Source Span Style Sub Summary Sup Textarea Title U Ul Video Viewport
</code></pre>
<p>This doesn't cover all possible HTML tags, but sufficient for most users' purposes. If other tags are needed adding them is pretty straightforward to do.</p>
<p>To use these tag classes, either &quot;Tag:&quot; or &quot;Tag new&quot; works. (These are in fact completely equivalent.) The colon form is more convenient and clearer so usually preferred.</p>
<h4 id="basic-tags"><strong>Basic tags</strong></h4>
<pre><code>A Article B Bdi Blockquote Body Button Canvas Code Datalist Del Details Div Em Fieldset Figure Figcaption Footer Form H1 H2 H3 H4 H5 H6 Header Iframe Ins Legend Li Main Map Meter Nav Ol Optgroup P Picture Pre Select Span Summary Sub Sup Textarea U Ul

# Syntax

Tag: &lt;options&gt; --&gt; {attrib list} {text-or-element list}
&lt;options&gt; 
    -nonl           (bool 0)  &quot;no nl chars around tag&quot;
    -zeroindent     (bool 0)  &quot;no indenting at all&quot;
    -indenting      (bool 0)  &quot;per tag indenting or not&quot;
    -indent         (int 0)   &quot;amount to indent&quot;
    -textoutdent    (int 0)   &quot;move text to left (script,style)&quot;
    -leftmarg       (int 0)   &quot;line starting point&quot;
    -fd             (str &quot;&quot;)  &quot;output device&quot;
{attrib list}   (str/list) 
{text/elements} (str/list of objects)

Methods: 
    write ?fd?  &quot;write&quot; is most useful method, avail in all tags.
                Takes one (positional) argument, &quot;fd&quot; or file 
                descriptor (e.g., from &quot;open&quot;). The default 
                empty string causes write to return rendered
                text associated with the tag.
</code></pre>
<h4 id="tags-without-end-tag"><strong>Tags without end tag</strong></h4>
<pre><code>Area Base Embed Hr Img Input Option 

# Syntax

Tag: &lt;options&gt; --&gt; {attrib list}
&lt;options&gt;   same as basic tags
{attrib list}   $nxargs contains only &lt;attrib value ...&gt; list
</code></pre>
<h4 id="html-tag-group"><strong>Html tag group</strong></h4>
<pre><code>Syntax:

Html: &lt;options&gt; --&gt; {&lt;head object&gt; &lt;body object&gt;}
    -lang   (EN-US)
    -fd     (&quot;&quot;)

Head: &lt;options&gt; --&gt; {elements only - NO ATTRIB}
    -title   (&quot;&quot;)   &quot;page title&quot;
    -descrip (&quot;&quot;)   &quot;page description&quot;

Meta: &lt;options&gt; 
    -name    (&quot;&quot;)
    -content (&quot;&quot;)

Link: --&gt; {attributes}

Preload: --&gt; {attributes}  

ScriptSrc: -src &lt;URL&gt; ?--&gt; {attributes}?

Script: -outdent &lt;int 0&gt; --&gt; {text}

Style: -outdent &lt;int 1&gt; --&gt; ?{media &lt;value&gt;}? {text}
</code></pre>
<h4 id="other-tags"><strong>Other tags</strong></h4>
<pre><code>Label Audio Video Source

Syntax:

Label: -for &lt;str&gt; --&gt; ?{attribs}? {text}

Audio: &lt;options&gt; --&gt; ?{attribs}? {element list}
    -src            URL 
    -autoplay       BOOL 0 
    -nocontrols     BOOL 0 
    -loop           BOOL 0 
    -muted          BOOL 0 
    -preload        ENUM {auto metadata none}

Video: &lt;options&gt; --&gt; ?{attribs}? {element list}
    -src            URL 
    -autoplay       BOOL 0 
    -nocontrols     BOOL 0 
    -loop           BOOL 0 
    -muted          BOOL 0
    -preload        ENUM {auto metadata none} 
    -poster         URL
    -width          300 (px)
    -height         150 (px)

Source: &lt;options&gt;
    -src            URL 
    -type           &lt;mime type&gt;
    -media          &quot;&quot;  for &lt;picture&gt;
    -sizes          &quot;&quot;  for &lt;picture&gt; 
    -srcset         &quot;&quot;  for &lt;picture&gt;
</code></pre>
<h4 id="other-commands"><strong>Other commands</strong></h4>
<p>The toolkit provides a number of object-commands that are not HTML tags but frequently very useful for constructing web pages. These include:</p>
<pre><code>Blist Bsrc Bsrcstub CommentDb CommDiv CommScript CommentRecv Component Contact ContactRecv Dynpage Menu ooWTserv Slider Smtp Srcset WebImg
</code></pre>
<p>Several utility classes provide internal support but also have functionality of interest to toolkit users:</p>
<pre><code>Bool Config Log Resource Util Stack
</code></pre>
<p>Both groups of commands will be described in later sections.</p>
<h3 id="architecture"><em><strong>Architecture</strong></em></h3>
<p><em>Element</em> is the abstract parent of all tag classes. <em>Element</em> contains generic functionality used by derived classes, on top of which properties are implemented in addition to or replacing what's defined in <em>Element</em>.</p>
<p>Tag constructors in <em>oowebtools</em> use <em>nxconstructor</em> (from <em>nxproc</em> extension) conferring certain advantages. First, <em>nxconstructor</em> (and <em>nxmethod</em>) allow named arguments of the form &quot;-param value&quot; with each &quot;param&quot; becoming a variable in the procedure body. Also <em>nx-</em> procedures have <em>nxunknown</em> and <em>nxargs</em> variables defined in the body. (By default these variables are empty.) These features are widely exploited in <em>oowebtools</em>.</p>
<p>In <em>nxproc</em>, procedures can have fixed (positional) arguments (optionally with defaults), named arguments, unknown arguments or nxargs.</p>
<pre><code>nxproc mycmd {{fixedarg 100} -namedarg &quot;value&quot; **} { ... }
mycmd 200 -namedarg &quot;text input&quot; unknownarg --&gt; mynxargs ...
</code></pre>
<p>In this case, &quot;mycmd&quot; body will have variables &quot;fixedarg&quot;, &quot;namedarg&quot;, &quot;nxunknown&quot; and &quot;nxargs&quot; containing 200, &quot;text input&quot;, &quot;unknownarg&quot;, and &quot;mynxargs&quot; respectively. The &quot;twostar&quot; (<code>**</code>) symbol means input on the command line not matching named arguments will be saved in the &quot;nxunknown&quot; variable rather than causing an error. (Note that &quot;nxconstructor&quot; and &quot;nxmethod&quot; work the same way as <em>nxproc</em>.)</p>
<p>In <em>oowebtools</em>, nxcontructors may have fixed or named arguments. In any case, they make use of &quot;nxargs&quot; by reading $nxargs and either sending data via &quot;next&quot; to the parent class, or processing $nxargs value as attributes and text/list of elements. The latter are saved in instance variables Attributes, Elements/Text which are used by the &quot;write&quot; method as it renders the variables' data into the target web page.</p>
<p>Toolkit users don't need to be too concerned about <em>nxproc</em> details. (Unless intending to use nxproc commands in their own work.)</p>
<p>TclOO classes as commands produce instance objects with <code>create</code> or <code>new</code>. As a convenience <em>oowebtools</em> has a namespace <code>Tag</code> with commands having the names of tag classes plus a trailing colon. Thus <code>Tag::A:</code> is a command that calls <code>A new</code>. In practice the Tag namespace exports its command names and these are imported into the tag class files.</p>
<p>The toolkit then works as follows: tag classes are defined in toolkit files. When these files are sourced (via <code>package require oowebtools</code>) class objects (e.g., Html, etc.) are created. Class objects are commands which in turn create instance objects that are commands in their own right. Instance commands call methods as defined in the class which do the actual work. Here are 4 instance commands calling &quot;write&quot;— all produce the same output:</p>
<pre><code>package require oowebtools

Html create html0        ; html0 write
Html new (-&gt; oo::Obj127) ; oo::Obj127 write
set html0 [Html new]     ; $html0 write
set html1 [Html: ]       ; $html1 write
</code></pre>
<p>If it helps understanding, an instance object/command calling methods is analagous to a <em>namespace ensemble</em>, that is, a command with subcommands. One opinion is the that the class/object structure is easier to organize and more versatile.</p>
<h2 id="installation"><strong>Installation</strong></h2>
<p>Installing <em>oowebtools</em> is simple. It's only necessary to copy the &quot;oowebtools&quot; directory to a location on Tcl package path. A typical location is /usr/local/lib or /usr/lib. Developers often have multiple Tcl binaries in separate directories, each with its own ./lib. In this case, placing a copy of oowebtools in the &quot;lib&quot; directories enables using with the particular versions of Tcl.</p>
<p>The files in directories css, js, db, util will need to be copies to a directory in the target HTML hierarchy whether in development or final versions. Of course in a particular case not everything in these directories will be needed.</p>
<h3 id="dependencies"><strong>Dependencies</strong></h3>
<p>The toolkit has these requirements:</p>
<ul>
<li>The <em>nxproc</em> extension, v1.0 or newer</li>
<li>Tcllib v2.0 or newer</li>
<li>sqlite3 v3.39 or newer</li>
</ul>
<p>These are available from the following sources:</p>
<ul>
<li>nxproc
<ul>
<li>https://thinairarts.com/fossil/nxproc/download</li>
</ul>
</li>
<li>tcllib2.0
<ul>
<li>https://www.tcl3d.org/bawt/download/Preview/Tcl9/tcllib-2.0.7z</li>
</ul>
</li>
<li>sqlite3
<ul>
<li>https://www.tcl3d.org/bawt/download/InputLibs/sqlite3-3.39.4.7z (This version is older than current but will still work.)</li>
<li>http://prdownloads.sourceforge.net/tcl/tcl9.0b1-src.tar.gz (Source release, requires compiling but that's not difficult. Distribution includes current version of sqlite3. It's compiled seamlessly with Tcl. No extra effort is required.)</li>
</ul>
</li>
</ul>
<p>Obtaining/installing these dependencies is straighforward and mostly painless. Once accomplished install oowebtools per above.</p>
<h2 id="using-component-classes-and-utilities"><strong>Using component classes and utilities</strong></h2>
<h3 id="element-derived-class-constructors"><strong><em>Element</em>-derived class constructors</strong></h3>
<p><strong>Description of class object constructors.</strong> HTML tag class constructors are written using <em>nxconstructor</em> from the <em>nxproc</em> package. These constructors use the same basic patterns to initialize object instances. The basic syntax is generic:</p>
<pre><code>&lt;Tagname&gt;(:| new) ?positional_args? \
    ?-option ?value? ...? --&gt; \
    ?{attribute value...}? ?{text|element list}?
</code></pre>
<p><em>Tagname</em> always starts with an upper case letter, followed by ' new' or its abbreviation, a colon.</p>
<p>There can be 0 or more positional/fixed args. Those without default values require a value entered on the command line.</p>
<p>There can be 0 or more named args. These are entered on the command line as ''-option value'' except for boolean types—the option alone toggles the default value. In most cases named arguments are attributes to be appended to the Attribute list for the entity.</p>
<p>Most tags classes are further configured by the ''end of argument'' symbol, <span style="display:inline-block;"><code>--&gt;</code>,</span> followed by one or two lists, an attribute list and/or a text string or list of tag objects.</p>
<p>An attribute list looks like <code>{class main id main ...}</code>. Element lists can be generated by using <code>[list ...]</code>, or <code>[subst {...}]</code>. The latter is often less confusing so that style is recommended. In any case everything following <span style="display:inline-block;"><code>--&gt;</code>,</span> is collected in the <code>nxargs</code> variable. <code>nxargs</code> is used in the <code>next</code> command to pass info to the superclass constructor.</p>
<pre><code>next ... --&gt; {*}$nxargs
</code></pre>
<p><em>Element</em> has several named args, including the all-important <code>-tag</code> and <code>-endtag</code>.</p>
<pre><code>next -tag div -endtag 1 --&gt; {*}$nxargs 
</code></pre>
<p><em>nxcontructor</em> defines another args-like variable, <code>nxunknown</code> which collects anything on the command line (before <code>--&gt;</code>) not previously defined. It is also passed to the superclass constructor.</p>
<pre><code>next -tag div -endtag 1 {*}$nxunknown --&gt; {*}$nxargs 
</code></pre>
<p>If the tag constructor has named arguments for configuring attributes, the associated variable are used after the next command.</p>
<pre><code>nxconstructor {-class &quot;&quot; -id &quot;&quot;} {
    my variable Attributes
    ...
    next ...
    lappend Attributes class $class id $id
}
</code></pre>
<p>Naturally there are variations on the above. Questions are ultimately resolved by the source code for a particular class.</p>
<p>When <em>oowebtools</em> is loaded all files are <code>source</code>'d which creates a class object for each toolkit entity. Class objects are used to create instance objects which call methods to render expected HTML output.</p>
<p>The syntax of <em>Element</em>-derived classes was described above.</p>
<h3 id="non-element-derived-classes"><strong>Non-<em>Element</em>-derived classes</strong></h3>
<p>This section attempts to describe the syntax of composite class objects not derived (or partially derived) from <em>Element</em>.</p>
<p>To be completed…</p>

</body>
</html>
