You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tcl.apache.org by mx...@apache.org on 2018/09/10 16:03:02 UTC

[tcl-rivet] 04/04: changing the ::rivet::xml form to enable selfclosing elements generation

This is an automated email from the ASF dual-hosted git repository.

mxmanghi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tcl-rivet.git

commit b604e3d8654e5d8546a285f569584c748e8de0ff
Author: Massimo Manghi <mx...@apache.org>
AuthorDate: Mon Sep 10 18:02:33 2018 +0200

    changing the ::rivet::xml form to enable selfclosing elements generation
---
 ChangeLog               |  7 +++--
 doc/xml/commands.xml    | 21 +++++++++++++--
 doc/xml/processing.xml  |  3 +--
 rivet/rivet-tcl/xml.tcl | 71 ++++++++++++++++++++++++++++++++++++-------------
 tests/commands.tcl      | 13 +++++++--
 tests/commands.test     |  9 ++++---
 tests/inspect.test      |  6 ++---
 7 files changed, 96 insertions(+), 34 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 18ff09a..4eb6808 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,9 @@
 2018-08-16 Massimo Manghi <mx...@apache.org>
-    * rivet/rivet-tcl/xml.tcl: now printing XML elements such as
-    <tag attr1="val1" attr2="val2".... /> if the text string is empty
+    * rivet/rivet-tcl/xml.tcl: changing form to support single self
+    closing XML elements such as <tag attr1="val1" attr2="val2".... /> 
+    when if the text string is empty
+    * tests/commands.tcl: changing ::rivet::xml test accordingly
+    * doc/xml/commands.xml: documenting new ::rivet::xml feature
 
 2018-08-07 Massimo Manghi <mx...@apache.org>
     * VERSION,configure.ac: first commit after svn to git migration.
diff --git a/doc/xml/commands.xml b/doc/xml/commands.xml
index 60dcfd1..09a237e 100644
--- a/doc/xml/commands.xml
+++ b/doc/xml/commands.xml
@@ -2,7 +2,7 @@
 	<title>Rivet Tcl Commands and Variables</title>
 	<section>
 		<para>
-			Starting with version 2.1.0 Rivet command set moved into the 
+			Starting with version 2.1.0 the Rivet command set moved into the 
 			<command>::rivet</command> namespace.
 		</para>
 		<para>
@@ -2111,12 +2111,29 @@ form_request end</programlisting>
             <programlisting>::rivet::xml "a string" b u
 &lt;== &lt;b&gt;&lt;u&gt;a string&lt;/u&gt;&lt;/b&gt;</programlisting>
             <para>
-                You can tell the tags which attributes they must have
+                You can specify the tags attributes by replacing a tag specification
+                with a odd-length list containing the tag name and a series of
+                attribute-value pairs
             </para>
             <programlisting><command>::rivet::xml "a string" [list div class box id testbox] b i</command>
 &lt;== &lt;div class=&quot;box&quot; id=&quot;testbox&quot;&gt;&lt;b&gt;&lt;i&gt;a string&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;</programlisting>
             <programlisting><command>::rivet::xml "text to be wrapped in XML" div [list a href "http://..../" title "info message"]</command> 
 &lt;== &lt;div&gt;&lt;a href=&quot;http://..../&quot; title=&quot;info message&quot;&gt;text to be wrapped in XML&lt;/a&gt;&lt;/div&gt;</programlisting>  
+				<para>
+					A single argument is interpreted as a list of tag name and attributes to be 
+					coded as a self closing element
+				</para>
+				<programlisting><command>::rivet::xml [list b a1 v1 a2 v2]</command>
+&lt;== &lt;b a1=&quot;v1&quot; a2=&quot;v2&quot; /&gt;</programlisting>
+				<para>
+					Unless the string is literally an empty string
+				</para>
+				<programlisting><command>::rivet::xml "" [list b a1 v1 a2 v2]</command>
+&lt;== &lt;b a1=&quot;v1&quot; a2=&quot;v2&quot;&gt;/b&gt;</programlisting>
+				<para>which is useful for generating 'script' elements in an HTML page header that wouldn't be understood 
+				as such</para>
+				<programlisting><command>::rivet::xml "" [list script type "text/javascript" src js/myscripts.js]</command>
+&lt;== &lt;script type=&quot;text/javascript&quot; src=&quot;js/myscripts.js&quot;&gt;&lt;/script&gt;</programlisting>
        </refsect1>
     </refentry>
 </section>
diff --git a/doc/xml/processing.xml b/doc/xml/processing.xml
index a96aae5..763e922 100644
--- a/doc/xml/processing.xml
+++ b/doc/xml/processing.xml
@@ -49,8 +49,7 @@
 			and any code interruption brought about by calling 
 			<command>::rivet::abort_page</command>.
 			The current procedure might work as a template to be
-			reworked and used as a template to develop your own
-			request handler.
+			reworked into your own request handler.
 		</note>
 	</section>
 	
diff --git a/rivet/rivet-tcl/xml.tcl b/rivet/rivet-tcl/xml.tcl
index cb18c04..13a2d1b 100644
--- a/rivet/rivet-tcl/xml.tcl
+++ b/rivet/rivet-tcl/xml.tcl
@@ -1,13 +1,25 @@
 #
-# xml.tcl string ?tag ?attr val? ?attr val?? ?tag ?attr val? ?attr val??
+# xml.tcl --
+#
+# Syntax:
+#
+#       ::rivet::xml string ?tag ?attr val? ?attr val?? ?tag ?attr val? ?attr val??
+#
+# or
+#
+#       ::rivet::xml ?tag ?attr val? ?attr val??
 #
 # Example 1:
 #
+# trivial nested markup fragment
+#
 #  ::rivet::xml Test b i 
 # <= <b><i>Test</i></b>
 #  
 # Example 2:
 #
+# XHTML Element with attributes
+#
 # ::rivet::xml Test [list div class box id testbox] b i
 # <= <div class="box" id="testbox"><b><i>Test</i></b></div>
 #
@@ -19,28 +31,47 @@
 # Example 4
 #
 # ::rivet::xml "" [list a attr1 val1 attr2 val2] [list b attr1 val1 attr2 val2]
-# <= <a attr1="val1" attr2="val2"><b attr1="val1" attr2="val2"/></a>
+# <= <a attr1="val1" attr2="val2"><b attr1="val1" attr2="val2"></b></a>
+#
+# Example 5
+#
+# single self closing element
+#
+# ::rivet::xml [list a attr1 val1 attr2 val2]
+# <= <a attr1="val1" attr2="val2" />
 #
 
 namespace eval ::rivet {
 
     proc xml {textstring args} {
 
-        set xmlout      ""
-        set tags_stack  {}
+        set single_element [::rivet::lempty $args]
+        if {$single_element} {
+
+            set tags_list   [list $textstring]
+
+            if {[::rivet::lempty $tags_list]} { return "" }
 
-        foreach el $args {
+        } else {
+
+            set tags_list $args
+
+        }
+
+        set tags_stack  {}
+        set el          {}
+        set xmlout      ""
+        foreach el $tags_list {
 
             set el  [lassign $el tag]
             lappend tags_stack $tag
-            append xmlout "<$tag"
+            append  xmlout "<$tag"
 
             foreach {attrib attrib_v} $el {
                 append xmlout " $attrib=\"$attrib_v\""
             }
 
             append xmlout ">"
-            set last_elem_attr $el
         }
 
 
@@ -48,24 +79,26 @@ namespace eval ::rivet {
 
             return $textstring
 
-        } else {
+        } elseif {$single_element} {
 
-            if {$textstring == ""} {
+            # variable 'el' keeps the last (innermost) attribute-value list
 
-                if {[llength $last_elem_attr]} { 
-                    set closing_seq "/>"
-                } else {
-                    set closing_seq " />"
-                }
-                set xmlout [string replace $xmlout end end $closing_seq]
-                if {[llength $tags_stack] > 1} {
-                    set xmlout [append xmlout "</[join [lreverse [lrange $tags_stack 0 end-1]] "></"]>"]
-                }
-                return $xmlout
+            if {[::rivet::lempty $el] == 1} {
+                set xmlout [string replace $xmlout end end " />"]
+            } else {
+                set xmlout [string replace $xmlout end end "/>"]
+            }
 
+            if {[llength $tags_stack] > 1} {
+                set xmlout [append xmlout "</[join [lreverse [lrange $tags_stack 0 end-1]] "></"]>"]
             }
+            return $xmlout
+
+        } else {
+
             return [append xmlout "$textstring</[join [lreverse $tags_stack] "></"]>"]
 
         }
     }
+
 }
diff --git a/tests/commands.tcl b/tests/commands.tcl
index 265ab96..8165ee0 100644
--- a/tests/commands.tcl
+++ b/tests/commands.tcl
@@ -10,9 +10,18 @@ if {[::rivet::var exists cmd]} {
     set cmd [::rivet::var get cmd]
     switch $cmd {
         xml {
-            puts [::rivet::xml "" a [list b a1 v1 a2 v2] [list c a1 v1 a2 v2]]
+
+            # generic ::rivet::xml usage
+
+            puts [::rivet::xml "a text string" a [list b a1 v1 a2 v2] [list c a1 v1 a2 v2]]
+            puts [::rivet::xml "a text string" [list b a1 v1 a2 v2] [list c a1 v1 a2 v2] a]
+
             puts [::rivet::xml "" [list b a1 v1 a2 v2] [list c a1 v1 a2 v2] a]
-            puts -nonewline [::rivet::xml "element text" a [list b a1 v1 a2 v2] [list c a1 v1 a2 v2]]
+
+            # self closing single element
+
+            puts [::rivet::xml [list a a1 v1 a2 v2]]
+            puts -nonewline [::rivet::xml p]
         }
         default {
             puts "invalid argument '$cmd'"
diff --git a/tests/commands.test b/tests/commands.test
index 2a5c1a1..bbee9bd 100644
--- a/tests/commands.test
+++ b/tests/commands.test
@@ -9,7 +9,8 @@
 ::tcltest::test tcl-xml-1.1 {::rivet::xml command} {
     set page [::http::geturl "${urlbase}commands.tcl?cmd=xml"]
     ::http::data $page
-} {<a><b a1="v1" a2="v2"><c a1="v1" a2="v2"/></b></a>
-<b a1="v1" a2="v2"><c a1="v1" a2="v2"><a /></c></b>
-<a><b a1="v1" a2="v2"><c a1="v1" a2="v2">element text</c></b></a>}
-
+} {<a><b a1="v1" a2="v2"><c a1="v1" a2="v2">a text string</c></b></a>
+<b a1="v1" a2="v2"><c a1="v1" a2="v2"><a>a text string</a></c></b>
+<b a1="v1" a2="v2"><c a1="v1" a2="v2"><a></a></c></b>
+<a a1="v1" a2="v2"/>
+<p />}
diff --git a/tests/inspect.test b/tests/inspect.test
index b8dd7cd..4268729 100644
--- a/tests/inspect.test
+++ b/tests/inspect.test
@@ -1,5 +1,5 @@
 
-::tcltest::test inspect-1.1 {basic introspection } {
+::tcltest::test inspect-1.1 {basic introspection 1.1} {
     apachetest::start { 
             -c "RivetServerConf ChildInitScript \"set init 1\"" } {} {
         catch {
@@ -11,7 +11,7 @@
     set match
 } {set init 1}
 
-::tcltest::test inspect-1.2 {basic introspection} {
+::tcltest::test inspect-1.2 {basic introspection 1.2} {
     apachetest::start { 
             -c "RivetServerConf ChildInitScript \"set init 1\"" } {} {
         catch {
@@ -23,7 +23,7 @@
     set match
 } {server {ChildInitScript {set init 1}}}
 
-::tcltest::test inspect-1.3 {basic introspection} {
+::tcltest::test inspect-1.3 {basic introspection 1.3} {
     file copy -force inspect.tcl /tmp/
     apachetest::start {
         -c "DocumentRoot /tmp" } {} {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tcl.apache.org
For additional commands, e-mail: commits-help@tcl.apache.org