Access to the `UnitValue` api/method in UXP Adobe InDesign

ExtendScript for Adobe InDesign had an api/method called UnitValue().
Some documentation of it is here:
https://extendscript.docsforadobe.dev/extendscript-tools-features/specifying-measurement-values.html?highlight=unitvalue#unitvalue-object-constructor

I had used it in some legacy code like this:

		var downUnitsToMove = String(new UnitValue(down, unit));
		var rightUnitsToMove = String(new UnitValue(right, unit));

I can’t seem to locate this in UXP. Anybody know the proper syntax or does it no longer exist?

jsw

I think this is defined at ExtendScript level, along with things like the XML object and not part of the InDesign DOM API.

You could do a doScript into ExtendScript, create an instance there and return the string.

IMO looking purely from a API perspective the UXP side of things is quite a downgrade to ExtendScript, it is slower and misses very useful/needed features that were part of ExtendScript for ages (resolving specifiers, persistent engine, global helper objects).

Thankfully the doscript is available with the option to do (serious) stuff in ExtendScript still from a UXP plugin. Best of both worlds I suppose…

1 Like

I am using math.js. It is useful not only for unit conversions, but also for calculating expressions.

1 Like

Try if you can make this workaround work for you.

function parseUnitValue(s, baseUnit) {
    if (s === undefined || s === '' || s.length === 0) {
        s = '0';
    }
    const regex = /\+*(\-*\d*[\.|,]?\d*\s*)(in|inch|inches|ft|foot|feet|yd|yard|yards|mi|mile|miles|mm|millimeter|millimeters|cm|centimeter|centimeters|m|meter|meters|km|kilometer|kilometers|pt|point|points|pc|pica|picas|ci|cicero|ciceros)?/gi;
    const match = s.match(regex);

    let stringIsValid = false;
    let sVal = 0;
    let sUnit = baseUnit;

    if (match && s === match[0]) {
        stringIsValid = true;
        sVal = s.replace(regex, '$1').replace(',', '.');
        sUnit = s.replace(regex, '$2').toLowerCase() || baseUnit;
    }

    if (!stringIsValid) {
        console.warn("Unknown Unit. Try: in, inch, inches, ft, foot, feet, yd, yard, yards, mi, mile, miles, pt, point, points, pc, pica, picas, ci, cicero, ciceros, mm, millimeter, millimeters, cm, centimeter, centimeters, m, meter, meters, km, kilometer, kilometers");
        return 0;
    }

    return convertToBaseUnit(parseFloat(sVal), sUnit, baseUnit);
}

function convertToBaseUnit(value, fromUnit, toUnit) {
    const units = {
        'in': 72, 'inch': 72, 'inches': 72,
        'ft': 864, 'foot': 864, 'feet': 864,
        'yd': 2592, 'yard': 2592, 'yards': 2592,
        'mi': 4572288, 'mile': 4572288, 'miles': 4572288,
        'mm': 2.834645669, 'millimeter': 2.834645669, 'millimeters': 2.834645669,
        'cm': 28.34645669, 'centimeter': 28.34645669, 'centimeters': 28.34645669,
        'm': 2834.645669, 'meter': 2834.645669, 'meters': 2834.645669,
        'km': 2834645.669, 'kilometer': 2834645.669, 'kilometers': 2834645.669,
        'pt': 1, 'point': 1, 'points': 1,
        'pc': 12, 'pica': 12, 'picas': 12,
        'ci': 12.7872, 'cicero': 12.7872, 'ciceros': 12.7872
    };

    if (!units[fromUnit] || !units[toUnit]) {
        console.error('Invalid unit conversion');
        return 0;
    }

    const pointValue = value * units[fromUnit];
    return pointValue / units[toUnit];
}
1 Like

As an update, I knew I only needed it it points so hard coded it for UXP. I do like all the suggestions. Thanks!
I’ll mark this as closed.

It would help others much more if the actual solution would be marked as such. If you used suggestions from multiple posts, would be great if you added the combined result, which worked for you and mark that as a solution. Current marked post doesn’t have the actual solution