FPDF和电视/电影编剧格式 [英] FPDF and TV/Film Screenplay formatting

查看:76
本文介绍了FPDF和电视/电影编剧格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个PHP脚本,将XML格式化为电视/电影编剧,事实证明这比预期的要困难一些.我已经创建了一些代码,但是,在某些地方我会卡住.

背景知识

在剧本中,存在多个标签,例如角色,对话框,场景标题,过渡等.它们具有不同的宽度,左右边距决定了页面的位置.

有两个主要方面值得关注,即我不知道:

  • 父/子XML标记,不能分开.
  • 如果子标记很长并且必须继续到另一个页面,则必须创建后续标记以表明它仍然是父标记.例如,如果显示了一个Character标记,并且计算了该标记的对话框(通过宽度,字符长度和行高)以继续到下一页,则必须在以下位置再次显示父代"character"下一页的顶部.
    • 此类父/孤儿标签包括:
    • "sceneheadng"->任何标签.
    • 字符"->对话框或括号
    • 括号"->对话框

但是,理想情况下,应该将父/子标签存储在这样的位置,以便无需添加大量代码就可以添加更多标签.

经过FPDF的大量配置和尝试后,到目前为止,这是我所拥有的:

// 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 ();
    }
}

此外,我编写了一个函数来计算组合的"$ saved"行的高度:

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;
    }
}

编辑

我发现LaTeX提供了一个编剧类(http://www.tug.org/texlive/Contents/live/texmf-dist/doc/latex/screenplay/screenplay.pdf),但是,我进行了搜索并找到了一个基于PHP的工具,将LaTeX转换为PDF,但没有成功.我知道LaTeX在服务器端运行,但是我仍然需要基于PHP的命令过程才能使用LaTeX生成所述PDF文件.

此外,在服务器上安装二进制文件,库或工具是不行的.我可以使用的工具是PHP及其内置的功能.任何可以将LaTex转换为PDF的类或PHP工具都非常有用.

解决方案

鉴于您的要求,我建议您使用在线Web服务推送您的LateX文件并获得编译的PDF作为回报.

这意味着您将获得完整的PDF文件,无需进行任何编译,无需安装,仅基于PHP的 Web服务和API.

有许多在线解决方案,有些是免费的,因此请检查适合您需要的解决方案:在线编辑文档

祝你好运!

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.

解决方案

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 !

这篇关于FPDF和电视/电影编剧格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆