How to limit the bookmark level is PDF

Here should go questions about transforming XML with XSLT and FOP.
girishkanmas
Posts: 8
Joined: Thu Apr 14, 2022 8:37 am

How to limit the bookmark level is PDF

Post by girishkanmas »

Hi,
In the "<custom-plugin>\cfg\fo\attrs\custom.xsl" file, I have used the following line to control the TOC entry levels:

Code: Select all

<xsl:variable name="tocMaximumLevel">3</xsl:variable>
However, the PDF bookmarks lists all the level.
How to do I control bookmark levels as per the custom TOC levels.
julien_lacour
Posts: 495
Joined: Wed Oct 16, 2019 3:47 pm

Re: How to limit the bookmark level is PDF

Post by julien_lacour »

Hello,

The tocMaximumLevel XSLT parameter is not used by the bookmarks templates, however you can add it in the template generating the fo:bookmark elements like in the example below:

Code: Select all

<xsl:template match="*[contains(@class, ' topic/topic ')]" mode="bookmark">
    <xsl:variable name="mapTopicref" select="key('map-id', @id)[1]" as="element()?"/>
    <xsl:variable name="topicTitle">
        <xsl:call-template name="getNavTitle"/>
    </xsl:variable>
    <xsl:variable name="topicLevel" as="xs:integer">
        <xsl:apply-templates select="." mode="get-topic-level"/>
    </xsl:variable>
    
    <xsl:choose>
      <xsl:when test="$topicLevel &lt; $tocMaximumLevel and
                      $mapTopicref[@toc = 'yes' or not(@toc)] or
                      not($mapTopicref)">
        <fo:bookmark>
            <xsl:attribute name="internal-destination">
                <xsl:call-template name="generate-toc-id"/>
            </xsl:attribute>
                <xsl:if test="$bookmarkStyle!='EXPANDED'">
                    <xsl:attribute name="starting-state">hide</xsl:attribute>
                </xsl:if>
            <fo:bookmark-title>
                <xsl:value-of select="normalize-space($topicTitle)"/>
            </fo:bookmark-title>
            <xsl:apply-templates mode="bookmark"/>
        </fo:bookmark>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates mode="bookmark"/>
      </xsl:otherwise>
    </xsl:choose>
</xsl:template>
This template will override the default template and you will obtain the result you want. And if you change the parameter value, it will apply on both toc and bookmarks.

Regards,
Julien
girishkanmas
Posts: 8
Joined: Thu Apr 14, 2022 8:37 am

Re: How to limit the bookmark level is PDF

Post by girishkanmas »

Hi Julien,

It worked like a charm!
Thank you so much.

Regards,
Girish
Last edited by girishkanmas on Wed May 04, 2022 6:51 pm, edited 1 time in total.
sbhatt
Posts: 2
Joined: Tue Mar 07, 2023 1:57 pm

Re: How to limit the bookmark level is PDF

Post by sbhatt »

Hi Julien,
I've tried the example that you shared and it works just fine. I did observe that the bookmarks, in this case, take the same number of levels as the TOC. Is there any way to keep the bookmarks level independent of the TOC level?
Thanks,
Somi
julien_lacour
Posts: 495
Joined: Wed Oct 16, 2019 3:47 pm

Re: How to limit the bookmark level is PDF

Post by julien_lacour »

Hello,

If you want to keep the bookmark level independent of the toc level, you can create a custom parameter:

Code: Select all

<xsl:param name="bookmarksMaximumLevel" select="1"/>
Something similar to what's in org.dita.pdf2\cfg\fo\attrs\basic-settings.xsl.

And then use this parameter in your custom bookmarks processing template:

Code: Select all

<xsl:template match="*[contains(@class, ' topic/topic ')]" mode="bookmark">
    <xsl:variable name="mapTopicref" select="key('map-id', @id)[1]" as="element()?"/>
    <xsl:variable name="topicTitle">
        <xsl:call-template name="getNavTitle"/>
    </xsl:variable>
    <xsl:variable name="topicLevel" as="xs:integer">
        <xsl:apply-templates select="." mode="get-topic-level"/>
    </xsl:variable>
    
    <xsl:if test="$topicLevel &lt;= $bookmarksMaximumLevel">
        <xsl:choose>
          <xsl:when test="$mapTopicref[@toc = 'yes' or not(@toc)] or
                          not($mapTopicref)">
            <fo:bookmark>
                <xsl:attribute name="internal-destination">
                    <xsl:call-template name="generate-toc-id"/>
                </xsl:attribute>
                    <xsl:if test="$bookmarkStyle!='EXPANDED'">
                        <xsl:attribute name="starting-state">hide</xsl:attribute>
                    </xsl:if>
                <fo:bookmark-title>
                    <xsl:value-of select="normalize-space($topicTitle)"/>
                </fo:bookmark-title>
                <xsl:apply-templates mode="bookmark"/>
            </fo:bookmark>
          </xsl:when>
          <xsl:otherwise>
            <xsl:apply-templates mode="bookmark"/>
          </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>
Don't customize directly the org.dita.pdf2 plugin you may lose your customization after an update.
Use the Customization directory or create your own custom PDF plugin.

Regards,
Julien
julien_lacour
Posts: 495
Joined: Wed Oct 16, 2019 3:47 pm

Re: How to limit the bookmark level is PDF

Post by julien_lacour »

The previous post works only for the DITA Map PDF - based on XSL-FO scenario, if you are using the DITA Map PDF - based on HTML5 & CSS scenario you can directly follow the instructions from the user-guide.

Regards,
Julien
sbhatt
Posts: 2
Joined: Tue Mar 07, 2023 1:57 pm

Re: How to limit the bookmark level is PDF

Post by sbhatt »

Thanks Julien.
Post Reply