Topics

problem with processing instructions in bookmap #DITA-OT #XSLT

Erik
 

Hi everyone,

I have some DITA content that makes use of processing instructions to add page breaks to PDF output. In some cases, these processing instructions are inside topics, and I have been able to use these to add breaking blocks in the PDF without any issue.

However, some of the page break processing instructions are added directly into the bookmap, and I can't hook in to these. I have tried using custom XSLT with dita.xsl.mapref, dita.xsl.mappull, and inside the plugin itself in root-processing.xsl, but I can't seem to get what I want.

My current understanding of the problem is that these PIs in the map itself don't get processed as topics, and so I can't simply convert them to fo:block elements. They do show up in stage1.xml, but I can't quite figure out how to convert them into formatting objects. I would really just like to know if there is some work-around for this, or if I'm wasting my time.

If anyone can point me in the right direction, I should be able to work it out. Any help would be greatly appreciated. Thanks in advance.

ekimber@contrext.com
 

If they are in the merged XML then you'll need to find them in the map structure that is included in the resolved XML. So if you are processing a topic you can chase down its corresponding topicref (if there is one), then look for the PI as presumably a preceding sibling (probably the first preceding sibling) of the topicref, but you'll need to look at the structure of the resolved XML to be sure.

The general technique for going from a topic to its topicref is demonstrated by this line from commons.xsl in the PDF2 transform:

<xsl:variable name="topicref" select="key('map-id', ancestor-or-self::*[contains(@class, ' topic/topic ')][1]/@id)"/>

From there you should be able to do what you want.

Cheers,

E.

--
Eliot Kimber
http://contrext.com


On 2/11/20, 10:47 AM, "main@dita-users.groups.io on behalf of eriks@..." <main@dita-users.groups.io on behalf of eriks@...> wrote:

Hi everyone,

I have some DITA content that makes use of processing instructions to add page breaks to PDF output. In some cases, these processing instructions are inside topics, and I have been able to use these to add breaking blocks in the PDF without any issue.

However, some of the page break processing instructions are added directly into the bookmap, and I can't hook in to these. I have tried using custom XSLT with dita.xsl.mapref, dita.xsl.mappull, and inside the plugin itself in root-processing.xsl, but I can't seem to get what I want.

My current understanding of the problem is that these PIs in the map itself don't get processed as topics, and so I can't simply convert them to fo:block elements. They do show up in stage1.xml, but I can't quite figure out how to convert them into formatting objects. I would really just like to know if there is some work-around for this, or if I'm wasting my time.

If anyone can point me in the right direction, I should be able to work it out. Any help would be greatly appreciated. Thanks in advance.

Erik
 

Hi Eliot,

Thanks for your reply! Based on your suggestion, I added the following:

            <xsl:attribute name="page-break-before">
                <xsl:if
                    test="key('map-id', @id)/preceding-sibling::processing-instruction()[name() = 'page-break']"
                    > always </xsl:if>
            </xsl:attribute>

and it seems to be doing the trick. It actually seems kind of obvious to me now, but thanks again for the nudge and helping me get there.

Cheers,
Erik

ekimber@contrext.com
 

Note that your preceding-sibling check is too inclusive--it will find any preceding sibling PI, which might before an earlier topicref, so you need to at least limit it to whatever comes after any preceding topicref.

One way to do this is to first find the preceding topicref (if any) and then use the ">>" (after) operator to find preceding siblings that follow the preceding topicref. So I would probably do something like:

<xsl:variable name="thisTopicref" as="element()?"
select=" key('map-id', @id)[1] "
/>
<xsl:variable name="precedingTopicref" as="element()?"
select="$thisTopicref/preceding-sibling::*[contains(@class, ' map/topicref ')][1]"
/>
<xsl:variable name="formattingPI" as="processing-instruction()?"
select="
$thisTopicref/preceding-sibling::processing-instruction()
[name(.) eq 'page-break'][. &gt;&gt; $precedingTopicref or
empty($precedingTopicref)][1]
"
/>
<xsl:attribute name="page-break-before
select="
if (exists($formattingPI))
then 'always'
else 'inherit'
"
/>


Cheers,

E.

--
Eliot Kimber
http://contrext.com


On 2/12/20, 2:52 AM, "main@dita-users.groups.io on behalf of eriks@..." <main@dita-users.groups.io on behalf of eriks@...> wrote:

Hi Eliot,

Thanks for your reply! Based on your suggestion, I added the following:

<xsl:attribute name="page-break-before">
<xsl:if
test="key('map-id', @id)/preceding-sibling::processing-instruction()[name() = 'page-break']"
> always </xsl:if>
</xsl:attribute>

and it seems to be doing the trick. It actually seems kind of obvious to me now, but thanks again for the nudge and helping me get there.

Cheers,
Erik