EVOLUTION-MANAGER
Edit File: literate.xml
<?xml version="1.0"?> <!DOCTYPE literate SYSTEM "literate.dtd" [ <!ENTITY % forS "INCLUDE"> <!ENTITY % forR "IGNORE"> ]> <literate> <doc> This document is a very early attempt to illustrate how we might use XML for "literate programming" with the S language. The idea is that we write code to be read by ahuman rather than the machine, but that in the process, we also generate the code. The goal is to develop more readable, understandable and hence maintainable and useful code. The topic was pionereed by Donald Knuth and there are various pieces of software that do it in different format. XML is a rather natural form. See also <a href="http://www.oasis-open.org/cover/xmlLitProg.html">Oasis-open</a> <P /> There are numerous practical benefits associated with using literate programming techniques. For one, it is easy to comment out code while still leaving it in the source. It is also easy to have two pieces of similar code and swap them when experimenting with some modifications. Also, it is easy to reuse a block of code without having to play pre-processor tricks. <P/> In this example, we are going to mix programming languages within the same file. We will write an S-language (meaning both SPlus and R and from here on, simply referred to as S) function which calls a C routine to perform the computation. The function is uninteresting and simply computes the process identifier of the R session. It calls the C function <croutine>getpid</croutine> to do this. </doc> <function language="R"> <doc> The function takes no arguments and returns a numeric vector of length 1. </doc> <![CDATA[ getpid <- function() { .Call("RS_getpid") } ]]> </function> <code language="C"> <a href="includes" /> <a href="RS_getpid" /> </code> <doc> The <croutine>getpid</croutine> is declared in the <file>unistd.h</file> header file. So we include it here. </doc> <code name="includes"> <![CDATA[ #include <unistd.h> ]]> </code> <code name="includes"> <![CDATA[ #include <Rinternals.h> ]]> </code> <code language="C"> USER_OBJECT_ RS_getpid() { USER_OBEJCT_ ans; pid_t id; id = getpid(); NEW_NUMERIC(1); NUMERIC_DATA(ans)[0] = id; return(id); } </code> <function language="R"> <doc> This is gratuitous text. </doc> while(T) { <a href="iterate" /> } </function> <doc> Note how we use the <b>sgets</b> entity here to avoid having to use a CDATA construct to escape the text. </doc> <code id="iterate"> if(x > 10) break else x %sgets; rnorm(9) </code> <doc> What we are trying to do here is produce elements that are processed conditionally. It appears that INCLUDE and IGNORE directives have to be within DTDs. (Is this true?) Hence we escape them here. </doc> <code> <![CDATA[ <![ %forS [ x = y@slot ] ]> <![ %forR [ x <- y$slot ] ]> ]]> </code> </literate>