<?xml version="1.0"?>
<!--
============================================================
 $Date$
 $Author$
 $Rev$
============================================================

NAnt build script for the TortoiseSVN documentation

All project specific configuration is stored in doc.build.include.
All user/site specific configuration is stored in doc.build.user.

-->

<project name="Documentation" default="all" basedir=".">
  <description>
    Builds the Documentation in all languages and all output formats
  </description>

  <!-- default: we don't clean first -->
  <property name="cleanup" value="" overwrite="false" />

  <include buildfile="doc.build.include" />
  
  <!-- we don't translate the docs anymore -->
  <property name="languages" value="en" overwrite="true" />

  <!-- ====================================================================== -->
  <!-- Loop over all languages                                                -->
  <!-- ====================================================================== -->

  <target name="all"
    description="Loop over all languages, output formats and applications and build documentation"
    depends="prepare">

    <foreach item="String" in="${languages}" delim="," property="lang.target">
      <!-- language code for English (US) (default)-->
      <property name="lang.target.code" value="1033" />
      <property name="languagebuildfile" value="${path.user.xsl}/${lang.target}/lang.build" />
      <if test="${file::exists(languagebuildfile)}">
        <include buildfile="${languagebuildfile}" />
      </if>
      <call target="doit" failonerror="${critical or lang.base==lang.target}" />
    </foreach>
  </target>

  <!-- ====================================================================== -->
  <!-- Loop over all applications and output formats                          -->
  <!-- ====================================================================== -->

  <target name="doit">

    <foreach item="String" in="${applications}" delim="," property="app">
      <property name="doc.source.file" value="source/${lang.base}/${app}.xml" />
      <property name="doc.base.name" value="${app}_${lang.base}" />
      <property name="doc.base.work" value="output/${doc.base.name}" />

      <property name="doc.target.name" value="${app}_${lang.target}" />
      <property name="doc.target.work" value="output/${doc.target.name}" />
      <property name="doc.target.source" value="source/${lang.target}/${app}/${app}.xml" />
      <property name="lang.pofile" value="../Languages/${lang.target}/TortoiseDoc.po" />

      <echo message="------------------------------------------------------------" />
      <echo message="Creating '${doc.target.name}' documentation" />

      <if test="${lang.base==lang.target or file::exists(lang.pofile)}">
        <!-- update version info in version.xml -->
        <call target="UpdateVersionInfo" />

        <call target="spellcheck" if="${property::exists('spellcheck') and spellcheck=='true'}" />

        <property name="xslt.source" value="${doc.target.source}" />
        <call target="copyimages"/>
        <foreach item="String" in="${docformats}" delim="," property="docformat">
          <call target="${docformat}" />
        </foreach>
      </if>
    </foreach>
  </target>

  <!-- ====================================================================== -->
  <!-- ====================================================================== -->

  <target name="clean" description="remove all generated files">
    <if test="${cleanup == 'yes'}">
      <delete dir="output" failonerror="false" />
    </if>
  </target>

  <!-- ====================================================================== -->
  <!-- ====================================================================== -->

  <target name="prepare" description="Create directories" depends="clean">
    <mkdir dir="output" />
    <call target="prepare.custom" if="${target::exists('prepare.custom')}" />

    <!-- find the path to the fonts -->
    <property name="fontpath" value="${string::replace(environment::get-variable('windir'), '\', '/')}/Fonts/" if="${not property::exists('fontpath')}"/>
    <fail unless="${directory::exists(fontpath)}">fontpath '${fontpath}' does not exist</fail>

    <!-- ensure "Version" translation invariant -->
    <copy file="source\${lang.base}\version.in" tofile="source\${lang.base}\version.xml" overwrite="true" />

    <!-- tune path to xsltproc.exe in aspell.bat -->
    <copy file="Aspell/aspell.in" tofile="Aspell/aspell.bat" overwrite="true">
      <filterchain>
        <replacetokens begintoken="$" endtoken="$">
          <token key="XSLTProcPath" value="${path.bin}" />
        </replacetokens>
      </filterchain>
    </copy>

    <!-- make sure the font metrics files are available -->
    <property name="metricsfile" value="xsl/fonts/arial.xml" />
    <if test="${not file::exists(metricsfile)}">
      <property name="configmetricsfile" value="xsl/fonts/config.bat" />
      <if test="${not file::exists(configmetricsfile)}">
        <echo level="Warning">
          The file /docs/xsl/fonts/config.bat is missing. We will auto-create
          it from the config.bat.sample file before building the docs. Please
          consider adapting it to your needs.
        </echo>
      </if>
      <exec program="createmetrics.bat"
            basedir="xsl/fonts"
            workingdir="xsl/fonts"
            verbose="false" />
    </if>

  </target>

  <!-- ====================================================================== -->
  <!-- ====================================================================== -->

  <target name="copyimages" description="Copy images">
    <delete dir="${doc.target.work}/images" failonerror="false" />
    <mkdir dir="${doc.target.work}/images" />

    <property name="xslt.params" value="${xsl.pdf.params}"/>
    <property name="xslt.target" value="${path::get-temp-file-name()}"/>
    <exec program="xsltproc"
          commandline="${xslt.params} --output ${xslt.target} images/extract-images.xsl ${xslt.source}"
          basedir="${path.bin}"
          verbose="false"/>
    <foreach item="Line" in="${xslt.target}" property="filename" trim="Both">
      <property name="destname" value="${doc.target.work}/images/${filename}"/>
      <copy file="images/${lang.target}/${filename}" tofile="${destname}" if="${file::exists(path::combine('images', path::combine(lang.target, filename)))}"/>
      <copy file="images/${lang.base}/${filename}" tofile="${destname}" unless="${file::exists(destname)}"/>
    </foreach>

    <copy todir="${doc.target.work}/images">
      <fileset basedir="images/${lang.base}">
        <include name="caution.png"/>
        <include name="warning.png"/>
        <include name="important.png"/>
        <include name="tip.png"/>
        <include name="link.png"/>
        <include name="note.png"/>
        <include name="Tortoise.png"/>
      </fileset>
    </copy>
  </target>

  <!-- ====================================================================== -->
  <!-- ====================================================================== -->

  <target name="uptodate" description="Check whether the given target is up to date">

    <echo message="Checking if '${file.target}' is up to date" />
    <uptodate property="file.target.uptodate">
      <sourcefiles>
        <include name="source/${lang.target}/${app}/**/*.xml" />
        <include name="source/${lang.target}/pubdate.xml" />
        <include name="source/${lang.target}/glossary.xml" />
        <include name="source/${lang.target}/wishlist.xml" />
        <include name="source/${lang.target}/version.in" />
      </sourcefiles>
      <targetfiles>
        <include name="${file.target}" />
      </targetfiles>
    </uptodate>
    <if test="${file.target.uptodate}">
      <echo message="Up to date" />
    </if>
  </target>

  <!-- ====================================================================== -->
  <!-- Run xsltproc with the defined parameters                               -->
  <!-- ====================================================================== -->

  <target name="xsltproc" description="Run xsltproc with the defined parameters">
    <echo message="Processing XML Source" />

    <!-- Check whether a language specific xsl file exists and use it -->
    <!-- if none is found, load XSL file from default location.       -->
    <property name="xslt.file.lang" value="${path.user.xsl}/${lang.target}/${xslt.file}" />
    <property name="xslt.file" value="${xslt.file.lang}" if="${file::exists(xslt.file.lang)}" />
    <property name="xslt.file" value="${path.user.xsl}/${xslt.file}" unless="${file::exists(xslt.file.lang)}" />

    <echo message="Stylesheet: ${xslt.file}" />
    <echo message="Parameters: ${xslt.params}" />
    <property name="xslt.output.file" value="${path::get-temp-file-name()}"/>
    <exec program="xsltproc"
          commandline="${xslt.params} --output ${xslt.target} ${xslt.file} ${xslt.source}"
          basedir="${path.bin}"
          output="${xslt.output.file}"
          verbose="false" />
    <loadfile file="${xslt.output.file}" property="xsltproc.output" />
    <fail if="${string::contains(xsltproc.output, ': parser error :')}">"Parser error" found</fail>
    <fail if="${string::contains(xsltproc.output, 'Error: no ID for constraint linkend:')}">"Error: no ID for constraint linkend:" found</fail>
    <fail if="${string::contains(xsltproc.output, 'ERROR: xref linking to ')}">"ERROR: xref linking to" found</fail>
  </target>

  <!-- ====================================================================== -->
  <!-- Profile source into a single file                                      -->
  <!-- ====================================================================== -->

  <target name="profile" description="Profile source into a single file">

    <call target="uptodate" />

    <if test="${not file.target.uptodate}">
      <property name="xslt.params" value="${xsl.profile.params}" />
      <property name="xslt.file" value="${xsl.profile.file}" />
      <property name="xslt.target" value="${file.target}.tmp" />

      <echo message="Profiling into: ${file.target}" />
      <call target="xsltproc" />

      <!-- Removes the moreinfo="" attributes added by xsltproc -->
      <move file="${xslt.target}" tofile="${file.target}" overwrite="true">
        <filterchain>
          <replacestring from=" moreinfo=&quot;none&quot;" to="" />
          <replacestring from="width=&quot;auto&quot; height=&quot;auto&quot; content-width=&quot;auto&quot; content-height=&quot;auto&quot;"
                         to="inline-progression-dimension.maximum=&quot;100%&quot; content-width=&quot;scale-down-to-fit&quot; content-height=&quot;scale-down-to-fit&quot;" />
        </filterchain>
      </move>
    </if>
  </target>


  <!-- ====================================================================== -->
  <!-- Try to update version info in the version file                         -->
  <!-- ====================================================================== -->

  <target name="UpdateVersionInfo" description="Updates the version file with version info">

    <copy
      file="source\${lang.target}\version.in"
      tofile="source\${lang.target}\version.xml"
      overwrite="true">

      <filterchain>
        <replacetokens begintoken="$" endtoken="$">
          <token key="MajorVersion" value="${environment::get-variable('MajorVersion')}" />
          <token key="MinorVersion" value="${environment::get-variable('MinorVersion')}" />
          <!--
          <token key="WCREV" value="${environment::get-variable('WCREV')}" />
-->
        </replacetokens>
      </filterchain>
    </copy>

  </target>

  <!-- ====================================================================== -->
  <!-- Run spellchecker on files                                              -->
  <!-- ====================================================================== -->

  <target name="spellcheck" description="Run spellchecker on files">
    <echo message="Spellchecking: '${app} ${lang.target}' This may take a few minutes" />
    <property name="spellcheck.log" value="ASpell/${app}_${lang.target}.log" />
    <mkdir dir="ASpell/${app}_${lang.target}" />

    <echo message="--- Spellchecking: '${lang.target}'"
      file="${spellcheck.log}"
      failonerror="false" />

    <copy file="Aspell/TortoiseSVN.tmpl.pws" tofile="Aspell/Temp.pws" overwrite="true">
      <filterchain>
        <replacetokens begintoken="$" endtoken="$">
          <token key="LANG" value="${lang.target}" />
        </replacetokens>
      </filterchain>
    </copy>

    <foreach item="File" property="file.base">
      <in>
        <items>
          <include name="source/${lang.base}/${app}/**/*.xml" />
          <include name="source/${lang.base}/glossary.xml" />
          <include name="source/${lang.base}/wishlist.xml" />
        </items>
      </in>
      <do>
        <property name="file.target" value="${string::replace(file.base,'\'+lang.base+'\','\'+lang.target+'\')}" />
        <property name="file.log" value="ASpell\${app}_${lang.target}\${path::get-file-name(file.target)}.log" />

        <uptodate property="file.target.uptodate">
          <sourcefiles>
            <include name="${file.target}" />
            <include name="ASpell/${lang.target}.pws" />
            <include name="ASpell/TortoiseSVN.tmpl.pws" />
          </sourcefiles>
          <targetfiles>
            <include name="${file.log}" />
          </targetfiles>
        </uptodate>

        <if test="${not file.target.uptodate}">
          <echo message="Checking: ${path::get-file-name(file.target)}" />
          <exec program="Aspell/aspell.bat"
            commandline="${path.spellcheck} ${lang.target} ${file.target} ${file.log}"
            failonerror="false" />
        </if>
        <exec program="Aspell/append.bat"
          commandline="${file.log} ${spellcheck.log}" />
      </do>
    </foreach>
  </target>

  <!-- ====================================================================== -->
  <!-- Create PDF documentation                                               -->
  <!-- ====================================================================== -->

  <target name="pdf" description="Create PDF documentation">

    <property name="file.target" value="output/${app}-${docverstring}.${environment::get-variable('MicroVersion')}-${lang.target}.pdf" />
    <call target="uptodate" />

    <if test="${not file.target.uptodate}">
      <property name="xslt.params" value="${xsl.pdf.params}" />
      <property name="xslt.file" value="${xsl.pdf.file}" />
      <property name="xslt.final" value="${doc.target.work}/${doc.target.name}" />
      <!-- set xslt.target to the name of the temp file -->
      <property name="xslt.target" value="${xslt.final}.tmp" />

      <call target="xsltproc" />

      <!-- Removes the span="inherit" attribute added by xsltproc, which causes a warning -->
      <move file="${xslt.target}" tofile="${xslt.final}.fo" overwrite="true">
        <filterchain>
          <replacestring from="span=&quot;inherit&quot; " to="" />
          <replacestring from="width=&quot;auto&quot; height=&quot;auto&quot; content-width=&quot;auto&quot; content-height=&quot;auto&quot;"
                         to="inline-progression-dimension.maximum=&quot;100%&quot; content-width=&quot;scale-down-to-fit&quot; content-height=&quot;scale-down-to-fit&quot;" />
        </filterchain>
      </move>

      <property name="userconfig.langtemplate" value="${path.user.xsl}/${lang.target}/userconfig.template.xml" />
      <property name="userconfig.lang" value="${path.user.xsl}/${lang.target}/userconfig.xml" />

      <if test="${file::exists(userconfig.langtemplate)}">
        <loadfile file="${userconfig.langtemplate}" property="configfile">
          <filterchain>
            <replacetokens begintoken="%" endtoken="%">
              <token key="WINFONTSDIR" value="${fontpath}" />
              <token key="USRFONTSDIR" value="${path.user.xsl}/fonts" />
            </replacetokens>
          </filterchain>
        </loadfile>
        <echo file="${userconfig.lang}" message="${configfile}" />
      </if>
      <property name="commandline" value="-q -fo ${xslt.final}.fo -pdf ${file.target}" />
      <property name="commandline" value="-c ${userconfig.lang} ${commandline}" if="${file::exists(userconfig.lang)}" />

      <exec program="fop.cmd"
            commandline="${commandline}"
            basedir="${path.fop}"
            verbose="false" />
    </if>
  </target>

  <!-- ====================================================================== -->
  <!-- Create CHM documentation                                               -->
  <!-- ====================================================================== -->

  <target name="chm" description="Create CHM documentation">

    <property name="file.target" value="${doc.target.work}.chm" />
    <call target="uptodate" />

    <if test="${not file.target.uptodate}">
      <property name="xslt.params" value="${xsl.chm.params}" />
      <property name="xslt.file" value="${xsl.chm.file}" />
      <property name="xslt.target" value="${doc.target.work}/${doc.target.name}" />

      <call target="xsltproc" />

      <!-- The CHM helpcontext target resides in an external build file -->
      <call target="help.prepare" if="${target::exists('help.prepare')}" />

      <copy file="${path.user.css}/styles_chm.css" todir="${doc.target.work}" />

      <exec program="SBAppLocale.exe"
            commandline="${lang.target.code} ${path.bin}/hhc.exe ${doc.target.work}/htmlhelp.hhp"
            basedir="${path.bin}"
            resultproperty="result.hhc"
            failonerror="false"
            verbose="false"
            timeout="600000" />

      <copy file="${doc.target.work}/htmlhelp.chm" tofile="${file.target}" />

      <if test="${doc.target.name == 'TortoiseSVN_en'}">
        <copy file="${doc.target.work}/alias.h" tofile="..\src\Resources\TSVNHelpAlias.h" />
        <copy file="${doc.target.work}/context.h" tofile="..\src\Resources\TSVNHelpContext.h" />
      </if>
      <if test="${doc.target.name == 'TortoiseMerge_en'}">
        <copy file="${doc.target.work}/alias.h" tofile="..\src\Resources\TMergeHelpAlias.h" />
        <copy file="${doc.target.work}/context.h" tofile="..\src\Resources\TMergeHelpContext.h" />
      </if>
    </if>
    <delete>
      <fileset>
        <include name="${doc.target.work}/*.*" />
      </fileset>
    </delete>
  </target>

  <!-- ====================================================================== -->
  <!-- Create HTML multi page documentation                                   -->
  <!-- ====================================================================== -->
  <target name="html" description="Create HTML documentation" depends="">

    <property name="file.target" value="${doc.target.work}/index.html" />
    <call target="uptodate" />

    <if test="${not file.target.uptodate}">
      <property name="xslt.params" value="${xsl.htmlsingle.params}" />
      <property name="xslt.file" value="${xsl.htmlsingle.file}" />
      <property name="xslt.target" value="${doc.target.work}/${doc.target.name}" />

      <copy file="${path.user.css}/styles_chm.css" todir="${doc.target.work}" />
      <copy file="${path.user.css}/styles_html.css" todir="${doc.target.work}" />

      <call target="xsltproc" />

    </if>
  </target>

  <!-- ====================================================================== -->
  <!-- Create HTML single page documentation                                  -->
  <!-- ====================================================================== -->

  <target name="htmlsingle" description="Create HTML single page documentation" depends="">

    <property name="file.target" value="${doc.target.work}/help-onepage.html" />
    <call target="uptodate" />

    <if test="${not file.target.uptodate}">
      <property name="xslt.params" value="${xsl.html.params}" />
      <property name="xslt.file" value="${xsl.html.file}" />
      <property name="xslt.target" value="${file.target}" />

      <copy file="${path.user.css}/styles_chm.css" todir="${doc.target.work}" />
      <copy file="${path.user.css}/styles_html.css" todir="${doc.target.work}" />

      <call target="xsltproc" />

    </if>
  </target>

  <!-- ====================================================================== -->
  <!-- Create the API documentation                                           -->
  <!-- ====================================================================== -->

  <target name="apidoc" depends="SubversionAPIdoc,TortoiseSVNAPIdoc" />

  <target name="SubversionAPIdoc">
    <loadfile file="API\DoxyfileSVN" property="SubversionDoxyFile" />
    <echo file="Doxyfile" message="${SubversionDoxyFile}" />
    <echo file="Doxyfile" message="HHC_LOCATION=${environment::get-variable('HHLOC')}" append="true" />
    <mkdir dir="output" />
    <exec program="doxygen.exe">
      <arg value="Doxyfile" />
    </exec>
    <move file="output\doxygen\html\SubversionAPI.chm" tofile="output\SubversionAPI.chm" overwrite="true" />
    <delete dir="output\doxygen" />
    <delete file="Doxyfile" />
  </target>

  <target name="TortoiseSVNAPIdoc">
    <loadfile file="API\Doxyfile" property="TortoiseSVNDoxyFile" />
    <echo file="Doxyfile" message="${TortoiseSVNDoxyFile}" />
    <echo file="Doxyfile" message="HHC_LOCATION=${environment::get-variable('HHLOC')}" append="true" />
    <mkdir dir="output" />
    <exec program="doxygen.exe">
      <arg value="Doxyfile" />
    </exec>
    <move file="output\doxygen\html\TortoiseAPI.chm" tofile="output\TortoiseSVNAPI.chm" overwrite="true" />
    <delete dir="output\doxygen" />
    <delete file="Doxyfile" />
  </target>

</project>
