How To

hints and ideas for using Xilize

ant "xilize" macro

For use in a ant build file. Modify it to suit your needs.

    <path id="xilpath" path="">
        <pathelement path="${engine.jar}" />  <!-- path to xilize-jEdit.jar -->
        <pathelement path="${bsh.jar}" />     <!-- pick one from here -->
    </path>

    <macrodef name="xilize">
        <attribute name="args"/>
        <sequential>
            <java
                    classpathref="xilpath"
                    classname="com.centeredwork.xilize.Main"
                    failonerror="true"
                    fork="true">
                <sysproperty key="_Silent_" value="${xsilent}"/>
                <arg line="@{args}"/>
            </java>
        </sequential>
    </macrodef>

Example usage:

    <target name="html" depends="init" description="xilize docs tree and copy to html/">
        <xilize args="docs" />
        <delete dir="html" />
        <mkdir dir="html" />
        <copy includeemptydirs="false" todir="html">
            <fileset
                    dir="docs"
                    excludes="**/*.xil,**/*.xilconfig,**/*.xilinc,**/*.bsh,**/*.svn" />
        </copy>
    </target>

See here for a complete if minimal build file.

jEdit "folding" macro

When using jEdit to write a large file Xilize source file, jEdit's explicit fold feature is handy — for example to fold each h2. or h3. heading. This jEdit macro folds whatever lines are highlighted.

Note: this is general purpose, not specific to Xilize.

// File:  fold.bsh

// Highlight text to fold then run this macro to create an explict fold.
// The top line of the selected text will be copied to the first fold comment line.

if(textArea.getSelectionCount() == 0 )
    return;
textArea.addExplicitFold();
textArea.goToNextLine(false);
textArea.goToStartOfWhiteSpace(false);
textArea.goToEndOfWhiteSpace(true);
Registers.copy(textArea,'$');
textArea.goToPrevLine(false);
textArea.goToEndOfWhiteSpace(false);
Registers.paste(textArea,'$',false);
textArea.collapseFold();
textArea.goToStartOfWhiteSpace(false);
textArea.goToNextLine(false);
textArea.insertEnterAndIndent();

using system properties to control output

Patrick asks,

I've written our user's guide using Xilize, and using Flying Saucer, can generate PDF from that. FS uses CSS to control all layout and formatting, and for PDF output, restricts itself to CSS marked as "print" media.

I'd like to have two different versions, one in size A4 and one in US Letter. The page size is specified by CSS, which is either embedded or linked in. Question is, how could I create two different versions of the same doc where only one value (a CSS string) changes? Can I somehow pass in variables to replace during generation?

jEdit Plugin solution

Assuming you are using the Xilize plugin for jEdit here is one solution. A similar method for using Xilize from the command line or from ant is also described.

The Xilize method for variable substitution is like ant's. ${key} is translated to the value of key. You give key a value with the define. directive. See this chapter of the User Guide.

Say you define printSize like this

    define. printSize US-letter

and use ${printSize} throughout your markup. This unlikely to be the precise solution to your actual problem but I offer it to describe the general technique.

The question is then how do you change the value of printSize from one execution of Xilize to the next without having to change your Xilize source file?

One option is use system properties and a combination of Xilize macros and jEdit macros. Xilize macros are similar to jEdit's in that they are both written in BeanShell. However, don't confuse the two. jEdit macros run in the jEdit environment and Xilize macros are executed by Xilize during markup translation.

You can write:

    define. printSize &{ System.getProperty("active.print.size") }

to assign the value of a system property to an Xilize key.

(Note the macro syntax begins with & not $ to distinguish it from value substitution. Any BeanShell snippet can be used in a macro with ; separating multiple statements. BeanShell code can also be placed in an external file. Since Xilize loads and evaluates all *.bsh files it finds as it processes a directory tree, any BeanShell code in those files can be used in macros and custom signatures. Using BeanShell you effectively have all the power of Java at your fingertips to use in Xilize markup.)

To get the printSize into the environment so the define. statement above can access it, use a jEdit macro, actually two of them.

This one for A4:

    System.setProperty("active.print.size", "A4");

And this one for US-letter:

    System.setProperty("active.print.size", "US-letter");

After creating those two jEdit macro files and perhaps assigning shortcuts to them, you can easily toggle between generating two different variants of the HTML produced with one Xilize source file. Properties set this way in a jEdit macro are persistent in the jEdit environment. So every time you run Xilize the value given to printSize will be that of the last System.setProperty() call issued.

You might also extend the macros to run Xilize and FlyingSaucer on the generated HTML to produce the PDF.

Any of these statements can be used in a jEdit macro to drive Xilize:

    xilize.Exec.getInstance().file(buffer.getPath());
    xilize.Exec.getInstance().directory(buffer.getPath());
    xilize.Exec.getInstance().branch(buffer.getPath());
    xilize.Exec.getInstance().project(buffer.getPath());

And of course you can use Runtime.getRuntime().exec(...) or some equivalent to drive FlyingSaucer from a jEdit macro.

controlling CSS

Patrick says above, "The page size is specified by CSS, which is either embedded or linked in." So he may want to modify HTML's <head> element. Xilize provides two ways to do that.

The first is described here in the User Guide but may not be sufficient for this case. The other method is more general, customizing the head element.

The same technique as above can be used:

define. headElementAdd  &{ System.getProperty("extend.head") }

using conditionals

Xilize also has an if...else... construct that can be used like this:

    if. System.getProperty("active.print.size").equals("A4") {{

        print size is A4

        else. {{

            print size is US-letter

         }}

    }}

The else part is optional. The more common variants use ifdef or ifndef and test for existence of a key being defined.

don't do this

Note: the following will not work:

  if. System.getProperty("active.print.size").equals("A4") {{

      define. x A4

          else. {{

              define. x US-letter

          }}

  }}

Because define. is always evaluated before anything else, the value of ${x} will always be "US-letter".

command line solution

When running Xilize from the command line or from ant, the same strategy as described above can be used with one modification. Instead of using jEdit macros to set system properties, use the normal ant or Java method.

When running Xilize directly from the command line, use Java's -Dkey=value syntax. For example:

    java -Dactive.print.size=A4 ...

If you use the Xilize ant macro, you can modify it by adding <sysproperty.../> elements:

    <sysproperty key="active.print.size" value="${print.size}"/>

and give the ant property print.size a value with any of the many normal ant mechanisms.