PDFlib Cookbook

cookbook

pdfua/inline_tags_in_textflow_pdfua1 PDFlib 10

Create Tagged PDF with Textflow where the tags are supplied inline in the text.

Download Java Code  Switch to PHP Code  Show Output 

/*
 * Inline tags in Textflow:
 * Create Tagged PDF with Textflow where the tags are supplied inline in the
 * text.
 *
 * Create multi-column text output which may span multiple pages;
 * The Textflow uses inline option lists with tagging information.
 * The inline tags demonstrate common tagging constructs like headings, links
 * and lists.
 *
 * Required software: PDFlib/PDFlib+PDI/PPS 10
 * Required data: font file
 */
package com.pdflib.cookbook.pdflib.pdfua;

import com.pdflib.pdflib;
import com.pdflib.PDFlibException;

public class inline_tags_in_textflow_pdfua1
{
    public static void main (String argv[])
    {
        pdflib p = null;

        String outfile = "inline_tags_in_textflow_pdfua1.pdf";
        String title = "Inline tags in Textflow";
        String searchpath = "../input";
        int act, tf = -1;
        String result;
        final double llx1= 50, lly1=50, urx1=250, ury1=800;
        final double llx2=300, lly2=50, urx2=500, ury2=800;
        int exitcode = 0;

        /* Repeat the dummy text to produce more contents */
        final int count = 10;

        /* Macros for various kinds of begin and end tags using "tagbegin" and "tagend" options */
        final String macros =
            "macro {" +
                "basefont {fontname=NotoSerif-Regular charref fontsize=11 leading=120%} " +

            "H1 {&basefont fontsize=16 leading=150%  fillcolor=red " +
            "    tagbegin={tagname=H1 Title = {Heading}} } " +
            "/H1 {tagend leading=40% nextparagraph} " +

            "P {&basefont alignment=justify " +
            "     tagbegin={tagname=P} fillcolor=black alignment=justify} " +
            "/P {nextline leading=80% nextparagraph tagend} " +

            "L {tagbegin={tagname=L ListNumbering=Disc} fillcolor=black alignment=justify} " +
            "/L {tagend} " +

            // Here we supply a nested "P" tag as child of "Caption"
            // as they bracket the same content
            "Caption {&basefont tagbegin={tagname=Caption tag={tagname=P}} } " +
            "/Caption {tagend} " +

            "LI {tagbegin={tagname=LI} } " +
            "/LI {tagend} " +

            "Lbl {&basefont tagbegin={tagname=Lbl}} " +
            "/Lbl {tagend} " +

            "LBody {&basefont tagbegin={tagname=LBody} } " +
            "/LBody {tagend} " +

            // Create a named matchbox for links; it will be used to create Link annotations 
            "Link {tagbegin={tagname=Link Title={Kraxi on the Web} Alt={Kraxi on the Web} } " +
            "matchbox={name=kraxi fillcolor=deepskyblue boxheight={capheight descender}} } " +
            "/Link {tagend matchbox=end} " +
            "}";

        /* Dummy text for filling the columns. Soft hyphens are marked with the
         * character reference "­" (character references are enabled by the
         * charref option).
         */
        final String text_P = 
            "<&P>Lorem ipsum dolor sit amet, consectetur adi&shy;pi&shy;sicing elit, " +
            "sed do eius&shy;mod tempor incidi&shy;dunt ut labore et dolore " +
            "magna ali&shy;qua. Ut enim ad minim ve&shy;niam, quis nostrud " +
            "exer&shy;citation ull&shy;amco la&shy;bo&shy;ris nisi ut " +
            "ali&shy;quip ex ea commodo con&shy;sequat. Duis aute irure dolor " +
            "in repre&shy;henderit in voluptate velit esse cillum dolore eu " +
            "fugiat nulla pari&shy;atur. Excep&shy;teur sint occae&shy;cat " +
            "cupi&shy;datat non proident, sunt in culpa qui officia " +
            "dese&shy;runt mollit anim id est laborum.<&/P>";

        // Caption text including a tagged Link
        // Important: do not combine the &Caption and &P macros in a single option
        // list since each list can hold only a single "tagbegin" option
        final String text_Caption = 
            "<&Caption>Visit our <&Link>Web site<&/Link> " +
            "for more infor&shy;ma&shy;tion about the following products:<&/Caption>\n";

        final String productlist[] = { "Apple", "Orange", "Banana" };

        try {
            p = new pdflib();

            // Make sure we are using an appropriate PDFlib version
            if ((int) p.get_option("major", "") < 10) {
                System.err.println("Error: Cookbook topic '" + title + "' requires PDFlib 10");
                System.exit(1);
            }

            /*
             * errorpolicy=exception means that the program will stop
             * if one of the API function runs into a problem.
             */
            p.set_option("errorpolicy=exception searchpath={" + searchpath + "}");         

            p.begin_document(outfile,
                    "pdfua=PDF/UA-1 lang=en tag={tagname=Document Title={" + title + "}}");

            p.set_info("Creator", "PDFlib Cookbook");
            p.set_info("Title", title);

            /* Automatically create spaces between chunks of text */
            p.set_option("autospace=true");

            // Feed macros and general options to the Textflow
            tf = p.add_textflow(tf, "", macros + " inlineoptions minlinecount=2");

            // Create some chapters
            for (int i=1; i<=count; i++)
            {
                // Tagged heading
                tf = p.add_textflow(tf, "<&H1>Chapter " + i + "<&/H1>\n", "");

                // Tagged paragraph text with inline tags
                tf = p.add_textflow(tf, text_P, "");

                // Start a tagged list
                tf = p.add_textflow(tf, "", "&L");

                // The list Caption contains a tagged Link element
                tf = p.add_textflow(tf, text_Caption, "");

                // List items
                for (int item=0; item < productlist.length; item++)
                {
                    tf = p.add_textflow(tf, "", "&LI");
                    tf = p.add_textflow(tf, "<&Lbl>&#x2022; <&/Lbl>", ""); 
                    tf = p.add_textflow(tf, "<&LBody>" + productlist[item] + "<&/LBody>\n", "");
                    tf = p.add_textflow(tf, "", "&/LI");
                }

                tf = p.add_textflow(tf, "", "&/L");
            }

            // Action for use in Web links
            act = p.create_action("URI", "url={http://www.kraxi.com}");

            /* Loop until all of the text is placed; create new pages
             * as long as more text needs to be placed. Two columns will
             * be created on all pages.
             */
            do
            {
                String optlist = "verticalalign=justify linespreadlimit=120% ";

                p.begin_page_ext(0, 0, "width=a4.width height=a4.height");

                /* Fill the first column */
                result = p.fit_textflow(tf, llx1, lly1, urx1, ury1, optlist);

                /* Fill the second column if we have more text*/
                if (!result.equals("_stop"))
                    result = p.fit_textflow(tf, llx2, lly2, urx2, ury2,optlist);

                /* Create Link annotations on all matchboxes named "kraxi"
                 * (if present on the page, otherwise the call doesn't have any effect)
                 */
                p.create_annotation(0, 0, 0, 0, "Link",
                        "action={activate " + act + "} linewidth=0 " +
                        "usematchbox={kraxi} contents={Link to Kraxi Web site}");

                p.end_page_ext("");

            /* "_boxfull" means we must continue because there is more text;
             * "_nextpage" is interpreted as "start new column"
             */
            } while (result.equals("_boxfull") || result.equals("_nextpage"));

            /* Check for errors */
            if (!result.equals("_stop"))
            {
                /* "_boxempty" happens if the box is very small and doesn't
                 * hold any text at all.
                 */
                if (result.equals( "_boxempty"))
                    throw new Exception ("Error: Textflow box too small");
                else
                {
                    /* Any other return value is a user exit caused by
                     * the "return" option; this requires dedicated code to
                     * deal with.
                     */
                    throw new Exception ("User return '" + result +
                            "' found in Textflow");
                }
            }

            p.delete_textflow(tf);

            p.end_document("");

        } catch (PDFlibException e) {
            System.err.print("PDFlib exception occurred:\n");
            System.err.print("[" + e.get_errnum() + "] " + e.get_apiname() +
                    ": " + e.get_errmsg() + "\n");
            exitcode = 1;
        } catch (Exception e) {
            System.err.println(e);
            exitcode = 1;
        } finally {
            if (p != null) {
                p.delete();
            }
            System.exit(exitcode);
        }
    }
}