-2

I'm attempting to adapt a script (below) for creating a List of Tables in which each entry functions as a hyperlink within the pdf that, when clicked, takes you to the respective table's page. The script below currently works by identifying a character style — "TOC number" — which is applied only to that portion of each entry [=paragraph] which contains the actual number; the script reads the number, based on the character style, and turns the number into a hyperlink which points to that numbered page in the InDesign file.

(Note that the actual page, in InDesign, is a blank placeholder. The tables — of which there are hundreds — are created in Excel and inserted in Acrobat using "Replace pages..." as the last step of our production process. All of which is to say: Please save your suggestions if they involve using InDesign's automatic TOC features; we already use those extensively, but for the step of the process involving pdfs of Excel tables, it's just not an option — we want to adapt the script below, which already works and (almost) suits out needs.)

To illustrate, here's the part (circled in red) of each entry/paragraph in the List of Tables that the script currently makes into a hyperlink:

Here's what we want to do: We want to make the entire entry/paragraph that precedes the page number (circled again in red) into a clickable hyperlink that refers to corresponding page number.

I suppose the easiest way to do this would be by altering the script such that it locates the page number and then GREPs for the preceding paragraph break, and turns everything up to that paragraph break into part of the link? Alternatively, I've designed the paragraph style for List of Table entries such that each part — the table number, the title, the ellipses, and the page numbers — each has a distinct character style, delimited by tabs. So that might be another way of defining, in the script, what text preceding each page number should become part of the link.

Can anyone demonstrate a solution by editing this script? It already (almost) works!

/* Copyright 2016, Kasyan Servetsky
October 3, 2016
Written by Kasyan Servetsky
http://www.kasyan.ho.com.ua
e-mail: askoldich@yahoo.com */
//======================================================================================
var scriptName = "Make hyperlinks",
set, doc, swatchOK,
count = 0;

PreCheck();

//===================================== FUNCTIONS  ======================================
function Main() {
    app.findGrepPreferences = app.changeGrepPreferences = NothingEnum.NOTHING;
    app.findGrepPreferences.findWhat = "\\d+";
    app.findGrepPreferences.appliedCharacterStyle = "TOC number";
    var foundItems = doc.findGrep(true);
    app.findGrepPreferences = app.changeGrepPreferences = NothingEnum.NOTHING;

    if (foundItems.length == 0) ErrorExit("No page numbers were found in the current document.", true);

    for (var f = 0; f < foundItems.length; f++) {
        try {
            var sourceTextRef = foundItems[f].insertionPoints[0].paragraphs[0].texts[0];  

            if (sourceTextRef.fillColor != swatchOK) {
                MakeHyperlink(sourceTextRef);
            }
        }
        catch(err) {
            $.writeln(err.message + ", line: " + err.line);
        }
    }

    var report = count + " hyperlink" + ((count == 1) ? " was" : "s were") + " created.";
    alert("Finished. " + report, scriptName);
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------
function MakeHyperlink(sourceTextRef) {
    var source, destination, hyperlink,
    pageNum = sourceTextRef.contents,
    obj = GetPage(pageNum);

    if (obj != null) {
        source = doc.hyperlinkTextSources.add(sourceTextRef);
        destination = obj.docDest.hyperlinkPageDestinations.add(obj.page);

        var name = "Page_" + pageNum;

        if (!doc.hyperlinks.itemByName(name).isValid) {
            hyperlink = doc.hyperlinks.add(source, destination, {name: name});
        }
        else {
            hyperlink = doc.hyperlinks.add(source, destination, {name: name + "_" + String(Math.random()).replace(/^0\./, "")});
        }

        if (hyperlink.isValid) {
            count++;
            sourceTextRef.fillColor = swatchOK;
        }
    }
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------
function GetPage(pageNum) {
    var obj = null;

    for (var i = 0; i < app.documents.length; i++) {
        if (app.documents[i].pages.itemByName(pageNum).isValid) {
            obj = {page: app.documents[i].pages.itemByName(pageNum), docDest: app.documents[i]};
            break;
        }
    }

    return obj; 
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------
function CheckSwatches() {
    if (doc.swatches.itemByName("===== OK =====") == null) {
        swatchOK = doc.colors.add({name : "===== OK =====", model : ColorModel.PROCESS, space : ColorSpace.RGB, colorValue : [0, 0, 0]});
    }
    else {
        swatchOK = doc.swatches.itemByName("===== OK =====");
    }
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------
function PreCheck() {
    if (app.documents.length == 0) ErrorExit("Please open a document and try again.", true);
    doc = app.activeDocument;
    if (!app.activeDocument.saved) ErrorExit("The current document has not been saved since it was created. Please save the document and try again.", true);
    CheckSwatches();
    Main();
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------
function ErrorExit(error, icon) {
    alert(error, scriptName, icon);
    exit();
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------
LaissezPasser
  • 396
  • 3
  • 18
  • 2
    This is not how SO works. It's not a "Hey fix this for me" site. What have you tried? What, of what you have tried, is not working? Can you show us what you've tried? Can you provide us with a [MCVE](https://stackoverflow.com/help/mcve)? – gforce301 Jul 03 '18 at 19:57
  • The original script used the line `var sourceTextRef = foundItems[f];`, which succeeds in hyperlinking only the page numbers themselves, instead of `var sourceTextRef = foundItems[f].insertionPoints[0].paragraphs[0].texts[0];`, which appears in the revised script that I've posted in the question, and tried, but which results in the message "Finished. 0 hyperlinks were added." – LaissezPasser Jul 03 '18 at 20:06
  • 1
    Can you surround the entire set of content that you "circled in red" in something that you can apply an innocuous character style to that you can name. Name it something like "Link Style". Then just replace "TOC number" with "Link Style" in the original script and see if it works. – gforce301 Jul 03 '18 at 22:56
  • The content in Figure 2 that is circled in red already has the paragraph style "TOC Table/Figure entry" applied to it. When I change the line to `var sourceTextRef = foundItems[f].appliedParagraphStyle = "TOC Table/Figure entry"`, that, too, returns the message: "Finished. 0 hyperlinks were created." – LaissezPasser Jul 04 '18 at 00:16
  • 3
    You're going to need to understand more of javascript than nothing to solve this. Your last comment is not even close to what I suggested but hey I'm helping for free and you're doing this for your work. If you want to discuss this as a paid job, you might contact Kasyan Servetsky since they wrote the original copyrighted script you're trying to hack. – gforce301 Jul 04 '18 at 00:27

1 Answers1

0

Below is the solution, which I worked out myself. My problem was that I was trying to do too much with one variable (sourceTextRef). Once I defined a second variable (tabPnum) that holds only the page number — as distinct from sourceTextRef, which I redefined to hold the entire paragraph in which each page number is found — and I passed that new parameter to the MakeHyperlink function, the script worked:

//======================================================================================
var scriptName = "TOC links",
set, doc, swatchOK,
count = 0;

PreCheck();

//===================================== FUNCTIONS  ======================================
function Main() {
    app.findGrepPreferences = app.changeGrepPreferences = NothingEnum.NOTHING;
    app.findGrepPreferences.findWhat = "\\d+";      
    app.findGrepPreferences.appliedParagraphStyle = app.activeDocument.paragraphStyleGroups.item("publications").paragraphStyleGroups.item("TOC & Acknowledgements").paragraphStyles.item("TOC Table/Figure entry");
    var foundItems = doc.findGrep(true);
    app.findGrepPreferences = app.changeGrepPreferences = NothingEnum.NOTHING;

    if (foundItems.length == 0) ErrorExit("No page numbers were found in the current document.", true);

    for (var f = 0; f < foundItems.length; f++) {
        try {
            var tabPnum = foundItems[f];      // foundItems[f] returns the page number . 

            var sourceTextRef = foundItems[f].words[0].lines[0].paragraphs[0];   // returns the full paragraph.

$.writeln(sourceTextRef.contents);

            if (sourceTextRef.fillColor != swatchOK) {
                MakeHyperlink(sourceTextRef, tabPnum);  // added tabPnum here (necessary for passing parameter to function below).
            }
        }
        catch(err) {
            $.writeln(err.message + ", line: " + err.line);
        }
    }

    var report = count + " hyperlink" + ((count == 1) ? " was" : "s were") + " created.";
    alert("Finished. " + report, scriptName);
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------
function MakeHyperlink(sourceTextRef, tabPnum) { //added parameter tabPnum as argument here)
    var source, destination, hyperlink, 
    pageNum = tabPnum.contents,   //  changed this line so that pageNum is defined by tabPnum. 

    obj = GetPage(pageNum);

    if (obj != null) {
        source = doc.hyperlinkTextSources.add(sourceTextRef);
        destination = obj.docDest.hyperlinkPageDestinations.add(obj.page);

        var name = "Page_" + pageNum;

        if (!doc.hyperlinks.itemByName(name).isValid) {
            hyperlink = doc.hyperlinks.add(source, destination, {name: name});
        }
        else {
            hyperlink = doc.hyperlinks.add(source, destination, {name: name + "_" + String(Math.random()).replace(/^0\./, "")});
        }

        if (hyperlink.isValid) {
            count++;
            sourceTextRef.fillColor = swatchOK;
        }
    }
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------
function GetPage(pageNum) {
    var obj = null;

    for (var i = 0; i < app.documents.length; i++) {
        if (app.documents[i].pages.itemByName(pageNum).isValid) {
            obj = {page: app.documents[i].pages.itemByName(pageNum), docDest: app.documents[i]};
            break;
        }
    }

    return obj; 
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------
function CheckSwatches() {
    if (doc.swatches.itemByName("===== OK =====") == null) {
        swatchOK = doc.colors.add({name : "===== OK =====", model : ColorModel.PROCESS, space : ColorSpace.CMYK, colorValue : [0, 0, 0, 100]});

    }
    else {
        swatchOK = doc.swatches.itemByName("===== OK =====");
    }
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------
function PreCheck() {
    if (app.documents.length == 0) ErrorExit("Please open a document and try again.", true);
    doc = app.activeDocument;
    if (!app.activeDocument.saved) ErrorExit("The current document has not been saved since it was created. Please save the document and try again.", true);
    CheckSwatches();
    Main();
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------
function ErrorExit(error, icon) {
    alert(error, scriptName, icon);
    exit();
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------
LaissezPasser
  • 396
  • 3
  • 18