<?php
/*
Created by Jon Lawrence.
(c) 2005 AAB Software under the GPL.
v. 1.0.0
Description:
The purpose of this class is to take a PHP string or PHP file and create a color-coded PDF document
for portability and printability of PHP source code.
Name:
This class will assume the title of "PPD" for "Portable Programming Document" and each PDF that
is generated by this class will have that as the "generator"
*/
define("PHP_PDF_ver", "PHP->PDF Converter v1.0.1");
define("PDFresolution", 72);
define("DEBUG", false);
class PHP_PDF
{
/* Set up the class variables to be used */
/* PRIVATE */
var $handle; // PDF handle to be used.
var $plain; // Plain version of PHP source
var $fonts; // Font array for normal/bold/italic/boldItalic
var $color; //current color to work with.
var $font; //current font to work with.
var $page; //current page
var $curX;
var $curY;
var $line;
var $lineNum;
var $inLine;
var $pVersion; //the php version array of regular expressions. enum(4, 5);
var $pUsed; //sets 4 or 5 for the version.
/* PUBLIC */
var $margin; // border size of page in inches
var $width; //width of the page in inches
var $height; //heigh of the page in inches
var $fontSpace; // font spacing (in pixels)
var $fontSize; //font size of document
var $centerHead; //the header to be on each page centered.
function PHP_PDF($title="PPD [Portable Programming Document]", $author="PHP->PDF Converter")
{
/* Start out the with the basic creation and prepare for inputed file/string */
//set the regular expressions depending on php version
$this->pVersion = array(4 => "|<font color=\"#([^\"]{6})\">([[:print:]\n]*)</font>|U", 5 => "|<span style=\"color: #([^\"]{6})\">([[:print:]\n]*)</span>|U");
$this->pUsed = 4;
/* SET UP DEFAULTS FOR PUBLIC VARS */
$this->margin = .5;
$this->width = 8.5;
$this->height = 11;
$this->fontSpace = 5;
$this->fontSize = 8;
$this->color = "000000";
$this->line = 1;
$this->centerHead = false;
$this->handle = PDF_new();
pdf_open_file($this->handle);
pdf_set_info($this->handle, "Title", $title);
pdf_set_info($this->handle, "Creator", PHP_PDF_ver);
pdf_set_info($this->handle, "Author", $author);
pdf_set_info($this->handle, "Subject", "text/phps");
/* Default font is Times-Roman */
$normal = pdf_findfont($this->handle, "Courier", "host", 0);
$bold = pdf_findfont($this->handle, "Times-Bold", "host", 0);
$italic = pdf_findfont($this->handle, "Times-Italic", "host", 0);
$BoldItalic = pdf_findfont($this->handle, "Times-BoldItalic", "host", 0);
$this->fonts = array("normal" => $normal, "bold" => $bold, "italic" => $italic, "bolditalic" => $BoldItalic);
$this->page = -1;
}
function loadText($text, $linenum=true)
{
$this->plain = $text;
$this->_create($linenum);
}
function loadFile($fname=__FILE__, $linenum=true)
{
$this->plain = file_get_contents($fname);
if(DEBUG)
echo $fname."\n";
$this->_create($linenum);
}
function getPDF()
{
//get the PDF data
return pdf_get_buffer($this->handle);
}
/* used to set the current php version */
function setPHP($ver=4)
{
$this->pUsed = ($ver==5) ? 5 : 4;
}
function _create($linenum = false)
{
/* Create the PDF from $this->plain */
$this->lineNum = $linenum;
$t_array = explode("\n", highlight_string($this->plain, true));
$colored = $t_array[1]; //pull the needed string from the array.
$this->inLine = false;
/* function variables */
list($curX, $curY) = $this->_newPage();
$this->_setColor("000000");
$font = $this->fonts['normal'];
$beginLine = $this->margin*PDFresolution;
$stepLine = $this->fontSize + $this->fontSpace;
$colored = str_replace("<br />", "\n ", $colored);
//Match all the <font color="#023456">Stuff</font>
$numMatch = preg_match_all($this->pVersion[$this->pUsed], $colored, $matches);
if($numMatch==0) return false;
// Start loop for the fonts
for($i=0; $i < $numMatch; $i++)
{
$this->_setColor($matches[1][$i]);
$match = str_replace("<br />", "\n ", $matches[2][$i]);
$t_array = explode("\n", $match);
//echo "### ". count($t_array) . " ###\n";
if(count($t_array)>1)
{
for($j=0;$j<count($t_array)-1;$j++)
{
$cLine = $t_array[$j];
$cLine = str_replace("\t", " ", $cLine);
$cLine = html_entity_decode($cLine);
$this->_writeText($cLine);
if($linenum===true && $this->inLine===false) $this->_writeNum();
$this->inLine = false;
$this->_newLine();
$this->line++;
}
$cLine = $t_array[count($t_array)-1];
//$cLine = str_replace("\t", " ", $cLine);
$cLine = html_entity_decode($cLine);
$this->_writeText($cLine);
}
else
{
$cLine = $t_array[0];
$cLine = html_entity_decode($cLine);
$this->_writeText($cLine);
}
}
//pdf_end_page($this->handle);
if($linenum===true) $this->_writeNum();
$this->_endPage();
pdf_close($this->handle);
} //END function _create()
/* Function to set the text color */
function _setColor($hex)
{
list($red, $green, $blue) = sscanf($hex, "%02x%02x%02x");
//echo "$hex::$red:$green:$blue<br />";
pdf_setcolor($this->handle, "both", "rgb", $red/255, $green/255, $blue/255);
//pdf_setcolor($this->handle, "both", "rgb", 0,0,0);
//Make sure the text is filled with the current "fill" color
pdf_set_value($this->handle, "textrendering", 0);
$this->color = $hex;
}
function _writeNum()
{
$curY = pdf_get_value($this->handle, "texty", 0);
pdf_setcolor($this->handle, "both", "rgb", 0,0,0);
pdf_set_value($this->handle, "textrendering", 0);
pdf_show_xy($this->handle, sprintf("%03d", $this->line), 10, $curY);
$this->_setColor($this->color);
}
/* function to enter header info */
function setHeader($text)
{
$this->centerHead = $text;
}
/* function to begin a new page */
function _newPage()
{
if($this->page > -1)
{
//Write a "PDF Created by" at the bottom of each page.
//pdf_end_page($this->handle);
$this->_endPage();
}
pdf_begin_page($this->handle, $this->width*PDFresolution, $this->height*PDFresolution);
//return the starting (x,y) of page
list($curX, $curY) = array($this->margin * PDFresolution, ($this->height-$this->margin)*PDFresolution-($this->fontSize+$this->fontSpace));
$val = pdf_set_text_pos($this->handle, $curX, $curY);
$curX = pdf_get_value($this->handle, "textx", 0);
$curY = pdf_get_value($this->handle, "texty", 0);
//echo "::_newPage() (x,y) = ($curX, $curY)<br />";
$this->page++;
pdf_setfont($this->handle, $this->fonts['normal'], $this->fontSize);
$this->_setColor($this->color);
return array($curX, $curY);
}
function _endPage()
{
/* Print Footer */
/* NOTE -- you may change this footer only if you credit the author somewhere else in
a visible fashion! */
$copy = "PDF Generated by PPD programmed by Jon Lawrence";
$width = pdf_stringwidth($this->handle, $copy);
$startPlace = (($this->width*PDFresolution)-$width)/2;
pdf_setcolor($this->handle, "both", "rgb", 0,0,0);
pdf_set_value($this->handle, "textrendering", 0);
pdf_show_xy($this->handle, $copy, $startPlace, 10);
/* Print header */
if($this->centerHead)
{
$width = pdf_stringwidth($this->handle, $this->centerHead);
$startPlace = (($this->width*PDFresolution)-$width)/2;
pdf_show_xy($this->handle, $this->centerHead, $startPlace, ($this->height*PDFresolution-$this->fontSize-10));
}
pdf_end_page($this->handle);
}
function _newLine()
{
//puts a new line in the PDF
$beginLine = $this->margin*PDFresolution;
$stepLine = $this->fontSize + $this->fontSpace;
$curX = pdf_get_value($this->handle, "textx", 0);
$curY = pdf_get_value($this->handle, "texty", 0);
if(($curY-$stepLine) <= ($this->margin*PDFresolution))
{
$this->_newPage();
return true;
}
$val=pdf_set_text_pos($this->handle, $beginLine, $curY-$stepLine);
if(DEBUG)
echo "\n";
return true;
}
function _writeText($text)
{
$beginLine = $this->margin*PDFresolution;
$stepLine = $this->fontSize + $this->fontSpace;
$curX = pdf_get_value($this->handle, "textx", 0);
$curY = pdf_get_value($this->handle, "texty", 0);
//echo "$curX :: $curY<br />";
//see if the entire line will fit
$stringWidth = pdf_stringwidth($this->handle, $text);
if(($stringWidth+$curX) <= (($this->width-$this->margin)*PDFresolution))
{
pdf_show($this->handle, $text);
pdf_set_text_pos($this->handle, $curX+$stringWidth, $curY);
if(DEBUG)
echo $text;
}
else
{
//doesn't all fit....
$insideFill = ($this->width-($this->margin*2))*PDFresolution;
$numberLines = ceil($stringWidth/$insideFill);
//check to see if a new page should be created first
if(($numberLines*$stepLine) > ($curY - $this->margin*PDFresolution))
$this->_newPage();
$words = explode(" ", $text);
foreach($words as $word)
{
$curX = pdf_get_value($this->handle, "textx", 0);
$curY = pdf_get_value($this->handle, "texty", 0);
$wordWidth = pdf_stringwidth($this->handle, $word);
if(($wordWidth+$curX) > (($this->width-$this->margin)*PDFresolution))
{
if(($this->lineNum===true) && $this->inLine===false)
{
$this->_writeNum();
$this->inLine = true;
}
$this->_newLine();
}
pdf_show($this->handle, $word." ");
}
}
} //END _writeText()
} //END PHP_PDF class
?>