Posted to tcl by oldlaptop at Fri May 23 23:40:26 GMT 2025view pretty

I don't really have much of a clue what I'm doing with TMML as yet. I also question whether this might be a bit too exhaustively detailed (especially LIMITS - those won't change automatically when the corresponding #defines/magic numbers change, even supposing I have them right. :)).

Index: doc/domNode.xml
==================================================================
--- doc/domNode.xml
+++ doc/domNode.xml
@@ -701,10 +701,11 @@
     <ref>domDoc</ref>
   </seealso>
   
   <keywords>
     <keyword>XML</keyword>
+    <keyword>XPath</keyword>
     <keyword>DOM</keyword>
     <keyword>document</keyword>
     <keyword>node</keyword>
     <keyword>parsing</keyword>
   </keywords>

Index: doc/tDOM.xml
==================================================================
--- doc/tDOM.xml
+++ doc/tDOM.xml
@@ -1,9 +1,10 @@
 <!DOCTYPE manual PUBLIC "-//jenglish//DTD TMML 0.5//EN" "tmml.dtd" [
 <!ENTITY dom SYSTEM "dom.xml">
 <!ENTITY domDoc SYSTEM "domDoc.xml">
 <!ENTITY domNode SYSTEM "domNode.xml">
+<!ENTITY xpathFunc SYSTEM "xpathFunc.xml">
 <!ENTITY expat SYSTEM "expat.xml">
 <!ENTITY expatapi SYSTEM "expatapi.xml">
 <!ENTITY pullparser SYSTEM "pullparser.xml">
 <!ENTITY schema SYSTEM "schema.xml">
 <!ENTITY tdomcmd SYSTEM "tdomcmd.xml">
@@ -15,10 +16,12 @@
 &dom;
 
 &domDoc;
 
 &domNode;
+
+&xpathFunc;
 
 &expat;
 
 &expatapi;
 

ADDED    doc/xpathFunc.xml
Index: doc/xpathFunc.xml
==================================================================
--- /dev/null
+++ doc/xpathFunc.xml
@@ -0,0 +1,150 @@
+<manpage id="xpathFunc" title="xpathFunc" cat="misc">
+  <namesection>
+    <name>::dom::xpathFunc</name>
+    <desc>Scripted XPath functions</desc>
+  </namesection>
+
+  <synopsis>
+    <syntax>::dom::xpathFunc::<m>funcName</m> <m>ctxNode</m> <m>pos</m> <m>nodeListType</m> <m>nodeList</m> ?<m>type arg type arg...</m>?
+::dom::xpathFunc::<m>namespaceURL</m>::<m>funcName</m> <m>ctxNode</m> <m>pos</m> <m>nodeListType</m> <m>nodeList</m> ?<m>type arg type arg...</m>?</syntax>
+  </synopsis>
+
+  <section>
+    <title>DESCRIPTION</title>
+    <p>
+      tDOM's XPath engine supports custom XPath functions implemented by Tcl
+      commands. When it encounters a function call to an unknown function name
+      without a namespace qualifier, the XPath engine looks for a Tcl command of
+      the same name in the <l>::dom::xpathFunc</l> namespace. If it encounters
+      an unknown namespace-qualified function call, it looks for a Tcl namespace
+      with a name equal to the function's full namespace URI inside
+      <l>::dom::xpathFunc</l>, and a Tcl command named for the local part of the
+      function's name inside that namespace. If it finds such a Tcl command, it
+      is executed with at least the following arguments, to describe the current
+      XPath context:
+    </p>
+
+    <dl>
+      <dle>
+        <dt>ctxNode</dt>
+        <dd>The <l>domNode</l> object command of the XPath context node.</dd>
+      </dle>
+      <dle>
+        <dt>pos</dt>
+        <dd>
+          The XPath context position, in zero-based form - that is, the return
+          value of the standard XPath <l>position()</l> function in the context
+          would be <l>$pos - 1</l>.
+        </dd>
+      </dle>
+      <dle>
+        <dt>nodeListType</dt>
+        <dd>
+          The type name for <m>nodeList</m>, as for the
+          <method>selectNodes</method> method's <m>typeVar</m>.
+        </dd>
+      </dle>
+      <dle>
+        <dt>nodeList</dt>
+        <dd>
+          A list of the <l>domNode</l> object commands of the context node and
+          all of its siblings, in document order. <m>ctxNode</m> will be equal
+          to <l>[lindex $nodeList $pos]</l>.
+        </dd>
+      </dle>
+    </dl>
+
+    <p>
+      If the function call includes any arguments, two arguments will be
+      appended to the command's argument list for each one:
+    </p>
+    <dl>
+      <dle>
+        <dt>type</dt>
+        <dd>
+          The argument's type name, as for <method>selectNodes</method>'s
+          <m>typeVar</m>.
+        </dd>
+      </dle>
+      <dle>
+        <dt>val</dt>
+        <dd>
+          The argument's value, as <method>selectNodes</method> would return
+          it in an XPath expression's result set.
+        </dd>
+      </dle>
+    </dl>
+
+    <p>
+      The command is required to return a 1- or 2-element Tcl list to provide
+      the result of the XPath function call. If the result list has two
+      elements, the first is the result's XPath type name, and the second is an
+      appropriately encoded value (note that the <m>attrnodes</m> type name is
+      not supported):
+    </p>
+    <dl>
+      <dle>
+        <dt>bool</dt>
+        <dd>Tcl boolean value acceptable to <fun>Tcl_GetBooleanFromObj</fun>.</dd>
+      </dle>
+      <dle>
+        <dt>number</dt>
+        <dd>
+          Tcl numeric value acceptable to <fun>Tcl_GetSizeIntFromObj</fun> or
+          <fun>Tcl_GetDoubleFromObj</fun>.
+        </dd>
+      </dle>
+      <dle>
+        <dt>string</dt><dd>Simple string.</dd>
+      </dle>
+      <dle>
+        <dt>nodes</dt><dd>Tcl list of <l>domNode</l> object commands.</dd>
+      </dle>
+      <dle>
+        <dt>attrvalues</dt><dd>Alias for <m>string</m>.</dd>
+      </dle>
+    </dl>
+    <p>
+      If the result list has only one element, it is treated as a simple string.
+      It is an error for the result to have zero elements, more than two
+      elements, or to be invalid as a Tcl list, and it is an error if the
+      <m>val</m> of a two-part result does not match the requirements described
+      above for its <m>type</m>.
+    </p>
+  </section>
+
+  <section>
+    <title>EXAMPLES</title>
+    <p>
+      A simple workalike for the XPath 2/3 <l>fn:matches()</l> function, not
+      otherwise available in an XPath 1.0 engine such as tDOM's:
+    </p>
+    <example>proc ::dom::xpathFunc::regmatch {
+    ctxNode pos nodeListType nodeList
+    inputType inputVal patternType patternVal
+} {
+    set input [::dom::xpathFuncHelper::coerce2string $inputType $inputVal]
+    set pattern [::dom::xpathFuncHelper::coerce2string $patternType $patternVal]
+    return [list bool [regexp $pattern $input]]
+}</example>
+  </section>
+
+  <section>
+    <title>LIMITS</title>
+    <p>
+      Function names are limited to 200 characters, including any namespace URI
+      and the <l>::</l> Tcl namespace separator between it and the local part.
+      Function calls may have a maximum of 20 arguments. Tcl commands created
+      with the deprecated <fun>Tcl_CreateCommand</fun> interface cannot be used
+      as scripted XPath functions.
+    </p>
+  </section>
+
+  <seealso>
+    <ref>domNode</ref>
+  </seealso>
+
+  <keywords>
+    <keyword>XPath</keyword>
+  </keywords>
+</manpage>