(* Author: Rolf Mertig *) (* Organization: GluonVision GmbH *) (* Copyright: GluonVision GmbH *) (* Date: 2006-06-06 *) (* Documentation: Evaluate from a command line a previously saved notebook, save the evaluated notebook, and print it to the default printer (which can be PDFCreator with 'Auto-save' option on; the files are in the directory as set in the PDFCreator option tab). For a sample usage see the Example section at the end of this file. *) (* Limitations: Windows only for the moment. *) (* Version: 1.0 *) (* Mathematica version needed: 5.0 or newer *) (* Comments: This is more complicated than it should be ... *) (* Maybe the "Pause[1]" pauses have to be bigger for larger notebooks ? *) (* ************************************* *) (* This code should not be run from the FrontEnd ... : *) If[$FrontEnd =!= Null, Print["This program should be run from the Kernel, not from a FrontEnd."] , (* ELSE *) BeginPackage["NB2PDF`"]; $Debug::usage="If set to True debugging messages are printed."; ; NB2PDF::usage="NB2PDF[nbfile] evaluates the notebook nbfile and prints it to the default printer. If the default printer is, e.g., PDFCreator (from https://sourceforge.net/projects/pdfcreator), with 'Auto-save' option on, the filename used for printing is the date, and the directory used for auto-save the one indicated in the 'Auto-save' dialog." ; NBOutToken::usage="NBOutToken is an option for NB2PDF. Its setting determines the string token added before the .nb starting filename. The resulting string is used as name for the evaluated saved notebook."; Begin["`Private`"]; $Debug = True; Options[NB2PDF] = {NBOutToken -> "_Evaluated"}; NB2PDF[nb_String /; StringMatchQ[nb, "*.nb", IgnoreCase-> True], opts___?OptionQ ] := nbtopdf[Get[nb], nb, opts] /; FileNames[nb] =!= {}; nbtopdf[nbin_Notebook, nbfilename_String, opts___?OptionQ] := Module[{(*nb, nbtmp, nt, nbfout*)}, nbtmp = $TemporaryPrefix <> StringJoin @@ Map[ToString, Date[] // Round] <>".txt"; nbtmp = StringReplace[nbtmp, "\\" -> "\\\\"]; nbtoken = NBOutToken /. {opts} /. Options[NB2PDF]; nbfout = StringInsert[nbfilename, nbtoken, -4]; (* in order to tell the FE that the notebook really exists we need to create something on disk. If this is not done a strange FE-dialog appears ... *) If[FileNames[nbfout] === {}, Export[nbfout,""]]; (* we need JLink *) Needs["JLink`"]; JLink`InstallJava[]; (* this uses the FrontEnd as a service, in the background *) JLink`UseFrontEnd[ (* nt = Insert[nbin /. (WindowTitle->_):> Sequence[], (WindowTitle -> nbfout), -1]; Print["WindowTitle option of nt ", Options[nt,WindowTitle]] /; $Debug; *) nt = nbin; (* add a final temporary cell and open the notebook : *) nb = NotebookPut @ Insert[nt, Cell[ "Export[\"" <> nbtmp <> "\"," <> ToString[Date[]]<> ",\"Text\"];", "Input"], {1,-1}]; Print["Head of nb = ", Head[nb]] /; $Debug; (* Put a cell at the end which will serve as a terminating condition *) SelectionMove[nb, Before, Notebook]; SelectionMove[nb,All,Notebook]; (* Evaluate everything. Attention: the notebook should terminate ... *) SelectionEvaluate[nb]; Print["starting While "] /;$ Debug; (* This is the tricky part: Since there are really two programs, the FrontEnd and the Kernel, we have to tell the kernel to wait for the FrontEnd to finish the evaluation of the notebook. We put the kernel evaluator in a While - loop until the last cell of the original notebook is evaluated (which cannot be done somehow with a kernel value or another FrontEnd-action, so we resume to writing a temporary file to disk and check if it there ... *) While[ ($filetype = FileType[nbtmp]) =!= File, Print["While waiting: ", $filetype] /;$ Debug; Pause[1] ]; Print["finished While "] /;$ Debug; (* at this point we are sure that everything is finished and the extra cell as well as the temporary file are removed easily: *) SelectionMove[nb,After,Notebook]; SelectionMove[nb,Previous,Cell]; DeleteFile[nbtmp]; Pause[1]; (* seems to be necessary *) NotebookDelete[nb]; Pause[1]; (* seems to be necessary *) NotebookSave[nb, nbfout, Interactive -> False]; fsizecheck = fsizecheck2 = 0; While[fsizecheck =!= fsizecheck2 || fsizecheck === 0, fsizecheck = FileByteCount[nbfout]; Print["fsizecheck = ",fsizecheck] /; $Debug; Pause[1]; fsizecheck2 = FileByteCount[nbfout]; ]; Pause[1]; (* print the easy way: (this could be more elaborate, with options, etc.) *) (* one could also use NETLink in order to manage the default printer ... *) NotebookPrint[nb]; (* it might take more than one second for the PDF file to show up in the default save-directory of PDFCreator *) Pause[1]; ]; ]; End[]; EndPackage[]; ]; (* ******************************************************* *) (* ******************************************************* *) (* EXAMPLE: *) (* ******************************************************* *) (* Example usage: Uncomment the instruction below and adapt to your needs and run this file from the command line like this: math < NB2PDF.m > NB2PDF.out The evaluated notebook will be C:\\nbfiles\\samplentebook_Evaluated.nb and the PDF file will be named by the current date and found in the directory as indicated in the PDFCreator option settings. *) (* NB2PDF["C:\\nbfiles\\samplenotebook.nb"] *)