Copy link to clipboard
Copied
Hello all!
Adobe Acrobat DC pro
Mac os 10.12.6
I want to create a acrobat action to split top level bookmarks using bm names for file names, to my surprise Adobe doesn't have that as an option under the "tools to add" when creating a new action. I was equally surprised to find very little discussion or code postings on the net about this subject.
What I did find doesn't work. I was hoping one of the experts on the forum could take a look at the code below and give some direction on how to get it to work.
Thanks in advance!!
BookmarkCollection bookmarks = document.Bookmarks;
for ( int index=0, fromPage=0; index<bookmarks.Count; index++ )
{
// determine last page of next part
int toPage = -1;
Bookmark bookmark = null;
if ( index == bookmarks.Count-1 )
{
// last bookmark - append all remaining pages
toPage = document.Pages.Count;
}
else
{
// not the last bookmark - append up to the next bookmark
bookmark = bookmarks[index+1];
GoToAction action = bookmark.Actions[0] as GoToAction;
if ( null != action )
{
InternalDestination destination = action.Destination as
InternalDestination;
if ( null != destination )
{
toPage = destination.Page.Index;
}
}
}
// create a new part
if ( -1 != toPage && null != bookmark )
{
Document part = new Document();
for ( int pageIndex=fromPage; pageIndex<toPage; pageIndex++ )
{
part.Pages.Add( document.Pages[pageIndex].Clone() );
}
using ( FileStream fileOut = new FileStream(
bookmark.Title + ".pdf", FileMode.Create, FileAccess.Write ) )
{
part.Write( fileOut );
}
fromPage = toPage;
}
}
Opps , missed that part, well here is an update,
bkTrgt.forEach(function(a,i,k){oDoc.extractPages(k,((i+1)<k.length)?k[i+1]-1:oDoc.numPages-1,oDoc.bookmarkRoot.children.name + ".pdf"})
The bookmarks children have exactly the same indexes as the page numbers in the array, so I just changed the code the get the save file name from the bookmark name at the index that is being operated on..
Copy link to clipboard
Copied
Any specific reason not to use the built-in command that does that? It's under the Split Document function.
Copy link to clipboard
Copied
PS. The code above was not written for Acrobat.
PPS. I've developed a script (a long time ago) that does it, if you're interested: Custom-made Adobe Scripts: Acrobat -- Extract Chapters by Bookmarks
Copy link to clipboard
Copied
Hello,
I wanted to create a acrobat action to split top level bookmarks so I could point to a folder location full of bookmarked pdfs, so I wouldn't have to physically open each file and go through the process: Organize Pages/Split/Split by: Top level bookmarks/Output Options/Use bookmark names for file names.
Thanks......
Copy link to clipboard
Copied
The built-in Split function will split files based on top level bookmarks and can be run against multiple files as though it were being initiated from an Action. Unless there is something you're leaving out of your question, there's no need to create an Action to do this.
Copy link to clipboard
Copied
Thanks for the reply Joel
Your'e correct as the Acrobat split function can be run against multiple files, I am working on creating an action that Creates Bookmarks-From Tags then I am running js to make them top level bookmarks, I just wanted to add the split function to make it fully automated.
Thanks
Copy link to clipboard
Copied
You may be over complicating this. What software is adding the tags?
Copy link to clipboard
Copied
Hello!
This is what I have for the action to create top level bookmarks from a tagged pdf and then split based on the bookmark names.
The problem i am having is I can't figure out how to loop to iterate over the bookmarks, executing
each one and then using the current page number information to determine the page range of each bookmark,
and then extract it as a new file with different page counts based on the # of pages between the bookmarks. What I am getting are pdfs named by the bookmarks with only one page and none of the pages between the bookmarks.
/* MakeTopLevelBookmarks */
var bm = this.bookmarkRoot;
var bmToDeleteArray = new Array();
// Iterate through each bookmark
var ibmLength = bm.children.length;
for (var i = 0; i < ibmLength; i++)
{
var bmToCheck = bm.children;
if((bmToCheck.name.indexOf("Structure")!=-1) && (bmToCheck.children!=null))
{
console.println("found bookmark with children " + i);
var ibmChildrenToMoveLength = bmToCheck.children.length;
for(var j=0; j<ibmChildrenToMoveLength; j++)
{
console.println("moving bookmark " + j);
bm.insertChild(bmToCheck.children[0], bm.children.length);
}
bmToDeleteArray[bmToDeleteArray.length] = bmToCheck;
}
}
for (var i = 0; i < bmToDeleteArray.length; i++)
{
// Delete bookmark
bmToDeleteArray.remove();
}
delete bmToDeleteArray;
/* Now Split */
if (this.bookmarkRoot.children!=null)
{
for (var i=0; i < this.bookmarkRoot.children.length; i++)
{
var bm = this.bookmarkRoot.children.execute();
var bmname = this.bookmarkRoot.children.name;
this.extractPages({nStart:bm + this.pageNum++, cPath: ""+ bmname +".pdf"});
}
}
Thanks in advance for any help!!
Copy link to clipboard
Copied
Loop Twice, once to collect target page data into an array, and then loop over the array to split out the pages
Copy link to clipboard
Copied
Hi Thom,
I am new to scripting, I understand the concept I just don't know the method/properties to perform the function.
Thanks in advance for any help!!
Copy link to clipboard
Copied
This type of coding is very tricky because you have to make several assumptions, any of which could break the script.
Assumptions
1. the bookmark goes to a page (could open an URL or do something else).
2. The pages are in order.
3. Executing happens synchronously, or fast enough to seem synchronous.
So here is some code that collects all the top level bookmark destinations, assuming all the assumptions are met.
oDoc = this;
bkTbkTrgt = []
this.bookmarkRoot.children.forEach(function(a){a.execute();bkTrgt.push(pageNum);})
Now extracting the pages is just a matter of walking this list
bkTrgt.forEach(function(a,i,k){oDoc.extractPages(k,((i+1)<k.length)?k[i+1]-1:oDoc.numPages-1,oDoc.documentFileName.replace(/\./,i+"."));})
There's the whole thing in 4 lines of code. Run it from the Console Window
I'll add this as a tool to pdfscripting.com, except with checks for the assumptions
Copy link to clipboard
Copied
Hello Thom!
Thank you for explaining about the assumptions and what to consider.............
In this case the bookmarks are intended only to be used for Identifying the first page in a rang of pages and for the spilt/extracted file naming.
The code you provided is splitting the pages correctly but the naming of the extracted files are not of their respective Bookmark names but of the file name and base numbering.
I've tried a few attempts to modify the code with no good results.
Thanks again for any help!!!!!
oDoc = this;
bkTrgt = []
this.bookmarkRoot.children.forEach(function(a){a.execute();bkTrgt.push(pageNum);})
bkTrgt.forEach(function(a,i,k){oDoc.extractPages(k,((i+1)<k.length)?k[i+1]-1:oDoc.numPages-1,oDoc.documentFileName.replace(/\./,i+"."));})
Copy link to clipboard
Copied
Opps , missed that part, well here is an update,
bkTrgt.forEach(function(a,i,k){oDoc.extractPages(k,((i+1)<k.length)?k[i+1]-1:oDoc.numPages-1,oDoc.bookmarkRoot.children.name + ".pdf"})
The bookmarks children have exactly the same indexes as the page numbers in the array, so I just changed the code the get the save file name from the bookmark name at the index that is being operated on..
Copy link to clipboard
Copied
Thank you very much!!
oDoc = this;
bkTrgt = []
this.bookmarkRoot.children.forEach(function(a){a.execute();bkTrgt.push(pageNum);})
bkTrgt.forEach(function(a,i,k){oDoc.extractPages(k,((i+1)<k.length)?k[i+1]-1:oDoc.numPages-1,oDoc.bookmarkRoot.children.name + ".pdf");});
Copy link to clipboard
Copied
Hi Mike,
Could you post the full code that's working? I'm a code noob, and tried to follow this thread, but it's all gone over my head!
Cheers,
Copy link to clipboard
Copied
Hi Pu_Kah,
sorry for the delayed response.....here's the working code.
oDoc = this;
bkTrgt = []
this.bookmarkRoot.children.forEach(function(a){a.execute();bkTrgt.push(pageNum);})
bkTrgt.forEach(function(a,i,k){oDoc.extractPages(k,((i+1)<k.length)?k[i+1]-1:oDoc.numPages-1,oDoc.bookmarkRoot.children.name + ".pdf");});
Regards,
Mike