You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-dev@xmlgraphics.apache.org by "Matthew L. Avizinis" <ml...@gleim.com> on 2002/07/29 21:00:08 UTC

FOP extension element

Hello all,
  I have written an FOP extension element, fop:WritePageNumber, which
outputs the page number where the element occurs in the fo document.  It has
several properties which allow to specify a filename, whether to start a new
file, append to an existing file, or close the root element of an existing
file, a root-element, child element-name, an id for the element.

If a root element is not specified <info> is used by default.
If a child element is not specified <x-ref> is used by default.
file = "new | append | end"
id = "string value"
filename = "string value"

So if you wrote:
<fop:WritePageNumber filename="index.xml" file="new" root-element="index"
element-name="indexterm" id="primary_test1"/>
<fop:WritePageNumber filename="index.xml" element-name="indexterm"
id="secondary_test2"/>
<fop:WritePageNumber filename="index.xml" file="end"
element-name="indexterm" id="secondary_test3"/>

you could have in file index.xml (page numbers chosen arbitrarily for this
example):
<index>
  <indexterm id="primary_test1">325</indexterm>
  <indexterm id="secondary_test2">326</indexterm>
  <indexterm id="secondary_test3">327</indexterm>
</index>

This has been useful for me because it allows me to process many chapters of
a book individually through FOP then put them together and still produce an
index and various other cross references across chapters.  It also allow the
generation of a table of contents without having to use forward page
references and thus the necessity of processing all chapters as one big
file.

If anyone else thinks this is something useful, I will post the code for
review.  It's not perfect code but it works.

   Matthew L. Avizinis <ma...@gleim.com>
Gleim Publications, Inc.
   4201 NW 95th Blvd.
 Gainesville, FL 32606
(352)-375-0772
      www.gleim.com <http://www.gleim.com>


---------------------------------------------------------------------
To unsubscribe, e-mail: fop-dev-unsubscribe@xml.apache.org
For additional commands, email: fop-dev-help@xml.apache.org


RE: FOP extension element

Posted by "Matthew L. Avizinis" <ml...@gleim.com>.
In response to a request here is the code and instructions to compile it.
The following properties need to be added to src/codegen/extproperties.xml.
Also, for reasons unknown to me FOP will not compile correctly unless they
also appear in src/codegen/foproperties.xml.
<!--  .....BEGIN ON NEXT LINE........  -->
    <property>
      <name>filename</name>
      <inherited>false</inherited>
      <datatype>String</datatype>
      <default></default>
    </property>
    <property>
      <name>file</name>
      <inherited>false</inherited>
      <datatype>String</datatype>
      <default></default>
    </property>
    <property>
      <name>id</name>
      <inherited>false</inherited>
      <datatype>String</datatype>
      <default></default>
    </property>
    <property>
      <name>root-element</name>
      <inherited>false</inherited>
      <datatype>String</datatype>
      <default></default>
    </property>
    <property>
      <name>element-name</name>
      <inherited>false</inherited>
      <datatype>String</datatype>
      <default></default>
    </property>
<!--  .....END ON PREVIOUS LINE........  -->

Add the following line to
src/org/apache/fop/extensions/ExtensionElementMapping.java
<!--  .....BEGIN ON NEXT LINE........  -->
            foObjs.put("WritePageNumber", WritePageNumber.maker());
<!--  .....END ON PREVIOUS LINE........  -->

Here is the code for WritePageNumber.java
<!--  .....BEGIN ON NEXT LINE........  -->
/*
 * $Id: Label.java,v 1.3 2002/02/18 20:29:20 matthew Exp $
 * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
 * For details on use and redistribution please refer to the
 * LICENSE file included with these sources.
 */

package org.apache.fop.extensions;

import java.io.*;
//FOP
import org.apache.fop.render.Renderer;
import org.apache.fop.fo.*;
import org.apache.fop.fo.flow.*;
import org.apache.fop.fo.properties.*;
import org.apache.fop.layout.*;
import org.apache.fop.datatypes.*;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.*;


public class WritePageNumber extends ExtensionObj {

    public static class Maker extends FObj.Maker {
        public FObj make(FObj parent, PropertyList propertyList) {
            return new WritePageNumber(parent, propertyList);
        }

    }

    public static FObj.Maker maker() {
        return new WritePageNumber.Maker();
    }
    String id;
    String filename;
    String file;
    String root_element;
    String element_name;


    public WritePageNumber(FObj parent, PropertyList propertyList) {
        super(parent, propertyList);
	}

    public Status layout(Area area) throws FOPException {
        if (!(area instanceof BlockArea)) {
            log.warn("write-page-number outside block area");
            return new Status(Status.OK);
        }

        /* The name of the file where to emit the page number */
        filename = this.properties.get("filename").getString();
        if (this.filename == null || this.filename.equals("")){
			log.warn("WritePageNumber filename property value required");
			return new Status(Status.OK);
		}

        /* file = "new | append | end", i.e. this is a new file,
        append to an existing file, or close the file to make it
        a valid xml file.  */
        this.file = this.properties.get("file").getString();

		/* This is so you can associate an id with the page number */
        this.id = this.properties.get("id").getString();
        if (this.id == null || this.id.equals("")){
			this.id = "not-defined-in-either-xml-or-xslt-file";
		}

        this.root_element = this.properties.get("root-element").getString();
        /* If the property isn't defined or is empty give it a default
value. */
        if (this.root_element == null || this.root_element.equals("")){
			this.root_element = "info";
		}

        this.element_name = this.properties.get("element-name").getString();
        /* If the property isn't defined or is empty give it a default
value. */
        if (this.element_name == null || this.element_name.equals("")){
			this.element_name = "x-ref";
		}

        /* OK, now assign the actual page number to p. */
        String p = area.getPage().getFormattedNumber();

        try{
			// Only in the case where file = "new" should a new file be opened.
			BufferedWriter out = new BufferedWriter(new
FileWriter(filename,(!"new".equals(file))));
			// Insert the root element if this is a new file.
			if ("new".equals(file)){
				out.write("<" + root_element + ">\n");
			}
			// emit the element an id and the page the id is on
			out.write("   <" + element_name + " id=\"" + this.id + "\">" + p + "</" +
element_name + ">\n");
			// Close the root element to make the file a valid xml file.
			out.flush();
			if ("end".equals(file)){
			try{
				BufferedReader in = new BufferedReader(new FileReader(filename));
				String root;
				root = in.readLine();
				out.write("</" + root.substring(1));
				in.close();
			} catch(IOException e){
			}
			}
			out.close();
		} catch (IOException e){
		}
        return new Status(Status.OK);
    }

}
<!--  .....END ON PREVIOUS LINE........  -->
Once all this is in place you should be able to just build FOP in the normal
way.  WritePageNumber.class will be put into the fop.jar.
To use the element place   xmlns:fop="http://xml.apache.org/fop/extensions"
in the xsl:stylesheet element and specify the element as described below.
When FOP is run you will end up with your pdf and an extra xml file.  To
make sure it is a valid xml file, make sure that the first time
WritePageNumber is used to include file="new" and that WritePageNumber
includes file="end" the last time it is used to properly close the root
element, whatever that happens to be.  The root element only has to be
specified once with file="new" if you want to use an element name other than
the default one because when file="end" is used the root element will be
read from the file being written and closed appropriately.
Finally, I am sure there are corrections that can be made to the code.  I
have not been programming in Java nearly as long as some of you in this
list, so please be kind with your critique.  Be that as it may, the code
works (with at least 0.20.4) and I think the element is rather nifty and I'd
be glad to hear if any of you use it in an interesting way.
Have fun,
   Matthew L. Avizinis <ma...@gleim.com>
Gleim Publications, Inc.
   4201 NW 95th Blvd.
 Gainesville, FL 32606
(352)-375-0772
      www.gleim.com <http://www.gleim.com>

=======================================================================
com·put·ing (kum' pyoot ing)
1. n the art of calculating how much time you wasted and money you spent in
a doomed attempt to master a machine with a mind of it's own. --from
computing: A HACKER'S DICTIONARY




> -----Original Message-----
> From: Matthew L. Avizinis [mailto:mla@gleim.com]
> Sent: Monday, July 29, 2002 3:00 PM
> To: fop-dev@xml.apache.org
> Subject: FOP extension element
>
>
> Hello all,
>   I have written an FOP extension element, fop:WritePageNumber, which
> outputs the page number where the element occurs in the fo
> document.  It has
> several properties which allow to specify a filename, whether to
> start a new
> file, append to an existing file, or close the root element of an existing
> file, a root-element, child element-name, an id for the element.
>
> If a root element is not specified <info> is used by default.
> If a child element is not specified <x-ref> is used by default.
> file = "new | append | end"
> id = "string value"
> filename = "string value"
>
> So if you wrote:
> <fop:WritePageNumber filename="index.xml" file="new" root-element="index"
> element-name="indexterm" id="primary_test1"/>
> <fop:WritePageNumber filename="index.xml" element-name="indexterm"
> id="secondary_test2"/>
> <fop:WritePageNumber filename="index.xml" file="end"
> element-name="indexterm" id="secondary_test3"/>
>
> you could have in file index.xml (page numbers chosen arbitrarily for this
> example):
> <index>
>   <indexterm id="primary_test1">325</indexterm>
>   <indexterm id="secondary_test2">326</indexterm>
>   <indexterm id="secondary_test3">327</indexterm>
> </index>
>
> This has been useful for me because it allows me to process many
> chapters of
> a book individually through FOP then put them together and still
> produce an
> index and various other cross references across chapters.  It
> also allow the
> generation of a table of contents without having to use forward page
> references and thus the necessity of processing all chapters as one big
> file.
>
> If anyone else thinks this is something useful, I will post the code for
> review.  It's not perfect code but it works.
>
>    Matthew L. Avizinis <ma...@gleim.com>
> Gleim Publications, Inc.
>    4201 NW 95th Blvd.
>  Gainesville, FL 32606
> (352)-375-0772
>       www.gleim.com <http://www.gleim.com>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: fop-dev-unsubscribe@xml.apache.org
> For additional commands, email: fop-dev-help@xml.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: fop-dev-unsubscribe@xml.apache.org
For additional commands, email: fop-dev-help@xml.apache.org


RE: FOP extension element

Posted by "Matthew L. Avizinis" <ml...@gleim.com>.
I meant to say, it's not particularly pretty code, but it works.  It's
simple so it shouldn't really have any defects.

>
> If anyone else thinks this is something useful, I will post the code for
> review.  It's not perfect code but it works.
>
>    Matthew L. Avizinis <ma...@gleim.com>
> Gleim Publications, Inc.
>    4201 NW 95th Blvd.
>  Gainesville, FL 32606
> (352)-375-0772
>       www.gleim.com <http://www.gleim.com>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: fop-dev-unsubscribe@xml.apache.org
> For additional commands, email: fop-dev-help@xml.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: fop-dev-unsubscribe@xml.apache.org
For additional commands, email: fop-dev-help@xml.apache.org