问题
I would like to create a PHP script which formats XML into a TV/Film Screenplay, this has proved somewhat more difficult than anticipated. I have created some of the code, however, there are particular places where I get stuck.
A little background
In a screenplay there exist multiple tags like character, dialog, sceneheading, transition etc. They have different widths and left and right margins determining the position on the page.
There are two main areas which have come into concern, i.e. I can't figure out:
- Parent/Children XML tags, which cannot be separated.
- If a child tag is long and has to continue to another page, then a subsequent tag must be created in order to show that it is still the parent. For instance, if a Character tag is shown and the dialog to that tag, the child, is calculated (through width, character length and line height) to continue to the next page, then the parent, "character" must be shown again at the top of the subsequent page.
- Such parent/orphan tags include:
- "sceneheadng" -> Any tag.
- "character" -> dialog or parenthetical
- "parenthetical" -> dialog
Ideally, however, the parent/children tags should be storred in such away that more can be added without lots and lots of code.
Here is what I have so far, after much FPDF configuration and attempts:
// Parse the XML string which has been requested from the database.
$xml = new SimpleXmlIterator($file, null);
$namespaces = $xml->getNamespaces(true);
/*
* An external function which converts the XML into an ORDERED array.
* This returns all the attributes of the xml and the following:
* "@type" Refers to the type, i.e. character/dialog etc,
* "@content" What was actually within the tags of the XML.
*/
$source = $parseXML($xml, $namespaces);
$saved = array ();
// For every line of the XML.
foreach ($source as $index => $line) {
/*
* We are going to save the current line of the XML so that we
* can check the size of the saved cells against the size of the
* page. If there is not enough space for specific tags which are
* required such as character and dialog, then we create a new page.
*
*/
$saved[] = $line;
$forward = false;
/*
* Here is where I get somewhat confused - I have attempted to create
* a mechanism that determines the "@types" which are needed as parents
* and children of one another.
*
* The $forward variable refers to the possibilty of writing the tag to
* the PDF. If the parent/orphan is possible or there are non, then it
* should be able to write.
*/
if ($forward) {
$width = 0;
foreach ($saved as $index => $value) {
/*
* Everything is measured in inches, therefore, I have created a
* point() function which turns inches into mm so that FPDF understands
* everything.
*
* The $format variable is an array which has margins, either top,
* left or right. We use this to position the Cell of a specific @type
* so that it appears in the correct format for a TV/Film script.
*
* The width variable is deduced via finding the full width of the page,
* then subtracting the subsequent left and right margin of the said
* @type.
*/
$width = (point ($setting["width"])
- (point ($format[$value["@type"]]["margin-left"])
+ point ($format[$value["@type"]]["margin-right"])));
/*
* The $pdf variable is that of the FPDF Class.
*/
$pdf->SetLeftMargin (point($format[$value["@type"]]["margin-left"]));
$pdf->SetRightMargin (point($format[$value["@type"]]["margin-right"]));
// Formatting purposes.
$pdf->Ln (0);
$pdf->MultiCell (
$width,
point ($setting["line-height"]), //Line height? Still needs fixing.
$value["@content"], // Physical text
1); // A temporary border to see what's going on.
}
// Reset the $saved, after no more parent/children?
$saved = array ();
}
}
Additionally, I have written a function which calculates the height of the combined "$saved" lines:
function calculate_page_breaks ($saved_lines, $act_upon = true) {
$num_lines = 0;
foreach ($saved_lines as $value) {
$column_width = (point ($setting["width"])
- (point ($format[$type][$value["@type"]]["margin-left"])
+ point ($format[$type][$value["@type"]]["margin-right"])));
$num_lines += ceil($pdf->GetStringWidth($value["@content"]) / ($column_width - 1));
}
$cell_height = 5 + 1; // have cells at a height of five so set to six for a padding
$height_of_cell = ceil($num_lines * $cell_height);
$space_left = point($setting["height"]) - $pdf->GetY();
$space_left -= point($format[$type]["margin-bottom"]);
// test if height of cell is greater than space left
if ($height_of_cell >= $space_left) {
// If this is not just a check, then we can physically "break" the page.
if ($act_upon) {
$pdf->Ln ();
$pdf->AddPage (); // page break
$pdf->SetTopMargin ($point($format[$type]["margin-top"]));
$pdf->SetLeftMargin ($point($format[$type]["margin-left"]));
$pdf->SetRightMargin ($point($format[$type]["margin-right"]));
$pdf->MultiCell (100,5,'','B',2); // this creates a blank row for formatting reasons
}
return false;
} else {
return true;
}
}
Edit
I have discovered that LaTeX offers a Screenplay Class (http://www.tug.org/texlive/Contents/live/texmf-dist/doc/latex/screenplay/screenplay.pdf), however, I have searched far and wide to find a PHP-based tool to convert LaTeX to PDF, but have had no success. I understand that LaTeX runs on the server side, however I still require a PHP-based command process in order to generate said PDF files using LaTeX.
Additionally, installing binaries, libraries or tools on to the server is a no-no. The tool at my disposal is PHP and the functionalities it has built in. Any class or PHP tool that can convert LaTex to PDF is incredibly useful.
回答1:
Given your requirements, I would recommend using online web services to push your LateX file and get a compiled PDF in return.
This means you get a full PDF file without any compilation, no installing, just pure PHP-based web services and API.
There are a number of online solutions, some are free, so please check the one that fits your need : Compiling documents online
Good luck !
来源:https://stackoverflow.com/questions/8478720/fpdf-and-tv-film-screenplay-formatting