@itwin/core-quantity 4.8.0-dev.9 → 4.9.0-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -1
- package/lib/cjs/Constants.js.map +1 -1
- package/lib/cjs/Exception.js.map +1 -1
- package/lib/cjs/Formatter/Format.d.ts +3 -0
- package/lib/cjs/Formatter/Format.d.ts.map +1 -1
- package/lib/cjs/Formatter/Format.js +8 -0
- package/lib/cjs/Formatter/Format.js.map +1 -1
- package/lib/cjs/Formatter/FormatEnums.js.map +1 -1
- package/lib/cjs/Formatter/Formatter.js.map +1 -1
- package/lib/cjs/Formatter/FormatterSpec.js.map +1 -1
- package/lib/cjs/Formatter/Interfaces.d.ts +1 -0
- package/lib/cjs/Formatter/Interfaces.d.ts.map +1 -1
- package/lib/cjs/Formatter/Interfaces.js.map +1 -1
- package/lib/cjs/Interfaces.js.map +1 -1
- package/lib/cjs/Parser.d.ts +25 -4
- package/lib/cjs/Parser.d.ts.map +1 -1
- package/lib/cjs/Parser.js +184 -117
- package/lib/cjs/Parser.js.map +1 -1
- package/lib/cjs/ParserSpec.js.map +1 -1
- package/lib/cjs/Quantity.js.map +1 -1
- package/lib/cjs/Unit.js.map +1 -1
- package/lib/cjs/core-quantity.js.map +1 -1
- package/lib/esm/Constants.js.map +1 -1
- package/lib/esm/Exception.js.map +1 -1
- package/lib/esm/Formatter/Format.d.ts +3 -0
- package/lib/esm/Formatter/Format.d.ts.map +1 -1
- package/lib/esm/Formatter/Format.js +8 -0
- package/lib/esm/Formatter/Format.js.map +1 -1
- package/lib/esm/Formatter/FormatEnums.js.map +1 -1
- package/lib/esm/Formatter/Formatter.js.map +1 -1
- package/lib/esm/Formatter/FormatterSpec.js.map +1 -1
- package/lib/esm/Formatter/Interfaces.d.ts +1 -0
- package/lib/esm/Formatter/Interfaces.d.ts.map +1 -1
- package/lib/esm/Formatter/Interfaces.js.map +1 -1
- package/lib/esm/Interfaces.js.map +1 -1
- package/lib/esm/Parser.d.ts +25 -4
- package/lib/esm/Parser.d.ts.map +1 -1
- package/lib/esm/Parser.js +184 -117
- package/lib/esm/Parser.js.map +1 -1
- package/lib/esm/ParserSpec.js.map +1 -1
- package/lib/esm/Quantity.js.map +1 -1
- package/lib/esm/Unit.js.map +1 -1
- package/lib/esm/core-quantity.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormatterSpec.js","sourceRoot":"","sources":["../../../src/Formatter/FormatterSpec.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Quantity\n */\n\nimport { UnitConversionProps, UnitConversionSpec, UnitProps, UnitsProvider } from \"../Interfaces\";\nimport { Format } from \"./Format\";\nimport { Formatter } from \"./Formatter\";\n\n// cSpell:ignore ZERONORMALIZED, nosign, onlynegative, signalways, negativeparentheses\n// cSpell:ignore trailzeroes, keepsinglezero, zeroempty, keepdecimalpoint, applyrounding, fractiondash, showunitlabel, prependunitlabel, exponentonlynegative\n\n/** A class that contains both formatting information and the conversion factors necessary to convert from an input unit to the units specified in the format.\n * Once created the FormatterSpec will be able to format quantity values with synchronous calls.\n * @beta\n */\nexport class FormatterSpec {\n protected _name: string;\n protected _conversions: UnitConversionSpec[] = []; // max four entries\n protected _format: Format;\n protected _persistenceUnit: UnitProps;\n\n /** Constructor\n * @param name The name of a format specification.\n * @param format Defines the output format for the quantity value.\n * @param conversions An array of conversion factors necessary to convert from an input unit to the units specified in the format.\n * @param persistenceUnit The unit the magnitude value is input.\n */\n constructor(name: string, format: Format, conversions?: UnitConversionSpec[], persistenceUnit?: UnitProps) {\n if (!persistenceUnit) {\n if (format.units) {\n const [props] = format.units[0];\n persistenceUnit = props;\n } else {\n throw new Error(\"Formatter Spec needs persistence unit to be specified\");\n }\n }\n\n this._name = name;\n this._format = format;\n this._persistenceUnit = persistenceUnit;\n if (conversions)\n this._conversions = conversions;\n }\n\n public get name(): string { return this._name; }\n /** Returns an array of UnitConversionSpecs, one for each unit that is to be shown in the formatted quantity string. */\n public get unitConversions(): UnitConversionSpec[] { return this._conversions; }\n public get format(): Format { return this._format; }\n public get persistenceUnit(): UnitProps { return this._persistenceUnit; }\n\n /** Get an array of UnitConversionSpecs, one for each unit that is to be shown in the formatted quantity string. */\n public static async getUnitConversions(format: Format, unitsProvider: UnitsProvider, inputUnit?: UnitProps): Promise<UnitConversionSpec[]> {\n const conversions: UnitConversionSpec[] = [];\n let persistenceUnit = inputUnit;\n if (!persistenceUnit) {\n if (format.units) {\n const [props] = format.units[0];\n persistenceUnit = props;\n } else {\n throw new Error(\"Formatter Spec needs persistence unit to be specified\");\n }\n }\n\n if (format.units) {\n let convertFromUnit = inputUnit;\n for (const unit of format.units) {\n let unitConversion: UnitConversionProps;\n if (convertFromUnit) {\n unitConversion = await unitsProvider.getConversion(convertFromUnit, unit[0]);\n } else {\n unitConversion = { factor: 1.0, offset: 0.0 };\n }\n const unitLabel = (unit[1] && unit[1].length > 0) ? unit[1] : unit[0].label;\n const spec = ({ name: unit[0].name, label: unitLabel, conversion: unitConversion, system: unit[0].system }) as UnitConversionSpec;\n\n conversions.push(spec);\n convertFromUnit = unit[0];\n }\n } else {\n // if format is only numeric and a input unit is defined set spec to use the input unit as the format unit\n if (inputUnit) {\n const spec: UnitConversionSpec = { name: inputUnit.name, label: inputUnit.label, system: inputUnit.system, conversion: { factor: 1.0, offset: 0.0 } };\n conversions.push(spec);\n }\n }\n\n return conversions;\n }\n\n /** Static async method to create a FormatSpec given the format and unit of the quantity that will be passed to the Formatter. The input unit will\n * be used to generate conversion information for each unit specified in the Format. This method is async due to the fact that the units provider must make\n * async calls to lookup unit definitions.\n * @param name The name of a format specification.\n * @param unitsProvider The units provider is used to look up unit definitions and provide conversion information for converting between units.\n * @param inputUnit The unit the value to be formatted. This unit is often referred to as persistence unit.\n */\n public static async create(name: string, format: Format, unitsProvider: UnitsProvider, inputUnit?: UnitProps): Promise<FormatterSpec> {\n const conversions: UnitConversionSpec[] = await FormatterSpec.getUnitConversions(format, unitsProvider, inputUnit);\n return new FormatterSpec(name, format, conversions, inputUnit);\n }\n\n /** Format a quantity value. */\n public applyFormatting(magnitude: number): string {\n return Formatter.formatQuantity(magnitude, this);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"FormatterSpec.js","sourceRoot":"","sources":["../../../src/Formatter/FormatterSpec.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Quantity\r\n */\r\n\r\nimport { UnitConversionProps, UnitConversionSpec, UnitProps, UnitsProvider } from \"../Interfaces\";\r\nimport { Format } from \"./Format\";\r\nimport { Formatter } from \"./Formatter\";\r\n\r\n// cSpell:ignore ZERONORMALIZED, nosign, onlynegative, signalways, negativeparentheses\r\n// cSpell:ignore trailzeroes, keepsinglezero, zeroempty, keepdecimalpoint, applyrounding, fractiondash, showunitlabel, prependunitlabel, exponentonlynegative\r\n\r\n/** A class that contains both formatting information and the conversion factors necessary to convert from an input unit to the units specified in the format.\r\n * Once created the FormatterSpec will be able to format quantity values with synchronous calls.\r\n * @beta\r\n */\r\nexport class FormatterSpec {\r\n protected _name: string;\r\n protected _conversions: UnitConversionSpec[] = []; // max four entries\r\n protected _format: Format;\r\n protected _persistenceUnit: UnitProps;\r\n\r\n /** Constructor\r\n * @param name The name of a format specification.\r\n * @param format Defines the output format for the quantity value.\r\n * @param conversions An array of conversion factors necessary to convert from an input unit to the units specified in the format.\r\n * @param persistenceUnit The unit the magnitude value is input.\r\n */\r\n constructor(name: string, format: Format, conversions?: UnitConversionSpec[], persistenceUnit?: UnitProps) {\r\n if (!persistenceUnit) {\r\n if (format.units) {\r\n const [props] = format.units[0];\r\n persistenceUnit = props;\r\n } else {\r\n throw new Error(\"Formatter Spec needs persistence unit to be specified\");\r\n }\r\n }\r\n\r\n this._name = name;\r\n this._format = format;\r\n this._persistenceUnit = persistenceUnit;\r\n if (conversions)\r\n this._conversions = conversions;\r\n }\r\n\r\n public get name(): string { return this._name; }\r\n /** Returns an array of UnitConversionSpecs, one for each unit that is to be shown in the formatted quantity string. */\r\n public get unitConversions(): UnitConversionSpec[] { return this._conversions; }\r\n public get format(): Format { return this._format; }\r\n public get persistenceUnit(): UnitProps { return this._persistenceUnit; }\r\n\r\n /** Get an array of UnitConversionSpecs, one for each unit that is to be shown in the formatted quantity string. */\r\n public static async getUnitConversions(format: Format, unitsProvider: UnitsProvider, inputUnit?: UnitProps): Promise<UnitConversionSpec[]> {\r\n const conversions: UnitConversionSpec[] = [];\r\n let persistenceUnit = inputUnit;\r\n if (!persistenceUnit) {\r\n if (format.units) {\r\n const [props] = format.units[0];\r\n persistenceUnit = props;\r\n } else {\r\n throw new Error(\"Formatter Spec needs persistence unit to be specified\");\r\n }\r\n }\r\n\r\n if (format.units) {\r\n let convertFromUnit = inputUnit;\r\n for (const unit of format.units) {\r\n let unitConversion: UnitConversionProps;\r\n if (convertFromUnit) {\r\n unitConversion = await unitsProvider.getConversion(convertFromUnit, unit[0]);\r\n } else {\r\n unitConversion = { factor: 1.0, offset: 0.0 };\r\n }\r\n const unitLabel = (unit[1] && unit[1].length > 0) ? unit[1] : unit[0].label;\r\n const spec = ({ name: unit[0].name, label: unitLabel, conversion: unitConversion, system: unit[0].system }) as UnitConversionSpec;\r\n\r\n conversions.push(spec);\r\n convertFromUnit = unit[0];\r\n }\r\n } else {\r\n // if format is only numeric and a input unit is defined set spec to use the input unit as the format unit\r\n if (inputUnit) {\r\n const spec: UnitConversionSpec = { name: inputUnit.name, label: inputUnit.label, system: inputUnit.system, conversion: { factor: 1.0, offset: 0.0 } };\r\n conversions.push(spec);\r\n }\r\n }\r\n\r\n return conversions;\r\n }\r\n\r\n /** Static async method to create a FormatSpec given the format and unit of the quantity that will be passed to the Formatter. The input unit will\r\n * be used to generate conversion information for each unit specified in the Format. This method is async due to the fact that the units provider must make\r\n * async calls to lookup unit definitions.\r\n * @param name The name of a format specification.\r\n * @param unitsProvider The units provider is used to look up unit definitions and provide conversion information for converting between units.\r\n * @param inputUnit The unit the value to be formatted. This unit is often referred to as persistence unit.\r\n */\r\n public static async create(name: string, format: Format, unitsProvider: UnitsProvider, inputUnit?: UnitProps): Promise<FormatterSpec> {\r\n const conversions: UnitConversionSpec[] = await FormatterSpec.getUnitConversions(format, unitsProvider, inputUnit);\r\n return new FormatterSpec(name, format, conversions, inputUnit);\r\n }\r\n\r\n /** Format a quantity value. */\r\n public applyFormatting(magnitude: number): string {\r\n return Formatter.formatQuantity(magnitude, this);\r\n }\r\n}\r\n"]}
|
|
@@ -19,6 +19,7 @@ export interface FormatProps {
|
|
|
19
19
|
readonly scientificType?: string;
|
|
20
20
|
readonly stationOffsetSize?: number;
|
|
21
21
|
readonly stationSeparator?: string;
|
|
22
|
+
readonly allowMathematicOperations?: boolean;
|
|
22
23
|
readonly composite?: {
|
|
23
24
|
readonly spacer?: string;
|
|
24
25
|
readonly includeZero?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Interfaces.d.ts","sourceRoot":"","sources":["../../../src/Formatter/Interfaces.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEhG;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE;QACnB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;QAC/B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;YACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;SACzB,CAAC,CAAC;KACJ,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,WAAW;IACpD,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC;CACtB;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,SAAU,WAAW,8BAEpD,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,yEAAyE;IACzE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,oCAAoC;IACpC,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,uFAAuF;IACvF,SAAS,CAAC,EAAE,gBAAgB,GAAG,mBAAmB,CAAC;IACnD,oDAAoD;IACpD,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB"}
|
|
1
|
+
{"version":3,"file":"Interfaces.d.ts","sourceRoot":"","sources":["../../../src/Formatter/Interfaces.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEhG;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IAC7C,QAAQ,CAAC,SAAS,CAAC,EAAE;QACnB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;QAC/B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;YACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;SACzB,CAAC,CAAC;KACJ,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,WAAW;IACpD,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC;CACtB;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,SAAU,WAAW,8BAEpD,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,yEAAyE;IACzE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,oCAAoC;IACpC,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,uFAAuF;IACvF,SAAS,CAAC,EAAE,gBAAgB,GAAG,mBAAmB,CAAC;IACnD,oDAAoD;IACpD,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Interfaces.js","sourceRoot":"","sources":["../../../src/Formatter/Interfaces.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;
|
|
1
|
+
{"version":3,"file":"Interfaces.js","sourceRoot":"","sources":["../../../src/Formatter/Interfaces.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAuCH;;GAEG;AACI,MAAM,mBAAmB,GAAG,CAAC,IAAiB,EAA6B,EAAE;IAClF,OAAQ,IAA0B,CAAC,MAAM,KAAK,SAAS,CAAC;AAC1D,CAAC,CAAC;AAFW,QAAA,mBAAmB,uBAE9B","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Quantity\r\n */\r\n\r\nimport { UnitProps } from \"../Interfaces\";\r\nimport { DecimalPrecision, FormatTraits, FormatType, FractionalPrecision } from \"./FormatEnums\";\r\n\r\n/** This interface defines the persistence format for describing the formatting of quantity values.\r\n * @beta\r\n */\r\nexport interface FormatProps {\r\n readonly type: string;\r\n readonly precision?: number;\r\n readonly roundFactor?: number;\r\n readonly minWidth?: number;\r\n readonly showSignOption?: string;\r\n readonly formatTraits?: string | string[];\r\n readonly decimalSeparator?: string;\r\n readonly thousandSeparator?: string;\r\n readonly uomSeparator?: string;\r\n readonly scientificType?: string; // conditionally required\r\n readonly stationOffsetSize?: number; // conditionally required\r\n readonly stationSeparator?: string;\r\n readonly allowMathematicOperations?: boolean;\r\n readonly composite?: {\r\n readonly spacer?: string;\r\n readonly includeZero?: boolean; // not currently used in Native formatter\r\n readonly units: Array<{\r\n readonly name: string;\r\n readonly label?: string;\r\n }>;\r\n };\r\n}\r\n\r\n/** This interface is used when supporting Custom Formatters that need more than the standard set of properties.\r\n * @beta\r\n */\r\nexport interface CustomFormatProps extends FormatProps {\r\n readonly custom: any;\r\n}\r\n\r\n/** CustomFormatProps type guard.\r\n * @beta\r\n */\r\nexport const isCustomFormatProps = (item: FormatProps): item is CustomFormatProps => {\r\n return (item as CustomFormatProps).custom !== undefined;\r\n};\r\n\r\n/** CloneFormat defines unit and label specification if primary unit is to be set during clone.\r\n * @beta\r\n */\r\nexport interface CloneUnit {\r\n unit?: UnitProps;\r\n label?: string;\r\n}\r\n\r\n/** CloneOptions that define modifications that can be made during the cloning of a Format.\r\n * @beta\r\n */\r\nexport interface CloneOptions {\r\n /** allows composite formats to be converted to only show primary unit */\r\n showOnlyPrimaryUnit?: boolean;\r\n /** allow format traits to be set */\r\n traits?: FormatTraits;\r\n /** allows new FormatType to be specified */\r\n type?: FormatType;\r\n /** allows precision to be set, this will throw if value is not valid for FormatType */\r\n precision?: DecimalPrecision | FractionalPrecision;\r\n /** allows primary unit and label to be specified */\r\n primaryUnit?: CloneUnit;\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Interfaces.js","sourceRoot":"","sources":["../../src/Interfaces.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Quantity\n */\n\n/** This interface allows a provider to be specified that will define an array of alternate labels for a specific unit.\n * @beta\n */\nexport interface AlternateUnitLabelsProvider {\n getAlternateUnitLabels: (unit: UnitProps) => string[] | undefined;\n}\n\n/** This interface provides basic information about a Unit that is return from a UnitProvider. This info\n * uniquely identifies a unit by its name.\n * @beta\n */\nexport interface UnitProps {\n /** Unique name for unit. */\n readonly name: string;\n /** Default label for unit. */\n readonly label: string;\n /** Unique name of unit phenomenon. Example phenomenon names include 'Units.LENGTH', 'Units.AREA', and 'Units.VOLUME' */\n readonly phenomenon: string;\n /** This is set to true if the Unit is known by the UnitsProvider. */\n readonly isValid: boolean;\n /** Unique system name. Example \"Units.USCUSTOM\",\" Units.METRIC\", \"Units.USSURVEY\", \"Units.IMPERIAL\" */\n readonly system: string;\n}\n\n/** This interface defines the required properties of a Quantity.\n * @beta\n */\nexport interface QuantityProps {\n readonly magnitude: number;\n readonly unit: UnitProps;\n readonly isValid: boolean;\n}\n\n/** Interface that defines how to convert between a specific unit an another in synchronous formatting or parsing processing.\n * @beta\n */\nexport interface UnitConversionSpec {\n /** Unit name that was used to locate the unit by the Unit Provider */\n name: string;\n /** The default label that is used to display unit */\n label: string;\n /** Unit system name, used to when finding preferred parse unit */\n system: string;\n /** the information necessary to convert the unit to a specific display unit */\n conversion: UnitConversionProps;\n /** Labels that may be used to represent the unit in a string that is to be parsed. */\n parseLabels?: string[];\n}\n\n/** This interface defines the properties required to convert a quantity value from one unit to another such as from meters to feet\n * or from Celsius to Fahrenheit.\n * @beta\n */\nexport interface UnitConversionProps {\n factor: number;\n offset: number;\n}\n\n/** Interface that defines potential parse units that may be found in user's string input of a quantity value.\n * @beta\n */\nexport interface PotentialParseUnit {\n unitName: string;\n altLabels?: string[];\n}\n\n/**\n * This interface defines extra properties to be associated with Units from Units Schema by name\n * @alpha\n */\nexport interface UnitExtraData {\n readonly name: string;\n readonly altDisplayLabels: string[];\n}\n\n/** This interface is implemented by the class that is responsible for locating units by name or label and providing conversion values between units.\n * The methods to be implemented are async allowing the UnitsProvider to query the backend when necessary to look up unit definition and conversion rules.\n * @beta\n */\nexport interface UnitsProvider {\n findUnit(unitLabel: string, schemaName?: string, phenomenon?: string, unitSystem?: string): Promise<UnitProps>;\n getUnitsByFamily(phenomenon: string): Promise<UnitProps[]>;\n findUnitByName(unitName: string): Promise<UnitProps>;\n getConversion(fromUnit: UnitProps, toUnit: UnitProps): Promise<UnitConversionProps>;\n}\n\n/**\n * Used to uniquely identify a unit system.\n * @beta\n */\nexport type UnitSystemKey = \"metric\" | \"imperial\" | \"usCustomary\" | \"usSurvey\";\n"]}
|
|
1
|
+
{"version":3,"file":"Interfaces.js","sourceRoot":"","sources":["../../src/Interfaces.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Quantity\r\n */\r\n\r\n/** This interface allows a provider to be specified that will define an array of alternate labels for a specific unit.\r\n * @beta\r\n */\r\nexport interface AlternateUnitLabelsProvider {\r\n getAlternateUnitLabels: (unit: UnitProps) => string[] | undefined;\r\n}\r\n\r\n/** This interface provides basic information about a Unit that is return from a UnitProvider. This info\r\n * uniquely identifies a unit by its name.\r\n * @beta\r\n */\r\nexport interface UnitProps {\r\n /** Unique name for unit. */\r\n readonly name: string;\r\n /** Default label for unit. */\r\n readonly label: string;\r\n /** Unique name of unit phenomenon. Example phenomenon names include 'Units.LENGTH', 'Units.AREA', and 'Units.VOLUME' */\r\n readonly phenomenon: string;\r\n /** This is set to true if the Unit is known by the UnitsProvider. */\r\n readonly isValid: boolean;\r\n /** Unique system name. Example \"Units.USCUSTOM\",\" Units.METRIC\", \"Units.USSURVEY\", \"Units.IMPERIAL\" */\r\n readonly system: string;\r\n}\r\n\r\n/** This interface defines the required properties of a Quantity.\r\n * @beta\r\n */\r\nexport interface QuantityProps {\r\n readonly magnitude: number;\r\n readonly unit: UnitProps;\r\n readonly isValid: boolean;\r\n}\r\n\r\n/** Interface that defines how to convert between a specific unit an another in synchronous formatting or parsing processing.\r\n * @beta\r\n */\r\nexport interface UnitConversionSpec {\r\n /** Unit name that was used to locate the unit by the Unit Provider */\r\n name: string;\r\n /** The default label that is used to display unit */\r\n label: string;\r\n /** Unit system name, used to when finding preferred parse unit */\r\n system: string;\r\n /** the information necessary to convert the unit to a specific display unit */\r\n conversion: UnitConversionProps;\r\n /** Labels that may be used to represent the unit in a string that is to be parsed. */\r\n parseLabels?: string[];\r\n}\r\n\r\n/** This interface defines the properties required to convert a quantity value from one unit to another such as from meters to feet\r\n * or from Celsius to Fahrenheit.\r\n * @beta\r\n */\r\nexport interface UnitConversionProps {\r\n factor: number;\r\n offset: number;\r\n}\r\n\r\n/** Interface that defines potential parse units that may be found in user's string input of a quantity value.\r\n * @beta\r\n */\r\nexport interface PotentialParseUnit {\r\n unitName: string;\r\n altLabels?: string[];\r\n}\r\n\r\n/**\r\n * This interface defines extra properties to be associated with Units from Units Schema by name\r\n * @alpha\r\n */\r\nexport interface UnitExtraData {\r\n readonly name: string;\r\n readonly altDisplayLabels: string[];\r\n}\r\n\r\n/** This interface is implemented by the class that is responsible for locating units by name or label and providing conversion values between units.\r\n * The methods to be implemented are async allowing the UnitsProvider to query the backend when necessary to look up unit definition and conversion rules.\r\n * @beta\r\n */\r\nexport interface UnitsProvider {\r\n findUnit(unitLabel: string, schemaName?: string, phenomenon?: string, unitSystem?: string): Promise<UnitProps>;\r\n getUnitsByFamily(phenomenon: string): Promise<UnitProps[]>;\r\n findUnitByName(unitName: string): Promise<UnitProps>;\r\n getConversion(fromUnit: UnitProps, toUnit: UnitProps): Promise<UnitConversionProps>;\r\n}\r\n\r\n/**\r\n * Used to uniquely identify a unit system.\r\n * @beta\r\n */\r\nexport type UnitSystemKey = \"metric\" | \"imperial\" | \"usCustomary\" | \"usSurvey\";\r\n"]}
|
package/lib/cjs/Parser.d.ts
CHANGED
|
@@ -13,7 +13,8 @@ export declare enum ParseError {
|
|
|
13
13
|
UnitLabelSuppliedButNotMatched = 3,
|
|
14
14
|
UnknownUnit = 4,
|
|
15
15
|
UnableToConvertParseTokensToQuantity = 5,
|
|
16
|
-
InvalidParserSpec = 6
|
|
16
|
+
InvalidParserSpec = 6,
|
|
17
|
+
MathematicOperationFoundButIsNotAllowed = 7
|
|
17
18
|
}
|
|
18
19
|
/** Parse error result from [[Parser.parseToQuantityValue]] or [[Parser.parseToQuantityValue]].
|
|
19
20
|
* @beta
|
|
@@ -33,6 +34,10 @@ export interface ParsedQuantity {
|
|
|
33
34
|
/** The magnitude of the parsed quantity. */
|
|
34
35
|
value: number;
|
|
35
36
|
}
|
|
37
|
+
declare enum Operator {
|
|
38
|
+
addition = "+",
|
|
39
|
+
subtraction = "-"
|
|
40
|
+
}
|
|
36
41
|
/**
|
|
37
42
|
* Defines Results of parsing a string input by a user into its desired value type
|
|
38
43
|
* @beta
|
|
@@ -42,8 +47,9 @@ export type QuantityParseResult = ParsedQuantity | ParseQuantityError;
|
|
|
42
47
|
* @beta
|
|
43
48
|
*/
|
|
44
49
|
declare class ParseToken {
|
|
45
|
-
value: number | string;
|
|
46
|
-
|
|
50
|
+
value: number | string | Operator;
|
|
51
|
+
isOperator: boolean;
|
|
52
|
+
constructor(value: string | number | Operator);
|
|
47
53
|
get isString(): boolean;
|
|
48
54
|
get isNumber(): boolean;
|
|
49
55
|
}
|
|
@@ -62,7 +68,15 @@ export declare class Parser {
|
|
|
62
68
|
* @param quantitySpecification The quantity string to ba parsed.
|
|
63
69
|
*/
|
|
64
70
|
static parseQuantitySpecification(quantitySpecification: string, format: Format): ParseToken[];
|
|
71
|
+
private static isMathematicOperation;
|
|
65
72
|
private static lookupUnitByLabel;
|
|
73
|
+
/**
|
|
74
|
+
* Get the output unit and all the conversion specs required to parse a given list of tokens.
|
|
75
|
+
*/
|
|
76
|
+
private static getRequiredUnitsConversionsToParseTokens;
|
|
77
|
+
/**
|
|
78
|
+
* Get the units information asynchronously, then convert the tokens into quantity using the synchronous tokens -> value.
|
|
79
|
+
*/
|
|
66
80
|
private static createQuantityFromParseTokens;
|
|
67
81
|
/** Async method to generate a Quantity given a string that represents a quantity value and likely a unit label.
|
|
68
82
|
* @param inString A string that contains text represent a quantity.
|
|
@@ -72,11 +86,18 @@ export declare class Parser {
|
|
|
72
86
|
static parseIntoQuantity(inString: string, format: Format, unitsProvider: UnitsProvider, altUnitLabelsProvider?: AlternateUnitLabelsProvider): Promise<QuantityProps>;
|
|
73
87
|
/** method to get the Unit Conversion given a unit label */
|
|
74
88
|
private static tryFindUnitConversion;
|
|
89
|
+
/**
|
|
90
|
+
* Get what the unit conversion is for a unitless value.
|
|
91
|
+
*/
|
|
92
|
+
private static getDefaultUnitConversion;
|
|
93
|
+
private static getNextTokenPair;
|
|
94
|
+
/**
|
|
95
|
+
* Accumulate the given list of tokens into a single quantity value. Formatting the tokens along the way.
|
|
96
|
+
*/
|
|
75
97
|
private static getQuantityValueFromParseTokens;
|
|
76
98
|
/** Method to generate a Quantity given a string that represents a quantity value.
|
|
77
99
|
* @param inString A string that contains text represent a quantity.
|
|
78
100
|
* @param parserSpec unit label if not explicitly defined by user. Must have matching entry in supplied array of unitsConversions.
|
|
79
|
-
* @param defaultValue default value to return if parsing is un successful
|
|
80
101
|
*/
|
|
81
102
|
static parseQuantityString(inString: string, parserSpec: ParserSpec): QuantityParseResult;
|
|
82
103
|
/** Method to generate a Quantity given a string that represents a quantity value and likely a unit label.
|
package/lib/cjs/Parser.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Parser.d.ts","sourceRoot":"","sources":["../../src/Parser.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,2BAA2B,EAAE,kBAAkB,EAAE,aAAa,EAAuB,kBAAkB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACjK,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C;;GAEG;AACH,oBAAY,UAAU;IACpB,2BAA2B,IAAI;IAC/B,0BAA0B,IAAA;IAC1B,8BAA8B,IAAA;IAC9B,WAAW,IAAA;IACX,oCAAoC,IAAA;IACpC,iBAAiB,IAAA;
|
|
1
|
+
{"version":3,"file":"Parser.d.ts","sourceRoot":"","sources":["../../src/Parser.ts"],"names":[],"mappings":"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"}
|
package/lib/cjs/Parser.js
CHANGED
|
@@ -22,18 +22,35 @@ var ParseError;
|
|
|
22
22
|
ParseError[ParseError["UnknownUnit"] = 4] = "UnknownUnit";
|
|
23
23
|
ParseError[ParseError["UnableToConvertParseTokensToQuantity"] = 5] = "UnableToConvertParseTokensToQuantity";
|
|
24
24
|
ParseError[ParseError["InvalidParserSpec"] = 6] = "InvalidParserSpec";
|
|
25
|
+
ParseError[ParseError["MathematicOperationFoundButIsNotAllowed"] = 7] = "MathematicOperationFoundButIsNotAllowed";
|
|
25
26
|
})(ParseError || (exports.ParseError = ParseError = {}));
|
|
27
|
+
var Operator;
|
|
28
|
+
(function (Operator) {
|
|
29
|
+
Operator["addition"] = "+";
|
|
30
|
+
Operator["subtraction"] = "-";
|
|
31
|
+
})(Operator || (Operator = {}));
|
|
32
|
+
function isOperator(char) {
|
|
33
|
+
if (typeof char === "number") {
|
|
34
|
+
// Convert the charcode to string.
|
|
35
|
+
char = String.fromCharCode(char);
|
|
36
|
+
}
|
|
37
|
+
return Object.values(Operator).includes(char);
|
|
38
|
+
}
|
|
26
39
|
/** A ParseToken holds either a numeric or string token extracted from a string that represents a quantity value.
|
|
27
40
|
* @beta
|
|
28
41
|
*/
|
|
29
42
|
class ParseToken {
|
|
30
43
|
constructor(value) {
|
|
31
|
-
|
|
44
|
+
this.isOperator = false;
|
|
45
|
+
if (typeof value === "string") {
|
|
32
46
|
this.value = value.trim();
|
|
33
|
-
|
|
47
|
+
this.isOperator = isOperator(this.value);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
34
50
|
this.value = value;
|
|
51
|
+
}
|
|
35
52
|
}
|
|
36
|
-
get isString() { return typeof this.value === "string"; }
|
|
53
|
+
get isString() { return !this.isOperator && typeof this.value === "string"; }
|
|
37
54
|
get isNumber() { return typeof this.value === "number"; }
|
|
38
55
|
}
|
|
39
56
|
/** A ScientificToken holds an index and string representing the exponent.
|
|
@@ -140,6 +157,7 @@ class Parser {
|
|
|
140
157
|
let processingNumber = false;
|
|
141
158
|
let wipToken = "";
|
|
142
159
|
let signToken = "";
|
|
160
|
+
let isStationSeparatorAdded = false;
|
|
143
161
|
let uomSeparatorToIgnore = 0;
|
|
144
162
|
let fractionDashCode = 0;
|
|
145
163
|
const skipCodes = [format.thousandSeparator.charCodeAt(0)];
|
|
@@ -225,9 +243,17 @@ class Parser {
|
|
|
225
243
|
}
|
|
226
244
|
}
|
|
227
245
|
}
|
|
228
|
-
|
|
229
|
-
|
|
246
|
+
if (format.type === FormatEnums_1.FormatType.Station && charCode === format.stationSeparator.charCodeAt(0)) {
|
|
247
|
+
if (!isStationSeparatorAdded) {
|
|
248
|
+
isStationSeparatorAdded = true;
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
isStationSeparatorAdded = false;
|
|
252
|
+
}
|
|
253
|
+
else if (skipCodes.findIndex((ref) => ref === charCode) !== -1) {
|
|
254
|
+
// ignore any codes in skipCodes
|
|
230
255
|
continue;
|
|
256
|
+
}
|
|
231
257
|
if (signToken.length > 0) {
|
|
232
258
|
wipToken = signToken + wipToken;
|
|
233
259
|
signToken = "";
|
|
@@ -235,12 +261,24 @@ class Parser {
|
|
|
235
261
|
tokens.push(new ParseToken(parseFloat(wipToken)));
|
|
236
262
|
wipToken = (i < str.length) ? str[i] : "";
|
|
237
263
|
processingNumber = false;
|
|
264
|
+
if (wipToken.length === 1 && isOperator(wipToken)) {
|
|
265
|
+
tokens.push(new ParseToken(wipToken)); // Push operator token.
|
|
266
|
+
wipToken = "";
|
|
267
|
+
}
|
|
238
268
|
}
|
|
239
269
|
else {
|
|
240
270
|
// not processing a number
|
|
241
|
-
if ((charCode
|
|
242
|
-
if (
|
|
243
|
-
|
|
271
|
+
if (isOperator(charCode)) {
|
|
272
|
+
if (wipToken.length > 0) {
|
|
273
|
+
// There is a token is progress, process it now, before adding the new operator token.
|
|
274
|
+
tokens.push(new ParseToken(wipToken));
|
|
275
|
+
wipToken = "";
|
|
276
|
+
}
|
|
277
|
+
tokens.push(new ParseToken(str[i])); // Push an Operator Token in the list.
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
if (wipToken.length === 0 && charCode === Constants_1.QuantityConstants.CHAR_SPACE) {
|
|
281
|
+
// Dont add space when the wip token is empty.
|
|
244
282
|
continue;
|
|
245
283
|
}
|
|
246
284
|
wipToken = wipToken.concat(str[i]);
|
|
@@ -261,6 +299,17 @@ class Parser {
|
|
|
261
299
|
}
|
|
262
300
|
return tokens;
|
|
263
301
|
}
|
|
302
|
+
static isMathematicOperation(tokens) {
|
|
303
|
+
if (tokens.length > 1) {
|
|
304
|
+
// The loop starts at one because the first token can be a operator without it being maths. Ex: "-5FT"
|
|
305
|
+
for (let i = 1; i < tokens.length; i++) {
|
|
306
|
+
if (tokens[i].isOperator)
|
|
307
|
+
// Operator found, it's a math operation.
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
264
313
|
static async lookupUnitByLabel(unitLabel, format, unitsProvider, altUnitLabelsProvider) {
|
|
265
314
|
const defaultUnit = format.units && format.units.length > 0 ? format.units[0][0] : undefined;
|
|
266
315
|
const labelToFind = unitLabel.toLowerCase();
|
|
@@ -285,69 +334,53 @@ class Parser {
|
|
|
285
334
|
foundUnit = await unitsProvider.findUnit(unitLabel, defaultUnit ? defaultUnit.phenomenon : undefined);
|
|
286
335
|
return foundUnit;
|
|
287
336
|
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
337
|
+
/**
|
|
338
|
+
* Get the output unit and all the conversion specs required to parse a given list of tokens.
|
|
339
|
+
*/
|
|
340
|
+
static async getRequiredUnitsConversionsToParseTokens(tokens, format, unitsProvider, altUnitLabelsProvider) {
|
|
341
|
+
let outUnit = (format.units && format.units.length > 0 ? format.units[0][0] : undefined);
|
|
342
|
+
const unitConversions = [];
|
|
343
|
+
const uniqueUnitLabels = [...new Set(tokens.filter((token) => token.isString).map((token) => token.value))];
|
|
344
|
+
for (const label of uniqueUnitLabels) {
|
|
345
|
+
const unitProps = await this.lookupUnitByLabel(label, format, unitsProvider, altUnitLabelsProvider);
|
|
346
|
+
if (!outUnit) {
|
|
347
|
+
// No default unit, assume that the first unit found is the desired output unit.
|
|
348
|
+
outUnit = unitProps;
|
|
294
349
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
350
|
+
let spec = unitConversions.find((specB) => specB.name === unitProps.name);
|
|
351
|
+
if (spec) {
|
|
352
|
+
// Already in the list, just add the label.
|
|
353
|
+
spec.parseLabels?.push(label.toLocaleLowerCase());
|
|
298
354
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
return new Quantity_1.Quantity(defaultUnit, tokens[0].value);
|
|
312
|
-
}
|
|
313
|
-
else if (defaultUnit) {
|
|
314
|
-
const conversion = await unitsProvider.getConversion(unit, defaultUnit);
|
|
315
|
-
const mag = ((tokens[0].value * conversion.factor)) + conversion.offset;
|
|
316
|
-
return new Quantity_1.Quantity(defaultUnit, mag);
|
|
355
|
+
else {
|
|
356
|
+
// Add new conversion to the list.
|
|
357
|
+
const conversion = await unitsProvider.getConversion(unitProps, outUnit);
|
|
358
|
+
if (conversion) {
|
|
359
|
+
spec = {
|
|
360
|
+
conversion,
|
|
361
|
+
label: unitProps.label,
|
|
362
|
+
system: unitProps.system,
|
|
363
|
+
name: unitProps.name,
|
|
364
|
+
parseLabels: [label.toLocaleLowerCase()],
|
|
365
|
+
};
|
|
366
|
+
unitConversions.push(spec);
|
|
317
367
|
}
|
|
318
368
|
}
|
|
319
369
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
mag = value;
|
|
332
|
-
else {
|
|
333
|
-
const conversion = await unitsProvider.getConversion(unit, defaultUnit);
|
|
334
|
-
mag = ((value * conversion.factor)) + conversion.offset;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
else {
|
|
338
|
-
if (defaultUnit) {
|
|
339
|
-
const conversion = await unitsProvider.getConversion(unit, defaultUnit);
|
|
340
|
-
if (mag < 0.0)
|
|
341
|
-
mag = mag - ((value * conversion.factor)) + conversion.offset;
|
|
342
|
-
else
|
|
343
|
-
mag = mag + ((value * conversion.factor)) + conversion.offset;
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
}
|
|
370
|
+
return { outUnit, specs: unitConversions };
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Get the units information asynchronously, then convert the tokens into quantity using the synchronous tokens -> value.
|
|
374
|
+
*/
|
|
375
|
+
static async createQuantityFromParseTokens(tokens, format, unitsProvider, altUnitLabelsProvider) {
|
|
376
|
+
const unitConversionInfos = await this.getRequiredUnitsConversionsToParseTokens(tokens, format, unitsProvider, altUnitLabelsProvider);
|
|
377
|
+
if (unitConversionInfos.outUnit) {
|
|
378
|
+
const value = Parser.getQuantityValueFromParseTokens(tokens, format, unitConversionInfos.specs, await unitsProvider.getConversion(unitConversionInfos.outUnit, unitConversionInfos.outUnit));
|
|
379
|
+
if (value.ok) {
|
|
380
|
+
return new Quantity_1.Quantity(unitConversionInfos.outUnit, value.value);
|
|
347
381
|
}
|
|
348
|
-
return new Quantity_1.Quantity(defaultUnit, mag);
|
|
349
382
|
}
|
|
350
|
-
return new Quantity_1.Quantity(
|
|
383
|
+
return new Quantity_1.Quantity();
|
|
351
384
|
}
|
|
352
385
|
/** Async method to generate a Quantity given a string that represents a quantity value and likely a unit label.
|
|
353
386
|
* @param inString A string that contains text represent a quantity.
|
|
@@ -356,7 +389,7 @@ class Parser {
|
|
|
356
389
|
*/
|
|
357
390
|
static async parseIntoQuantity(inString, format, unitsProvider, altUnitLabelsProvider) {
|
|
358
391
|
const tokens = Parser.parseQuantitySpecification(inString, format);
|
|
359
|
-
if (tokens.length === 0)
|
|
392
|
+
if (tokens.length === 0 || (!format.allowMathematicOperations && Parser.isMathematicOperation(tokens)))
|
|
360
393
|
return new Quantity_1.Quantity();
|
|
361
394
|
return Parser.createQuantityFromParseTokens(tokens, format, unitsProvider, altUnitLabelsProvider);
|
|
362
395
|
}
|
|
@@ -399,75 +432,106 @@ class Parser {
|
|
|
399
432
|
}
|
|
400
433
|
return undefined;
|
|
401
434
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
435
|
+
/**
|
|
436
|
+
* Get what the unit conversion is for a unitless value.
|
|
437
|
+
*/
|
|
438
|
+
static getDefaultUnitConversion(tokens, unitsConversions, defaultUnit) {
|
|
439
|
+
let unitConversion = defaultUnit ? Parser.tryFindUnitConversion(defaultUnit.label, unitsConversions, defaultUnit) : undefined;
|
|
440
|
+
if (!unitConversion) {
|
|
441
|
+
// No default unit conversion, take the first valid unit.
|
|
442
|
+
const uniqueUnitLabels = [...new Set(tokens.filter((token) => token.isString).map((token) => token.value))];
|
|
443
|
+
for (const label of uniqueUnitLabels) {
|
|
444
|
+
unitConversion = Parser.tryFindUnitConversion(label, unitsConversions, defaultUnit);
|
|
445
|
+
if (unitConversion !== undefined)
|
|
446
|
+
return unitConversion;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
return unitConversion;
|
|
450
|
+
}
|
|
451
|
+
// Get the next token pair to parse into a quantity.
|
|
452
|
+
static getNextTokenPair(index, tokens) {
|
|
453
|
+
if (index >= tokens.length)
|
|
454
|
+
return;
|
|
455
|
+
// 6 possible combination of token pair.
|
|
456
|
+
// Stringified to ease comparison later.
|
|
457
|
+
const validCombinations = [
|
|
458
|
+
JSON.stringify(["string"]), // ['FT']
|
|
459
|
+
JSON.stringify(["string", "number"]), // ['$', 5] unit specification comes before value (like currency)
|
|
460
|
+
JSON.stringify(["number"]), // [5]
|
|
461
|
+
JSON.stringify(["number", "string"]), // [5, 'FT']
|
|
462
|
+
JSON.stringify(["operator", "number"]), // ['-', 5]
|
|
463
|
+
JSON.stringify(["operator", "number", "string"]), // ['-', 5, 'FT']
|
|
464
|
+
];
|
|
465
|
+
// Push up to 3 tokens in the list, if the length allows it.
|
|
466
|
+
const maxNbrTokensInThePair = Math.min(tokens.length - index, 3);
|
|
467
|
+
const tokenPair = tokens.slice(index, index + maxNbrTokensInThePair);
|
|
468
|
+
const currentCombination = tokenPair.map((token) => token.isOperator ? "operator" : (token.isNumber ? "number" : "string"));
|
|
469
|
+
// Check if the token pair is valid. If not, try again by removing the last token util empty.
|
|
470
|
+
// Ex: ['5', 'FT', '7'] invalid => ['5', 'FT'] valid returned
|
|
471
|
+
for (let i = currentCombination.length - 1; i >= 0; i--) {
|
|
472
|
+
if (validCombinations.includes(JSON.stringify(currentCombination))) {
|
|
473
|
+
break;
|
|
418
474
|
}
|
|
419
475
|
else {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
if (undefined !== conversion)
|
|
423
|
-
return { ok: true, value: conversion.factor + conversion.offset };
|
|
424
|
-
else
|
|
425
|
-
return { ok: false, error: ParseError.NoValueOrUnitFoundInString };
|
|
476
|
+
currentCombination.pop();
|
|
477
|
+
tokenPair.pop();
|
|
426
478
|
}
|
|
427
479
|
}
|
|
428
|
-
|
|
429
|
-
|
|
480
|
+
return tokenPair.length > 0 ? tokenPair : undefined;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Accumulate the given list of tokens into a single quantity value. Formatting the tokens along the way.
|
|
484
|
+
*/
|
|
485
|
+
static getQuantityValueFromParseTokens(tokens, format, unitsConversions, defaultUnitConversion) {
|
|
486
|
+
const defaultUnit = format.units && format.units.length > 0 ? format.units[0][0] : undefined;
|
|
487
|
+
defaultUnitConversion = defaultUnitConversion ? defaultUnitConversion : Parser.getDefaultUnitConversion(tokens, unitsConversions, defaultUnit);
|
|
488
|
+
let tokenPair;
|
|
489
|
+
let increment = 1;
|
|
490
|
+
let mag = 0.0;
|
|
491
|
+
// The sign is saved outside from the loop for cases like this. '-1m 50cm 10mm + 2m 30cm 40mm' => -1.51m + 2.34m
|
|
492
|
+
let sign = 1;
|
|
493
|
+
for (let i = 0; i < tokens.length; i = i + increment) {
|
|
494
|
+
tokenPair = this.getNextTokenPair(i, tokens);
|
|
495
|
+
if (!tokenPair || tokenPair.length === 0) {
|
|
496
|
+
return { ok: false, error: ParseError.UnableToConvertParseTokensToQuantity };
|
|
497
|
+
}
|
|
498
|
+
increment = tokenPair.length;
|
|
499
|
+
// Keep the sign so its applied to the next tokens.
|
|
500
|
+
if (tokenPair[0].isOperator) {
|
|
501
|
+
sign = tokenPair[0].value === Operator.addition ? 1 : -1;
|
|
502
|
+
tokenPair.shift();
|
|
503
|
+
}
|
|
430
504
|
// unit specification comes before value (like currency)
|
|
431
|
-
if (
|
|
432
|
-
|
|
505
|
+
if (tokenPair.length === 2 && tokenPair[0].isString) {
|
|
506
|
+
// Invert it so the currency sign comes second.
|
|
507
|
+
tokenPair = [tokenPair[1], tokenPair[0]];
|
|
433
508
|
}
|
|
434
|
-
if (
|
|
435
|
-
let
|
|
436
|
-
|
|
437
|
-
if (
|
|
438
|
-
conversion = Parser.tryFindUnitConversion(
|
|
509
|
+
if (tokenPair[0].isNumber) {
|
|
510
|
+
let value = sign * tokenPair[0].value;
|
|
511
|
+
let conversion;
|
|
512
|
+
if (tokenPair.length === 2 && tokenPair[1].isString) {
|
|
513
|
+
conversion = Parser.tryFindUnitConversion(tokenPair[1].value, unitsConversions, defaultUnit);
|
|
439
514
|
}
|
|
515
|
+
conversion = conversion ? conversion : defaultUnitConversion;
|
|
440
516
|
if (conversion) {
|
|
441
|
-
|
|
442
|
-
return { ok: true, value };
|
|
517
|
+
value = (value * conversion.factor) + conversion.offset;
|
|
443
518
|
}
|
|
444
|
-
|
|
445
|
-
return { ok: true, value: tokens[0].value };
|
|
519
|
+
mag = mag + value;
|
|
446
520
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
const value = tokens[i].value;
|
|
454
|
-
const conversion = Parser.tryFindUnitConversion(tokens[i + 1].value, unitsConversions, defaultUnit);
|
|
455
|
-
if (conversion) {
|
|
456
|
-
if (mag < 0.0)
|
|
457
|
-
mag = mag - ((value * conversion.factor)) + conversion.offset;
|
|
458
|
-
else
|
|
459
|
-
mag = mag + ((value * conversion.factor)) + conversion.offset;
|
|
460
|
-
}
|
|
521
|
+
else {
|
|
522
|
+
// only the unit label was specified so assume magnitude of 0
|
|
523
|
+
const conversion = Parser.tryFindUnitConversion(tokenPair[0].value, unitsConversions, defaultUnit);
|
|
524
|
+
if (conversion === undefined) {
|
|
525
|
+
// Unknown unit label
|
|
526
|
+
return { ok: false, error: ParseError.NoValueOrUnitFoundInString };
|
|
461
527
|
}
|
|
462
528
|
}
|
|
463
|
-
return { ok: true, value: mag };
|
|
464
529
|
}
|
|
465
|
-
return { ok:
|
|
530
|
+
return { ok: true, value: mag };
|
|
466
531
|
}
|
|
467
532
|
/** Method to generate a Quantity given a string that represents a quantity value.
|
|
468
533
|
* @param inString A string that contains text represent a quantity.
|
|
469
534
|
* @param parserSpec unit label if not explicitly defined by user. Must have matching entry in supplied array of unitsConversions.
|
|
470
|
-
* @param defaultValue default value to return if parsing is un successful
|
|
471
535
|
*/
|
|
472
536
|
static parseQuantityString(inString, parserSpec) {
|
|
473
537
|
return Parser.parseToQuantityValue(inString, parserSpec.format, parserSpec.unitConversions);
|
|
@@ -493,6 +557,9 @@ class Parser {
|
|
|
493
557
|
const tokens = Parser.parseQuantitySpecification(inString, format);
|
|
494
558
|
if (tokens.length === 0)
|
|
495
559
|
return { ok: false, error: ParseError.UnableToGenerateParseTokens };
|
|
560
|
+
if (!format.allowMathematicOperations && Parser.isMathematicOperation(tokens)) {
|
|
561
|
+
return { ok: false, error: ParseError.MathematicOperationFoundButIsNotAllowed };
|
|
562
|
+
}
|
|
496
563
|
if (Parser._log) {
|
|
497
564
|
// eslint-disable-next-line no-console
|
|
498
565
|
console.log(`Parse tokens`);
|