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

String Formatting in Extendscript

Enthusiast ,
Jun 30, 2024 Jun 30, 2024

I found this great script by @rob day  in this group which returns font metrics data.

I wish this could be included in InDesign's info panel by Adobe. 

 

Currently the script gives output in points. I have modified it to give data in MM also.

Issue is that the output is not properly formatted. I have attached a screenshot.

 

Is there a way to give proper formatting. I tried printf, sprintf, console.log but all these do not work in extendscript.

 

I want the top headers to be in bold, left headers to be in bold. ":" should be aligned. The values of Points to be aligned so that it becomes easier to read.

 

I have attached @rob day script here with modification.

// the selected character
var s = app.activeDocument.selection[0]; 
// the fixed decimal place
var dn = 3;

if (s.constructor.name == "Character") {
    var p = getFontMetric(s).pointSize;
    var bl = getFontMetric(s).baseline;
    var a = getFontMetric(s).ascent;
    var d = getFontMetric(s).descent;
    var ch = getFontMetric(s).capHeight;
    var xh = getFontMetric(s).xHeight;
    

alert("\u0009Points:" + "\u0009" + " MM:\r" + "Point Size:" + p + "\u0009" + p*.3572 + "\r" + "Baseline: " + bl + "\u0009" + bl*.3572 + "\r" + "Ascender: " + a + "\u0009" + a*.3572 +  "\r" + "Descender: " + d + "\u0009" + d*.3572 + "\r" +  "Cap Height: " + ch + "\u0009" + ch*.3572 + "\r" + "x-Height: " + xh + "\u0009" + xh*.3572);

} else {
    alert("Please Select a Single Character");
}


/**
* Gets the selected character’s font metrics 
* @ param the character selection  
* @ return an object with pointSize, baseline, ascent,descent, xHeight, and capHeight 
*/
function getFontMetric(s){
    app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;
    var o = new Object;
    o.pointSize = s.pointSize.toFixed(dn);
    o.baseline = s.baseline.toFixed(dn);
    o.ascent = s.ascent.toFixed(dn);
    o.descent = s.descent.toFixed(dn);
    app.copy();
    var tf = app.activeDocument.textFrames.add({geometricBounds: [0,0,500,500], textFramePreferences: {firstBaselineOffset: FirstBaseline.CAP_HEIGHT, insetSpacing: 0, minimumFirstBaselineOffset: 0, verticalJustification: VerticalJustification.TOP_ALIGN}});  
    app.select([tf.parentStory.insertionPoints[0]]);    
    app.paste();
    tf.texts[0].alignToBaseline = false;
    o.capHeight = tf.texts[0].insertionPoints[0].baseline.toFixed(dn);
    tf.textFramePreferences.firstBaselineOffset = FirstBaseline.X_HEIGHT;
    o.xHeight = tf.texts[0].insertionPoints[0].baseline.toFixed(dn);
    tf.remove();
    app.select(s)
    app.scriptPreferences.userInteractionLevel = UserInteractionLevels.INTERACT_WITH_ALL;
    return o
}
TOPICS
How to , Scripting
749
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

correct answers 1 Correct answer

Community Expert , Jun 30, 2024 Jun 30, 2024

Also, you might look at the unitValue object which lets you convert units—it’s returning a different value than your .3572 multiplier:

 

// the selected character
var s = app.activeDocument.selection[0]; 
// the fixed decimal place
var dn = 3;

if (s.constructor.name == "Character") {
    var t = "Metric\tPoints\tMillimeters\r"
    var p = getFontMetric(s).pointSize;
    p = "Point Size:\t" + p + "\t" + UnitValue( p, "pt" ).as("mm").toFixed(dn) + "\r";
    
    var bl = getFontMetric(s).baselin
...
Translate
Community Expert ,
Jun 30, 2024 Jun 30, 2024

Can't check right now but maybe this will work:

 

number.toFixed(places);

 

or

 

Math.round(number * 1000) / 1000;

 

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
Enthusiast ,
Jun 30, 2024 Jun 30, 2024

@Robert at ID-Tasker @rob day Hi Robert. Thanks for the reply.

Actually this the kind of output I am looking for:

Required OutputRequired Outputexpand image

 Thanks. I am not in a hurry. Plz do have a look at it whenever you get time. In the meantime, I will try the function which you have suggested.

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 ,
Jun 30, 2024 Jun 30, 2024

Hi @Bedazzled532 , There‘s no way that I know of to format the alert() dialog result. You might be able to use the scriptUI window class to create some alignment in a window aor palette.

 

You could also create a text frame somewhere in the document with a tab delimited string as the contents and style that, but that would take some work.

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
Enthusiast ,
Jun 30, 2024 Jun 30, 2024

@rob day Ok. Thanks. Actually I was thinking of formatting a string as we use to do in printf in earlier days and then show it through alert. I will try what you suggested.

I have limited decimal places to 3 by @Robert at ID-Tasker suggested function.

 

Here is how the alert function looks like:

alert("\u0009Points:" + "\u0009" + " MM:\r" + "Point Size:" + p + "\u0009" + (p*.3572).toFixed(3) + "\r" + "Baseline: " + bl + "\u0009" + (bl*.3572).toFixed(3) + "\r" + "Ascender: " + a + "\u0009" + (a*.3572).toFixed(3) +  "\r" + "Descender: " + d + "\u0009" + (d*.3572).toFixed(3) + "\r" +  "Cap Height: " + ch + "\u0009" + (ch*.3572).toFixed(3) + "\r" + "x-Height: " + xh + "\u0009" + (xh*.3572).toFixed(3));

How can I use a method padEnd and padStart. I see that there is a function but when I use this function, I get that there is no function named padEnd or padStart.

 

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 ,
Jun 30, 2024 Jun 30, 2024

@Bedazzled532

 

I don't think padding will work - as font used in UI is "variable width".

 

But as the tab works - \u0009 - you can use it to align your results.

 

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
Enthusiast ,
Jun 30, 2024 Jun 30, 2024

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 ,
Jun 30, 2024 Jun 30, 2024

Also, you might look at the unitValue object which lets you convert units—it’s returning a different value than your .3572 multiplier:

 

// the selected character
var s = app.activeDocument.selection[0]; 
// the fixed decimal place
var dn = 3;

if (s.constructor.name == "Character") {
    var t = "Metric\tPoints\tMillimeters\r"
    var p = getFontMetric(s).pointSize;
    p = "Point Size:\t" + p + "\t" + UnitValue( p, "pt" ).as("mm").toFixed(dn) + "\r";
    
    var bl = getFontMetric(s).baseline;
    bl = "Baseline:\t" +bl + "\t" + UnitValue( bl, "pt" ).as("mm").toFixed(dn) + "\r";
    
    var a = getFontMetric(s).ascent;
    a = "Ascent:\t" +a + "\t" + UnitValue( a, "pt" ).as("mm").toFixed(dn) + "\r";

    var d = getFontMetric(s).descent;
    d = "Descent:\t" +d + "\t" + UnitValue( d, "pt" ).as("mm").toFixed(dn) + "\r";

    var ch = getFontMetric(s).capHeight;
    ch = "Cap Ht:\t" +ch + "\t" + UnitValue( ch, "pt" ).as("mm").toFixed(dn) + "\r";

    var xh = getFontMetric(s).xHeight;
    xh = "xHeight:\t" +xh + "\t" + UnitValue( xh, "pt" ).as("mm").toFixed(dn) + "\r";
    
    alert(t + p + bl + a + d + ch + xh)

} else {
    alert("Please Select a Single Character");
}


/**
* Gets the selected character’s font metrics 
* @ param the character selection  
* @ return an object with pointSize, baseline, ascent,descent, xHeight, and capHeight 
*/
function getFontMetric(s){
    app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;
    var o = new Object;
    o.pointSize = s.pointSize.toFixed(dn);
    o.baseline = s.baseline.toFixed(dn);
    o.ascent = s.ascent.toFixed(dn);
    o.descent = s.descent.toFixed(dn);
    app.copy();
    var tf = app.activeDocument.textFrames.add({geometricBounds: [0,0,500,500], textFramePreferences: {firstBaselineOffset: FirstBaseline.CAP_HEIGHT, insetSpacing: 0, minimumFirstBaselineOffset: 0, verticalJustification: VerticalJustification.TOP_ALIGN}});  
    app.select([tf.parentStory.insertionPoints[0]]);    
    app.paste();
    tf.texts[0].alignToBaseline = false;
    o.capHeight = tf.texts[0].insertionPoints[0].baseline.toFixed(dn);
    tf.textFramePreferences.firstBaselineOffset = FirstBaseline.X_HEIGHT;
    o.xHeight = tf.texts[0].insertionPoints[0].baseline.toFixed(dn);
    tf.remove();
    app.select(s)
    app.scriptPreferences.userInteractionLevel = UserInteractionLevels.INTERACT_WITH_ALL;
    return o
}

 

 

 

Screen Shot 36.pngexpand image

 

Screen Shot 39.pngexpand imageScreen Shot 40.pngexpand image

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 ,
Jun 30, 2024 Jun 30, 2024

Also, if you want to stay with an alert, double tabs help with the alignment

 

Screen Shot 37.pngexpand image

 

if (s.constructor.name == "Character") {
    var t = "Metric\t\tPoints\t\tMillimeters\r"
    var p = getFontMetric(s).pointSize;
    p = "Point Size:\t\t" + p + "\t\t" + UnitValue( p, "pt" ).as("mm").toFixed(dn) + "\r";
    
    var bl = getFontMetric(s).baseline;
    bl = "Baseline:\t\t" +bl + "\t\t" + UnitValue( bl, "pt" ).as("mm").toFixed(dn) + "\r";
    
    var a = getFontMetric(s).ascent;
    a = "Ascent:\t\t" +a + "\t\t" + UnitValue( a, "pt" ).as("mm").toFixed(dn) + "\r";

    var d = getFontMetric(s).descent;
    d = "Descent:\t\t" +d + "\t\t" + UnitValue( d, "pt" ).as("mm").toFixed(dn) + "\r";

    var ch = getFontMetric(s).capHeight;
    ch = "Cap Ht:\t\t" +ch + "\t\t" + UnitValue( ch, "pt" ).as("mm").toFixed(dn) + "\r";

    var xh = getFontMetric(s).xHeight;
    xh = "xHeight:\t\t" +xh + "\t\t" + UnitValue( xh, "pt" ).as("mm").toFixed(dn) + "\r";
    
    alert(t + p + bl + a + d + ch + xh)

} else {
    alert("Please Select a Single Character");
}
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
Enthusiast ,
Jun 30, 2024 Jun 30, 2024
LATEST

@rob day Thank you so much. This is exactly what I was looking for.

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