Skip to main content
Inspiring
December 17, 2016
질문

Is there a view that reveals the baseline, median and/or cap height for lines of type?

  • December 17, 2016
  • 3 답변들
  • 3550 조회

CC on a Mac. I'm wondering it there is a view that reveals the locations of the baseline, median and/or cap height for lines of type. I'd like to place some graphics and have them snap into place.

    이 주제는 답변이 닫혔습니다.

    3 답변

    Peter Kahrel
    Community Expert
    Community Expert
    December 19, 2016

    Sandee -- In your example, green is baseline, lavender is the cap height. The bits that stick out below the baseline and above the x-height are called undershoot and overshoot, respectively. And in some fonts, serifs and flex can stick out above the cap height.

    Marie -- Here is a script that places guides at the descender, baseline, x-height, cap height and descender of some selected text. (Unlike baseline, descender, and ascender, cap height and x-height are not available to scripts and determining them requires a convoluted method.) As it is, the script places guides only at the baseline and the cap height. To enable the three other guides, remove the two slashes at the beginning of the lines. To change the colour of the guides, change the RGB values. The guides are placed on a new layer, which you can hide or remove.

    Peter

    (function () {

     

      var page = app.windows[0].activePage;

      var lines = app.selection[0].lines.everyItem().getElements();

      var ch;

      var xcap;

     

      function characterHeights (ch) {

        app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;

        var o = {};

        var frame = app.documents[0].pages[0].textFrames.add ({geometricBounds: [0, 0, 20, 20], contents: 'x'});

        frame.paragraphs[0].appliedParagraphStyle = ch.appliedParagraphStyle;

        frame.textFramePreferences.firstBaselineOffset = FirstBaseline.X_HEIGHT;

        o.xHeight = frame.characters[0].baseline;

        frame.textFramePreferences.firstBaselineOffset = FirstBaseline.CAP_HEIGHT;

        o.capHeight = frame.characters[0].baseline;

        frame.remove();

        return o;

      }

      function addGuide (pos, colour) {

        page.guides.add (app.documents[0].layers.item ('metrics'), {

          guideType: GuideTypeOptions.RULER,

          location: pos,

          orientation: HorizontalOrVertical.HORIZONTAL,

          guideColor: colour,

        });

      }

      if (app.selection.length === 0 || !app.selection[0].hasOwnProperty('baseline')) {

        alert ('Select some text.');

        exit();

      }

      if (app.documents[0].layers.item ('metrics') === null) {

        app.documents[0].layers.add ({name: 'metrics'});

      }

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

        ch = lines.characters[0];

        xcap = characterHeights (ch);

        //addGuide (ch.baseline - ch.ascent, [0, 255, 0]);   // Ascender

        addGuide (ch.baseline - xcap.capHeight, [255, 0, 0]);  // Cap height

        //addGuide (ch.baseline - xcap.xHeight, [255, 0, 0]);   // x height

        addGuide (ch.baseline, [0, 0, 255]);   // Baseline

        //addGuide (ch.baseline + ch.descent, [0, 255, 0]);   // Descender

      }

    }());

    Known Participant
    February 26, 2021

    Peter, could you please update the script for it to work on later versions? On 2018 and 2020, it returns this error:

    JavaScript Error!
    
    Error Number: 21
    Error String: undefined is not an object
    
    Engine: main
    File: …
    Line: 36
    Source: ch=lines.characters[0];
    rob day
    Community Expert
    Community Expert
    February 26, 2021

    In case Peter misses this— ch=lines.characters[0] is missing the i variable, so should be ch=lines[i].characters[0]

     

    Also the script works great, but if the selected text’s paragraph style’s font size is overriden the rules will not be accurate, or if  the point size is larger than the temporary text frame’s 20pt height, there will be an overset and you’ll get an error. Changing the characterHeights(ch) function to this seems to work:

     

     

     

    (function () {
    
      var page = app.windows[0].activePage;
      var lines = app.selection[0].lines.everyItem().getElements();
      var ch;
      var xcap;
    
      function characterHeights (ch) {
        app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;
        
        var o = {};
        
        var frame = app.documents[0].pages[0].textFrames.add ({ contents: 'x'});
        frame.characters[0].pointSize = ch.pointSize;
        frame.geometricBounds = [0,0,ch.pointSize,ch.pointSize]
        frame.characters[0].appliedFont = ch.appliedFont;
        frame.textFramePreferences.firstBaselineOffset = FirstBaseline.X_HEIGHT;
        o.xHeight = frame.characters[0].baseline;
    
        frame.textFramePreferences.firstBaselineOffset = FirstBaseline.CAP_HEIGHT;
        o.capHeight = frame.characters[0].baseline;
    
        frame.remove();
    
        return o;
    
      }
    
      function addGuide (pos, colour) {
    
        page.guides.add (app.documents[0].layers.item ('metrics'), {
          guideType: GuideTypeOptions.RULER,
          location: pos,
          orientation: HorizontalOrVertical.HORIZONTAL,
          guideColor: colour,
        });
      }
    
      if (app.selection.length === 0 || !app.selection[0].hasOwnProperty('baseline')) {
        alert ('Select some text.');
        exit();
      }
    
      if (app.documents[0].layers.item ('metrics') === null) {
        app.documents[0].layers.add ({name: 'metrics'});
      }
    
      for (var i = 0; i < lines.length; i++) {
    
        ch = lines[i].characters[0];
    
        xcap = characterHeights (ch);
    
        addGuide (ch.baseline - ch.ascent, [0, 255, 0]);   // Ascender
    
        addGuide (ch.baseline - xcap.capHeight, [255, 0, 0]);  // Cap height
    
        addGuide (ch.baseline - xcap.xHeight, [255, 0, 0]);   // x height
    
        addGuide (ch.baseline, [0, 0, 255]);   // Baseline
    
        addGuide (ch.baseline + ch.descent, [0, 255, 0]);   // Descender
    
      }
    
    }());

     

     

     

    Community Expert
    December 18, 2016

    MarieMeyer wrote:

    CC on a Mac. I'm wondering it there is a view that reveals the locations of the baseline, median and/or cap height for lines of type. I'd like to place some graphics and have them snap into place.

    Hi Marie,

    if your text is working with a baseline grid a placed graphic would snap to that grid.

    For  cap-height or x-height you probably could select a character, "H" for cap-height, "x" for x-height and create a duplicate outline of the selection and align your graphic to the outlined character.

    To get a duplicate outlined character just select a character and when on a Mac press the alt key and use menu Type > Create Outlines

    Regards,
    Uwe

    Community Expert
    December 18, 2016

    With a selected duplicate of a character outlined you could also create guides with a script that comes along with every version of InDesign: AddGuides.jsx . Open your Scripts panel in InDesign, look under Application > Samples > JavaScript.

    Select the outlined shape and do some controls after double-clicking the script AddGuides.jsx from the Scripts panel:

    Don't know why

  • the controls say "Add Guides Around: Path Points Vertical Anchor" if I want horizontal guides, but it is working that way. Maybe better would be: "Add horizontal Guide at Path Points" and "Add vertical Guide at Path Points".


    Here the script author used technical terms like "Horizontal Anchor" and "Vertical Anchor" that a "normal" user, who did not dived into InDesign's Document Object Model for scripting cannot understand.

  • After inspecting the code I know why, because the values of property anchor of a pathPoint are used and described that come along with an array of x- and y-values as [x,y]. And x-values would be used for vertical guides and y-values would be used for horizontal guides.

    After running the script:

    Also note that you cannot undo the action of this script in one go.
    That would require to add some simple lines of code to wrap the whole script into one single function and call that function with a doScript.

    Something like that:

    app.doScript

        (

        createGuidesOfSelectedObject,

        ScriptLanguage.JAVASCRIPT,

        [],

        UndoModes.ENTIRE_SCRIPT,

        "Create guides of selected object | SCRIPT"

        );

    function createGuidesOfSelectedObject()

    {

    /* ADD ADOBE'S CODE BETWEEN THE TWO BRACES*/

    }

    Note: The name of the outer function is used with doScript()

    The string that says "Create guides …" is the thing you'll see, if you go to InDesign's menu to do the undo action.

    Change it to something you like.

    From the ExtendScript Toolkit:

    Do not forget to add the closing brace of the added function declaration above.
    Add a new line at the very end of Adobe's code and add the closing brace:

    Regards,
    Uwe

  • Barb Binder
    Community Expert
    Community Expert
    December 17, 2016

    No, but you can pull ruler guides out of the horizontal ruler to mark any or all three.

    ~Barb at Rocky Mountain Training
    MarieMeyer작성자
    Inspiring
    December 17, 2016

    I know how to pull ruler guides, but how would I place them - just eyeball it? And would I have to manually repeat for each line of text? Can I group them with a line of text, so that if the line moves, the guides move, too?

    Barb Binder
    Community Expert
    Community Expert
    December 17, 2016

    Unfortunately, it's a yes (eyeball), yes (manually repeat) and a no (you can't anchor guides to the text).

    You can display a baseline grid automatically (set it up in Prefs, turn it on with View > Grids and Guides, and snap contents to the grid with a button on the Control panel or via a ¶ style) and you can create ruler guides automatically (Layout > Create Guides), but I don't think either of these are exactly what you are hoping for.

    You can put this on a feature request form: Wishform - Adobe InDesign

    ~Barb at Rocky Mountain Training