• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

how to Find/Replace a part of URL in InDesign

Community Beginner ,
Nov 26, 2022 Nov 26, 2022

Copy link to clipboard

Copied

Hi, I have a planner document with hundreds of pages and thousands of links.

For example, text "06" is linked to the URL "https://calendar.google.com/calendar/u/0/r/eventedit?action=TEMPLATE&dates=20230101T060000/20230101T...
I need to replace "20230101" to "20230102"

is there a way to run a script on each separate page to replace a part of URL destination (linked text stays the same)?

TOPICS
Scripting

Views

1.1K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Nov 27, 2022 Nov 27, 2022

Okay, now that I have looked at the OP's demo file I have realised that the problem was that the hyperlinks were all faulty—none had destinations at all, so they couldn't be adjusted. I cleaned up the file and re-wrote the script so that now it generates suitable hyperlinks based on a URL template string, and it grabs details from the page, including day number, month number and hour of day (using find paragraph styles), and creates a hyperlink based on these details. (It gets the month number f

...

Votes

Translate

Translate
Community Expert ,
Nov 26, 2022 Nov 26, 2022

Copy link to clipboard

Copied

Hi @debvlad2, I've written a script that should do what you want, with a caveat: your document should be set up so that any hyperlink with text "06" uses the same hyperlink destination URL. If this is the case, then the script will report 1 change. But keep in mind that the script alters the hyperlinkURLDestination, which may be shared with other hyperlinks, even ones that don't have the text "06". So please test in your case. Also note that in your example, it changes two parts of the URL because "20230101" appears twice in the URL. Let me know how you go.

- Mark

/**
 * Find/change in the destination URL of any hyperlink
 * text source matching 'settings.findWhat'.
 * IMPORTANT: this will alter the actual hyperlinkURLDestination,
 * regardless of how many hyperlinks share it.
 * @author m1b
 * @version 2022-11-27
 * @discussion https://community.adobe.com/t5/indesign-discussions/how-to-find-replace-a-part-of-url-in-indesign/m-p/13374674
 */
var settings = {

    // the document text to find
    findWhat: '06',

    // the destination url text to find
    findDestinationWhat: '20230101',

    // the destination url text to change to
    changeDestinationTo: '20230102'

}

function main() {

    var doc = app.activeDocument,
        hyperlinks = doc.hyperlinks,
        findDestinationRegex = new RegExp(settings.findDestinationWhat, 'g'),
        counter = 0;

    for (var i = 0; i < hyperlinks.length; i++) {

        var dest = hyperlinks[i].destination,
            text = hyperlinks[i].source.sourceText.contents;

        if (
            hyperlinks[i].destination.constructor.name !== 'HyperlinkURLDestination'
            || text != settings.findWhat
            || dest.destinationURL.search(findDestinationRegex) == -1
        )
            continue;

        // make the change
        dest.destinationURL = dest.destinationURL.replace(findDestinationRegex, settings.changeDestinationTo);
        counter++;

    }

    alert('Changed ' + counter + ' hyperlink URL destinations.');

}; // end main

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Find/change Hyperlink URLs');

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Nov 26, 2022 Nov 26, 2022

Copy link to clipboard

Copied

m1b, thank you for responding and being so helpful. I am attaching a screenshot to illustrate my situation:

hourly.png

so every page (365 of them) has "06", 07",08", ... and they all have different URLs -- correlating to date and time of the Google calendar

What I'm trying to do is "reuse" a group of properly linked texboxes from January 1 page by copying it to January 2 page, etc and running a script on each consecutive page to re-link URLs with a proper date.

  • can your script be limited to 1 page only or at least a selection of textboxes?
  • can your script omit searching for "06" and simply search and replace all occurences of "20230101" with "20230102" in the URL (on that page only)?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 26, 2022 Nov 26, 2022

Copy link to clipboard

Copied

Hi @debvlad2, sure, try this version, which has two major differences from the first version:

1. limits search to the active page.

2. creates new hyperlink destination URLs.

See how that works for you.

- Mark

 

 

 

/**
 * Find/change in the destination URL of
 * any hyperlink on the current page.
 * Will create a new hyperlinkURLDestinations
 * where necessary.
 * @author m1b
 * @version 2022-11-27
 * @discussion https://community.adobe.com/t5/indesign-discussions/how-to-find-replace-a-part-of-url-in-indesign/m-p/13374674
 */
var settings = {

    // the destination url text to find
    findDestinationWhat: '20230101',

    // the destination url text to change to
    changeDestinationTo: '20230102'

}

function main() {

    var doc = app.activeDocument,
        targetPage = doc.layoutWindows[0].activePage,
        hyperlinks = doc.hyperlinks,
        findDestinationRegex = new RegExp(settings.findDestinationWhat, 'g'),
        previousDest,
        counter = 0;

    for (var i = 0; i < hyperlinks.length; i++) {

        try {

            var hyperlink = hyperlinks[i],
                dest = hyperlink.destination,
                page = hyperlink.source.sourceText.parentTextFrames[0].parentPage;

            if (
                hyperlink.destination.constructor.name !== 'HyperlinkURLDestination'
                || targetPage.documentOffset != page.documentOffset
                || dest.destinationURL.search(findDestinationRegex) == -1
            )
                continue;

            // make the change
            var newURL = dest.destinationURL.replace(findDestinationRegex, settings.changeDestinationTo);

            // but use the same destination as the
            // last if they have the same URL
            if (
                previousDest != undefined
                && newURL == previousDest.destinationURL
            ) {
                newDest = previousDest;
            }

            else {
                newDest = doc.hyperlinkURLDestinations.add(newURL, { hidden: false });
                previousDest = newDest;
            }

            hyperlink.destination = newDest;
            counter++;

        } catch (error) {

        }

    }

    alert('Changed ' + counter + ' hyperlink URL destinations on page ' + targetPage.name + '.');

}; // end main

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Fix Hyperlink URLs on Page');

 

 

Edit: added some error checking. Edit2: to save time on troubleshooting I put everything in the loop in a try/catch block. This will probably be fine, because we only want the hyperlinks that match our expectations, but please check that the script has changed all that it needs to.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Nov 26, 2022 Nov 26, 2022

Copy link to clipboard

Copied

Thank you! I get the following error:
Screen Shot 2022-11-26 at 7.43.10 PM.png
but I'm able to get it done with a workaround -- I paste the group with links to a blank page, run the script, then copy the corrected group to the original document. Not sure why the error happens in the original doc.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 26, 2022 Nov 26, 2022

Copy link to clipboard

Copied

Hi @debvlad2, well done on finding a workaround. I have updated the script above with some checks to avoid that error. Can you give it a go?

- Mark

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Nov 26, 2022 Nov 26, 2022

Copy link to clipboard

Copied

Thank you again! I still get an error, but a different one this time:
Screen Shot 2022-11-26 at 10.36.36 PM.png

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 26, 2022 Nov 26, 2022

Copy link to clipboard

Copied

Okay, yes it's hard to know what's going on without testing with your document. Instead, I've just put he whole loop in a try/catch block, which means if it gets an error, it'll just ignore that hyperlink and move on to the next. The only downside to this, is the possibility that the error is being generated on a desired hyperlink and therefore it isn't changing the destination of that hyperlink. So please check after using. One way to check is to look at the hyperlinks panel, and just hover your mouse cursor over the hyperlinks in the panel and it will show the URL as a tooltip.

- Mark

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Nov 26, 2022 Nov 26, 2022

Copy link to clipboard

Copied

Mark, thank you for helping me. I checked and unfortunately the links are not being updated by the script in the main document.

Screen Shot 2022-11-26 at 11.49.03 PM.png

it probably has to do with the way my page laid out. If you want, I can send you my file. for the time being the workaround is ok.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 26, 2022 Nov 26, 2022

Copy link to clipboard

Copied

Yes please, send me a demo file... maybe just a couple of pages? I'm interested to know what's causing the error.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 27, 2022 Nov 27, 2022

Copy link to clipboard

Copied

LATEST

Okay, now that I have looked at the OP's demo file I have realised that the problem was that the hyperlinks were all faulty—none had destinations at all, so they couldn't be adjusted. I cleaned up the file and re-wrote the script so that now it generates suitable hyperlinks based on a URL template string, and it grabs details from the page, including day number, month number and hour of day (using find paragraph styles), and creates a hyperlink based on these details. (It gets the month number from the applied master page name.)

 

Well, for the sake of people learning scripting, here is the final script below. - Mark

 

/**
 * Create hyperlinks for calendar elements.
 * Will remove existing hyperlinks previously
 * created by this script.
 * Expects the document to have paragraph styles
 * for daily time and daily day number, as well
 * as master spreads named after the months.
 * @author m1b
 * @version 2022-11-28
 * @discussion https://community.adobe.com/t5/indesign-discussions/how-to-find-replace-a-part-of-url-in-indesign/m-p/13374674
 */
var settings = {

    // year
    year: 2023,

    // the URL string
    urlTemplate: 'https://calendar.google.com/calendar/u/0/r/eventedit?action=TEMPLATE&dates=#yyyy#mm#ddT#hh0000/#yyyy#mm#ddT#ii0000',

    // paragraph style names
    dailyTimeStyleName: 'Daily time',
    dailyDayNumberStyleName: 'Daily day number',

};


function main() {

    var doc = app.activeDocument,
        hyperlinks = doc.hyperlinks,
        matchOldHyperlinks = /T\d\d$/;

    // first remove any hyperlinks
    // create previous by this script
    for (var i = hyperlinks.length - 1; i >= 0; i--)
        if (matchOldHyperlinks.test(hyperlinks[i].name))
            hyperlinks[i].remove();

    // reset grep prefs
    app.findGrepPreferences = NothingEnum.NOTHING;
    app.changeGrepPreferences = NothingEnum.NOTHING;

    // find criterion
    app.findGrepPreferences.findWhat = '^\\d{2}$';
    app.findGrepPreferences.appliedParagraphStyle = settings.dailyDayNumberStyleName;

    // find the dayNumbers
    var dayNumbers = doc.findGrep();

    if (dayNumbers.length == 0) {
        alert('Could not find any day numbers in ' + doc.name + '.');
        return;
    }

    // store all the day numbers in array indexed by page's documentOffset
    var days = [],
        masterNames = ['B-JANUARY', 'C-FEBRUARY', 'D-MARCH', 'E-APRIL', 'F-MAY', 'G-JUNE', 'H-JULY', 'I-AUGUST', 'J-SEPTEMBER', 'K-OCTOBER', 'L-NOVEMBER', 'M-DECEMBER'];

    for (var i = 0; i < dayNumbers.length; i++) {

        var page = textPage(dayNumbers[i]);

        days[page.documentOffset] = {
            dayNumber: dayNumbers[i].contents,
            monthNumber: indexOf(page.appliedMaster.name, masterNames) + 1
        }

    }

    // find the daily times
    app.findGrepPreferences.appliedParagraphStyle = settings.dailyTimeStyleName;

    var dailyTimes = doc.findGrep(),
        counter = 0;

    if (dailyTimes.length == 0) {
        alert('Could not any daily times in ' + doc.name + '.');
        return;
    }

    // find placeholders in the url template
    var findYear = /#yyyy/g,
        findMonth = /#mm/g,
        findDay = /#dd/g,
        findHourStart = /#hh/g,
        findHourEnd = /#ii/g;

    for (var i = 0; i < dailyTimes.length; i++) {

        var documentOffset = textPage(dailyTimes[i]).documentOffset,

            // get the url elements
            monthNumber = ('0' + days[documentOffset].monthNumber).slice(-2),
            dayNumber = days[documentOffset].dayNumber,
            hourStart = dailyTimes[i].contents,
            hourEnd = ('0' + (Number(hourStart) + 1)).slice(-2),

            // make the url based on the template
            url = settings.urlTemplate
                .replace(findYear, String(settings.year))
                .replace(findMonth, monthNumber)
                .replace(findDay, dayNumber)
                .replace(findHourStart, hourStart)
                .replace(findHourEnd, hourEnd),

            name = [settings.year, monthNumber, dayNumber].join('-') + 'T' + hourStart;

        // remove hyperlink if already exists
        if (doc.hyperlinks.itemByName(name).isValid)
            doc.hyperlinks.itemByName(name).remove();

        var existingHyperlinkSources = dailyTimes[i].findHyperlinks();
        for (var j = existingHyperlinkSources.length - 1; j >= 0; j--)
            existingHyperlinkSources[j].remove();

        // set up hyperlink
        var hyperlinkSource = doc.hyperlinkTextSources.add(dailyTimes[i]),
            hyperlinkDestination = doc.hyperlinkURLDestinations.add(url, { hidden: false }),
            hyperlink = doc.hyperlinks.add(hyperlinkSource, hyperlinkDestination);

        hyperlink.name = name;
        counter++;

    }

    alert('Added ' + counter + ' hyperlinks.');
    return;


    /**
     * Returns the document offset
     * of the text's page.
     * @Param {text} text - an Indesign text object.
     * @Returns {Number}
     */
    function textPage(text) {

        if (text.parentTextFrames[0].parentPage)
            return text.parentTextFrames[0].parentPage;

    };


    /**
     * Returns index of obj in arr.
     * Returns -1 if not found.
     * @Param {any} obj
     * @Param {Array} arr
     * @Returns {Number}
     */
    function indexOf(obj, arr) {
        for (var i = 0; i < arr.length; i++)
            if (arr[i] == obj)
                return i;
        return -1;
    };

}; // end main

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Add Calendar Hyperlinks');

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines