2

Is there a possibility to generate bookmarks (for DDX table of content) with Coldfusion or DDX without starting a new page?

Coldfusion gives us the possibility to generate pdf-bookmarks with:

<cfdocumentsection name=""></cfdocumentsection>

But this also creates a new page.

All help is welcome.

code:

<cfdocument name="myPdf" format="PDF">
    <cfdocumentsection name="section 1">
        This is section 1
    </cfdocumentsection>
    <cfdocumentsection name="section 2">
        This is section 2
    </cfdocumentsection>
    <cfdocumentsection name="section 3">
        This is section 3
    </cfdocumentsection>
</cfdocument>
<cfprocessingdirective suppressWhitespace="true">
        <cfcontent type="application/pdf" reset="true" variable="#tobinary(myPdf)#"/>
</cfprocessingdirective>

this results in a pdf document with 3 pages and 3 bookmarks

Xavier L.
  • 368
  • 1
  • 11
  • The `` tag in itself does not create a new page. Most likely it is something else in your code causing that to happen but you have not given the code for us to see. So we cannot be of much help. Add more of your code to the question so we might be able to help you. – Miguel-F May 23 '16 at 12:58
  • i got a feeling cfdocumentsection does create a new page, i was playing with it a while back and this is something came across that i couldn't find a way around – luke May 23 '16 at 18:04

2 Answers2

2

I found the solution, but it's not easy:

Let's say we have 3 sections of undefined length

    <cfsavecontent variable="section1">
        <p>This is section 1</p>
    </cfsavecontent>
    <cfsavecontent variable="section2">
        <p>This is section 2</p>
    </cfsavecontent>
    <cfsavecontent variable="section3">
        <p>This is section 3</p>
    </cfsavecontent>

<cfset sectionList = 'section1,section2,section3'>
<cfset bookmarkList = "">
<cfset content = "">
<cfset currentPage = 1>
<cfloop list="#sectionList#" index="i">
    <cfdocument name="infoPdf" format="PDF" bookmark="false">
        <cfdocumentsection>
            <cfoutput>#content#</cfoutput>
            <h2>FakeHeader</h2>
        </cfdocumentsection>
    </cfdocument>

Get the page info to know at what page the content will be

        <cfpdf action="getinfo" name="pdfInfo" source="infoPdf">
        <cfset currentPage = pdfInfo.TotalPages>
        <cfset bookmarkList = listAppend(bookmarkList, currentPage)> 
        <cfset content &= VARIABLES[i]> 
        <cfdocument name="myPdf" format="PDF" bookmark="false">
            <cfdocumentsection>
                <cfoutput>#content#</cfoutput>
            </cfdocumentsection>
        </cfdocument>
    </cfloop>
    <cfset fileWrite(ExpandPath("test.pdf"),myPdf)>

Define bookmark.xml for DDX manipulation

<cfxml variable="bookmarks">
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Bookmarks xmlns="http://ns.adobe.com/pdf/bookmarks" version="1.0">
    <cfoutput>
        <cfloop from="1" to="#listlen(sectionList)#" index="i">
            <Bookmark>
                <Title>#ListGetAt(sectionList,i)#</Title>
                <Dest>
                  <Fit PageNum="#ListGetAt(bookmarkList,i)-1#"/>
                </Dest>
            </Bookmark>  
        </cfloop>
    </cfoutput>
</Bookmarks>
</cfxml>
<cfset fileWrite(ExpandPath("/bookmarks.xml"),bookmarks)>

DDX file

<cfsavecontent variable="myDDX">
    <DDX xmlns="http://ns.adobe.com/DDX/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://ns.adobe.com/DDX/1.0/ coldfusion_ddx.xsd">
        <PDF result="Out1">
            <PDF source="test"/>
            <Bookmarks source="inputxml"/>
        </PDF>
        <PDF result="Out">
            <TableOfContents includeInTOC="false" bookmarkTitle="Table of Contents"  maxBookmarkLevel="infinite">   
                <TableOfContentsEntryPattern applicableLevel="all">
                    <StyledText>
                        <p font-family="Arial" font-size="11pt">
                            <_BookmarkTitle/>
                            <Space/>
                            <Space/>
                            <leader leader-pattern="dotted"/>
                            <Space/>
                            <Space/> 
                            <_BookmarkPageCitation/>
                        </p>
                    </StyledText>
                </TableOfContentsEntryPattern>
            </TableOfContents>
            <PDF source="Out1"/>
        </PDF>
    </DDX>
</cfsavecontent>

DDX processing

    <cfset inputStruct = StructNew()>
    <cfset inputStruct.test = 'test.pdf'>
    <cfset inputStruct.inputxml = "bookmarks.xml"/>
    <cfset outputStruct = StructNew()>
    <cfset outputStruct.Out = "CombinedDocument.pdf">
<cfpdf action="processddx" ddxfile="#myddx#" inputfiles="#inputStruct#" outputfiles="#outputStruct#" name="ddxVar">
<cfpdf action="read" source="CombinedDocument.pdf" name="resultPdf">
<cfprocessingdirective suppressWhitespace="true">
    <cfcontent type="application/pdf" reset="true" variable="#tobinary(resultPdf)#"/>
</cfprocessingdirective> 
Xavier L.
  • 368
  • 1
  • 11
0

In your <cfdocument> tag try adding the bookmark attribute to enable bookmarks within the PDF. Like this:

<cfdocument name="myPdf" format="PDF" bookmark="yes">
    ...

NOTE: Support for this was added in ColdFusion 9. You did not mention what version you are running.

See the docs

Bookmarks

ColdFusion 9 supports bookmarks. In the cfdocument tag, set the bookmark attribute to yes. Then specify the bookmark name for each cfdocumentsection tag.

Miguel-F
  • 13,450
  • 6
  • 38
  • 63
  • that still creates a new page for each bookmark/cfdocumentsection – luke May 23 '16 at 21:40
  • I'm using Coldfusion 2016. Bookmark="true" just generates the bookmark for the PDF but it still creates a new page for each cfdocumentsection. I'm trying to add multiple bookmarks/page. Multi-level bookmark would also be a nice feature by eg. nesting cfdocumentsection-tags but this is not supported. the only way this works is with DDX. But each bookmark still results in a new page. – Xavier L. May 24 '16 at 07:15