Page 1 of 1

Footnotes Related to Tables in PDF Documents

Posted: Sun Oct 17, 2021 2:55 pm
by pjporter88
Hello,

I have been reviewing how to style footnotes in PDF output using DITA to HTML5 with CSS. It only seems to cover "typical" cases of footnotes that get collected and placed at the bottom of the page, where a separator line could be added.

We have a use case where we often have footnotes inside the cells of tables and want the footnotes placed in small font immediately underneath the table instead of at the bottom of the page, so that the footnotes are "connected" to the table. Alternatively, perhaps the footnotes could go inside an html footer element for that table.? I know there is no footer for tables in DITA though.

Is this possible? If so, how might that be done?

Thank you!
Pat

Re: Footnotes Related to Tables in PDF Documents

Posted: Tue Oct 19, 2021 9:41 am
by julien_lacour
Hello Pat,

If you want to move table footnotes follow these instructions:
  1. Create a publishing template file (.opt) in a new folder from your project. Then create an xslt folder inside it.
  2. In the newly created folder, create an XSLT style-sheet (for example merged2mergedExtension.xsl) with the following content:

    Code: Select all

        <?xml version="1.0" encoding="UTF-8"?>
        <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:xs="http://www.w3.org/2001/XMLSchema"
          exclude-result-prefixes="xs"
          version="2.0">
    
          <!-- Match only top level tables (i.e tables that are not nested in other tables),
            that have footnotes. -->
          <xsl:template match="
              *[contains(@class, 'topic/table')]
              [not(ancestor::*[contains(@class, 'topic/table')])]
              [//*[contains(@class, 'topic/fn')]]">
            <xsl:next-match>
              <xsl:with-param name="top-level-table" select="." tunnel="yes"/>
            </xsl:next-match>
    
            <!-- Create a list with all the footnotes from the current table. -->
            <ol class="- topic/ol " outputclass="table-fn-container">
              <xsl:for-each select=".//*[contains(@class, 'topic/fn')]">
                <li class="- topic/li " id="{generate-id(.)}" outputclass="table-fn">
                  <xsl:apply-templates select="node()"/>
                </li>
              </xsl:for-each>
            </ol>
          </xsl:template>
    
          <!-- Match the footnotes in table entries, replace them with a link. -->
          <xsl:template match="*[contains(@class, 'topic/entry')]//*[contains(@class, 'topic/fn')]">
            <xsl:param name="top-level-table" tunnel="yes"/>
            <!-- Determine the footnote number. -->
            <xsl:variable name="fn-number" select="
                index-of($top-level-table//*[contains(@class, 'topic/fn')], .)"/>
            <xref type="fn" class="- topic/xref " href="#{generate-id(.)}"
              outputclass="table-fn-call">
              <xsl:value-of select="$fn-number"/>
            </xref>
          </xsl:template>
    
        </xsl:stylesheet>
    
  3. Open the .opt file and set the XSLT style-sheet created in the previous step with the com.oxygenxml.pdf.css.xsl.merged2html5 XSLT extension point:

    Code: Select all

        <publishing-template>
          ...
          <pdf>
            ...        
            <xslt>
              <extension
                id="com.oxygenxml.pdf.css.xsl.merged2merged"
                file="xslt/merged2mergedExtension.xsl"/>
            </xslt>
    
  4. Create a css folder in the publishing template directory. In this directory, save a custom CSS file with rules that style the glossary structure. For example:

    Code: Select all

        /* Customize footnote calls, inside the table. */
        *[outputclass ~= 'table-fn-call'] {
          color: black;
          text-decoration: none;
          font-size: smaller;
          vertical-align: super;
          line-height: none;
        }
    
        /* Hide the "on page .." text that follows xrefs. */
        *[outputclass ~= 'table-fn-call']:after {
          display: none;
        }
    
        /* Customize the list containing all the table footnotes. */
        *[outputclass ~= 'table-fn-container'] {
          border-top: 1pt solid black;
        }
    
        /* Customize footnotes display, below the table. */
        *[outputclass ~= 'table-fn'] {
          font-size: 1em;
        }
        *[outputclass ~= 'table-fn']::marker {
          font-size: 1em;
        }
    
  5. Open the template descriptor file associated with your publishing template (the .opt file) and reference your custom CSS file in the resources element:

    Code: Select all

        <publishing-template>
          ...
          <pdf>
            ...                
            <resources>            
              <css file="css/custom.css"/>
            </resources> 
    
  6. Edit the DITA Map PDF - based on HTML5 & CSS transformation scenario.
  7. In the Templates tab, click the Choose Custom Publishing Template link and select your template.
  8. Click OK to save the changes and run the transformation scenario.
Feel free to change the values from the CSS in order to obtain the desired output.

Regards,
Julien

Re: Footnotes Related to Tables in PDF Documents

Posted: Tue Oct 19, 2021 2:48 pm
by pjporter88
Thank you Julien!
Can't wait to implement this.
Very much appreciated!
Pat

Re: Footnotes Related to Tables in PDF Documents

Posted: Thu Jul 28, 2022 3:03 pm
by patjporter
Hi Julien,
When I implemented the code above, it worked great...but I am getting this format on the footnote markers:
image.png
image.png (18.36 KiB) Viewed 3419 times
I tried adding to the custom css that you gave me above the following:

Code: Select all

    *[outputclass ~= 'table-fn']::marker {      
    font-size: 1em;
    content: "(" counter(footnote) ")";
    }
But this caused my transform to crash. Here what is in the styles.css:

Code: Select all

/*footnotes-style-parentheses*/
@media print {
  *[class~="topic/fn"]::footnote-call,
  *[class~="topic/fn"]::footnote-marker {
    content: "(" counter(footnote) ")";
  }
}
Maybe the two are conflicting with each other, or maybe the change that I made in custom.css is incorrect?

Can you help me understand how to make the two have the same format, basically like this: (1)(4)

Thank you!
Pat

Re: Footnotes Related to Tables in PDF Documents

Posted: Thu Jul 28, 2022 4:52 pm
by patjporter
Also please notice that footnotes that are second, third, etc. instances of a footnote in a table are structured as <xref> to the original <fn> element to avoid duplication with a type="fn" but they are showing up formatted as hyperlinks because they are xrefs. Is there a way to prevent <xref type="fn"> from displaying as a hyperlink in blue with the underline?

Code: Select all

<entry> <p>Production - Pre CoA<fn id="fn-1">DAY / VMC is required for flight outside
              the normal operational envelope, i.e., airstarts, electrical checks, flight control
              shutoff checks, cabin pressure low checks, stalls, spoiler control, engine handling on
              non-FADEC, engines, operation above Vmo / Mmo, and alternate gear extension. </fn>
              </p> <p>Completion - Pre-Approach Validations<xref
              href="Chapter-209Runway---Weather-Requirements.dita#ID-000012f8/fn-1" type="fn"/></p> </entry>
Thank you!
Pat

Re: Footnotes Related to Tables in PDF Documents

Posted: Fri Jul 29, 2022 3:42 am
by patjporter
Apologies for continuing to add to this post...but I discovered a problem. I structured my footnotes according to this reference:
https://www.oxygenxml.com/dita/1.3/spec ... se/fn.html
But, when I add an id attribute to the first instance of a fn, it does not put the footnote call in the table entry:

Code: Select all

<row>
            <entry>Production - Pre CoA<fn id="001">DAY / VMC is required for flight outside the
              normal operational envelope, i.e., airstarts, electrical checks, flight control
              shutoff checks, cabin pressure low checks, stalls, spoiler control, engine handling on
              non-FADEC, engines, operation above Vmo / Mmo, and alternate gear
              extension.</fn></entry>
            <entry>1000/3</entry>
            <entry> 1000/3 or IFR Cir<fn>Use of IFR Cir Min requires prior validation of a properly
              functioning aircraft instrument approach system.</fn><fn>If the forecast arrival
              weather is less than 1000/3, the proper functioning of the aircraft instruments should
              be verified after takeoff. If they function correctly, then the flight can continue
              using IFR Cir Minimums.</fn></entry>
            <entry>Required</entry>
          </row>
image.png
image.png (11.24 KiB) Viewed 3389 times
When I deleted the @id from the first fn element, the number 1 published. When I added back it, it did not.
Is this by chance a known issue and is there a workaround, like adding an outputclass that the html will recognize as a class?
Thank you,
Pat

Re: Footnotes Related to Tables in PDF Documents

Posted: Fri Jul 29, 2022 5:03 am
by chrispitude
Hi Pat,

From Darwin Information Typing Architecture (DITA) Version 1.3 > 3.2.2.16 <fn>:
A footnote that specifies an @id attribute is a use-by-reference footnote. Upon output, it does not appear anywhere unless it has been referenced using an <xref> with the @type attribute set to "fn".
This definitely takes some getting used to. It confuses our writers too.

I need to try this footnotes-under-table technique - this is something our writers have asked about!

Re: Footnotes Related to Tables in PDF Documents

Posted: Fri Jul 29, 2022 5:40 am
by patjporter
Interesting…so you have to write the fn, then you have to reference it…seems redundant, but I understand,
We actually use a different extend-script based process through FrameMaker for our flight manuals written in DITA that publishes the use-by reference.
Thanks for clearing that up!
Pat

Re: Footnotes Related to Tables in PDF Documents

Posted: Fri Jul 29, 2022 5:46 am
by patjporter
Would you be able to help with the formatting questions?
Thanks!
Pat

Re: Footnotes Related to Tables in PDF Documents

Posted: Fri Jul 29, 2022 1:31 pm
by patjporter
So I updated my footnotes to add cross-references for the <fn> elements that had id attributes set on them. When I ran it using the default transform I got this (a single instance):
image.png
image.png (8.84 KiB) Viewed 3358 times
When I ran it with the code that Julien provided above to place the footnotes under the table rather than at the bottom of the page, I got this...they are duplicated:
image.png
image.png (85.62 KiB) Viewed 3358 times
What I was aiming for is two things:
(a) Footnotes directly under the table (Julien's code does this).
(b) Formatted like all the other footnotes (not hyperlinks and surrounded by parentheses ( ) in both the callouts and the footnotes under the table. (I am getting first instance non-hyperlink, all xrefs are hyperlinks, and no parentheses).
Perhaps Julien may have the opportunity to assist and modify the code he provided above...I am having too much difficulty trying to figure it out.
Thank you!
Pat

Re: Footnotes Related to Tables in PDF Documents

Posted: Fri Jul 29, 2022 2:06 pm
by julien_lacour
Hi Pat,

For the formatting part, you should try the following CSS:

Code: Select all

/* Customize footnote calls, inside the table. */
*[outputclass ~= 'table-fn-call'] {
  color: black;
  text-decoration: none;
  font-size: smaller;
  vertical-align: super;
  line-height: none;
}

/* Hide the "on page .." text that follows xrefs. */
*[outputclass ~= 'table-fn-call']:after {
  display: none;
}

/* Customize the list containing all the table footnotes. */
*[outputclass ~= 'table-fn-container'] {
  border-top: 1pt solid black;
  counter-reset: table-footnote;
}

/* Customize footnotes display, below the table. */
*[outputclass ~= 'table-fn'] {
  font-size: 1em;
  counter-increment: table-footnote;
}
*[outputclass ~= 'table-fn']::marker {
  font-size: 1em;
  content: "(" counter(table-footnote) ")";
}
Regards,
Julien

Re: Footnotes Related to Tables in PDF Documents

Posted: Fri Jul 29, 2022 3:46 pm
by patjporter
Hi Julien, thank you. In the XSLT you provided, the footnote calls in tables are being formatted as hyperlinks with the text decoration (blue, underline). Will this css entry override that?
When I deleted that part of the XSLT you provided (the part that converted the footnote calls to links), I now get the footnotes both under the table and at the bottom of the page, so I broke something.
Tried to fix on thing, broke another.
Pat

Re: Footnotes Related to Tables in PDF Documents

Posted: Mon Aug 01, 2022 5:20 pm
by Dan
Hello Pat,

I changed the stylesheet to:
1. Preserve the original ID on the LI generated for a footnote, so that the XREFs that point to the footnote still work.
2. Remove the footnotes with ID once they are copied as LIs in OLs. This avoids getting them in the footer of the page.
3. Replace footnotes without ID with XREFs that point to the generated LIs.

So this is the stylesheet - the second template is critical, please do not remove it.

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">

  <!--
    Match only top level tables (i.e tables that are not nested in other tables), that have footnotes.
  -->
  <xsl:template match="
      *[contains(@class, 'topic/table')]
      [not(ancestor::*[contains(@class, 'topic/table')])]
      [//*[contains(@class, 'topic/fn')]]">
    <xsl:next-match>
      <xsl:with-param name="top-level-table" select="." tunnel="yes"/>
    </xsl:next-match>
    <!-- Create a list with all the footnotes from the current table. -->
    <ol class="- topic/ol " outputclass="table-fn-container">
      <xsl:for-each select=".//*[contains(@class, 'topic/fn')]">
        <!-- Try to preserve the footnote ID, if available, so that the xrefs will have a target. -->
        <li class="- topic/li " id="{if(@id) then @id else generate-id(.)}" outputclass="table-fn">
          <xsl:apply-templates select="node()"/>
        </li>
      </xsl:for-each>
    </ol>
  </xsl:template>

  <!-- 
    The footnotes having an ID must be ignored, they are accessible only 
    through existing xrefs (xrefs added already in the merged.xml file).
    
    The above template already made a copy of these footnotes in the OL element
    so is not a problem if we do not generate markup for them in the cell. -->
  <xsl:template match="*[contains(@class, 'topic/entry')]//*[contains(@class, 'topic/fn')][@id]"/>

  <!-- 
    These are footnotes without ID. They are also copied in the OL element, 
    but have no xrefs pointing to them (because have no ID), so we generate xrefs. 
  -->
  <xsl:template match="*[contains(@class, 'topic/entry')]//*[contains(@class, 'topic/fn')][not(@id)]">
    <xsl:param name="top-level-table" tunnel="yes"/>

    <!-- Determine the footnote number as the index from the table, in normal document order. -->
    <xsl:variable name="fn-number" select="
        index-of($top-level-table//*[contains(@class, 'topic/fn')], .)"/>

    <xref type="fn" class="- topic/xref " href="#{generate-id(.)}" outputclass="table-fn-call">
      <!-- Generate an extra <sup>, identical to what DITA-OT generates for other xrefs. -->
      <sup class="+ topic/ph hi-d/sup ">
        <xsl:value-of select="$fn-number"/>
      </sup>
    </xref>
  </xsl:template>
</xsl:stylesheet>
Now, in the CSS, I changed the selectors that added "(" and ")" to the footnote calls (xrefs now) to match the pattern of the structure generated by DITA-OT for xrefs that point to footnotes.
Here is the CSS, the part referring to the footnotes:

Code: Select all

/* Customize footnote calls, inside the table. */
*[outputclass ~= 'table-fn-call'] {
  color: black;
  text-decoration: none;
  font-size: smaller;
  vertical-align: super;
  line-height: none;
}

/* Hide the "on page .." text that follows xrefs. */
*[outputclass ~= 'table-fn-call']:after {
  display: none;
}

/* Customize the list containing all the table footnotes. */
*[outputclass ~= 'table-fn-container'] {
  border-top: 1pt solid black;
  counter-reset: table-footnote;
}

/* Customize footnotes display, below the table. */
*[outputclass ~= 'table-fn'] {
  font-size: 8pt;
  counter-increment: table-footnote;
}
*[outputclass ~= 'table-fn']::marker {
  font-size: 8pt;
  content: "(" counter(table-footnote) ")";
}

/* Customize xrefs pointing to footnotes with IDs. */
*[class ~= "topic/table"] *[class ~= "topic/xref"][type = 'fn'] {
  color: unset;
  text-decoration: none;
}
*[class ~= "topic/table"] *[class ~= "topic/xref"][type = 'fn']:after {
  content: none;
}
*[class ~= "topic/table"] *[class ~= "topic/xref"][type = 'fn'] *[class ~= "hi-d/sup"]:before {
  content: "(";
}
*[class ~= "topic/table"] *[class ~= "topic/xref"][type = 'fn'] *[class ~= "hi-d/sup"]:after {
  content: ")";
}
IMPORTANT: Please test this customization on various example, to make sure there are no missing footnotes and that the links are working!

Many regards,
Dan

Re: Footnotes Related to Tables in PDF Documents

Posted: Thu Jul 27, 2023 4:49 am
by Tinmen
This approach and code work great as a template added to the DITA MAP PDF - based on HTML5 & CSS transform. I have been trying to adapt it to a DITA MAP PDF transform based on XML and XSLT transforms since I cannot add it as a merged template to my transform.

I have had some limited success with converting the CSS to XSL attributes and modifying the XSL code to call those attributes. For example, the XSL attributes:

Code: Select all

<xsl:attribute-set name="table__fn__call">
    <xsl:attribute name="color">black</xsl:attribute>
    <xsl:attribute name="text-decoration">none</xsl:attribute>
    <xsl:attribute name="font-size">7pt</xsl:attribute>
    <xsl:attribute name="vertical-align">super</xsl:attribute>
    <xsl:attribute name="line-height">0pt</xsl:attribute>
    <xsl:attribute name="display">none</xsl:attribute>
  </xsl:attribute-set>
  <xsl:attribute-set name="table__fn__container">
    <xsl:attribute name="border-top">1pt solid black</xsl:attribute>
    <xsl:attribute name="counter-reset">table-footnote</xsl:attribute>
  </xsl:attribute-set>
  <xsl:attribute-set name="table__fn">
    <xsl:attribute name="font-size">8pt</xsl:attribute>
    <xsl:attribute name="counter-increment">table-footnote</xsl:attribute>
  </xsl:attribute-set>
Modified XSL code snippet:

Code: Select all

<xsl:template match="
      *[contains(@class, 'topic/table')]
      [not(ancestor::*[contains(@class, 'topic/table')])]
      [//*[contains(@class, 'topic/fn')]]">
      <xsl:next-match>
        <xsl:with-param name="top-level-table" select="." tunnel="yes"/>
      </xsl:next-match>
      <!-- Create a list with all the footnotes from the current table. -->
      <fo:block xsl:use-attribute-sets="table__fn__container">
      <ol class="- topic/ol ">
        <fo:block xsl:use-attribute-sets="table__fn">
        <xsl:for-each select=".//*[contains(@class, 'topic/fn')]">
          <!-- Try to preserve the footnote ID, if available, so that the xrefs will have a target. -->
          <li class="- topic/li " id="{if(@id) then @id else generate-id(.)}">
            <xsl:apply-templates select="node()"/>
          </li>
        </xsl:for-each>
        </fo:block>
      </ol>
      </fo:block>
    </xsl:template>
Has anyone attempted to use this table footnote approach in this way?

As it happens using xsl fo, I can get the footnote line to appear after each table and the footnote numbers to appear in each cell, which is reset for each table. I cannot get the footnote legend to appear beneath the line for each table, nor can I get a footnote reset to work for footnotes that appear after the table. For example, I have two footnotes before the table, and they label as 1 and 2, respectively. I have 24 footnotes in three tables, each labeled 1 - 8. I have a remaining footnote after the last table that gets labeled as 27 (instead of 3). In the footnote legend at the bottom of the page, I have 1,2,27. So, the footnote counter for the page is not being reset, and it is adding up the total number of footnotes in the three tables.

None of this happens when using the code as part of a merged PDF template. But using that approach is not an option for the project I working on.

However, after several hours of effort, I wonder if it can be fully adapted to an xsl fop.

Any suggestions would be most appreciated.

Re: Footnotes Related to Tables in PDF Documents

Posted: Thu Aug 03, 2023 10:23 pm
by Tinmen
I've completed a rewrite using XSL FOP. For the most part, everything works. I didn't need the xref link for the list appearing under each table, so that code is not included. However, one major problem remains with my implementation. The footnote counter cannot be reset TMK using XSL FOP (it was never implemented in the XSLT 2.0 standard), so any footnote appearing outside a table is incremented by the total number of footnotes contained in the table. This results in footnotes outside a table having a very large number. In documents with lots of pages of tables, this can be very annoying and misleading. If anyone knows have to overcome this limitation, it would be most helpful.

Code: Select all

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:opentopic-func="http://www.idiominc.com/opentopic/exsl/function"
  xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:dita2xslfo="http://dita-ot.sourceforge.net/ns/200910/dita2xslfo"
  xmlns:dita-ot="http://dita-ot.sourceforge.net/ns/201007/dita-ot"
  exclude-result-prefixes="opentopic-func xs dita2xslfo dita-ot" version="2.0">

  <!-- xsl fop coded by Tinmen 7/2023 based on original xsl / css code from Oxygen -->
  <!--
    Match only top level tables (i.e tables that are not nested in other tables), that have footnotes.
  -->

  <!-- contents of table entries or similer structures -->

  <xsl:template match="
      *[contains(@class, 'topic/table')]
      [not(ancestor::*[contains(@class, 'topic/table')])]
      [//*[contains(@class, 'topic/fn')]]">
    <xsl:next-match>
      <xsl:with-param name="top-level-table" select="." tunnel="yes"/>
    </xsl:next-match>
    <!-- Create a list with all the footnotes from the current table. -->
    <fo:block keep-with-previous.within-page="always" border-top="0pt solid black"
      margin-right="30mm">
      <fo:list-block margin-top="3mm">
        <!-- Some tables may not contain footnotes so test for that -->
        <xsl:choose>
          <xsl:when test=".//*[contains(@class, 'topic/fn')]">
            <xsl:for-each select=".//*[contains(@class, 'topic/fn')]">
              <!-- Try to preserve the footnote ID, if available, so that the xrefs will have a target. -->
              <fo:list-item font-size="7.5pt" keep-with-next.within-page="always">
                <fo:list-item-label end-indent="label-end()">
                  <fo:block>
                    <xsl:number value="position()" format="1"/>
                  </fo:block>
                </fo:list-item-label>
                <fo:list-item-body>
                  <fo:block margin-left="4mm">
                    <xsl:if test="
                        if (@id) then
                          @id
                        else
                          generate-id(.)"> </xsl:if>
                    <xsl:apply-templates select="node()"/>
                  </fo:block>
                </fo:list-item-body>
              </fo:list-item>
            </xsl:for-each>
          </xsl:when>
          <xsl:otherwise>
            <fo:list-item keep-with-next.within-page="always">
              <fo:list-item-label end-indent="label-end()"/> 
              <fo:list-item-body/>
            </fo:list-item>
          </xsl:otherwise>
        </xsl:choose>
      </fo:list-block>
    </fo:block>
  </xsl:template>


  <!-- 
    The footnotes having an ID must be ignored, they are accessible only 
    through existing xrefs (xrefs added already in the merged.xml file).
    
    The above template already made a copy of these footnotes in the OL element
    so is not a problem if we do not generate markup for them in the cell. -->

  <xsl:template match="*[contains(@class, 'topic/entry')]//*[contains(@class, 'topic/fn')][@id]"/>

  <!-- 
    These are footnotes without ID. They are also copied in the OL element, 
    but have no xrefs pointing to them (because have no ID), so we generate xrefs. 
  -->

  <xsl:template
    match="*[contains(@class, 'topic/entry')]//*[contains(@class, 'topic/fn')][not(@id)]">
    <xsl:param name="top-level-table" tunnel="yes"/>
    <!-- Determine the footnote number as the index from the table, in normal document order. -->
    <xsl:variable name="fn-number" select="
        index-of($top-level-table//*[contains(@class, 'topic/fn')], .)"/>
    <fo:inline padding-left="1mm" baseline-shift="super" color="black" font-size="6pt">
      <xsl:value-of select="$fn-number"/>
    </fo:inline>
  </xsl:template>
</xsl:stylesheet>

Re: Footnotes Related to Tables in PDF Documents

Posted: Tue Aug 08, 2023 12:48 pm
by julien_lacour
Hello,

You can overwrite the following template from org.dita.pdf2/xsl/fo/topic.xsl:

Code: Select all

<xsl:template match="*[contains(@class,' topic/fn ')]" mode="callout">
  <xsl:choose>
    <xsl:when test="@callout">
      <xsl:value-of select="@callout"/>
    </xsl:when>
    <xsl:otherwise>
      <!--<xsl:value-of select="count(key('enumerableByClass', 'topic/fn')[. &lt;&lt; current()]) + 1"/>-->
      <xsl:value-of select="index-of(//*[contains(@class, 'topic/fn')][not(ancestor::*[contains(@class, 'topic/table')])], .)"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>
The original 'value-of' is commented, the new one only get the index of footnotes outside tables.

Regards,
Julien

Re: Footnotes Related to Tables in PDF Documents

Posted: Tue Aug 08, 2023 6:27 pm
by Tinmen
Perfect! Thank you, Julien. That worked.
I added the template you provided to my custom file, which solved the problem.
Regards
Tinmen

Re: Footnotes Related to Tables in PDF Documents

Posted: Fri Aug 11, 2023 12:08 am
by Tinmen
Hi Julien:
I noted a problem arose, which I didn't see at first. The code fixes the numbering issue. However, when I need to use tags within the fn by setting an ID, the footnote for that resue tag appears below the table, but the numbers for the reusable footnote do not appear inside the table in the rendered PDF. The number "1" should appear in the highlighted areas.
For example:

Code: Select all

<entry>Do Not Disturb<fn id="1">See call times.</fn></entry>
and then the subsequent xref back to the reusable fn ID.

Code: Select all

<entry>After Midnight<xref href="#first_topic/1" type="fn"/></entry>
Can this approach support reusable fn tags?
Regards
Tinmen

Re: Footnotes Related to Tables in PDF Documents

Posted: Fri Aug 11, 2023 2:45 pm
by julien_lacour
Hello,

If you add the following template that process xrefs in table cells, you should have all that you need:

Code: Select all

<xsl:template match="*[contains(@class, 'topic/xref')][@type='fn']
  [ancestor::*[contains(@class, 'topic/entry')]]">
  <xsl:param name="top-level-table" tunnel="yes"/>
  <xsl:variable name="destination" select="opentopic-func:getDestinationId(@href)"/>
  <xsl:variable name="fn" select="
    $top-level-table//*[contains(@class, 'topic/fn')][@id = $destination]"/>
  <xsl:choose>
    <xsl:when test="$fn">
      <!-- There is a reference in the table, recalculate index. -->
      <xsl:variable name="fn-number" select="
        index-of($top-level-table//*[contains(@class, 'topic/fn')], $fn)"/>
      <fo:inline padding-left="1mm" baseline-shift="super" color="black" font-size="6pt">
        <xsl:value-of select="$fn-number"/>
      </fo:inline>
    </xsl:when>
    <xsl:otherwise>
      <!-- There is no reference in the table, keep original index. -->
      <xsl:next-match/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>
Regards,
Julien

Re: Footnotes Related to Tables in PDF Documents

Posted: Fri Aug 11, 2023 9:48 pm
by Tinmen
Thanks, Julien.
Unfortunately, this code doesn't correct the issue (yet). It may be due to the following error message I see relating to

Code: Select all

select="opentopic-func:getDestinationId(@href)"/>
Error Message
Cannot find a 1-argument function named Q{http://www.idiominc.com/opentopic/exsl/ ... nationId()
UPDATE
I sorted out the issue with the error occurring. I had the version set to 2.0, so I changed it back to 1.1, and that took care of the opentopic error message.

Everything is working now.

Regards
Tinmen

Re: Footnotes Related to Tables in PDF Documents

Posted: Mon Mar 11, 2024 10:36 am
by Heidi
julien_lacour wrote: Tue Oct 19, 2021 9:41 am Hello Pat,

If you want to move table footnotes follow these instructions:
  1. Create a publishing template file (.opt) in a new folder from your project. Then create an xslt folder inside it.
  2. In the newly created folder, create an XSLT style-sheet (for example merged2mergedExtension.xsl) with the following content:

    Code: Select all

        <?xml version="1.0" encoding="UTF-8"?>
        <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:xs="http://www.w3.org/2001/XMLSchema"
          exclude-result-prefixes="xs"
          version="2.0">
    
          <!-- Match only top level tables (i.e tables that are not nested in other tables),
            that have footnotes. -->
          <xsl:template match="
              *[contains(@class, 'topic/table')]
              [not(ancestor::*[contains(@class, 'topic/table')])]
              [//*[contains(@class, 'topic/fn')]]">
            <xsl:next-match>
              <xsl:with-param name="top-level-table" select="." tunnel="yes"/>
            </xsl:next-match>
    
            <!-- Create a list with all the footnotes from the current table. -->
            <ol class="- topic/ol " outputclass="table-fn-container">
              <xsl:for-each select=".//*[contains(@class, 'topic/fn')]">
                <li class="- topic/li " id="{generate-id(.)}" outputclass="table-fn">
                  <xsl:apply-templates select="node()"/>
                </li>
              </xsl:for-each>
            </ol>
          </xsl:template>
    
          <!-- Match the footnotes in table entries, replace them with a link. -->
          <xsl:template match="*[contains(@class, 'topic/entry')]//*[contains(@class, 'topic/fn')]">
            <xsl:param name="top-level-table" tunnel="yes"/>
            <!-- Determine the footnote number. -->
            <xsl:variable name="fn-number" select="
                index-of($top-level-table//*[contains(@class, 'topic/fn')], .)"/>
            <xref type="fn" class="- topic/xref " href="#{generate-id(.)}"
              outputclass="table-fn-call">
              <xsl:value-of select="$fn-number"/>
            </xref>
          </xsl:template>
    
        </xsl:stylesheet>
    
  3. Open the .opt file and set the XSLT style-sheet created in the previous step with the com.oxygenxml.pdf.css.xsl.merged2html5 XSLT extension point:

    Code: Select all

        <publishing-template>
          ...
          <pdf>
            ...        
            <xslt>
              <extension
                id="com.oxygenxml.pdf.css.xsl.merged2merged"
                file="xslt/merged2mergedExtension.xsl"/>
            </xslt>
    
  4. Create a css folder in the publishing template directory. In this directory, save a custom CSS file with rules that style the glossary structure. For example:

    Code: Select all

        /* Customize footnote calls, inside the table. */
        *[outputclass ~= 'table-fn-call'] {
          color: black;
          text-decoration: none;
          font-size: smaller;
          vertical-align: super;
          line-height: none;
        }
    
        /* Hide the "on page .." text that follows xrefs. */
        *[outputclass ~= 'table-fn-call']:after {
          display: none;
        }
    
        /* Customize the list containing all the table footnotes. */
        *[outputclass ~= 'table-fn-container'] {
          border-top: 1pt solid black;
        }
    
        /* Customize footnotes display, below the table. */
        *[outputclass ~= 'table-fn'] {
          font-size: 1em;
        }
        *[outputclass ~= 'table-fn']::marker {
          font-size: 1em;
        }
    
  5. Open the template descriptor file associated with your publishing template (the .opt file) and reference your custom CSS file in the resources element:

    Code: Select all

        <publishing-template>
          ...
          <pdf>
            ...                
            <resources>            
              <css file="css/custom.css"/>
            </resources> 
    
  6. Edit the DITA Map PDF - based on HTML5 & CSS transformation scenario.
  7. In the Templates tab, click the Choose Custom Publishing Template link and select your template.
  8. Click OK to save the changes and run the transformation scenario.
Feel free to change the values from the CSS in order to obtain the desired output.

Regards,
Julien
Hi,
I added this configuration and it works well. But I have 2 issues:

1. When I want to set an alternative callout (e.g. <fn callout="*"...>) the output is still numbered. Is there a way to change the configuration that alternative callouts can be set?

2. The text is displayed indented. I tried to change the css with margin-left:0;, but this isn't working. I think its because of the <ol> container. Can I only change this, when I change the <ol> element in general? Or is there another way?

Thank you
Heidi

Re: Footnotes Related to Tables in PDF Documents

Posted: Mon Mar 11, 2024 12:22 pm
by julien_lacour
Hello Heidi,

1. To take the callout attribute value into account, you need to change a little bit the stylesheets:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:opentopic-func="http://www.idiominc.com/opentopic/exsl/function"
  exclude-result-prefixes="xs opentopic-func" 
  version="2.0">
  
  <!--
    Match only top level tables (i.e tables that are not nested in other tables),
    that contains some footnotes.
  -->
  <xsl:template match="*[contains(@class, 'topic/table')]
    [not(ancestor::*[contains(@class, 'topic/table')])]
    [//*[contains(@class, 'topic/fn')]]">
    <xsl:next-match>
      <xsl:with-param name="top-level-table" select="." tunnel="yes"/>
    </xsl:next-match>
    <!-- Create a list with all the footnotes from the current table. -->
    <ol class="- topic/ol " outputclass="table-fn-container">
      <xsl:for-each select=".//*[contains(@class, 'topic/fn')]">
        <!--
          Try to preserve the footnote ID, if available, so that the xrefs will have a target.
        -->
        <li class="- topic/li " id="{if(@id) then @id else generate-id(.)}"
          outputclass="table-fn">
          <xsl:copy-of select="@callout"/>
          <xsl:apply-templates select="node()"/>
        </li>
      </xsl:for-each>
    </ol>
  </xsl:template>
  
  <!-- 
    The footnotes that have an ID must be ignored, they are accessible only 
    through existing xrefs (already present in the merged.xml file).
    
    The above template already made a copy of these footnotes in the OL element
    so it is not a problem if markup is not generated for them in the cell.
  -->
  <xsl:template
    match="*[contains(@class, 'topic/entry')]//*[contains(@class, 'topic/fn')][@id]"/>
  
  <!--
    The xrefs to footnotes with IDs inside table-cells. We need to recalculate
    their indexes if their referenced footnote is also in the table.
  -->
  <xsl:template match="*[contains(@class, 'topic/xref')][@type='fn']
    [ancestor::*[contains(@class, 'topic/entry')]]">
    <xsl:param name="top-level-table" tunnel="yes"/>
    <xsl:variable name="destination" select="opentopic-func:getDestinationId(@href)"/>
    <xsl:variable name="fn" select="
      $top-level-table//*[contains(@class, 'topic/fn')][@id = $destination]"/>
    <xsl:choose>
      <xsl:when test="$fn">
        <!-- There is a reference in the table, recalculate index. -->
        <xsl:variable name="fn-number" select="
          index-of($top-level-table//*[contains(@class, 'topic/fn')], $fn)"/>
        <xsl:copy>
          <xsl:apply-templates select="@*"/>
          <xsl:apply-templates select="$fn/@callout"/>
          <xsl:apply-templates select="node()
            except (text(), *[contains(@class, 'hi-d/sup')])"/>
          <sup class="+ topic/ph hi-d/sup ">
            <xsl:apply-templates select="child::*[contains(@class, 'hi-d/sup')]/@*"/>
            <xsl:value-of select="$fn-number"/>
          </sup>
        </xsl:copy>
      </xsl:when>
      <xsl:otherwise>
        <!-- There is no reference in the table, keep original index. -->
        <xsl:next-match/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <!-- 
    The footnotes without ID inside table-cells. They are copied in the OL element, but have 
    no xrefs pointing to them (because they have no ID), so xrefs are generated. 
  -->
  <xsl:template
    match="*[contains(@class, 'topic/entry')]//*[contains(@class, 'topic/fn')][not(@id)]">
    <!-- Determine the footnote index in the document order. -->
    <xsl:param name="top-level-table" tunnel="yes"/>
    <xsl:variable name="fn-number" select="
      index-of($top-level-table//*[contains(@class, 'topic/fn')], .)"/>
    <xref type="fn" class="- topic/xref "
      href="#{generate-id(.)}" outputclass="table-fn-call">
      <xsl:copy-of select="@callout"/>
      <!-- Generate an extra <sup>, identical to what DITA-OT generates for other xrefs. -->
      <sup class="+ topic/ph hi-d/sup ">
        <xsl:value-of select="$fn-number"/>
      </sup>
    </xref>
  </xsl:template>
  
</xsl:stylesheet>

Code: Select all

/* Customize footnote calls, inside the table. */
*[outputclass ~= 'table-fn-call'] {
  line-height: none;
}
*[class ~= "topic/table"] *[class ~= "topic/xref"][type = 'fn'][callout] *[class ~= "hi-d/sup"] {
  content: oxy_xpath("ancestor::*[contains(@class, 'topic/xref')]/@callout");
}

/* Customize the list containing all the table footnotes. */
*[outputclass ~= 'table-fn-container'] {
  border-top: 1pt solid black;
  counter-reset: table-footnote;
}

/* Customize footnotes display, below the table. */
*[outputclass ~= 'table-fn'] {
  font-size: smaller;
  counter-increment: table-footnote;
}
*[outputclass ~= 'table-fn']::marker {
  font-size: smaller;
  content: "(" counter(table-footnote) ")";
}
*[outputclass ~= 'table-fn'][callout]::marker {
  content: "(" attr(callout) ")";
}

/* Customize xrefs pointing to footnotes, inside the table. */
*[class ~= "topic/table"] *[class ~= "topic/xref"][type = 'fn'] {
  color: unset;
  text-decoration: none;
}
*[class ~= "topic/table"] *[class ~= "topic/xref"][type = 'fn']:after {
  content: none;
}
*[class ~= "topic/table"] *[class ~= "topic/xref"][type = 'fn'] *[class ~= "hi-d/sup"]:before {
  content: "(";
}
*[class ~= "topic/table"] *[class ~= "topic/xref"][type = 'fn'] *[class ~= "hi-d/sup"]:after {
  content: ")";
}
I will update the documentation with these modifications too.

2. To remove the ol indent you need to use padding instead of margin:

Code: Select all

*[outputclass ~= 'table-fn-container'] {
  padding-left: 0;
}
Regards,
Julien

Re: Footnotes Related to Tables in PDF Documents

Posted: Tue Mar 12, 2024 11:36 am
by Heidi
Hi Julien,
thanks a lot for this modifications! They work as expected.

LG Heidi