Bookmark

Sample JavaScript code to use Apryse SDK for programmatically reading and editing existing outline items, and for creating new PDF bookmarks using the high-level API. Learn more about our Web SDK and PDF Editing & Manipulation Library.

1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2023 by Apryse Software Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6(exports => {
7
8
9
10
11
12
13
14
15
16
17
18
19 exports.runBookmarkTest = () => {
20 const PDFNet = exports.Core.PDFNet;
21
22 const addIndent = async (item, str) => {
23 const ident = (await item.getIndent()) - 1;
24 for (let i = 0; i < ident; ++i) {
25 str += ' ';
26 // note: must manually set IndentString to empty after this function is called.
27 }
28 return str;
29 };
30
31 const printOutlineTree = async item => {
32 for (; item != null; item = await item.getNext()) {
33 let IndentString = '';
34 let ActionString = '';
35 let TitleString = '';
36
37 IndentString = await addIndent(item, IndentString);
38 TitleString = await item.getTitle();
39
40 ActionString = (IndentString + (await item.isOpen()) ? '- ' : '+ ') + TitleString + ' ACTION -> ';
41
42 const action = await item.getAction();
43 if (await action.isValid()) {
44 const actionType = await action.getType();
45 if (actionType === PDFNet.Action.Type.e_GoTo) {
46 const dest = await action.getDest();
47 if (await dest.isValid()) {
48 const page = await dest.getPage();
49 console.log(ActionString + 'GoTo Page # ' + (await page.getIndex()));
50 }
51 } else {
52 console.log(ActionString + 'Not a "GoTo" action');
53 }
54 } else {
55 console.log(ActionString + 'NULL');
56 }
57
58 if (await item.hasChildren()) {
59 await printOutlineTree(await item.getFirstChild());
60 }
61 }
62 };
63
64 const main = async () => {
65 const ret = 0;
66
67 // Relative path to the folder containing test files.
68 const inputPath = '../TestFiles/';
69
70 // The following example illustrates how to create and edit the outline tree
71 // using high-level Bookmark methods.
72
73 let doc = await PDFNet.PDFDoc.createFromURL(inputPath + 'numbered.pdf');
74 doc.initSecurityHandler();
75 doc.lock();
76
77 // Lets first create the root bookmark items.
78 const red = await PDFNet.Bookmark.create(doc, 'Red');
79 const green = await PDFNet.Bookmark.create(doc, 'Green');
80 const blue = await PDFNet.Bookmark.create(doc, 'Blue');
81
82 doc.addRootBookmark(red);
83 doc.addRootBookmark(green);
84 doc.addRootBookmark(blue);
85
86 // You can also add new root bookmarks using Bookmark.addNext("...")
87 blue.addNewNext('foo');
88 blue.addNewNext('bar');
89
90 // We can now associate new bookmarks with page destinations:
91
92 // The following example creates an 'explicit' destination (see
93 // section '8.2.1 Destinations' in PDF Reference for more details)
94
95 const redIter = await doc.getPageIterator(1);
96
97 const redCurrpage = await redIter.current();
98 // eslint-disable-next-line @typescript-eslint/no-unused-vars
99 const redCurrpageActual = await doc.getPage(1);
100 const redDest = await PDFNet.Destination.createFit(redCurrpage);
101 red.setAction(await PDFNet.Action.createGoto(redDest));
102
103 // Create an explicit destination to the first green page in the document
104 const tenthPage = await doc.getPage(10);
105 const greenDest = await PDFNet.Destination.createFit(tenthPage);
106 green.setAction(await PDFNet.Action.createGoto(greenDest));
107
108 // The following example creates a 'named' destination (see
109 // section '8.2.1 Destinations' in PDF Reference for more details)
110 // Named destinations have certain advantages over explicit destinations.
111 const key = 'blue1';
112 const nineteenthPage = await doc.getPage(19);
113 const blueDest = await PDFNet.Destination.createFit(nineteenthPage);
114 const blueAction = await PDFNet.Action.createGotoWithKey(key, blueDest); // TODO FIND FIX
115
116 blue.setAction(blueAction);
117
118 // We can now add children Bookmarks subRed1 instanceof Promise
119 const subRed1 = await red.addNewChild('Red - Page 1');
120 subRed1.setAction(await PDFNet.Action.createGoto(await PDFNet.Destination.createFit(await doc.getPage(1))));
121 const subRed2 = await red.addNewChild('Red - Page 2');
122 subRed2.setAction(await PDFNet.Action.createGoto(await PDFNet.Destination.createFit(await doc.getPage(2))));
123 const subRed3 = await red.addNewChild('Red - Page 3');
124 subRed3.setAction(await PDFNet.Action.createGoto(await PDFNet.Destination.createFit(await doc.getPage(3))));
125 const subRed4 = await subRed3.addNewChild('Red - Page 4');
126 subRed4.setAction(await PDFNet.Action.createGoto(await PDFNet.Destination.createFit(await doc.getPage(4))));
127 const subRed5 = await subRed3.addNewChild('Red - Page 5');
128 subRed5.setAction(await PDFNet.Action.createGoto(await PDFNet.Destination.createFit(await doc.getPage(5))));
129 const subRed6 = await subRed3.addNewChild('Red - Page 6');
130 subRed6.setAction(await PDFNet.Action.createGoto(await PDFNet.Destination.createFit(await doc.getPage(6))));
131
132 // Example of how to find and delete a bookmark by title text.
133 const firstbookmark = await doc.getFirstBookmark();
134 const foo = await firstbookmark.find('foo');
135 if (await foo.isValid()) {
136 foo.delete();
137 } else {
138 console.log('Bookmark foo is invalid');
139 }
140 const bar = await firstbookmark.find('bar');
141 if (await bar.isValid()) {
142 bar.delete();
143 } else {
144 console.log('Bookmark bar is invalid');
145 }
146
147 // Adding color to Bookmarks. Color and other formatting can help readers
148 // get around more easily in large PDF documents.
149 red.setColor(1, 0, 0);
150 green.setColor(0, 1, 0);
151 green.setFlags(2); // set bold font
152 blue.setColor(0, 0, 1);
153 blue.setFlags(3); // set bold and italic
154
155 const bookmarkBuffer = await doc.saveMemoryBuffer(0);
156 saveBufferAsPDFDoc(bookmarkBuffer, 'bookmark.pdf');
157 console.log('Done. Result saved in bookmark.pdf');
158
159 // The following example illustrates how to traverse the outline tree using
160 // Bookmark navigation methods: Bookmark.getNext(), Bookmark.getPrev(),
161 // Bookmark.getFirstChild () and Bookmark.getLastChild ().
162
163 // Open the document that was saved in the previous code sample
164 const docOut = await PDFNet.PDFDoc.createFromBuffer(bookmarkBuffer);
165 docOut.initSecurityHandler();
166 docOut.lock();
167
168 const root = await docOut.getFirstBookmark();
169 await printOutlineTree(root);
170
171 console.log('Done.');
172
173 // The following example illustrates how to create a Bookmark to a page
174 // in a remote document. A remote go-to action is similar to an ordinary
175 // go-to action, but jumps to a destination in another PDF file instead
176 // of the current file. See Section 8.5.3 'Remote Go-To Actions' in PDF
177 // Reference Manual for details.
178
179 // Use the document from the previous sample. The sample is done this way
180 // since we cannot guarantee that bookmarkBuffer is still valid since it
181 // may have been sent using transfers to the worker
182 doc = docOut;
183
184 doc.initSecurityHandler();
185
186 // Create file specification (the file referred to by the remote bookmark)
187 const fileSpec = await doc.createIndirectDict();
188 fileSpec.putName('Type', 'Filespec');
189 fileSpec.putString('F', 'bookmark.pdf');
190 const spec = await PDFNet.FileSpec.createFromObj(fileSpec);
191 const gotoRemote = await PDFNet.Action.createGotoRemoteSetNewWindow(spec, 5, true);
192
193 const remoteBookmark1 = await PDFNet.Bookmark.create(doc, 'REMOTE BOOKMARK 1');
194 remoteBookmark1.setAction(gotoRemote);
195 doc.addRootBookmark(remoteBookmark1);
196
197 // Create another remote bookmark, but this time using the low-level SDF/Cos API.
198 // Create a remote action
199 const remoteBookmark2 = await PDFNet.Bookmark.create(doc, 'REMOTE BOOKMARK 2');
200 doc.addRootBookmark(remoteBookmark2);
201
202 const gotoR = await (await remoteBookmark2.getSDFObj()).putDict('A');
203 {
204 gotoR.putName('S', 'GoToR'); // Set action type
205 gotoR.putBool('NewWindow', true);
206
207 // Set the file specification
208 gotoR.put('F', fileSpec);
209
210 // jump to the first page. Note that pages are indexed from 0.
211 const dest = await gotoR.putArray('D');
212 dest.pushBackNumber(9);
213 dest.pushBackName('Fit');
214 }
215
216 const docbuf = await doc.saveMemoryBuffer(PDFNet.SDFDoc.SaveOptions.e_remove_unused);
217 saveBufferAsPDFDoc(docbuf, 'bookmark_remote.pdf');
218
219 console.log('Done. Result saved in bookmark_remote.pdf');
220 return ret;
221 };
222 // add your own license key as the second parameter, e.g. PDFNet.runWithCleanup(main, 'YOUR_LICENSE_KEY')
223 PDFNet.runWithCleanup(main);
224 };
225})(window);
226// eslint-disable-next-line spaced-comment
227//# sourceURL=BookmarkTest.js

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales