Skip to content

Commit c594bbe

Browse files
Refactor: HF-24 address prep-ultra polish (category, regex hoist, docs)
Address three nits surfaced by the final fresh-eyes review: - ConfigParams.ts: stringifyCurrency was filed under @category 'Date and Time' (copied from sibling stringifyDateTime/Duration), placing a currency-formatting option under the Date and Time TypeDoc nav group. Move it to @category 'Number' to match where currencySymbol already lives, so currency-related config clusters together in generated API docs. - ConfigParams.ts: expand the stringifyCurrency JSDoc to state plainly that the formatter calls the callback for every format string that reaches it, not only currency-shaped ones, and that returning undefined is the opt-out path for unsupported formats. IDE users reading the contract no longer have to infer this from the guide. - format.ts: hoist the LCID-tagged currency-guard regex into a module-level const (LCID_CURRENCY_TAG) shared by defaultStringifyDateTime and defaultStringifyDuration. Avoids re-instantiating the same RegExp on every format() call (TEXT can be invoked thousands of times per recalc), and documents at the declaration site why the pattern is intentionally unanchored — Excel does not mix date/time tokens with currency tags in a single format string, so a mid-string match cannot misclassify a legitimate composite.
1 parent e0d7af5 commit c594bbe

2 files changed

Lines changed: 22 additions & 6 deletions

File tree

src/ConfigParams.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,15 +314,16 @@ export interface ConfigParams {
314314
* Sets a function that converts numeric values into currency-formatted strings.
315315
*
316316
* The function receives the raw value and the format string passed to `TEXT`
317-
* and should return a string or `undefined`. Returning `undefined` lets the
318-
* formatter fall through to the built-in number formatter, so a callback that
319-
* recognizes only some format strings can safely opt out of the rest.
317+
* and should return a string or `undefined`. The formatter calls this for
318+
* every format string that reaches it, not only currency-shaped ones — return
319+
* `undefined` for any format your callback does not handle and HyperFormula
320+
* will fall through to the built-in number formatter.
320321
*
321322
* For more information, see the [Currency handling guide](/guide/currency-handling.md).
322323
*
323324
* @default defaultStringifyCurrency
324325
*
325-
* @category Date and Time
326+
* @category Number
326327
*/
327328
stringifyCurrency: (value: number, currencyFormat: string) => Maybe<string>,
328329
/**

src/format/format.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,21 @@ import {RawScalarValue} from '../interpreter/InterpreterValue'
1010
import {Maybe} from '../Maybe'
1111
import {FormatToken, parseForDateTimeFormat, parseForNumberFormat, TokenType} from './parser'
1212

13+
/**
14+
* Detects Excel LCID-tagged currency tags (`[$SYMBOL-LCID]` with a non-empty
15+
* SYMBOL portion). Shared by `defaultStringifyDateTime` and
16+
* `defaultStringifyDuration` so a format string carrying such a tag short-
17+
* circuits both date and duration dispatch and falls through to the
18+
* number formatter (or the user-supplied `stringifyCurrency` callback).
19+
*
20+
* The pattern is intentionally unanchored: any occurrence of `[$SYMBOL-`
21+
* in the format string triggers the guard. Excel does not mix date/time
22+
* tokens with a currency tag in the same format string, so a mid-string
23+
* match cannot misclassify a legitimate composite — every observed
24+
* format string with a currency tag is currency-only.
25+
*/
26+
const LCID_CURRENCY_TAG = /\[\$[^\-\]]+-/
27+
1328
export function format(value: number, formatArg: string, config: Config, dateHelper: DateTimeHelper): RawScalarValue {
1429
// Currency callback runs first so a user-supplied stringifyCurrency can
1530
// intercept LCID-tagged or bare-letter currency formats before the
@@ -100,7 +115,7 @@ export function defaultStringifyDuration(time: SimpleTime, formatArg: string): M
100115
// (H in CHF/HUF, m in AMD/HMD) that parseForDateTimeFormat would
101116
// otherwise interpret as time tokens. See defaultStringifyDateTime
102117
// for the symbol-vs-locale-modifier rationale.
103-
if (/\[\$[^\-\]]+-/.test(formatArg)) {
118+
if (LCID_CURRENCY_TAG.test(formatArg)) {
104119
return undefined
105120
}
106121
const expression = parseForDateTimeFormat(formatArg)
@@ -176,7 +191,7 @@ export function defaultStringifyDateTime(dateTime: SimpleDateTime, formatArg: st
176191
// and the `-` to distinguish currency tags (`[$USD-409]`, `[$€-2]`) from
177192
// Excel's locale-only modifier (`[$-409]`, `[$-F800]`), which is valid
178193
// on date/time formats and must continue to flow through this function.
179-
if (/\[\$[^\-\]]+-/.test(formatArg)) {
194+
if (LCID_CURRENCY_TAG.test(formatArg)) {
180195
return undefined
181196
}
182197
const expression = parseForDateTimeFormat(formatArg)

0 commit comments

Comments
 (0)