Copy link to clipboard
Copied
I have a book that contains over 2,500 phone numbers that I update twice a year in InDesign and then export it into PDF. I just discovered a way for recipients of this PDF to save it to their iBooks app to then have the ability to access it from their mobile devices (iPhones, for the most part), where they can just click on a particular phone number and have their device automatically dial out to that number. Since there are SO many numbers provided in my book, is there an easy way to convert/program all of the numbers to essentially do the same function - call when clicked - all in one fell swoop, instead of converting each individual phone number into a hyperlink? There has to be some code or script to accomplish this - can someone please help? Thanks!
Here is a version of the script that adds a progress bar (which apparently doesn't always show on certain versions of Mac). In a clean new document with just 2,500 phone numbers the script runs almost a minute on my (almost new, well-specced) PC (in CC2015 and 2017). The progress bar shows that the script tears off furiously, then slows down after about 500 links, and crawls to the finish. But do try a test on a document with a few dozen numbers.
Peter
...#targetengine phone_numbers;
(function () {
Copy link to clipboard
Copied
The hard part is probably identifying the phone numbers. What are the criteria? What distinguishes phone numbers from, say, ISBN numbers or any other numbers? Once you can find the numbers you need a script to create hyperlinks, but that's simple.
Peter
Copy link to clipboard
Copied
Right now, all of our phone numbers in this book are based in the U.S., so currently we use the following formatting for the numbers: (###) ###-####; however, we are open to changing the format if it would make it easier to come up with a script for this.
Copy link to clipboard
Copied
Isn't there a built-in GREP search that hunts for all 10-digit phone numbers and sets them to the same typeset condition while you can optionally also applying a character style to it?
Copy link to clipboard
Copied
Here's a script that creates links from phone numbers in the format you gave. The URL destinations have the form 'tel:' followed by the number stripped of anything non-digit (parentheses and spaces in this case). The script uses the character style 'Hyperlink', which, is created if it doesn't exist. The script closes the Hyperlinks panel to gain some speed. If you've many phone numbers, the script will start to slow down after creating about 800 links -- that's an Inesign thing, it just gets slow with many links.
Peter
(function () {
var i;
var cStyle;
var found;
var source;
var destination;
try {
app.panels.item('$ID/Hyperlinks').visible = false;
} catch (_) {
}
if (!app.documents[0].characterStyles.item ('Hyperlink').isValid) {
app.documents[0].characterStyles.add ({name: 'Hyperlink', underline: true});
}
cStyle = app.documents[0].characterStyles.item ('Hyperlink');
app.findGrepPreferences = null;
app.findGrepPreferences.findWhat = /\(\d\d\d\)\s\d\d\d\s\d\d\d\d/.source;
found = app.documents[0].findGrep();
for (var i = 0; i < found.length; i++) {
source = app.documents[0].hyperlinkTextSources.add (found, {appliedCharacterStyle: cStyle});
destination = app.documents[0].hyperlinkURLDestinations.add ({
destinationURL: 'tel:' + found.contents.replace(/\D/g,'')
});
app.documents[0].hyperlinks.add (source, destination);
}
}());
Copy link to clipboard
Copied
Really cool stuff pkharel!!!
There just might be a small mistake in the GREP query \(\d\d\d\)\s\d\d\d\d\d\d\d
Space should be replaced by dash \(\d\d\d\)-\d\d\d\d\d\d\d
Additional question: why do you close the hyperlink panel? Is there a specific reason for that?
Copy link to clipboard
Copied
Thanks for spotting that, Vinny. But you corrected it wrong . It should be
\(\d\d\d\)\s\d\d\d-\d\d\d\d
> Additional question: why do you close the hyperlink panel? Is there a specific reason for that?
It speeds up the script because InDesign doesn't have to update the panel.
P.
Copy link to clipboard
Copied
1/Ooops...
2/Ok I understand the speed issue!
Thanks!
Copy link to clipboard
Copied
Thank you for providing this information, Peter! I've entered the script into InDesign; however, it doesn't seem to be doing anything: I have my document open and when I double-click the script to run it, I can't tell if anything is being done.
Also, it's been over 30 minutes now since I first ran the script - how long should it normally take to create links from phone numbers?
Copy link to clipboard
Copied
One last thing, I took your script and replaced the corrected GREP query, but just wanted to confirm that I had captured it correctly - is this how it should appear:
(function () {
var i;
var cStyle;
var found;
var source;
var destination;
try {
app.panels.item('$ID/Hyperlinks').visible = false;
} catch (_) {
}
if
(!app.documents[0].characterStyles.item ('Hyperlink').isValid) {
app.documents[0].characterStyles.add ({name: 'Hyperlink', underline: true});
}
cStyle =
app.documents[0].characterStyles.item ('Hyperlink');
app.findGrepPreferences = null;
app.findGrepPreferences.findWhat = /
\(\d\d\d\)\s\d\d\d-\d\d\d\d/.source;
found = app.documents[0].findGrep();
for (var i = 0; i < found.length;
i++) {
source =
app.documents[0].hyperlinkTextSources.add (found, {appliedCharacterStyle:
cStyle});
destination =
app.documents[0].hyperlinkURLDestinations.add ({
destinationURL: 'tel:' + found.contents.replace(/\D/g,'')
});
app.documents[0].hyperlinks.add (source, destination);
}
}());
Copy link to clipboard
Copied
Stephanie -- You changed the GREP correctly, no problem there. You'd better try the script on a small sample: copy some text containing, say, five phone numbers, out of your document into a new document and try the script again.
Peter
Copy link to clipboard
Copied
Here is a version of the script that adds a progress bar (which apparently doesn't always show on certain versions of Mac). In a clean new document with just 2,500 phone numbers the script runs almost a minute on my (almost new, well-specced) PC (in CC2015 and 2017). The progress bar shows that the script tears off furiously, then slows down after about 500 links, and crawls to the finish. But do try a test on a document with a few dozen numbers.
Peter
#targetengine phone_numbers;
(function () {
var i;
var w;
var cStyle;
var found;
var source;
var destination;
app.scriptPreferences.enableRedraw = true;
try {
app.panels.item('$ID/Hyperlinks').visible = false;
} catch (_) {
}
if (!app.documents[0].characterStyles.item ('Hyperlink').isValid) {
app.documents[0].characterStyles.add ({name: 'Hyperlink', underline: true});
}
cStyle = app.documents[0].characterStyles.item ('Hyperlink');
app.findGrepPreferences = null;
app.findGrepPreferences.findWhat = /\(\d\d\d\)\s\d\d\d-\d\d\d\d/.source;
found = app.documents[0].findGrep();
w = new Window ('palette {text: "Phone URLs"}');
w.pbar = w.add ('progressbar', undefined, 0, found.length);
w.pbar.preferredSize.width = 300;
w.show();
for (i = 0; i < found.length; i++) {
w.pbar.value = i+1;
source = app.documents[0].hyperlinkTextSources.add (found, {appliedCharacterStyle: cStyle});
destination = app.documents[0].hyperlinkURLDestinations.add ({
destinationURL: 'tel:' + found.contents.replace(/\D/g,'')
});
app.documents[0].hyperlinks.add (source, destination);
}
try {
w.close();
} catch (_) {
}
}());
Copy link to clipboard
Copied
Peter - this script worked! It did what I needed it to do! I am SO ecstatic about this.
I'm hoping that I could bother you again for one more script: I've noticed that the script fails when there are already hyperlinks included in the document. Do you have an easy script that will remove any hyperlinks already contained within the document? Sometimes I don't always notice that there are hyperlinks in place (no underline or character style) so rather than scrolling through the whole document to search for these hyperlinks, I thought it would be easier to just remove them all at once with a new script and then run my happy script above.
Copy link to clipboard
Copied
Between lines 12 and 14, add this single line:
app.documents[0].hyperlinks.everyItem().remove();
P.
Copy link to clipboard
Copied
Peter - I've added the one line above to the script provided six days ago and I keep getting this popup when I attempt to run the revised script. Does it make sense to you?
This is exactly how I have the script with the one line added:
(function () {
var i;
var w;
var cStyle;
var found;
var source;
var destination;
app.scriptPreferences.enableRedraw = true;
try {
app.panels.item('$ID/Hyperlinks').visible = false;
} catch (_) {
}
if (!app.documents[0].characterStyles.item ('Hyperlink').isValid) {
app.documents[0].characterStyles.add ({name: 'Hyperlink', underline: true});
}
cStyle = app.documents[0].characterStyles.item ('Hyperlink');
app.findGrepPreferences = null;
app.findGrepPreferences.findWhat = /\(\d\d\d\)\s\d\d\d-\d\d\d\d/.source;
found = app.documents[0].findGrep();
w = new Window ('palette {text: "Phone URLs"}');
w.pbar = w.add ('progressbar', undefined, 0, found.length);
w.pbar.preferredSize.width = 300;
w.show();
for (i = 0; i < found.length; i++) {
w.pbar.value = i+1;
source = app.documents[0].hyperlinkTextSources.add (found, {appliedCharacterStyle: cStyle});
destination = app.documents[0].hyperlinkURLDestinations.add ({
destinationURL: 'tel:' + found.contents.replace(/\D/g,'')
});
app.documents[0].hyperlinks.add (source, destination);
}
try {
w.close();
} catch (_) {
}
}());
Can this be fixed?
~Stephanie
Copy link to clipboard
Copied
I don't see the added line in the script you posted, Stephanie. And when I copy the text of your script, it works fine over here. What happens if you go back to the first version I posted? Does that still work? Don't forget the first line, #targetengine phone_numbers;
You could in principle run that additional line as a separate script, by the way, it's just more convenient if everything is in one script.
Peter
Copy link to clipboard
Copied
Darn - I forgot to send the script with the added line. OK, so this is the revised script that I actually used that is giving me that JavaScript error popup above:
(function () {
var i;
var w;
var cStyle;
var found;
var source;
var destination;
app.scriptPreferences.enableRedraw = true;
app.documents[0].hyperlinks.everyItem().remove();
try {
app.panels.item('$ID/Hyperlinks').visible = false;
} catch (_) {
}
if (!app.documents[0].characterStyles.item ('Hyperlink').isValid) {
app.documents[0].characterStyles.add ({name: 'Hyperlink', underline: true});
}
cStyle = app.documents[0].characterStyles.item ('Hyperlink');
app.findGrepPreferences = null;
app.findGrepPreferences.findWhat = /\(\d\d\d\)\s\d\d\d-\d\d\d\d/.source;
found = app.documents[0].findGrep();
w = new Window ('palette {text: "Phone URLs"}');
w.pbar = w.add ('progressbar', undefined, 0, found.length);
w.pbar.preferredSize.width = 300;
w.show();
for (i = 0; i < found.length; i++) {
w.pbar.value = i+1;
source = app.documents[0].hyperlinkTextSources.add (found, {appliedCharacterStyle: cStyle});
destination = app.documents[0].hyperlinkURLDestinations.add ({
destinationURL: 'tel:' + found.contents.replace(/\D/g,'')
});
app.documents[0].hyperlinks.add (source, destination);
}
try {
w.close();
} catch (_) {
}
}());
So then I went ahead and added the first line, #targetengine phone_numbers;, and then got this error message:
Does this make any sense to you? Ideally I would LOVE to have everything run in just one script - would definitely be more convenient!
Thanks so much!
~Stephanie
Copy link to clipboard
Copied
Looks like you inserted
first line, #targetengine phone_numbers;
that should be
#targetengine phone_numbers;
P.
Copy link to clipboard
Copied
Hi,
in addition to @pkahrel comment, you could use a GREP query to apply a character style to your tel numbers. (Or paragraph, depending on how your design is set). Then, as suggested by pkahrel, you'll need a script.
I personally don't find that simple, especially to set up the hyperlink as "tel:" instead of "http://" but maybe a specialist can help you on this one.
Here's the beginning of a script allowing you to find your numbers, assuming a character style is applied:
var myDoc =app.activeDocument;
var myLW = 100;
var myStyleNames = myDoc.characterStyles.everyItem().name;
var myDialog = app.dialogs.add({name:"Create tel: hyperlink", canCancel:true});
with(myDialog.dialogColumns.add()){
with(borderPanels.add()){
with(dialogColumns.add()){staticTexts.add({staticLabel:"Choose your tel number Character Style: ", minWidth:myLW});}
with(dialogColumns.add()){var myChooseStyle = dropdowns.add({stringList:myStyleNames, selectedIndex:0});}
}
}
var myResult = myDialog.show();
if(myResult == true){
var mySelStyle = myStyleNames[myChooseStyle.selectedIndex];
myDialog.destroy();
}
else{
myDialog.destroy();
}
app.findTextPreferences = NothingEnum.nothing;
app.changeTextPreferences = NothingEnum.nothing;
app.findTextPreferences.appliedCharacterStyle = mySelStyle.toString();
var mySearch = app.findText(false);
alert ('you have '+mySearch.length + ' tel numbers to convert');
for(i=0 ; i<mySearch.length; i++){
var number = mySearch.contents;
// here's the tricky part for me, specialists please advice
// myDoc.hyperlinkURLDestinations.add(number, {name:number});
}
Copy link to clipboard
Copied
Vinny -- Finding the phone numbers is the challenge. After that it's not such a problem.
Copy link to clipboard
Copied
pkahrel -- I'm sure a GREP query can do it easily. Maybe @stephanieb23791774 can display examples of phone numbers format. (would be little bit more tricky if there are different international formats). Besides, it also depends on the design. They can be in a table column for instance... would be very easy then.
Would you agree on thinking than first step would be applying paragraph or character style? I would be interested to see how you would code what i call "the tricky part". (in javascript, I don't know VBScript)
I think it's an interesting question. I might use the answer for my projects as well. I'll keep an eye on this thread.
regards
Copy link to clipboard
Copied
Hi there! Sorry for the delay, but just so you know, unless you are outside of the U.S., there are no international formatted numbers - the numbers are all based within the U.S. Right now, we format the numbers as such: (###) ###-####; however, we are open to formatting it differently if it will make writing a script for this easier.
I'm familiar with the GREP query, as well as applying a character style - at this point I'd just really like to try to figure out a way to quickly complete this, as well have a process that can be used for going forward: we update this book twice a year.
Copy link to clipboard
Copied
Any follow-up on the "easy" part of this? I have no idea how to make a script in InDesign
Copy link to clipboard
Copied
Hello! I'm getting an error when I try this script. I get a message that says this:
JavaScript Error!
Error Number: 30477
Error String: Invalid value for parameter 'source' of method 'add'.
Expected Text, but received (Paragraph).
Engine: phone_numbers
File: C:\Program Files\Adobe\Adobe InDesign 2020\Scripts Panel\numbers to hyperlink.js
Line: 59
Source: source = app.document[0].hyperlinkTextSources.add (found, {appliedCharacterStyle: cStyle});
If I can get this to work, it would save me so much time! Any help would be greatly appreciated.
Copy link to clipboard
Copied
Hi jims85923660,
what exact version of the code did you run?
Could you post the code in a reply here by using the forum editor's "Insert/Edit code sample" function with Language: JavaScript ? I fear that all the code presented in this thread from 2016 was damaged last year by moving this thread to the new Adobe Forum. This happened to a lot of ExtendScript (JavaScript) code samples all over the place. Not only in the InDesign forum.
Regards,
Uwe Laubender
( ACP )