The Metamark system is a flexible way to permit one source document to represent many versions. A book source can be translated to Latex chapters or interlinked HTML sections. A C program source can be translated to versions that compile with various C compilers as well as an annotated HTML version that spans multiple web pages.
Since I figured there would be rather long stretches of text without markup commands, my language had only four symbols that caused the translator to hiccup and take closer notice: "+", "-", "{", and "}". I choose the syntax to be less "in my face" than SGML based syntaxes are. For example, +/l{hi} for <i>hi</i>.
I implemented that markup language in Perl. "Tcl/Tk for Programmers" was written in it. It produced a Latex version that was edited by a Latex expert to produce the publisher's page masters. It also produced an HTML version, 25% of which can be found at the book's home page ( "Tcl/Tk for Programmers"). I called this markup language the "HL" markup language.
After that book was finished, I began to think about adaptations to the HL markup language that would have made life easier for the layout editor as well as for future projects requiring different markup languages. These thoughts lead to my Metamark system which I implemented in Tcl/Tk and describe here. The Metamark system separated markup language definition from the languager parser and from any language translator. In short it enabled the creation of different markup languages with the same syntax and with multiple targets.
Then, I used Metamark to create a Tcl-extension markup language, the purpose of which was to speed up the creation of extensions to Tcl. The products of the Tcl-extension markup language are of two kinds: C source code and HTML documentation. The C source code can be produced in different versions for use with C/C++ translators on different platforms. The Tcl-extension markup language put me into a position where I could quickly create Tcl extensions that compile in different environments and are self-documenting.
+/command nameCommand names consist of alphameric characters and are not expected to be long. Optionally, commands may be followed by arguments as in-/command name
+/command name{argument}Seven Metamark commands are built in. Particular markup languages in the Metamark system do not differ in overall syntax rules or these seven built-in commands. They get their distinct features from other markup commands and from the translations that are assigned to these other commands. Command names, types, and number of parameters are described in a syntax file and command translations are described in a translator file. Both the syntax file and the translator file must be written in Tcl.-/command name{argument}
Each document is written for a particular markup language. That markup language is identified by putting
+/lang{name of syntax file}at the beginning of the document. The Metamark system will run with a syntax file and no translator file. In that mode, it merely checks the document for syntax. When starting new projects I have begun writing documents before I have completed a translator file.
The kind of translation you want for a document can be ensured with a translator file. For a given Metamark language there may be more than one of these. Passing a translator file name along with a document name to the Metamark system will determine the kind of translation that is performed. For example, a markup language for C programs can have translator files that produce platform specific code.
Lets consider such a markup language, the one I created for making Tcl extensions. That language has a command
+/procfor marking the names of those C functions that will be executed from Tcl. The command might be used this way
+/proc{advanceChar}{}There is no prototype or other form of declaration needed for advanceChar. The effect of what you see above is to generate boilerplate code (in different places of the target document) which fills out the necessary C declarations and also invokes the functions from Tcl's API for linking the advanceChar function to Tcl's run-time system.code for the advanceChar function goes here+/end
Moreover, the boilerplate generated by this system is context dependent. It will be done one way if +/proc appears between +/class and -/class and object commands and another way if +/proc appears between +/object and -/object. (Here "class" and "object" have meanings very similar to those you are used to with object oriented languages. To understand the exact meanings in the context of Tcl, think of the difference in Tk between a button command and a .button1 configure command.)
I wrote translator files for three C compilers. This is much cleaner than the usual way of generating platform dependent code with macros because the source code is not burdened with the various alternatives. Duplicate code witin these three translator backends is avoided because the Metamark system permits one backend to inherit from another.
A final feature of Metamark is that it enables you to define a filter function. A filter is applied to all parts of a document that are not part of a markup command. Of course, you do not need to use this feature; a default filter function leaves all document text unfiltered. For the Tcl-extension example, the translators that produce C code use the default filter but the translators which produce HTML, make alterations so text characters that might otherwise begin HTML commands are not perceived by the browser to do so.
To show how a Metamark language appears to the user, here's the original marked up C code which was the original document for a Tcl extension. The Metamark system produced this annotated HTML listing as well as separate unannotated versions that compile with gcc, Borland, and Microsoft C/C++ compilers.