Skip to content

Commit

Permalink
[helpers] Add some action data parsing helper functions for integer a…
Browse files Browse the repository at this point in the history
…nd boolean types; Add numeric `clamp()` function.
  • Loading branch information
mpaperno committed Sep 30, 2023
1 parent 8e3abf5 commit ea64b2e
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { DynamicIcon, ParseState, globalImageCache } from "./modules";
import * as m_el from "./modules/elements";
import { ConsoleEndpoint, Logger, logging , LogLevel } from './modules/logging';
import { setTPClient, PluginSettings } from './common'
import { parseIntOrDefault, /* parseBoolOrDefault, */ clamp } from './utils/helpers'
import { dirname as pdirname, resolve as presolve } from 'path';
const { version: pluginVersion } = require('../package.json'); // 'import' causes lint error in VSCode

Expand Down Expand Up @@ -546,11 +547,11 @@ function onSettings(settings:{ [key:string]:string }[]) {
PluginSettings.imageFilesBasePath = val.trim() || DEFAULT_IMAGE_FILE_BASE_PATH;
break;
case C.SettingName.PngCompressLevel:
PluginSettings.defaultOutputCompressionLevel = /^\d$/.test(val) ? parseInt(val) : 0;
PluginSettings.defaultOutputCompressionLevel = clamp(parseIntOrDefault(val, PluginSettings.defaultOutputCompressionLevel), 0, 9);
break;
// Ignore GPU setting for now, possibly revisit if skia-canvas is fixed.
// case C.SettingName.GPU:
// PluginSettings.defaultGpuRendering = /(?:[1-9]\d*|yes|true|enabled?)/i.test(val);
// PluginSettings.defaultGpuRendering = parseBoolOrDefault(val, PluginSettings.defaultGpuRendering);
// break;
}
});
Expand Down
2 changes: 2 additions & 0 deletions src/utils/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export const enum Str {
IconCategoryName = PluginShortName, // Name of TP Category for dynamically created icon States.
IdPrefix = "dynamic_icons_", // prefix used in TP IDs for actions/data/states/etc
IdSep = "_", // action/data ID separator character
Default = "default", // used in action fields TP UI to indicate a default value
DefaultChar = 'd', // must match first char of `Default`, used in code for quick value comparisons
};

// Constant TP state IDs
Expand Down
28 changes: 28 additions & 0 deletions src/utils/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { Alignment } from '../modules/enums';
import { Str } from './consts'
import { PointType } from '../modules/geometry';
import { logging } from '../modules/logging';

// Used to validate if a string is a single numeric value. Accepts leading sign, base prefix (0x/0b/0o), decimals, and exponential notation.
const NUMBER_VALIDATION_REGEX = new RegExp(/^[+-]?(?:0[xbo])?\d+(?:\.\d*)?(?:e[+-]?\d+)?$/);
// To test if a text string is "truthy."
const BOOL_TEST_REGEX = new RegExp(/\b(?:yes|on|true|enabled?|\d*[1-9]\d*)\b/i);
// Global match anything not a \d(igit): \D
const RE_NOT_DIGIT_G = new RegExp(/\D/g);

/** Constrain a numeric `value` between `min` and `max`, inclusive. */
export function clamp(value: number, min: number, max: number) {
return Math.max(min, Math.min(max, value));
}

/** Evaluates a numeric expression within an arbitrary string. Returns zero if evaluation fails or value string was empty.
Note that the number formats must be "language neutral," meaning always period for decimal separator and no thousands separators. */
Expand Down Expand Up @@ -134,3 +144,21 @@ export function parseAlignmentFromValue(value: string, atype: Alignment = Alignm
}
return ret;
}

/** Returns true/false based on if a string value looks "truthy", meaning it contains "yes", "on", "true", "enable[d]", or any digit > 0. */
export function parseBoolFromValue(value: string) {
return BOOL_TEST_REGEX.test(value);
}

/** Returns an integer value contained in string `value`, or the provded `dflt` default if `value` is blank/NaN or is "default". */
export function parseIntOrDefault(value: string, dflt: number): number {
if (!value || value[0] == Str.DefaultChar)
return dflt;
const iv = parseInt(value.replace(RE_NOT_DIGIT_G, ''));
return iv == Number.NaN ? dflt : iv;
}

/** Returns `true` if the string `value` is "truthy," or the provded default if `value` is blank or is "default". @see parseBoolFromValue() */
export function parseBoolOrDefault(value: string, dflt: boolean): boolean {
return !value || value[0] == Str.DefaultChar ? dflt : parseBoolFromValue(value);
}

0 comments on commit ea64b2e

Please sign in to comment.