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

Is there any specific algorithm relationship between Letter spacing and font size in InDesign?

Explorer ,
Jun 13, 2023 Jun 13, 2023

68.png

ABCD Name

AD Name

ABD Name

 

I need to align the three above.

Some people may use grids, but that feature is difficult to use and I usually don't use it. It's better to use font spacing.

 

However, it is troublesome to adjust the font spacing. For example, when the font size becomes larger, I have to try every Letter spacing value.

Just want to ask: What is the relationship between font size and spacing, can we calculate it?

 

TOPICS
Bug , How to , Import and export , Scripting , Sync and storage
4.9K
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 4 Correct answers

Community Expert , Jun 14, 2023 Jun 14, 2023

Hi @dublove5CFE, the issue here is converting tracking units (which I assume you are using to space out the A in the second line) into ruler units. Tracking is measured in em units which relate to the font size. The conversion factor is, 1000 / font size. Some fonts have differing sized em squares but Indesign seems to calibrate them all to 1000 units in terms of the UI and scripting API. You can see how it works in this script, that attempts to solve your problem.

 

 

/**
 * Letterspace Chars T
...
Translate
Community Expert , Jun 15, 2023 Jun 15, 2023

Hi @dublove5CFE, I have written a modified version that also sets the tab stop so that the tab character width is 5mm (you can adjust this in the script). I've also put the letterspacing into a function so it can be used for other purposes.

demo2.gif

Try this version and see what you think.

- Mark

 

/**
 * Letterspace Chars Before Tab
 * Script expects to have a text selection that includes
 * paragraphs that share a tab stop, and will and will
 * adjust tracking of characters before the tab character
 *
...
Translate
Community Expert , Jun 15, 2023 Jun 15, 2023

Hi @dublove5CFE, it sounds like it might be better in your case just to replace the tab with another character of your choice. Here is a re-write of the script that replaces tab with em space u+2003. You could choose another unicode space character.

- Mark

demo3.gif

 

/**
 * Letterspace Chars Before Tab
 * Script expects to have a text selection that includes
 * paragraphs that share a tab stop, and will adjust
 * tracking of characters before the tab character
 * so that the last characters before each 
...
Translate
Community Expert , Jun 16, 2023 Jun 16, 2023

Thank you Robert.

Translate
Community Expert ,
Jun 13, 2023 Jun 13, 2023

Letter spacing (kerning values) are set by the type designer and generally vary withthe combination of glyphs. For consistent spacing no matter waht the text might be you would need to use a mono-spaced font like Courier, or create your own.

I suspect this might work better if set up as a table. You could then use full justification in your paragraph styles to completely fill the width of each cell regardless of the number of characters.

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 ,
Jun 14, 2023 Jun 14, 2023

The table is too cumbersome. Not a good idea

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 ,
Jun 15, 2024 Jun 15, 2024
quote

The table is too cumbersome. Not a good idea


By @dublove5CFE

 

@dublove

 

Here is initial comment from the latest code created by m1b:

 

 * Notes and assumptions:
 * - Script assumes each paragraph is a single line.

 

This condition = "convert to table and forget" - earlier idea from @Peter Spier to use table... And would also automatically work for multiline paragraphs. 

 

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 ,
Jun 13, 2023 Jun 13, 2023

A,B,C,D,N,a,m,e - each one has a DIFFERENT width chosen by the font designer. But they scale reasonably exactly with the font size - if you go from 12 point to 24 point the letter spacing (for each letter, for that specific font and weight and style) is exactly double.

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 ,
Jun 14, 2023 Jun 14, 2023

I have been searching for many years

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 14, 2023 Jun 14, 2023

You can type (or place) your tabbed text normally, then select it and Table > Convert text to table...

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 ,
Jun 14, 2023 Jun 14, 2023

I'm not sure what you've been searching for.  It doesn't seem to relate to my point about each font being different. But you don't have to guess, you can get the font metrics (or a programmer could...)

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 ,
Jun 14, 2023 Jun 14, 2023

What EXACTLY are you trying to achieve? 

 

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 14, 2023 Jun 14, 2023

Hi @dublove5CFE, the issue here is converting tracking units (which I assume you are using to space out the A in the second line) into ruler units. Tracking is measured in em units which relate to the font size. The conversion factor is, 1000 / font size. Some fonts have differing sized em squares but Indesign seems to calibrate them all to 1000 units in terms of the UI and scripting API. You can see how it works in this script, that attempts to solve your problem.

 

 

/**
 * Letterspace Chars To Align Tab.
 * Script expects to have a text selection that includes paragraphs share a tab stop,
 * and will adjust tracking of characters before the tab character so that the last
 * characters in each paragraph align.
 * So that the script can be run multiple times, it resets tracking to 0 each time.
 * @author m1b
 * @discussion https://community.adobe.com/t5/indesign-discussions/is-there-any-specific-algorithm-relationship-between-letter-spacing-and-font-size-in-indesign/m-p/13861581
 */

function main() {

    app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;

    const emSquare = 1000;

    var doc = app.activeDocument,
        text = doc.selection[0];

    if (
        text == undefined
        || typeof text.findGrep !== 'function'
    ) {
        alert('Please select some text and run script again.');
        return;
    }

    // find paragraphs with tabs
    app.findGrepPreferences = NothingEnum.NOTHING;
    app.findGrepPreferences.findWhat = '^[^\\t]+\\t';
    var found = text.findGrep();

    // store the horizontal position
    // of the right-most tab
    var positions = [],
        maxPosition = -Infinity;

    for (var i = 0; i < found.length; i++) {
        found[i].tracking = 0;
        positions[i] = found[i].insertionPoints[found[i].insertionPoints.length - 2].horizontalOffset;
        if (positions[i] > maxPosition)
            maxPosition = positions[i];
    }

    // track out the initial characters
    for (var i = 0; i < found.length; i++) {

        if (positions[i] == maxPosition)
            continue;

        var chars = found[i].characters.itemByRange(0, found[i].characters.length - 3).characters;

        for (var j = 0; j < chars.length; j++)
            chars[j].tracking = ((maxPosition - positions[i]) / chars.length) * (emSquare / chars[j].pointSize);

    }

}; // end main

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Space Chars Before Tab");

 

Edit 2023-06-15: reset tracking to zero time.

Edit 2023-06-16: now correctly handles no characters before tab.

 

In the script you can see the conversion into em units here: <ruler distance> * (emSquare / chars[j].pointSize). Where emSquare is 1000.

 

Note that for convenience I altered your example so that every paragraph has a tab character to tell the script where to align. The script will only work if there is a tab in every selected paragraph—it will try to align the text before the tab. Here is what it does when I run it:

demo.gif

Let me know if that helps.

- Mark

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 ,
Jun 15, 2023 Jun 15, 2023

That's great.

Very effective, thank you very much.

I can quickly get different Letter spacing and add these values to the character style.

Use grep to call these character styles in paragraph styles

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 ,
Jun 15, 2023 Jun 15, 2023

Found a small problem.

If you later add or delete content, the script will become invalid

You need to manually set the Letter spacing to 0, and then run the script.

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 ,
Jun 15, 2023 Jun 15, 2023

I try to modify the script. Clear the Letter spacing before running the script.

I failed.

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 15, 2023 Jun 15, 2023

No problem. I have updated the script above.

- Mark

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 ,
Jun 15, 2023 Jun 15, 2023

Can you control the value of the Tab key?

It would be great if it could be added to the script.

Using the longest character before the tab as a reference, set the value of the tab?

998.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
Explorer ,
Jun 15, 2023 Jun 15, 2023

Starting with the Tab key will prompt for an error.

And there is also no alignment

6690.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 ,
Jun 15, 2023 Jun 15, 2023

Hi @dublove5CFE, I have written a modified version that also sets the tab stop so that the tab character width is 5mm (you can adjust this in the script). I've also put the letterspacing into a function so it can be used for other purposes.

demo2.gif

Try this version and see what you think.

- Mark

 

/**
 * Letterspace Chars Before Tab
 * Script expects to have a text selection that includes
 * paragraphs that share a tab stop, and will and will
 * adjust tracking of characters before the tab character
 * so that the last characters in each paragraph align.
 * It will set a tab stop so that the width of the tab
 * character equals `tabWidth`.
 * @author m1b
 * @discussion https://community.adobe.com/t5/indesign-discussions/is-there-any-specific-algorithm-relationship-between-letter-spacing-and-font-size-in-indesign/m-p/13861581
 */
function main() {

    var tabWidth = '5mm';

    app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;

    var doc = app.activeDocument,
        text = doc.selection[0];

    if (
        text == undefined
        || typeof text.findGrep !== 'function'
        || text.contents == ''
    ) {
        alert('Please select some text and run script again.');
        return;
    }

    // find paragraphs with tabs
    app.findGrepPreferences = NothingEnum.NOTHING;
    app.findGrepPreferences.findWhat = '^[^\\t]*\\t';
    var found = text.findGrep();

    // store the horizontal position
    // of the right-most tab
    var positions = [],
        maxPosition = -Infinity,
        tabPosition = 0,
        tabWidthPts = new UnitValue(tabWidth).as('pt');

    for (var i = 0; i < found.length; i++) {
        found[i].tracking = 0;
        positions[i] = found[i].insertionPoints[found[i].insertionPoints.length - 2].horizontalOffset;
        if (positions[i] > maxPosition) {
            maxPosition = positions[i];
            left = found[i].insertionPoints[0].horizontalOffset;
            tabPosition = found[i].insertionPoints[found[i].insertionPoints.length - 1].horizontalOffset;
        }
    }

    for (var i = 0; i < found.length; i++) {

        var tabStops = found[i].tabStops;

        // remove all tab stops in alignment area
        for (var j = tabStops.length - 1; j >= 0; j--)
            if (tabStops[j].position <= Math.max(maxPosition + tabWidthPts, tabPosition))
                tabStops[j].remove();

        // set a tab stop to match the tabWidth
        tabStops.add({ position: maxPosition - left + tabWidthPts });

        if (
            positions[i] !== maxPosition
            && found[i].characters.length > 1
        )
            // letterspace the characters before tab
            letterspaceToWidth(found[i].characters.itemByRange(0, found[i].characters.length - 2), maxPosition - found[i].insertionPoints[0].horizontalOffset);

    }

};

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Space Chars Before Tab");


/**
 * Applies tracking to text so that
 * the width of the text will match
 * with `width` parameter supplied.
 * Assumptions:
 * - text is justified left
 * - text is uniform point size
 * - text doesn't span multiple lines
 * @author m1b
 * @version 2023-06-16
 * @param {Text} text - an Indesign text object.
 * @param {Number} width - the desired width in pts.
 */
function letterspaceToWidth(text, width) {

    if (!text.hasOwnProperty('insertionPoints'))
        return;

    const emSquare = 1000;

    var left = text.insertionPoints[0].horizontalOffset,
        right = text.insertionPoints[text.insertionPoints.length - 1].horizontalOffset,
        chars = text.characters.itemByRange(0, text.characters.length - 2).characters,
        delta = width - (right - left);

    for (var i = 0; i < chars.length; i++)
        chars[i].tracking = (delta / chars.length) * (emSquare / chars[i].pointSize);

};

 

 

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 ,
Jun 15, 2023 Jun 15, 2023

Yes, that's it. You're amazing.

Thank you.

Your script may be included by Adobe in the future and comes with it

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 ,
Jun 15, 2023 Jun 15, 2023

 

  var tabWidth = '4mm';

 

Another question

How to write this sentence with one character width?

Full width or half width characters.

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 15, 2023 Jun 15, 2023

Hi @dublove5CFE, it sounds like it might be better in your case just to replace the tab with another character of your choice. Here is a re-write of the script that replaces tab with em space u+2003. You could choose another unicode space character.

- Mark

demo3.gif

 

/**
 * Letterspace Chars Before Tab
 * Script expects to have a text selection that includes
 * paragraphs that share a tab stop, and will adjust
 * tracking of characters before the tab character
 * so that the last characters before each tab align
 * vertically. Script will replace tab with a character
 * of your choice.
 * @author m1b
 * @discussion https://community.adobe.com/t5/indesign-discussions/is-there-any-specific-algorithm-relationship-between-letter-spacing-and-font-size-in-indesign/m-p/13861581
 */
function main() {

    // replace tab with em space
    var dividerChar = '\u2003';

    app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;

    var doc = app.activeDocument,
        text = doc.selection[0];

    if (
        text == undefined
        || typeof text.findGrep !== 'function'
        || text.contents == ''
    ) {
        alert('Please select some text and run script again.');
        return;
    }

    // add space when no characters before tab
    app.findGrepPreferences = app.changeGrepPreferences = NothingEnum.NOTHING;
    app.findGrepPreferences.findWhat = '^([\\t]?)\\t';
    app.changeGrepPreferences.changeTo = ' $0';
    text.changeGrep();
    
    // find paragraphs with tabs
    app.findGrepPreferences.findWhat = '^[^\\t]*\\t';
    var found = text.findGrep();

    // store the horizontal position
    // of the right-most tab
    var positions = [],
        maxPosition = -Infinity;

    for (var i = 0; i < found.length; i++) {

        // start with no letterspacing
        found[i].tracking = 0;

        positions[i] = found[i].insertionPoints[found[i].insertionPoints.length - 2].horizontalOffset;
        if (positions[i] > maxPosition) {
            maxPosition = positions[i];
            left = found[i].insertionPoints[0].horizontalOffset;
        }
    }

    for (var i = 0; i < found.length; i++) {

        if (
            positions[i] !== maxPosition
            // && found[i].characters.length > 1
        )
            // letterspace the characters before tab
            letterspaceToWidth(found[i].characters.itemByRange(0, found[i].characters.length - 2), maxPosition - found[i].insertionPoints[0].horizontalOffset);

        // replace tab with a divider character
        found[i].characters.lastItem().contents = dividerChar;

    }

};

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Letterspace Chars Before Tab");


/**
 * Applies tracking to text so that
 * the width of the text will match
 * with `width` parameter supplied.
 * Assumptions:
 * - text is justified left
 * - text is uniform point size
 * - text doesn't span multiple lines
 * @author m1b
 * @version 2023-06-16
 * @param {Text} text - an Indesign text object.
 * @param {Number} width - the desired width in pts.
 */
function letterspaceToWidth(text, width) {

    if (!text.hasOwnProperty('insertionPoints'))
        return;

    const emSquare = 1000;

    var left = text.insertionPoints[0].horizontalOffset,
        right = text.insertionPoints[text.insertionPoints.length - 1].horizontalOffset,
        chars = text.characters.itemByRange(0, text.characters.length - 2).characters,
        delta = width - (right - left);

    for (var i = 0; i < chars.length; i++)
        chars[i].tracking = (delta / chars.length) * (emSquare / chars[i].pointSize);

};

 

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 ,
Jun 16, 2023 Jun 16, 2023

Thank you~

Forget it, I'll manually modify the tab value.

This space looks so strange.

I want to keep the tab, just make sure that the spacing between the tabs is exactly one word wide

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 16, 2023 Jun 16, 2023

Okay, no worries. I'm sure I can make the script do what you want, but I don't understand what you mean. Sorry.

- Mark

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 ,
Jun 16, 2023 Jun 16, 2023

I'm sorry to trouble you too much.

I want to keep using tab, just make the value of tab exactly one character wide.

(Full width character width)

This way, I don't need to try adjusting this value multiple times.

7779.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 ,
Jun 16, 2023 Jun 16, 2023

I'll repeat myself - what are you trying to achieve OVERALL? 

 

What kind of publication are you preparing? 

 

How do you get your data? How is it originally formatted? 

 

Can you show us more real life example screenshot? 

 

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 ,
Jun 16, 2023 Jun 16, 2023

sorry 

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