Copy link to clipboard
Copied
I have a script that goes through an open InDesign document and creates a report with information on the fonts in the document.
Occasionally, I receive an error string: "The requested scripting property is not available for the font." despite all fonts being loaded/installed in the InDesign document.
The missing property is the fontStyleName. Could this be caused by a font conflict? Even if that were the case, wouldn't the script be using the font property of the font that is installed?
Copy link to clipboard
Copied
Which fornt (and font family) is that?
Copy link to clipboard
Copied
The designer used Gill Sans. I try to avoid this font if possible but it's not my Document. I noticed that there is a mixture of ttc and otf in their packaged Document fonts folder.
from the Indesign file:
Copy link to clipboard
Copied
Those TTF/OTF mixes are always a problem.
Forgot to ask earlier: in "The requested scripting property is not available for the font", what is that property?
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Can you show us your script? I'm pretty sure it would be just a case of adding try...catch.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Unfortunately, your code won't work after adding try....catch - it needs to be re-written - but I'm not JS guy.
In your code, author assumed that this part:
familyNames = app.activeDocument.fonts.everyItem().fontFamily;
styleNames = app.activeDocument.fonts.everyItem().fontStyleName;
fontNames = app.activeDocument.fonts.everyItem().name;
fontTypes = app.activeDocument.fonts.everyItem().fontType;
fileNames = app.activeDocument.fonts.everyItem().location;
will always work and each array will have the same number of "records" - but if we start ignoring errors - there will be a different number of "records" and you'll get wrong sets of data.
I'm pretty sure @Peter Kahrel or @rob day or @brian_p_dts can re-write it for you.
Copy link to clipboard
Copied
But this code doesn't make much sense...
this block:
if (( fontStatus.indexOf("NOT_AVAILABLE ") !== -1) || ( fontStatus.indexOf("SUBSTITUTED") !== -1 ))
{
alert ("Document appears to have missing fonts");
exit();
}
should be much earlier - before the loop - why to waste time to get all info from all fonts - xxxNames variables - when after first loop it will break anyway - if there are NOT_AVAILABLE and SUBSTITUTED fonts ?
And when you don't have such fonts - this code will be wasting time and executing:
var fontStatus = app.activeDocument.fonts.everyItem().status.toString();
with every font...
And even if there are NOT_AVAILABLE and SUBSTITUTED fonts - I think it would be good to know?
Then "missingFonts" variable is declared as "false" - but never set in the loop or anywhere else to "true" - so the last "if" is pointless as it will always be "true"...
The whole code is botched...
Copy link to clipboard
Copied
In addition to @Robert at ID-Tasker comments, this is indeed not a good approach:
styleNames = app.activeDocument.fonts.everyItem().fontStyleName;
If there's any missing font, you'll always get the exact error you get: "The requested scripting property is not available for the font." (This also applies to fontType and location).
You can try this line first, if you wish, but if there's an error you'll need to iterate through fonts to find out what font exactly is causing the error.
Also, you may think that there are no missing fonts as they're not reported in the UI, but internally there can be missing fonts that InDesign doesn't report to the user as they don't affect document's output. Such fonts, however, will be reported when you query the document fonts via scripts. (I think this can be caused by missing fonts in unused styles as well as other similar situations).
If you want the same results on font usage you get from InDesign's UI, you'll need to script InDesign's preflight, not query document fonts. Querying fonts can - and will - report missing fonts that you can in fact ignore.
Copy link to clipboard
Copied
This makes sense! Thanks Leo
Copy link to clipboard
Copied
I noticed that "report" in package has all of the font information I need (full name, type, file name). Is this what you were referring to? Is it be possible to create a CSV or tab separated report from InDesign with only this info via scripting? Thanks.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
You could package just the info file text via a script. Something like this creates a new folder in the ID files parent folder with a txt file with only the font info:
var d = app.activeDocument;
var infof = new Folder(d.filePath + "/FontInfo");
var idp = infof + "/" + d.name
infof.create()
d.packageForPrint (infof, false, false, false, false, false, true, true, false, false)
File(idp).remove()
var ip = File(infof + "/Instructions.txt")
var t = readFile(ip)
var ft = t.split("FONTS")[1].split("COLORS AND INKS")[0];
writeText(ip,ft);
function readFile(p) {
var f = new File(p);
f.open("r");
var x = f.read();
f.close();
return x; //returns the text in the file sampletext.txt
}
function writeText(p,s){
var file = new File(p);
file.encoding = 'UTF-8';
file.open('w');
file.write(s);
file.close();
}
Copy link to clipboard
Copied
@rob day, haven't you missed few ";" ?
Copy link to clipboard
Copied
Hi @michaelr26894937 , I’m not sure the code has to be that complicated. Something like this:
var path = Folder.desktop + "/Font Info.csv";
var f = app.activeDocument.fonts;
var fi = "Font Name\tStyle\tLocation\tStatus\r"
for (var i = 0; i < f.length; i++){
fi += f[i].name.split("\t")[0] + "\t" + f[i].fontStyleName + "\t" + f[i].location + "\t" + f[i].status.toString() + "\r"
};
writeCSV(path,fi)
/**
* Write CSV
* @ param the file path
* @ param the text
*
*/
function writeCSV(p,s){
var file = new File(p);
file.encoding = 'UTF-8';
file.open('w');
file.write(s);
file.close();
}
Outputs this CSV:
For this doc:
Copy link to clipboard
Copied
@rob day :
I only think he'll get the very same error for some fonts that was the reason for his post here:
+ f[i].fontStyleName
So he may need to try-catch this property (as well as location) first?
Copy link to clipboard
Copied
So he may need to try-catch this property (as well as location) first?
Yes.
Another option might be with the name property. With my font library and Adobe type fonts, the name string always includes the name and style with a tab in between. So in my code this returns the name without the style :
f[i].name.split("\t")[0]
and this would return just the style
f[i].name.split("\t")[1]
Copy link to clipboard
Copied
Actually, I’m not sure I understand the code @michaelr26894937 posted—maybe the fontStyleName doesn’t exist for all fonts, or the error might be happening in the complicated loop.
If a document font really has no fontStyleName property this simple loop should also throw an error:
var f = app.activeDocument.fonts;
for (var i = 0; i < f.length; i++){
$.writeln(f[i].fontStyleName)
};
Copy link to clipboard
Copied
Something like this should work, without try-catch:
allFonts = document.fonts.everyItem().properties;
s = "Font Name\tStyle\tLocation\tStatus\r"
for (i = 0; i < allFonts.length; i++){
s += allFonts[i].name.split("\t")[0] + "\t" + allFonts[i].fontStyleName + "\t" + allFonts[i].location + "\t" + allFonts[i].status.toString() + "\r"
};
alert(s);... the reason being that you get an array of objects, with each object containing all the properties of each font. If a certain property doesn't exist for the font, accessing it via the object will return undefined, as for any property not contained in an object, as opposed to trying to access it from the font object itself, in which case InDesign scripting will throw an error.
Copy link to clipboard
Copied
Excellent idea @TᴀW!
Find more inspiration, events, and resources on the new Adobe Community
Explore Now