(* :Title: PagePrint *)

(* :Author: Mark Fisher *)

(* :Mathematica Version: 6.0 *)

(* :History: Original version, December 2004
		June 2007 Updated for Version 6 with help from John Fultz
*)

(* :References: Adapted from code written at my request by
John Fultz, jfultz@wolfram.com *)

PagePrint::usage =
"PagePrint[graphic, opts] prints the graphic on a blank
page. The option LandscapeOrientation can be either True or False
(default). Run PagePrint[] to select which printer to use (if not
the default printer). The page orientation of the printer should be
portrait even if landscape orientation is desired. The
option PageMargins specifies the page margins in inches. The default is 1.
Horizontal and vertical page margins may be specified separately.
The image is resized to fill the space within the margins. The
option ImageDimensions is ignored with the default setting Automatic.
Setting ImageDimensions -> {w, h} overrides the PageMargins option and
places the image in a centered rectangle (w \[Times] h) inches. Setting
ImageDimensions -> w effectively specifies {w, w * ar}, where ar is the
aspect ratio of the graphic. The option PaperDimensions can be
used to specify the dimensions of the paper (in inches). The default is
PaperDimensions -> {8.5, 11}. The default behavior of opening the 
print dialog box can be changed using OpenPrintDialog -> False.
The option MarginAdjustments may be used to correct for the fact that a 
printer's margins are not the same left and right or bottom and top. The
default setting is MarginAdjustments -> {0, 0}. For example, setting
MarginAdjustments -> {1/8, 0} will shift the graphic 1/8 inch to the
right on the virtual page."

PaperDimensions::usage = "PaperDimensions is an option for \
PagePrint that specifies the dimensions of the paper in inches \
(in portrait orientation). The default is PaperDimensions -> {8.5, 11}."

LandscapeOrientation::usage = "LandscapeOrientation is an option for \
PagePrint."

PageMargins::usage = "PageMargins is an option for \
PagePrint that specifies the page margins in inches. \
Horizontal and vertical page margins may be specified separately. \
The default is PageMargins -> 1."

ImageDimensions::usage = "ImageDimensions is an option for
PagePrint."

MarginAdjustments::usage = "MarginAdjustment is an Option for PagePrint \
that can take account of the printer's margins by shifting the image on \
the virtual page. The default is MarginAdjustments -> {0, 0}."

OpenPrintDialog::usage = "OpenPrintDialog is an option for PagePrint \
that specifies whether to open the print dialog box. The default \
setting is OpenPrintDialog -> True."

PrintFileName::usage = "PrintFileName is an option for \
PagePrint that specifies a file to print to. to direct the page. The \
default is PrintFileName -> None which directs the page to the \
printer."

PrintDirectory::usage = "PrintDirectory is an option \
for PagePrint that specifies the directory in which to put the file when \
printing to a file. The default setting is PrintDirectory :> \ 
$UserDocumentsDirectory. To put the file in the current (working) \
directory, use PrintDirectory -> Directory[]."

PagePrintScale::usage = "PagePrintScale is an option for PagePrint \
that determines the units used. The default setting is PagePrintScale \
-> 72, which specifies inches. To convert to millimeters, use \
PagePrintScale -> 72/25.4 and then specify the PaperDimensions, \
PageMargins, MarginAdjustments in millimeters."

Options[PagePrint] = {
	PagePrintScale -> 72,
	PaperDimensions -> {8.5, 11},
	PageMargins -> 1,
	MarginAdjustments -> {0, 0},
	LandscapeOrientation -> False,
	ImageDimensions -> Automatic,
	OpenPrintDialog -> True,
	PrintFileName -> None,
	PrintDirectory :> $UserDocumentsDirectory
	}

PagePrint[] := FrontEndTokenExecute["SystemPrintOptionsDialog"]

PagePrint[x_, OptionsPattern[]] :=
	Module[{scale, pdim, marg, madj, land, idim, opd, fn, dir,
			orient, size, xOnPage, nb},

	{scale, pdim, marg, madj, land, imdim, opd, fn, dir} =
		OptionValue[{PagePrintScale, PaperDimensions, PageMargins, 
			MarginAdjustments, LandscapeOrientation, ImageDimensions, 
			OpenPrintDialog, PrintFileName, PrintDirectory}];

	(* setup the page *)
	land = TrueQ[land];
	orient = If[land, {0, -1}, {1, 0}];
	If[imdim === Automatic,
		size = If[land, Reverse[pdim], pdim] - 2 * marg * {1, 1},
		(* else use ImageDimensions *)
		size = imdim {1, AspectRatio /. AbsoluteOptions[x, AspectRatio]}
			];
	xOnPage = Graphics[
		{White, 
			Rectangle[{0, 0}, pdim],
			Inset[x, pdim/2 + madj, ImageScaled[{.5, .5}], size, orient]
			},
				ImageSize -> scale * pdim,
				PlotRangePadding -> 0 (* this is crucial *)
		];

	(* setup the notebook *)
	nb = NotebookCreate[
		Visible -> False,
		PrintingOptions -> {
			"FirstPageHeader" -> False,
			"FirstPageFooter" -> False,
			"RestPagesHeader" -> False,
			"RestPagesFooter" -> False,
			"PrintingMargins" -> {{0,0},{0,0}}
			}];
	NotebookWrite[nb,
		Cell[
			BoxData[ToBoxes[xOnPage]], (* thanks to John *)
			"Graphics",
			Magnification -> 1, (* this fixes the 80% problem *)
			ImageMargins -> {{0,0},{0,0}},
			CellMargins -> {{0,0},{0,0}}
			]
		];
	If[fn === None,
		NotebookPrint[nb, Interactive -> TrueQ[opd]],
		NotebookPrint[nb, ToFileName[dir, fn]]
		];
	NotebookClose[nb]
	]

