Tell me more ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Here is an ant script for generating TeX code and documentation for one LaTeX class and one LaTeX package. It is my first larger ant script: I welcome suggestions for improvements.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project name="customer TeX code" default="main">
<description>Buildscript for the LaTeX classes and packages</description>

<property name="foo" value="foo" />
<property name="bar" value="bar" />

<!-- target: init -->
<target name="init" description="initialize properties">
    <condition property="foo.uptodate">
        <and>
            <available file="${foo}.cls" />
            <available file="${foo}.drv" />
            <available file="${foo}.pdf" />
            <uptodate property="foo.cls.uptodate" targetfile="${foo}.cls">
                <srcfiles file="${foo}.dtx" />
                <srcfiles file="${foo}.ins" />
            </uptodate>
            <uptodate property="foo.drv.uptodate" targetfile="${foo}.drv">
                <srcfiles file="${foo}.dtx" />
                <srcfiles file="${foo}.ins" />
            </uptodate>
            <uptodate property="foo.pdf.uptodate" targetfile="${foo}.pdf">
                <srcfiles file="${foo}.dtx" />
                <srcfiles file="${foo}.ins" />
            </uptodate>
        </and>
    </condition>
    <condition property="bar.uptodate">
        <and>
            <available file="${bar}.sty" />
            <available file="${bar}.drv" />
            <available file="${bar}.pdf" />
            <uptodate property="bar.sty.uptodate" targetfile="${bar}.sty">
                <srcfiles file="${bar}.dtx" />
                <srcfiles file="${bar}.ins" />
            </uptodate>
            <uptodate property="bar.drv.uptodate" targetfile="${bar}.drv">
                <srcfiles file="${bar}.dtx" />
                <srcfiles file="${bar}.ins" />
            </uptodate>
            <uptodate property="bar.pdf.uptodate" targetfile="${bar}.pdf">
                <srcfiles file="${bar}.dtx" />
                <srcfiles file="${bar}.ins" />
            </uptodate>
        </and>
    </condition>
</target>

<!-- target: foo -->
<target name="foo" unless="foo.uptodate" depends="init" description="builds all files for the foo class">
    <exec executable="latex" failonerror="true">
        <arg value="${foo}.ins" />
    </exec>
    <exec executable="lualatex" failonerror="true">
        <arg value="-draftmode" />
        <arg value="${foo}.drv" />
    </exec>
    <parallel>
        <exec executable="makeindex" failonerror="true">
            <arg value="-s" />
            <arg value="gind.ist" />
            <arg value="-t" />
            <arg value="${foo}.ind.ilg" />
            <arg value="${foo}.idx" />
        </exec>
        <exec executable="makeindex" failonerror="true">
            <arg value="-s" />
            <arg value="gglo.ist" />
            <arg value="-t" />
            <arg value="${foo}.gls.ilg" />
            <arg value="-o" />
            <arg value="${foo}.gls" />
            <arg value="${foo}.glo" />
        </exec>
    </parallel>
    <exec executable="lualatex" failonerror="true">
        <arg value="-draftmode" />
        <arg value="${foo}.drv" />
    </exec>
    <exec executable="lualatex" failonerror="true">
        <arg value="${foo}.drv" />
    </exec>
</target>

<!-- target: bar -->
<target name="bar" unless="bar.uptodate" depends="init" description="builds all files for the bar package">
    <exec executable="latex" failonerror="true">
        <arg value="${bar}.ins" />
    </exec>
    <exec executable="lualatex" failonerror="true">
        <arg value="-draftmode" />
        <arg value="${bar}.drv" />
    </exec>
    <parallel>
        <exec executable="makeindex" failonerror="true">
            <arg value="-s" />
            <arg value="gind.ist" />
            <arg value="-t" />
            <arg value="${bar}.ind.ilg" />
            <arg value="${bar}.idx" />
        </exec>
        <exec executable="makeindex" failonerror="true">
            <arg value="-s" />
            <arg value="gglo.ist" />
            <arg value="-t" />
            <arg value="${bar}.gls.ilg" />
            <arg value="-o" />
            <arg value="${bar}.gls" />
            <arg value="${bar}.glo" />
        </exec>
    </parallel>
    <exec executable="lualatex" failonerror="true">
        <arg value="-draftmode" />
        <arg value="${bar}.drv" />
    </exec>
    <exec executable="lualatex" failonerror="true">
        <arg value="${bar}.drv" />
    </exec>
</target>

<!-- target: main -->
<target name="main" depends="foo, bar" description="default target" />
</project>

EDIT: Now with <macrodef> as suggested by @palacsint

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project name="customer TeX code" default="main">
<description>Buildscript for the LaTeX classes and packages</description>

<property name="foo" value="foo" />
<property name="bar" value="bar" />

<!-- macrodef: latex-uptodate -->
<macrodef name="latex-uptodate" description="checks if a latex package or class (the extension is given in the extension attribute) is newer than its source files">
    <attribute name="basename" default="unknown" />
    <attribute name="extension" default="cls" />
    <sequential>
        <condition property="@{basename}.uptodate">
            <and>
                <available file="@{basename}.@{extension}" />
                <available file="@{basename}.drv" />
                <available file="@{basename}.pdf" />
                <uptodate property="@{basename}.@{extension}.uptodate" targetfile="@{basename}.@{extension}">
                    <srcfiles file="@{basename}.dtx" />
                    <srcfiles file="@{basename}.ins" />
                </uptodate>
                <uptodate property="@{basename}.drv.uptodate" targetfile="@{basename}.drv">
                    <srcfiles file="@{basename}.dtx" />
                    <srcfiles file="@{basename}.ins" />
                </uptodate>
                <uptodate property="@{basename}.pdf.uptodate" targetfile="@{basename}.pdf">
                    <srcfiles file="@{basename}.dtx" />
                    <srcfiles file="@{basename}.ins" />
                </uptodate>
            </and>
        </condition>
    </sequential>
</macrodef>

<!-- macrodef: compile-latex -->
<macrodef name="compile-latex" description="builds and compiles a latex package or class">
    <attribute name="filename" default="unknown" />
    <sequential>
        <exec executable="latex" failonerror="true">
            <arg value="@{filename}.ins" />
        </exec>
        <parallel>
            <exec executable="makeindex" failonerror="true">
                <arg value="-s" />
                <arg value="gind.ist" />
                <arg value="-t" />
                <arg value="@{filename}.ind.ilg" />
                <arg value="@{filename}.idx" />
            </exec>
            <exec executable="makeindex" failonerror="true">
                <arg value="-s" />
                <arg value="gglo.ist" />
                <arg value="-t" />
                <arg value="@{filename}.gls.ilg" />
                <arg value="-o" />
                <arg value="@{filename}.gls" />
                <arg value="@{filename}.glo" />
            </exec>
        </parallel>
        <exec executable="lualatex" failonerror="true">
            <arg value="-draftmode" />
            <arg value="@{filename}.drv" />
        </exec>
        <exec executable="lualatex" failonerror="true">
            <arg value="@{filename}.drv" />
        </exec>
    </sequential>
</macrodef>

<!-- target: init -->
<target name="init" description="initialize properties">
    <parallel>
        <latex-uptodate basename="${foo}" />
        <latex-uptodate basename="${bar}" extension="sty" />
    </parallel>
</target>

<!-- target: foo -->
<target name="foo" unless="${foo}.uptodate" depends="init" description="builds all files for the foo class">
    <compile-latex filename="${foo}" />
</target>

<!-- target: bar -->
<target name="bar" unless="${bar}.uptodate" depends="init" description="builds all files for the bar package">
    <compile-latex filename="${bar}" />
</target>

<!-- target: main -->
<target name="main" depends="foo, bar" description="default target" />
</project>

EDIT2: latex-uptodate now with union and srcresources.

<!-- macrodef: latex-uptodate -->
<macrodef name="latex-uptodate" description="checks if a latex package or class (the extension is given in the extension attribute) is newer than its source files">
    <attribute name="basename" />
    <attribute name="extension" />
    <sequential>
        <union id="latex-src-union">
            <filelist>
                <file name="@{basename}.dtx" />
                <file name="@{basename}.ins" />
            </filelist>
        </union>
        <condition property="@{basename}.uptodate">
            <and>
                <available file="@{basename}.@{extension}" />
                <available file="@{basename}.drv" />
                <available file="@{basename}.pdf" />
                <uptodate property="@{basename}.@{extension}.uptodate" targetfile="@{basename}.@{extension}">
                    <srcresources refid="latex-src-union" />
                </uptodate>
                <uptodate property="@{basename}.drv.uptodate" targetfile="@{basename}.drv">
                    <srcresources refid="latex-src-union" />
                </uptodate>
                <uptodate property="@{basename}.pdf.uptodate" targetfile="@{basename}.pdf">
                    <srcresources refid="latex-src-union" />
                </uptodate>
            </and>
        </condition>
    </sequential>
</macrodef>
share|improve this question
Can’t comment specifically on the ant file but it seems like a lot of effort. Are you aware of the existence of latexmk which ships with all modern TeX distributions and which is a versatile build tool for TeX (requiring in most cases zero configuration)? – Konrad Rudolph Jul 19 '12 at 19:11
@KonradRudolph: Yes. But I need it on Windows, MacOS and Linux. And I fear that the configuration latexmk needs for this build process and the dependencies is also quite non-trivial. And I wanted to learn ant. :-) – Martin Schröder Jul 19 '12 at 20:17

1 Answer

up vote 2 down vote accepted

The bar and foo targets (as well as the conditions on foo.uptodate and bar.uptodate) seems really similar to each other. I'd try to remove this duplication with a presetdef or a macrodef

Reply for the edit:

Nice to see that the macrodef works :-). A few other ideas:

  1. <attribute name="basename" default="unknown" />
    

    Are you sure that you need the default attribute here? The macrodef documentation says the following:

    The attributes will be required attributes unless a default value has been set.

  2. I'd create a list for

    <srcfiles file="@{basename}.dtx" />
    <srcfiles file="@{basename}.ins" />
    

    Here is an example: Ant: using Filelist as Fileset in Uptodate?

  3. After this I guess the three uptodate tag could be replaced with only one which uses a composite or a chained mapper but I'm not too familiar with these.

share|improve this answer
1  
Thanks; I've added a new version with macrodef to the question. – Martin Schröder Jul 18 '12 at 14:41
@MartinSchröder: Thanks for the feedback! I've updated the answer. – palacsint Jul 18 '12 at 18:20
Thanks. I've updated the question with a new version with union and srcresources. That seems to be an area that's severly underdocumented in the online manual. :-( – Martin Schröder Jul 19 '12 at 10:05

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.