5.9 PDF Documents

One of the important uses of *Mathematica* is as an electronic format for technical documents. This derives in large part from the properties of *Mathematica* notebooks, which provide a document format that combines text, mathematics, and graphics suitable for many technical areas. It is quite possible to use a web*Mathematica* site to generate technical documents. One format that is very easy to generate is *Mathematica* notebooks, and there are a number of web*Mathematica* examples that work by returning *Mathematica* notebooks to the client. One example is Content.jsp. Using *Mathematica* notebooks has the advantage that the document can be worked on further after reaching the client. A disadvantage is that it requires the client to have access to an application that can read notebooks, such as *Mathematica* or *MathReader, *http://www.wolfram.com/products/mathreader/. Another alternative is to use PDF. This has the advantage that the vast majority of clients are set up to render PDF. This section will explore how to generate PDF documents from web*Mathematica*.

*Mathematica*, currently, does not have built-in technology for generating PDF, so external tools are required. The steps for generating PDF involve generating a *Mathematica* notebook, converting the notebook to PostScript, and converting the PostScript to PDF. These steps are discussed in the following sections.

Generating a *Mathematica* Notebook

A common way to do this involves using *Mathematica* commands for generating notebooks. A sample function is shown below (taken from the source used by Content.jsp).

MakeNotebook[] :=

UseFrontEnd[

Module[ {nb, nbobj},

nb = NotebookCreate[] ;

NotebookWrite[ nb, Cell[ "A Dynamically Created Notebook", "Title"]] ;

NotebookWrite[ nb,

Cell[ "Converted to " <> $$button, "Subtitle"]] ;

NotebookWrite[ nb, Cell[ "The date is " <> ToString[ Date[]], "Text"]] ;

nbobj = NotebookGet[ nb] ;

NotebookClose[ nb] ;

nbobj]]

This sample shows how a notebook object is created with NotebookCreate, and then how the content is added with NotebookWrite. When the notebook is complete, a *Mathematica* expression holding the notebook is obtained with NotebookGet, and this is returned. In a real life situation, the document could contain graphics, more text, and some computations. The *Mathematica* documentation has much more information on the commands for generating notebooks.

A major advantage of working with *Mathematica* notebooks like this is that they will take care of details such as font selection, graphics, and mathematics without the author having to be very involved.

Converting to PostScript

This is done quite easily with the function NotebookPrint. The following writes a PostScript representation of the notebook object into file.ps. The notebook object could be generated with the techniques in the previous section.

NotebookPrint[ nb, file.ps]

Unfortunately, in the current version of *Mathematica* (4.2), NotebookPrint does not work very satisfactorily on Windows.

Converting PostScript to PDF

There are a number of tools for converting PostScript to PDF. Two that we have experience with are ps2pdf, http://www.cs.wisc.edu/~ghost/doc/AFPL/8.00/Ps2pdf.htm, and PStill, http://www.pstill.com. These are third-party tools that are not supported by Wolfram Research, but seem to work very satisfactorily. For both of them, it is necessary to make sure they can access all the special fonts that *Mathematica* uses. The documentation for the particular converter should be studied to see how to add extra fonts, which are available in the *Mathematica* layout.

5.9.1 Creating PDF Example

This section describes an example that generates a notebook and converts it to PDF. For it to work you need to install PDF tools described in the last section. If you installed web*Mathematica* as described above, you should be able to connect to this JSP via http://localhost:8080/webMathematica/Examples/PDF/Generate.jsp. (You may have some other URL for accessing your server.) The source is in webMathematica/Examples/PDF/Generate.jsp and webMathematica/WEB-INF/Applications/ExampleUtilities/PDF.m.

First, here is the JSP source.

<form action="Generate.jsp" method="post">

This example generates a notebook, converts it to PDF and returns

the PDF.

</p>

<msp:allocateKernel>

<msp:evaluate>

If[ MSPValueQ[ $$button],

Get[ "ExampleUtilities`Content`"] ;

Get[ "ExampleUtilities`PDF`"] ;

nb = MakeNotebook[] ;

pdf = NotebookToPDF[ nb] ;

If[ StringQ[ pdf],

MSPReturn[ pdf, "application/pdf"],

"Conversion failed, perhaps the PDF tools are not installed."]]

</msp:evaluate>

</msp:allocateKernel>

<br>

<br>

<input type="submit" name="button" value="Generate">

</form>

This code loads a couple of packages for creating notebooks and converting to PDF. It calls the function MakeNotebook, which generates a very simple notebook. It then passes the notebook object that was created into the function NotebookToPDF. If this returns a string, then this is returned to the client using MSPReturn.

Here is the *Mathematica* source for the function NotebookToPDF.

$PStillCommand = "/usr/local/pstill_dist/pstill"

PDFCommand[ out_, in_] :=

$PStillCommand <> " -o " <> out <> " " <> in

NotebookToPDF[nb_]:=

Module[ {stm1, stm2, file1, file2, res},

stm1= OpenTemporary[];

stm2=OpenTemporary[];

Close[stm1];

Close[stm2];

file1=First[stm1];

file2=First[stm2];

UseFrontEnd[ NotebookPrint[nb, file1]];

Run[ PDFCommand[ file2, file1]];

res=Read[file2, Record, RecordSeparators -> {}];

DeleteFile[file1];

DeleteFile[file2];

res

]

Note that this requires a definition to point to the location of the conversion tools. In this case it is set to use PStill, but it could easily be modified to use ps2pdf. Note also that the command is suitable for a Unix file system. On Windows it could be set as shown below; note the double-quotes around the command and note the doubling of the back-slashes.

$PStillCommand="\"C:\\Program Files\\GPStill\\pstill.exe\""

The code first creates some temporary files and then sends PostScript to one of the files with the command NotebookPrint. It then uses the Run command to invoke the PDF conversion on the PostScript, and finally reads the PDF into a *Mathematica* string and returns this as the result.

There are all sorts of further extensions to these simple functions that interface with the PostScript to PDF conversion tools. For example, they could be extended to pass various options to the converter.