Page 1 of 1
Output filename based on variables
Posted: Thu Jul 25, 2019 5:45 pm
by AndrewCampbell
I'd like to be able to set the output base filename (the part specified by args.output.base) based on the value of some variables.
In my case, the mainbooktitle in each of my bookmaps consists of three ph elements which are in turn keyref'ed, something like this:
Code: Select all
<mainbooktitle>
<ph keyref="Product"/>
<ph keyref="Release"/>
<ph keyref="DocumentType/>
</mainbooktitle>
I would like the output filename to be something like "[value of Product]_[value of Release]_[value of DocumentType].pdf".
I can think of a few complex ways of making this happen by wrapping the DITA-OT in a shell script or something similar, but I'd prefer to do it as a regular plugin, especially as I could use a regular plugin within Oxygen. Is this possible?
Re: Output filename based on variables
Posted: Fri Jul 26, 2019 8:26 am
by Radu
Hi Andrew,
I see you already got some answers on the DITA Users List.
I do not have a clear idea how a plugin could do that, probably if the plugin would have some custom ANT target which would be called before the PDF is produced, it could call an XSLT script to process the DITA Map from the temporary files folder (which would already have the keyrefs expanded). Then it would use the result produced by the XSLT script to set the value of the "args.output.base" parameter in the ANT build file.
Another Oxygen-specific approach would be to edit the transformation scenario and in the "Parameters" tab set a value for the "args.output.base" parameter using Oxygen specific editor variables like "${xpath_eval(expression)} ":
https://www.oxygenxml.com/doc/versions/ ... bles.htmle
and try to use XPath to read the value for each key from the DITA Map where it is defined. But this would work only inside Oxygen.
Regards,
Radu
Re: Output filename based on variables
Posted: Tue Jun 18, 2024 9:34 am
by horisonten
Sorry to revive the old thread. Not sure if it is best practice to revive old threads. To me it feels like it since there would be many very similar topics which would make it more convoluted and hard to find. This thread is one of the top Google results and exactly what I'm trying to achieve.
So I'm trying to do the exact same as the OP by using XPath in the "args.output.base".
I have a <bookmap/mainbooktitle> which contains three <ph> elements with keyrefs:
Code: Select all
<mainbooktitle>Product name <ph keyref="variable1"/>, <ph keyref="variable2"/>, <ph keyref="variable3"/>
But I cannot get this to be set as the PDF output file name.
If I try:
Code: Select all
${xpath_eval(//*[contains(@class, " bookmap/mainbooktitle ")])}
I get this fatal error:
xml:485: java.nio.file.InvalidPathException: Illegal char <<> at index 81: C:\Users\User\OxygenXMLEditor\NKT\out\pdf-css-html5\<mainbooktitle>Product name <ph keyref="variable1"/>, <ph keyref="variable2"/>, <ph keyref="variable3"/>
But this Xpath works in the XPath Builder and fetches the correct text.
And this:
Code: Select all
${xpath_eval(//*[contains(@class, " bookmap/mainbooktitle ")]/text())}
Gives a similar error:
485: java.nio.file.InvalidPathException: Illegal char <
But this Xpath works in the XPath Builder and fetches the correct text.
If I try this to at least get something in the file name:
Code: Select all
${xpath_eval(//*[contains(@class, " bookmap/mainbooktitle ")]/span[@keyref = "variable1"])}
There are no errors, but the file name is empty (".pdf"). This Xpath also works in the XPath Builder and fetches the correct text.
So what can be the issue here? Is the issue that the keyrefs are not available/resolved for the xpath function?
Re: Output filename based on variables
Posted: Tue Jun 18, 2024 2:06 pm
by julien_lacour
Hello horisonten,
From what I tested, running the following XPath in Oxygen XPath/XQuery Builder view:
Code: Select all
//*[contains(@class, " bookmap/mainbooktitle ")]
Will return you "Product name , ," without expanded keys.
The XPath is evaluated after parsing the ditamap, before expanding conrefs and keyrefs (as you assumed).
This is why you get an error when using it from the args.output.base parameter.
Regards,
Julien
Re: Output filename based on variables
Posted: Tue Jun 18, 2024 6:49 pm
by horisonten
julien_lacour wrote: ↑Tue Jun 18, 2024 2:06 pm
Hello horisonten,
From what I tested, running the following XPath in Oxygen XPath/XQuery Builder view:
Code: Select all
//*[contains(@class, " bookmap/mainbooktitle ")]
Will return you "Product name , ," without expanded keys.
The XPath is evaluated after parsing the ditamap, before expanding conrefs and keyrefs (as you assumed).
This is why you get an error when using it from the args.output.base parameter.
Regards,
Julien
Yes, sorry I was a bit vague. I cannot get the resolved keyrefs inte the Xpath builder. But I'm not getting errors and I see that the Xpath is pointing to the correct location.
So is there a workaround where I actually can use Xpath in the args.output.base to set the PDF file name dynamically? I'm using a ditaval to control the content of the <ph> elements in the mainbooktitle and would like to avoid manually setting the pdf name every time.
Re: Output filename based on variables
Posted: Wed Jun 19, 2024 10:03 am
by julien_lacour
Hello horisonten,
You could use a
custom Ant build file which calls the default target then changes the PDF file name by calling the XPath query inside an XSLT stylesheet on either merged.xml or merged.html file:
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<project basedir="." default="dist">
<!-- The DITA-OT default build file -->
<import file="path/to/org.dita.base/build.xml"/>
<target name="dist">
<!-- Call the DITA-OT default target -->
<antcall target="init"/>
<!-- Change PDF file name -->
<antcall target="change-pdf-name"/>
</target>
<target name="change-pdf-name">
<!-- The files paths must be relative to the ditamap -->
<xslt in="out/pdf-css-html5/book.merged.xml" out="out/pdf-css-html5/temp.txt">
<style>
<string>
<![CDATA[
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="3.0">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:value-of select="//*[contains(@class, ' bookmap/mainbooktitle ')]"/>
</xsl:template>
</xsl:stylesheet>
]]>
</string>
</style>
</xslt>
<loadfile property="title" srcFile="out/pdf-css-html5/temp.txt"/>
<delete file="out/pdf-css-html5/temp.txt"/>
<move file="out/pdf-css-html5/book.pdf" tofile="out/pdf-css-html5/${title}.pdf"/>
</target>
</project>
Regards,
Julien
Re: Output filename based on variables
Posted: Wed Jun 19, 2024 3:08 pm
by horisonten
Great, thank you very much! I got it to work when using a transformation scenario.
But I'm unable to find the solution for making it work when using a DITA-OT project file which is pointing to an .opt file.
How would I go about to make the Ant build file work when using a DITA-OT project file and .opt?
Re: Output filename based on variables
Posted: Thu Jun 20, 2024 9:40 am
by julien_lacour
Hello horisonten,
If you are using a DITA project file with an OPT file the only solution is to set the 'args.output.base' parameter for each deliverable: either from the OPT file or if you are using the same template for different deliverables directly in the DITA project file. The Ant build file is not available at this level and cannot be changed.
Regards,
Julien
Re: Output filename based on variables
Posted: Thu Jun 20, 2024 1:24 pm
by horisonten
julien_lacour wrote: ↑Thu Jun 20, 2024 9:40 am
Hello horisonten,
If you are using a DITA project file with an OPT file the only solution is to set the 'args.output.base' parameter for each deliverable: either from the OPT file or if you are using the same template for different deliverables directly in the DITA project file. The Ant build file is not available at this level and cannot be changed.
Regards,
Julien
All right, fair enough.
Could you please add an improvement suggestion at least? It would be very handy to be able to
easily set the output pdf filename based on <keyrefs> in the Mainbooktitle.
Re: Output filename based on variables
Posted: Thu Jun 20, 2024 2:04 pm
by julien_lacour
Hello horisonten,
Sure, I added OPE-281 as improvement to set file names using args.output.base parameter and titles with keys.
Regards,
Julien
Re: Output filename based on variables
Posted: Fri Jun 21, 2024 2:52 am
by xephon
The way I solved this in the past is like so:
You add an Ant target after processing. There is the preprocessing.post extension point in the OT. After preprocessing, the keyrefs are resolved. In this target, read the temporary map and cherry pick what you want. Then save this in properties, maybe in a property file. Let the normal processing continue and call another target at the very end, read your properties and rename the PDF.