Short Markup Language update

Martin Klang <[email protected]> Sun, 28 May 2006 02:25:25 +0100
Newsgroups gmane.text.xml.o-xml
Message-ID <[email protected]>
Hello all,

I've been doing some work on the SML project lately and thought I'd  
post an update.

For those of you who don't already know, SML is a simple XML  
shorthand notation which allows you to write and edit XML without  
some of the unnecessary verbosity. There's some background info on  
the project page:
http://www.o-xml.org/projects/sml.html

However that page doesn't (yet) cover the most interesting part,  
which is the macro feature. The shorthand notation is useful in its  
own right, but XML vocabularies still turn out a lot more verbose  
than their keyword-based equivalents.
Enter macros. In the SML context, this simply means a way of  
rewriting a sequence of names and values into a longer XML equivalent.

As you might have guessed, one of the first goals of SML is to  
provide a short, simple notation for o:XML that looks more like  
traditional languages. Using SML with macros, you can now write a  
function declaration like this:

o:function public String foo(Node bar, Node baz){
	o:do {
		o:return "concat($bar, $baz)";
	}
}

which would be parsed and translated to:

<o:function name="foo" type="String" access="public">
	<o:param name="bar" type="Node"/>
	<o:param name="bar" type="Node"/>
	<o:do>
		<o:return select="concat($bar, $baz)"/>
	</o:do>
</o:function>

The macro itself is defined using SML markup, which looks like this:

   <sml:macro name="function">
     <sml:element name="function">
       <sml:attribute name="name" position="last" use="required"/>
       <sml:attribute name="access" use="optional">
         <sml:value>public</sml:value>
         <sml:value>protected</sml:value>
         <sml:value>private</sml:value>
       </sml:attribute>
       <sml:attribute name="type" use="optional"/>
       <sml:part min="0" max="unbounded">
         <sml:element name="param">
           <sml:attribute name="name" position="last" use="required"/>
           <sml:attribute name="type" use="optional"/>
         </sml:element>
       </sml:part>
     </sml:element>
   </sml:macro>

So how does this work?

Well the SML Parser treats any sequence of names and values that  
doesn't look like an element as a macro, and will invoke the matching  
macro handler. This is how the o:return macro is recognised.
Furthermore any sequence that contains a parenthesised list will also  
be treated as a macro, so that you can macro-expand eg:
o:while("$i < 10"){}

The macro definition says what values to turn into specific elements  
and attributes. The definition is automatically converted to Java  
code, which is then plugged into the SML parser. The parser itself is  
a SAX XMLReader that produces plain XML events (there's also a DOM  
DocumentBuilder available).
Since the parser is extensible with new macrohandlers, using your own  
macros is very simple.

I've also started work on an extensible SAX ContentHandler which will  
serialise XML as SML, using the defined macro conversions 'in reverse'.

The last release of ObjectBox included an SML parser but without the  
macros. Next version will include o:XML macros, and maybe doc and  
unit-test macros too if I have the time to write them.

You can also download and use the SML tools on their own, even write  
up some macros (XSLT anyone?). Let me know if you want instructions  
or help.
I'll post a release on freshmeat shortly, meanwhile you can access  
CVS as usual:
http://cvs.pingdynasty.com/viewcvs/sml/

have fun!

/m