// Runtime checks and cleanup for value types in the spec that aren't easily expressed through our type system.
// These will help us to prevent silent failures and corrupted documents.
//
//
//
//
//
export function universalMeasureValue(val: string): string {
const unit = val.slice(-2);
if (!universalMeasureUnits.includes(unit)) {
throw new Error(`Invalid unit '${unit}' specified. Valid units are ${universalMeasureUnits.join(", ")}`);
}
const amount = val.substring(0, val.length - 2);
if (isNaN(Number(amount))) {
throw new Error(`Invalid value '${amount}' specified. Expected a valid number.`);
}
return val;
}
const universalMeasureUnits = ["mm", "cm", "in", "pt", "pc", "pi"];
//
//
//
//
//
export function positiveUniversalMeasureValue(val: string): string {
const value = universalMeasureValue(val);
if (parseInt(value, 10) < 0) {
throw new Error(`Invalid value '${value}' specified. Expected a positive number.`);
}
return value;
}
//
//
//
//
//
//
//
//
// The xsd:hexBinary type represents binary data as a sequence of binary octets.
// It uses hexadecimal encoding, where each binary octet is a two-character hexadecimal number.
// Lowercase and uppercase letters A through F are permitted. For example, 0FB8 and 0fb8 are two
// equal xsd:hexBinary representations consisting of two octets.
//
//
//
//
//
export function hexColorValue(val: string): string {
if (val === "auto") {
return val;
}
// It's super common to see colors prefixed with a pound, but technically invalid here.
// Most clients work with it, but strip it off anyway for strict compliance.
const color = val.charAt(0) === "#" ? val.substring(1) : val;
if (color.length !== 6 || isNaN(Number("0x" + color))) {
throw new Error(`Invalid color value '${color}'. Expected six digit hex value (eg FF9900)`);
}
return color;
}
//
//
//
export function unsignedDecimalNumber(val: number): number {
if (isNaN(val) || val < 0) {
throw new Error(`Invalid value '${val}' specified. Must be a positive base10 integer.`);
}
return Math.floor(val);
}
//
//
//
export function signedTwipsMeasureValue(val: string | number): string | number {
if (typeof val === "string") {
return universalMeasureValue(val);
}
if (isNaN(val)) {
throw new Error(`Invalid value '${val}' specified. Expected a valid number.`);
}
return Math.floor(val);
}
//
//
//
export function hpsMeasureValue(val: string | number): string | number {
return typeof val === "string" ? positiveUniversalMeasureValue(val) : unsignedDecimalNumber(val);
}