Hello all; As you might have noticed if you read the IRC log between Jean-Marc and I yesterday, I promised that I would try and draw up XML descriptions for nodes in piper, so here is my first attempt at that. I've included a few xml files and the dtd describing the general format below, along with comments along the way. I hope I am making some sense with this... Please ask questions and I can try to expand on anything that is confusing. Thanks much! Brad The biggest thing to note is that I changed the name "node" to now be "locus". The reason I did this is that node just conflicts too much with DOM, and it makes things confusing, in my opinion. I know that "locus" might not be that descriptive to start with, but at least it is unambiguous when you see it, unlike node (or pnode or piper_node or whatever). Other suggestions for names are always welcome :-). Below is the description of a locus constant (Constant.cc from the Overflow code). <!--Constant.xml Locus type describing a constant value. --> <!DOCTYPE piperplugin SYSTEM "piperplugin.dtd"> <piperplugin> <module name = "General"> <locus name = "Constant"> <parameter name = "constant_value" type = "ANY" /> <output name = "output_constant" type = "ANY" /> </locus> </module> </piperplugin> This is a description of a bit more complicated locus that executes a command line and returns the results. <!-- NetExec.xml Locus capable of executing a commandline argument and returning the results and status. --> <!DOCTYPE piperplugin SYSTEM "piperplugin.dtd"> <piperplugin> <module name = "IO"> <locus name = "NetExec"> <input name = "command" type = "STRING" /> <input name = "arguments" type = "STRING" /> <output name = "command_output" type = "STRING" /> <output name = "command_status" type = "STRING" /> <description> Execute an argument on the command line and return the results and status. </description> </locus> </module> </piperplugin> Below is how you could use these two basic locus types to create a locus describing 'ls -l.' The biggest change over how Overflow does things is that I use the concepts of xlink's exensively. Xlink (http://www.w3.org/TR/2000/WD-xlink-20000221/) is the XML specification for relating two documents. The big advantage of doing things this way is that a locus like still contains all the information about how it was constructed, so we could "reverse construct" a created node to its individual parts, so it could be modified. The basic idea behind how the xlink stuff will work is that the 'xlink:href' would suck in another xml document, and the xlink:to stuff would make substitutions in the xml file. I _think_ this will work and this seems like the "good official" way to do it. <!--ls.xml The ls command represented as a piper plugin. This is the representation of how 'ls -l' would look. --> <!DOCTYPE piperplugin SYSTEM "piperplugin.dtd"> <piperplugin> <module name = "unix"> <module name = "utilities"> <locus name = "ls"> <plugin_link xlink:href = "IO/NetExec.xml"> <connect xlink:to = "command" xlink:from ="ls_name"/> <connect xlink:to = "arguments" xlink:from = "ls_options"/> </plugin_link> <plugin_link name = "ls_name" xlink:href = "General/Constant.xml"> <substitute xlink:to = "constant_value" value = "ls"/> </plugin_link> <plugin_link name = "ls_options" xlink:href = "General/Constant.xml"> <substitute xlink:to = "constant_value" value = "-l"/> </plugin_link> <description> ls -l List the long contents of the current directory. </description> </locus> </module> </module> </piperplugin> One thing that Jean-Marc mentioned is handling nodes that can have a variable number of inputs. The way I thought to handle this was to add an attribute called "expand" to the <input>, <output> and <parameter> tags. This attribute is set at "no" by default, but if it set at "yes," then this will tell Piper that it can add new tags of this type on demand by the user. So this would mean that if someone was dealing with the Mux locus in the user interface, they could select an option like "add input" on the the choices input, and could do this, while they would get an error if they tried to do the same thing on the "switch" input. <!-- Mux.xml A multiplexer, like a switch statment, that selects one input from multiple inputs. --> <!DOCTYPE piperplugin SYSTEM "piperplugin.dtd"> <piperplugin> <module name = "Logic"> <locus name = "Mux"> <input name = "switch" type = "STRING"/> <input name = "choices" type = "ANY" expand = "yes"/> <output name = "choice_selected" type = "ANY"/> </locus> </module> </piperplugin> And finally, here is the DTD that describes the piper-plugin xml format: <!--Preliminary dtd for pluging programs in to work with piper--> <!ELEMENT piperplugin (module)> <!ELEMENT module (module | locus)> <!ATTLIST module name CDATA #REQUIRED> <!ELEMENT locus (parameter*, input*, output*, plugin_link*, description?)> <!ATTLIST locus name CDATA #REQUIRED> <!ELEMENT parameter EMPTY> <!ATTLIST parameter name ID #REQUIRED type (VALUE | STRING | LIST | ANY) #REQUIRED expand (yes | no) "no"> <!ELEMENT input EMPTY> <!ATTLIST input name ID #REQUIRED type (VALUE | STREAM | OBJECT | CONDITION | STRING | ANY) #REQUIRED expand (yes | no) "no"> <!ELEMENT output EMPTY> <!ATTLIST output name ID #REQUIRED type (VALUE | STREAM | OBJECT | CONDITION | STRING | ANY) #REQUIRED expand (yes | no) "no"> <!ELEMENT plugin_link (connect*, substitute*)> <!ATTLIST plugin_link name ID #IMPLIED xlink:type CDATA "simple" xlink:href CDATA #REQUIRED> <!ELEMENT connect EMPTY> <!ATTLIST connect xlink:to CDATA #REQUIRED xlink:from IDREF #IMPLIED value CDATA #IMPLIED> <!ELEMENT substitute EMPTY> <!ATTLIST substitute xlink:to CDATA #REQUIRED xlink:from IDREF #IMPLIED value CDATA #IMPLIED> <!ELEMENT description (#PCDATA)>