Skip to main content
Known Participant
March 1, 2024
Answered

How to avoid empty space in the inside of the equations

  • March 1, 2024
  • 7 replies
  • 9208 views

Dear Team,

 

I need to avoid the empty boundary space around equations inside the frame. I have to exactly fit the equation such that there is no white space. Can you provide or suggest any script related to this request?

Please advise.

 

Or any option available in the mathtype to fix this issue?

 

Please see the screenshot for your reference below:

 

 

Thanks

kanagakumar

This topic has been closed for replies.
Correct answer m1b

Dear Team,

 

Sure, I will continue working manually.

Kindly let me know if you have any scripts that meet my needs or if you have any other alternatives.

Thank you for taking the time to respond to my inquiry. I'm going to close our conversation as of now.

 

@Peter Kahrel @rob day @m1b @Joel Cherney @brian_p_dts 

Thank you for your support and guidance.

 

Thanks

kk


Hi @kanagakumar and others, really you guys have worked out the hard parts already. So I've written a script that uses your insights, and hopefully this will do what you want.

 

I have assumed that the equations are all eps graphics that are anchored in text. I've included options to set a uniform scale for the equations, and also to fit the frame to the content—this is critical, otherwise the baseline might not be correct.

 

Give it a try and let me know how you go.

- Mark

 

Example, using scalePercent: 120:

 

 

 

 

 

/**
 * Aligns all anchored EPS math equation graphics to their baseline
 * by using the `Baseline` value in the eps markup.
 *
 * Options:
 *   - apply an object style to each equation's frame
 *   - apply a separate object style for "display" equation's frames
 *   - scale the equation graphic
 *   - fit content to frame (NOTE: turning this off may result in baseline misalignments.)
 *   - adjusts equations cropping on left and right sides.
 *
 * Notes:
 *   - "Display" equations start a line, are displayed on the line by themselves
 *      and do not have baseline adjustments.
 * @author m1b
 * @discussion https://community.adobe.com/t5/indesign-discussions/how-to-avoid-empty-space-in-the-inside-of-the-equations/m-p/14460828
 */
function main() {

    var settings = {
        equationInlineStyleName: 'Equation Inline',
        equationDisplayStyleName: 'EQ-text Wrap',
        scalePercent: 100,
        leftSideBearing: -1,
        rightSidebearing: -1,
        fitFrameToContent: true,
    };

    app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;

    var counter = 0,
        doc = app.activeDocument,
        inlineEquationStyle = getThing(doc.allObjectStyles, 'name', settings.equationInlineStyleName),
        displayEquationStyle = getThing(doc.allObjectStyles, 'name', settings.equationDisplayStyleName),
        graphics = doc.allGraphics;

    for (var i = 0, eps, baseline, newYOffset, isDisplay; i < graphics.length; i++) {

        if (
            'EPS' !== graphics[i].constructor.name
            || undefined == graphics[i].parent.anchoredObjectSettings
        )
            // ignore non-eps and non-anchored graphics
            continue;

        eps = graphics[i];

        // get the baseline from the eps file
        baseline = getBaselineOfEPS(eps);

        if (undefined == baseline)
            // didn't get baseline
            continue;

        // "display" equations are handled differently
        isDisplay = true === isDisplayEquation(eps);

        // apply object style
        if (isDisplay && displayEquationStyle)
            eps.parent.appliedObjectStyle = displayEquationStyle;

        else if (inlineEquationStyle)
            eps.parent.appliedObjectStyle = inlineEquationStyle;

        // scale
        if (settings.scalePercent)
            eps.properties = {
                verticalScale: settings.scalePercent,
                horizontalScale: settings.scalePercent,
            };

        // adjust the frame
        crop(eps, [0, settings.leftSideBearing, 0, settings.rightSidebearing], settings.fitFrameToContent);

        // the anchored object Y offset value
        newYOffset = -baseline * (eps.verticalScale / 100);

        if (!isDisplay)
            // adjust the anchored position
            eps.parent.anchoredObjectSettings.anchorYoffset = newYOffset;

        counter++;

    }

    alert('Adjusted ' + counter + ' anchored eps graphics.');

};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Align Anchored Equations');

/**
 * Returns the `baseline` value
 * from the EPS file.
 * @author Peter Kahrel
 * @author Rob Day
 * @author m1b
 * @version 2024-03-09
 * @param {EPS} graphic - an EPS graphic.
 * @returns {Number} - the baseline extracted from the file.
 */
function getBaselineOfEPS(graphic) {

    var f = File(graphic.itemLink.filePath);

    if (!f.exists)
        return;

    f.encoding = 'BINARY';
    f.open('r');
    var str = f.read();
    f.close();

    return Number(str.match(/%%Baseline:\s(\d+)/)[1] || 0);

};

/**
 * Returns a thing with matching property.
 * @param {Array|collection} things - the things to look through, eg. PageItems.
 * @param {String} key - the property name, eg. 'name'.
 * @param {*} value - the value to match.
 * @returns {*} - the thing.
 */
function getThing(things, key, value) {

    for (var i = 0; i < things.length; i++)
        if (things[i][key] == value)
            return things[i];

};

/**
 * Adjust a graphic's container's bounds,
 * either relative to the graphic, or
 * relative to the graphic's container.
 *
 * Example:
 *   crop(myGraphic,[0,0,0,0]); // equivalent to fit frame to content
 *
 * Example:
 *   copy(mygraphic, [-1,-1,-1,-1], false); // reduce frame by 1 point all around
 *
 * @author m1b
 * @version 2024-03-12
 * @param {contained object} graphic - the target graphic, eg. PDF.
 * @param {Array<Number>} offset - the adjustment to make, in points, in current units to [top, left, bottom, right].
 * @param {Boolean} adjustRelativeToGraphic - whether the adjustment is relative to graphic object; otherwise will be relative to graphic's parentframe (default: true).
 */
function crop(graphic, offset, adjustRelativeToGraphic) {

    var frame = graphic.parent,
        bounds = false !== adjustRelativeToGraphic
            ? graphic.geometricBounds
            : frame.geometricBounds;

    if (undefined == bounds)
        return;

    frame.geometricBounds = [
        bounds[0] - offset[0],
        bounds[1] - offset[1],
        bounds[2] + offset[2],
        bounds[3] + offset[3],
    ];

};

/**
 * Returns true when the supplied EPS
 * is a "Display" equation.
 * @param {EPS} eps - an Indesign EPS graphic.
 * @returns {Boolean}
 */
function isDisplayEquation(eps) {

    return {
        'EQ': true,
        'EQ-I': true,
    }[eps.parent.parent.appliedParagraphStyle.name];

};

 

 

Edit 2024-03-12: Added the crop function and added "sidebearings" to the settings object so that the equation graphic's frames can be adjusted on the left and right.

Edit 2024-03-12: Added handling of "display" equations as per OP's comments.

Edit 2024-03-12: Changed isDisplayEquation function as per OP's comments.

7 replies

Peter Kahrel
Community Expert
Community Expert
March 9, 2024

@rob day 

> Why do the bounds matter?

 

If you place an EPS eqn inline, the spaces before and after the eqn are wider than the space of the line, that's the problem. The vertical paddings matter less, thoughin principle the vertical padding could increase the leading of the line.

Peter Kahrel
Community Expert
Community Expert
March 3, 2024

You can also start reading after the binary bytes (the text starts around byte 35 or so):

 

That's tricky, because before the line with Baseline you have variable-length items such as the file name and font names.

m1b
Community Expert
Community Expert
March 3, 2024

Yeah and since I have no idea what is encoded before byte 35, for all I know it could be variable too! I retract my suggestion. 🙂

- Mark

Known Participant
March 8, 2024

Dear Team,

Still, I am working manually for all equation frames. 

 

Thanks

kk

Peter Kahrel
Community Expert
Community Expert
March 3, 2024

Maybe you should set the encoding to binary. This code works for me (on Windows):

 

f = File ('d:/test/sample.eps');
f.encoding = 'BINARY';
f.open('r');
s = f.read();
f.close();

alert ('Baseline: ' + s.match (/%%Baseline:\s(\d+)/)[1]);
rob day
Community Expert
Community Expert
March 3, 2024

That worked thanks

Peter Kahrel
Community Expert
Community Expert
March 3, 2024

MathType (EPS) equations always have 1 point padding. In the post that Joel cited Mr MathType says 2 points, but in my experience it's always 1, but that may be because I usually dealt with MT EPSs that didn't come from Word.

 

Anyway, you can't just chop off 1 or 2 points because the padding doesn't take into account font metrics (undershoot, overshoot, left and right side bearings) so whatever fixed padding value you use, you always get it wrong. There's just no good way to clip MT EPSs to their content.

 

The second problem mentioned, how to align the EPSs baseline with the parent line's baseline, can be handled accurately. The EPS file contains some metrics. Look for the line that starts with %%Baseline:

%%Baseline: 14

This equations's baseline is 14 points. You can then use the method outlined by Rob (setting wrap and baseline adjustment) to align the equation's baseline.

rob day
Community Expert
Community Expert
March 3, 2024

Hi Peter, Thanks! Not sure if aligning the baselines is what @kanagakumar is after, but it does indeed work— the negative value of the %%Baseline number aligns the baselines. Is there a way to read the contents of an EPS text via scripting? Calling file.open("r")  doesn’t seem to work for me:

 

 

 

 

 

 

 

 

Joel Cherney
Community Expert
Community Expert
March 1, 2024

I was actually in a long thread about this very issue a few months back, and after many, many attempts to figure out how to get something out of MathType that wouldn't be padded in this way, it was pointed out that @MrMathType — Retired himself had already posted a padding-reduction solution. You might try one of the many other options suggested there. 

rob day
Community Expert
Community Expert
March 1, 2024

Hi Joel, What is the problem with the bounds if the object fill is transparent — [None]? Is it about matching the baselines? If the bottom padding is consistent, a baseline shift could be applied to the anchor.

Joel Cherney
Community Expert
Community Expert
March 1, 2024

I hadn't noticed your reply when I wrote mine - and I like the direction you're thinking in, Rob. I assume that you could safely reduce the size of the bounding box on all four sides. When I placed the provided sample EPS files as inline anchored objects, I found that I could reduce the bounding box in size by around, but not exactly, two points on each side. When I did so, the baseline of the text in the EPS sat exactly where you'd expect if you were working with live text, without baseline adjustment. 

 

 

rob day
Community Expert
Community Expert
March 1, 2024

Hi @kanagakumar , the background of the eps is [None], and the eps container can also be [None], can you describe a case where the size of the bounding box is a problem? The parent container could be made smaller via scripting, but it would not change the text’s output.

m1b
Community Expert
Community Expert
March 1, 2024

It depends on how the artwork for the equation is structured. But are you able to import them with "Show Import Options" on? And then (depending on the file format—hopefully PDF or similar vector format) try choosing: Art

That can sometimes help in this sort of case. The problem may be that the program that generated the equation artwork file may have included a white box behind it, so Indesign thinks that this is part of the art.

 

If the above isn't helpful, could you share a couple of samples of the equation artwork?

- Mark

Known Participant
March 1, 2024

Dear Mark,

 

Thanks for your reply.

 

Please see the attachment for the samples mathtype equations.

 

Thanks

kk

m1b
Community Expert
Community Expert
March 1, 2024

Thanks @kanagakumar that is helpful. The problem in your case appears to be that the bounding box of the artwork is the bounds of the glyphs, which is usually bigger than the actual letterform itself (there is space to either side of the letterform so that there is a pleasing gap between adjacent letterforms). This works badly for your situation though.

 

A possible solution is to outline the fonts so that they are vector paths rather than font glyphs. Then the bounding box is tight to the edges:

If you think this is a good option, you can see if you can convert to outlines in the exporting stage (from your maths typesetting app) or you can convert the .eps files to outline using Illustrator. Let me know if you need help doing the converting as it may be possible to script it (eg. if there are hundreds of files).

- Mark.