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

fontStyleName property unavailable for font

Explorer ,
Nov 16, 2023 Nov 16, 2023

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?

 

TOPICS
How to , Scripting
1.3K
Translate
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 16, 2023 Nov 16, 2023

Which fornt (and font family) is that?

Translate
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
Explorer ,
Nov 16, 2023 Nov 16, 2023

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.

 

Screenshot 2023-11-16 at 2.18.39 PM.png

from the Indesign file:

Screenshot 2023-11-16 at 2.20.13 PM.png

 

 

 

Translate
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 16, 2023 Nov 16, 2023

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?

Translate
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
Explorer ,
Nov 16, 2023 Nov 16, 2023
fontStyleName
Translate
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
LEGEND ,
Nov 16, 2023 Nov 16, 2023

Can you show us your script? I'm pretty sure it would be just a case of adding try...catch.

 

Translate
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
Explorer ,
Nov 16, 2023 Nov 16, 2023
Here is the part of the script that collects the font information. Thanks.
 
(function () {
var doc = app.activeDocument;
var myBaseName = doc.name;
var familyNames = [];
var i;
var names = [];
var styleNames = [];
var fontTypes = [];
var fileNames = [];
var missingFonts = false;

if (/InDesign/.test(app.name)) {
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;

for (i = 0; i < fontNames.length; i++) {
var file = new File(fileNames[i]);
var fileName = decodeURI(file.name);
names.push([familyNames[i] + " " + styleNames[i], fileName, fontTypes[i]]);

var fontStatus = app.activeDocument.fonts.everyItem().status.toString();

if (( fontStatus.indexOf("NOT_AVAILABLE ") !== -1) || ( fontStatus.indexOf("SUBSTITUTED") !== -1 ))
 
{
 
alert ("Document appears to have missing fonts");
 
exit();
 
}

}

if (!missingFonts) {
writeCsv("InDesign Document", names);
} else {
alert("One or more fonts are missing. Please check and try again.");
}
}
Translate
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
LEGEND ,
Nov 16, 2023 Nov 16, 2023

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.

 

Translate
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
LEGEND ,
Nov 16, 2023 Nov 16, 2023

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...

 

Translate
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 16, 2023 Nov 16, 2023

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.

 

Translate
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
Explorer ,
Nov 17, 2023 Nov 17, 2023

This makes sense! Thanks Leo

Translate
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
Explorer ,
Nov 17, 2023 Nov 17, 2023

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.

Translate
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 17, 2023 Nov 17, 2023

Hi @michaelr26894937 , Does the script I posted above throw the same error on the Gill Sans mix?

 

 

Translate
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 17, 2023 Nov 17, 2023

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();
}

 Screen Shot 11.png

Translate
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
LEGEND ,
Nov 17, 2023 Nov 17, 2023
LATEST

@rob day, haven't you missed few ";" ?

 

Translate
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 16, 2023 Nov 16, 2023

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:

Screen Shot 3.png

For this doc:

 

Screen Shot 1.png

Translate
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 16, 2023 Nov 16, 2023

@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?

Translate
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 16, 2023 Nov 16, 2023

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]

 

 

 

Translate
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 16, 2023 Nov 16, 2023

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)
};

 

 

 

Translate
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
People's Champ ,
Nov 16, 2023 Nov 16, 2023

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.

 

Translate
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 16, 2023 Nov 16, 2023

Excellent idea @TᴀW!

Translate
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