-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit - minimally functional FOML implementation.
- Loading branch information
Showing
21 changed files
with
683 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
fop-1.0/ | ||
*~ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
<?php | ||
|
||
require_once 'FomlConfig.php'; | ||
|
||
class FOML | ||
{ | ||
static $fopExec = "fop-1.0/fop"; // fopExec is relative to this directory | ||
static $pdfMimeType = "application/pdf"; | ||
static $tempDir = null; // defaults to system temp directory | ||
static $keepTempFiles = true; // set to true for debugging | ||
|
||
static function GeneratePhp($Template) | ||
{ | ||
$fomlParser = new FomlParser(); | ||
$php = $fomlParser->ParseFile($Template); | ||
return $php; | ||
} | ||
|
||
// returns XSL-FO string | ||
// REVISIT - use ob_start with a callback function to capture output directly to a file, | ||
// and return a temporary filename instead of a string. | ||
static function GenerateXslFo($Template, $Args=null) | ||
{ | ||
// import variables | ||
if ($Args) { | ||
foreach ($Args as $key=>$value) { | ||
$$key = $value; | ||
} | ||
} | ||
$_php = FOML::GeneratePhp($Template); | ||
|
||
ob_start(); | ||
eval("?".">".$_php); // prefixed with ? > to exit implicit php mode | ||
$xslFo = ob_get_contents(); | ||
ob_end_clean(); | ||
return $xslFo; | ||
} | ||
|
||
static function TempName($Prefix) | ||
{ | ||
$tempDir = FOML::$tempDir; | ||
if ($tempDir == null) $tempDir = sys_get_temp_dir(); | ||
return tempnam($tempDir, $Prefix); | ||
} | ||
|
||
// returns the name of the temporary pdf output file. | ||
// The file must be unlinked by the caller. | ||
static function XslFoToPdf($XslFo) | ||
{ | ||
$pdfFileName = FOML::TempName("pdf-"); | ||
$xslFoFileName = FOML::TempName("xslfo-"); | ||
|
||
$xslFile = fopen($xslFoFileName, "w"); | ||
fwrite($xslFile, $XslFo); | ||
fclose($xslFile); | ||
|
||
$escapedPdfFileName = escapeshellarg($pdfFileName); | ||
$escapedXslFoFileName = escapeshellarg($xslFoFileName); | ||
$fop = dirname(__FILE__).'/'.FOML::$fopExec; | ||
$cmd = "{$fop} {$escapedXslFoFileName} {$escapedPdfFileName}"; | ||
shell_exec($cmd); | ||
|
||
if (!FOML::$keepTempFiles) unlink($xslFoFileName); | ||
|
||
return $pdfFileName; | ||
} | ||
|
||
static function Render($Template, $Args=null, $Headers=null) | ||
{ | ||
$xslFo = FOML::GenerateXslFo($Template, $Args); | ||
$pdfFileName = FOML::XslFoToPdf($xslFo); | ||
$size = filesize($pdfFileName); | ||
$mimeType = FOML::$pdfMimeType; | ||
|
||
if ($Headers) { | ||
foreach ($Headers as $header) { | ||
header($header); | ||
} | ||
} | ||
header("Content-Length: {$size}"); | ||
header("Content-Type: {$pdfMimeType}"); | ||
|
||
$fileHandle = fopen($pdfFileName, "rb"); | ||
fpassthru($fileHandle); | ||
fclose($fileHandle); | ||
|
||
if (!FOML::$keepTempFiles) unlink($pdfFileName); | ||
} | ||
static function RenderInline($Template, $Args=null) | ||
{ | ||
$headers = array("Content-Disposition"=>"inline"); | ||
FOML::Render($Template, $Args, $headers); | ||
} | ||
|
||
static function RenderAttachment($Template, $Filename, $Args=null) | ||
{ | ||
$headers = array("Content-Disposition: attachment; filename=\"{$FileName}\""); | ||
FOML::Render($Template, $Args, $headers); | ||
} | ||
} | ||
|
||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php | ||
class FomlCommentNode extends FomlNode | ||
{ | ||
const MATCH_RE = "/^\/(.*)/"; | ||
|
||
function __construct($Matches) | ||
{ | ||
$this->text = $Matches[1]; | ||
} | ||
|
||
function RenderPrefix() | ||
{ | ||
// todo - should we escape inner "-->" to avoid early closing? | ||
print "<!-- {$this->text} "; | ||
} | ||
|
||
function RenderSuffix() | ||
{ | ||
print "-->\n"; | ||
} | ||
} | ||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
|
||
/* | ||
if you are using an autoloader, you can remove all of these | ||
requires and let the autoloader lazy-load the classes | ||
*/ | ||
|
||
require_once 'FomlParser.php'; | ||
require_once 'FomlNode.php'; | ||
|
||
require_once 'FomlCommentNode.php'; | ||
require_once 'FomlDoctypeNode.php'; | ||
require_once 'FomlExecNode.php'; | ||
require_once 'FomlFilterNode.php'; | ||
require_once 'FomlInsertNode.php'; | ||
require_once 'FomlTagNode.php'; | ||
require_once 'FomlTextNode.php'; | ||
require_once 'FomlExecNode.php'; | ||
|
||
require_once 'FomlDoc.php'; | ||
require_once 'FomlParseTree.php'; | ||
|
||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php | ||
class FomlDoc extends FomlNode | ||
{ | ||
|
||
function RenderToString() | ||
{ | ||
ob_start(); | ||
$this->Render(); | ||
$output = ob_get_contents(); | ||
ob_end_clean(); | ||
return $output; | ||
} | ||
|
||
function EvalToString($Args) | ||
{ | ||
foreach ($Args as $key=>$value) { | ||
$$key = $value; | ||
} | ||
|
||
$php = $this->RenderToString(); | ||
ob_start(); | ||
eval("?".">".$php); | ||
$output = ob_get_contents(); | ||
ob_end_clean(); | ||
return $output; | ||
} | ||
|
||
} | ||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
class FomlDoctypeNode extends FomlNode | ||
{ | ||
const MATCH_RE = "/^\!\!\!\s*/"; | ||
|
||
function __construct($Matches) | ||
{ | ||
// Nothing to save. | ||
} | ||
|
||
function RenderPrefix() | ||
{ | ||
print '<?php echo \'<?xml version="1.0" encoding="utf-8"?>\'?>'; | ||
} | ||
|
||
function RenderSuffix() | ||
{ | ||
} | ||
|
||
|
||
|
||
} | ||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?php | ||
class FomlExecNode extends FomlNode | ||
{ | ||
const MATCH_RE = "/^-\s*(.*)/"; | ||
/* | ||
* Examples | ||
* - $x = 0 | ||
* - foreach ($i=0;$i<10;$i++) | ||
*/ | ||
|
||
/* | ||
* else and elseif are interesting. They don't need special handling - the tree | ||
* will naturally render like this: | ||
* < ? php if (condition) { ? > | ||
* stuff | ||
* < ? php } ? > | ||
* < ? php else { ? > | ||
* more stuff | ||
* < ? php } ? > | ||
* because | ||
*/ | ||
|
||
public $code; | ||
public $hasBlock; // if true enclose block in {} otherwise end command with ";" | ||
|
||
function __construct($Matches) | ||
{ | ||
$this->code = $Matches[1]; | ||
$this->hasBlock = preg_match("/^(foreach|for|while|if|else|elseif)/", $this->code); | ||
} | ||
|
||
function RenderPrefix() | ||
{ | ||
print "<?php "; | ||
print $this->code; | ||
if ($this->hasBlock) { | ||
print "{ ?>"; | ||
} else { | ||
print "; ?>"; | ||
} | ||
} | ||
|
||
function RenderSuffix() | ||
{ | ||
if ($this->hasBlock) { | ||
print "<?php } ?>"; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<?php | ||
class FomlFilter | ||
{ | ||
static function CreateAndRender($Args) | ||
{ | ||
$filterClass = get_called_class(); | ||
$filter = new $filterClass($Args); | ||
$filter->Render(); | ||
} | ||
} | ||
|
||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<?php | ||
|
||
// TODO - filter doesn't yet pass child nodes to filter | ||
// For now I'm just using it for :include('file.foml') | ||
|
||
class FomlFilterNode extends FomlNode | ||
{ | ||
// this re is probably not rich enough to support args using variable expansion | ||
const MATCH_RE = "/^:([a-zA-Z0-9]+)(\((.*)\))?/"; | ||
|
||
public $filterClass; | ||
|
||
function __construct($Matches) | ||
{ | ||
$filter = $Matches[1]; | ||
$args = $Matches[3]; | ||
if (isset(FomlParser::$FILTER_CLASSES[$filter])) | ||
{ | ||
$this->filterClass = FomlParser::$FILTER_CLASSES[$filter]; | ||
$this->args = $args; | ||
} else { | ||
throw new FomlException("Unknown filter '{$filter}'"); | ||
} | ||
} | ||
|
||
function RenderPrefix() | ||
{ | ||
print "<?php {$this->filterClass}::CreateAndRender({$this->args}) ?>\n"; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
class FomlIncludeFilter extends FomlFilter | ||
{ | ||
public $fileName; | ||
|
||
function __construct($Arg) | ||
{ | ||
$this->fileName = $Arg; | ||
} | ||
|
||
function Render() | ||
{ | ||
// REVISIT : can't just print the PHP here because we are | ||
// called from within the eval context. However doing it this | ||
// way hides all of the variables, which might be a problem. | ||
eval('?'.'>'. FomlParser::ParseFile($this->fileName)); | ||
} | ||
} | ||
|
||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
class FomlInsertNode extends FomlNode | ||
{ | ||
const MATCH_RE = "/^=\s*(.*)/"; | ||
|
||
function __construct($Matches) | ||
{ | ||
$this->code = $Matches[1]; | ||
} | ||
|
||
function RenderPrefix() | ||
{ | ||
print "<?php print "; | ||
print $this->code; | ||
print "; ?>"; | ||
print " \n"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
class FomlNode | ||
{ | ||
public $children = array(); | ||
|
||
function RenderPrefix() | ||
{ | ||
} | ||
|
||
function RenderSuffix() | ||
{ | ||
} | ||
|
||
function Render($Indent=0) | ||
{ | ||
$this->RenderPrefix(); | ||
foreach ($this->children as $child) { | ||
$child->Render(); | ||
} | ||
$this->RenderSuffix(); | ||
} | ||
} | ||
?> |
Oops, something went wrong.