Use Script to Change a Cross-Reference Format
Copy link to clipboard
Copied
Does anybody know if there is a way to use a script to change a cross-reference format?
We have complex technical documents that use quite a number of cross-references and a number of different formats. Sometimes mistakes are made. Rather than manually finding each instance of ProcedureReference and changing it to SectionReference (formatting, style differences), is there any way to do it by VB script?
Thanks.
BTW, the other scripts you folks have helped me work out work flawlessly and save me loads of time when converting a book from interactive PDF to hard copy print format. Much thanks for that, too!
Copy link to clipboard
Copied
It's all there in the object model (I looked in the CC object model), but beware because CrossReference means two different things in the object model. There's the cross references you're talking about and then there's those that appear in an index.
It appears that a Document has a collection of CrossReferenceFormats which have collections of BuildingBlocks, the types of which are determined by the BuildingBlockType enumeration.
Dave
Copy link to clipboard
Copied
I looked at the Adobe InDesign Object Model online and, unless it is out of date, saw absolutely no metion of cross-reference formats.
Is there a way, in code, to specifiy a cross-reference format and change it to a different corss-reference format?
Copy link to clipboard
Copied
CrossReferenceFormats have been part of the object model since CS4.
Dave
Copy link to clipboard
Copied
What I am trying to find out is how to identify a cross-reference format in a vb script and change it to another format.
For example:
try {
app.activeDocument.paragraphStyles.item("Old Style").name = "New Style"}
catch (e) {}
lets me reassign a paragraph style.
Is there a similar way to do this for a cross-reference format?
Copy link to clipboard
Copied
I don't want to appear picky, but scripting is a very picky business. What your script does is rename a paragraph style, not reassign it. The object style suggests that you can do the same with a cross reference format using essentially the same code but with "crossReferenceFormats" instead of paragraphStyles.
Bear in mind, I'm reading the object model (using ESTK's Help menu feature 'Object Model Viewer') and drawing conclusions from what I see -- I'm not writing scripts and trying them out because right now I'm up to my eyes in a script of my own.
Dave
Copy link to clipboard
Copied
You aren't picky. Just before I looked at your response, I realized I was asking the wrong question and using the wrong code as an example.
I wrote a script that changed CrossReference format names but that is not what I was trying to accomplish. DOH!
What I need to figure out is more along the lines of this:
app.findGrepPreferences.appliedCharacterStyle = myFindStyle;
app.changeGrepPreferences.appliedCharacterStyle = myChangeStyle;
app.activeDocument.changeGrep();
But with cross-reference formats rather than paragraph or character styles. Sorry for creating the confusion.
I'm going to try the above trying to subsitute appliedCrossReference and see what happens...which me luck.
Copy link to clipboard
Copied
I'm getting a little desperate. Been pouring through the documentation and cannot seem to find anything that indicates how to identify and change one cross reference to another one.
Apparently, findGrepPreferences and changeGrepPreferences do not support cross reference formats/sources. The documentation seems to indicate that cross reference source is better because it is a part of the hyperlink class, which is really what a cross-reference outside an index is.
However, looking at jongware's wonderfully searchable Adobe InDesign 6.0 Object Model, I cannot seem to find anything which indicates a way to identify a crossreference format/source and change it to a different one.
Here's the code I've been playing with:
var myFindStyle, myChangeStyle,
myFindStyle = app.activeDocument.CrossReferenceFormat.name("CrossReference_Old")
myChangeStyle = app.activeDocument.CrossReferenceFormat.name("CrossReference_New")
app.findGrepPreferences.appliedCrossReferenceFormat = myFindStyle;
app.changeGrepPreferences.appliedCrossReferenceFormat = myChangeStyle;
app.activeDocument.changeGrep();
But it fails whether I use CrossReferenceFormat or CrossReferenceSource.
I know I'm missing something obvious, but, obviously, I can't see it. Help!
Copy link to clipboard
Copied
Where are you pulling this stuff from? You're not missing something, you're indulging in wishful thinking.
Here's how I tackle this kind of thing when I haven't a clue how something works:
1. Make a new document.
2. Make a new object
3. Explore the object in ESTK
I'm not sure that you have anything like ESTK in VB, so you may have to switch to JS to conquer this.
The first clue that there's something odd here is that you have to use the Hyperlinks panel to make a cross-reference. InDesign thinks of these things as hyperlinks.
Having made one, you can do this:
//DESCRIPTION: Exploring our one and only Cross Reference
(function(){
var xRef = app.documents[0].hyperlinks[0];
for (p in xRef) {
$.writeln(p + ": " + xRef
);
}
}()
In my case, this produced:
hidden: false
name: Cross-Reference
source: [object CrossReferenceSource]
visible: false
highlight: 1852796517
width: 1952999790
borderColor: 1765960811
borderStyle: 1936682084
destination: [object ParagraphDestination]
id: 487
label:
isValid: true
parent: [object Document]
index: 0
properties: [object Object]
events: [object Events]
eventListeners: [object EventListeners]
isValid: true
Which means that the next thing to look at is the source object.
I'll come back with more when I get that far.
Dave
Copy link to clipboard
Copied
So now I tried:
//DESCRIPTION: Exploring the source of our one and only Cross Reference
(function(){
var xRef = app.documents[0].hyperlinks[0];
var source = xRef.source;
for (p in source) {
$.writeln(p + ": " + source
);
}
}())
And this returns:
appliedFormat: [object CrossReferenceFormat]
hidden: false
name: Hyperlink 1
sourceText: [object Text]
appliedCharacterStyle: null
id: 484
label:
isValid: true
parent: [object Document]
index: 0
properties: [object Object]
events: [object Events]
eventListeners: [object EventListeners]
isValid: true
And now we find a CrossReferenceFormat.
Dave
Copy link to clipboard
Copied
Before I pursue this path any further, it's worth looking into the issue of how does one find source hyperlinks in text (because that seems to be what's driving you). Obviously, you can start with the hyperlinks and find all the sources, but working that way is a bit like using a reverse telephone directory.
The hyperlink marker does appear in the text, so can we search for it? And if so, is what we find useful?
Dave
Copy link to clipboard
Copied
Hmm: I don't think it can be done that way. You can't search for hypelinks and text doesn't have any collections that help. If you watch what happens in the UI as you move the insertion point cursor through the source text, you'll see that contrary to what I was thinking, there is no marker in the text, so it must be operating in reverse, oberving the text ranges involved and highlighting as you work.
So, that suggests that your script is going to have to work in a similar fashion.
Have I pointed you enough in the right direction or do you need some more help? I think if you do need more help, I need some more specific information -- how do you know which cross reference you want to change? Or are you really looking to change all the cross references that use a particular format to use a different one? Or perhaps you want to redefine an existing format?
Dave
Copy link to clipboard
Copied
Dave,
Not so much wishful thinking, just a little desperation.
I do see what your code is doing and I tried it myself. One problem is that is not coming up with the actual name of the hyperlink. It is just calling it Hyperlink 1 when it's cross reference format name is Paragraph Text (I'm just playing with the native xreferences that come when you create a new ID document).
What I need to do is to tell it to find every instance of a cross reference with a given format name and change to to a cross reference with a different format name. This becomes important because the appearance of the xref will change in the document because the two formats will have different character formats assigned and, in our documents, we need to have cross-references look different depending on what they are referring to and what context they are in. Sometimes they'll be blue bold underline, sometimes blue bolditalic underline, sometimes blue ALL CAPS, etc.
Perhaps because ID does treat crossreferences like hyperlinks, my goal may not be possible.
In looking at jongware's object model, i can see a class of CrossReferenceSource that does have a name property. What I cannot figure out is how to go through the currently open document and identify each crossreference with CrossReferenceSource.Name("Old") and assign it to CrossReferenceSource.Name("New").
I'm not seeking to rename the cross reference. Already know how to do that. What I am seeking to do is to reassign it, like reassigning a paragraph syle the way you can using GREP. Am I making sense?
Copy link to clipboard
Copied
To add a follow up, what I want to do is the equivalent of this:
Double-click on a cross reference to open the Edit Cross-Reference DB.
Then, from the Cross-Reference Format drop down, choose a different format.
Then, click OK.
Copy link to clipboard
Copied
Ah, we cross posted and the conclusion I just drew was wrong.
I'll be back.
Dave
Copy link to clipboard
Copied
So, here we go:
//DESCRIPTION: Exploring the cross reference format of source of our one and only Cross Reference
(function(){
var xRef = app.documents[0].hyperlinks[0];
var source = xRef.source;
var format = xRef.source.appliedFormat;
for (p in format) {
$.writeln(p + ": " + format
);
}
}())
And this produces:
name: Full Paragraph & Page Number
appliedCharacterStyle: null
id: 150
label:
isValid: true
parent: [object Document]
index: 0
properties: [object Object]
events: [object Events]
eventListeners: [object EventListeners]
buildingBlocks: [object BuildingBlocks]
isValid: true
And here, the key thing to notice is that the parent of the format is the document. So:
//DESCRIPTION: Looking at xRef formats
var myFormats = app.documents[0].crossReferenceFormats;
$.writeln(myFormats.everyItem().name.join("\n"));
And this produces:
Full Paragraph & Page Number
Full Paragraph
Paragraph Text & Page Number
Paragraph Text
Paragraph Number & Page Number
Paragraph Number
Text Anchor Name & Page Number
Text Anchor Name
Page Number
So, let's write a script to change our cross reference to use Paragraph Text:
//DESCRIPTION: Change cross ref to use whole paragraph format
var myFormat = app.documents[0].crossReferenceFormats.item("Paragraph Text");
var myXref = app.documents[0].hyperlinks[0];
myXref.source.appliedFormat = myFormat;
Obviously, this is a very simple example, but it does what you want. I took advantage of knowing that the only hyperlink in my document is a cross reference. You'd need to check to see which source is currently applied and change only the ones you want to change.
Dave
Copy link to clipboard
Copied
Dave,
Looks cool...however, will have to look at it in detail later. Just been ordered to help start dinner. Thanks so much for your time and suggestions. Will let you know tomorrow if it works.
Copy link to clipboard
Copied
Dave,
Sorry it took me so long to test this out but a few hot items came up at my client which had to be dealt with first.
Anyway, tried your simple script and it works and I get it. I created a simple document with two cross references and then changed the line to hyperlinks[1] and it changed the second cross reference format but not the first.
Unfortunately, it would be very difficult to impossible for me to know the hyperlink index for each instance I needed to change, plus, it would vary from document to document so a universal script would be impossible.
I need to find a more direct route in which I find all instances of say, "Paragraph Text & Page Number" and change them to "Paragraph Text".
You've been very helpful so far. Any suggestions as to a more direct route?
Copy link to clipboard
Copied
Do what I do: examine the object model viewer to understand the capabilities of the objects that interest you. Pay careful attention to the parent property because that tells you what other objects can have collections of the object of interest.
Also, for things that live in text, check out the find/change possibilites -- you can even do that in the UI: if you can search for it in the UI then chances are you can script the same search.
Dave
Copy link to clipboard
Copied
We're cross-poosting here. What you suggested regarding the UI is exactly what I am trying to do. I know how to do it in the UI, I just can't figure out how to do it in script.
I have been studying the object model but it's a bit terse and, since I lack a depth of knowledge, I'm struggling to understand somethings.
However, when I look at the properties for the class Document, I see crossReferenceFormats and hyperlinks, and, when I look at the methods for each, the index [ ], appears to be identical so I do not understand the difference in behavior.
Copy link to clipboard
Copied
What you're describing now is not a change in cross reference format but a change in formatting of the text of the source of a cross reference.
A cross reference format determines whether it says something like see page 1 or see "My friend george" on page 1.
Can't you just search for the character styles?
Dave
Copy link to clipboard
Copied
I know this post is old but since it was the first post I came across when googling for a solution to this issue, I will add my solution for future readers of the post.
The following script lets me change the cross reference format of the first hyperlink in the selected text frame. It opens a dialog window with a dropdown menu from which you can choose the format you want to apply.
var myDoc = app.activeDocument;
var mySel = app.selection[0];
//list of format styles. These names must correspond existing formats in your document
var formats = ["crossref format 1", "crossref format 2", "crossref format 3"];
//dialog with dropdown menu
var w = new Window('dialog', 'Anchor format');
w.group = w.add('group');
w.group.add('statictext {text: "Välj format:"}');
var formatDD = w.add("dropdownlist", undefined, formats);
formatDD.selection = 0;
w.buttons = w.add('group {alignment: "right"}');
w.ok = w.buttons.add('button {text: "OK", enabled: true}');
w.buttons.add('button {text: "Cancel"}');
w.show();
//find cross ref and apply new format
selectedFormat = formatDD.selection.text;
var hyplink = mySel.paragraphs[0].findHyperlinks()[0];
hyplink.appliedFormat = myDoc.crossReferenceFormats.item(selectedFormat);