Skip to main content
aniri5j9ox8tw2ln
Brainiac
March 31, 2025
Answered

Split ID document. Can anybody change this script?

  • March 31, 2025
  • 3 replies
  • 2587 views

Hello!

Can someone please modify this script for me, because my document have to be split with double pages, but with this script they are separated into individual pages... Thank you very much!

 

/*
    CreateIndividualPages.jsx
    Makes new INDD files of each page of a document, named as the page number
    */

var doc = app.activeDocument;
var pages = doc.pages.everyItem().getElements();
var docName = doc.name.replace(".indd", "");
var filePath = doc.filePath;

// set this value to the number of pages each document should have.
var delta = 3;

for (var p = 0; p < pages.length; p = p + 50) {
  var keyPage = pages[p];
  var nextKeyPage = p + 50;

  var newDoc = app.documents.add();
  newDoc.name = docName + "_" + (p + 1) + ".indd";

  // copy key page to new document
  keyPage.duplicate(LocationOptions.BEFORE, newDoc.pages[0]);

  // remove staring page of new document
  newDoc.pages[1].remove();

  // for each page after the keyPage and up to the nextKeyPage, (skip first page)
  for (var k = p + 1; k < nextKeyPage; k++) {
    // if page exists, append to newDoc
    if (pages[k] !== undefined) {
      pages[k].duplicate(
        LocationOptions.AFTER,
        newDoc.pages[newDoc.pages.length - 1]
      );
    }
  }

  newDoc.save(File(filePath + "/" + newDoc.name));
  newDoc.close(SaveOptions.NO);
}
alert("Done!");
Correct answer m1b

@aniri5j9ox8tw2ln I mean my script does that exactly, so feel free to try it.

 

You just need to set pageCount to

pageCount: 50,

 and you can also adjust this line:

fileNameTemplate: "Output/{docName}_pages {pageStart}-{pageEnd}.indd",

This is how the output folder and file name is derived.

- Mark

3 replies

m1b
Community Expert
March 31, 2025

Hi @aniri5j9ox8tw2ln and others, I'm not sure if the script Peter posted might do the trick, but I've written my own version for fun. Maybe it will be useful, too. I don't duplicate to new documents, because then you lose lots of document settings. It's a quick script so will definitely have bugs in some cases. I'm tempted to add I added a UI.

- Mark

/**
 * @file Divide Document.js
 *
 * Outputs new Indesign documents comprising
 * sequences of pages of the active document.
 *
 * Makes attempt to cleanly cut text threads but
 * some complex cases may not work properly.
 *
 * @author m1b
 * @version 2025-04-02
 * @discussion https://community.adobe.com/t5/indesign-discussions/split-id-document-can-anybody-change-this-script/m-p/15241392#M618671
 */
function main() {

    var settings = {

        /** number of pages in each created document */
        pageCount: 50,

        /** path inside the parent folder and file name with template tokens */
        fileNameTemplate: "Output/{docName}_pages {pageStart}-{pageEnd}.indd",

        /** whether to keep the divided documents section numbering start */
        keepPageNumbering: true,

        /** whether to reveal the folder in the OS afterwards */
        revealFolder: true,

        /** whether to show the UI */
        showUI: true,

    };

    if (0 === app.documents.length)
        return alert("Please open a document and try again.");

    var doc = settings.doc = app.activeDocument;

    if (!doc.saved)
        return alert("Please save the document first.");

    if (settings.showUI) {

        var result = ui(settings);

        if (2 === result)
            // user cancelled
            return;

    }

    doc.documentPreferences.properties = {
        allowPageShuffle: false,
        preserveLayoutWhenShuffling: true,
    };

    var docName = doc.name.replace(/\.[^\.]+$/, '');
    var filePath = doc.filePath,
        f;

    var totalPages = doc.pages.length;
    var len = Math.ceil(totalPages / settings.pageCount);

    for (var i = 0; i < len; i++) {

        var start = i * settings.pageCount,
            end = Math.min(start + settings.pageCount - 1, totalPages - 1);

        // open a copy of the document
        var newDoc = app.open(doc.fullName, true, OpenOptions.OPEN_COPY);

        // the pages we want
        var targetPages = newDoc.pages.itemByRange(end, start).getElements();

        var firstPage = targetPages[0],
            lastPage = targetPages[targetPages.length - 1];

        var firstPageOffset = firstPage.documentOffset;

        // cut threads to these pages
        cutTextThreads(firstPage, lastPage);

        // remove the unwanted pages
        deleteAllPagesExceptRange(newDoc, firstPage, lastPage);

        if (settings.keepPageNumbering)
            newDoc.pages[0].appliedSection.properties = {
                continueNumbering: false,
                pageNumberStart: firstPageOffset + 1,
            };

        // populate the file name using the template
        var fileName = settings.fileNameTemplate
            .replace(/^\/?/, "/") // add leading slash
            .replace(/\{docName\}/g, docName)
            .replace(/\{pageStart\}/g, doc.pages[start].name) /* || newDoc.pages[start].pages[0].name)*/
            .replace(/\{pageEnd\}/g, doc.pages[end].name); /* || newDoc.pages[end].pages[-1].name);*/

        // the file to save
        f = new File(filePath + fileName);

        if (!f.parent.exists)
            f.parent.create();

        newDoc.save(f);
        newDoc.close(SaveOptions.NO);

    }

    if (settings.revealFolder)
        // reveal output folder
        f.parent.execute();

};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Divide Document');

/**
 * Cuts text frame threading.
 *   - provide `startPage` to cut text threads before.
 *   - provide `endPage` to cut text threads after.
 * @author m1b
 * @version 2025-04-01
 * @param {Page} [startPage] - the start page where the threads should be cut.
 * @param {Page} [endPage] - the end page where the threads should be cut.
 */
function cutTextThreads(startPage, endPage) {

    if (startPage) {

        // cut text before this page
        for (var i = 0; i < startPage.textFrames.length; i++)
            cutTextFrame(startPage.textFrames[i], false);

    }

    if (endPage) {

        // cut text after this page
        for (var i = 0; i < endPage.textFrames.length; i++)
            if (endPage.textFrames[i].nextTextFrame)
                cutTextFrame(endPage.textFrames[i].nextTextFrame, false);

    }

};

/**
  * Cuts the text frame's story thread, so that
  * the story starts in this text frame.
  * @author m1b
  * @version 2025-04-01
  * @param {TextFrame} tf - the textframe to cut.
  * @param {Boolean} [cutThreadOnSamePage] - whether to cut the thread even if the previous text frame is on the same page (default: false).
  */
function cutTextFrame(tf, cutThreadOnSamePage) {

    var previous = tf.previousTextFrame;

    if (!previous)
        return;

    if (
        !cutThreadOnSamePage
        && previous.parentPage === tf.parentPage
    )
        return;

    var story = tf.parentStory,
        index = tf.characters[0].index;

    tf.previousTextFrame = null;
    story.characters.itemByRange(index, story.length - 1).move(LocationOptions.AT_BEGINNING, tf);

};

/**
 * Deletes all pages of `doc` before `firstPage` and after `lastPage`.
 * @author m1b
 * @version 2025-04-01
 * @param {Document} doc - an Indesign document.
 * @param {Page} firstPage - the first page to keep.
 * @param {Page} lastPage - the last page to keep.
 */
function deleteAllPagesExceptRange(doc, firstPage, lastPage) {

    var minPageOffset = doc.pages.firstItem().documentOffset,
        maxPageOffset = doc.pages.lastItem().documentOffset;

    // the pages we don't want
    var deleteBeforeA = minPageOffset,
        deleteBeforeB = Math.max(minPageOffset, firstPage.documentOffset - 1),
        deleteAfterA = Math.min(maxPageOffset, lastPage.documentOffset + 1),
        deleteAfterB = maxPageOffset;

    if (deleteAfterB - deleteAfterA > 0)
        // remove pages after
        doc.pages.itemByRange(deleteAfterA, deleteAfterB).remove();

    if (deleteBeforeB - deleteBeforeA > 0)
        // remove pages before
        doc.pages.itemByRange(deleteBeforeA, deleteBeforeB).remove();

};

/**
 * Shows UI for Divide Document Script
 * @param {Object} settings - the settings to adjust via UI.
 * @returns {1|2} - result code
 */
function ui(settings) {

    loadSettings();

    // make the dialog
    var w = new Window("dialog", 'Divide Document', undefined),

        group0 = w.add("group {orientation:'row', alignment:['fill','top'], alignChildren:['left','top'], margins:[10,10,10,10] }"),
        group1 = group0.add("group {orientation:'column', alignment:['fill','top'], alignChildren:['left','top'], margins:[10,10,10,10] }"),
        group2 = group0.add("group {orientation:'column', alignment:['fill','top'], alignChildren:['left','top'], margins:[10,10,10,10] }"),

        label1 = group1.add('statictext {preferredSize: [160,-1], text:"Pages Per Division:", justify: "left"}'),
        group2a = group1.add("group {orientation:'row' }"),
        pageCountField = group2a.add('edittext {preferredSize: [60,-1], text:""}'),
        multiplierLabel = group2a.add('statictext {preferredSize: [100,20], text:"", justify: "left"}'),
        keepPageNumberingCheckBox = group1.add("CheckBox { text: 'Keep Numbering', alignment:['left','top'] }"),

        label2 = group2.add('statictext {text:"Filename Template:", justify: "left"}'),
        fileNameTemplateField = group2.add('edittext {preferredSize: [450,-1], text:""}'),
        infoText = group2.add('statictext {text:"", preferredSize:[350,-1], alignment:["fill","bottom"], justify: "left"}'),

        bottom = w.add("group {orientation:'row', alignment:['fill','bottom'], alignChildren:['fill','bottom'] }"),
        infoGroup = bottom.add("group {orientation:'row', alignment:['fill','bottom'], margins:[0,0,0,6] }"),
        buttons = bottom.add("Group { orientation: 'row', alignment: ['right','bottom'], margins:[0,0,0,6] }"),
        hints = infoGroup.add('statictext {text:"", justify: "left"}'),
        cancelButton = buttons.add("Button { text:'Cancel', properties:{name:'cancel'} }"),
        divideButton = buttons.add("Button { text:'Divide', enabled: true, name: 'ok' }");

    // populate UI
    keepPageNumberingCheckBox.value = (true === settings.keepPageNumbering);
    pageCountField.text = settings.pageCount;
    fileNameTemplateField.text = settings.fileNameTemplate;
    hints.text = 'Placeholders: {docName} {pageStart} {pageEnd} {part}';
    updateUI();

    // event handlers
    pageCountField.onChanging = updateUI;
    fileNameTemplateField.onChanging = updateUI;
    divideButton.onClick = done;

    w.center();
    return w.show();

    function getPartCount() {

        var partCount = Math.ceil(settings.doc.pages.length / Number(pageCountField.text));

        if (
            !pageCountField.text
            || isNaN(partCount)
        )
            return;

        return partCount;

    };

    function updateUI() {

        var partCount = getPartCount();

        divideButton.enabled = undefined != partCount;

        if (!partCount)
            return;

        multiplierLabel.text = '\u00D7 ' + partCount + ' documents';

        // show mock filename
        infoText.text = 'Example: ' + fileNameTemplateField.text
            .replace(/^\/?/, "/") // add leading slash
            .replace(/\{docName\}/g, settings.doc.name.replace(/\.[^\.]+$/, ''))
            .replace(/\{pageStart\}/g, 1)
            .replace(/\{pageEnd\}/g, pageCountField.text)
            .replace(/\{part\}/g, partCount);

    };

    function done() {

        // update settings
        settings.fileNameTemplate = fileNameTemplateField.text;
        settings.keepPageNumbering = keepPageNumberingCheckBox.value;
        settings.pageCount = Number(pageCountField.text);

        saveSettings();

        // close window with success code
        w.close(1);
    };

    function loadSettings() {

        // load last-used settings from document
        settings.pageCount = Number(settings.doc.extractLabel('pageCount') || settings.pageCount);
        settings.fileNameTemplate = settings.doc.extractLabel('fileNameTemplate') || settings.fileNameTemplate;

        var keepPageNumbering = settings.doc.extractLabel('keepPageNumbering');
        settings.keepPageNumbering = '' == keepPageNumbering
            ? settings.keepPageNumbering
            : 'FALSE' === keepPageNumbering;

    };

    function saveSettings() {

        // store last-used languages in document
        settings.doc.insertLabel('fileNameTemplate', settings.fileNameTemplate);
        settings.doc.insertLabel('keepPageNumbering', (settings.keepPageNumbering ? "TRUE" : "FALSE"));
        settings.doc.insertLabel('pageCount', String(settings.pageCount));

    };

};

Edit 2025-04-01: improved script—now will keep text threads intact in most cases, and handle arbitrary spread sizes.

Edit 2025-04-02: added a UI.

Robert at ID-Tasker
Brainiac
March 31, 2025

This will split all threaded Stories.

 

Robert at ID-Tasker
Brainiac
March 31, 2025

This almost works - moves whole range together, in one step:

 

var mySpreads = app.activeDocument.spreads.itemByRange(1, 2); 
mySpreads.duplicate(LocationOptions.AFTER, app.documents[1]);

 

 

and keeps TextFrames linked together - but ONLY within the same Spreads??

 

 

 

BUT - when done manually:

 

 

It works...

 

 

Peter Spier
Community Expert
March 31, 2025

I posted this script yesterday for someone else:

*****************************************************

SeparatePages.jsx
An InDesign CS2 javascript by Harbs.
For more scripts and automation tools visit www.in-tools.com.

Will separate all pages to allow for inner bleeds
while preserving the original orientation of the page.
Basic testing done on CS2 ME. (Should work with CS and CS3 also, but untested.)
Use at your own risk!!!

*******************************************************/
aDoc = app.activeDocument;
for (i=0;i<aDoc.pages.length;i++){
	aSide = aDoc.pages[i].side;
	aSide = aSide + "";
	aDoc.pages[i].insertLabel("direction",aSide);
	}
aDoc.documentPreferences.allowPageShuffle = true;
aDoc.documentPreferences.facingPages = false;
aDoc.documentPreferences.allowPageShuffle = false;
aDoc.documentPreferences.facingPages = true;
for (i=0;i<aDoc.pages.length;i++){
	myPage = aDoc.pages[i];
	mySide = myPage.extractLabel("direction");
	if (mySide == "1818653800"){
		myPage.move(LocationOptions.atEnd,myPage,BindingOptions.leftAlign);
		}else{
		myPage.move(LocationOptions.atEnd,myPage,BindingOptions.rightAlign);
		}
	}
Robert at ID-Tasker
Brainiac
March 31, 2025

@Peter Spier

 

But OP wants to "export" as spreads - or two pages per document - as individual INDD documents. 

 

Peter Spier
Community Expert
March 31, 2025

I think you misread the intent here. As I read it, the doc is set up as facing pages, and needs to remain as facing pages, but the spreads need to be split to allow for inside bleed, which is what that script does.

My javascripting is a bit rusty, so I'm not sure if the OP's script makes a new doc with all the page from the old one, or multiple new docs, and I don't see anywhere that it specifies single or facing pages.

Some clarification of the intent from @aniri5j9ox8tw2ln would be helpful here.

Robert at ID-Tasker
Brainiac
March 31, 2025

Do you need to preserve spreads layout - or just 2x pages per document? 

 

aniri5j9ox8tw2ln
Brainiac
April 1, 2025

Hello everyone! I would like to split a 200-page document into several parts and have therefore set the division to 50 pages each. But the pages should remain double-sided as my original layout. In the end, I would like to have my document in several ID files in the Finder, which then have in addition to the file name 1, 2, 3, 4 etc. in it... Thank you very much for your effort and the tests so far. Which script is the right one for me?

Dave Creamer of IDEAS
Community Expert
April 1, 2025

Assuming you are printing this document, why not do this in Acrobat with the Split feature? That way, your original InDesign document intact for future editing.

 

David Creamer: Community Expert (ACI and ACE 1995-2023)