[Read this for an introduction to what I'm talking about].
Now that we’ve got our FrameMaker documents in XML, how can we exploit their new format? One of the first things I did was to create new ways of reading (eventually changing) the simple data stored within them. This isn’t all that earth-shattering, but when you consider how difficult it is to find and change some values in the FrameMaker UI this is a big win. Where to start? Bookfiles.
To be able to apply stylesheets or data-collection tools to books (rather than individual files), I need to be able to collect a books components. So, convert your bookfile to MX (yeah, it works on bookfiles as well as chapter files), and search through it for one of the filenames you know is a part of the book (you’ll probably want to pretty-print the XML first). I get something like this:
<BookComponent> <FileName>`<c\>ch01'</FileName> <Unique>27107</Unique> <StartPageSide>StartRightSide</StartPageSide> <PageNumbering>Restart</PageNumbering> <PgfNumbering>Continue</PgfNumbering> <PageNumPrefix>`'</PageNumPrefix> <PageNumSuffix>`'</PageNumSuffix> <DefaultPrint>Yes</DefaultPrint> <DefaultApply>Yes</DefaultApply> </BookComponent>
MX in this case has a pretty comprehensible structure, so we’ll need to grab a BookComponent/FileName, do a little text processing to remove the funky characters, and potentially append our MX file extension (I chose “.mx”). Here’s a very simple stylesheet to do just that:
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="@*|node()"> <xsl:apply-templates/> </xsl:template> <xsl:template match="/"> <xsl:element name="components"> <xsl:apply-templates/> </xsl:element> </xsl:template> <xsl:template match="//BookComponent/FileName"> <xsl:param name="extension" select="'.mx'"/> <xsl:variable name="str-after"> <xsl:value-of select="substring-after(., '>')"/> </xsl:variable> <xsl:element name="component"> <xsl:value-of select="substring($str-after, 1, string-length($str-after) - 1)"/> <xsl:value-of select="$extension"/> </xsl:element> </xsl:template> </xsl:stylesheet>
When you run that on a MX bookfile, you should see an output like this (note that the file extension is customizable above):
<?xml version="1.0"?> <components> <component>svcTOC.fm.mx</component> <component>foreword.mx</component> <component>ch00.mx</component> <component>ch01.mx</component> <component>ch02.mx</component> <component>ch03.mx</component> <component>ch04.mx</component> <component>ch05.mx</component> <component>ch06.mx</component> <component>ch07.mx</component> <component>ch08.mx</component> <component>ch09.mx</component> <component>appa.mx</component> <component>appb.mx</component> <component>appc.mx</component> <component>appd.mx</component> <component>appe.mx</component> <component>svcIX.fm.mx</component> <component>svcAPL.fm.mx</component> <component>svcLOR.fm.mx</component> </components>
That’ll give us a nice structure to direct other processes to the individual component files.
The code is also available here or darcs get http://kfahlgren.com/code/mx/.