How to detect new units if RulerUnits.Unknown

In the Illustrator Preferences or current document settings (Document Setup → Units) you set the ruler units. Document units do not affect global preferences, but changing global units will change document settings. In the DOM, the activeDocument.rulerUnits property returns the current units from the list: RulerUnits.Pixels, RulerUnits.Millimeters, and so on. But more interesting is RulerUnits.Unknown — the document exists, but the units in it don’t exist?

The CC 2020 release showed that this is easily possible for Adobe developers. They added feet, yards, and meters to Illustrator, but forgot about the API, and for a long time. Even in the latest betas of CC 2022, scripts in documents with new units get RulerUnits.Unknown. This prevents you from converting units from one to the other because the sizes of objects and artboards in the scripts are stored in pixels.

The script didn’t detect the feet units

Luckily, Illustrator still needs somewhere to store information about document units, and it writes it in XMP metadata: activeDocument.XMPString. In the Adobe’s book “XMP Specification” , where it mentions a property of type Dimensions that contains three fields:

  • stDim:h — height,
  • stDim:unit — ruler units.

An example of a piece of metadata with the field we need:

<xmpTPg:NPages>1</xmpTPg:NPages>
<xmpTPg:HasVisibleTransparency>False</xmpTPg:HasVisibleTransparency>
<xmpTPg:HasVisibleOverprint>False</xmpTPg:HasVisibleOverprint>
<xmpTPg:MaxPageSize rdf:parseType="Resource">
<stDim:w>1366.000000</stDim:w>
<stDim:h>768.000000</stDim:h>
<stDim:unit>Pixels</stDim:unit>
</xmpTPg:MaxPageSize>

Let’s face the pain right away — the problem is that the metadata is written only when the file is saved. This means that when changing units in a document, the user must save the file before running the script. There are no such problems with older units, because the scripts get them on the fly.

Our algorithm will look like this:

  • get data from activeDocument.XMPString,
  • find the field stDim:unit,
  • retrieve the name of the units, e.g. by searching for matches of the exec() string.
var doc = activeDocument;
if (doc.rulerUnits == RulerUnits.Unknown) {
var xmp = doc.XMPString;
var units = '';
if (/stDim:unit/i.test(xmp)) {
units = /<stDim:unit>(.*?)<\/stDim:unit>/g.exec(xmp)[1];
}
alert('Current units: ' + units);
}
After saving the document the units are read from XMP

The example applies to new units only, and you can see the full code for the ruler check and conversion function in the ArtboardsFinder script.

Upd: CC 2023 v27.1.1 was released in December 2022 and added new unit keys for RulerUnits. But for previous versions, checking the contents of XMP with RulerUnits.Unknown is still relevant.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
AiScripts

Sergey Osokin. I’m a illustrator & Script Developer (Ai, Ps). Writing about bugs and tricks.