From e07b3d266963bb9ce9ed11d6258ec9a52bd82c54 Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Tue, 9 Jun 2026 10:25:57 +0000 Subject: [PATCH 01/35] feat(metadata): add function description types (HF-249) --- .../functionMetadata/FunctionDescription.ts | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 src/interpreter/functionMetadata/FunctionDescription.ts diff --git a/src/interpreter/functionMetadata/FunctionDescription.ts b/src/interpreter/functionMetadata/FunctionDescription.ts new file mode 100644 index 000000000..ff12f13bf --- /dev/null +++ b/src/interpreter/functionMetadata/FunctionDescription.ts @@ -0,0 +1,86 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +/** + * The function categories, matching the `### ` headers in `docs/guide/built-in-functions.md`. + */ +export const FUNCTION_CATEGORIES = [ + 'Array manipulation', 'Database', 'Date and time', 'Engineering', + 'Information', 'Financial', 'Logical', 'Lookup and reference', + 'Math and trigonometry', 'Matrix functions', 'Operator', 'Statistical', 'Text', +] as const + +/** + * Language-independent function category identifier. + */ +export type FunctionCategory = typeof FUNCTION_CATEGORIES[number] + +/** + * Storage: authored, human-readable metadata for one function parameter. + */ +export interface ParameterDoc { + /** Display name as shown in the syntax, Google-Sheets style, e.g. `'Factor1'`. */ + name: string, + /** What the argument does. Present but empty (`''`) in the MVP; authored in a later phase. */ + description: string, +} + +/** + * Storage: authored metadata for one canonical function. English in the MVP. + */ +export interface FunctionDoc { + category: FunctionCategory, + /** One-liner, sentence-case description. English in the MVP. (A separate long description may follow later.) */ + shortDescription: string, + /** Ordered; length MUST equal the function's `implementedFunctions.parameters` length (implementation arity). */ + parameters: ParameterDoc[], +} + +/** + * Public: a single entry of the short function list returned by `getAvailableFunctions`. + */ +export interface FunctionListEntry { + /** Function name, translated for the active language. */ + name: string, + /** Language-independent function id, e.g. `'SUMIF'`. */ + canonicalName: string, + category: FunctionCategory, + /** One-liner description (English in the MVP). */ + shortDescription: string, +} + +/** + * Public: a single parameter of a function's full details returned by `getFunctionDetails`. + */ +export interface FunctionParameterDescription { + /** Human-readable parameter name. */ + name: string, + /** What the argument does. Present but empty (`''`) in the MVP; populated in a later phase. */ + description: string, + /** `true` when the argument may be omitted. */ + optional: boolean, + /** `true` for the last `repeatLastArgs` parameters. */ + repeatable: boolean, +} + +/** + * Public: the full details for one function returned by `getFunctionDetails`. + */ +export interface FunctionDetails { + /** Function name, translated for the active language. */ + name: string, + /** Language-independent function id, e.g. `'SUMIF'`. */ + canonicalName: string, + category: FunctionCategory, + /** One-liner description (English in the MVP). */ + shortDescription: string, + /** Generated from the parameter names, optionality and `repeatLastArgs`. */ + syntax: string, + parameters: FunctionParameterDescription[], + /** Link to the function's documentation. Present but empty (`''`) in the MVP; populated in a later phase. */ + documentationUrl: string, + /** Usage examples. Present but empty (`[]`) in the MVP; populated in a later phase. */ + examples: string[], +} From 25130c2477476fcb3167b28687ee7ff52b7e33a5 Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Tue, 9 Jun 2026 10:48:35 +0000 Subject: [PATCH 02/35] feat(metadata): add canonical function id helper (HF-249) --- .../buildFunctionDescriptions.ts | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/interpreter/functionMetadata/buildFunctionDescriptions.ts diff --git a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts new file mode 100644 index 000000000..c96d17ed9 --- /dev/null +++ b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts @@ -0,0 +1,23 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +import {FunctionPluginDefinition} from '../plugin/FunctionPlugin' + +/** + * Returns the canonical function id set: the union of every plugin's `implementedFunctions` keys. + * + * Aliases (kept in a separate `plugin.aliases` map) and protected ids (e.g. `VERSION`, `OFFSET`, registered + * outside the regular plugin set) are excluded by construction. Operators such as `HF.ADD` are included because + * they live in an arithmetic plugin's `implementedFunctions`. + * + * @param {FunctionPluginDefinition[]} plugins - registered function plugins, e.g. from `FunctionRegistry.getPlugins()` + */ +export function getCanonicalFunctionIds(plugins: FunctionPluginDefinition[]): string[] { + const ids = new Set() + plugins.forEach(plugin => { + Object.keys(plugin.implementedFunctions).forEach(id => ids.add(id)) + }) + return Array.from(ids) +} From cdb89aa2c675a5b9b753c00f88a4bc0738945964 Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Tue, 9 Jun 2026 10:50:09 +0000 Subject: [PATCH 03/35] feat(metadata): generate function syntax from parameters (HF-249) --- .../buildFunctionDescriptions.ts | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts index c96d17ed9..73c44b6f0 100644 --- a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts +++ b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts @@ -3,7 +3,10 @@ * Copyright (c) 2025 Handsoncode. All rights reserved. */ -import {FunctionPluginDefinition} from '../plugin/FunctionPlugin' +import {FunctionPluginDefinition, FunctionMetadata, FunctionArgument} from '../plugin/FunctionPlugin' + +/** The structural subset of `FunctionMetadata` the builders read (so callers/tests need not supply `method`). */ +export type StructuralMetadata = Pick /** * Returns the canonical function id set: the union of every plugin's `implementedFunctions` keys. @@ -21,3 +24,27 @@ export function getCanonicalFunctionIds(plugins: FunctionPluginDefinition[]): st }) return Array.from(ids) } + +/** + * Returns whether a parameter may be omitted: it declares `optionalArg`, or it has a `defaultValue`. + * + * @param {FunctionArgument | undefined} arg - the structural argument metadata, or `undefined` + */ +export function isParameterOptional(arg: FunctionArgument | undefined): boolean { + return arg?.optionalArg === true || arg?.defaultValue !== undefined +} + +/** + * Builds the display syntax string from parameter names and structural metadata. Required parameters are rendered + * bare, optional ones in brackets, and a trailing `, ...` is appended when the last `repeatLastArgs` parameters repeat. + * + * @param {string} displayName - the function name to show (the translated name in the active language) + * @param {string[]} parameterNames - authored parameter names, index-aligned with `metadata.parameters` + * @param {StructuralMetadata} metadata - structural metadata (`parameters` + `repeatLastArgs`) from `implementedFunctions` + */ +export function generateSyntax(displayName: string, parameterNames: string[], metadata: StructuralMetadata): string { + const args = metadata.parameters ?? [] + const rendered = parameterNames.map((name, index) => isParameterOptional(args[index]) ? `[${name}]` : name) + const repeatSuffix = (metadata.repeatLastArgs ?? 0) > 0 ? ', ...' : '' + return `${displayName}(${rendered.join(', ')}${repeatSuffix})` +} From 2b4c625043e7c30200a64c445d25123300e875be Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Tue, 9 Jun 2026 10:51:52 +0000 Subject: [PATCH 04/35] feat(metadata): add list/details merge builders (HF-249) --- .../buildFunctionDescriptions.ts | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts index 73c44b6f0..44956849a 100644 --- a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts +++ b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts @@ -4,6 +4,10 @@ */ import {FunctionPluginDefinition, FunctionMetadata, FunctionArgument} from '../plugin/FunctionPlugin' +import {FunctionDoc, FunctionListEntry, FunctionDetails, FunctionParameterDescription} from './FunctionDescription' + +/** Resolves a function's display name: the translation for the active language, or the canonical id as fallback. */ +type TranslateName = (canonicalName: string) => string | undefined /** The structural subset of `FunctionMetadata` the builders read (so callers/tests need not supply `method`). */ export type StructuralMetadata = Pick @@ -48,3 +52,61 @@ export function generateSyntax(displayName: string, parameterNames: string[], me const repeatSuffix = (metadata.repeatLastArgs ?? 0) > 0 ? ', ...' : '' return `${displayName}(${rendered.join(', ')}${repeatSuffix})` } + +/** + * Resolves the display name for a function: the translated name, or the canonical id when no translation exists. + * + * @param {string} canonicalName - the language-independent function id + * @param {TranslateName} translate - per-id translation lookup (returns `undefined` when untranslated) + */ +function resolveName(canonicalName: string, translate: TranslateName): string { + return translate(canonicalName) ?? canonicalName +} + +/** + * Builds a Tier-1 list entry by joining the catalogue doc with the translation on the canonical id. + * + * @param {string} canonicalName - the language-independent function id + * @param {FunctionDoc} doc - the function's authored catalogue entry + * @param {TranslateName} translate - per-id translation lookup + */ +export function buildFunctionListEntry(canonicalName: string, doc: FunctionDoc, translate: TranslateName): FunctionListEntry { + return { + name: resolveName(canonicalName, translate), + canonicalName, + category: doc.category, + shortDescription: doc.shortDescription, + } +} + +/** + * Builds a Tier-2 details object: the list fields plus generated syntax and per-parameter optionality/repeatability. + * `documentationUrl`, `examples` and each parameter `description` are present but empty in the MVP. + * + * @param {string} canonicalName - the language-independent function id + * @param {FunctionDoc} doc - the function's authored catalogue entry + * @param {StructuralMetadata} metadata - structural metadata from `implementedFunctions` + * @param {TranslateName} translate - per-id translation lookup + */ +export function buildFunctionDetails(canonicalName: string, doc: FunctionDoc, metadata: StructuralMetadata, translate: TranslateName): FunctionDetails { + const name = resolveName(canonicalName, translate) + const args = metadata.parameters ?? [] + const repeatLastArgs = metadata.repeatLastArgs ?? 0 + const firstRepeatableIndex = doc.parameters.length - repeatLastArgs + const parameters: FunctionParameterDescription[] = doc.parameters.map((param, index) => ({ + name: param.name, + description: param.description, + optional: isParameterOptional(args[index]), + repeatable: repeatLastArgs > 0 && index >= firstRepeatableIndex, + })) + return { + name, + canonicalName, + category: doc.category, + shortDescription: doc.shortDescription, + syntax: generateSyntax(name, doc.parameters.map(parameter => parameter.name), metadata), + parameters, + documentationUrl: '', + examples: [], + } +} From 6e7c50f0d375f5f64b46b7bb7451c169ed3e3ef7 Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Tue, 9 Jun 2026 10:53:36 +0000 Subject: [PATCH 05/35] feat(metadata): compose FUNCTION_DOCS with seed categories (HF-249) --- .../functionMetadata/categories/logical.ts | 17 ++++++++++++ .../categories/math-and-trigonometry.ts | 27 +++++++++++++++++++ src/interpreter/functionMetadata/index.ts | 19 +++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 src/interpreter/functionMetadata/categories/logical.ts create mode 100644 src/interpreter/functionMetadata/categories/math-and-trigonometry.ts create mode 100644 src/interpreter/functionMetadata/index.ts diff --git a/src/interpreter/functionMetadata/categories/logical.ts b/src/interpreter/functionMetadata/categories/logical.ts new file mode 100644 index 000000000..4f422a686 --- /dev/null +++ b/src/interpreter/functionMetadata/categories/logical.ts @@ -0,0 +1,17 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +import {FunctionDoc} from '../FunctionDescription' + +/** + * Catalogue entries for the "Logical" category. Seeded subset; completed by the migration. + */ +export const LOGICAL_DOCS: Record = { + IFS: { + category: 'Logical', + shortDescription: 'Checks one or more conditions and returns the value for the first that is met.', + parameters: [{name: 'Condition1', description: ''}, {name: 'Value1', description: ''}], + }, +} diff --git a/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts b/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts new file mode 100644 index 000000000..63bd7eea2 --- /dev/null +++ b/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts @@ -0,0 +1,27 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +import {FunctionDoc} from '../FunctionDescription' + +/** + * Catalogue entries for the "Math and trigonometry" category. Seeded subset; completed by the migration. + */ +export const MATH_AND_TRIGONOMETRY_DOCS: Record = { + SUMIF: { + category: 'Math and trigonometry', + shortDescription: 'Sums the cells that meet a criterion.', + parameters: [{name: 'Range', description: ''}, {name: 'Criterion', description: ''}, {name: 'SumRange', description: ''}], + }, + SUM: { + category: 'Math and trigonometry', + shortDescription: 'Sums a series of numbers or cells.', + parameters: [{name: 'Number1', description: ''}], + }, + PI: { + category: 'Math and trigonometry', + shortDescription: 'Returns the value of pi.', + parameters: [], + }, +} diff --git a/src/interpreter/functionMetadata/index.ts b/src/interpreter/functionMetadata/index.ts new file mode 100644 index 000000000..6faacbc6f --- /dev/null +++ b/src/interpreter/functionMetadata/index.ts @@ -0,0 +1,19 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +import {FunctionDoc} from './FunctionDescription' +import {MATH_AND_TRIGONOMETRY_DOCS} from './categories/math-and-trigonometry' +import {LOGICAL_DOCS} from './categories/logical' + +export * from './FunctionDescription' + +/** + * Canonical-id-keyed catalogue of human-readable function metadata, composed from the per-category files. + * Coverage of the whole canonical set is enforced by test, not by convention. + */ +export const FUNCTION_DOCS: Record = { + ...MATH_AND_TRIGONOMETRY_DOCS, + ...LOGICAL_DOCS, +} From bcc39efb446b9f938ce2e0ce539ff0f07903876e Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Tue, 9 Jun 2026 11:40:57 +0000 Subject: [PATCH 06/35] feat(metadata): expose getAvailableFunctions/getFunctionDetails public API (HF-249) Add static and instance getAvailableFunctions and getFunctionDetails to HyperFormula, backed by the function metadata catalogue. Instance methods delegate to the static ones using the configured language. Re-export the public catalogue types from the package entry point. --- src/HyperFormula.ts | 111 ++++++++++++++++++++++++++++++++++++++++++++ src/index.ts | 5 ++ 2 files changed, 116 insertions(+) diff --git a/src/HyperFormula.ts b/src/HyperFormula.ts index 566957270..c2dcd7daa 100644 --- a/src/HyperFormula.ts +++ b/src/HyperFormula.ts @@ -45,6 +45,9 @@ import {ExportedChange, Exporter} from './Exporter' import {LicenseKeyValidityState} from './helpers/licenseKeyValidator' import {buildTranslationPackage, RawTranslationPackage, TranslationPackage} from './i18n' import {FunctionPluginDefinition} from './interpreter' +import {FUNCTION_DOCS} from './interpreter/functionMetadata' +import {buildFunctionDetails, buildFunctionListEntry, getCanonicalFunctionIds} from './interpreter/functionMetadata/buildFunctionDescriptions' +import {FunctionDetails, FunctionListEntry} from './interpreter/functionMetadata/FunctionDescription' import {FunctionRegistry, FunctionTranslationsPackage} from './interpreter/FunctionRegistry' import {FormatInfo} from './interpreter/InterpreterValue' import {LazilyTransformingAstService} from './LazilyTransformingAstService' @@ -649,6 +652,69 @@ export class HyperFormula implements TypedEmitter { return FunctionRegistry.getPlugins() } + /** + * Returns metadata of all built-in functions available for a given language, as a short list suitable for a function + * picker. Each entry contains the translated name, the language-independent canonical name, the category, and a short + * description. + * + * Only documented built-in functions are listed; custom (user-registered) functions are not included. The list is + * sorted by category, then by canonical name. + * + * @param {string} code - language code, e.g. `'enGB'` + * + * @throws [[ExpectedValueOfTypeError]] if any of its basic type argument is of wrong type + * @throws [[LanguageNotRegisteredError]] when the given language is not registered + * + * @example + * ```js + * // get the list of available functions, translated for enGB + * const functions = HyperFormula.getAvailableFunctions('enGB'); + * ``` + * + * @category Static Methods + */ + public static getAvailableFunctions(code: string): FunctionListEntry[] { + validateArgToType(code, 'string', 'code') + const language = this.getLanguage(code) + const translate = (id: string) => language.getMaybeFunctionTranslation(id) + return getCanonicalFunctionIds(FunctionRegistry.getPlugins()) + .filter(id => FUNCTION_DOCS[id] !== undefined) + .map(id => buildFunctionListEntry(id, FUNCTION_DOCS[id], translate)) + .sort((a, b) => a.category === b.category ? a.canonicalName.localeCompare(b.canonicalName) : a.category.localeCompare(b.category)) + } + + /** + * Returns the full metadata of a single built-in function for a given language, including the generated syntax and + * per-parameter optionality and repeatability. Returns `undefined` when the function id is unknown or has no + * documentation (e.g. a custom function). + * + * @param {string} canonicalName - the language-independent function id, e.g. `'SUMIF'` + * @param {string} code - language code, e.g. `'enGB'` + * + * @throws [[ExpectedValueOfTypeError]] if any of its basic type argument is of wrong type + * @throws [[LanguageNotRegisteredError]] when the given language is not registered + * + * @example + * ```js + * // get the details of the SUMIF function, translated for enGB + * const details = HyperFormula.getFunctionDetails('SUMIF', 'enGB'); + * ``` + * + * @category Static Methods + */ + public static getFunctionDetails(canonicalName: string, code: string): FunctionDetails | undefined { + validateArgToType(canonicalName, 'string', 'canonicalName') + validateArgToType(code, 'string', 'code') + const doc = FUNCTION_DOCS[canonicalName] + const plugin = FunctionRegistry.getFunctionPlugin(canonicalName) + if (doc === undefined || plugin === undefined) { + return undefined + } + const language = this.getLanguage(code) + const translate = (id: string) => language.getMaybeFunctionTranslation(id) + return buildFunctionDetails(canonicalName, doc, plugin.implementedFunctions[canonicalName], translate) + } + /** * @internal */ @@ -4358,6 +4424,51 @@ export class HyperFormula implements TypedEmitter { return this._functionRegistry.getPlugins() } + /** + * Returns metadata of all built-in functions available for a function picker, with names translated according to the + * language set in this instance's configuration. Each entry contains the translated name, the language-independent + * canonical name, the category, and a short description. + * + * Only documented built-in functions are listed; custom (user-registered) functions are not included. The list is + * sorted by category, then by canonical name. + * + * @example + * ```js + * const hfInstance = HyperFormula.buildEmpty(); + * + * // get the list of available functions, translated for the configured language + * const functions = hfInstance.getAvailableFunctions(); + * ``` + * + * @category Custom Functions + */ + public getAvailableFunctions(): FunctionListEntry[] { + return HyperFormula.getAvailableFunctions(this._config.language) + } + + /** + * Returns the full metadata of a single built-in function, with names translated according to the language set in + * this instance's configuration, including the generated syntax and per-parameter optionality and repeatability. + * Returns `undefined` when the function id is unknown or has no documentation (e.g. a custom function). + * + * @param {string} canonicalName - the language-independent function id, e.g. `'SUMIF'` + * + * @throws [[ExpectedValueOfTypeError]] if any of its basic type argument is of wrong type + * + * @example + * ```js + * const hfInstance = HyperFormula.buildEmpty(); + * + * // get the details of the SUMIF function, translated for the configured language + * const details = hfInstance.getFunctionDetails('SUMIF'); + * ``` + * + * @category Custom Functions + */ + public getFunctionDetails(canonicalName: string): FunctionDetails | undefined { + return HyperFormula.getFunctionDetails(canonicalName, this._config.language) + } + /** * Interprets number as a date + time. * diff --git a/src/index.ts b/src/index.ts index 4039d4a20..23b060cf4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -49,6 +49,7 @@ import {HyperFormula} from './HyperFormula' import {RawTranslationPackage} from './i18n' import enGB from './i18n/languages/enGB' import {FunctionArgument, FunctionPlugin, FunctionPluginDefinition, FunctionArgumentType, ImplementedFunctions, FunctionMetadata, EmptyValue} from './interpreter' +import {FunctionCategory, FunctionDetails, FunctionListEntry, FunctionParameterDescription} from './interpreter/functionMetadata/FunctionDescription' import {FormatInfo} from './interpreter/InterpreterValue' import * as plugins from './interpreter/plugin' import {SimpleRangeValue} from './SimpleRangeValue' @@ -138,6 +139,10 @@ export { RawTranslationPackage, FunctionPluginDefinition, FunctionArgument, + FunctionListEntry, + FunctionDetails, + FunctionParameterDescription, + FunctionCategory, NamedExpression, NamedExpressionOptions, HyperFormula, From ba34e55c5f2349012c6954d2ac1c16a5afbafcdf Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Tue, 9 Jun 2026 12:21:44 +0000 Subject: [PATCH 07/35] feat(metadata): migrate full 363-function catalogue from docs (HF-249) Replace the seeded catalogue with all 363 canonical built-ins, generated from docs/guide/built-in-functions.md by scripts/hf249-migrate-function-docs.ts (dev-only, not shipped). Parameter names come from the Syntax column but their count and optionality follow the implementation arity; repeating groups collapse and duplicate names are disambiguated. Also fall back to the canonical id when a language pack leaves a function name empty (e.g. SWITCH in several locales). --- scripts/hf249-migrate-function-docs.ts | 234 +++++++++ .../buildFunctionDescriptions.ts | 7 +- .../categories/array-manipulation.ts | 33 ++ .../functionMetadata/categories/database.ts | 73 +++ .../categories/date-and-time.ts | 143 ++++++ .../categories/engineering.ts | 243 ++++++++++ .../functionMetadata/categories/financial.ts | 153 ++++++ .../categories/information.ts | 93 ++++ .../functionMetadata/categories/logical.ts | 55 ++- .../categories/lookup-and-reference.ts | 78 +++ .../categories/math-and-trigonometry.ts | 365 +++++++++++++- .../categories/matrix-functions.ts | 33 ++ .../functionMetadata/categories/operator.ts | 88 ++++ .../categories/statistical.ts | 458 ++++++++++++++++++ .../functionMetadata/categories/text.ts | 143 ++++++ src/interpreter/functionMetadata/index.ts | 28 +- 16 files changed, 2213 insertions(+), 14 deletions(-) create mode 100644 scripts/hf249-migrate-function-docs.ts create mode 100644 src/interpreter/functionMetadata/categories/array-manipulation.ts create mode 100644 src/interpreter/functionMetadata/categories/database.ts create mode 100644 src/interpreter/functionMetadata/categories/date-and-time.ts create mode 100644 src/interpreter/functionMetadata/categories/engineering.ts create mode 100644 src/interpreter/functionMetadata/categories/financial.ts create mode 100644 src/interpreter/functionMetadata/categories/information.ts create mode 100644 src/interpreter/functionMetadata/categories/lookup-and-reference.ts create mode 100644 src/interpreter/functionMetadata/categories/matrix-functions.ts create mode 100644 src/interpreter/functionMetadata/categories/operator.ts create mode 100644 src/interpreter/functionMetadata/categories/statistical.ts create mode 100644 src/interpreter/functionMetadata/categories/text.ts diff --git a/scripts/hf249-migrate-function-docs.ts b/scripts/hf249-migrate-function-docs.ts new file mode 100644 index 000000000..f09be0cdd --- /dev/null +++ b/scripts/hf249-migrate-function-docs.ts @@ -0,0 +1,234 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +/** + * HF-249 — function metadata migration tool (dev-only; never shipped, because `tsconfig.json` `include` + * is restricted to `["src"]`). + * + * Regenerates the per-category `FunctionDoc` catalogue files under + * `src/interpreter/functionMetadata/categories/` (and their `index.ts` barrel) from + * `docs/guide/built-in-functions.md`: + * + * - the canonical id set is taken from `implementedFunctions` (aliases and protected ids are excluded); + * - `category` and `shortDescription` come from the doc table's "Function ID" section and "Description" column; + * - parameter names come from the "Syntax" column, but their COUNT and optionality are governed by the + * implementation arity — the syntax column is only a (sometimes dirty) source of human-readable names. + * + * Run with: `npm run tsnode scripts/hf249-migrate-function-docs.ts` + */ + +import * as fs from 'fs' +import * as path from 'path' +import {HyperFormula} from '../src' +import {FUNCTION_CATEGORIES, FunctionCategory} from '../src/interpreter/functionMetadata/FunctionDescription' + +const REPO_ROOT = path.resolve(__dirname, '..') +const DOC_PATH = path.join(REPO_ROOT, 'docs/guide/built-in-functions.md') +const CATEGORIES_DIR = path.join(REPO_ROOT, 'src/interpreter/functionMetadata/categories') +const INDEX_PATH = path.join(REPO_ROOT, 'src/interpreter/functionMetadata/index.ts') + +/** Parameter names the documentation under-specifies relative to the implementation arity. */ +const PARAMETER_NAME_OVERRIDES: Record = { + 'T.TEST': ['Array1', 'Array2', 'Tails', 'Type'], +} + +interface DocRow { + category: FunctionCategory, + description: string, + syntax: string, +} + +/** Maps each documented function id to its category, description and raw syntax (first occurrence wins). */ +function parseDoc(): Map { + const markdown = fs.readFileSync(DOC_PATH, 'utf8') + const rows = new Map() + let category: FunctionCategory | null = null + for (const line of markdown.split('\n')) { + const header = /^### (.+?)\s*$/.exec(line) + if (header) { + category = (FUNCTION_CATEGORIES as readonly string[]).includes(header[1]) ? header[1] as FunctionCategory : null + continue + } + if (category && line.startsWith('|') && !/^\|\s*:?-+/.test(line)) { + const cells = line.split('|').map(cell => cell.trim()) + const id = cells[1] + if (!id || id === 'Function ID' || rows.has(id)) { + continue + } + rows.set(id, {category, description: cells[2] ?? '', syntax: cells[3] ?? ''}) + } + } + return rows +} + +/** Extracts trimmed parameter names from a syntax string, dropping optional brackets, quotes and ellipsis markers. */ +function parseSyntaxNames(syntax: string): string[] { + const open = syntax.indexOf('(') + const close = syntax.lastIndexOf(')') + if (open < 0 || close < 0) { + return [] + } + const inner = syntax.slice(open + 1, close).replace(/[[\]]/g, '') + return inner + .split(',') + .map(part => part.trim().replace(/^"|"$/g, '').replace(/^\.+/, '').trim()) + .filter(part => part.length > 0) +} + +/** Disambiguates repeated names (e.g. `[Number, Number]` -> `[Number1, Number2]`) so every name is unique. */ +function uniquify(names: string[]): string[] { + const totals: Record = {} + for (const name of names) { + totals[name] = (totals[name] ?? 0) + 1 + } + const seen: Record = {} + return names.map(name => { + if (totals[name] > 1) { + seen[name] = (seen[name] ?? 0) + 1 + return `${name}${seen[name]}` + } + return name + }) +} + +/** + * Produces exactly `arity` unique, non-empty parameter names. The syntax column lists `Name1, Name2, ...NameN` + * for repeating groups, so the first `arity` names already collapse those groups onto the implementation arity. + */ +function deriveParameterNames(id: string, syntax: string, arity: number): string[] { + const override = PARAMETER_NAME_OVERRIDES[id] + if (override !== undefined) { + if (override.length !== arity) { + throw new Error(`Override for ${id} has ${override.length} names but the implementation arity is ${arity}`) + } + return override + } + const names = parseSyntaxNames(syntax).slice(0, arity) + while (names.length < arity) { + names.push(`Arg${names.length + 1}`) + } + return uniquify(names) +} + +/** The category's file name, e.g. `'Math and trigonometry'` -> `'math-and-trigonometry'`. */ +function kebabCase(category: string): string { + return category.toLowerCase().replace(/\s+/g, '-') +} + +/** The category's exported constant name, e.g. `'Math and trigonometry'` -> `'MATH_AND_TRIGONOMETRY_DOCS'`. */ +function constName(category: string): string { + return `${category.toUpperCase().replace(/\s+/g, '_')}_DOCS` +} + +/** Renders a single-quoted TypeScript string literal, escaping backslashes and single quotes. */ +function asStringLiteral(value: string): string { + return `'${value.replace(/\\/g, '\\\\').replace(/'/g, '\\\'')}'` +} + +/** Renders an object key: a bare identifier where valid, otherwise a quoted string (e.g. `'HF.ADD'`). */ +function asKey(id: string): string { + return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(id) ? id : asStringLiteral(id) +} + +const LICENSE = `/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */` + +interface Entry { + id: string, + description: string, + names: string[], +} + +/** Renders the source of one `categories/.ts` file, with entries sorted by canonical id. */ +function emitCategoryFile(category: FunctionCategory, entries: Entry[]): string { + const body = [...entries].sort((a, b) => a.id.localeCompare(b.id)).map(entry => { + const params = entry.names.map(name => `{name: ${asStringLiteral(name)}, description: ''}`).join(', ') + return ` ${asKey(entry.id)}: { + category: ${asStringLiteral(category)}, + shortDescription: ${asStringLiteral(entry.description)}, + parameters: [${params}], + },` + }).join('\n') + return `${LICENSE} + +import {FunctionDoc} from '../FunctionDescription' + +/** + * Catalogue entries for the "${category}" category. Generated from \`docs/guide/built-in-functions.md\` by + * \`scripts/hf249-migrate-function-docs.ts\`; parameter descriptions are authored in a later phase. + */ +export const ${constName(category)}: Record = { +${body} +} +` +} + +/** Renders the source of the `index.ts` barrel that composes every category file into `FUNCTION_DOCS`. */ +function emitIndex(categories: FunctionCategory[]): string { + const ordered = [...categories].sort((a, b) => kebabCase(a).localeCompare(kebabCase(b))) + const imports = ordered.map(category => `import {${constName(category)}} from './categories/${kebabCase(category)}'`).join('\n') + const spreads = ordered.map(category => ` ...${constName(category)},`).join('\n') + return `${LICENSE} + +import {FunctionDoc} from './FunctionDescription' +${imports} + +export * from './FunctionDescription' + +/** + * Canonical-id-keyed catalogue of human-readable function metadata, composed from the per-category files. + * Generated by \`scripts/hf249-migrate-function-docs.ts\`. Coverage of the whole canonical set is enforced by test. + */ +export const FUNCTION_DOCS: Record = { +${spreads} +} +` +} + +/** Reads the docs and implementation arity, derives every entry, and writes the category files and barrel. */ +function main(): void { + const arityById = new Map() + for (const plugin of HyperFormula.getAllFunctionPlugins()) { + const impl = plugin.implementedFunctions + for (const id of Object.keys(impl)) { + arityById.set(id, (impl[id].parameters ?? []).length) + } + } + + const docRows = parseDoc() + const byCategory = new Map() + const missing: string[] = [] + + for (const id of arityById.keys()) { + const row = docRows.get(id) + if (row === undefined) { + missing.push(id) + continue + } + const names = deriveParameterNames(id, row.syntax, arityById.get(id) as number) + const list = byCategory.get(row.category) ?? [] + list.push({id, description: row.description, names}) + byCategory.set(row.category, list) + } + + if (missing.length > 0) { + throw new Error(`No documentation row for canonical ids: ${missing.join(', ')}`) + } + + const categories = [...byCategory.keys()] + for (const category of categories) { + const file = path.join(CATEGORIES_DIR, `${kebabCase(category)}.ts`) + fs.writeFileSync(file, emitCategoryFile(category, byCategory.get(category) as Entry[])) + console.log(`wrote ${path.relative(REPO_ROOT, file)} (${(byCategory.get(category) as Entry[]).length})`) + } + fs.writeFileSync(INDEX_PATH, emitIndex(categories)) + + const total = categories.reduce((sum, category) => sum + (byCategory.get(category) as Entry[]).length, 0) + console.log(`wrote ${path.relative(REPO_ROOT, INDEX_PATH)}; ${total} functions across ${categories.length} categories`) +} + +main() diff --git a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts index 44956849a..d3625a3cc 100644 --- a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts +++ b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts @@ -54,13 +54,16 @@ export function generateSyntax(displayName: string, parameterNames: string[], me } /** - * Resolves the display name for a function: the translated name, or the canonical id when no translation exists. + * Resolves the display name for a function: the translated name, or the canonical id when there is no usable + * translation. Some bundled language packs leave a function untranslated as an empty string (e.g. `SWITCH` in + * several locales), so an empty translation falls back to the canonical id just like a missing one. * * @param {string} canonicalName - the language-independent function id * @param {TranslateName} translate - per-id translation lookup (returns `undefined` when untranslated) */ function resolveName(canonicalName: string, translate: TranslateName): string { - return translate(canonicalName) ?? canonicalName + const translated = translate(canonicalName) + return translated === undefined || translated === '' ? canonicalName : translated } /** diff --git a/src/interpreter/functionMetadata/categories/array-manipulation.ts b/src/interpreter/functionMetadata/categories/array-manipulation.ts new file mode 100644 index 000000000..370742b8d --- /dev/null +++ b/src/interpreter/functionMetadata/categories/array-manipulation.ts @@ -0,0 +1,33 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +import {FunctionDoc} from '../FunctionDescription' + +/** + * Catalogue entries for the "Array manipulation" category. Generated from `docs/guide/built-in-functions.md` by + * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + */ +export const ARRAY_MANIPULATION_DOCS: Record = { + ARRAY_CONSTRAIN: { + category: 'Array manipulation', + shortDescription: 'Truncates an array to given dimensions.', + parameters: [{name: 'Array', description: ''}, {name: 'Height', description: ''}, {name: 'Width', description: ''}], + }, + ARRAYFORMULA: { + category: 'Array manipulation', + shortDescription: 'Enables the array arithmetic mode for a single formula.', + parameters: [{name: 'Formula', description: ''}], + }, + FILTER: { + category: 'Array manipulation', + shortDescription: 'Filters an array, based on multiple conditions (boolean arrays).', + parameters: [{name: 'SourceArray', description: ''}, {name: 'BoolArray1', description: ''}], + }, + SEQUENCE: { + category: 'Array manipulation', + shortDescription: 'Returns an array of sequential numbers.', + parameters: [{name: 'Rows', description: ''}, {name: 'Cols', description: ''}, {name: 'Start', description: ''}, {name: 'Step', description: ''}], + }, +} diff --git a/src/interpreter/functionMetadata/categories/database.ts b/src/interpreter/functionMetadata/categories/database.ts new file mode 100644 index 000000000..89949d10d --- /dev/null +++ b/src/interpreter/functionMetadata/categories/database.ts @@ -0,0 +1,73 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +import {FunctionDoc} from '../FunctionDescription' + +/** + * Catalogue entries for the "Database" category. Generated from `docs/guide/built-in-functions.md` by + * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + */ +export const DATABASE_DOCS: Record = { + DAVERAGE: { + category: 'Database', + shortDescription: 'Returns the average of all values in a database field that match the given criteria.', + parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + }, + DCOUNT: { + category: 'Database', + shortDescription: 'Counts the cells containing numbers in a database field that match the given criteria.', + parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + }, + DCOUNTA: { + category: 'Database', + shortDescription: 'Counts the non-empty cells in a database field that match the given criteria.', + parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + }, + DGET: { + category: 'Database', + shortDescription: 'Returns the single value from a database field that matches the given criteria. Returns #VALUE! if no records match, and #NUM! if more than one record matches.', + parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + }, + DMAX: { + category: 'Database', + shortDescription: 'Returns the maximum value in a database field that matches the given criteria.', + parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + }, + DMIN: { + category: 'Database', + shortDescription: 'Returns the minimum value in a database field that matches the given criteria.', + parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + }, + DPRODUCT: { + category: 'Database', + shortDescription: 'Returns the product of all values in a database field that match the given criteria.', + parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + }, + DSTDEV: { + category: 'Database', + shortDescription: 'Returns the sample standard deviation of all values in a database field that match the given criteria.', + parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + }, + DSTDEVP: { + category: 'Database', + shortDescription: 'Returns the population standard deviation of all values in a database field that match the given criteria.', + parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + }, + DSUM: { + category: 'Database', + shortDescription: 'Returns the sum of all values in a database field that match the given criteria.', + parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + }, + DVAR: { + category: 'Database', + shortDescription: 'Returns the sample variance of all values in a database field that match the given criteria.', + parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + }, + DVARP: { + category: 'Database', + shortDescription: 'Returns the population variance of all values in a database field that match the given criteria.', + parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + }, +} diff --git a/src/interpreter/functionMetadata/categories/date-and-time.ts b/src/interpreter/functionMetadata/categories/date-and-time.ts new file mode 100644 index 000000000..91a3d7c9b --- /dev/null +++ b/src/interpreter/functionMetadata/categories/date-and-time.ts @@ -0,0 +1,143 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +import {FunctionDoc} from '../FunctionDescription' + +/** + * Catalogue entries for the "Date and time" category. Generated from `docs/guide/built-in-functions.md` by + * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + */ +export const DATE_AND_TIME_DOCS: Record = { + DATE: { + category: 'Date and time', + shortDescription: 'Returns the specified date as the number of full days since [`nullDate`](../api/interfaces/configparams.md#nulldate).', + parameters: [{name: 'Year', description: ''}, {name: 'Month', description: ''}, {name: 'Day', description: ''}], + }, + DATEDIF: { + category: 'Date and time', + shortDescription: 'Calculates distance between two dates.
Supported units: "D" (days), "M" (months), "Y" (years), "MD" (days ignoring months and years), "YM" (months ignoring years), or "YD" (days ignoring years).', + parameters: [{name: 'Date1', description: ''}, {name: 'Date2', description: ''}, {name: 'Unit', description: ''}], + }, + DATEVALUE: { + category: 'Date and time', + shortDescription: 'Parses a date string and returns it as the number of full days since [`nullDate`](../api/interfaces/configparams.md#nulldate).
Accepts formats set by the [`dateFormats`](../api/interfaces/configparams.md#dateformats) option.', + parameters: [{name: 'Datestring', description: ''}], + }, + DAY: { + category: 'Date and time', + shortDescription: 'Returns the day of the given date value.', + parameters: [{name: 'Number', description: ''}], + }, + DAYS: { + category: 'Date and time', + shortDescription: 'Calculates the difference between two date values.', + parameters: [{name: 'Date2', description: ''}, {name: 'Date1', description: ''}], + }, + DAYS360: { + category: 'Date and time', + shortDescription: 'Calculates the difference between two date values in days, in 360-day basis.', + parameters: [{name: 'Date2', description: ''}, {name: 'Date1', description: ''}, {name: 'Format', description: ''}], + }, + EDATE: { + category: 'Date and time', + shortDescription: 'Shifts the given startdate by given number of months and returns it as the number of full days since [`nullDate`](../api/interfaces/configparams.md#nulldate).[^non-odff]', + parameters: [{name: 'Startdate', description: ''}, {name: 'Months', description: ''}], + }, + EOMONTH: { + category: 'Date and time', + shortDescription: 'Returns the date of the last day of a month which falls months away from the start date. Returns the value in the form of number of full days since [`nullDate`](../api/interfaces/configparams.md#nulldate).[^non-odff]', + parameters: [{name: 'Startdate', description: ''}, {name: 'Months', description: ''}], + }, + HOUR: { + category: 'Date and time', + shortDescription: 'Returns hour component of given time.', + parameters: [{name: 'Time', description: ''}], + }, + INTERVAL: { + category: 'Date and time', + shortDescription: 'Returns interval string from given number of seconds.', + parameters: [{name: 'Seconds', description: ''}], + }, + ISOWEEKNUM: { + category: 'Date and time', + shortDescription: 'Returns an ISO week number that corresponds to the week of year.', + parameters: [{name: 'Date', description: ''}], + }, + MINUTE: { + category: 'Date and time', + shortDescription: 'Returns minute component of given time.', + parameters: [{name: 'Time', description: ''}], + }, + MONTH: { + category: 'Date and time', + shortDescription: 'Returns the month for the given date value.', + parameters: [{name: 'Number', description: ''}], + }, + NETWORKDAYS: { + category: 'Date and time', + shortDescription: 'Returns the number of working days between two given dates.', + parameters: [{name: 'Date1', description: ''}, {name: 'Date2', description: ''}, {name: 'Holidays', description: ''}], + }, + 'NETWORKDAYS.INTL': { + category: 'Date and time', + shortDescription: 'Returns the number of working days between two given dates.', + parameters: [{name: 'Date1', description: ''}, {name: 'Date2', description: ''}, {name: 'Mode', description: ''}, {name: 'Holidays', description: ''}], + }, + NOW: { + category: 'Date and time', + shortDescription: 'Returns current date + time as a number of days since [`nullDate`](../api/interfaces/configparams.md#nulldate).', + parameters: [], + }, + SECOND: { + category: 'Date and time', + shortDescription: 'Returns second component of given time.', + parameters: [{name: 'Time', description: ''}], + }, + TIME: { + category: 'Date and time', + shortDescription: 'Returns the number that represents a given time as a fraction of full day.', + parameters: [{name: 'Hour', description: ''}, {name: 'Minute', description: ''}, {name: 'Second', description: ''}], + }, + TIMEVALUE: { + category: 'Date and time', + shortDescription: 'Parses a time string and returns a number that represents it as a fraction of a full day.
Accepts formats set by the [`timeFormats`](../api/interfaces/configparams.md#timeformats) option.', + parameters: [{name: 'Timestring', description: ''}], + }, + TODAY: { + category: 'Date and time', + shortDescription: 'Returns an integer representing the current date as the number of full days since [`nullDate`](../api/interfaces/configparams.md#nulldate).', + parameters: [], + }, + WEEKDAY: { + category: 'Date and time', + shortDescription: 'Computes a number between 1-7 representing the day of week.', + parameters: [{name: 'Date', description: ''}, {name: 'Type', description: ''}], + }, + WEEKNUM: { + category: 'Date and time', + shortDescription: 'Returns a week number that corresponds to the week of year.', + parameters: [{name: 'Date', description: ''}, {name: 'Type', description: ''}], + }, + WORKDAY: { + category: 'Date and time', + shortDescription: 'Returns the working day number of days from start day.', + parameters: [{name: 'Date', description: ''}, {name: 'Shift', description: ''}, {name: 'Holidays', description: ''}], + }, + 'WORKDAY.INTL': { + category: 'Date and time', + shortDescription: 'Returns the working day number of days from start day.', + parameters: [{name: 'Date', description: ''}, {name: 'Shift', description: ''}, {name: 'Mode', description: ''}, {name: 'Holidays', description: ''}], + }, + YEAR: { + category: 'Date and time', + shortDescription: 'Returns the year as a number according to the internal calculation rules.', + parameters: [{name: 'Number', description: ''}], + }, + YEARFRAC: { + category: 'Date and time', + shortDescription: 'Computes the difference between two date values, in fraction of years.', + parameters: [{name: 'Date2', description: ''}, {name: 'Date1', description: ''}, {name: 'Format', description: ''}], + }, +} diff --git a/src/interpreter/functionMetadata/categories/engineering.ts b/src/interpreter/functionMetadata/categories/engineering.ts new file mode 100644 index 000000000..d15ef5d67 --- /dev/null +++ b/src/interpreter/functionMetadata/categories/engineering.ts @@ -0,0 +1,243 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +import {FunctionDoc} from '../FunctionDescription' + +/** + * Catalogue entries for the "Engineering" category. Generated from `docs/guide/built-in-functions.md` by + * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + */ +export const ENGINEERING_DOCS: Record = { + BIN2DEC: { + category: 'Engineering', + shortDescription: 'The result is the decimal number for the binary number entered.', + parameters: [{name: 'Number', description: ''}], + }, + BIN2HEX: { + category: 'Engineering', + shortDescription: 'The result is the hexadecimal number for the binary number entered.', + parameters: [{name: 'Number', description: ''}, {name: 'Places', description: ''}], + }, + BIN2OCT: { + category: 'Engineering', + shortDescription: 'The result is the octal number for the binary number entered.', + parameters: [{name: 'Number', description: ''}, {name: 'Places', description: ''}], + }, + BITAND: { + category: 'Engineering', + shortDescription: 'Returns a bitwise logical "and" of the parameters.', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}], + }, + BITLSHIFT: { + category: 'Engineering', + shortDescription: 'Shifts a number left by n bits.', + parameters: [{name: 'Number', description: ''}, {name: 'Shift', description: ''}], + }, + BITOR: { + category: 'Engineering', + shortDescription: 'Returns a bitwise logical "or" of the parameters.', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}], + }, + BITRSHIFT: { + category: 'Engineering', + shortDescription: 'Shifts a number right by n bits.', + parameters: [{name: 'Number', description: ''}, {name: 'Shift', description: ''}], + }, + BITXOR: { + category: 'Engineering', + shortDescription: 'Returns a bitwise logical "exclusive or" of the parameters.', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}], + }, + COMPLEX: { + category: 'Engineering', + shortDescription: 'Returns complex number from Re and Im parts.', + parameters: [{name: 'Re', description: ''}, {name: 'Im', description: ''}, {name: 'Symbol', description: ''}], + }, + DEC2BIN: { + category: 'Engineering', + shortDescription: 'Returns the binary number for the decimal number entered between –512 and 511.', + parameters: [{name: 'Number', description: ''}, {name: 'Places', description: ''}], + }, + DEC2HEX: { + category: 'Engineering', + shortDescription: 'Returns the hexadecimal number for the decimal number entered.', + parameters: [{name: 'Number', description: ''}, {name: 'Places', description: ''}], + }, + DEC2OCT: { + category: 'Engineering', + shortDescription: 'Returns the octal number for the decimal number entered.', + parameters: [{name: 'Number', description: ''}, {name: 'Places', description: ''}], + }, + DELTA: { + category: 'Engineering', + shortDescription: 'Returns TRUE (1) if both numbers are equal, otherwise returns FALSE (0).', + parameters: [{name: 'Number_1', description: ''}, {name: 'Number_2', description: ''}], + }, + ERF: { + category: 'Engineering', + shortDescription: 'Returns values of the Gaussian error integral.', + parameters: [{name: 'Lower_Limit', description: ''}, {name: 'Upper_Limit', description: ''}], + }, + ERFC: { + category: 'Engineering', + shortDescription: 'Returns complementary values of the Gaussian error integral between x and infinity.', + parameters: [{name: 'Lower_Limit', description: ''}], + }, + HEX2BIN: { + category: 'Engineering', + shortDescription: 'The result is the binary number for the hexadecimal number entered.', + parameters: [{name: 'Number', description: ''}, {name: 'Places', description: ''}], + }, + HEX2DEC: { + category: 'Engineering', + shortDescription: 'The result is the decimal number for the hexadecimal number entered.', + parameters: [{name: 'Number', description: ''}], + }, + HEX2OCT: { + category: 'Engineering', + shortDescription: 'The result is the octal number for the hexadecimal number entered.', + parameters: [{name: 'Number', description: ''}, {name: 'Places', description: ''}], + }, + IMABS: { + category: 'Engineering', + shortDescription: 'Returns modulus of a complex number.', + parameters: [{name: 'Complex', description: ''}], + }, + IMAGINARY: { + category: 'Engineering', + shortDescription: 'Returns imaginary part of a complex number.', + parameters: [{name: 'Complex', description: ''}], + }, + IMARGUMENT: { + category: 'Engineering', + shortDescription: 'Returns argument of a complex number.', + parameters: [{name: 'Complex', description: ''}], + }, + IMCONJUGATE: { + category: 'Engineering', + shortDescription: 'Returns conjugate of a complex number.', + parameters: [{name: 'Complex', description: ''}], + }, + IMCOS: { + category: 'Engineering', + shortDescription: 'Returns cosine of a complex number.', + parameters: [{name: 'Complex', description: ''}], + }, + IMCOSH: { + category: 'Engineering', + shortDescription: 'Returns hyperbolic cosine of a complex number.', + parameters: [{name: 'Complex', description: ''}], + }, + IMCOT: { + category: 'Engineering', + shortDescription: 'Returns cotangent of a complex number.', + parameters: [{name: 'Complex', description: ''}], + }, + IMCSC: { + category: 'Engineering', + shortDescription: 'Returns cosecant of a complex number.', + parameters: [{name: 'Complex', description: ''}], + }, + IMCSCH: { + category: 'Engineering', + shortDescription: 'Returns hyperbolic cosecant of a complex number.', + parameters: [{name: 'Complex', description: ''}], + }, + IMDIV: { + category: 'Engineering', + shortDescription: 'Divides two complex numbers.', + parameters: [{name: 'Complex1', description: ''}, {name: 'Complex2', description: ''}], + }, + IMEXP: { + category: 'Engineering', + shortDescription: 'Returns exponent of a complex number.', + parameters: [{name: 'Complex', description: ''}], + }, + IMLN: { + category: 'Engineering', + shortDescription: 'Returns natural logarithm of a complex number.', + parameters: [{name: 'Complex', description: ''}], + }, + IMLOG10: { + category: 'Engineering', + shortDescription: 'Returns base-10 logarithm of a complex number.', + parameters: [{name: 'Complex', description: ''}], + }, + IMLOG2: { + category: 'Engineering', + shortDescription: 'Returns binary logarithm of a complex number.', + parameters: [{name: 'Complex', description: ''}], + }, + IMPOWER: { + category: 'Engineering', + shortDescription: 'Returns a complex number raised to a given power.', + parameters: [{name: 'Complex', description: ''}, {name: 'Number', description: ''}], + }, + IMPRODUCT: { + category: 'Engineering', + shortDescription: 'Multiplies complex numbers.', + parameters: [{name: 'Complex1', description: ''}], + }, + IMREAL: { + category: 'Engineering', + shortDescription: 'Returns real part of a complex number.', + parameters: [{name: 'Complex', description: ''}], + }, + IMSEC: { + category: 'Engineering', + shortDescription: 'Returns the secant of a complex number.', + parameters: [{name: 'Complex', description: ''}], + }, + IMSECH: { + category: 'Engineering', + shortDescription: 'Returns the hyperbolic secant of a complex number.', + parameters: [{name: 'Complex', description: ''}], + }, + IMSIN: { + category: 'Engineering', + shortDescription: 'Returns sine of a complex number.', + parameters: [{name: 'Complex', description: ''}], + }, + IMSINH: { + category: 'Engineering', + shortDescription: 'Returns hyperbolic sine of a complex number.', + parameters: [{name: 'Complex', description: ''}], + }, + IMSQRT: { + category: 'Engineering', + shortDescription: 'Returns a square root of a complex number.', + parameters: [{name: 'Complex', description: ''}], + }, + IMSUB: { + category: 'Engineering', + shortDescription: 'Subtracts two complex numbers.', + parameters: [{name: 'Complex1', description: ''}, {name: 'Complex2', description: ''}], + }, + IMSUM: { + category: 'Engineering', + shortDescription: 'Adds complex numbers.', + parameters: [{name: 'Complex1', description: ''}], + }, + IMTAN: { + category: 'Engineering', + shortDescription: 'Returns the tangent of a complex number.', + parameters: [{name: 'Complex', description: ''}], + }, + OCT2BIN: { + category: 'Engineering', + shortDescription: 'The result is the binary number for the octal number entered.', + parameters: [{name: 'Number', description: ''}, {name: 'Places', description: ''}], + }, + OCT2DEC: { + category: 'Engineering', + shortDescription: 'The result is the decimal number for the octal number entered.', + parameters: [{name: 'Number', description: ''}], + }, + OCT2HEX: { + category: 'Engineering', + shortDescription: 'The result is the hexadecimal number for the octal number entered.', + parameters: [{name: 'Number', description: ''}, {name: 'Places', description: ''}], + }, +} diff --git a/src/interpreter/functionMetadata/categories/financial.ts b/src/interpreter/functionMetadata/categories/financial.ts new file mode 100644 index 000000000..bf1e6b7a2 --- /dev/null +++ b/src/interpreter/functionMetadata/categories/financial.ts @@ -0,0 +1,153 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +import {FunctionDoc} from '../FunctionDescription' + +/** + * Catalogue entries for the "Financial" category. Generated from `docs/guide/built-in-functions.md` by + * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + */ +export const FINANCIAL_DOCS: Record = { + CUMIPMT: { + category: 'Financial', + shortDescription: 'Returns the cumulative interest paid on a loan between a start period and an end period.', + parameters: [{name: 'Rate', description: ''}, {name: 'Nper', description: ''}, {name: 'Pv', description: ''}, {name: 'Start', description: ''}, {name: 'End', description: ''}, {name: 'type', description: ''}], + }, + CUMPRINC: { + category: 'Financial', + shortDescription: 'Returns the cumulative principal paid on a loan between a start period and an end period.', + parameters: [{name: 'Rate', description: ''}, {name: 'Nper', description: ''}, {name: 'Pv', description: ''}, {name: 'Start', description: ''}, {name: 'End', description: ''}, {name: 'Type', description: ''}], + }, + DB: { + category: 'Financial', + shortDescription: 'Returns the depreciation of an asset for a period using the fixed-declining balance method.', + parameters: [{name: 'Cost', description: ''}, {name: 'Salvage', description: ''}, {name: 'Life', description: ''}, {name: 'Period', description: ''}, {name: 'Month', description: ''}], + }, + DDB: { + category: 'Financial', + shortDescription: 'Returns the depreciation of an asset for a period using the double-declining balance method.', + parameters: [{name: 'Cost', description: ''}, {name: 'Salvage', description: ''}, {name: 'Life', description: ''}, {name: 'Period', description: ''}, {name: 'Factor', description: ''}], + }, + DOLLARDE: { + category: 'Financial', + shortDescription: 'Converts a price entered with a special notation to a price displayed as a decimal number.', + parameters: [{name: 'Price', description: ''}, {name: 'Fraction', description: ''}], + }, + DOLLARFR: { + category: 'Financial', + shortDescription: 'Converts a price displayed as a decimal number to a price entered with a special notation.', + parameters: [{name: 'Price', description: ''}, {name: 'Fraction', description: ''}], + }, + EFFECT: { + category: 'Financial', + shortDescription: 'Calculates the effective annual interest rate from a nominal interest rate and the number of compounding periods per year.', + parameters: [{name: 'Nominal_rate', description: ''}, {name: 'Npery', description: ''}], + }, + FV: { + category: 'Financial', + shortDescription: 'Returns the future value of an investment.', + parameters: [{name: 'Rate', description: ''}, {name: 'Nper', description: ''}, {name: 'Pmt', description: ''}, {name: 'Pv', description: ''}, {name: 'Type', description: ''}], + }, + FVSCHEDULE: { + category: 'Financial', + shortDescription: 'Returns the future value of an investment based on a rate schedule.', + parameters: [{name: 'Pv', description: ''}, {name: 'Schedule', description: ''}], + }, + IPMT: { + category: 'Financial', + shortDescription: 'Returns the interest portion of a given loan payment in a given payment period.', + parameters: [{name: 'Rate', description: ''}, {name: 'Per', description: ''}, {name: 'Nper', description: ''}, {name: 'Pv', description: ''}, {name: 'Fv', description: ''}, {name: 'Type', description: ''}], + }, + IRR: { + category: 'Financial', + shortDescription: 'Returns the internal rate of return for a series of cash flows.', + parameters: [{name: 'Values', description: ''}, {name: 'Guess', description: ''}], + }, + ISPMT: { + category: 'Financial', + shortDescription: 'Returns the interest paid for a given period of an investment with equal principal payments.', + parameters: [{name: 'Rate', description: ''}, {name: 'Per', description: ''}, {name: 'Nper', description: ''}, {name: 'Value', description: ''}], + }, + MIRR: { + category: 'Financial', + shortDescription: 'Returns modified internal value for cashflows.', + parameters: [{name: 'Flows', description: ''}, {name: 'FRate', description: ''}, {name: 'RRate', description: ''}], + }, + NOMINAL: { + category: 'Financial', + shortDescription: 'Returns the nominal interest rate.', + parameters: [{name: 'Effect_rate', description: ''}, {name: 'Npery', description: ''}], + }, + NPER: { + category: 'Financial', + shortDescription: 'Returns the number of periods for an investment assuming periodic, constant payments and a constant interest rate.', + parameters: [{name: 'Rate', description: ''}, {name: 'Pmt', description: ''}, {name: 'Pv', description: ''}, {name: 'Fv', description: ''}, {name: 'Type', description: ''}], + }, + NPV: { + category: 'Financial', + shortDescription: 'Returns net present value.', + parameters: [{name: 'Rate', description: ''}, {name: 'Value1', description: ''}], + }, + PDURATION: { + category: 'Financial', + shortDescription: 'Returns number of periods to reach specific value.', + parameters: [{name: 'Rate', description: ''}, {name: 'Pv', description: ''}, {name: 'Fv', description: ''}], + }, + PMT: { + category: 'Financial', + shortDescription: 'Returns the periodic payment for a loan.', + parameters: [{name: 'Rate', description: ''}, {name: 'Nper', description: ''}, {name: 'Pv', description: ''}, {name: 'Fv', description: ''}, {name: 'Type', description: ''}], + }, + PPMT: { + category: 'Financial', + shortDescription: 'Calculates the principal portion of a given loan payment.', + parameters: [{name: 'Rate', description: ''}, {name: 'Per', description: ''}, {name: 'Nper', description: ''}, {name: 'Pv', description: ''}, {name: 'Fv', description: ''}, {name: 'Type', description: ''}], + }, + PV: { + category: 'Financial', + shortDescription: 'Returns the present value of an investment.', + parameters: [{name: 'Rate', description: ''}, {name: 'Nper', description: ''}, {name: 'Pmt', description: ''}, {name: 'Fv', description: ''}, {name: 'Type', description: ''}], + }, + RATE: { + category: 'Financial', + shortDescription: 'Returns the interest rate per period of an annuity.', + parameters: [{name: 'Nper', description: ''}, {name: 'Pmt', description: ''}, {name: 'Pv', description: ''}, {name: 'Fv', description: ''}, {name: 'Type', description: ''}, {name: 'guess', description: ''}], + }, + RRI: { + category: 'Financial', + shortDescription: 'Returns an equivalent interest rate for the growth of an investment.', + parameters: [{name: 'Nper', description: ''}, {name: 'Pv', description: ''}, {name: 'Fv', description: ''}], + }, + SLN: { + category: 'Financial', + shortDescription: 'Returns the depreciation of an asset for one period, based on a straight-line method.', + parameters: [{name: 'Cost', description: ''}, {name: 'Salvage', description: ''}, {name: 'Life', description: ''}], + }, + SYD: { + category: 'Financial', + shortDescription: 'Returns the "sum-of-years" depreciation for an asset in a period.', + parameters: [{name: 'Cost', description: ''}, {name: 'Salvage', description: ''}, {name: 'Life', description: ''}, {name: 'Period', description: ''}], + }, + TBILLEQ: { + category: 'Financial', + shortDescription: 'Returns the bond-equivalent yield for a Treasury bill.', + parameters: [{name: 'Settlement', description: ''}, {name: 'Maturity', description: ''}, {name: 'Discount', description: ''}], + }, + TBILLPRICE: { + category: 'Financial', + shortDescription: 'Returns the price per $100 face value for a Treasury bill.', + parameters: [{name: 'Settlement', description: ''}, {name: 'Maturity', description: ''}, {name: 'Discount', description: ''}], + }, + TBILLYIELD: { + category: 'Financial', + shortDescription: 'Returns the yield for a Treasury bill.', + parameters: [{name: 'Settlement', description: ''}, {name: 'Maturity', description: ''}, {name: 'Price', description: ''}], + }, + XNPV: { + category: 'Financial', + shortDescription: 'Returns net present value.', + parameters: [{name: 'Rate', description: ''}, {name: 'Payments', description: ''}, {name: 'Dates', description: ''}], + }, +} diff --git a/src/interpreter/functionMetadata/categories/information.ts b/src/interpreter/functionMetadata/categories/information.ts new file mode 100644 index 000000000..ab12675e7 --- /dev/null +++ b/src/interpreter/functionMetadata/categories/information.ts @@ -0,0 +1,93 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +import {FunctionDoc} from '../FunctionDescription' + +/** + * Catalogue entries for the "Information" category. Generated from `docs/guide/built-in-functions.md` by + * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + */ +export const INFORMATION_DOCS: Record = { + ISBINARY: { + category: 'Information', + shortDescription: 'Returns TRUE if provided value is a valid binary number.', + parameters: [{name: 'Value', description: ''}], + }, + ISBLANK: { + category: 'Information', + shortDescription: 'Returns TRUE if the reference to a cell is blank.', + parameters: [{name: 'Value', description: ''}], + }, + ISERR: { + category: 'Information', + shortDescription: 'Returns TRUE if the value is error value except #N/A!.', + parameters: [{name: 'Value', description: ''}], + }, + ISERROR: { + category: 'Information', + shortDescription: 'Returns TRUE if the value is general error value.', + parameters: [{name: 'Value', description: ''}], + }, + ISEVEN: { + category: 'Information', + shortDescription: 'Returns TRUE if the value is an even integer, or FALSE if the value is odd.', + parameters: [{name: 'Value', description: ''}], + }, + ISFORMULA: { + category: 'Information', + shortDescription: 'Checks whether referenced cell is a formula.', + parameters: [{name: 'Value', description: ''}], + }, + ISLOGICAL: { + category: 'Information', + shortDescription: 'Tests for a logical value (TRUE or FALSE).', + parameters: [{name: 'Value', description: ''}], + }, + ISNA: { + category: 'Information', + shortDescription: 'Returns TRUE if the value is #N/A! error.', + parameters: [{name: 'Value', description: ''}], + }, + ISNONTEXT: { + category: 'Information', + shortDescription: 'Tests if the cell contents are text or numbers, and returns FALSE if the contents are text.', + parameters: [{name: 'Value', description: ''}], + }, + ISNUMBER: { + category: 'Information', + shortDescription: 'Returns TRUE if the value refers to a number.', + parameters: [{name: 'Value', description: ''}], + }, + ISODD: { + category: 'Information', + shortDescription: 'Returns TRUE if the value is odd, or FALSE if the number is even.', + parameters: [{name: 'Value', description: ''}], + }, + ISREF: { + category: 'Information', + shortDescription: 'Returns TRUE if provided value is #REF! error.', + parameters: [{name: 'Value', description: ''}], + }, + ISTEXT: { + category: 'Information', + shortDescription: 'Returns TRUE if the cell contents reference text.', + parameters: [{name: 'Value', description: ''}], + }, + NA: { + category: 'Information', + shortDescription: 'Returns #N/A! error value.', + parameters: [], + }, + SHEET: { + category: 'Information', + shortDescription: 'Returns sheet number of a given value or a formula sheet number if no argument is provided.', + parameters: [{name: 'Value', description: ''}], + }, + SHEETS: { + category: 'Information', + shortDescription: 'Returns number of sheet of a given reference or number of all sheets in workbook when no argument is provided.', + parameters: [{name: 'Value', description: ''}], + }, +} diff --git a/src/interpreter/functionMetadata/categories/logical.ts b/src/interpreter/functionMetadata/categories/logical.ts index 4f422a686..b9e2e86c0 100644 --- a/src/interpreter/functionMetadata/categories/logical.ts +++ b/src/interpreter/functionMetadata/categories/logical.ts @@ -6,12 +6,63 @@ import {FunctionDoc} from '../FunctionDescription' /** - * Catalogue entries for the "Logical" category. Seeded subset; completed by the migration. + * Catalogue entries for the "Logical" category. Generated from `docs/guide/built-in-functions.md` by + * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. */ export const LOGICAL_DOCS: Record = { + AND: { + category: 'Logical', + shortDescription: 'Returns TRUE if all arguments are TRUE.', + parameters: [{name: 'Logical_value1', description: ''}], + }, + FALSE: { + category: 'Logical', + shortDescription: 'Returns the logical value FALSE.', + parameters: [], + }, + IF: { + category: 'Logical', + shortDescription: 'Specifies a logical test to be performed.', + parameters: [{name: 'Test', description: ''}, {name: 'Then_value', description: ''}, {name: 'Otherwise_value', description: ''}], + }, + IFERROR: { + category: 'Logical', + shortDescription: 'Returns the value if the cell does not contains an error value, or the alternative value if it does.', + parameters: [{name: 'Value', description: ''}, {name: 'Alternate_value', description: ''}], + }, + IFNA: { + category: 'Logical', + shortDescription: 'Returns the value if the cell does not contains the #N/A (value not available) error value, or the alternative value if it does.', + parameters: [{name: 'Value', description: ''}, {name: 'Alternate_value', description: ''}], + }, IFS: { category: 'Logical', - shortDescription: 'Checks one or more conditions and returns the value for the first that is met.', + shortDescription: 'Evaluates multiple logical tests and returns a value that corresponds to the first true condition.', parameters: [{name: 'Condition1', description: ''}, {name: 'Value1', description: ''}], }, + NOT: { + category: 'Logical', + shortDescription: 'Complements (inverts) a logical value.', + parameters: [{name: 'Logicalvalue', description: ''}], + }, + OR: { + category: 'Logical', + shortDescription: 'Returns TRUE if at least one argument is TRUE.', + parameters: [{name: 'Logical_value1', description: ''}], + }, + SWITCH: { + category: 'Logical', + shortDescription: 'Evaluates a list of arguments, consisting of an expression followed by a value.', + parameters: [{name: 'Expression1', description: ''}, {name: 'Value1', description: ''}, {name: 'Expression2', description: ''}], + }, + TRUE: { + category: 'Logical', + shortDescription: 'The logical value is set to TRUE.', + parameters: [], + }, + XOR: { + category: 'Logical', + shortDescription: 'Returns true if an odd number of arguments evaluates to TRUE.', + parameters: [{name: 'Logical_value1', description: ''}], + }, } diff --git a/src/interpreter/functionMetadata/categories/lookup-and-reference.ts b/src/interpreter/functionMetadata/categories/lookup-and-reference.ts new file mode 100644 index 000000000..a1b491563 --- /dev/null +++ b/src/interpreter/functionMetadata/categories/lookup-and-reference.ts @@ -0,0 +1,78 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +import {FunctionDoc} from '../FunctionDescription' + +/** + * Catalogue entries for the "Lookup and reference" category. Generated from `docs/guide/built-in-functions.md` by + * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + */ +export const LOOKUP_AND_REFERENCE_DOCS: Record = { + ADDRESS: { + category: 'Lookup and reference', + shortDescription: 'Returns a cell reference as a string.', + parameters: [{name: 'Row', description: ''}, {name: 'Column', description: ''}, {name: 'AbsoluteRelativeMode', description: ''}, {name: 'UseA1Notation', description: ''}, {name: 'Sheet', description: ''}], + }, + CHOOSE: { + category: 'Lookup and reference', + shortDescription: 'Uses an index to return a value from a list of values.', + parameters: [{name: 'Index', description: ''}, {name: 'Value1', description: ''}], + }, + COLUMN: { + category: 'Lookup and reference', + shortDescription: 'Returns column number of a given reference or formula reference if argument not provided.', + parameters: [{name: 'Reference', description: ''}], + }, + COLUMNS: { + category: 'Lookup and reference', + shortDescription: 'Returns the number of columns in the given reference.', + parameters: [{name: 'Array', description: ''}], + }, + FORMULATEXT: { + category: 'Lookup and reference', + shortDescription: 'Returns a formula in a given cell as a string.', + parameters: [{name: 'Reference', description: ''}], + }, + HLOOKUP: { + category: 'Lookup and reference', + shortDescription: 'Searches horizontally with reference to adjacent cells to the bottom.', + parameters: [{name: 'Search_Criterion', description: ''}, {name: 'Array', description: ''}, {name: 'Index', description: ''}, {name: 'Sort_Order', description: ''}], + }, + HYPERLINK: { + category: 'Lookup and reference', + shortDescription: 'Stores the url in the cell\'s metadata. It can be read using method [`getCellHyperlink`](../api/classes/hyperformula.md#getcellhyperlink)', + parameters: [{name: 'Url', description: ''}, {name: 'LinkLabel', description: ''}], + }, + INDEX: { + category: 'Lookup and reference', + shortDescription: 'Returns the contents of a cell specified by row and column number. The column number is optional and defaults to 1.', + parameters: [{name: 'Range', description: ''}, {name: 'Row', description: ''}, {name: 'Column', description: ''}], + }, + MATCH: { + category: 'Lookup and reference', + shortDescription: 'Returns the relative position of an item in an array that matches a specified value.', + parameters: [{name: 'Searchcriterion', description: ''}, {name: 'LookupArray', description: ''}, {name: 'MatchType', description: ''}], + }, + ROW: { + category: 'Lookup and reference', + shortDescription: 'Returns row number of a given reference or formula reference if argument not provided.', + parameters: [{name: 'Reference', description: ''}], + }, + ROWS: { + category: 'Lookup and reference', + shortDescription: 'Returns the number of rows in the given reference.', + parameters: [{name: 'Array', description: ''}], + }, + VLOOKUP: { + category: 'Lookup and reference', + shortDescription: 'Searches vertically with reference to adjacent cells to the right.', + parameters: [{name: 'Search_Criterion', description: ''}, {name: 'Array', description: ''}, {name: 'Index', description: ''}, {name: 'Sort_Order', description: ''}], + }, + XLOOKUP: { + category: 'Lookup and reference', + shortDescription: 'Searches for a key in a range and returns the item corresponding to the match it finds. If no match exists, then XLOOKUP can return the closest (approximate) match.', + parameters: [{name: 'LookupValue', description: ''}, {name: 'LookupArray', description: ''}, {name: 'ReturnArray', description: ''}, {name: 'IfNotFound', description: ''}, {name: 'MatchMode', description: ''}, {name: 'SearchMode', description: ''}], + }, +} diff --git a/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts b/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts index 63bd7eea2..9e864f3e9 100644 --- a/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts +++ b/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts @@ -6,22 +6,373 @@ import {FunctionDoc} from '../FunctionDescription' /** - * Catalogue entries for the "Math and trigonometry" category. Seeded subset; completed by the migration. + * Catalogue entries for the "Math and trigonometry" category. Generated from `docs/guide/built-in-functions.md` by + * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. */ export const MATH_AND_TRIGONOMETRY_DOCS: Record = { - SUMIF: { + ABS: { category: 'Math and trigonometry', - shortDescription: 'Sums the cells that meet a criterion.', - parameters: [{name: 'Range', description: ''}, {name: 'Criterion', description: ''}, {name: 'SumRange', description: ''}], + shortDescription: 'Returns the absolute value of a number.', + parameters: [{name: 'Number', description: ''}], }, - SUM: { + ACOS: { + category: 'Math and trigonometry', + shortDescription: 'Returns the inverse trigonometric cosine of a number.', + parameters: [{name: 'Number', description: ''}], + }, + ACOSH: { + category: 'Math and trigonometry', + shortDescription: 'Returns the inverse hyperbolic cosine of a number.', + parameters: [{name: 'Number', description: ''}], + }, + ACOT: { + category: 'Math and trigonometry', + shortDescription: 'Returns the inverse trigonometric cotangent of a number.', + parameters: [{name: 'Number', description: ''}], + }, + ACOTH: { + category: 'Math and trigonometry', + shortDescription: 'Returns the inverse hyperbolic cotangent of a number.', + parameters: [{name: 'Number', description: ''}], + }, + ARABIC: { + category: 'Math and trigonometry', + shortDescription: 'Converts number from roman form.', + parameters: [{name: 'String', description: ''}], + }, + ASIN: { + category: 'Math and trigonometry', + shortDescription: 'Returns the inverse trigonometric sine of a number.', + parameters: [{name: 'Number', description: ''}], + }, + ASINH: { + category: 'Math and trigonometry', + shortDescription: 'Returns the inverse hyperbolic sine of a number.', + parameters: [{name: 'Number', description: ''}], + }, + ATAN: { + category: 'Math and trigonometry', + shortDescription: 'Returns the inverse trigonometric tangent of a number.', + parameters: [{name: 'Number', description: ''}], + }, + ATAN2: { + category: 'Math and trigonometry', + shortDescription: 'Returns the inverse trigonometric tangent of the specified x and y coordinates.', + parameters: [{name: 'Numberx', description: ''}, {name: 'Numbery', description: ''}], + }, + ATANH: { + category: 'Math and trigonometry', + shortDescription: 'Returns the inverse hyperbolic tangent of a number.', + parameters: [{name: 'Number', description: ''}], + }, + BASE: { + category: 'Math and trigonometry', + shortDescription: 'Converts a positive integer to a specified base into a text from the numbering system.', + parameters: [{name: 'Number', description: ''}, {name: 'Radix', description: ''}, {name: 'Minimumlength', description: ''}], + }, + CEILING: { + category: 'Math and trigonometry', + shortDescription: 'Rounds a number up to the nearest multiple of Significance.', + parameters: [{name: 'Number', description: ''}, {name: 'Significance', description: ''}], + }, + 'CEILING.MATH': { + category: 'Math and trigonometry', + shortDescription: 'Rounds a number up to the nearest multiple of Significance.', + parameters: [{name: 'Number', description: ''}, {name: 'Significance', description: ''}, {name: 'Mode', description: ''}], + }, + 'CEILING.PRECISE': { + category: 'Math and trigonometry', + shortDescription: 'Rounds a number up to the nearest multiple of Significance.', + parameters: [{name: 'Number', description: ''}, {name: 'Significance', description: ''}], + }, + COMBIN: { + category: 'Math and trigonometry', + shortDescription: 'Returns number of combinations (without repetitions).', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}], + }, + COMBINA: { + category: 'Math and trigonometry', + shortDescription: 'Returns number of combinations (with repetitions).', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}], + }, + COS: { + category: 'Math and trigonometry', + shortDescription: 'Returns the cosine of the given angle (in radians).', + parameters: [{name: 'Number', description: ''}], + }, + COSH: { + category: 'Math and trigonometry', + shortDescription: 'Returns the hyperbolic cosine of the given value.', + parameters: [{name: 'Number', description: ''}], + }, + COT: { + category: 'Math and trigonometry', + shortDescription: 'Returns the cotangent of the given angle (in radians).', + parameters: [{name: 'Number', description: ''}], + }, + COTH: { + category: 'Math and trigonometry', + shortDescription: 'Returns the hyperbolic cotangent of the given value.', + parameters: [{name: 'Number', description: ''}], + }, + COUNTUNIQUE: { + category: 'Math and trigonometry', + shortDescription: 'Counts the number of unique values in a list of specified values and ranges.', + parameters: [{name: 'Value1', description: ''}], + }, + CSC: { + category: 'Math and trigonometry', + shortDescription: 'Returns the cosecant of the given angle (in radians).', + parameters: [{name: 'Number', description: ''}], + }, + CSCH: { + category: 'Math and trigonometry', + shortDescription: 'Returns the hyperbolic cosecant of the given value.', + parameters: [{name: 'Number', description: ''}], + }, + DECIMAL: { + category: 'Math and trigonometry', + shortDescription: 'Converts text with characters from a number system to a positive integer in the base radix given.', + parameters: [{name: 'Text', description: ''}, {name: 'Radix', description: ''}], + }, + DEGREES: { + category: 'Math and trigonometry', + shortDescription: 'Converts radians into degrees.', + parameters: [{name: 'Number', description: ''}], + }, + EVEN: { + category: 'Math and trigonometry', + shortDescription: 'Rounds a positive number up to the next even integer and a negative number down to the next even integer.', + parameters: [{name: 'Number', description: ''}], + }, + EXP: { + category: 'Math and trigonometry', + shortDescription: 'Returns constant e raised to the power of a number.', + parameters: [{name: 'Number', description: ''}], + }, + FACT: { + category: 'Math and trigonometry', + shortDescription: 'Returns a factorial of a number.', + parameters: [{name: 'Number', description: ''}], + }, + FACTDOUBLE: { + category: 'Math and trigonometry', + shortDescription: 'Returns a double factorial of a number.', + parameters: [{name: 'Number', description: ''}], + }, + FLOOR: { + category: 'Math and trigonometry', + shortDescription: 'Rounds a number down to the nearest multiple of Significance.', + parameters: [{name: 'Number', description: ''}, {name: 'Significance', description: ''}], + }, + 'FLOOR.MATH': { + category: 'Math and trigonometry', + shortDescription: 'Rounds a number down to the nearest multiple of Significance.', + parameters: [{name: 'Number', description: ''}, {name: 'Significance', description: ''}, {name: 'Mode', description: ''}], + }, + 'FLOOR.PRECISE': { + category: 'Math and trigonometry', + shortDescription: 'Rounds a number down to the nearest multiple of Significance.', + parameters: [{name: 'Number', description: ''}, {name: 'Significance', description: ''}], + }, + GCD: { + category: 'Math and trigonometry', + shortDescription: 'Computes greatest common divisor of numbers.', + parameters: [{name: 'Number1', description: ''}], + }, + INT: { + category: 'Math and trigonometry', + shortDescription: 'Rounds a number down to the nearest integer.', + parameters: [{name: 'Number', description: ''}], + }, + LCM: { + category: 'Math and trigonometry', + shortDescription: 'Computes least common multiple of numbers.', + parameters: [{name: 'Number1', description: ''}], + }, + LN: { + category: 'Math and trigonometry', + shortDescription: 'Returns the natural logarithm based on the constant e of a number.', + parameters: [{name: 'Number', description: ''}], + }, + LOG: { + category: 'Math and trigonometry', + shortDescription: 'Returns the logarithm of a number to the specified base.', + parameters: [{name: 'Number', description: ''}, {name: 'Base', description: ''}], + }, + LOG10: { + category: 'Math and trigonometry', + shortDescription: 'Returns the base-10 logarithm of a number.', + parameters: [{name: 'Number', description: ''}], + }, + MOD: { category: 'Math and trigonometry', - shortDescription: 'Sums a series of numbers or cells.', + shortDescription: 'Returns the remainder when one integer is divided by another.', + parameters: [{name: 'Dividend', description: ''}, {name: 'Divisor', description: ''}], + }, + MROUND: { + category: 'Math and trigonometry', + shortDescription: 'Rounds number to the neares multiplicity.', + parameters: [{name: 'Number', description: ''}, {name: 'Base', description: ''}], + }, + MULTINOMIAL: { + category: 'Math and trigonometry', + shortDescription: 'Returns number of multiset combinations.', parameters: [{name: 'Number1', description: ''}], }, + ODD: { + category: 'Math and trigonometry', + shortDescription: 'Rounds a positive number up to the nearest odd integer and a negative number down to the nearest odd integer.', + parameters: [{name: 'Number', description: ''}], + }, PI: { category: 'Math and trigonometry', - shortDescription: 'Returns the value of pi.', + shortDescription: 'Returns 3.14159265358979, the value of the mathematical constant PI to 14 decimal places.', + parameters: [], + }, + POWER: { + category: 'Math and trigonometry', + shortDescription: 'Returns a number raised to another number.', + parameters: [{name: 'Base', description: ''}, {name: 'Exponent', description: ''}], + }, + PRODUCT: { + category: 'Math and trigonometry', + shortDescription: 'Returns product of numbers.', + parameters: [{name: 'Number1', description: ''}], + }, + QUOTIENT: { + category: 'Math and trigonometry', + shortDescription: 'Returns integer part of a division.', + parameters: [{name: 'Dividend', description: ''}, {name: 'Divisor', description: ''}], + }, + RADIANS: { + category: 'Math and trigonometry', + shortDescription: 'Converts degrees to radians.', + parameters: [{name: 'Number', description: ''}], + }, + RAND: { + category: 'Math and trigonometry', + shortDescription: 'Returns a random number between 0 and 1.', parameters: [], }, + RANDBETWEEN: { + category: 'Math and trigonometry', + shortDescription: 'Returns a random integer between two numbers.', + parameters: [{name: 'Lowerbound', description: ''}, {name: 'Upperbound', description: ''}], + }, + ROMAN: { + category: 'Math and trigonometry', + shortDescription: 'Converts number to roman form.', + parameters: [{name: 'Number', description: ''}, {name: 'Mode', description: ''}], + }, + ROUND: { + category: 'Math and trigonometry', + shortDescription: 'Rounds a number to a certain number of decimal places.', + parameters: [{name: 'Number', description: ''}, {name: 'Count', description: ''}], + }, + ROUNDDOWN: { + category: 'Math and trigonometry', + shortDescription: 'Rounds a number down, toward zero, to a certain precision.', + parameters: [{name: 'Number', description: ''}, {name: 'Count', description: ''}], + }, + ROUNDUP: { + category: 'Math and trigonometry', + shortDescription: 'Rounds a number up, away from zero, to a certain precision.', + parameters: [{name: 'Number', description: ''}, {name: 'Count', description: ''}], + }, + SEC: { + category: 'Math and trigonometry', + shortDescription: 'Returns the secant of the given angle (in radians).', + parameters: [{name: 'Number', description: ''}], + }, + SECH: { + category: 'Math and trigonometry', + shortDescription: 'Returns the hyperbolic secant of the given angle (in radians).', + parameters: [{name: 'Number', description: ''}], + }, + SERIESSUM: { + category: 'Math and trigonometry', + shortDescription: 'Evaluates series at a point.', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Number3', description: ''}, {name: 'Coefficients', description: ''}], + }, + SIGN: { + category: 'Math and trigonometry', + shortDescription: 'Returns sign of a number.', + parameters: [{name: 'Number', description: ''}], + }, + SIN: { + category: 'Math and trigonometry', + shortDescription: 'Returns the sine of the given angle (in radians).', + parameters: [{name: 'Number', description: ''}], + }, + SINH: { + category: 'Math and trigonometry', + shortDescription: 'Returns the hyperbolic sine of the given value.', + parameters: [{name: 'Number', description: ''}], + }, + SQRT: { + category: 'Math and trigonometry', + shortDescription: 'Returns the positive square root of a number.', + parameters: [{name: 'Number', description: ''}], + }, + SQRTPI: { + category: 'Math and trigonometry', + shortDescription: 'Returns sqrt of number times pi.', + parameters: [{name: 'Number', description: ''}], + }, + SUBTOTAL: { + category: 'Math and trigonometry', + shortDescription: 'Computes aggregation using function specified by number.', + parameters: [{name: 'Function', description: ''}, {name: 'Number1', description: ''}], + }, + SUM: { + category: 'Math and trigonometry', + shortDescription: 'Sums up the values of the specified cells.', + parameters: [{name: 'Number1', description: ''}], + }, + SUMIF: { + category: 'Math and trigonometry', + shortDescription: 'Sums up the values of cells that belong to the specified range and meet the specified condition.', + parameters: [{name: 'Range', description: ''}, {name: 'Criteria', description: ''}, {name: 'Sumrange', description: ''}], + }, + SUMIFS: { + category: 'Math and trigonometry', + shortDescription: 'Sums up the values of cells that belong to the specified range and meet the specified sets of conditions.', + parameters: [{name: 'Sum_Range', description: ''}, {name: 'Criterion_range1', description: ''}, {name: 'Criterion1', description: ''}], + }, + SUMPRODUCT: { + category: 'Math and trigonometry', + shortDescription: 'Multiplies corresponding elements in the given arrays, and returns the sum of those products.', + parameters: [{name: 'Array1', description: ''}], + }, + SUMSQ: { + category: 'Math and trigonometry', + shortDescription: 'Returns the sum of the squares of the arguments', + parameters: [{name: 'Number1', description: ''}], + }, + SUMX2MY2: { + category: 'Math and trigonometry', + shortDescription: 'Returns the sum of the square differences.', + parameters: [{name: 'Range1', description: ''}, {name: 'Range2', description: ''}], + }, + SUMX2PY2: { + category: 'Math and trigonometry', + shortDescription: 'Returns the sum of the square sums.', + parameters: [{name: 'Range1', description: ''}, {name: 'Range2', description: ''}], + }, + SUMXMY2: { + category: 'Math and trigonometry', + shortDescription: 'Returns the sum of the square of differences.', + parameters: [{name: 'Range1', description: ''}, {name: 'Range2', description: ''}], + }, + TAN: { + category: 'Math and trigonometry', + shortDescription: 'Returns the tangent of the given angle (in radians).', + parameters: [{name: 'Number', description: ''}], + }, + TANH: { + category: 'Math and trigonometry', + shortDescription: 'Returns the hyperbolic tangent of the given value.', + parameters: [{name: 'Number', description: ''}], + }, } diff --git a/src/interpreter/functionMetadata/categories/matrix-functions.ts b/src/interpreter/functionMetadata/categories/matrix-functions.ts new file mode 100644 index 000000000..7efebad71 --- /dev/null +++ b/src/interpreter/functionMetadata/categories/matrix-functions.ts @@ -0,0 +1,33 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +import {FunctionDoc} from '../FunctionDescription' + +/** + * Catalogue entries for the "Matrix functions" category. Generated from `docs/guide/built-in-functions.md` by + * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + */ +export const MATRIX_FUNCTIONS_DOCS: Record = { + MAXPOOL: { + category: 'Matrix functions', + shortDescription: 'Calculates a smaller range which is a maximum of a Window_size, in a given Range, for every Stride element.', + parameters: [{name: 'Range', description: ''}, {name: 'Window_size', description: ''}, {name: 'Stride', description: ''}], + }, + MEDIANPOOL: { + category: 'Matrix functions', + shortDescription: 'Calculates a smaller range which is a median of a Window_size, in a given Range, for every Stride element.', + parameters: [{name: 'Range', description: ''}, {name: 'Window_size', description: ''}, {name: 'Stride', description: ''}], + }, + MMULT: { + category: 'Matrix functions', + shortDescription: 'Calculates the array product of two arrays.', + parameters: [{name: 'Array1', description: ''}, {name: 'Array2', description: ''}], + }, + TRANSPOSE: { + category: 'Matrix functions', + shortDescription: 'Transposes the rows and columns of an array.', + parameters: [{name: 'Array', description: ''}], + }, +} diff --git a/src/interpreter/functionMetadata/categories/operator.ts b/src/interpreter/functionMetadata/categories/operator.ts new file mode 100644 index 000000000..9305a5ebd --- /dev/null +++ b/src/interpreter/functionMetadata/categories/operator.ts @@ -0,0 +1,88 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +import {FunctionDoc} from '../FunctionDescription' + +/** + * Catalogue entries for the "Operator" category. Generated from `docs/guide/built-in-functions.md` by + * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + */ +export const OPERATOR_DOCS: Record = { + 'HF.ADD': { + category: 'Operator', + shortDescription: 'Adds two values.', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}], + }, + 'HF.CONCAT': { + category: 'Operator', + shortDescription: 'Concatenates two strings.', + parameters: [{name: 'String1', description: ''}, {name: 'String2', description: ''}], + }, + 'HF.DIVIDE': { + category: 'Operator', + shortDescription: 'Divides two values.', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}], + }, + 'HF.EQ': { + category: 'Operator', + shortDescription: 'Tests two values for equality.', + parameters: [{name: 'Value1', description: ''}, {name: 'Value2', description: ''}], + }, + 'HF.GT': { + category: 'Operator', + shortDescription: 'Tests two values for greater-than relation.', + parameters: [{name: 'Value1', description: ''}, {name: 'Value2', description: ''}], + }, + 'HF.GTE': { + category: 'Operator', + shortDescription: 'Tests two values for greater-equal relation.', + parameters: [{name: 'Value1', description: ''}, {name: 'Value2', description: ''}], + }, + 'HF.LT': { + category: 'Operator', + shortDescription: 'Tests two values for less-than relation.', + parameters: [{name: 'Value1', description: ''}, {name: 'Value2', description: ''}], + }, + 'HF.LTE': { + category: 'Operator', + shortDescription: 'Tests two values for less-equal relation.', + parameters: [{name: 'Value1', description: ''}, {name: 'Value2', description: ''}], + }, + 'HF.MINUS': { + category: 'Operator', + shortDescription: 'Subtracts two values.', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}], + }, + 'HF.MULTIPLY': { + category: 'Operator', + shortDescription: 'Multiplies two values.', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}], + }, + 'HF.NE': { + category: 'Operator', + shortDescription: 'Tests two values for inequality.', + parameters: [{name: 'Value1', description: ''}, {name: 'Value2', description: ''}], + }, + 'HF.POW': { + category: 'Operator', + shortDescription: 'Computes power of two values.', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}], + }, + 'HF.UMINUS': { + category: 'Operator', + shortDescription: 'Negates the value.', + parameters: [{name: 'Number', description: ''}], + }, + 'HF.UNARY_PERCENT': { + category: 'Operator', + shortDescription: 'Applies percent operator.', + parameters: [{name: 'Number', description: ''}], + }, + 'HF.UPLUS': { + category: 'Operator', + shortDescription: 'Applies unary plus.', + parameters: [{name: 'Number', description: ''}], + }, +} diff --git a/src/interpreter/functionMetadata/categories/statistical.ts b/src/interpreter/functionMetadata/categories/statistical.ts new file mode 100644 index 000000000..ca57025dd --- /dev/null +++ b/src/interpreter/functionMetadata/categories/statistical.ts @@ -0,0 +1,458 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +import {FunctionDoc} from '../FunctionDescription' + +/** + * Catalogue entries for the "Statistical" category. Generated from `docs/guide/built-in-functions.md` by + * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + */ +export const STATISTICAL_DOCS: Record = { + AVEDEV: { + category: 'Statistical', + shortDescription: 'Returns the average deviation of the arguments.', + parameters: [{name: 'Number1', description: ''}], + }, + AVERAGE: { + category: 'Statistical', + shortDescription: 'Returns the average of the arguments.', + parameters: [{name: 'Number1', description: ''}], + }, + AVERAGEA: { + category: 'Statistical', + shortDescription: 'Returns the average of the arguments.', + parameters: [{name: 'Value1', description: ''}], + }, + AVERAGEIF: { + category: 'Statistical', + shortDescription: 'Returns the arithmetic mean of all cells in a range that satisfy a given condition.', + parameters: [{name: 'Range', description: ''}, {name: 'Criterion', description: ''}, {name: 'Average_Range', description: ''}], + }, + BESSELI: { + category: 'Statistical', + shortDescription: 'Returns value of Bessel function.', + parameters: [{name: 'x', description: ''}, {name: 'n', description: ''}], + }, + BESSELJ: { + category: 'Statistical', + shortDescription: 'Returns value of Bessel function.', + parameters: [{name: 'x', description: ''}, {name: 'n', description: ''}], + }, + BESSELK: { + category: 'Statistical', + shortDescription: 'Returns value of Bessel function.', + parameters: [{name: 'x', description: ''}, {name: 'n', description: ''}], + }, + BESSELY: { + category: 'Statistical', + shortDescription: 'Returns value of Bessel function.', + parameters: [{name: 'x', description: ''}, {name: 'n', description: ''}], + }, + 'BETA.DIST': { + category: 'Statistical', + shortDescription: 'Returns the density of Beta distribution.', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Number3', description: ''}, {name: 'Boolean', description: ''}, {name: 'Number4', description: ''}, {name: 'Number5', description: ''}], + }, + 'BETA.INV': { + category: 'Statistical', + shortDescription: 'Returns the inverse Beta distribution value.', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Number3', description: ''}, {name: 'Number4', description: ''}, {name: 'Number5', description: ''}], + }, + 'BINOM.DIST': { + category: 'Statistical', + shortDescription: 'Returns density of binomial distribution.', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Number3', description: ''}, {name: 'Boolean', description: ''}], + }, + 'BINOM.INV': { + category: 'Statistical', + shortDescription: 'Returns inverse binomial distribution value.', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Number3', description: ''}], + }, + 'CHISQ.DIST': { + category: 'Statistical', + shortDescription: 'Returns value of chi-square distribution.', + parameters: [{name: 'X', description: ''}, {name: 'Degrees', description: ''}, {name: 'Mode', description: ''}], + }, + 'CHISQ.DIST.RT': { + category: 'Statistical', + shortDescription: 'Returns probability of chi-square right-side distribution.', + parameters: [{name: 'X', description: ''}, {name: 'Degrees', description: ''}], + }, + 'CHISQ.INV': { + category: 'Statistical', + shortDescription: 'Returns inverse of chi-square distribution.', + parameters: [{name: 'P', description: ''}, {name: 'Degrees', description: ''}], + }, + 'CHISQ.INV.RT': { + category: 'Statistical', + shortDescription: 'Returns inverse of chi-square right-side distribution.', + parameters: [{name: 'P', description: ''}, {name: 'Degrees', description: ''}], + }, + 'CHISQ.TEST': { + category: 'Statistical', + shortDescription: 'Returns chisquared-test value for a dataset.', + parameters: [{name: 'Array1', description: ''}, {name: 'Array2', description: ''}], + }, + 'CONFIDENCE.NORM': { + category: 'Statistical', + shortDescription: 'Returns upper confidence bound for normal distribution.', + parameters: [{name: 'Alpha', description: ''}, {name: 'Stdev', description: ''}, {name: 'Size', description: ''}], + }, + 'CONFIDENCE.T': { + category: 'Statistical', + shortDescription: 'Returns upper confidence bound for T distribution.', + parameters: [{name: 'Alpha', description: ''}, {name: 'Stdev', description: ''}, {name: 'Size', description: ''}], + }, + CORREL: { + category: 'Statistical', + shortDescription: 'Returns the correlation coefficient between two data sets.', + parameters: [{name: 'Data1', description: ''}, {name: 'Data2', description: ''}], + }, + COUNT: { + category: 'Statistical', + shortDescription: 'Counts how many numbers are in the list of arguments.', + parameters: [{name: 'Value1', description: ''}], + }, + COUNTA: { + category: 'Statistical', + shortDescription: 'Counts how many values are in the list of arguments.', + parameters: [{name: 'Value1', description: ''}], + }, + COUNTBLANK: { + category: 'Statistical', + shortDescription: 'Returns the number of empty cells.', + parameters: [{name: 'Range', description: ''}], + }, + COUNTIF: { + category: 'Statistical', + shortDescription: 'Returns the number of cells that meet with certain criteria within a cell range.', + parameters: [{name: 'Range', description: ''}, {name: 'Criteria', description: ''}], + }, + COUNTIFS: { + category: 'Statistical', + shortDescription: 'Returns the count of rows or columns that meet criteria in multiple ranges.', + parameters: [{name: 'Range1', description: ''}, {name: 'Criterion1', description: ''}], + }, + 'COVARIANCE.P': { + category: 'Statistical', + shortDescription: 'Returns the covariance between two data sets, population normalized.', + parameters: [{name: 'Data1', description: ''}, {name: 'Data2', description: ''}], + }, + 'COVARIANCE.S': { + category: 'Statistical', + shortDescription: 'Returns the covariance between two data sets, sample normalized.', + parameters: [{name: 'Data1', description: ''}, {name: 'Data2', description: ''}], + }, + DEVSQ: { + category: 'Statistical', + shortDescription: 'Returns sum of squared deviations.', + parameters: [{name: 'Number1', description: ''}], + }, + 'EXPON.DIST': { + category: 'Statistical', + shortDescription: 'Returns density of a exponential distribution.', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Boolean', description: ''}], + }, + 'F.DIST': { + category: 'Statistical', + shortDescription: 'Returns value of F distribution.', + parameters: [{name: 'X', description: ''}, {name: 'Degree1', description: ''}, {name: 'Degree2', description: ''}, {name: 'Mode', description: ''}], + }, + 'F.DIST.RT': { + category: 'Statistical', + shortDescription: 'Returns probability of F right-side distribution.', + parameters: [{name: 'X', description: ''}, {name: 'Degree1', description: ''}, {name: 'Degree2', description: ''}], + }, + 'F.INV': { + category: 'Statistical', + shortDescription: 'Returns inverse of F distribution.', + parameters: [{name: 'P', description: ''}, {name: 'Degree1', description: ''}, {name: 'Degree2', description: ''}], + }, + 'F.INV.RT': { + category: 'Statistical', + shortDescription: 'Returns inverse of F right-side distribution.', + parameters: [{name: 'P', description: ''}, {name: 'Degree1', description: ''}, {name: 'Degree2', description: ''}], + }, + 'F.TEST': { + category: 'Statistical', + shortDescription: 'Returns f-test value for a dataset.', + parameters: [{name: 'Array1', description: ''}, {name: 'Array2', description: ''}], + }, + FISHER: { + category: 'Statistical', + shortDescription: 'Returns Fisher transformation value.', + parameters: [{name: 'Number', description: ''}], + }, + FISHERINV: { + category: 'Statistical', + shortDescription: 'Returns inverse Fischer transformation value.', + parameters: [{name: 'Number', description: ''}], + }, + GAMMA: { + category: 'Statistical', + shortDescription: 'Returns value of Gamma function.', + parameters: [{name: 'Number', description: ''}], + }, + 'GAMMA.DIST': { + category: 'Statistical', + shortDescription: 'Returns density of Gamma distribution.', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Number3', description: ''}, {name: 'Boolean', description: ''}], + }, + 'GAMMA.INV': { + category: 'Statistical', + shortDescription: 'Returns inverse Gamma distribution value.', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Number3', description: ''}], + }, + GAMMALN: { + category: 'Statistical', + shortDescription: 'Returns natural logarithm of Gamma function.', + parameters: [{name: 'Number', description: ''}], + }, + GAUSS: { + category: 'Statistical', + shortDescription: 'Returns the probability of gaussian variable falling more than this many times standard deviation from mean.', + parameters: [{name: 'Number', description: ''}], + }, + GEOMEAN: { + category: 'Statistical', + shortDescription: 'Returns the geometric average.', + parameters: [{name: 'Number1', description: ''}], + }, + HARMEAN: { + category: 'Statistical', + shortDescription: 'Returns the harmonic average.', + parameters: [{name: 'Number1', description: ''}], + }, + 'HYPGEOM.DIST': { + category: 'Statistical', + shortDescription: 'Returns density of hypergeometric distribution.', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Number3', description: ''}, {name: 'Number4', description: ''}, {name: 'Boolean', description: ''}], + }, + LARGE: { + category: 'Statistical', + shortDescription: 'Returns k-th largest value in a range.', + parameters: [{name: 'Range', description: ''}, {name: 'K', description: ''}], + }, + 'LOGNORM.DIST': { + category: 'Statistical', + shortDescription: 'Returns density of lognormal distribution.', + parameters: [{name: 'X', description: ''}, {name: 'Mean', description: ''}, {name: 'Stddev', description: ''}, {name: 'Mode', description: ''}], + }, + 'LOGNORM.INV': { + category: 'Statistical', + shortDescription: 'Returns value of inverse lognormal distribution.', + parameters: [{name: 'P', description: ''}, {name: 'Mean', description: ''}, {name: 'Stddev', description: ''}], + }, + MAX: { + category: 'Statistical', + shortDescription: 'Returns the maximum value in a list of arguments.', + parameters: [{name: 'Number1', description: ''}], + }, + MAXA: { + category: 'Statistical', + shortDescription: 'Returns the maximum value in a list of arguments.', + parameters: [{name: 'Value1', description: ''}], + }, + MAXIFS: { + category: 'Statistical', + shortDescription: 'Returns the maximum value of the cells in a range that meet a set of criteria.', + parameters: [{name: 'Max_Range', description: ''}, {name: 'Criterion_range1', description: ''}, {name: 'Criterion1', description: ''}], + }, + MEDIAN: { + category: 'Statistical', + shortDescription: 'Returns the median of a set of numbers.', + parameters: [{name: 'Number1', description: ''}], + }, + MIN: { + category: 'Statistical', + shortDescription: 'Returns the minimum value in a list of arguments.', + parameters: [{name: 'Number1', description: ''}], + }, + MINA: { + category: 'Statistical', + shortDescription: 'Returns the minimum value in a list of arguments.', + parameters: [{name: 'Value1', description: ''}], + }, + MINIFS: { + category: 'Statistical', + shortDescription: 'Returns the minimum value of the cells in a range that meet a set of criteria.', + parameters: [{name: 'Min_Range', description: ''}, {name: 'Criterion_range1', description: ''}, {name: 'Criterion1', description: ''}], + }, + 'NEGBINOM.DIST': { + category: 'Statistical', + shortDescription: 'Returns density of negative binomial distribution.', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Number3', description: ''}, {name: 'Mode', description: ''}], + }, + 'NORM.DIST': { + category: 'Statistical', + shortDescription: 'Returns density of normal distribution.', + parameters: [{name: 'X', description: ''}, {name: 'Mean', description: ''}, {name: 'Stddev', description: ''}, {name: 'Mode', description: ''}], + }, + 'NORM.INV': { + category: 'Statistical', + shortDescription: 'Returns value of inverse normal distribution.', + parameters: [{name: 'P', description: ''}, {name: 'Mean', description: ''}, {name: 'Stddev', description: ''}], + }, + 'NORM.S.DIST': { + category: 'Statistical', + shortDescription: 'Returns density of normal distribution.', + parameters: [{name: 'X', description: ''}, {name: 'Mode', description: ''}], + }, + 'NORM.S.INV': { + category: 'Statistical', + shortDescription: 'Returns value of inverse normal distribution.', + parameters: [{name: 'P', description: ''}], + }, + 'PERCENTILE.EXC': { + category: 'Statistical', + shortDescription: 'Returns the k-th percentile of values in a range, exclusive of 0 and 1.', + parameters: [{name: 'Data', description: ''}, {name: 'K', description: ''}], + }, + 'PERCENTILE.INC': { + category: 'Statistical', + shortDescription: 'Returns the k-th percentile of values in a range, inclusive of 0 and 1.', + parameters: [{name: 'Data', description: ''}, {name: 'K', description: ''}], + }, + PHI: { + category: 'Statistical', + shortDescription: 'Returns probability densitity of normal distribution.', + parameters: [{name: 'X', description: ''}], + }, + 'POISSON.DIST': { + category: 'Statistical', + shortDescription: 'Returns density of Poisson distribution.', + parameters: [{name: 'X', description: ''}, {name: 'Mean', description: ''}, {name: 'Mode', description: ''}], + }, + 'QUARTILE.EXC': { + category: 'Statistical', + shortDescription: 'Returns the quartile of a data set, based on exclusive percentile values.', + parameters: [{name: 'Data', description: ''}, {name: 'Quart', description: ''}], + }, + 'QUARTILE.INC': { + category: 'Statistical', + shortDescription: 'Returns the quartile of a data set, based on inclusive percentile values.', + parameters: [{name: 'Data', description: ''}, {name: 'Quart', description: ''}], + }, + RSQ: { + category: 'Statistical', + shortDescription: 'Returns the squared correlation coefficient between two data sets.', + parameters: [{name: 'Data1', description: ''}, {name: 'Data2', description: ''}], + }, + SKEW: { + category: 'Statistical', + shortDescription: 'Returns skeweness of a sample.', + parameters: [{name: 'Number1', description: ''}], + }, + 'SKEW.P': { + category: 'Statistical', + shortDescription: 'Returns skeweness of a population.', + parameters: [{name: 'Number1', description: ''}], + }, + SLOPE: { + category: 'Statistical', + shortDescription: 'Returns the slope of a linear regression line.', + parameters: [{name: 'Array1', description: ''}, {name: 'Array2', description: ''}], + }, + SMALL: { + category: 'Statistical', + shortDescription: 'Returns k-th smallest value in a range.', + parameters: [{name: 'Range', description: ''}, {name: 'K', description: ''}], + }, + STANDARDIZE: { + category: 'Statistical', + shortDescription: 'Returns normalized value wrt expected value and standard deviation.', + parameters: [{name: 'X', description: ''}, {name: 'Mean', description: ''}, {name: 'Stddev', description: ''}], + }, + 'STDEV.P': { + category: 'Statistical', + shortDescription: 'Returns standard deviation of a population.', + parameters: [{name: 'Value1', description: ''}], + }, + 'STDEV.S': { + category: 'Statistical', + shortDescription: 'Returns standard deviation of a sample.', + parameters: [{name: 'Value1', description: ''}], + }, + STDEVA: { + category: 'Statistical', + shortDescription: 'Returns standard deviation of a sample.', + parameters: [{name: 'Value1', description: ''}], + }, + STDEVPA: { + category: 'Statistical', + shortDescription: 'Returns standard deviation of a population.', + parameters: [{name: 'Value1', description: ''}], + }, + STEYX: { + category: 'Statistical', + shortDescription: 'Returns standard error for predicted of the predicted y value for each x value.', + parameters: [{name: 'Array1', description: ''}, {name: 'Array2', description: ''}], + }, + 'T.DIST': { + category: 'Statistical', + shortDescription: 'Returns density of Student-t distribution.', + parameters: [{name: 'X', description: ''}, {name: 'Degrees', description: ''}, {name: 'Mode', description: ''}], + }, + 'T.DIST.2T': { + category: 'Statistical', + shortDescription: 'Returns density of Student-t distribution, both-sided.', + parameters: [{name: 'X', description: ''}, {name: 'Degrees', description: ''}], + }, + 'T.DIST.RT': { + category: 'Statistical', + shortDescription: 'Returns density of Student-t distribution, right-tailed.', + parameters: [{name: 'X', description: ''}, {name: 'Degrees', description: ''}], + }, + 'T.INV': { + category: 'Statistical', + shortDescription: 'Returns inverse Student-t distribution.', + parameters: [{name: 'P', description: ''}, {name: 'Degrees', description: ''}], + }, + 'T.INV.2T': { + category: 'Statistical', + shortDescription: 'Returns inverse Student-t distribution, both-sided.', + parameters: [{name: 'P', description: ''}, {name: 'Degrees', description: ''}], + }, + 'T.TEST': { + category: 'Statistical', + shortDescription: 'Returns t-test value for a dataset.', + parameters: [{name: 'Array1', description: ''}, {name: 'Array2', description: ''}, {name: 'Tails', description: ''}, {name: 'Type', description: ''}], + }, + TDIST: { + category: 'Statistical', + shortDescription: 'Returns density of Student-t distribution, both-sided or right-tailed.', + parameters: [{name: 'X', description: ''}, {name: 'Degrees', description: ''}, {name: 'Mode', description: ''}], + }, + 'VAR.P': { + category: 'Statistical', + shortDescription: 'Returns variance of a population.', + parameters: [{name: 'Value1', description: ''}], + }, + 'VAR.S': { + category: 'Statistical', + shortDescription: 'Returns variance of a sample.', + parameters: [{name: 'Value1', description: ''}], + }, + VARA: { + category: 'Statistical', + shortDescription: 'Returns variance of a sample.', + parameters: [{name: 'Value1', description: ''}], + }, + VARPA: { + category: 'Statistical', + shortDescription: 'Returns variance of a population.', + parameters: [{name: 'Value1', description: ''}], + }, + 'WEIBULL.DIST': { + category: 'Statistical', + shortDescription: 'Returns density of Weibull distribution.', + parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Number3', description: ''}, {name: 'Boolean', description: ''}], + }, + 'Z.TEST': { + category: 'Statistical', + shortDescription: 'Returns z-test value for a dataset.', + parameters: [{name: 'Array', description: ''}, {name: 'X', description: ''}, {name: 'Sigma', description: ''}], + }, +} diff --git a/src/interpreter/functionMetadata/categories/text.ts b/src/interpreter/functionMetadata/categories/text.ts new file mode 100644 index 000000000..5b19fe850 --- /dev/null +++ b/src/interpreter/functionMetadata/categories/text.ts @@ -0,0 +1,143 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +import {FunctionDoc} from '../FunctionDescription' + +/** + * Catalogue entries for the "Text" category. Generated from `docs/guide/built-in-functions.md` by + * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + */ +export const TEXT_DOCS: Record = { + CHAR: { + category: 'Text', + shortDescription: 'Converts a number into a character according to the current code table.', + parameters: [{name: 'Number', description: ''}], + }, + CLEAN: { + category: 'Text', + shortDescription: 'Returns text that has been "cleaned" of line breaks and other non-printable characters.', + parameters: [{name: 'Text', description: ''}], + }, + CODE: { + category: 'Text', + shortDescription: 'Returns a numeric code for the first character in a text string.', + parameters: [{name: 'Text', description: ''}], + }, + CONCATENATE: { + category: 'Text', + shortDescription: 'Combines several text strings into one string.', + parameters: [{name: 'Text1', description: ''}], + }, + EXACT: { + category: 'Text', + shortDescription: 'Returns TRUE if both text strings are exactly the same.', + parameters: [{name: 'Text1', description: ''}, {name: 'Text2', description: ''}], + }, + FIND: { + category: 'Text', + shortDescription: 'Returns the location of one text string inside another.', + parameters: [{name: 'Text1', description: ''}, {name: 'Text2', description: ''}, {name: 'Number', description: ''}], + }, + LEFT: { + category: 'Text', + shortDescription: 'Extracts a given number of characters from the left side of a text string.', + parameters: [{name: 'Text', description: ''}, {name: 'Number', description: ''}], + }, + LEN: { + category: 'Text', + shortDescription: 'Returns length of a given text.', + parameters: [{name: 'Text', description: ''}], + }, + LOWER: { + category: 'Text', + shortDescription: 'Returns text converted to lowercase.', + parameters: [{name: 'Text', description: ''}], + }, + MID: { + category: 'Text', + shortDescription: 'Returns substring of a given length starting from Start_position.', + parameters: [{name: 'Text', description: ''}, {name: 'Start_position', description: ''}, {name: 'Length', description: ''}], + }, + N: { + category: 'Text', + shortDescription: 'Converts a value to a number.', + parameters: [{name: 'Value', description: ''}], + }, + PROPER: { + category: 'Text', + shortDescription: 'Capitalizes words given text string.', + parameters: [{name: 'Text', description: ''}], + }, + REPLACE: { + category: 'Text', + shortDescription: 'Replaces substring of a text of a given length that starts at given position.', + parameters: [{name: 'Text', description: ''}, {name: 'Start_position', description: ''}, {name: 'Length', description: ''}, {name: 'New_text', description: ''}], + }, + REPT: { + category: 'Text', + shortDescription: 'Repeats text a given number of times.', + parameters: [{name: 'Text', description: ''}, {name: 'Number', description: ''}], + }, + RIGHT: { + category: 'Text', + shortDescription: 'Extracts a given number of characters from the right side of a text string.', + parameters: [{name: 'Text', description: ''}, {name: 'Number', description: ''}], + }, + SEARCH: { + category: 'Text', + shortDescription: 'Returns the location of Search_string inside Text. Case-insensitive. Allows the use of wildcards.', + parameters: [{name: 'Search_string', description: ''}, {name: 'Text', description: ''}, {name: 'Start_position', description: ''}], + }, + SPLIT: { + category: 'Text', + shortDescription: 'Divides the provided text using the space character as a separator and returns the substring at the zero-based position specified by the second argument.
`SPLIT("Lorem ipsum", 0) -> "Lorem"`
`SPLIT("Lorem ipsum", 1) -> "ipsum"`', + parameters: [{name: 'Text', description: ''}, {name: 'Index', description: ''}], + }, + SUBSTITUTE: { + category: 'Text', + shortDescription: 'Returns string where occurrences of Old_text are replaced by New_text. Replaces only specific occurrence if last parameter is provided.', + parameters: [{name: 'Text', description: ''}, {name: 'Old_text', description: ''}, {name: 'New_text', description: ''}, {name: 'Occurrence', description: ''}], + }, + T: { + category: 'Text', + shortDescription: 'Returns text if given value is text, empty string otherwise.', + parameters: [{name: 'Value', description: ''}], + }, + TEXT: { + category: 'Text', + shortDescription: 'Converts a number into text according to a given format.
By default, accepts the same formats that can be passed to the [`dateFormats`](../api/interfaces/configparams.md#dateformats) option, but can be further customized with the [`stringifyDateTime`](../api/interfaces/configparams.md#stringifydatetime) option.', + parameters: [{name: 'Number', description: ''}, {name: 'Format', description: ''}], + }, + TEXTJOIN: { + category: 'Text', + shortDescription: 'Joins text from multiple strings and/or ranges with a delimiter. Supports array/range delimiters that cycle through gaps. When ignore_empty is TRUE, empty strings are skipped. Returns #VALUE! if result exceeds 32,767 characters.', + parameters: [{name: 'Delimiter', description: ''}, {name: 'Ignore_empty', description: ''}, {name: 'Text1', description: ''}], + }, + TRIM: { + category: 'Text', + shortDescription: 'Strips extra spaces from text.', + parameters: [{name: 'Text', description: ''}], + }, + UNICHAR: { + category: 'Text', + shortDescription: 'Returns the character created by using provided code point.', + parameters: [{name: 'Number', description: ''}], + }, + UNICODE: { + category: 'Text', + shortDescription: 'Returns the Unicode code point of a first character of a text.', + parameters: [{name: 'Text', description: ''}], + }, + UPPER: { + category: 'Text', + shortDescription: 'Returns text converted to uppercase.', + parameters: [{name: 'Text', description: ''}], + }, + VALUE: { + category: 'Text', + shortDescription: 'Parses a number, date, time, datetime, currency, or percentage from a text string.', + parameters: [{name: 'Text', description: ''}], + }, +} diff --git a/src/interpreter/functionMetadata/index.ts b/src/interpreter/functionMetadata/index.ts index 6faacbc6f..fe2c5d0d6 100644 --- a/src/interpreter/functionMetadata/index.ts +++ b/src/interpreter/functionMetadata/index.ts @@ -4,16 +4,38 @@ */ import {FunctionDoc} from './FunctionDescription' -import {MATH_AND_TRIGONOMETRY_DOCS} from './categories/math-and-trigonometry' +import {ARRAY_MANIPULATION_DOCS} from './categories/array-manipulation' +import {DATABASE_DOCS} from './categories/database' +import {DATE_AND_TIME_DOCS} from './categories/date-and-time' +import {ENGINEERING_DOCS} from './categories/engineering' +import {FINANCIAL_DOCS} from './categories/financial' +import {INFORMATION_DOCS} from './categories/information' import {LOGICAL_DOCS} from './categories/logical' +import {LOOKUP_AND_REFERENCE_DOCS} from './categories/lookup-and-reference' +import {MATH_AND_TRIGONOMETRY_DOCS} from './categories/math-and-trigonometry' +import {MATRIX_FUNCTIONS_DOCS} from './categories/matrix-functions' +import {OPERATOR_DOCS} from './categories/operator' +import {STATISTICAL_DOCS} from './categories/statistical' +import {TEXT_DOCS} from './categories/text' export * from './FunctionDescription' /** * Canonical-id-keyed catalogue of human-readable function metadata, composed from the per-category files. - * Coverage of the whole canonical set is enforced by test, not by convention. + * Generated by `scripts/hf249-migrate-function-docs.ts`. Coverage of the whole canonical set is enforced by test. */ export const FUNCTION_DOCS: Record = { - ...MATH_AND_TRIGONOMETRY_DOCS, + ...ARRAY_MANIPULATION_DOCS, + ...DATABASE_DOCS, + ...DATE_AND_TIME_DOCS, + ...ENGINEERING_DOCS, + ...FINANCIAL_DOCS, + ...INFORMATION_DOCS, ...LOGICAL_DOCS, + ...LOOKUP_AND_REFERENCE_DOCS, + ...MATH_AND_TRIGONOMETRY_DOCS, + ...MATRIX_FUNCTIONS_DOCS, + ...OPERATOR_DOCS, + ...STATISTICAL_DOCS, + ...TEXT_DOCS, } From 58185f19ca027fc074847032cf2a03cec6604c62 Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Tue, 9 Jun 2026 12:34:05 +0000 Subject: [PATCH 08/35] docs(metadata): document getAvailableFunctions/getFunctionDetails (HF-249) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a CHANGELOG entry for the new built-in function metadata API, and a "Function metadata" section to the custom functions guide clarifying that the catalogue covers built-ins only — custom functions are absent from getAvailableFunctions() and getFunctionDetails() returns undefined for them. --- CHANGELOG.md | 1 + docs/guide/custom-functions.md | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 683e1da14..9b7295921 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Added +- Added the `getAvailableFunctions()` and `getFunctionDetails()` methods (both static and instance) for retrieving built-in function metadata: category, translated name, short description, generated syntax, and parameters. - Added an Indonesian (Bahasa Indonesia) language pack. [#1674](https://github.com/handsontable/hyperformula/pull/1674) ## [3.3.0] - 2026-05-20 diff --git a/docs/guide/custom-functions.md b/docs/guide/custom-functions.md index 49794b1d3..06fe409b3 100644 --- a/docs/guide/custom-functions.md +++ b/docs/guide/custom-functions.md @@ -538,3 +538,29 @@ MyCustomPlugin.translations = { }; ``` ::: + +## Function metadata + +HyperFormula ships metadata for its built-in functions (category, translated +name, short description, syntax, and parameters). You can retrieve it with the +`getAvailableFunctions()` and `getFunctionDetails()` methods, available both as +static methods and as instance methods: + +```js +// a short list of all built-in functions, with names translated for a language +const functions = HyperFormula.getAvailableFunctions('enGB'); + +// the full details of a single built-in function +const sumDetails = HyperFormula.getFunctionDetails('SUM', 'enGB'); +``` + +This metadata covers **built-in functions only**. Custom functions are not +included: they don't appear in the `getAvailableFunctions()` list, and +`getFunctionDetails()` returns `undefined` for them. + +```js +HyperFormula.registerFunctionPlugin(MyCustomPlugin, MyCustomPlugin.translations); + +// a custom function is not part of the built-in metadata +const details = HyperFormula.getFunctionDetails('MY_FUNCTION', 'enGB'); // undefined +``` From 3f8857b64a85c08ca70d957e7bf0f727bbff230e Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Wed, 10 Jun 2026 03:02:01 +0000 Subject: [PATCH 09/35] ci: retrigger after tests-branch cleanup (HF-249) From b78c11b4618b7365f0e9d32e18636f333e13619a Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Wed, 10 Jun 2026 06:49:09 +0000 Subject: [PATCH 10/35] fix(metadata): correct instance @category and guard catalogue arity drift (HF-249) --- src/HyperFormula.ts | 4 ++-- .../functionMetadata/buildFunctionDescriptions.ts | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/HyperFormula.ts b/src/HyperFormula.ts index c2dcd7daa..0b5d122fa 100644 --- a/src/HyperFormula.ts +++ b/src/HyperFormula.ts @@ -4440,7 +4440,7 @@ export class HyperFormula implements TypedEmitter { * const functions = hfInstance.getAvailableFunctions(); * ``` * - * @category Custom Functions + * @category Helpers */ public getAvailableFunctions(): FunctionListEntry[] { return HyperFormula.getAvailableFunctions(this._config.language) @@ -4463,7 +4463,7 @@ export class HyperFormula implements TypedEmitter { * const details = hfInstance.getFunctionDetails('SUMIF'); * ``` * - * @category Custom Functions + * @category Helpers */ public getFunctionDetails(canonicalName: string): FunctionDetails | undefined { return HyperFormula.getFunctionDetails(canonicalName, this._config.language) diff --git a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts index d3625a3cc..8ece69a48 100644 --- a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts +++ b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts @@ -90,8 +90,13 @@ export function buildFunctionListEntry(canonicalName: string, doc: FunctionDoc, * @param {FunctionDoc} doc - the function's authored catalogue entry * @param {StructuralMetadata} metadata - structural metadata from `implementedFunctions` * @param {TranslateName} translate - per-id translation lookup + * @throws {Error} when `doc.parameters.length` does not equal `(metadata.parameters ?? []).length` */ export function buildFunctionDetails(canonicalName: string, doc: FunctionDoc, metadata: StructuralMetadata, translate: TranslateName): FunctionDetails { + const implParamCount = (metadata.parameters ?? []).length + if (doc.parameters.length !== implParamCount) { + throw new Error(`Function metadata mismatch for ${canonicalName}: catalogue has ${doc.parameters.length} parameters, implementation has ${implParamCount}`) + } const name = resolveName(canonicalName, translate) const args = metadata.parameters ?? [] const repeatLastArgs = metadata.repeatLastArgs ?? 0 From abc7a1288307fde0aa7e6b5d4b989448e0a3d636 Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Wed, 10 Jun 2026 06:58:46 +0000 Subject: [PATCH 11/35] fix(metadata): degrade getFunctionDetails to undefined on catalogue drift (HF-249) --- src/HyperFormula.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/HyperFormula.ts b/src/HyperFormula.ts index 0b5d122fa..9d295d028 100644 --- a/src/HyperFormula.ts +++ b/src/HyperFormula.ts @@ -710,9 +710,16 @@ export class HyperFormula implements TypedEmitter { if (doc === undefined || plugin === undefined) { return undefined } + // Degrade gracefully when the catalogue and implementation have drifted out of sync (parameter + // count mismatch). buildFunctionDetails throws on drift so tests keep it loud; the public API + // returns undefined instead so callers never see an undocumented crash path. + const implMeta = plugin.implementedFunctions[canonicalName] + if (doc.parameters.length !== (implMeta.parameters ?? []).length) { + return undefined + } const language = this.getLanguage(code) const translate = (id: string) => language.getMaybeFunctionTranslation(id) - return buildFunctionDetails(canonicalName, doc, plugin.implementedFunctions[canonicalName], translate) + return buildFunctionDetails(canonicalName, doc, implMeta, translate) } /** From 385fc11ebfedec79c2fe6e0416570a2a30e84248 Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Wed, 10 Jun 2026 06:58:53 +0000 Subject: [PATCH 12/35] docs(metadata): link PR in CHANGELOG entry (HF-249) --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b7295921..d12805028 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Added -- Added the `getAvailableFunctions()` and `getFunctionDetails()` methods (both static and instance) for retrieving built-in function metadata: category, translated name, short description, generated syntax, and parameters. +- Added the `getAvailableFunctions()` and `getFunctionDetails()` methods (both static and instance) for retrieving built-in function metadata: category, translated name, short description, generated syntax, and parameters. [#1692](https://github.com/handsontable/hyperformula/pull/1692) - Added an Indonesian (Bahasa Indonesia) language pack. [#1674](https://github.com/handsontable/hyperformula/pull/1674) ## [3.3.0] - 2026-05-20 From 384ab7a04179ac81fe690ce84c0f32aed8b260b6 Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Wed, 10 Jun 2026 07:19:06 +0000 Subject: [PATCH 13/35] ci: retrigger after tests-branch matcher fix (HF-249) From d86f8696f42b4540b5a2b11c45e4d7b4a2fce864 Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Wed, 10 Jun 2026 11:10:48 +0000 Subject: [PATCH 14/35] fix(metadata): list only currently-registered functions, consistent with getFunctionDetails (HF-249) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit getAvailableFunctions derived its id set from each plugin class's static implementedFunctions, so an unregistered built-in (or a registry mutation) could still appear in the list while getFunctionDetails returned undefined for it. Gate the list on FunctionRegistry.getFunctionPlugin(id) — the same resolution getFunctionDetails uses — so list and details never disagree. (Cursor Bugbot, #1692.) --- src/HyperFormula.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/HyperFormula.ts b/src/HyperFormula.ts index 9d295d028..afd8c4d8e 100644 --- a/src/HyperFormula.ts +++ b/src/HyperFormula.ts @@ -678,7 +678,9 @@ export class HyperFormula implements TypedEmitter { const language = this.getLanguage(code) const translate = (id: string) => language.getMaybeFunctionTranslation(id) return getCanonicalFunctionIds(FunctionRegistry.getPlugins()) - .filter(id => FUNCTION_DOCS[id] !== undefined) + // documented AND still registered — gate on the same resolution `getFunctionDetails` uses, so the list never + // advertises a function the details lookup cannot resolve (e.g. after `unregisterFunction`). + .filter(id => FUNCTION_DOCS[id] !== undefined && FunctionRegistry.getFunctionPlugin(id) !== undefined) .map(id => buildFunctionListEntry(id, FUNCTION_DOCS[id], translate)) .sort((a, b) => a.category === b.category ? a.canonicalName.localeCompare(b.canonicalName) : a.category.localeCompare(b.category)) } From 4078a565ee9b229e73dc3c7f0f48fd8f68dd1fe9 Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Wed, 10 Jun 2026 11:36:47 +0000 Subject: [PATCH 15/35] ci: retrigger after tests-branch cursor fixes (HF-249) From c98e9b167daf9284e5e6551f5eff31f136158707 Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Wed, 10 Jun 2026 11:47:05 +0000 Subject: [PATCH 16/35] fix(metadata): share listability gate so getAvailableFunctions and getFunctionDetails agree (HF-249) getAvailableFunctions filtered on documented+registered but not the catalogue-vs-implementation arity check that getFunctionDetails applies, so a drifted function could appear in the list yet return undefined from details. Extract resolveListableMetadata (documented + registered + arity-consistent) and use it in both. (Cursor, #1692.) --- src/HyperFormula.ts | 46 +++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/src/HyperFormula.ts b/src/HyperFormula.ts index afd8c4d8e..e7f18b524 100644 --- a/src/HyperFormula.ts +++ b/src/HyperFormula.ts @@ -46,8 +46,8 @@ import {LicenseKeyValidityState} from './helpers/licenseKeyValidator' import {buildTranslationPackage, RawTranslationPackage, TranslationPackage} from './i18n' import {FunctionPluginDefinition} from './interpreter' import {FUNCTION_DOCS} from './interpreter/functionMetadata' -import {buildFunctionDetails, buildFunctionListEntry, getCanonicalFunctionIds} from './interpreter/functionMetadata/buildFunctionDescriptions' -import {FunctionDetails, FunctionListEntry} from './interpreter/functionMetadata/FunctionDescription' +import {buildFunctionDetails, buildFunctionListEntry, getCanonicalFunctionIds, StructuralMetadata} from './interpreter/functionMetadata/buildFunctionDescriptions' +import {FunctionDetails, FunctionDoc, FunctionListEntry} from './interpreter/functionMetadata/FunctionDescription' import {FunctionRegistry, FunctionTranslationsPackage} from './interpreter/FunctionRegistry' import {FormatInfo} from './interpreter/InterpreterValue' import {LazilyTransformingAstService} from './LazilyTransformingAstService' @@ -678,13 +678,33 @@ export class HyperFormula implements TypedEmitter { const language = this.getLanguage(code) const translate = (id: string) => language.getMaybeFunctionTranslation(id) return getCanonicalFunctionIds(FunctionRegistry.getPlugins()) - // documented AND still registered — gate on the same resolution `getFunctionDetails` uses, so the list never - // advertises a function the details lookup cannot resolve (e.g. after `unregisterFunction`). - .filter(id => FUNCTION_DOCS[id] !== undefined && FunctionRegistry.getFunctionPlugin(id) !== undefined) + // List only functions whose details `getFunctionDetails` can resolve — documented, currently registered, and + // with catalogue arity matching the implementation — so the list and the details never disagree. + .filter(id => this.resolveListableMetadata(id) !== undefined) .map(id => buildFunctionListEntry(id, FUNCTION_DOCS[id], translate)) .sort((a, b) => a.category === b.category ? a.canonicalName.localeCompare(b.canonicalName) : a.category.localeCompare(b.category)) } + /** + * Resolves a function's catalogue doc and structural metadata when it is listable: documented, currently + * registered, and with a catalogue parameter count equal to the implementation arity. Returns `undefined` + * otherwise. Shared by `getAvailableFunctions` and `getFunctionDetails` so the list and the details agree exactly. + * + * @param {string} canonicalName - the language-independent function id + */ + private static resolveListableMetadata(canonicalName: string): { doc: FunctionDoc, metadata: StructuralMetadata } | undefined { + const doc = FUNCTION_DOCS[canonicalName] + const plugin = FunctionRegistry.getFunctionPlugin(canonicalName) + if (doc === undefined || plugin === undefined) { + return undefined + } + const metadata = plugin.implementedFunctions[canonicalName] + if (doc.parameters.length !== (metadata.parameters ?? []).length) { + return undefined + } + return {doc, metadata} + } + /** * Returns the full metadata of a single built-in function for a given language, including the generated syntax and * per-parameter optionality and repeatability. Returns `undefined` when the function id is unknown or has no @@ -707,21 +727,15 @@ export class HyperFormula implements TypedEmitter { public static getFunctionDetails(canonicalName: string, code: string): FunctionDetails | undefined { validateArgToType(canonicalName, 'string', 'canonicalName') validateArgToType(code, 'string', 'code') - const doc = FUNCTION_DOCS[canonicalName] - const plugin = FunctionRegistry.getFunctionPlugin(canonicalName) - if (doc === undefined || plugin === undefined) { - return undefined - } - // Degrade gracefully when the catalogue and implementation have drifted out of sync (parameter - // count mismatch). buildFunctionDetails throws on drift so tests keep it loud; the public API - // returns undefined instead so callers never see an undocumented crash path. - const implMeta = plugin.implementedFunctions[canonicalName] - if (doc.parameters.length !== (implMeta.parameters ?? []).length) { + // Same gate as `getAvailableFunctions` (documented + registered + arity-consistent). Returns undefined for + // unknown/custom ids or catalogue-vs-implementation drift, so callers never hit the loud throw in buildFunctionDetails. + const resolved = this.resolveListableMetadata(canonicalName) + if (resolved === undefined) { return undefined } const language = this.getLanguage(code) const translate = (id: string) => language.getMaybeFunctionTranslation(id) - return buildFunctionDetails(canonicalName, doc, implMeta, translate) + return buildFunctionDetails(canonicalName, resolved.doc, resolved.metadata, translate) } /** From 767679071d26b6413d6de5e518b776e7ff963635 Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Tue, 23 Jun 2026 07:45:51 +0000 Subject: [PATCH 17/35] fix(metadata): Title-case parameter names for casing consistency (HF-249) Align parameter display names in the generated function-metadata catalogue with their Title-Case siblings: - financial.ts: CUMIPMT `type` -> `Type` (matches CUMPRINC); RATE `guess` -> `Guess` - statistical.ts: BESSELI/J/K/Y `x`,`n` -> `X`,`N` Also add an instance-method example to the "Function metadata" section of docs/guide/custom-functions.md so the "available both as static and instance methods" claim is backed by a snippet. Co-Authored-By: Claude Opus 4.8 --- docs/guide/custom-functions.md | 13 +++++++++++++ .../functionMetadata/categories/financial.ts | 4 ++-- .../functionMetadata/categories/statistical.ts | 8 ++++---- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/docs/guide/custom-functions.md b/docs/guide/custom-functions.md index 06fe409b3..7c9096215 100644 --- a/docs/guide/custom-functions.md +++ b/docs/guide/custom-functions.md @@ -554,6 +554,19 @@ const functions = HyperFormula.getAvailableFunctions('enGB'); const sumDetails = HyperFormula.getFunctionDetails('SUM', 'enGB'); ``` +The same methods are also available on an instance, where they use the +instance's configured language by default: + +```js +const hf = HyperFormula.buildEmpty({ language: 'enGB' }); + +// a short list of all built-in functions +const functions = hf.getAvailableFunctions(); + +// the full details of a single built-in function +const sumDetails = hf.getFunctionDetails('SUM'); +``` + This metadata covers **built-in functions only**. Custom functions are not included: they don't appear in the `getAvailableFunctions()` list, and `getFunctionDetails()` returns `undefined` for them. diff --git a/src/interpreter/functionMetadata/categories/financial.ts b/src/interpreter/functionMetadata/categories/financial.ts index bf1e6b7a2..1e5546844 100644 --- a/src/interpreter/functionMetadata/categories/financial.ts +++ b/src/interpreter/functionMetadata/categories/financial.ts @@ -13,7 +13,7 @@ export const FINANCIAL_DOCS: Record = { CUMIPMT: { category: 'Financial', shortDescription: 'Returns the cumulative interest paid on a loan between a start period and an end period.', - parameters: [{name: 'Rate', description: ''}, {name: 'Nper', description: ''}, {name: 'Pv', description: ''}, {name: 'Start', description: ''}, {name: 'End', description: ''}, {name: 'type', description: ''}], + parameters: [{name: 'Rate', description: ''}, {name: 'Nper', description: ''}, {name: 'Pv', description: ''}, {name: 'Start', description: ''}, {name: 'End', description: ''}, {name: 'Type', description: ''}], }, CUMPRINC: { category: 'Financial', @@ -113,7 +113,7 @@ export const FINANCIAL_DOCS: Record = { RATE: { category: 'Financial', shortDescription: 'Returns the interest rate per period of an annuity.', - parameters: [{name: 'Nper', description: ''}, {name: 'Pmt', description: ''}, {name: 'Pv', description: ''}, {name: 'Fv', description: ''}, {name: 'Type', description: ''}, {name: 'guess', description: ''}], + parameters: [{name: 'Nper', description: ''}, {name: 'Pmt', description: ''}, {name: 'Pv', description: ''}, {name: 'Fv', description: ''}, {name: 'Type', description: ''}, {name: 'Guess', description: ''}], }, RRI: { category: 'Financial', diff --git a/src/interpreter/functionMetadata/categories/statistical.ts b/src/interpreter/functionMetadata/categories/statistical.ts index ca57025dd..2e88fa8e3 100644 --- a/src/interpreter/functionMetadata/categories/statistical.ts +++ b/src/interpreter/functionMetadata/categories/statistical.ts @@ -33,22 +33,22 @@ export const STATISTICAL_DOCS: Record = { BESSELI: { category: 'Statistical', shortDescription: 'Returns value of Bessel function.', - parameters: [{name: 'x', description: ''}, {name: 'n', description: ''}], + parameters: [{name: 'X', description: ''}, {name: 'N', description: ''}], }, BESSELJ: { category: 'Statistical', shortDescription: 'Returns value of Bessel function.', - parameters: [{name: 'x', description: ''}, {name: 'n', description: ''}], + parameters: [{name: 'X', description: ''}, {name: 'N', description: ''}], }, BESSELK: { category: 'Statistical', shortDescription: 'Returns value of Bessel function.', - parameters: [{name: 'x', description: ''}, {name: 'n', description: ''}], + parameters: [{name: 'X', description: ''}, {name: 'N', description: ''}], }, BESSELY: { category: 'Statistical', shortDescription: 'Returns value of Bessel function.', - parameters: [{name: 'x', description: ''}, {name: 'n', description: ''}], + parameters: [{name: 'X', description: ''}, {name: 'N', description: ''}], }, 'BETA.DIST': { category: 'Statistical', From a7b5d97ce0c5c57769bbff27fa3841b228a5ef52 Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Tue, 23 Jun 2026 16:15:18 +0000 Subject: [PATCH 18/35] refactor(metadata): apply review feedback to function metadata API (HF-249) Address the CHANGES_REQUESTED review on #1692: - Rename the metadata name field to localizedName (FunctionListEntry, FunctionDetails). - Drop the generated syntax string; getFunctionDetails now returns the parameter list plus repeatLastArgs so the caller renders the syntax. - Surface repeatLastArgs as a number on FunctionDetails instead of a per-parameter repeatable boolean (the last N args may repeat). - Include custom functions and aliases: the instance methods read the instance's own registry; the static methods cover built-ins + aliases. - Sort getAvailableFunctions alphabetically by localizedName. - Verify categories against the official Excel docs categories; the ten with an Excel equivalent already match, three are HyperFormula-specific. - Update the custom-functions guide and the CHANGELOG entry. Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 2 +- docs/guide/custom-functions.md | 42 +++-- src/HyperFormula.ts | 150 ++++++++++++------ src/interpreter/FunctionRegistry.ts | 16 ++ .../functionMetadata/FunctionDescription.ts | 30 ++-- .../buildFunctionDescriptions.ts | 71 ++++++--- 6 files changed, 215 insertions(+), 96 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d12805028..e588716e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Added -- Added the `getAvailableFunctions()` and `getFunctionDetails()` methods (both static and instance) for retrieving built-in function metadata: category, translated name, short description, generated syntax, and parameters. [#1692](https://github.com/handsontable/hyperformula/pull/1692) +- Added the `getAvailableFunctions()` and `getFunctionDetails()` methods (both static and instance) for retrieving function metadata. [#1692](https://github.com/handsontable/hyperformula/pull/1692) - Added an Indonesian (Bahasa Indonesia) language pack. [#1674](https://github.com/handsontable/hyperformula/pull/1674) ## [3.3.0] - 2026-05-20 diff --git a/docs/guide/custom-functions.md b/docs/guide/custom-functions.md index 7c9096215..359e22ad1 100644 --- a/docs/guide/custom-functions.md +++ b/docs/guide/custom-functions.md @@ -541,39 +541,57 @@ MyCustomPlugin.translations = { ## Function metadata -HyperFormula ships metadata for its built-in functions (category, translated -name, short description, syntax, and parameters). You can retrieve it with the +HyperFormula exposes metadata about the functions it knows (category, translated +name, short description, and the parameter list). You can retrieve it with the `getAvailableFunctions()` and `getFunctionDetails()` methods, available both as static methods and as instance methods: ```js -// a short list of all built-in functions, with names translated for a language +// a short list of available functions, with names translated for a language const functions = HyperFormula.getAvailableFunctions('enGB'); -// the full details of a single built-in function +// the full details of a single function const sumDetails = HyperFormula.getFunctionDetails('SUM', 'enGB'); ``` +`getAvailableFunctions()` returns entries sorted alphabetically by their +localized name, each with `localizedName`, `canonicalName`, `category`, and +`shortDescription`. `getFunctionDetails()` returns the same fields plus the +ordered `parameters` list (each with `name`, `description`, and `optional`) and +`repeatLastArgs` — the number of trailing parameters that repeat for functions +with a variable number of arguments (`0` for a fixed argument list). The +methods do not return a pre-rendered syntax string; build it from `parameters` +and `repeatLastArgs` as your UI needs. + The same methods are also available on an instance, where they use the instance's configured language by default: ```js const hf = HyperFormula.buildEmpty({ language: 'enGB' }); -// a short list of all built-in functions +// a short list of available functions const functions = hf.getAvailableFunctions(); -// the full details of a single built-in function +// the full details of a single function const sumDetails = hf.getFunctionDetails('SUM'); ``` -This metadata covers **built-in functions only**. Custom functions are not -included: they don't appear in the `getAvailableFunctions()` list, and -`getFunctionDetails()` returns `undefined` for them. +Both built-in functions and their aliases are included. Custom (user-registered) +functions are registered per instance, so they are listed by the **instance** +methods, not by the static ones — the static methods only see the globally +registered built-ins and their aliases. A custom function has no shipped +catalogue entry, so its `category` is `undefined`, its `shortDescription` is +empty, and its parameters are reported positionally (`Arg1`, `Arg2`, ...). ```js -HyperFormula.registerFunctionPlugin(MyCustomPlugin, MyCustomPlugin.translations); +const hf = HyperFormula.buildEmpty({ + language: 'enGB', + functionPlugins: [MyCustomPlugin], +}); + +// the instance methods include the custom function +const details = hf.getFunctionDetails('MY_FUNCTION'); // { canonicalName: 'MY_FUNCTION', category: undefined, ... } -// a custom function is not part of the built-in metadata -const details = HyperFormula.getFunctionDetails('MY_FUNCTION', 'enGB'); // undefined +// the static methods do not, as custom functions are instance-scoped +const staticDetails = HyperFormula.getFunctionDetails('MY_FUNCTION', 'enGB'); // undefined ``` diff --git a/src/HyperFormula.ts b/src/HyperFormula.ts index a2956ca72..56ea68c84 100644 --- a/src/HyperFormula.ts +++ b/src/HyperFormula.ts @@ -46,7 +46,7 @@ import {LicenseKeyValidityState} from './helpers/licenseKeyValidator' import {buildTranslationPackage, RawTranslationPackage, TranslationPackage} from './i18n' import {FunctionPluginDefinition} from './interpreter' import {FUNCTION_DOCS} from './interpreter/functionMetadata' -import {buildFunctionDetails, buildFunctionListEntry, getCanonicalFunctionIds, StructuralMetadata} from './interpreter/functionMetadata/buildFunctionDescriptions' +import {buildCustomFunctionDetails, buildCustomFunctionListEntry, buildFunctionDetails, buildFunctionListEntry, StructuralMetadata} from './interpreter/functionMetadata/buildFunctionDescriptions' import {FunctionDetails, FunctionDoc, FunctionListEntry} from './interpreter/functionMetadata/FunctionDescription' import {FunctionRegistry, FunctionTranslationsPackage} from './interpreter/FunctionRegistry' import {FormatInfo} from './interpreter/InterpreterValue' @@ -653,12 +653,13 @@ export class HyperFormula implements TypedEmitter { } /** - * Returns metadata of all built-in functions available for a given language, as a short list suitable for a function - * picker. Each entry contains the translated name, the language-independent canonical name, the category, and a short - * description. + * Returns metadata of all functions available for a given language, as a short list suitable for a function + * picker. Each entry contains the translated name, the language-independent canonical name, the category, and a + * short description. Entries are sorted alphabetically by their localized name. * - * Only documented built-in functions are listed; custom (user-registered) functions are not included. The list is - * sorted by category, then by canonical name. + * The static method covers the globally-registered built-in functions and their aliases. Custom (user-registered) + * functions are instance-scoped, so they are listed only by the instance method [[getAvailableFunctions]], not by + * this static one. * * @param {string} code - language code, e.g. `'enGB'` * @@ -676,39 +677,20 @@ export class HyperFormula implements TypedEmitter { public static getAvailableFunctions(code: string): FunctionListEntry[] { validateArgToType(code, 'string', 'code') const language = this.getLanguage(code) - const translate = (id: string) => language.getMaybeFunctionTranslation(id) - return getCanonicalFunctionIds(FunctionRegistry.getPlugins()) - // List only functions whose details `getFunctionDetails` can resolve — documented, currently registered, and - // with catalogue arity matching the implementation — so the list and the details never disagree. - .filter(id => this.resolveListableMetadata(id) !== undefined) - .map(id => buildFunctionListEntry(id, FUNCTION_DOCS[id], translate)) - .sort((a, b) => a.category === b.category ? a.canonicalName.localeCompare(b.canonicalName) : a.category.localeCompare(b.category)) + return HyperFormula.buildAvailableFunctions( + FunctionRegistry.getListableFunctionIds(), + (id) => FunctionRegistry.getFunctionPlugin(id), + language, + ) } /** - * Resolves a function's catalogue doc and structural metadata when it is listable: documented, currently - * registered, and with a catalogue parameter count equal to the implementation arity. Returns `undefined` - * otherwise. Shared by `getAvailableFunctions` and `getFunctionDetails` so the list and the details agree exactly. + * Returns the full metadata of a single function for a given language: the parameter list (with per-parameter + * optionality), the number of trailing parameters that repeat (`repeatLastArgs`), the category and a short + * description. Returns `undefined` when the function id is unknown or not registered. * - * @param {string} canonicalName - the language-independent function id - */ - private static resolveListableMetadata(canonicalName: string): { doc: FunctionDoc, metadata: StructuralMetadata } | undefined { - const doc = FUNCTION_DOCS[canonicalName] - const plugin = FunctionRegistry.getFunctionPlugin(canonicalName) - if (doc === undefined || plugin === undefined) { - return undefined - } - const metadata = plugin.implementedFunctions[canonicalName] - if (doc.parameters.length !== (metadata.parameters ?? []).length) { - return undefined - } - return {doc, metadata} - } - - /** - * Returns the full metadata of a single built-in function for a given language, including the generated syntax and - * per-parameter optionality and repeatability. Returns `undefined` when the function id is unknown or has no - * documentation (e.g. a custom function). + * The static method resolves the globally-registered built-in functions and their aliases. For custom + * (user-registered) functions, use the instance method [[getFunctionDetails]]. * * @param {string} canonicalName - the language-independent function id, e.g. `'SUMIF'` * @param {string} code - language code, e.g. `'enGB'` @@ -727,15 +709,71 @@ export class HyperFormula implements TypedEmitter { public static getFunctionDetails(canonicalName: string, code: string): FunctionDetails | undefined { validateArgToType(canonicalName, 'string', 'canonicalName') validateArgToType(code, 'string', 'code') - // Same gate as `getAvailableFunctions` (documented + registered + arity-consistent). Returns undefined for - // unknown/custom ids or catalogue-vs-implementation drift, so callers never hit the loud throw in buildFunctionDetails. - const resolved = this.resolveListableMetadata(canonicalName) + const language = this.getLanguage(code) + return HyperFormula.buildFunctionDetailsFor(canonicalName, FunctionRegistry.getFunctionPlugin(canonicalName), language) + } + + /** + * Resolves the structural metadata and catalogue doc for a registered function id, following aliases to their + * target. Returns `undefined` when the id is not registered or its catalogue doc disagrees with the implementation + * arity (catalogue drift). When the id is registered but has no catalogue doc (a custom function), `doc` is + * `undefined` and only the structural metadata is available. Shared by the list and the details builders so they + * always agree. The `getPlugin` callback abstracts over the static and the instance registry. + * + * @param {string} functionId - the language-independent function id (canonical id or alias) + * @param {FunctionPluginDefinition | undefined} plugin - the plugin registered for `functionId`, or `undefined` + */ + private static resolveFunctionMetadata(functionId: string, plugin: FunctionPluginDefinition | undefined): { doc: FunctionDoc | undefined, metadata: StructuralMetadata } | undefined { + if (plugin === undefined) { + return undefined + } + // An alias shares its target's implementation metadata and catalogue doc, but keeps its own (alias) name. + const metadataKey = plugin.aliases?.[functionId] ?? functionId + const metadata = plugin.implementedFunctions[metadataKey] + if (metadata === undefined) { + return undefined + } + const doc = FUNCTION_DOCS[metadataKey] + if (doc !== undefined && doc.parameters.length !== (metadata.parameters ?? []).length) { + // Catalogue drift: drop from both the list and the details so they never disagree. + return undefined + } + return {doc, metadata} + } + + /** + * Builds the function list for a set of registered ids. Documented functions use their catalogue entry; custom + * functions are listed with their name only. Sorted alphabetically by localized name. + */ + private static buildAvailableFunctions(functionIds: string[], getPlugin: (id: string) => FunctionPluginDefinition | undefined, language: TranslationPackage): FunctionListEntry[] { + const translate = (id: string) => language.getMaybeFunctionTranslation(id) + return functionIds + .map(id => { + const resolved = HyperFormula.resolveFunctionMetadata(id, getPlugin(id)) + if (resolved === undefined) { + return undefined + } + return resolved.doc !== undefined + ? buildFunctionListEntry(id, resolved.doc, translate) + : buildCustomFunctionListEntry(id, translate) + }) + .filter((entry): entry is FunctionListEntry => entry !== undefined) + .sort((a, b) => a.localizedName.localeCompare(b.localizedName)) + } + + /** + * Builds the full details for a single registered id, or `undefined` when it is unknown/not registered. + * Documented functions use their catalogue entry; custom functions report their structural metadata only. + */ + private static buildFunctionDetailsFor(functionId: string, plugin: FunctionPluginDefinition | undefined, language: TranslationPackage): FunctionDetails | undefined { + const resolved = HyperFormula.resolveFunctionMetadata(functionId, plugin) if (resolved === undefined) { return undefined } - const language = this.getLanguage(code) const translate = (id: string) => language.getMaybeFunctionTranslation(id) - return buildFunctionDetails(canonicalName, resolved.doc, resolved.metadata, translate) + return resolved.doc !== undefined + ? buildFunctionDetails(functionId, resolved.doc, resolved.metadata, translate) + : buildCustomFunctionDetails(functionId, resolved.metadata, translate) } /** @@ -4455,12 +4493,14 @@ export class HyperFormula implements TypedEmitter { } /** - * Returns metadata of all built-in functions available for a function picker, with names translated according to the - * language set in this instance's configuration. Each entry contains the translated name, the language-independent - * canonical name, the category, and a short description. + * Returns metadata of all functions available in this instance for a function picker, with names translated + * according to the language set in this instance's configuration. Each entry contains the translated name, the + * language-independent canonical name, the category, and a short description. Entries are sorted alphabetically by + * their localized name. * - * Only documented built-in functions are listed; custom (user-registered) functions are not included. The list is - * sorted by category, then by canonical name. + * The list reflects this instance's own registry: the built-in functions and any custom (user-registered) + * functions, plus their aliases. Custom functions ship no catalogue entry, so their `category` is `undefined` and + * their `shortDescription` is empty. * * @example * ```js @@ -4473,13 +4513,21 @@ export class HyperFormula implements TypedEmitter { * @category Helpers */ public getAvailableFunctions(): FunctionListEntry[] { - return HyperFormula.getAvailableFunctions(this._config.language) + const language = HyperFormula.getLanguage(this._config.language) + return HyperFormula.buildAvailableFunctions( + this._functionRegistry.getListableFunctionIds(), + (id) => this._functionRegistry.getFunctionPlugin(id), + language, + ) } /** - * Returns the full metadata of a single built-in function, with names translated according to the language set in - * this instance's configuration, including the generated syntax and per-parameter optionality and repeatability. - * Returns `undefined` when the function id is unknown or has no documentation (e.g. a custom function). + * Returns the full metadata of a single function registered in this instance, with names translated according to + * the language set in this instance's configuration: the parameter list (with per-parameter optionality), the + * number of trailing parameters that repeat (`repeatLastArgs`), the category and a short description. Resolves both + * built-in and custom (user-registered) functions, as well as aliases. Returns `undefined` when the function id is + * unknown or not registered in this instance. For a custom function, `category` is `undefined`, `shortDescription` + * is empty, and parameters are reported positionally (`Arg1`, `Arg2`, ...). * * @param {string} canonicalName - the language-independent function id, e.g. `'SUMIF'` * @@ -4496,7 +4544,9 @@ export class HyperFormula implements TypedEmitter { * @category Helpers */ public getFunctionDetails(canonicalName: string): FunctionDetails | undefined { - return HyperFormula.getFunctionDetails(canonicalName, this._config.language) + validateArgToType(canonicalName, 'string', 'canonicalName') + const language = HyperFormula.getLanguage(this._config.language) + return HyperFormula.buildFunctionDetailsFor(canonicalName, this._functionRegistry.getFunctionPlugin(canonicalName), language) } /** diff --git a/src/interpreter/FunctionRegistry.ts b/src/interpreter/FunctionRegistry.ts index fe016bf5b..274be1ce0 100644 --- a/src/interpreter/FunctionRegistry.ts +++ b/src/interpreter/FunctionRegistry.ts @@ -120,6 +120,14 @@ export class FunctionRegistry { return Array.from(new Set(this.plugins.values()).values()) } + /** + * Returns the ids of all registered, non-protected functions, including aliases. Used by the function-metadata + * API to list every function reachable in a formula (built-in canonical ids plus their aliases). + */ + public static getListableFunctionIds(): string[] { + return Array.from(this.plugins.keys()) + } + public static getFunctionPlugin(functionId: string): Maybe { if (this.functionIsProtected(functionId)) { return undefined @@ -233,6 +241,14 @@ export class FunctionRegistry { return this.instancePlugins.get(functionId) } + /** + * Returns the ids of all functions registered in this instance, including aliases and any custom (user-registered) + * functions, excluding protected ids. Used by the instance-level function-metadata API. + */ + public getListableFunctionIds(): string[] { + return Array.from(this.instancePlugins.keys()).filter(id => !FunctionRegistry.functionIsProtected(id)) + } + public getFunction(functionId: string): Maybe { const pluginEntry = this.functions.get(functionId) if (pluginEntry !== undefined && this.config.translationPackage.isFunctionTranslated(functionId)) { diff --git a/src/interpreter/functionMetadata/FunctionDescription.ts b/src/interpreter/functionMetadata/FunctionDescription.ts index ff12f13bf..05e3a427a 100644 --- a/src/interpreter/functionMetadata/FunctionDescription.ts +++ b/src/interpreter/functionMetadata/FunctionDescription.ts @@ -5,6 +5,12 @@ /** * The function categories, matching the `### ` headers in `docs/guide/built-in-functions.md`. + * + * The ten categories with an Excel equivalent use the same names as the official Excel docs + * (https://support.microsoft.com/en-us/office/excel-functions-by-category-5f91f4e9-7b42-46d2-9bd1-63f26a86c0eb), + * which name them in full words (e.g. "Math and trigonometry functions", "Lookup and reference functions") rather + * than the abbreviated ribbon labels ("Math & Trig", "Lookup & Reference"). `Array manipulation`, `Matrix functions` + * and `Operator` are HyperFormula-specific and have no Excel equivalent. */ export const FUNCTION_CATEGORIES = [ 'Array manipulation', 'Database', 'Date and time', 'Engineering', @@ -43,11 +49,12 @@ export interface FunctionDoc { */ export interface FunctionListEntry { /** Function name, translated for the active language. */ - name: string, + localizedName: string, /** Language-independent function id, e.g. `'SUMIF'`. */ canonicalName: string, - category: FunctionCategory, - /** One-liner description (English in the MVP). */ + /** Documented category, or `undefined` for custom (user-registered) functions that ship no catalogue entry. */ + category: FunctionCategory | undefined, + /** One-liner description (English in the MVP). Empty (`''`) for custom functions. */ shortDescription: string, } @@ -61,8 +68,6 @@ export interface FunctionParameterDescription { description: string, /** `true` when the argument may be omitted. */ optional: boolean, - /** `true` for the last `repeatLastArgs` parameters. */ - repeatable: boolean, } /** @@ -70,15 +75,20 @@ export interface FunctionParameterDescription { */ export interface FunctionDetails { /** Function name, translated for the active language. */ - name: string, + localizedName: string, /** Language-independent function id, e.g. `'SUMIF'`. */ canonicalName: string, - category: FunctionCategory, - /** One-liner description (English in the MVP). */ + /** Documented category, or `undefined` for custom (user-registered) functions that ship no catalogue entry. */ + category: FunctionCategory | undefined, + /** One-liner description (English in the MVP). Empty (`''`) for custom functions. */ shortDescription: string, - /** Generated from the parameter names, optionality and `repeatLastArgs`. */ - syntax: string, parameters: FunctionParameterDescription[], + /** + * How many of the trailing `parameters` repeat indefinitely (a function with a variable number of arguments). + * `0` when the argument list is fixed; e.g. `1` for `SUM(Number1, ...)`, `2` for `SUMIFS` where the last + * (Criteria range, Criterion) pair repeats. The caller renders the syntax string from this. + */ + repeatLastArgs: number, /** Link to the function's documentation. Present but empty (`''`) in the MVP; populated in a later phase. */ documentationUrl: string, /** Usage examples. Present but empty (`[]`) in the MVP; populated in a later phase. */ diff --git a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts index 8ece69a48..a5dc2fe66 100644 --- a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts +++ b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts @@ -38,21 +38,6 @@ export function isParameterOptional(arg: FunctionArgument | undefined): boolean return arg?.optionalArg === true || arg?.defaultValue !== undefined } -/** - * Builds the display syntax string from parameter names and structural metadata. Required parameters are rendered - * bare, optional ones in brackets, and a trailing `, ...` is appended when the last `repeatLastArgs` parameters repeat. - * - * @param {string} displayName - the function name to show (the translated name in the active language) - * @param {string[]} parameterNames - authored parameter names, index-aligned with `metadata.parameters` - * @param {StructuralMetadata} metadata - structural metadata (`parameters` + `repeatLastArgs`) from `implementedFunctions` - */ -export function generateSyntax(displayName: string, parameterNames: string[], metadata: StructuralMetadata): string { - const args = metadata.parameters ?? [] - const rendered = parameterNames.map((name, index) => isParameterOptional(args[index]) ? `[${name}]` : name) - const repeatSuffix = (metadata.repeatLastArgs ?? 0) > 0 ? ', ...' : '' - return `${displayName}(${rendered.join(', ')}${repeatSuffix})` -} - /** * Resolves the display name for a function: the translated name, or the canonical id when there is no usable * translation. Some bundled language packs leave a function untranslated as an empty string (e.g. `SWITCH` in @@ -75,7 +60,7 @@ function resolveName(canonicalName: string, translate: TranslateName): string { */ export function buildFunctionListEntry(canonicalName: string, doc: FunctionDoc, translate: TranslateName): FunctionListEntry { return { - name: resolveName(canonicalName, translate), + localizedName: resolveName(canonicalName, translate), canonicalName, category: doc.category, shortDescription: doc.shortDescription, @@ -83,7 +68,8 @@ export function buildFunctionListEntry(canonicalName: string, doc: FunctionDoc, } /** - * Builds a Tier-2 details object: the list fields plus generated syntax and per-parameter optionality/repeatability. + * Builds a Tier-2 details object: the list fields plus the parameter list (name, description, optionality) and + * `repeatLastArgs` (how many trailing parameters repeat). The caller renders the syntax string from these. * `documentationUrl`, `examples` and each parameter `description` are present but empty in the MVP. * * @param {string} canonicalName - the language-independent function id @@ -97,23 +83,62 @@ export function buildFunctionDetails(canonicalName: string, doc: FunctionDoc, me if (doc.parameters.length !== implParamCount) { throw new Error(`Function metadata mismatch for ${canonicalName}: catalogue has ${doc.parameters.length} parameters, implementation has ${implParamCount}`) } - const name = resolveName(canonicalName, translate) const args = metadata.parameters ?? [] - const repeatLastArgs = metadata.repeatLastArgs ?? 0 - const firstRepeatableIndex = doc.parameters.length - repeatLastArgs const parameters: FunctionParameterDescription[] = doc.parameters.map((param, index) => ({ name: param.name, description: param.description, optional: isParameterOptional(args[index]), - repeatable: repeatLastArgs > 0 && index >= firstRepeatableIndex, })) return { - name, + localizedName: resolveName(canonicalName, translate), canonicalName, category: doc.category, shortDescription: doc.shortDescription, - syntax: generateSyntax(name, doc.parameters.map(parameter => parameter.name), metadata), parameters, + repeatLastArgs: metadata.repeatLastArgs ?? 0, + documentationUrl: '', + examples: [], + } +} + +/** + * Builds a Tier-1 list entry for a custom (user-registered) function, which ships no catalogue doc. Only the name + * is known; `category` is `undefined` and `shortDescription` is empty. + * + * @param {string} canonicalName - the language-independent function id + * @param {TranslateName} translate - per-id translation lookup + */ +export function buildCustomFunctionListEntry(canonicalName: string, translate: TranslateName): FunctionListEntry { + return { + localizedName: resolveName(canonicalName, translate), + canonicalName, + category: undefined, + shortDescription: '', + } +} + +/** + * Builds Tier-2 details for a custom (user-registered) function from its structural metadata alone (no catalogue + * doc): positional parameter names (`Arg1`, `Arg2`, ...), per-parameter optionality, and `repeatLastArgs`. + * + * @param {string} canonicalName - the language-independent function id + * @param {StructuralMetadata} metadata - structural metadata from `implementedFunctions` + * @param {TranslateName} translate - per-id translation lookup + */ +export function buildCustomFunctionDetails(canonicalName: string, metadata: StructuralMetadata, translate: TranslateName): FunctionDetails { + const args = metadata.parameters ?? [] + const parameters: FunctionParameterDescription[] = args.map((arg, index) => ({ + name: `Arg${index + 1}`, + description: '', + optional: isParameterOptional(arg), + })) + return { + localizedName: resolveName(canonicalName, translate), + canonicalName, + category: undefined, + shortDescription: '', + parameters, + repeatLastArgs: metadata.repeatLastArgs ?? 0, documentationUrl: '', examples: [], } From ffdaa8b9396a6af46a206762f5cb3ee28afd85cb Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Tue, 23 Jun 2026 18:04:18 +0000 Subject: [PATCH 19/35] fix(metadata): report shadowed built-ins as custom, harden ordering and repeatLastArgs (HF-249) Address multi-reviewer findings on the function-metadata API: - A user/custom plugin that shadows a built-in id (e.g. a custom SUM) is now reported as a custom function (positional params, undefined category, empty description) instead of borrowing the built-in's catalogue doc, and is no longer silently dropped on an arity mismatch. The catalogue doc is attached only when the registered plugin is the built-in plugin that canonically owns the id, checked via a built-in-plugin-ownership map derived from the same plugin set the catalogue was generated from. - getAvailableFunctions now sorts under an explicit, language-derived Intl.Collator (BCP-47 locale from the language code) instead of the host-locale-dependent String.localeCompare, with the canonical name as a stable tiebreaker for entries sharing a localized name. - buildCustomFunctionDetails clamps repeatLastArgs to the declared parameter count, so a pathological custom plugin cannot report more repeating trailing parameters than it has. - Remove getCanonicalFunctionIds from the production module (its only remaining consumer was a test). Co-Authored-By: Claude Opus 4.8 --- src/HyperFormula.ts | 40 ++++++++++---- .../buildFunctionDescriptions.ts | 53 ++++++++++++++----- 2 files changed, 72 insertions(+), 21 deletions(-) diff --git a/src/HyperFormula.ts b/src/HyperFormula.ts index 56ea68c84..f0d05b2b6 100644 --- a/src/HyperFormula.ts +++ b/src/HyperFormula.ts @@ -46,7 +46,7 @@ import {LicenseKeyValidityState} from './helpers/licenseKeyValidator' import {buildTranslationPackage, RawTranslationPackage, TranslationPackage} from './i18n' import {FunctionPluginDefinition} from './interpreter' import {FUNCTION_DOCS} from './interpreter/functionMetadata' -import {buildCustomFunctionDetails, buildCustomFunctionListEntry, buildFunctionDetails, buildFunctionListEntry, StructuralMetadata} from './interpreter/functionMetadata/buildFunctionDescriptions' +import {buildCustomFunctionDetails, buildCustomFunctionListEntry, buildFunctionDetails, buildFunctionListEntry, isBuiltinFunction, StructuralMetadata} from './interpreter/functionMetadata/buildFunctionDescriptions' import {FunctionDetails, FunctionDoc, FunctionListEntry} from './interpreter/functionMetadata/FunctionDescription' import {FunctionRegistry, FunctionTranslationsPackage} from './interpreter/FunctionRegistry' import {FormatInfo} from './interpreter/InterpreterValue' @@ -681,6 +681,7 @@ export class HyperFormula implements TypedEmitter { FunctionRegistry.getListableFunctionIds(), (id) => FunctionRegistry.getFunctionPlugin(id), language, + code, ) } @@ -715,10 +716,12 @@ export class HyperFormula implements TypedEmitter { /** * Resolves the structural metadata and catalogue doc for a registered function id, following aliases to their - * target. Returns `undefined` when the id is not registered or its catalogue doc disagrees with the implementation - * arity (catalogue drift). When the id is registered but has no catalogue doc (a custom function), `doc` is - * `undefined` and only the structural metadata is available. Shared by the list and the details builders so they - * always agree. The `getPlugin` callback abstracts over the static and the instance registry. + * target. Returns `undefined` when the id is not registered or its built-in catalogue doc disagrees with the + * implementation arity (catalogue drift). The catalogue doc is attached only when the id is genuinely provided by + * its built-in plugin; a user-registered plugin that shadows a built-in id is treated as a custom function (`doc` + * is `undefined`), so the API reflects what actually runs rather than stale built-in metadata. When the id has no + * applicable doc, `doc` is `undefined` and only the structural metadata is available. Shared by the list and the + * details builders so they always agree. The `getPlugin` callback abstracts over the static and the instance registry. * * @param {string} functionId - the language-independent function id (canonical id or alias) * @param {FunctionPluginDefinition | undefined} plugin - the plugin registered for `functionId`, or `undefined` @@ -733,7 +736,9 @@ export class HyperFormula implements TypedEmitter { if (metadata === undefined) { return undefined } - const doc = FUNCTION_DOCS[metadataKey] + // Use the catalogue doc only when the built-in plugin that owns this id is the one actually registered for it. + // A custom plugin overriding a built-in id is reported as a custom function, never with the built-in's doc. + const doc = isBuiltinFunction(metadataKey, plugin) ? FUNCTION_DOCS[metadataKey] : undefined if (doc !== undefined && doc.parameters.length !== (metadata.parameters ?? []).length) { // Catalogue drift: drop from both the list and the details so they never disagree. return undefined @@ -741,12 +746,28 @@ export class HyperFormula implements TypedEmitter { return {doc, metadata} } + /** + * Converts a HyperFormula language code (e.g. `'enGB'`, `'plPL'`) to a BCP-47 locale (e.g. `'en-GB'`, `'pl-PL'`) + * so the function list collator is deterministic across hosts. Codes in the canonical `` shape get a + * hyphen inserted; any other shape is passed through and left for `Intl.Collator` to interpret (it falls back to + * the default locale for an unrecognized tag, which is still applied consistently within a single call). + * + * @param {string} languageCode - the HyperFormula language code + */ + private static toBcp47Locale(languageCode: string): string { + const match = /^([a-z]{2})([A-Z]{2})$/.exec(languageCode) + return match !== null ? `${match[1]}-${match[2]}` : languageCode + } + /** * Builds the function list for a set of registered ids. Documented functions use their catalogue entry; custom - * functions are listed with their name only. Sorted alphabetically by localized name. + * functions are listed with their name only. Sorted by localized name under an explicit, language-derived collator + * (so the order does not depend on the host locale), with the language-independent canonical name as a stable + * tiebreaker for entries that share a localized name. */ - private static buildAvailableFunctions(functionIds: string[], getPlugin: (id: string) => FunctionPluginDefinition | undefined, language: TranslationPackage): FunctionListEntry[] { + private static buildAvailableFunctions(functionIds: string[], getPlugin: (id: string) => FunctionPluginDefinition | undefined, language: TranslationPackage, languageCode: string): FunctionListEntry[] { const translate = (id: string) => language.getMaybeFunctionTranslation(id) + const collator = new Intl.Collator(HyperFormula.toBcp47Locale(languageCode)) return functionIds .map(id => { const resolved = HyperFormula.resolveFunctionMetadata(id, getPlugin(id)) @@ -758,7 +779,7 @@ export class HyperFormula implements TypedEmitter { : buildCustomFunctionListEntry(id, translate) }) .filter((entry): entry is FunctionListEntry => entry !== undefined) - .sort((a, b) => a.localizedName.localeCompare(b.localizedName)) + .sort((a, b) => collator.compare(a.localizedName, b.localizedName) || collator.compare(a.canonicalName, b.canonicalName)) } /** @@ -4518,6 +4539,7 @@ export class HyperFormula implements TypedEmitter { this._functionRegistry.getListableFunctionIds(), (id) => this._functionRegistry.getFunctionPlugin(id), language, + this._config.language, ) } diff --git a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts index a5dc2fe66..645bc3e15 100644 --- a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts +++ b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts @@ -3,6 +3,7 @@ * Copyright (c) 2025 Handsoncode. All rights reserved. */ +import * as builtinPlugins from '../plugin' import {FunctionPluginDefinition, FunctionMetadata, FunctionArgument} from '../plugin/FunctionPlugin' import {FunctionDoc, FunctionListEntry, FunctionDetails, FunctionParameterDescription} from './FunctionDescription' @@ -13,20 +14,45 @@ type TranslateName = (canonicalName: string) => string | undefined export type StructuralMetadata = Pick /** - * Returns the canonical function id set: the union of every plugin's `implementedFunctions` keys. + * Maps each catalogue-documented canonical id to the built-in plugin that canonically provides it. The catalogue + * (`FUNCTION_DOCS`) was generated from exactly this built-in plugin set, so this map is the source of truth for + * "is the id genuinely served by its built-in plugin?". Built lazily once from the static `* as plugins` export. * - * Aliases (kept in a separate `plugin.aliases` map) and protected ids (e.g. `VERSION`, `OFFSET`, registered - * outside the regular plugin set) are excluded by construction. Operators such as `HF.ADD` are included because - * they live in an arithmetic plugin's `implementedFunctions`. + * Used by the metadata API to decide whether a registered id may borrow the catalogue doc: a user plugin that + * shadows a built-in id (e.g. a custom `SUM`) is a different class than the value stored here, so it is treated as + * a custom function rather than mislabelled with the built-in's category/description. + */ +let builtinOwnersCache: Map | undefined + +/** + * Returns the canonical-id -> built-in-plugin ownership map, computing it once and memoizing it. + * + * Only `implementedFunctions` keys are recorded (not aliases): callers resolve an alias to its target id before + * consulting this map, so the target id is what must be matched. + */ +function getBuiltinFunctionOwners(): Map { + if (builtinOwnersCache === undefined) { + const owners = new Map() + Object.keys(builtinPlugins).forEach(exportName => { + const plugin = (builtinPlugins as Record)[exportName] + Object.keys(plugin.implementedFunctions).forEach(id => owners.set(id, plugin)) + }) + builtinOwnersCache = owners + } + return builtinOwnersCache +} + +/** + * Returns whether `plugin` is the built-in plugin that canonically provides `canonicalId`. `false` when the id is + * not a built-in id at all, or when a different (e.g. user-registered) plugin currently provides it. Used to gate + * use of the catalogue doc so a custom function shadowing a built-in id is never described with the built-in's + * metadata. * - * @param {FunctionPluginDefinition[]} plugins - registered function plugins, e.g. from `FunctionRegistry.getPlugins()` + * @param {string} canonicalId - the language-independent function id (the alias target, never an alias) + * @param {FunctionPluginDefinition} plugin - the plugin currently registered for the id */ -export function getCanonicalFunctionIds(plugins: FunctionPluginDefinition[]): string[] { - const ids = new Set() - plugins.forEach(plugin => { - Object.keys(plugin.implementedFunctions).forEach(id => ids.add(id)) - }) - return Array.from(ids) +export function isBuiltinFunction(canonicalId: string, plugin: FunctionPluginDefinition): boolean { + return getBuiltinFunctionOwners().get(canonicalId) === plugin } /** @@ -132,13 +158,16 @@ export function buildCustomFunctionDetails(canonicalName: string, metadata: Stru description: '', optional: isParameterOptional(arg), })) + // A pathological custom plugin may declare `repeatLastArgs` larger than its parameter count, which would render + // as "the last N of M parameters repeat" with N > M. Clamp to the declared parameter count so the output stays + // meaningful. (No built-in is affected, so the built-in path keeps the verbatim value.) return { localizedName: resolveName(canonicalName, translate), canonicalName, category: undefined, shortDescription: '', parameters, - repeatLastArgs: metadata.repeatLastArgs ?? 0, + repeatLastArgs: Math.min(metadata.repeatLastArgs ?? 0, parameters.length), documentationUrl: '', examples: [], } From 594d2ce693cc655a9dd4a285ad47b33491b81df4 Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Wed, 24 Jun 2026 10:55:46 +0000 Subject: [PATCH 20/35] fix(metadata): break module-load cycle from built-in owner lookup (HF-249) buildFunctionDescriptions eagerly imported the plugin barrel to detect built-in ownership; since HyperFormula loads the metadata builders early, that created a module-load-order cycle crashing the bundled build ('Class extends value undefined' in the perf benchmark). Move the built-in owner snapshot to FunctionRegistry (captured in index.ts, which already imports the barrel to register built-ins) and expose isBuiltinFunction; the builders no longer import the barrel. Shadow-vs- built-in behavior is unchanged. Co-Authored-By: Claude Opus 4.8 --- src/HyperFormula.ts | 4 +- src/index.ts | 11 ++++- src/interpreter/FunctionRegistry.ts | 41 +++++++++++++++++ .../buildFunctionDescriptions.ts | 45 +------------------ 4 files changed, 54 insertions(+), 47 deletions(-) diff --git a/src/HyperFormula.ts b/src/HyperFormula.ts index f0d05b2b6..8142b098c 100644 --- a/src/HyperFormula.ts +++ b/src/HyperFormula.ts @@ -46,7 +46,7 @@ import {LicenseKeyValidityState} from './helpers/licenseKeyValidator' import {buildTranslationPackage, RawTranslationPackage, TranslationPackage} from './i18n' import {FunctionPluginDefinition} from './interpreter' import {FUNCTION_DOCS} from './interpreter/functionMetadata' -import {buildCustomFunctionDetails, buildCustomFunctionListEntry, buildFunctionDetails, buildFunctionListEntry, isBuiltinFunction, StructuralMetadata} from './interpreter/functionMetadata/buildFunctionDescriptions' +import {buildCustomFunctionDetails, buildCustomFunctionListEntry, buildFunctionDetails, buildFunctionListEntry, StructuralMetadata} from './interpreter/functionMetadata/buildFunctionDescriptions' import {FunctionDetails, FunctionDoc, FunctionListEntry} from './interpreter/functionMetadata/FunctionDescription' import {FunctionRegistry, FunctionTranslationsPackage} from './interpreter/FunctionRegistry' import {FormatInfo} from './interpreter/InterpreterValue' @@ -738,7 +738,7 @@ export class HyperFormula implements TypedEmitter { } // Use the catalogue doc only when the built-in plugin that owns this id is the one actually registered for it. // A custom plugin overriding a built-in id is reported as a custom function, never with the built-in's doc. - const doc = isBuiltinFunction(metadataKey, plugin) ? FUNCTION_DOCS[metadataKey] : undefined + const doc = FunctionRegistry.isBuiltinFunction(metadataKey, plugin) ? FUNCTION_DOCS[metadataKey] : undefined if (doc !== undefined && doc.parameters.length !== (metadata.parameters ?? []).length) { // Catalogue drift: drop from both the list and the details so they never disagree. return undefined diff --git a/src/index.ts b/src/index.ts index 23b060cf4..444bf1c99 100644 --- a/src/index.ts +++ b/src/index.ts @@ -49,6 +49,7 @@ import {HyperFormula} from './HyperFormula' import {RawTranslationPackage} from './i18n' import enGB from './i18n/languages/enGB' import {FunctionArgument, FunctionPlugin, FunctionPluginDefinition, FunctionArgumentType, ImplementedFunctions, FunctionMetadata, EmptyValue} from './interpreter' +import {FunctionRegistry} from './interpreter/FunctionRegistry' import {FunctionCategory, FunctionDetails, FunctionListEntry, FunctionParameterDescription} from './interpreter/functionMetadata/FunctionDescription' import {FormatInfo} from './interpreter/InterpreterValue' import * as plugins from './interpreter/plugin' @@ -110,13 +111,21 @@ const defaultLanguage = Config.defaultConfig.language HyperFormula.registerLanguage(defaultLanguage, enGB) HyperFormula.languages[enGB.langCode] = enGB +const builtinPlugins: FunctionPluginDefinition[] = [] for (const pluginName of Object.getOwnPropertyNames(plugins)) { if (!pluginName.startsWith('_')) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - HyperFormula.registerFunctionPlugin(plugins[pluginName]) + const plugin = plugins[pluginName] as FunctionPluginDefinition + HyperFormula.registerFunctionPlugin(plugin) + builtinPlugins.push(plugin) } } +// Snapshot the original built-in id -> plugin ownership so the function-metadata API can distinguish a genuine +// built-in id from a user plugin that shadows one. Captured here (the only place that bulk-registers the built-ins) +// rather than in the metadata builders, which must not import the plugin barrel: doing so eagerly creates a +// module-load-order cycle that crashes the bundled build ("Class extends value undefined"). +FunctionRegistry.captureBuiltinFunctionOwners(builtinPlugins) export default HyperFormulaNS diff --git a/src/interpreter/FunctionRegistry.ts b/src/interpreter/FunctionRegistry.ts index 274be1ce0..e9c6bc9f6 100644 --- a/src/interpreter/FunctionRegistry.ts +++ b/src/interpreter/FunctionRegistry.ts @@ -39,6 +39,18 @@ function validateAndReturnMetadataFromName(functionId: string, plugin: FunctionP export class FunctionRegistry { public static plugins: Map = new Map() + /** + * Maps each built-in canonical id to the built-in plugin that canonically provides it. Captured once at module + * init (from `index.ts`, which already imports the plugin barrel to register the built-ins) so the metadata API + * can tell a genuine built-in id from a user plugin that merely shadows a built-in id. Keyed by + * `implementedFunctions` keys only, never aliases: callers resolve an alias to its target id before consulting it. + * + * Lives here rather than in the metadata builders so those builders need not import the plugin barrel: doing so + * eagerly would create a module-load-order cycle (`HyperFormula.ts` pulls in the builders early). This map is a + * frozen snapshot of the original built-in ownership, unaffected by later `registerFunction`/`unregister` calls. + */ + private static readonly _builtinFunctionOwners: Map = new Map() + private static readonly _protectedPlugins: Map = new Map([ ['VERSION', VersionPlugin], ['OFFSET', undefined], @@ -78,6 +90,35 @@ export class FunctionRegistry { } } + /** + * Records the given plugins as the canonical built-in owners. Called once at module init by `index.ts` with the + * complete built-in plugin set (which it already imports to register them). Only `implementedFunctions` keys are + * snapshotted, not aliases, because alias lookups are resolved to their target id before {@link isBuiltinFunction} + * is consulted. Idempotent: re-recording the same id keeps the last writer, but the built-in set is fixed. + * + * @param {FunctionPluginDefinition[]} builtinPlugins - the built-in plugin classes, as imported by `index.ts` + */ + public static captureBuiltinFunctionOwners(builtinPlugins: FunctionPluginDefinition[]): void { + for (const plugin of builtinPlugins) { + for (const id of Object.keys(plugin.implementedFunctions)) { + this._builtinFunctionOwners.set(id, plugin) + } + } + } + + /** + * Returns whether `plugin` is the built-in plugin that canonically provides `canonicalId`. `false` when the id is + * not a built-in id at all, or when a different (e.g. user-registered) plugin currently provides it. Lets the + * metadata API gate use of the catalogue doc so a custom function shadowing a built-in id is never described with + * the built-in's metadata. + * + * @param {string} canonicalId - the language-independent function id (the alias target, never an alias) + * @param {FunctionPluginDefinition} plugin - the plugin currently registered for the id + */ + public static isBuiltinFunction(canonicalId: string, plugin: FunctionPluginDefinition): boolean { + return this._builtinFunctionOwners.get(canonicalId) === plugin + } + public static registerFunction(functionId: string, plugin: FunctionPluginDefinition, translations?: FunctionTranslationsPackage): void { this.loadPluginFunction(plugin, functionId, this.plugins) if (translations !== undefined) { diff --git a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts index 645bc3e15..d65256de1 100644 --- a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts +++ b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts @@ -3,8 +3,7 @@ * Copyright (c) 2025 Handsoncode. All rights reserved. */ -import * as builtinPlugins from '../plugin' -import {FunctionPluginDefinition, FunctionMetadata, FunctionArgument} from '../plugin/FunctionPlugin' +import {FunctionMetadata, FunctionArgument} from '../plugin/FunctionPlugin' import {FunctionDoc, FunctionListEntry, FunctionDetails, FunctionParameterDescription} from './FunctionDescription' /** Resolves a function's display name: the translation for the active language, or the canonical id as fallback. */ @@ -13,48 +12,6 @@ type TranslateName = (canonicalName: string) => string | undefined /** The structural subset of `FunctionMetadata` the builders read (so callers/tests need not supply `method`). */ export type StructuralMetadata = Pick -/** - * Maps each catalogue-documented canonical id to the built-in plugin that canonically provides it. The catalogue - * (`FUNCTION_DOCS`) was generated from exactly this built-in plugin set, so this map is the source of truth for - * "is the id genuinely served by its built-in plugin?". Built lazily once from the static `* as plugins` export. - * - * Used by the metadata API to decide whether a registered id may borrow the catalogue doc: a user plugin that - * shadows a built-in id (e.g. a custom `SUM`) is a different class than the value stored here, so it is treated as - * a custom function rather than mislabelled with the built-in's category/description. - */ -let builtinOwnersCache: Map | undefined - -/** - * Returns the canonical-id -> built-in-plugin ownership map, computing it once and memoizing it. - * - * Only `implementedFunctions` keys are recorded (not aliases): callers resolve an alias to its target id before - * consulting this map, so the target id is what must be matched. - */ -function getBuiltinFunctionOwners(): Map { - if (builtinOwnersCache === undefined) { - const owners = new Map() - Object.keys(builtinPlugins).forEach(exportName => { - const plugin = (builtinPlugins as Record)[exportName] - Object.keys(plugin.implementedFunctions).forEach(id => owners.set(id, plugin)) - }) - builtinOwnersCache = owners - } - return builtinOwnersCache -} - -/** - * Returns whether `plugin` is the built-in plugin that canonically provides `canonicalId`. `false` when the id is - * not a built-in id at all, or when a different (e.g. user-registered) plugin currently provides it. Used to gate - * use of the catalogue doc so a custom function shadowing a built-in id is never described with the built-in's - * metadata. - * - * @param {string} canonicalId - the language-independent function id (the alias target, never an alias) - * @param {FunctionPluginDefinition} plugin - the plugin currently registered for the id - */ -export function isBuiltinFunction(canonicalId: string, plugin: FunctionPluginDefinition): boolean { - return getBuiltinFunctionOwners().get(canonicalId) === plugin -} - /** * Returns whether a parameter may be omitted: it declares `optionalArg`, or it has a `defaultValue`. * From 07e8065b5e2d8cc71ca5a4ae11fd8213a947f8b9 Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Wed, 24 Jun 2026 12:45:05 +0000 Subject: [PATCH 21/35] docs(guide): drop redundant "no syntax string" note from function metadata (HF-249) Per review: the metadata guide need not describe what the API does NOT return. Keep only the repeatLastArgs explanation. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/guide/custom-functions.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/guide/custom-functions.md b/docs/guide/custom-functions.md index 359e22ad1..8caf3a345 100644 --- a/docs/guide/custom-functions.md +++ b/docs/guide/custom-functions.md @@ -559,9 +559,7 @@ localized name, each with `localizedName`, `canonicalName`, `category`, and `shortDescription`. `getFunctionDetails()` returns the same fields plus the ordered `parameters` list (each with `name`, `description`, and `optional`) and `repeatLastArgs` — the number of trailing parameters that repeat for functions -with a variable number of arguments (`0` for a fixed argument list). The -methods do not return a pre-rendered syntax string; build it from `parameters` -and `repeatLastArgs` as your UI needs. +with a variable number of arguments (`0` for a fixed argument list). The same methods are also available on an instance, where they use the instance's configured language by default: From ff285371a7e271afe7b236ec4ff268e0bd57cf6b Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Thu, 25 Jun 2026 09:26:54 +0000 Subject: [PATCH 22/35] feat(metadata): author SUM and SUMIF reference metadata; optional doc/examples on FunctionDoc (HF-249) Add optional documentationUrl/examples to FunctionDoc and surface them in getFunctionDetails (falling back to ''/[] when absent). Author SUM and SUMIF as reference functions with real parameter descriptions, examples and a documentation link so the Formula Builder team can test rendering of populated metadata. The migration generator does not emit these fields; a comment guards the two entries against regeneration. Co-Authored-By: Claude Opus 4.8 --- .../functionMetadata/FunctionDescription.ts | 14 ++++++++++++-- .../buildFunctionDescriptions.ts | 7 ++++--- .../categories/math-and-trigonometry.ts | 16 ++++++++++++++-- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/interpreter/functionMetadata/FunctionDescription.ts b/src/interpreter/functionMetadata/FunctionDescription.ts index 05e3a427a..39fdc0aff 100644 --- a/src/interpreter/functionMetadata/FunctionDescription.ts +++ b/src/interpreter/functionMetadata/FunctionDescription.ts @@ -42,6 +42,16 @@ export interface FunctionDoc { shortDescription: string, /** Ordered; length MUST equal the function's `implementedFunctions.parameters` length (implementation arity). */ parameters: ParameterDoc[], + /** + * Link to the function's documentation. Optional and absent for most functions in the MVP (surfaced as `''`); + * authored per function in a later phase. + */ + documentationUrl?: string, + /** + * Usage examples. Optional and absent for most functions in the MVP (surfaced as `[]`); authored per function + * in a later phase. + */ + examples?: string[], } /** @@ -89,8 +99,8 @@ export interface FunctionDetails { * (Criteria range, Criterion) pair repeats. The caller renders the syntax string from this. */ repeatLastArgs: number, - /** Link to the function's documentation. Present but empty (`''`) in the MVP; populated in a later phase. */ + /** Link to the function's documentation. Authored per function; `''` for functions not yet documented. */ documentationUrl: string, - /** Usage examples. Present but empty (`[]`) in the MVP; populated in a later phase. */ + /** Usage examples. Authored per function; `[]` for functions not yet documented. */ examples: string[], } diff --git a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts index d65256de1..b3845b4df 100644 --- a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts +++ b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts @@ -53,7 +53,8 @@ export function buildFunctionListEntry(canonicalName: string, doc: FunctionDoc, /** * Builds a Tier-2 details object: the list fields plus the parameter list (name, description, optionality) and * `repeatLastArgs` (how many trailing parameters repeat). The caller renders the syntax string from these. - * `documentationUrl`, `examples` and each parameter `description` are present but empty in the MVP. + * `documentationUrl` and `examples` come from the catalogue doc when authored, and fall back to `''`/`[]` + * otherwise; each parameter `description` is present but empty for functions not yet authored. * * @param {string} canonicalName - the language-independent function id * @param {FunctionDoc} doc - the function's authored catalogue entry @@ -79,8 +80,8 @@ export function buildFunctionDetails(canonicalName: string, doc: FunctionDoc, me shortDescription: doc.shortDescription, parameters, repeatLastArgs: metadata.repeatLastArgs ?? 0, - documentationUrl: '', - examples: [], + documentationUrl: doc.documentationUrl ?? '', + examples: doc.examples ?? [], } } diff --git a/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts b/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts index 9e864f3e9..4ebb5f1fb 100644 --- a/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts +++ b/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts @@ -325,15 +325,27 @@ export const MATH_AND_TRIGONOMETRY_DOCS: Record = { shortDescription: 'Computes aggregation using function specified by number.', parameters: [{name: 'Function', description: ''}, {name: 'Number1', description: ''}], }, + // HAND-AUTHORED reference functions (HF-249): SUM and SUMIF carry real parameter descriptions, examples and a + // documentationUrl so the Formula Builder team can test rendering of populated metadata. The migration generator + // (scripts/hf249-migrate-function-docs.ts) does NOT emit `examples`/`documentationUrl`, so DO NOT re-run it over + // this file without merge-preserving these two entries, or they will be silently reset to empty. SUM: { category: 'Math and trigonometry', shortDescription: 'Sums up the values of the specified cells.', - parameters: [{name: 'Number1', description: ''}], + parameters: [{name: 'Number1', description: 'A number, cell reference, or range whose values are added together. Further numbers or ranges can be passed as additional arguments.'}], + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions', + examples: ['=SUM(1, 2, 3)', '=SUM(A1:A10)', '=SUM(B1:B5, 100)'], }, SUMIF: { category: 'Math and trigonometry', shortDescription: 'Sums up the values of cells that belong to the specified range and meet the specified condition.', - parameters: [{name: 'Range', description: ''}, {name: 'Criteria', description: ''}, {name: 'Sumrange', description: ''}], + parameters: [ + {name: 'Range', description: 'The range of cells tested against the criterion.'}, + {name: 'Criteria', description: 'The condition that selects which cells are summed, e.g. ">5", "apples", or a cell reference.'}, + {name: 'Sumrange', description: 'The range of cells to sum. When omitted, the cells in Range are summed instead.'}, + ], + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions', + examples: ['=SUMIF(A1:A10, ">5")', '=SUMIF(B1:B10, "apples", C1:C10)'], }, SUMIFS: { category: 'Math and trigonometry', From 8207bf3656e055e3c3180230bd3ad1179d184f10 Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Thu, 25 Jun 2026 09:55:15 +0000 Subject: [PATCH 23/35] docs(guide): document documentationUrl and examples in getFunctionDetails (HF-249) The custom-functions guide listed the getFunctionDetails return shape but omitted the documentationUrl and examples fields; add them so the documented shape matches FunctionDetails. Co-Authored-By: Claude Opus 4.8 --- docs/guide/custom-functions.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/guide/custom-functions.md b/docs/guide/custom-functions.md index 8caf3a345..58ca997c4 100644 --- a/docs/guide/custom-functions.md +++ b/docs/guide/custom-functions.md @@ -557,9 +557,11 @@ const sumDetails = HyperFormula.getFunctionDetails('SUM', 'enGB'); `getAvailableFunctions()` returns entries sorted alphabetically by their localized name, each with `localizedName`, `canonicalName`, `category`, and `shortDescription`. `getFunctionDetails()` returns the same fields plus the -ordered `parameters` list (each with `name`, `description`, and `optional`) and +ordered `parameters` list (each with `name`, `description`, and `optional`), `repeatLastArgs` — the number of trailing parameters that repeat for functions -with a variable number of arguments (`0` for a fixed argument list). +with a variable number of arguments (`0` for a fixed argument list) — and +`documentationUrl` and `examples`, which carry the function's documentation link +and usage examples where authored (otherwise `''` and `[]`). The same methods are also available on an instance, where they use the instance's configured language by default: From c65115bd19a0ede4af5a34c45cf42ef16233e7ad Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 14 Jul 2026 11:36:46 +0000 Subject: [PATCH 24/35] Add missing XIRR, VSTACK, HSTACK to function catalogue - Add XIRR to Financial category with Values, Dates, Guess parameters - Add VSTACK and HSTACK to Array manipulation category with Array1 parameter - Move Function metadata section from custom-functions.md to built-in-functions.md - Fixes Bugbot review: Missing catalogue mislabels builtins Co-authored-by: Kuba Sekowski --- docs/guide/built-in-functions.md | 57 +++++++++++++++++++ docs/guide/custom-functions.md | 57 ------------------- .../categories/array-manipulation.ts | 10 ++++ .../functionMetadata/categories/financial.ts | 5 ++ 4 files changed, 72 insertions(+), 57 deletions(-) diff --git a/docs/guide/built-in-functions.md b/docs/guide/built-in-functions.md index d486c8e04..67ac33c6b 100644 --- a/docs/guide/built-in-functions.md +++ b/docs/guide/built-in-functions.md @@ -53,6 +53,63 @@ _Some categories such as compatibility and cube are yet to be supported._ You can modify the built-in functions or create your own, by adding a [custom function](custom-functions.md). ::: +## Function metadata + +HyperFormula exposes metadata about the functions it knows (category, translated +name, short description, and the parameter list). You can retrieve it with the +`getAvailableFunctions()` and `getFunctionDetails()` methods, available both as +static methods and as instance methods: + +```js +// a short list of available functions, with names translated for a language +const functions = HyperFormula.getAvailableFunctions('enGB'); + +// the full details of a single function +const sumDetails = HyperFormula.getFunctionDetails('SUM', 'enGB'); +``` + +`getAvailableFunctions()` returns entries sorted alphabetically by their +localized name, each with `localizedName`, `canonicalName`, `category`, and +`shortDescription`. `getFunctionDetails()` returns the same fields plus the +ordered `parameters` list (each with `name`, `description`, and `optional`), +`repeatLastArgs` — the number of trailing parameters that repeat for functions +with a variable number of arguments — and `documentationUrl` and `examples`, +which carry the function's documentation link and usage examples where authored +(otherwise `''` and `[]`). + +The same methods are also available on an instance, where they use the +instance's configured language by default: + +```js +const hf = HyperFormula.buildEmpty({ language: 'enGB' }); + +// a short list of available functions +const functions = hf.getAvailableFunctions(); + +// the full details of a single function +const sumDetails = hf.getFunctionDetails('SUM'); +``` + +Both built-in functions and their aliases are included. Custom (user-registered) +functions are registered per instance, so they are listed by the **instance** +methods, not by the static ones — the static methods only see the globally +registered built-ins and their aliases. A custom function has no shipped +catalogue entry, so its `category` is `undefined`, its `shortDescription` is +empty, and its parameters are reported positionally (`Arg1`, `Arg2`, ...). + +```js +const hf = HyperFormula.buildEmpty({ + language: 'enGB', + functionPlugins: [MyCustomPlugin], +}); + +// the instance methods include the custom function +const details = hf.getFunctionDetails('MY_FUNCTION'); // { canonicalName: 'MY_FUNCTION', category: undefined, ... } + +// the static methods do not, as custom functions are instance-scoped +const staticDetails = HyperFormula.getFunctionDetails('MY_FUNCTION', 'enGB'); // undefined +``` + ## List of available functions Total number of functions: **{{ $page.functionsCount }}** diff --git a/docs/guide/custom-functions.md b/docs/guide/custom-functions.md index 58ca997c4..49794b1d3 100644 --- a/docs/guide/custom-functions.md +++ b/docs/guide/custom-functions.md @@ -538,60 +538,3 @@ MyCustomPlugin.translations = { }; ``` ::: - -## Function metadata - -HyperFormula exposes metadata about the functions it knows (category, translated -name, short description, and the parameter list). You can retrieve it with the -`getAvailableFunctions()` and `getFunctionDetails()` methods, available both as -static methods and as instance methods: - -```js -// a short list of available functions, with names translated for a language -const functions = HyperFormula.getAvailableFunctions('enGB'); - -// the full details of a single function -const sumDetails = HyperFormula.getFunctionDetails('SUM', 'enGB'); -``` - -`getAvailableFunctions()` returns entries sorted alphabetically by their -localized name, each with `localizedName`, `canonicalName`, `category`, and -`shortDescription`. `getFunctionDetails()` returns the same fields plus the -ordered `parameters` list (each with `name`, `description`, and `optional`), -`repeatLastArgs` — the number of trailing parameters that repeat for functions -with a variable number of arguments (`0` for a fixed argument list) — and -`documentationUrl` and `examples`, which carry the function's documentation link -and usage examples where authored (otherwise `''` and `[]`). - -The same methods are also available on an instance, where they use the -instance's configured language by default: - -```js -const hf = HyperFormula.buildEmpty({ language: 'enGB' }); - -// a short list of available functions -const functions = hf.getAvailableFunctions(); - -// the full details of a single function -const sumDetails = hf.getFunctionDetails('SUM'); -``` - -Both built-in functions and their aliases are included. Custom (user-registered) -functions are registered per instance, so they are listed by the **instance** -methods, not by the static ones — the static methods only see the globally -registered built-ins and their aliases. A custom function has no shipped -catalogue entry, so its `category` is `undefined`, its `shortDescription` is -empty, and its parameters are reported positionally (`Arg1`, `Arg2`, ...). - -```js -const hf = HyperFormula.buildEmpty({ - language: 'enGB', - functionPlugins: [MyCustomPlugin], -}); - -// the instance methods include the custom function -const details = hf.getFunctionDetails('MY_FUNCTION'); // { canonicalName: 'MY_FUNCTION', category: undefined, ... } - -// the static methods do not, as custom functions are instance-scoped -const staticDetails = HyperFormula.getFunctionDetails('MY_FUNCTION', 'enGB'); // undefined -``` diff --git a/src/interpreter/functionMetadata/categories/array-manipulation.ts b/src/interpreter/functionMetadata/categories/array-manipulation.ts index 370742b8d..793f8533a 100644 --- a/src/interpreter/functionMetadata/categories/array-manipulation.ts +++ b/src/interpreter/functionMetadata/categories/array-manipulation.ts @@ -30,4 +30,14 @@ export const ARRAY_MANIPULATION_DOCS: Record = { shortDescription: 'Returns an array of sequential numbers.', parameters: [{name: 'Rows', description: ''}, {name: 'Cols', description: ''}, {name: 'Start', description: ''}, {name: 'Step', description: ''}], }, + VSTACK: { + category: 'Array manipulation', + shortDescription: 'Stacks arrays vertically into a single array.', + parameters: [{name: 'Array1', description: ''}], + }, + HSTACK: { + category: 'Array manipulation', + shortDescription: 'Stacks arrays horizontally into a single array.', + parameters: [{name: 'Array1', description: ''}], + }, } diff --git a/src/interpreter/functionMetadata/categories/financial.ts b/src/interpreter/functionMetadata/categories/financial.ts index 1e5546844..05244947a 100644 --- a/src/interpreter/functionMetadata/categories/financial.ts +++ b/src/interpreter/functionMetadata/categories/financial.ts @@ -150,4 +150,9 @@ export const FINANCIAL_DOCS: Record = { shortDescription: 'Returns net present value.', parameters: [{name: 'Rate', description: ''}, {name: 'Payments', description: ''}, {name: 'Dates', description: ''}], }, + XIRR: { + category: 'Financial', + shortDescription: 'Returns the internal rate of return for a schedule of cash flows that is not necessarily periodic.', + parameters: [{name: 'Values', description: ''}, {name: 'Dates', description: ''}, {name: 'Guess', description: ''}], + }, } From 86ab411f2dec0c8bf5771f869e7fdfeef53abd03 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 14 Jul 2026 11:44:20 +0000 Subject: [PATCH 25/35] Fix static metadata API to exclude globally-registered custom plugins Static getAvailableFunctions and getFunctionDetails now filter out custom plugins registered via HyperFormula.registerFunctionPlugin, returning only built-in functions and their aliases as documented. Co-authored-by: Kuba Sekowski --- src/HyperFormula.ts | 12 +++++++++++- src/interpreter/FunctionRegistry.ts | 15 ++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/HyperFormula.ts b/src/HyperFormula.ts index 8142b098c..5ddd02b98 100644 --- a/src/HyperFormula.ts +++ b/src/HyperFormula.ts @@ -710,8 +710,18 @@ export class HyperFormula implements TypedEmitter { public static getFunctionDetails(canonicalName: string, code: string): FunctionDetails | undefined { validateArgToType(canonicalName, 'string', 'canonicalName') validateArgToType(code, 'string', 'code') + const plugin = FunctionRegistry.getFunctionPlugin(canonicalName) + if (plugin === undefined) { + return undefined + } + // Resolve aliases to their canonical target id before checking built-in ownership + const canonicalId = plugin.aliases?.[canonicalName] ?? canonicalName + // The static method only describes built-in functions; custom plugins are excluded and available via the instance method + if (!FunctionRegistry.isBuiltinFunction(canonicalId, plugin)) { + return undefined + } const language = this.getLanguage(code) - return HyperFormula.buildFunctionDetailsFor(canonicalName, FunctionRegistry.getFunctionPlugin(canonicalName), language) + return HyperFormula.buildFunctionDetailsFor(canonicalName, plugin, language) } /** diff --git a/src/interpreter/FunctionRegistry.ts b/src/interpreter/FunctionRegistry.ts index e9c6bc9f6..9fdf38993 100644 --- a/src/interpreter/FunctionRegistry.ts +++ b/src/interpreter/FunctionRegistry.ts @@ -162,11 +162,20 @@ export class FunctionRegistry { } /** - * Returns the ids of all registered, non-protected functions, including aliases. Used by the function-metadata - * API to list every function reachable in a formula (built-in canonical ids plus their aliases). + * Returns the ids of all registered, non-protected built-in functions, including aliases. Used by the static + * function-metadata API to list every built-in function reachable in a formula. Custom functions registered via + * registerFunctionPlugin are excluded; they appear only in the instance method variant. */ public static getListableFunctionIds(): string[] { - return Array.from(this.plugins.keys()) + const ids: string[] = [] + for (const [functionId, plugin] of this.plugins.entries()) { + // Resolve aliases to their canonical target id before checking built-in ownership + const canonicalId = plugin.aliases?.[functionId] ?? functionId + if (this.isBuiltinFunction(canonicalId, plugin)) { + ids.push(functionId) + } + } + return ids } public static getFunctionPlugin(functionId: string): Maybe { From 707fce83f7f5a3bdd2da5b782ca7894aaddf6b1c Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 14 Jul 2026 11:47:45 +0000 Subject: [PATCH 26/35] docs: clarify custom plugins don't appear in static metadata API Add note to custom-functions.md explaining that globally-registered custom plugins (via registerFunctionPlugin) are available in all instances but don't appear in static metadata API methods. Co-authored-by: Kuba Sekowski --- docs/guide/custom-functions.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/guide/custom-functions.md b/docs/guide/custom-functions.md index 49794b1d3..9f93950f7 100644 --- a/docs/guide/custom-functions.md +++ b/docs/guide/custom-functions.md @@ -142,6 +142,10 @@ method: HyperFormula.registerFunctionPlugin(MyCustomPlugin, MyCustomPluginTranslations); ``` +::: tip +Custom functions registered with `registerFunctionPlugin()` are available in all HyperFormula instances. However, they do not appear in the static metadata API methods (`HyperFormula.getAvailableFunctions()` and `HyperFormula.getFunctionDetails()`). To retrieve metadata for custom functions, use the instance methods (`hfInstance.getAvailableFunctions()` and `hfInstance.getFunctionDetails()`). See the [Function metadata](built-in-functions.md#function-metadata) section for more details. +::: + ### 6. Use your custom function in a formula Now, you're ready to use your GREET function in a formula. From 8e26e2af66d350ebc5ccd1530ae0c2bb4cb0e3d2 Mon Sep 17 00:00:00 2001 From: Kuba Sekowski Date: Tue, 14 Jul 2026 13:58:58 +0200 Subject: [PATCH 27/35] Describe the guidelines about the docs in the DEV_DOCS --- DEV_DOCS.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DEV_DOCS.md b/DEV_DOCS.md index 9ca91f9aa..5db668650 100644 --- a/DEV_DOCS.md +++ b/DEV_DOCS.md @@ -90,6 +90,10 @@ A single pull request should contain an atomic self-contained functional change - All changes to the production code must be covered by automatic tests kept in the `test/` directory. - Each test case must be very simple and focused on a single assertion. Don't use loops, conditionals, or other control flow statements in test cases. +## Documentation + +- We try not to duplicate information in the documentation. The API reference (generated from JSDocs) should contain all the details about each function and class (it is the primary source of truth). Guides should provide high-level overview. They may duplicate some of the information from the API reference if they are relevant to the context but, above all, they should link to the API reference for the detailed information. + ## How to add a new function Adding a built-in function is similar to adding a [custom function](docs/guide/custom-functions.md), so that guide is a useful reference for the function-implementation patterns (argument metadata, return types, array handling). The built-in flow on top of that is: From b90f9394a0b2b8e4c5b840b0f60599fc3930497a Mon Sep 17 00:00:00 2001 From: Kuba Sekowski Date: Tue, 14 Jul 2026 14:05:26 +0200 Subject: [PATCH 28/35] Update docs about getAvailableFunctions and getFunctionDetails --- docs/guide/built-in-functions.md | 64 ++++++------------- src/HyperFormula.ts | 14 ++-- .../functionMetadata/FunctionDescription.ts | 1 + 3 files changed, 27 insertions(+), 52 deletions(-) diff --git a/docs/guide/built-in-functions.md b/docs/guide/built-in-functions.md index 67ac33c6b..97aab9ffa 100644 --- a/docs/guide/built-in-functions.md +++ b/docs/guide/built-in-functions.md @@ -55,60 +55,32 @@ You can modify the built-in functions or create your own, by adding a [custom fu ## Function metadata -HyperFormula exposes metadata about the functions it knows (category, translated -name, short description, and the parameter list). You can retrieve it with the -`getAvailableFunctions()` and `getFunctionDetails()` methods, available both as -static methods and as instance methods: +HyperFormula exposes metadata about the functions it knows — localized and +canonical names, category, a short description, and the parameter list — which is +useful for building UI such as a function picker or a reference panel. Two +methods return it, each available as a **static** method (covering the +globally-registered built-ins and their aliases) and as an **instance** method +(which additionally sees the instance's [custom functions](custom-functions.md) +and defaults to its configured language): + +- [`getAvailableFunctions()`](../api/classes/hyperformula.md#getavailablefunctions) + — a short list with one entry per function. +- [`getFunctionDetails()`](../api/classes/hyperformula.md#getfunctiondetails) + — the full details of a single function, including its parameters. ```js -// a short list of available functions, with names translated for a language +// static methods take the language code explicitly const functions = HyperFormula.getAvailableFunctions('enGB'); - -// the full details of a single function const sumDetails = HyperFormula.getFunctionDetails('SUM', 'enGB'); -``` - -`getAvailableFunctions()` returns entries sorted alphabetically by their -localized name, each with `localizedName`, `canonicalName`, `category`, and -`shortDescription`. `getFunctionDetails()` returns the same fields plus the -ordered `parameters` list (each with `name`, `description`, and `optional`), -`repeatLastArgs` — the number of trailing parameters that repeat for functions -with a variable number of arguments — and `documentationUrl` and `examples`, -which carry the function's documentation link and usage examples where authored -(otherwise `''` and `[]`). -The same methods are also available on an instance, where they use the -instance's configured language by default: - -```js +// instance methods use the instance's configured language const hf = HyperFormula.buildEmpty({ language: 'enGB' }); - -// a short list of available functions -const functions = hf.getAvailableFunctions(); - -// the full details of a single function -const sumDetails = hf.getFunctionDetails('SUM'); +const instanceFunctions = hf.getAvailableFunctions(); +const instanceSumDetails = hf.getFunctionDetails('SUM'); ``` -Both built-in functions and their aliases are included. Custom (user-registered) -functions are registered per instance, so they are listed by the **instance** -methods, not by the static ones — the static methods only see the globally -registered built-ins and their aliases. A custom function has no shipped -catalogue entry, so its `category` is `undefined`, its `shortDescription` is -empty, and its parameters are reported positionally (`Arg1`, `Arg2`, ...). - -```js -const hf = HyperFormula.buildEmpty({ - language: 'enGB', - functionPlugins: [MyCustomPlugin], -}); - -// the instance methods include the custom function -const details = hf.getFunctionDetails('MY_FUNCTION'); // { canonicalName: 'MY_FUNCTION', category: undefined, ... } - -// the static methods do not, as custom functions are instance-scoped -const staticDetails = HyperFormula.getFunctionDetails('MY_FUNCTION', 'enGB'); // undefined -``` +See the linked API reference for each method's exact return shape and for how +custom functions are reported. ## List of available functions diff --git a/src/HyperFormula.ts b/src/HyperFormula.ts index 8142b098c..3a349fe50 100644 --- a/src/HyperFormula.ts +++ b/src/HyperFormula.ts @@ -687,8 +687,9 @@ export class HyperFormula implements TypedEmitter { /** * Returns the full metadata of a single function for a given language: the parameter list (with per-parameter - * optionality), the number of trailing parameters that repeat (`repeatLastArgs`), the category and a short - * description. Returns `undefined` when the function id is unknown or not registered. + * optionality), the number of trailing parameters that repeat (`repeatLastArgs`), the category, a short + * description, and the documentation link (`documentationUrl`) and usage examples (`examples`) where authored + * (otherwise `''` and `[]`). Returns `undefined` when the function id is unknown or not registered. * * The static method resolves the globally-registered built-in functions and their aliases. For custom * (user-registered) functions, use the instance method [[getFunctionDetails]]. @@ -4546,10 +4547,11 @@ export class HyperFormula implements TypedEmitter { /** * Returns the full metadata of a single function registered in this instance, with names translated according to * the language set in this instance's configuration: the parameter list (with per-parameter optionality), the - * number of trailing parameters that repeat (`repeatLastArgs`), the category and a short description. Resolves both - * built-in and custom (user-registered) functions, as well as aliases. Returns `undefined` when the function id is - * unknown or not registered in this instance. For a custom function, `category` is `undefined`, `shortDescription` - * is empty, and parameters are reported positionally (`Arg1`, `Arg2`, ...). + * number of trailing parameters that repeat (`repeatLastArgs`), the category, a short description, and the + * documentation link (`documentationUrl`) and usage examples (`examples`) where authored (otherwise `''` and `[]`). + * Resolves both built-in and custom (user-registered) functions, as well as aliases. Returns `undefined` when the + * function id is unknown or not registered in this instance. For a custom function, `category` is `undefined`, + * `shortDescription` is empty, and parameters are reported positionally (`Arg1`, `Arg2`, ...). * * @param {string} canonicalName - the language-independent function id, e.g. `'SUMIF'` * diff --git a/src/interpreter/functionMetadata/FunctionDescription.ts b/src/interpreter/functionMetadata/FunctionDescription.ts index 39fdc0aff..f68ccfefa 100644 --- a/src/interpreter/functionMetadata/FunctionDescription.ts +++ b/src/interpreter/functionMetadata/FunctionDescription.ts @@ -92,6 +92,7 @@ export interface FunctionDetails { category: FunctionCategory | undefined, /** One-liner description (English in the MVP). Empty (`''`) for custom functions. */ shortDescription: string, + /** The function's parameters, in declaration order. */ parameters: FunctionParameterDescription[], /** * How many of the trailing `parameters` repeat indefinitely (a function with a variable number of arguments). From 4612e7599a93f1bcd28eaf15cc8410379ad98822 Mon Sep 17 00:00:00 2001 From: Kuba Sekowski Date: Tue, 14 Jul 2026 15:36:24 +0200 Subject: [PATCH 29/35] refactor(metadata): use snake_case for all catalogue parameter names (HF-249) (#1709) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Context Addresses a code-review finding on #1692: the function-metadata catalogue mixed several parameter-name conventions, which surface directly in a function-picker UI. Even closely-related functions disagreed — `SUMIF` used `Range, Criteria, Sumrange`, `SUMIFS` used `Sum_Range, Criterion_range1, Criterion1`, `AVERAGEIF` used `Range, Criterion, Average_Range` — mixing Title-case, `snake_Case`, and run-on tokens. This normalizes **every** `FunctionDoc` parameter name to `snake_case` so the catalogue is internally consistent. **What changed** - All 172 unique parameter names across the 13 `categories/*.ts` files are now `snake_case` (lowercase words joined by `_`, camelCase/acronym boundaries split, separators unified, trailing digits kept attached: `Number1`/`Number_1` → `number1`). - Run-on tokens the docs left unsplit are segmented so siblings agree: `Sumrange` → `sum_range` (matches `SUMIFS`), `Searchcriterion` → `search_criterion` (matches `VLOOKUP`/`HLOOKUP`), plus `logical_value`, `date_string`, `time_string`, `start_date`, `minimum_length`, `lower_bound`, `upper_bound`, `number_x`, `number_y`. - The migration generator (`scripts/hf249-migrate-function-docs.ts`) now emits `snake_case` via a shared, exported `toSnakeCase` helper (+ a small segmentation table), so a future regeneration stays consistent. Its `main()` is guarded with `require.main === module` so the helper can be imported without side effects. - **Not touched:** parameter `description`s, `examples`, `documentationUrl`, categories, short descriptions, ordering. Custom-function positional names (`Arg1`, `Arg2`, …) are unchanged — they are a documented, self-consistent placeholder for user functions that ship no metadata (see open question below). ### How did you test your changes? - `tsc --noEmit` — clean. - `eslint` on the changed files — 0 errors. - `test/smoke.spec.ts` — 4/4 pass. - Ad-hoc runtime checks against the built API: - every catalogue **and** `getFunctionDetails` parameter name matches `^[a-z][a-z0-9]*(_[a-z0-9]+)*$`; - names are unique within each function (no collisions introduced by the transform); - `getAvailableFunctions`/`getFunctionDetails` list↔details parity still holds; - `SUMIF` & `SUMIFS` both expose `sum_range`; `MATCH` & `VLOOKUP` both expose `search_criterion`; - custom-function details still report `Arg1`, `Arg2`. - Ran the generator to confirm it produces identical parameter names to this hand-applied transform (the only regen deltas are unrelated pre-existing drift — alphabetical re-sorting of manually-added `HSTACK`/`XIRR`, the hand-authored `SUM`/`SUMIF` fields, and a stale `TEXT` description — so the regen output was discarded). ### Types of changes - [ ] Breaking change (a fix or a feature because of which an existing functionality doesn't work as expected anymore) - [x] New feature or improvement (a non-breaking change that adds functionality) - [ ] Bug fix (a non-breaking change that fixes an issue) - [ ] Additional language file, or a change to an existing language file (translations) - [ ] Change to the documentation ### Related issues: 1. Follow-up to #1692 (HF-249); targets that branch. ### Notes for reviewers - **Paired tests:** the private test suite (`hyperformula-tests#14`) asserts specific parameter names (e.g. `SUMIF` params); those expectations need updating to the new `snake_case` names. - **Open question — custom functions:** the request was "snake_case for all param names". I scoped this to the catalogue and left the runtime custom-function placeholders as the documented `Arg1`/`Arg2`. If you'd also like those lowercased (`arg1`/`arg2`), it's a 1-line change in `buildCustomFunctionDetails` plus a `custom-functions.md` wording update — say the word. - **Segmentation calls** (`sumrange`→`sum_range`, etc.) are the only editorial decisions here; everything else is mechanical.
Open in Web Open in Cursor 
Co-authored-by: Cursor Agent Co-authored-by: Kuba Sekowski --- scripts/hf249-migrate-function-docs.ts | 56 +++++- .../categories/array-manipulation.ts | 12 +- .../functionMetadata/categories/database.ts | 24 +-- .../categories/date-and-time.ts | 48 ++--- .../categories/engineering.ts | 92 ++++----- .../functionMetadata/categories/financial.ts | 58 +++--- .../categories/information.ts | 30 +-- .../functionMetadata/categories/logical.ts | 18 +- .../categories/lookup-and-reference.ts | 26 +-- .../categories/math-and-trigonometry.ts | 146 +++++++------- .../categories/matrix-functions.ts | 8 +- .../functionMetadata/categories/operator.ts | 30 +-- .../categories/statistical.ts | 178 +++++++++--------- .../functionMetadata/categories/text.ts | 52 ++--- 14 files changed, 410 insertions(+), 368 deletions(-) diff --git a/scripts/hf249-migrate-function-docs.ts b/scripts/hf249-migrate-function-docs.ts index f09be0cdd..6b40bb8fe 100644 --- a/scripts/hf249-migrate-function-docs.ts +++ b/scripts/hf249-migrate-function-docs.ts @@ -29,9 +29,47 @@ const DOC_PATH = path.join(REPO_ROOT, 'docs/guide/built-in-functions.md') const CATEGORIES_DIR = path.join(REPO_ROOT, 'src/interpreter/functionMetadata/categories') const INDEX_PATH = path.join(REPO_ROOT, 'src/interpreter/functionMetadata/index.ts') -/** Parameter names the documentation under-specifies relative to the implementation arity. */ +/** Parameter names the documentation under-specifies relative to the implementation arity (already snake_case). */ const PARAMETER_NAME_OVERRIDES: Record = { - 'T.TEST': ['Array1', 'Array2', 'Tails', 'Type'], + 'T.TEST': ['array1', 'array2', 'tails', 'type'], +} + +/** + * Word-segmentation fixes for parameter tokens the documentation writes as a single run-on word (e.g. `Sumrange`), + * so they read consistently with their multi-word siblings (`Sum_Range` -> `sum_range`). Keyed by the mechanically + * snake-cased token; the value is the corrected snake_case name. + */ +const SNAKE_CASE_SEGMENTATION: Record = { + sumrange: 'sum_range', + searchcriterion: 'search_criterion', + logicalvalue: 'logical_value', + datestring: 'date_string', + timestring: 'time_string', + startdate: 'start_date', + minimumlength: 'minimum_length', + lowerbound: 'lower_bound', + upperbound: 'upper_bound', + numberx: 'number_x', + numbery: 'number_y', +} + +/** + * Converts a raw parameter name to snake_case: lowercase words joined by underscores, with camelCase/PascalCase and + * acronym boundaries split, existing separators unified, and trailing digits kept attached to their word + * (`Number1`, `Number_1` -> `number1`). A small segmentation table then fixes run-on tokens the docs left unsplit. + * + * @param {string} name - the raw parameter name from the syntax column + */ +export function toSnakeCase(name: string): string { + const mechanical = name + .replace(/([a-z0-9])([A-Z])/g, '$1_$2') + .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') + .replace(/[\s.\-]+/g, '_') + .toLowerCase() + .replace(/_+(\d)/g, '$1') + .replace(/_+/g, '_') + .replace(/^_|_$/g, '') + return SNAKE_CASE_SEGMENTATION[mechanical] ?? mechanical } interface DocRow { @@ -94,8 +132,9 @@ function uniquify(names: string[]): string[] { } /** - * Produces exactly `arity` unique, non-empty parameter names. The syntax column lists `Name1, Name2, ...NameN` - * for repeating groups, so the first `arity` names already collapse those groups onto the implementation arity. + * Produces exactly `arity` unique, non-empty snake_case parameter names. The syntax column lists + * `Name1, Name2, ...NameN` for repeating groups, so the first `arity` names already collapse those groups onto the + * implementation arity; each is normalized to snake_case and any shortfall is padded with `arg1`, `arg2`, ... */ function deriveParameterNames(id: string, syntax: string, arity: number): string[] { const override = PARAMETER_NAME_OVERRIDES[id] @@ -105,9 +144,9 @@ function deriveParameterNames(id: string, syntax: string, arity: number): string } return override } - const names = parseSyntaxNames(syntax).slice(0, arity) + const names = parseSyntaxNames(syntax).slice(0, arity).map(toSnakeCase) while (names.length < arity) { - names.push(`Arg${names.length + 1}`) + names.push(`arg${names.length + 1}`) } return uniquify(names) } @@ -231,4 +270,7 @@ function main(): void { console.log(`wrote ${path.relative(REPO_ROOT, INDEX_PATH)}; ${total} functions across ${categories.length} categories`) } -main() +// Only regenerate when executed directly; guarded so helpers (e.g. `toSnakeCase`) can be imported without side effects. +if (require.main === module) { + main() +} diff --git a/src/interpreter/functionMetadata/categories/array-manipulation.ts b/src/interpreter/functionMetadata/categories/array-manipulation.ts index 793f8533a..bf03946af 100644 --- a/src/interpreter/functionMetadata/categories/array-manipulation.ts +++ b/src/interpreter/functionMetadata/categories/array-manipulation.ts @@ -13,31 +13,31 @@ export const ARRAY_MANIPULATION_DOCS: Record = { ARRAY_CONSTRAIN: { category: 'Array manipulation', shortDescription: 'Truncates an array to given dimensions.', - parameters: [{name: 'Array', description: ''}, {name: 'Height', description: ''}, {name: 'Width', description: ''}], + parameters: [{name: 'array', description: ''}, {name: 'height', description: ''}, {name: 'width', description: ''}], }, ARRAYFORMULA: { category: 'Array manipulation', shortDescription: 'Enables the array arithmetic mode for a single formula.', - parameters: [{name: 'Formula', description: ''}], + parameters: [{name: 'formula', description: ''}], }, FILTER: { category: 'Array manipulation', shortDescription: 'Filters an array, based on multiple conditions (boolean arrays).', - parameters: [{name: 'SourceArray', description: ''}, {name: 'BoolArray1', description: ''}], + parameters: [{name: 'source_array', description: ''}, {name: 'bool_array1', description: ''}], }, SEQUENCE: { category: 'Array manipulation', shortDescription: 'Returns an array of sequential numbers.', - parameters: [{name: 'Rows', description: ''}, {name: 'Cols', description: ''}, {name: 'Start', description: ''}, {name: 'Step', description: ''}], + parameters: [{name: 'rows', description: ''}, {name: 'cols', description: ''}, {name: 'start', description: ''}, {name: 'step', description: ''}], }, VSTACK: { category: 'Array manipulation', shortDescription: 'Stacks arrays vertically into a single array.', - parameters: [{name: 'Array1', description: ''}], + parameters: [{name: 'array1', description: ''}], }, HSTACK: { category: 'Array manipulation', shortDescription: 'Stacks arrays horizontally into a single array.', - parameters: [{name: 'Array1', description: ''}], + parameters: [{name: 'array1', description: ''}], }, } diff --git a/src/interpreter/functionMetadata/categories/database.ts b/src/interpreter/functionMetadata/categories/database.ts index 89949d10d..4a2d3e1d7 100644 --- a/src/interpreter/functionMetadata/categories/database.ts +++ b/src/interpreter/functionMetadata/categories/database.ts @@ -13,61 +13,61 @@ export const DATABASE_DOCS: Record = { DAVERAGE: { category: 'Database', shortDescription: 'Returns the average of all values in a database field that match the given criteria.', - parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], }, DCOUNT: { category: 'Database', shortDescription: 'Counts the cells containing numbers in a database field that match the given criteria.', - parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], }, DCOUNTA: { category: 'Database', shortDescription: 'Counts the non-empty cells in a database field that match the given criteria.', - parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], }, DGET: { category: 'Database', shortDescription: 'Returns the single value from a database field that matches the given criteria. Returns #VALUE! if no records match, and #NUM! if more than one record matches.', - parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], }, DMAX: { category: 'Database', shortDescription: 'Returns the maximum value in a database field that matches the given criteria.', - parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], }, DMIN: { category: 'Database', shortDescription: 'Returns the minimum value in a database field that matches the given criteria.', - parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], }, DPRODUCT: { category: 'Database', shortDescription: 'Returns the product of all values in a database field that match the given criteria.', - parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], }, DSTDEV: { category: 'Database', shortDescription: 'Returns the sample standard deviation of all values in a database field that match the given criteria.', - parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], }, DSTDEVP: { category: 'Database', shortDescription: 'Returns the population standard deviation of all values in a database field that match the given criteria.', - parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], }, DSUM: { category: 'Database', shortDescription: 'Returns the sum of all values in a database field that match the given criteria.', - parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], }, DVAR: { category: 'Database', shortDescription: 'Returns the sample variance of all values in a database field that match the given criteria.', - parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], }, DVARP: { category: 'Database', shortDescription: 'Returns the population variance of all values in a database field that match the given criteria.', - parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}], + parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], }, } diff --git a/src/interpreter/functionMetadata/categories/date-and-time.ts b/src/interpreter/functionMetadata/categories/date-and-time.ts index 91a3d7c9b..fce033bb0 100644 --- a/src/interpreter/functionMetadata/categories/date-and-time.ts +++ b/src/interpreter/functionMetadata/categories/date-and-time.ts @@ -13,77 +13,77 @@ export const DATE_AND_TIME_DOCS: Record = { DATE: { category: 'Date and time', shortDescription: 'Returns the specified date as the number of full days since [`nullDate`](../api/interfaces/configparams.md#nulldate).', - parameters: [{name: 'Year', description: ''}, {name: 'Month', description: ''}, {name: 'Day', description: ''}], + parameters: [{name: 'year', description: ''}, {name: 'month', description: ''}, {name: 'day', description: ''}], }, DATEDIF: { category: 'Date and time', shortDescription: 'Calculates distance between two dates.
Supported units: "D" (days), "M" (months), "Y" (years), "MD" (days ignoring months and years), "YM" (months ignoring years), or "YD" (days ignoring years).', - parameters: [{name: 'Date1', description: ''}, {name: 'Date2', description: ''}, {name: 'Unit', description: ''}], + parameters: [{name: 'date1', description: ''}, {name: 'date2', description: ''}, {name: 'unit', description: ''}], }, DATEVALUE: { category: 'Date and time', shortDescription: 'Parses a date string and returns it as the number of full days since [`nullDate`](../api/interfaces/configparams.md#nulldate).
Accepts formats set by the [`dateFormats`](../api/interfaces/configparams.md#dateformats) option.', - parameters: [{name: 'Datestring', description: ''}], + parameters: [{name: 'date_string', description: ''}], }, DAY: { category: 'Date and time', shortDescription: 'Returns the day of the given date value.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, DAYS: { category: 'Date and time', shortDescription: 'Calculates the difference between two date values.', - parameters: [{name: 'Date2', description: ''}, {name: 'Date1', description: ''}], + parameters: [{name: 'date2', description: ''}, {name: 'date1', description: ''}], }, DAYS360: { category: 'Date and time', shortDescription: 'Calculates the difference between two date values in days, in 360-day basis.', - parameters: [{name: 'Date2', description: ''}, {name: 'Date1', description: ''}, {name: 'Format', description: ''}], + parameters: [{name: 'date2', description: ''}, {name: 'date1', description: ''}, {name: 'format', description: ''}], }, EDATE: { category: 'Date and time', shortDescription: 'Shifts the given startdate by given number of months and returns it as the number of full days since [`nullDate`](../api/interfaces/configparams.md#nulldate).[^non-odff]', - parameters: [{name: 'Startdate', description: ''}, {name: 'Months', description: ''}], + parameters: [{name: 'start_date', description: ''}, {name: 'months', description: ''}], }, EOMONTH: { category: 'Date and time', shortDescription: 'Returns the date of the last day of a month which falls months away from the start date. Returns the value in the form of number of full days since [`nullDate`](../api/interfaces/configparams.md#nulldate).[^non-odff]', - parameters: [{name: 'Startdate', description: ''}, {name: 'Months', description: ''}], + parameters: [{name: 'start_date', description: ''}, {name: 'months', description: ''}], }, HOUR: { category: 'Date and time', shortDescription: 'Returns hour component of given time.', - parameters: [{name: 'Time', description: ''}], + parameters: [{name: 'time', description: ''}], }, INTERVAL: { category: 'Date and time', shortDescription: 'Returns interval string from given number of seconds.', - parameters: [{name: 'Seconds', description: ''}], + parameters: [{name: 'seconds', description: ''}], }, ISOWEEKNUM: { category: 'Date and time', shortDescription: 'Returns an ISO week number that corresponds to the week of year.', - parameters: [{name: 'Date', description: ''}], + parameters: [{name: 'date', description: ''}], }, MINUTE: { category: 'Date and time', shortDescription: 'Returns minute component of given time.', - parameters: [{name: 'Time', description: ''}], + parameters: [{name: 'time', description: ''}], }, MONTH: { category: 'Date and time', shortDescription: 'Returns the month for the given date value.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, NETWORKDAYS: { category: 'Date and time', shortDescription: 'Returns the number of working days between two given dates.', - parameters: [{name: 'Date1', description: ''}, {name: 'Date2', description: ''}, {name: 'Holidays', description: ''}], + parameters: [{name: 'date1', description: ''}, {name: 'date2', description: ''}, {name: 'holidays', description: ''}], }, 'NETWORKDAYS.INTL': { category: 'Date and time', shortDescription: 'Returns the number of working days between two given dates.', - parameters: [{name: 'Date1', description: ''}, {name: 'Date2', description: ''}, {name: 'Mode', description: ''}, {name: 'Holidays', description: ''}], + parameters: [{name: 'date1', description: ''}, {name: 'date2', description: ''}, {name: 'mode', description: ''}, {name: 'holidays', description: ''}], }, NOW: { category: 'Date and time', @@ -93,17 +93,17 @@ export const DATE_AND_TIME_DOCS: Record = { SECOND: { category: 'Date and time', shortDescription: 'Returns second component of given time.', - parameters: [{name: 'Time', description: ''}], + parameters: [{name: 'time', description: ''}], }, TIME: { category: 'Date and time', shortDescription: 'Returns the number that represents a given time as a fraction of full day.', - parameters: [{name: 'Hour', description: ''}, {name: 'Minute', description: ''}, {name: 'Second', description: ''}], + parameters: [{name: 'hour', description: ''}, {name: 'minute', description: ''}, {name: 'second', description: ''}], }, TIMEVALUE: { category: 'Date and time', shortDescription: 'Parses a time string and returns a number that represents it as a fraction of a full day.
Accepts formats set by the [`timeFormats`](../api/interfaces/configparams.md#timeformats) option.', - parameters: [{name: 'Timestring', description: ''}], + parameters: [{name: 'time_string', description: ''}], }, TODAY: { category: 'Date and time', @@ -113,31 +113,31 @@ export const DATE_AND_TIME_DOCS: Record = { WEEKDAY: { category: 'Date and time', shortDescription: 'Computes a number between 1-7 representing the day of week.', - parameters: [{name: 'Date', description: ''}, {name: 'Type', description: ''}], + parameters: [{name: 'date', description: ''}, {name: 'type', description: ''}], }, WEEKNUM: { category: 'Date and time', shortDescription: 'Returns a week number that corresponds to the week of year.', - parameters: [{name: 'Date', description: ''}, {name: 'Type', description: ''}], + parameters: [{name: 'date', description: ''}, {name: 'type', description: ''}], }, WORKDAY: { category: 'Date and time', shortDescription: 'Returns the working day number of days from start day.', - parameters: [{name: 'Date', description: ''}, {name: 'Shift', description: ''}, {name: 'Holidays', description: ''}], + parameters: [{name: 'date', description: ''}, {name: 'shift', description: ''}, {name: 'holidays', description: ''}], }, 'WORKDAY.INTL': { category: 'Date and time', shortDescription: 'Returns the working day number of days from start day.', - parameters: [{name: 'Date', description: ''}, {name: 'Shift', description: ''}, {name: 'Mode', description: ''}, {name: 'Holidays', description: ''}], + parameters: [{name: 'date', description: ''}, {name: 'shift', description: ''}, {name: 'mode', description: ''}, {name: 'holidays', description: ''}], }, YEAR: { category: 'Date and time', shortDescription: 'Returns the year as a number according to the internal calculation rules.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, YEARFRAC: { category: 'Date and time', shortDescription: 'Computes the difference between two date values, in fraction of years.', - parameters: [{name: 'Date2', description: ''}, {name: 'Date1', description: ''}, {name: 'Format', description: ''}], + parameters: [{name: 'date2', description: ''}, {name: 'date1', description: ''}, {name: 'format', description: ''}], }, } diff --git a/src/interpreter/functionMetadata/categories/engineering.ts b/src/interpreter/functionMetadata/categories/engineering.ts index d15ef5d67..eb15286fc 100644 --- a/src/interpreter/functionMetadata/categories/engineering.ts +++ b/src/interpreter/functionMetadata/categories/engineering.ts @@ -13,231 +13,231 @@ export const ENGINEERING_DOCS: Record = { BIN2DEC: { category: 'Engineering', shortDescription: 'The result is the decimal number for the binary number entered.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, BIN2HEX: { category: 'Engineering', shortDescription: 'The result is the hexadecimal number for the binary number entered.', - parameters: [{name: 'Number', description: ''}, {name: 'Places', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'places', description: ''}], }, BIN2OCT: { category: 'Engineering', shortDescription: 'The result is the octal number for the binary number entered.', - parameters: [{name: 'Number', description: ''}, {name: 'Places', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'places', description: ''}], }, BITAND: { category: 'Engineering', shortDescription: 'Returns a bitwise logical "and" of the parameters.', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], }, BITLSHIFT: { category: 'Engineering', shortDescription: 'Shifts a number left by n bits.', - parameters: [{name: 'Number', description: ''}, {name: 'Shift', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'shift', description: ''}], }, BITOR: { category: 'Engineering', shortDescription: 'Returns a bitwise logical "or" of the parameters.', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], }, BITRSHIFT: { category: 'Engineering', shortDescription: 'Shifts a number right by n bits.', - parameters: [{name: 'Number', description: ''}, {name: 'Shift', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'shift', description: ''}], }, BITXOR: { category: 'Engineering', shortDescription: 'Returns a bitwise logical "exclusive or" of the parameters.', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], }, COMPLEX: { category: 'Engineering', shortDescription: 'Returns complex number from Re and Im parts.', - parameters: [{name: 'Re', description: ''}, {name: 'Im', description: ''}, {name: 'Symbol', description: ''}], + parameters: [{name: 're', description: ''}, {name: 'im', description: ''}, {name: 'symbol', description: ''}], }, DEC2BIN: { category: 'Engineering', shortDescription: 'Returns the binary number for the decimal number entered between –512 and 511.', - parameters: [{name: 'Number', description: ''}, {name: 'Places', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'places', description: ''}], }, DEC2HEX: { category: 'Engineering', shortDescription: 'Returns the hexadecimal number for the decimal number entered.', - parameters: [{name: 'Number', description: ''}, {name: 'Places', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'places', description: ''}], }, DEC2OCT: { category: 'Engineering', shortDescription: 'Returns the octal number for the decimal number entered.', - parameters: [{name: 'Number', description: ''}, {name: 'Places', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'places', description: ''}], }, DELTA: { category: 'Engineering', shortDescription: 'Returns TRUE (1) if both numbers are equal, otherwise returns FALSE (0).', - parameters: [{name: 'Number_1', description: ''}, {name: 'Number_2', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], }, ERF: { category: 'Engineering', shortDescription: 'Returns values of the Gaussian error integral.', - parameters: [{name: 'Lower_Limit', description: ''}, {name: 'Upper_Limit', description: ''}], + parameters: [{name: 'lower_limit', description: ''}, {name: 'upper_limit', description: ''}], }, ERFC: { category: 'Engineering', shortDescription: 'Returns complementary values of the Gaussian error integral between x and infinity.', - parameters: [{name: 'Lower_Limit', description: ''}], + parameters: [{name: 'lower_limit', description: ''}], }, HEX2BIN: { category: 'Engineering', shortDescription: 'The result is the binary number for the hexadecimal number entered.', - parameters: [{name: 'Number', description: ''}, {name: 'Places', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'places', description: ''}], }, HEX2DEC: { category: 'Engineering', shortDescription: 'The result is the decimal number for the hexadecimal number entered.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, HEX2OCT: { category: 'Engineering', shortDescription: 'The result is the octal number for the hexadecimal number entered.', - parameters: [{name: 'Number', description: ''}, {name: 'Places', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'places', description: ''}], }, IMABS: { category: 'Engineering', shortDescription: 'Returns modulus of a complex number.', - parameters: [{name: 'Complex', description: ''}], + parameters: [{name: 'complex', description: ''}], }, IMAGINARY: { category: 'Engineering', shortDescription: 'Returns imaginary part of a complex number.', - parameters: [{name: 'Complex', description: ''}], + parameters: [{name: 'complex', description: ''}], }, IMARGUMENT: { category: 'Engineering', shortDescription: 'Returns argument of a complex number.', - parameters: [{name: 'Complex', description: ''}], + parameters: [{name: 'complex', description: ''}], }, IMCONJUGATE: { category: 'Engineering', shortDescription: 'Returns conjugate of a complex number.', - parameters: [{name: 'Complex', description: ''}], + parameters: [{name: 'complex', description: ''}], }, IMCOS: { category: 'Engineering', shortDescription: 'Returns cosine of a complex number.', - parameters: [{name: 'Complex', description: ''}], + parameters: [{name: 'complex', description: ''}], }, IMCOSH: { category: 'Engineering', shortDescription: 'Returns hyperbolic cosine of a complex number.', - parameters: [{name: 'Complex', description: ''}], + parameters: [{name: 'complex', description: ''}], }, IMCOT: { category: 'Engineering', shortDescription: 'Returns cotangent of a complex number.', - parameters: [{name: 'Complex', description: ''}], + parameters: [{name: 'complex', description: ''}], }, IMCSC: { category: 'Engineering', shortDescription: 'Returns cosecant of a complex number.', - parameters: [{name: 'Complex', description: ''}], + parameters: [{name: 'complex', description: ''}], }, IMCSCH: { category: 'Engineering', shortDescription: 'Returns hyperbolic cosecant of a complex number.', - parameters: [{name: 'Complex', description: ''}], + parameters: [{name: 'complex', description: ''}], }, IMDIV: { category: 'Engineering', shortDescription: 'Divides two complex numbers.', - parameters: [{name: 'Complex1', description: ''}, {name: 'Complex2', description: ''}], + parameters: [{name: 'complex1', description: ''}, {name: 'complex2', description: ''}], }, IMEXP: { category: 'Engineering', shortDescription: 'Returns exponent of a complex number.', - parameters: [{name: 'Complex', description: ''}], + parameters: [{name: 'complex', description: ''}], }, IMLN: { category: 'Engineering', shortDescription: 'Returns natural logarithm of a complex number.', - parameters: [{name: 'Complex', description: ''}], + parameters: [{name: 'complex', description: ''}], }, IMLOG10: { category: 'Engineering', shortDescription: 'Returns base-10 logarithm of a complex number.', - parameters: [{name: 'Complex', description: ''}], + parameters: [{name: 'complex', description: ''}], }, IMLOG2: { category: 'Engineering', shortDescription: 'Returns binary logarithm of a complex number.', - parameters: [{name: 'Complex', description: ''}], + parameters: [{name: 'complex', description: ''}], }, IMPOWER: { category: 'Engineering', shortDescription: 'Returns a complex number raised to a given power.', - parameters: [{name: 'Complex', description: ''}, {name: 'Number', description: ''}], + parameters: [{name: 'complex', description: ''}, {name: 'number', description: ''}], }, IMPRODUCT: { category: 'Engineering', shortDescription: 'Multiplies complex numbers.', - parameters: [{name: 'Complex1', description: ''}], + parameters: [{name: 'complex1', description: ''}], }, IMREAL: { category: 'Engineering', shortDescription: 'Returns real part of a complex number.', - parameters: [{name: 'Complex', description: ''}], + parameters: [{name: 'complex', description: ''}], }, IMSEC: { category: 'Engineering', shortDescription: 'Returns the secant of a complex number.', - parameters: [{name: 'Complex', description: ''}], + parameters: [{name: 'complex', description: ''}], }, IMSECH: { category: 'Engineering', shortDescription: 'Returns the hyperbolic secant of a complex number.', - parameters: [{name: 'Complex', description: ''}], + parameters: [{name: 'complex', description: ''}], }, IMSIN: { category: 'Engineering', shortDescription: 'Returns sine of a complex number.', - parameters: [{name: 'Complex', description: ''}], + parameters: [{name: 'complex', description: ''}], }, IMSINH: { category: 'Engineering', shortDescription: 'Returns hyperbolic sine of a complex number.', - parameters: [{name: 'Complex', description: ''}], + parameters: [{name: 'complex', description: ''}], }, IMSQRT: { category: 'Engineering', shortDescription: 'Returns a square root of a complex number.', - parameters: [{name: 'Complex', description: ''}], + parameters: [{name: 'complex', description: ''}], }, IMSUB: { category: 'Engineering', shortDescription: 'Subtracts two complex numbers.', - parameters: [{name: 'Complex1', description: ''}, {name: 'Complex2', description: ''}], + parameters: [{name: 'complex1', description: ''}, {name: 'complex2', description: ''}], }, IMSUM: { category: 'Engineering', shortDescription: 'Adds complex numbers.', - parameters: [{name: 'Complex1', description: ''}], + parameters: [{name: 'complex1', description: ''}], }, IMTAN: { category: 'Engineering', shortDescription: 'Returns the tangent of a complex number.', - parameters: [{name: 'Complex', description: ''}], + parameters: [{name: 'complex', description: ''}], }, OCT2BIN: { category: 'Engineering', shortDescription: 'The result is the binary number for the octal number entered.', - parameters: [{name: 'Number', description: ''}, {name: 'Places', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'places', description: ''}], }, OCT2DEC: { category: 'Engineering', shortDescription: 'The result is the decimal number for the octal number entered.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, OCT2HEX: { category: 'Engineering', shortDescription: 'The result is the hexadecimal number for the octal number entered.', - parameters: [{name: 'Number', description: ''}, {name: 'Places', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'places', description: ''}], }, } diff --git a/src/interpreter/functionMetadata/categories/financial.ts b/src/interpreter/functionMetadata/categories/financial.ts index 05244947a..c4cb31e5b 100644 --- a/src/interpreter/functionMetadata/categories/financial.ts +++ b/src/interpreter/functionMetadata/categories/financial.ts @@ -13,146 +13,146 @@ export const FINANCIAL_DOCS: Record = { CUMIPMT: { category: 'Financial', shortDescription: 'Returns the cumulative interest paid on a loan between a start period and an end period.', - parameters: [{name: 'Rate', description: ''}, {name: 'Nper', description: ''}, {name: 'Pv', description: ''}, {name: 'Start', description: ''}, {name: 'End', description: ''}, {name: 'Type', description: ''}], + parameters: [{name: 'rate', description: ''}, {name: 'nper', description: ''}, {name: 'pv', description: ''}, {name: 'start', description: ''}, {name: 'end', description: ''}, {name: 'type', description: ''}], }, CUMPRINC: { category: 'Financial', shortDescription: 'Returns the cumulative principal paid on a loan between a start period and an end period.', - parameters: [{name: 'Rate', description: ''}, {name: 'Nper', description: ''}, {name: 'Pv', description: ''}, {name: 'Start', description: ''}, {name: 'End', description: ''}, {name: 'Type', description: ''}], + parameters: [{name: 'rate', description: ''}, {name: 'nper', description: ''}, {name: 'pv', description: ''}, {name: 'start', description: ''}, {name: 'end', description: ''}, {name: 'type', description: ''}], }, DB: { category: 'Financial', shortDescription: 'Returns the depreciation of an asset for a period using the fixed-declining balance method.', - parameters: [{name: 'Cost', description: ''}, {name: 'Salvage', description: ''}, {name: 'Life', description: ''}, {name: 'Period', description: ''}, {name: 'Month', description: ''}], + parameters: [{name: 'cost', description: ''}, {name: 'salvage', description: ''}, {name: 'life', description: ''}, {name: 'period', description: ''}, {name: 'month', description: ''}], }, DDB: { category: 'Financial', shortDescription: 'Returns the depreciation of an asset for a period using the double-declining balance method.', - parameters: [{name: 'Cost', description: ''}, {name: 'Salvage', description: ''}, {name: 'Life', description: ''}, {name: 'Period', description: ''}, {name: 'Factor', description: ''}], + parameters: [{name: 'cost', description: ''}, {name: 'salvage', description: ''}, {name: 'life', description: ''}, {name: 'period', description: ''}, {name: 'factor', description: ''}], }, DOLLARDE: { category: 'Financial', shortDescription: 'Converts a price entered with a special notation to a price displayed as a decimal number.', - parameters: [{name: 'Price', description: ''}, {name: 'Fraction', description: ''}], + parameters: [{name: 'price', description: ''}, {name: 'fraction', description: ''}], }, DOLLARFR: { category: 'Financial', shortDescription: 'Converts a price displayed as a decimal number to a price entered with a special notation.', - parameters: [{name: 'Price', description: ''}, {name: 'Fraction', description: ''}], + parameters: [{name: 'price', description: ''}, {name: 'fraction', description: ''}], }, EFFECT: { category: 'Financial', shortDescription: 'Calculates the effective annual interest rate from a nominal interest rate and the number of compounding periods per year.', - parameters: [{name: 'Nominal_rate', description: ''}, {name: 'Npery', description: ''}], + parameters: [{name: 'nominal_rate', description: ''}, {name: 'npery', description: ''}], }, FV: { category: 'Financial', shortDescription: 'Returns the future value of an investment.', - parameters: [{name: 'Rate', description: ''}, {name: 'Nper', description: ''}, {name: 'Pmt', description: ''}, {name: 'Pv', description: ''}, {name: 'Type', description: ''}], + parameters: [{name: 'rate', description: ''}, {name: 'nper', description: ''}, {name: 'pmt', description: ''}, {name: 'pv', description: ''}, {name: 'type', description: ''}], }, FVSCHEDULE: { category: 'Financial', shortDescription: 'Returns the future value of an investment based on a rate schedule.', - parameters: [{name: 'Pv', description: ''}, {name: 'Schedule', description: ''}], + parameters: [{name: 'pv', description: ''}, {name: 'schedule', description: ''}], }, IPMT: { category: 'Financial', shortDescription: 'Returns the interest portion of a given loan payment in a given payment period.', - parameters: [{name: 'Rate', description: ''}, {name: 'Per', description: ''}, {name: 'Nper', description: ''}, {name: 'Pv', description: ''}, {name: 'Fv', description: ''}, {name: 'Type', description: ''}], + parameters: [{name: 'rate', description: ''}, {name: 'per', description: ''}, {name: 'nper', description: ''}, {name: 'pv', description: ''}, {name: 'fv', description: ''}, {name: 'type', description: ''}], }, IRR: { category: 'Financial', shortDescription: 'Returns the internal rate of return for a series of cash flows.', - parameters: [{name: 'Values', description: ''}, {name: 'Guess', description: ''}], + parameters: [{name: 'values', description: ''}, {name: 'guess', description: ''}], }, ISPMT: { category: 'Financial', shortDescription: 'Returns the interest paid for a given period of an investment with equal principal payments.', - parameters: [{name: 'Rate', description: ''}, {name: 'Per', description: ''}, {name: 'Nper', description: ''}, {name: 'Value', description: ''}], + parameters: [{name: 'rate', description: ''}, {name: 'per', description: ''}, {name: 'nper', description: ''}, {name: 'value', description: ''}], }, MIRR: { category: 'Financial', shortDescription: 'Returns modified internal value for cashflows.', - parameters: [{name: 'Flows', description: ''}, {name: 'FRate', description: ''}, {name: 'RRate', description: ''}], + parameters: [{name: 'flows', description: ''}, {name: 'f_rate', description: ''}, {name: 'r_rate', description: ''}], }, NOMINAL: { category: 'Financial', shortDescription: 'Returns the nominal interest rate.', - parameters: [{name: 'Effect_rate', description: ''}, {name: 'Npery', description: ''}], + parameters: [{name: 'effect_rate', description: ''}, {name: 'npery', description: ''}], }, NPER: { category: 'Financial', shortDescription: 'Returns the number of periods for an investment assuming periodic, constant payments and a constant interest rate.', - parameters: [{name: 'Rate', description: ''}, {name: 'Pmt', description: ''}, {name: 'Pv', description: ''}, {name: 'Fv', description: ''}, {name: 'Type', description: ''}], + parameters: [{name: 'rate', description: ''}, {name: 'pmt', description: ''}, {name: 'pv', description: ''}, {name: 'fv', description: ''}, {name: 'type', description: ''}], }, NPV: { category: 'Financial', shortDescription: 'Returns net present value.', - parameters: [{name: 'Rate', description: ''}, {name: 'Value1', description: ''}], + parameters: [{name: 'rate', description: ''}, {name: 'value1', description: ''}], }, PDURATION: { category: 'Financial', shortDescription: 'Returns number of periods to reach specific value.', - parameters: [{name: 'Rate', description: ''}, {name: 'Pv', description: ''}, {name: 'Fv', description: ''}], + parameters: [{name: 'rate', description: ''}, {name: 'pv', description: ''}, {name: 'fv', description: ''}], }, PMT: { category: 'Financial', shortDescription: 'Returns the periodic payment for a loan.', - parameters: [{name: 'Rate', description: ''}, {name: 'Nper', description: ''}, {name: 'Pv', description: ''}, {name: 'Fv', description: ''}, {name: 'Type', description: ''}], + parameters: [{name: 'rate', description: ''}, {name: 'nper', description: ''}, {name: 'pv', description: ''}, {name: 'fv', description: ''}, {name: 'type', description: ''}], }, PPMT: { category: 'Financial', shortDescription: 'Calculates the principal portion of a given loan payment.', - parameters: [{name: 'Rate', description: ''}, {name: 'Per', description: ''}, {name: 'Nper', description: ''}, {name: 'Pv', description: ''}, {name: 'Fv', description: ''}, {name: 'Type', description: ''}], + parameters: [{name: 'rate', description: ''}, {name: 'per', description: ''}, {name: 'nper', description: ''}, {name: 'pv', description: ''}, {name: 'fv', description: ''}, {name: 'type', description: ''}], }, PV: { category: 'Financial', shortDescription: 'Returns the present value of an investment.', - parameters: [{name: 'Rate', description: ''}, {name: 'Nper', description: ''}, {name: 'Pmt', description: ''}, {name: 'Fv', description: ''}, {name: 'Type', description: ''}], + parameters: [{name: 'rate', description: ''}, {name: 'nper', description: ''}, {name: 'pmt', description: ''}, {name: 'fv', description: ''}, {name: 'type', description: ''}], }, RATE: { category: 'Financial', shortDescription: 'Returns the interest rate per period of an annuity.', - parameters: [{name: 'Nper', description: ''}, {name: 'Pmt', description: ''}, {name: 'Pv', description: ''}, {name: 'Fv', description: ''}, {name: 'Type', description: ''}, {name: 'Guess', description: ''}], + parameters: [{name: 'nper', description: ''}, {name: 'pmt', description: ''}, {name: 'pv', description: ''}, {name: 'fv', description: ''}, {name: 'type', description: ''}, {name: 'guess', description: ''}], }, RRI: { category: 'Financial', shortDescription: 'Returns an equivalent interest rate for the growth of an investment.', - parameters: [{name: 'Nper', description: ''}, {name: 'Pv', description: ''}, {name: 'Fv', description: ''}], + parameters: [{name: 'nper', description: ''}, {name: 'pv', description: ''}, {name: 'fv', description: ''}], }, SLN: { category: 'Financial', shortDescription: 'Returns the depreciation of an asset for one period, based on a straight-line method.', - parameters: [{name: 'Cost', description: ''}, {name: 'Salvage', description: ''}, {name: 'Life', description: ''}], + parameters: [{name: 'cost', description: ''}, {name: 'salvage', description: ''}, {name: 'life', description: ''}], }, SYD: { category: 'Financial', shortDescription: 'Returns the "sum-of-years" depreciation for an asset in a period.', - parameters: [{name: 'Cost', description: ''}, {name: 'Salvage', description: ''}, {name: 'Life', description: ''}, {name: 'Period', description: ''}], + parameters: [{name: 'cost', description: ''}, {name: 'salvage', description: ''}, {name: 'life', description: ''}, {name: 'period', description: ''}], }, TBILLEQ: { category: 'Financial', shortDescription: 'Returns the bond-equivalent yield for a Treasury bill.', - parameters: [{name: 'Settlement', description: ''}, {name: 'Maturity', description: ''}, {name: 'Discount', description: ''}], + parameters: [{name: 'settlement', description: ''}, {name: 'maturity', description: ''}, {name: 'discount', description: ''}], }, TBILLPRICE: { category: 'Financial', shortDescription: 'Returns the price per $100 face value for a Treasury bill.', - parameters: [{name: 'Settlement', description: ''}, {name: 'Maturity', description: ''}, {name: 'Discount', description: ''}], + parameters: [{name: 'settlement', description: ''}, {name: 'maturity', description: ''}, {name: 'discount', description: ''}], }, TBILLYIELD: { category: 'Financial', shortDescription: 'Returns the yield for a Treasury bill.', - parameters: [{name: 'Settlement', description: ''}, {name: 'Maturity', description: ''}, {name: 'Price', description: ''}], + parameters: [{name: 'settlement', description: ''}, {name: 'maturity', description: ''}, {name: 'price', description: ''}], }, XNPV: { category: 'Financial', shortDescription: 'Returns net present value.', - parameters: [{name: 'Rate', description: ''}, {name: 'Payments', description: ''}, {name: 'Dates', description: ''}], + parameters: [{name: 'rate', description: ''}, {name: 'payments', description: ''}, {name: 'dates', description: ''}], }, XIRR: { category: 'Financial', shortDescription: 'Returns the internal rate of return for a schedule of cash flows that is not necessarily periodic.', - parameters: [{name: 'Values', description: ''}, {name: 'Dates', description: ''}, {name: 'Guess', description: ''}], + parameters: [{name: 'values', description: ''}, {name: 'dates', description: ''}, {name: 'guess', description: ''}], }, } diff --git a/src/interpreter/functionMetadata/categories/information.ts b/src/interpreter/functionMetadata/categories/information.ts index ab12675e7..1799f73a6 100644 --- a/src/interpreter/functionMetadata/categories/information.ts +++ b/src/interpreter/functionMetadata/categories/information.ts @@ -13,67 +13,67 @@ export const INFORMATION_DOCS: Record = { ISBINARY: { category: 'Information', shortDescription: 'Returns TRUE if provided value is a valid binary number.', - parameters: [{name: 'Value', description: ''}], + parameters: [{name: 'value', description: ''}], }, ISBLANK: { category: 'Information', shortDescription: 'Returns TRUE if the reference to a cell is blank.', - parameters: [{name: 'Value', description: ''}], + parameters: [{name: 'value', description: ''}], }, ISERR: { category: 'Information', shortDescription: 'Returns TRUE if the value is error value except #N/A!.', - parameters: [{name: 'Value', description: ''}], + parameters: [{name: 'value', description: ''}], }, ISERROR: { category: 'Information', shortDescription: 'Returns TRUE if the value is general error value.', - parameters: [{name: 'Value', description: ''}], + parameters: [{name: 'value', description: ''}], }, ISEVEN: { category: 'Information', shortDescription: 'Returns TRUE if the value is an even integer, or FALSE if the value is odd.', - parameters: [{name: 'Value', description: ''}], + parameters: [{name: 'value', description: ''}], }, ISFORMULA: { category: 'Information', shortDescription: 'Checks whether referenced cell is a formula.', - parameters: [{name: 'Value', description: ''}], + parameters: [{name: 'value', description: ''}], }, ISLOGICAL: { category: 'Information', shortDescription: 'Tests for a logical value (TRUE or FALSE).', - parameters: [{name: 'Value', description: ''}], + parameters: [{name: 'value', description: ''}], }, ISNA: { category: 'Information', shortDescription: 'Returns TRUE if the value is #N/A! error.', - parameters: [{name: 'Value', description: ''}], + parameters: [{name: 'value', description: ''}], }, ISNONTEXT: { category: 'Information', shortDescription: 'Tests if the cell contents are text or numbers, and returns FALSE if the contents are text.', - parameters: [{name: 'Value', description: ''}], + parameters: [{name: 'value', description: ''}], }, ISNUMBER: { category: 'Information', shortDescription: 'Returns TRUE if the value refers to a number.', - parameters: [{name: 'Value', description: ''}], + parameters: [{name: 'value', description: ''}], }, ISODD: { category: 'Information', shortDescription: 'Returns TRUE if the value is odd, or FALSE if the number is even.', - parameters: [{name: 'Value', description: ''}], + parameters: [{name: 'value', description: ''}], }, ISREF: { category: 'Information', shortDescription: 'Returns TRUE if provided value is #REF! error.', - parameters: [{name: 'Value', description: ''}], + parameters: [{name: 'value', description: ''}], }, ISTEXT: { category: 'Information', shortDescription: 'Returns TRUE if the cell contents reference text.', - parameters: [{name: 'Value', description: ''}], + parameters: [{name: 'value', description: ''}], }, NA: { category: 'Information', @@ -83,11 +83,11 @@ export const INFORMATION_DOCS: Record = { SHEET: { category: 'Information', shortDescription: 'Returns sheet number of a given value or a formula sheet number if no argument is provided.', - parameters: [{name: 'Value', description: ''}], + parameters: [{name: 'value', description: ''}], }, SHEETS: { category: 'Information', shortDescription: 'Returns number of sheet of a given reference or number of all sheets in workbook when no argument is provided.', - parameters: [{name: 'Value', description: ''}], + parameters: [{name: 'value', description: ''}], }, } diff --git a/src/interpreter/functionMetadata/categories/logical.ts b/src/interpreter/functionMetadata/categories/logical.ts index b9e2e86c0..87a20b9ec 100644 --- a/src/interpreter/functionMetadata/categories/logical.ts +++ b/src/interpreter/functionMetadata/categories/logical.ts @@ -13,7 +13,7 @@ export const LOGICAL_DOCS: Record = { AND: { category: 'Logical', shortDescription: 'Returns TRUE if all arguments are TRUE.', - parameters: [{name: 'Logical_value1', description: ''}], + parameters: [{name: 'logical_value1', description: ''}], }, FALSE: { category: 'Logical', @@ -23,37 +23,37 @@ export const LOGICAL_DOCS: Record = { IF: { category: 'Logical', shortDescription: 'Specifies a logical test to be performed.', - parameters: [{name: 'Test', description: ''}, {name: 'Then_value', description: ''}, {name: 'Otherwise_value', description: ''}], + parameters: [{name: 'test', description: ''}, {name: 'then_value', description: ''}, {name: 'otherwise_value', description: ''}], }, IFERROR: { category: 'Logical', shortDescription: 'Returns the value if the cell does not contains an error value, or the alternative value if it does.', - parameters: [{name: 'Value', description: ''}, {name: 'Alternate_value', description: ''}], + parameters: [{name: 'value', description: ''}, {name: 'alternate_value', description: ''}], }, IFNA: { category: 'Logical', shortDescription: 'Returns the value if the cell does not contains the #N/A (value not available) error value, or the alternative value if it does.', - parameters: [{name: 'Value', description: ''}, {name: 'Alternate_value', description: ''}], + parameters: [{name: 'value', description: ''}, {name: 'alternate_value', description: ''}], }, IFS: { category: 'Logical', shortDescription: 'Evaluates multiple logical tests and returns a value that corresponds to the first true condition.', - parameters: [{name: 'Condition1', description: ''}, {name: 'Value1', description: ''}], + parameters: [{name: 'condition1', description: ''}, {name: 'value1', description: ''}], }, NOT: { category: 'Logical', shortDescription: 'Complements (inverts) a logical value.', - parameters: [{name: 'Logicalvalue', description: ''}], + parameters: [{name: 'logical_value', description: ''}], }, OR: { category: 'Logical', shortDescription: 'Returns TRUE if at least one argument is TRUE.', - parameters: [{name: 'Logical_value1', description: ''}], + parameters: [{name: 'logical_value1', description: ''}], }, SWITCH: { category: 'Logical', shortDescription: 'Evaluates a list of arguments, consisting of an expression followed by a value.', - parameters: [{name: 'Expression1', description: ''}, {name: 'Value1', description: ''}, {name: 'Expression2', description: ''}], + parameters: [{name: 'expression1', description: ''}, {name: 'value1', description: ''}, {name: 'expression2', description: ''}], }, TRUE: { category: 'Logical', @@ -63,6 +63,6 @@ export const LOGICAL_DOCS: Record = { XOR: { category: 'Logical', shortDescription: 'Returns true if an odd number of arguments evaluates to TRUE.', - parameters: [{name: 'Logical_value1', description: ''}], + parameters: [{name: 'logical_value1', description: ''}], }, } diff --git a/src/interpreter/functionMetadata/categories/lookup-and-reference.ts b/src/interpreter/functionMetadata/categories/lookup-and-reference.ts index a1b491563..456e76265 100644 --- a/src/interpreter/functionMetadata/categories/lookup-and-reference.ts +++ b/src/interpreter/functionMetadata/categories/lookup-and-reference.ts @@ -13,66 +13,66 @@ export const LOOKUP_AND_REFERENCE_DOCS: Record = { ADDRESS: { category: 'Lookup and reference', shortDescription: 'Returns a cell reference as a string.', - parameters: [{name: 'Row', description: ''}, {name: 'Column', description: ''}, {name: 'AbsoluteRelativeMode', description: ''}, {name: 'UseA1Notation', description: ''}, {name: 'Sheet', description: ''}], + parameters: [{name: 'row', description: ''}, {name: 'column', description: ''}, {name: 'absolute_relative_mode', description: ''}, {name: 'use_a1_notation', description: ''}, {name: 'sheet', description: ''}], }, CHOOSE: { category: 'Lookup and reference', shortDescription: 'Uses an index to return a value from a list of values.', - parameters: [{name: 'Index', description: ''}, {name: 'Value1', description: ''}], + parameters: [{name: 'index', description: ''}, {name: 'value1', description: ''}], }, COLUMN: { category: 'Lookup and reference', shortDescription: 'Returns column number of a given reference or formula reference if argument not provided.', - parameters: [{name: 'Reference', description: ''}], + parameters: [{name: 'reference', description: ''}], }, COLUMNS: { category: 'Lookup and reference', shortDescription: 'Returns the number of columns in the given reference.', - parameters: [{name: 'Array', description: ''}], + parameters: [{name: 'array', description: ''}], }, FORMULATEXT: { category: 'Lookup and reference', shortDescription: 'Returns a formula in a given cell as a string.', - parameters: [{name: 'Reference', description: ''}], + parameters: [{name: 'reference', description: ''}], }, HLOOKUP: { category: 'Lookup and reference', shortDescription: 'Searches horizontally with reference to adjacent cells to the bottom.', - parameters: [{name: 'Search_Criterion', description: ''}, {name: 'Array', description: ''}, {name: 'Index', description: ''}, {name: 'Sort_Order', description: ''}], + parameters: [{name: 'search_criterion', description: ''}, {name: 'array', description: ''}, {name: 'index', description: ''}, {name: 'sort_order', description: ''}], }, HYPERLINK: { category: 'Lookup and reference', shortDescription: 'Stores the url in the cell\'s metadata. It can be read using method [`getCellHyperlink`](../api/classes/hyperformula.md#getcellhyperlink)', - parameters: [{name: 'Url', description: ''}, {name: 'LinkLabel', description: ''}], + parameters: [{name: 'url', description: ''}, {name: 'link_label', description: ''}], }, INDEX: { category: 'Lookup and reference', shortDescription: 'Returns the contents of a cell specified by row and column number. The column number is optional and defaults to 1.', - parameters: [{name: 'Range', description: ''}, {name: 'Row', description: ''}, {name: 'Column', description: ''}], + parameters: [{name: 'range', description: ''}, {name: 'row', description: ''}, {name: 'column', description: ''}], }, MATCH: { category: 'Lookup and reference', shortDescription: 'Returns the relative position of an item in an array that matches a specified value.', - parameters: [{name: 'Searchcriterion', description: ''}, {name: 'LookupArray', description: ''}, {name: 'MatchType', description: ''}], + parameters: [{name: 'search_criterion', description: ''}, {name: 'lookup_array', description: ''}, {name: 'match_type', description: ''}], }, ROW: { category: 'Lookup and reference', shortDescription: 'Returns row number of a given reference or formula reference if argument not provided.', - parameters: [{name: 'Reference', description: ''}], + parameters: [{name: 'reference', description: ''}], }, ROWS: { category: 'Lookup and reference', shortDescription: 'Returns the number of rows in the given reference.', - parameters: [{name: 'Array', description: ''}], + parameters: [{name: 'array', description: ''}], }, VLOOKUP: { category: 'Lookup and reference', shortDescription: 'Searches vertically with reference to adjacent cells to the right.', - parameters: [{name: 'Search_Criterion', description: ''}, {name: 'Array', description: ''}, {name: 'Index', description: ''}, {name: 'Sort_Order', description: ''}], + parameters: [{name: 'search_criterion', description: ''}, {name: 'array', description: ''}, {name: 'index', description: ''}, {name: 'sort_order', description: ''}], }, XLOOKUP: { category: 'Lookup and reference', shortDescription: 'Searches for a key in a range and returns the item corresponding to the match it finds. If no match exists, then XLOOKUP can return the closest (approximate) match.', - parameters: [{name: 'LookupValue', description: ''}, {name: 'LookupArray', description: ''}, {name: 'ReturnArray', description: ''}, {name: 'IfNotFound', description: ''}, {name: 'MatchMode', description: ''}, {name: 'SearchMode', description: ''}], + parameters: [{name: 'lookup_value', description: ''}, {name: 'lookup_array', description: ''}, {name: 'return_array', description: ''}, {name: 'if_not_found', description: ''}, {name: 'match_mode', description: ''}, {name: 'search_mode', description: ''}], }, } diff --git a/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts b/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts index 4ebb5f1fb..008202a50 100644 --- a/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts +++ b/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts @@ -13,217 +13,217 @@ export const MATH_AND_TRIGONOMETRY_DOCS: Record = { ABS: { category: 'Math and trigonometry', shortDescription: 'Returns the absolute value of a number.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, ACOS: { category: 'Math and trigonometry', shortDescription: 'Returns the inverse trigonometric cosine of a number.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, ACOSH: { category: 'Math and trigonometry', shortDescription: 'Returns the inverse hyperbolic cosine of a number.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, ACOT: { category: 'Math and trigonometry', shortDescription: 'Returns the inverse trigonometric cotangent of a number.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, ACOTH: { category: 'Math and trigonometry', shortDescription: 'Returns the inverse hyperbolic cotangent of a number.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, ARABIC: { category: 'Math and trigonometry', shortDescription: 'Converts number from roman form.', - parameters: [{name: 'String', description: ''}], + parameters: [{name: 'string', description: ''}], }, ASIN: { category: 'Math and trigonometry', shortDescription: 'Returns the inverse trigonometric sine of a number.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, ASINH: { category: 'Math and trigonometry', shortDescription: 'Returns the inverse hyperbolic sine of a number.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, ATAN: { category: 'Math and trigonometry', shortDescription: 'Returns the inverse trigonometric tangent of a number.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, ATAN2: { category: 'Math and trigonometry', shortDescription: 'Returns the inverse trigonometric tangent of the specified x and y coordinates.', - parameters: [{name: 'Numberx', description: ''}, {name: 'Numbery', description: ''}], + parameters: [{name: 'number_x', description: ''}, {name: 'number_y', description: ''}], }, ATANH: { category: 'Math and trigonometry', shortDescription: 'Returns the inverse hyperbolic tangent of a number.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, BASE: { category: 'Math and trigonometry', shortDescription: 'Converts a positive integer to a specified base into a text from the numbering system.', - parameters: [{name: 'Number', description: ''}, {name: 'Radix', description: ''}, {name: 'Minimumlength', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'radix', description: ''}, {name: 'minimum_length', description: ''}], }, CEILING: { category: 'Math and trigonometry', shortDescription: 'Rounds a number up to the nearest multiple of Significance.', - parameters: [{name: 'Number', description: ''}, {name: 'Significance', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'significance', description: ''}], }, 'CEILING.MATH': { category: 'Math and trigonometry', shortDescription: 'Rounds a number up to the nearest multiple of Significance.', - parameters: [{name: 'Number', description: ''}, {name: 'Significance', description: ''}, {name: 'Mode', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'significance', description: ''}, {name: 'mode', description: ''}], }, 'CEILING.PRECISE': { category: 'Math and trigonometry', shortDescription: 'Rounds a number up to the nearest multiple of Significance.', - parameters: [{name: 'Number', description: ''}, {name: 'Significance', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'significance', description: ''}], }, COMBIN: { category: 'Math and trigonometry', shortDescription: 'Returns number of combinations (without repetitions).', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], }, COMBINA: { category: 'Math and trigonometry', shortDescription: 'Returns number of combinations (with repetitions).', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], }, COS: { category: 'Math and trigonometry', shortDescription: 'Returns the cosine of the given angle (in radians).', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, COSH: { category: 'Math and trigonometry', shortDescription: 'Returns the hyperbolic cosine of the given value.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, COT: { category: 'Math and trigonometry', shortDescription: 'Returns the cotangent of the given angle (in radians).', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, COTH: { category: 'Math and trigonometry', shortDescription: 'Returns the hyperbolic cotangent of the given value.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, COUNTUNIQUE: { category: 'Math and trigonometry', shortDescription: 'Counts the number of unique values in a list of specified values and ranges.', - parameters: [{name: 'Value1', description: ''}], + parameters: [{name: 'value1', description: ''}], }, CSC: { category: 'Math and trigonometry', shortDescription: 'Returns the cosecant of the given angle (in radians).', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, CSCH: { category: 'Math and trigonometry', shortDescription: 'Returns the hyperbolic cosecant of the given value.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, DECIMAL: { category: 'Math and trigonometry', shortDescription: 'Converts text with characters from a number system to a positive integer in the base radix given.', - parameters: [{name: 'Text', description: ''}, {name: 'Radix', description: ''}], + parameters: [{name: 'text', description: ''}, {name: 'radix', description: ''}], }, DEGREES: { category: 'Math and trigonometry', shortDescription: 'Converts radians into degrees.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, EVEN: { category: 'Math and trigonometry', shortDescription: 'Rounds a positive number up to the next even integer and a negative number down to the next even integer.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, EXP: { category: 'Math and trigonometry', shortDescription: 'Returns constant e raised to the power of a number.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, FACT: { category: 'Math and trigonometry', shortDescription: 'Returns a factorial of a number.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, FACTDOUBLE: { category: 'Math and trigonometry', shortDescription: 'Returns a double factorial of a number.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, FLOOR: { category: 'Math and trigonometry', shortDescription: 'Rounds a number down to the nearest multiple of Significance.', - parameters: [{name: 'Number', description: ''}, {name: 'Significance', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'significance', description: ''}], }, 'FLOOR.MATH': { category: 'Math and trigonometry', shortDescription: 'Rounds a number down to the nearest multiple of Significance.', - parameters: [{name: 'Number', description: ''}, {name: 'Significance', description: ''}, {name: 'Mode', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'significance', description: ''}, {name: 'mode', description: ''}], }, 'FLOOR.PRECISE': { category: 'Math and trigonometry', shortDescription: 'Rounds a number down to the nearest multiple of Significance.', - parameters: [{name: 'Number', description: ''}, {name: 'Significance', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'significance', description: ''}], }, GCD: { category: 'Math and trigonometry', shortDescription: 'Computes greatest common divisor of numbers.', - parameters: [{name: 'Number1', description: ''}], + parameters: [{name: 'number1', description: ''}], }, INT: { category: 'Math and trigonometry', shortDescription: 'Rounds a number down to the nearest integer.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, LCM: { category: 'Math and trigonometry', shortDescription: 'Computes least common multiple of numbers.', - parameters: [{name: 'Number1', description: ''}], + parameters: [{name: 'number1', description: ''}], }, LN: { category: 'Math and trigonometry', shortDescription: 'Returns the natural logarithm based on the constant e of a number.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, LOG: { category: 'Math and trigonometry', shortDescription: 'Returns the logarithm of a number to the specified base.', - parameters: [{name: 'Number', description: ''}, {name: 'Base', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'base', description: ''}], }, LOG10: { category: 'Math and trigonometry', shortDescription: 'Returns the base-10 logarithm of a number.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, MOD: { category: 'Math and trigonometry', shortDescription: 'Returns the remainder when one integer is divided by another.', - parameters: [{name: 'Dividend', description: ''}, {name: 'Divisor', description: ''}], + parameters: [{name: 'dividend', description: ''}, {name: 'divisor', description: ''}], }, MROUND: { category: 'Math and trigonometry', shortDescription: 'Rounds number to the neares multiplicity.', - parameters: [{name: 'Number', description: ''}, {name: 'Base', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'base', description: ''}], }, MULTINOMIAL: { category: 'Math and trigonometry', shortDescription: 'Returns number of multiset combinations.', - parameters: [{name: 'Number1', description: ''}], + parameters: [{name: 'number1', description: ''}], }, ODD: { category: 'Math and trigonometry', shortDescription: 'Rounds a positive number up to the nearest odd integer and a negative number down to the nearest odd integer.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, PI: { category: 'Math and trigonometry', @@ -233,22 +233,22 @@ export const MATH_AND_TRIGONOMETRY_DOCS: Record = { POWER: { category: 'Math and trigonometry', shortDescription: 'Returns a number raised to another number.', - parameters: [{name: 'Base', description: ''}, {name: 'Exponent', description: ''}], + parameters: [{name: 'base', description: ''}, {name: 'exponent', description: ''}], }, PRODUCT: { category: 'Math and trigonometry', shortDescription: 'Returns product of numbers.', - parameters: [{name: 'Number1', description: ''}], + parameters: [{name: 'number1', description: ''}], }, QUOTIENT: { category: 'Math and trigonometry', shortDescription: 'Returns integer part of a division.', - parameters: [{name: 'Dividend', description: ''}, {name: 'Divisor', description: ''}], + parameters: [{name: 'dividend', description: ''}, {name: 'divisor', description: ''}], }, RADIANS: { category: 'Math and trigonometry', shortDescription: 'Converts degrees to radians.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, RAND: { category: 'Math and trigonometry', @@ -258,72 +258,72 @@ export const MATH_AND_TRIGONOMETRY_DOCS: Record = { RANDBETWEEN: { category: 'Math and trigonometry', shortDescription: 'Returns a random integer between two numbers.', - parameters: [{name: 'Lowerbound', description: ''}, {name: 'Upperbound', description: ''}], + parameters: [{name: 'lower_bound', description: ''}, {name: 'upper_bound', description: ''}], }, ROMAN: { category: 'Math and trigonometry', shortDescription: 'Converts number to roman form.', - parameters: [{name: 'Number', description: ''}, {name: 'Mode', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'mode', description: ''}], }, ROUND: { category: 'Math and trigonometry', shortDescription: 'Rounds a number to a certain number of decimal places.', - parameters: [{name: 'Number', description: ''}, {name: 'Count', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'count', description: ''}], }, ROUNDDOWN: { category: 'Math and trigonometry', shortDescription: 'Rounds a number down, toward zero, to a certain precision.', - parameters: [{name: 'Number', description: ''}, {name: 'Count', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'count', description: ''}], }, ROUNDUP: { category: 'Math and trigonometry', shortDescription: 'Rounds a number up, away from zero, to a certain precision.', - parameters: [{name: 'Number', description: ''}, {name: 'Count', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'count', description: ''}], }, SEC: { category: 'Math and trigonometry', shortDescription: 'Returns the secant of the given angle (in radians).', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, SECH: { category: 'Math and trigonometry', shortDescription: 'Returns the hyperbolic secant of the given angle (in radians).', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, SERIESSUM: { category: 'Math and trigonometry', shortDescription: 'Evaluates series at a point.', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Number3', description: ''}, {name: 'Coefficients', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'number3', description: ''}, {name: 'coefficients', description: ''}], }, SIGN: { category: 'Math and trigonometry', shortDescription: 'Returns sign of a number.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, SIN: { category: 'Math and trigonometry', shortDescription: 'Returns the sine of the given angle (in radians).', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, SINH: { category: 'Math and trigonometry', shortDescription: 'Returns the hyperbolic sine of the given value.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, SQRT: { category: 'Math and trigonometry', shortDescription: 'Returns the positive square root of a number.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, SQRTPI: { category: 'Math and trigonometry', shortDescription: 'Returns sqrt of number times pi.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, SUBTOTAL: { category: 'Math and trigonometry', shortDescription: 'Computes aggregation using function specified by number.', - parameters: [{name: 'Function', description: ''}, {name: 'Number1', description: ''}], + parameters: [{name: 'function', description: ''}, {name: 'number1', description: ''}], }, // HAND-AUTHORED reference functions (HF-249): SUM and SUMIF carry real parameter descriptions, examples and a // documentationUrl so the Formula Builder team can test rendering of populated metadata. The migration generator @@ -332,7 +332,7 @@ export const MATH_AND_TRIGONOMETRY_DOCS: Record = { SUM: { category: 'Math and trigonometry', shortDescription: 'Sums up the values of the specified cells.', - parameters: [{name: 'Number1', description: 'A number, cell reference, or range whose values are added together. Further numbers or ranges can be passed as additional arguments.'}], + parameters: [{name: 'number1', description: 'A number, cell reference, or range whose values are added together. Further numbers or ranges can be passed as additional arguments.'}], documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions', examples: ['=SUM(1, 2, 3)', '=SUM(A1:A10)', '=SUM(B1:B5, 100)'], }, @@ -340,9 +340,9 @@ export const MATH_AND_TRIGONOMETRY_DOCS: Record = { category: 'Math and trigonometry', shortDescription: 'Sums up the values of cells that belong to the specified range and meet the specified condition.', parameters: [ - {name: 'Range', description: 'The range of cells tested against the criterion.'}, - {name: 'Criteria', description: 'The condition that selects which cells are summed, e.g. ">5", "apples", or a cell reference.'}, - {name: 'Sumrange', description: 'The range of cells to sum. When omitted, the cells in Range are summed instead.'}, + {name: 'range', description: 'The range of cells tested against the criterion.'}, + {name: 'criteria', description: 'The condition that selects which cells are summed, e.g. ">5", "apples", or a cell reference.'}, + {name: 'sum_range', description: 'The range of cells to sum. When omitted, the cells in Range are summed instead.'}, ], documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions', examples: ['=SUMIF(A1:A10, ">5")', '=SUMIF(B1:B10, "apples", C1:C10)'], @@ -350,41 +350,41 @@ export const MATH_AND_TRIGONOMETRY_DOCS: Record = { SUMIFS: { category: 'Math and trigonometry', shortDescription: 'Sums up the values of cells that belong to the specified range and meet the specified sets of conditions.', - parameters: [{name: 'Sum_Range', description: ''}, {name: 'Criterion_range1', description: ''}, {name: 'Criterion1', description: ''}], + parameters: [{name: 'sum_range', description: ''}, {name: 'criterion_range1', description: ''}, {name: 'criterion1', description: ''}], }, SUMPRODUCT: { category: 'Math and trigonometry', shortDescription: 'Multiplies corresponding elements in the given arrays, and returns the sum of those products.', - parameters: [{name: 'Array1', description: ''}], + parameters: [{name: 'array1', description: ''}], }, SUMSQ: { category: 'Math and trigonometry', shortDescription: 'Returns the sum of the squares of the arguments', - parameters: [{name: 'Number1', description: ''}], + parameters: [{name: 'number1', description: ''}], }, SUMX2MY2: { category: 'Math and trigonometry', shortDescription: 'Returns the sum of the square differences.', - parameters: [{name: 'Range1', description: ''}, {name: 'Range2', description: ''}], + parameters: [{name: 'range1', description: ''}, {name: 'range2', description: ''}], }, SUMX2PY2: { category: 'Math and trigonometry', shortDescription: 'Returns the sum of the square sums.', - parameters: [{name: 'Range1', description: ''}, {name: 'Range2', description: ''}], + parameters: [{name: 'range1', description: ''}, {name: 'range2', description: ''}], }, SUMXMY2: { category: 'Math and trigonometry', shortDescription: 'Returns the sum of the square of differences.', - parameters: [{name: 'Range1', description: ''}, {name: 'Range2', description: ''}], + parameters: [{name: 'range1', description: ''}, {name: 'range2', description: ''}], }, TAN: { category: 'Math and trigonometry', shortDescription: 'Returns the tangent of the given angle (in radians).', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, TANH: { category: 'Math and trigonometry', shortDescription: 'Returns the hyperbolic tangent of the given value.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, } diff --git a/src/interpreter/functionMetadata/categories/matrix-functions.ts b/src/interpreter/functionMetadata/categories/matrix-functions.ts index 7efebad71..fc3f4ded3 100644 --- a/src/interpreter/functionMetadata/categories/matrix-functions.ts +++ b/src/interpreter/functionMetadata/categories/matrix-functions.ts @@ -13,21 +13,21 @@ export const MATRIX_FUNCTIONS_DOCS: Record = { MAXPOOL: { category: 'Matrix functions', shortDescription: 'Calculates a smaller range which is a maximum of a Window_size, in a given Range, for every Stride element.', - parameters: [{name: 'Range', description: ''}, {name: 'Window_size', description: ''}, {name: 'Stride', description: ''}], + parameters: [{name: 'range', description: ''}, {name: 'window_size', description: ''}, {name: 'stride', description: ''}], }, MEDIANPOOL: { category: 'Matrix functions', shortDescription: 'Calculates a smaller range which is a median of a Window_size, in a given Range, for every Stride element.', - parameters: [{name: 'Range', description: ''}, {name: 'Window_size', description: ''}, {name: 'Stride', description: ''}], + parameters: [{name: 'range', description: ''}, {name: 'window_size', description: ''}, {name: 'stride', description: ''}], }, MMULT: { category: 'Matrix functions', shortDescription: 'Calculates the array product of two arrays.', - parameters: [{name: 'Array1', description: ''}, {name: 'Array2', description: ''}], + parameters: [{name: 'array1', description: ''}, {name: 'array2', description: ''}], }, TRANSPOSE: { category: 'Matrix functions', shortDescription: 'Transposes the rows and columns of an array.', - parameters: [{name: 'Array', description: ''}], + parameters: [{name: 'array', description: ''}], }, } diff --git a/src/interpreter/functionMetadata/categories/operator.ts b/src/interpreter/functionMetadata/categories/operator.ts index 9305a5ebd..d7a7258b8 100644 --- a/src/interpreter/functionMetadata/categories/operator.ts +++ b/src/interpreter/functionMetadata/categories/operator.ts @@ -13,76 +13,76 @@ export const OPERATOR_DOCS: Record = { 'HF.ADD': { category: 'Operator', shortDescription: 'Adds two values.', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], }, 'HF.CONCAT': { category: 'Operator', shortDescription: 'Concatenates two strings.', - parameters: [{name: 'String1', description: ''}, {name: 'String2', description: ''}], + parameters: [{name: 'string1', description: ''}, {name: 'string2', description: ''}], }, 'HF.DIVIDE': { category: 'Operator', shortDescription: 'Divides two values.', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], }, 'HF.EQ': { category: 'Operator', shortDescription: 'Tests two values for equality.', - parameters: [{name: 'Value1', description: ''}, {name: 'Value2', description: ''}], + parameters: [{name: 'value1', description: ''}, {name: 'value2', description: ''}], }, 'HF.GT': { category: 'Operator', shortDescription: 'Tests two values for greater-than relation.', - parameters: [{name: 'Value1', description: ''}, {name: 'Value2', description: ''}], + parameters: [{name: 'value1', description: ''}, {name: 'value2', description: ''}], }, 'HF.GTE': { category: 'Operator', shortDescription: 'Tests two values for greater-equal relation.', - parameters: [{name: 'Value1', description: ''}, {name: 'Value2', description: ''}], + parameters: [{name: 'value1', description: ''}, {name: 'value2', description: ''}], }, 'HF.LT': { category: 'Operator', shortDescription: 'Tests two values for less-than relation.', - parameters: [{name: 'Value1', description: ''}, {name: 'Value2', description: ''}], + parameters: [{name: 'value1', description: ''}, {name: 'value2', description: ''}], }, 'HF.LTE': { category: 'Operator', shortDescription: 'Tests two values for less-equal relation.', - parameters: [{name: 'Value1', description: ''}, {name: 'Value2', description: ''}], + parameters: [{name: 'value1', description: ''}, {name: 'value2', description: ''}], }, 'HF.MINUS': { category: 'Operator', shortDescription: 'Subtracts two values.', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], }, 'HF.MULTIPLY': { category: 'Operator', shortDescription: 'Multiplies two values.', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], }, 'HF.NE': { category: 'Operator', shortDescription: 'Tests two values for inequality.', - parameters: [{name: 'Value1', description: ''}, {name: 'Value2', description: ''}], + parameters: [{name: 'value1', description: ''}, {name: 'value2', description: ''}], }, 'HF.POW': { category: 'Operator', shortDescription: 'Computes power of two values.', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], }, 'HF.UMINUS': { category: 'Operator', shortDescription: 'Negates the value.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, 'HF.UNARY_PERCENT': { category: 'Operator', shortDescription: 'Applies percent operator.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, 'HF.UPLUS': { category: 'Operator', shortDescription: 'Applies unary plus.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, } diff --git a/src/interpreter/functionMetadata/categories/statistical.ts b/src/interpreter/functionMetadata/categories/statistical.ts index 2e88fa8e3..9e9ce0f53 100644 --- a/src/interpreter/functionMetadata/categories/statistical.ts +++ b/src/interpreter/functionMetadata/categories/statistical.ts @@ -13,446 +13,446 @@ export const STATISTICAL_DOCS: Record = { AVEDEV: { category: 'Statistical', shortDescription: 'Returns the average deviation of the arguments.', - parameters: [{name: 'Number1', description: ''}], + parameters: [{name: 'number1', description: ''}], }, AVERAGE: { category: 'Statistical', shortDescription: 'Returns the average of the arguments.', - parameters: [{name: 'Number1', description: ''}], + parameters: [{name: 'number1', description: ''}], }, AVERAGEA: { category: 'Statistical', shortDescription: 'Returns the average of the arguments.', - parameters: [{name: 'Value1', description: ''}], + parameters: [{name: 'value1', description: ''}], }, AVERAGEIF: { category: 'Statistical', shortDescription: 'Returns the arithmetic mean of all cells in a range that satisfy a given condition.', - parameters: [{name: 'Range', description: ''}, {name: 'Criterion', description: ''}, {name: 'Average_Range', description: ''}], + parameters: [{name: 'range', description: ''}, {name: 'criterion', description: ''}, {name: 'average_range', description: ''}], }, BESSELI: { category: 'Statistical', shortDescription: 'Returns value of Bessel function.', - parameters: [{name: 'X', description: ''}, {name: 'N', description: ''}], + parameters: [{name: 'x', description: ''}, {name: 'n', description: ''}], }, BESSELJ: { category: 'Statistical', shortDescription: 'Returns value of Bessel function.', - parameters: [{name: 'X', description: ''}, {name: 'N', description: ''}], + parameters: [{name: 'x', description: ''}, {name: 'n', description: ''}], }, BESSELK: { category: 'Statistical', shortDescription: 'Returns value of Bessel function.', - parameters: [{name: 'X', description: ''}, {name: 'N', description: ''}], + parameters: [{name: 'x', description: ''}, {name: 'n', description: ''}], }, BESSELY: { category: 'Statistical', shortDescription: 'Returns value of Bessel function.', - parameters: [{name: 'X', description: ''}, {name: 'N', description: ''}], + parameters: [{name: 'x', description: ''}, {name: 'n', description: ''}], }, 'BETA.DIST': { category: 'Statistical', shortDescription: 'Returns the density of Beta distribution.', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Number3', description: ''}, {name: 'Boolean', description: ''}, {name: 'Number4', description: ''}, {name: 'Number5', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'number3', description: ''}, {name: 'boolean', description: ''}, {name: 'number4', description: ''}, {name: 'number5', description: ''}], }, 'BETA.INV': { category: 'Statistical', shortDescription: 'Returns the inverse Beta distribution value.', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Number3', description: ''}, {name: 'Number4', description: ''}, {name: 'Number5', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'number3', description: ''}, {name: 'number4', description: ''}, {name: 'number5', description: ''}], }, 'BINOM.DIST': { category: 'Statistical', shortDescription: 'Returns density of binomial distribution.', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Number3', description: ''}, {name: 'Boolean', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'number3', description: ''}, {name: 'boolean', description: ''}], }, 'BINOM.INV': { category: 'Statistical', shortDescription: 'Returns inverse binomial distribution value.', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Number3', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'number3', description: ''}], }, 'CHISQ.DIST': { category: 'Statistical', shortDescription: 'Returns value of chi-square distribution.', - parameters: [{name: 'X', description: ''}, {name: 'Degrees', description: ''}, {name: 'Mode', description: ''}], + parameters: [{name: 'x', description: ''}, {name: 'degrees', description: ''}, {name: 'mode', description: ''}], }, 'CHISQ.DIST.RT': { category: 'Statistical', shortDescription: 'Returns probability of chi-square right-side distribution.', - parameters: [{name: 'X', description: ''}, {name: 'Degrees', description: ''}], + parameters: [{name: 'x', description: ''}, {name: 'degrees', description: ''}], }, 'CHISQ.INV': { category: 'Statistical', shortDescription: 'Returns inverse of chi-square distribution.', - parameters: [{name: 'P', description: ''}, {name: 'Degrees', description: ''}], + parameters: [{name: 'p', description: ''}, {name: 'degrees', description: ''}], }, 'CHISQ.INV.RT': { category: 'Statistical', shortDescription: 'Returns inverse of chi-square right-side distribution.', - parameters: [{name: 'P', description: ''}, {name: 'Degrees', description: ''}], + parameters: [{name: 'p', description: ''}, {name: 'degrees', description: ''}], }, 'CHISQ.TEST': { category: 'Statistical', shortDescription: 'Returns chisquared-test value for a dataset.', - parameters: [{name: 'Array1', description: ''}, {name: 'Array2', description: ''}], + parameters: [{name: 'array1', description: ''}, {name: 'array2', description: ''}], }, 'CONFIDENCE.NORM': { category: 'Statistical', shortDescription: 'Returns upper confidence bound for normal distribution.', - parameters: [{name: 'Alpha', description: ''}, {name: 'Stdev', description: ''}, {name: 'Size', description: ''}], + parameters: [{name: 'alpha', description: ''}, {name: 'stdev', description: ''}, {name: 'size', description: ''}], }, 'CONFIDENCE.T': { category: 'Statistical', shortDescription: 'Returns upper confidence bound for T distribution.', - parameters: [{name: 'Alpha', description: ''}, {name: 'Stdev', description: ''}, {name: 'Size', description: ''}], + parameters: [{name: 'alpha', description: ''}, {name: 'stdev', description: ''}, {name: 'size', description: ''}], }, CORREL: { category: 'Statistical', shortDescription: 'Returns the correlation coefficient between two data sets.', - parameters: [{name: 'Data1', description: ''}, {name: 'Data2', description: ''}], + parameters: [{name: 'data1', description: ''}, {name: 'data2', description: ''}], }, COUNT: { category: 'Statistical', shortDescription: 'Counts how many numbers are in the list of arguments.', - parameters: [{name: 'Value1', description: ''}], + parameters: [{name: 'value1', description: ''}], }, COUNTA: { category: 'Statistical', shortDescription: 'Counts how many values are in the list of arguments.', - parameters: [{name: 'Value1', description: ''}], + parameters: [{name: 'value1', description: ''}], }, COUNTBLANK: { category: 'Statistical', shortDescription: 'Returns the number of empty cells.', - parameters: [{name: 'Range', description: ''}], + parameters: [{name: 'range', description: ''}], }, COUNTIF: { category: 'Statistical', shortDescription: 'Returns the number of cells that meet with certain criteria within a cell range.', - parameters: [{name: 'Range', description: ''}, {name: 'Criteria', description: ''}], + parameters: [{name: 'range', description: ''}, {name: 'criteria', description: ''}], }, COUNTIFS: { category: 'Statistical', shortDescription: 'Returns the count of rows or columns that meet criteria in multiple ranges.', - parameters: [{name: 'Range1', description: ''}, {name: 'Criterion1', description: ''}], + parameters: [{name: 'range1', description: ''}, {name: 'criterion1', description: ''}], }, 'COVARIANCE.P': { category: 'Statistical', shortDescription: 'Returns the covariance between two data sets, population normalized.', - parameters: [{name: 'Data1', description: ''}, {name: 'Data2', description: ''}], + parameters: [{name: 'data1', description: ''}, {name: 'data2', description: ''}], }, 'COVARIANCE.S': { category: 'Statistical', shortDescription: 'Returns the covariance between two data sets, sample normalized.', - parameters: [{name: 'Data1', description: ''}, {name: 'Data2', description: ''}], + parameters: [{name: 'data1', description: ''}, {name: 'data2', description: ''}], }, DEVSQ: { category: 'Statistical', shortDescription: 'Returns sum of squared deviations.', - parameters: [{name: 'Number1', description: ''}], + parameters: [{name: 'number1', description: ''}], }, 'EXPON.DIST': { category: 'Statistical', shortDescription: 'Returns density of a exponential distribution.', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Boolean', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'boolean', description: ''}], }, 'F.DIST': { category: 'Statistical', shortDescription: 'Returns value of F distribution.', - parameters: [{name: 'X', description: ''}, {name: 'Degree1', description: ''}, {name: 'Degree2', description: ''}, {name: 'Mode', description: ''}], + parameters: [{name: 'x', description: ''}, {name: 'degree1', description: ''}, {name: 'degree2', description: ''}, {name: 'mode', description: ''}], }, 'F.DIST.RT': { category: 'Statistical', shortDescription: 'Returns probability of F right-side distribution.', - parameters: [{name: 'X', description: ''}, {name: 'Degree1', description: ''}, {name: 'Degree2', description: ''}], + parameters: [{name: 'x', description: ''}, {name: 'degree1', description: ''}, {name: 'degree2', description: ''}], }, 'F.INV': { category: 'Statistical', shortDescription: 'Returns inverse of F distribution.', - parameters: [{name: 'P', description: ''}, {name: 'Degree1', description: ''}, {name: 'Degree2', description: ''}], + parameters: [{name: 'p', description: ''}, {name: 'degree1', description: ''}, {name: 'degree2', description: ''}], }, 'F.INV.RT': { category: 'Statistical', shortDescription: 'Returns inverse of F right-side distribution.', - parameters: [{name: 'P', description: ''}, {name: 'Degree1', description: ''}, {name: 'Degree2', description: ''}], + parameters: [{name: 'p', description: ''}, {name: 'degree1', description: ''}, {name: 'degree2', description: ''}], }, 'F.TEST': { category: 'Statistical', shortDescription: 'Returns f-test value for a dataset.', - parameters: [{name: 'Array1', description: ''}, {name: 'Array2', description: ''}], + parameters: [{name: 'array1', description: ''}, {name: 'array2', description: ''}], }, FISHER: { category: 'Statistical', shortDescription: 'Returns Fisher transformation value.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, FISHERINV: { category: 'Statistical', shortDescription: 'Returns inverse Fischer transformation value.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, GAMMA: { category: 'Statistical', shortDescription: 'Returns value of Gamma function.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, 'GAMMA.DIST': { category: 'Statistical', shortDescription: 'Returns density of Gamma distribution.', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Number3', description: ''}, {name: 'Boolean', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'number3', description: ''}, {name: 'boolean', description: ''}], }, 'GAMMA.INV': { category: 'Statistical', shortDescription: 'Returns inverse Gamma distribution value.', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Number3', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'number3', description: ''}], }, GAMMALN: { category: 'Statistical', shortDescription: 'Returns natural logarithm of Gamma function.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, GAUSS: { category: 'Statistical', shortDescription: 'Returns the probability of gaussian variable falling more than this many times standard deviation from mean.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, GEOMEAN: { category: 'Statistical', shortDescription: 'Returns the geometric average.', - parameters: [{name: 'Number1', description: ''}], + parameters: [{name: 'number1', description: ''}], }, HARMEAN: { category: 'Statistical', shortDescription: 'Returns the harmonic average.', - parameters: [{name: 'Number1', description: ''}], + parameters: [{name: 'number1', description: ''}], }, 'HYPGEOM.DIST': { category: 'Statistical', shortDescription: 'Returns density of hypergeometric distribution.', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Number3', description: ''}, {name: 'Number4', description: ''}, {name: 'Boolean', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'number3', description: ''}, {name: 'number4', description: ''}, {name: 'boolean', description: ''}], }, LARGE: { category: 'Statistical', shortDescription: 'Returns k-th largest value in a range.', - parameters: [{name: 'Range', description: ''}, {name: 'K', description: ''}], + parameters: [{name: 'range', description: ''}, {name: 'k', description: ''}], }, 'LOGNORM.DIST': { category: 'Statistical', shortDescription: 'Returns density of lognormal distribution.', - parameters: [{name: 'X', description: ''}, {name: 'Mean', description: ''}, {name: 'Stddev', description: ''}, {name: 'Mode', description: ''}], + parameters: [{name: 'x', description: ''}, {name: 'mean', description: ''}, {name: 'stddev', description: ''}, {name: 'mode', description: ''}], }, 'LOGNORM.INV': { category: 'Statistical', shortDescription: 'Returns value of inverse lognormal distribution.', - parameters: [{name: 'P', description: ''}, {name: 'Mean', description: ''}, {name: 'Stddev', description: ''}], + parameters: [{name: 'p', description: ''}, {name: 'mean', description: ''}, {name: 'stddev', description: ''}], }, MAX: { category: 'Statistical', shortDescription: 'Returns the maximum value in a list of arguments.', - parameters: [{name: 'Number1', description: ''}], + parameters: [{name: 'number1', description: ''}], }, MAXA: { category: 'Statistical', shortDescription: 'Returns the maximum value in a list of arguments.', - parameters: [{name: 'Value1', description: ''}], + parameters: [{name: 'value1', description: ''}], }, MAXIFS: { category: 'Statistical', shortDescription: 'Returns the maximum value of the cells in a range that meet a set of criteria.', - parameters: [{name: 'Max_Range', description: ''}, {name: 'Criterion_range1', description: ''}, {name: 'Criterion1', description: ''}], + parameters: [{name: 'max_range', description: ''}, {name: 'criterion_range1', description: ''}, {name: 'criterion1', description: ''}], }, MEDIAN: { category: 'Statistical', shortDescription: 'Returns the median of a set of numbers.', - parameters: [{name: 'Number1', description: ''}], + parameters: [{name: 'number1', description: ''}], }, MIN: { category: 'Statistical', shortDescription: 'Returns the minimum value in a list of arguments.', - parameters: [{name: 'Number1', description: ''}], + parameters: [{name: 'number1', description: ''}], }, MINA: { category: 'Statistical', shortDescription: 'Returns the minimum value in a list of arguments.', - parameters: [{name: 'Value1', description: ''}], + parameters: [{name: 'value1', description: ''}], }, MINIFS: { category: 'Statistical', shortDescription: 'Returns the minimum value of the cells in a range that meet a set of criteria.', - parameters: [{name: 'Min_Range', description: ''}, {name: 'Criterion_range1', description: ''}, {name: 'Criterion1', description: ''}], + parameters: [{name: 'min_range', description: ''}, {name: 'criterion_range1', description: ''}, {name: 'criterion1', description: ''}], }, 'NEGBINOM.DIST': { category: 'Statistical', shortDescription: 'Returns density of negative binomial distribution.', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Number3', description: ''}, {name: 'Mode', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'number3', description: ''}, {name: 'mode', description: ''}], }, 'NORM.DIST': { category: 'Statistical', shortDescription: 'Returns density of normal distribution.', - parameters: [{name: 'X', description: ''}, {name: 'Mean', description: ''}, {name: 'Stddev', description: ''}, {name: 'Mode', description: ''}], + parameters: [{name: 'x', description: ''}, {name: 'mean', description: ''}, {name: 'stddev', description: ''}, {name: 'mode', description: ''}], }, 'NORM.INV': { category: 'Statistical', shortDescription: 'Returns value of inverse normal distribution.', - parameters: [{name: 'P', description: ''}, {name: 'Mean', description: ''}, {name: 'Stddev', description: ''}], + parameters: [{name: 'p', description: ''}, {name: 'mean', description: ''}, {name: 'stddev', description: ''}], }, 'NORM.S.DIST': { category: 'Statistical', shortDescription: 'Returns density of normal distribution.', - parameters: [{name: 'X', description: ''}, {name: 'Mode', description: ''}], + parameters: [{name: 'x', description: ''}, {name: 'mode', description: ''}], }, 'NORM.S.INV': { category: 'Statistical', shortDescription: 'Returns value of inverse normal distribution.', - parameters: [{name: 'P', description: ''}], + parameters: [{name: 'p', description: ''}], }, 'PERCENTILE.EXC': { category: 'Statistical', shortDescription: 'Returns the k-th percentile of values in a range, exclusive of 0 and 1.', - parameters: [{name: 'Data', description: ''}, {name: 'K', description: ''}], + parameters: [{name: 'data', description: ''}, {name: 'k', description: ''}], }, 'PERCENTILE.INC': { category: 'Statistical', shortDescription: 'Returns the k-th percentile of values in a range, inclusive of 0 and 1.', - parameters: [{name: 'Data', description: ''}, {name: 'K', description: ''}], + parameters: [{name: 'data', description: ''}, {name: 'k', description: ''}], }, PHI: { category: 'Statistical', shortDescription: 'Returns probability densitity of normal distribution.', - parameters: [{name: 'X', description: ''}], + parameters: [{name: 'x', description: ''}], }, 'POISSON.DIST': { category: 'Statistical', shortDescription: 'Returns density of Poisson distribution.', - parameters: [{name: 'X', description: ''}, {name: 'Mean', description: ''}, {name: 'Mode', description: ''}], + parameters: [{name: 'x', description: ''}, {name: 'mean', description: ''}, {name: 'mode', description: ''}], }, 'QUARTILE.EXC': { category: 'Statistical', shortDescription: 'Returns the quartile of a data set, based on exclusive percentile values.', - parameters: [{name: 'Data', description: ''}, {name: 'Quart', description: ''}], + parameters: [{name: 'data', description: ''}, {name: 'quart', description: ''}], }, 'QUARTILE.INC': { category: 'Statistical', shortDescription: 'Returns the quartile of a data set, based on inclusive percentile values.', - parameters: [{name: 'Data', description: ''}, {name: 'Quart', description: ''}], + parameters: [{name: 'data', description: ''}, {name: 'quart', description: ''}], }, RSQ: { category: 'Statistical', shortDescription: 'Returns the squared correlation coefficient between two data sets.', - parameters: [{name: 'Data1', description: ''}, {name: 'Data2', description: ''}], + parameters: [{name: 'data1', description: ''}, {name: 'data2', description: ''}], }, SKEW: { category: 'Statistical', shortDescription: 'Returns skeweness of a sample.', - parameters: [{name: 'Number1', description: ''}], + parameters: [{name: 'number1', description: ''}], }, 'SKEW.P': { category: 'Statistical', shortDescription: 'Returns skeweness of a population.', - parameters: [{name: 'Number1', description: ''}], + parameters: [{name: 'number1', description: ''}], }, SLOPE: { category: 'Statistical', shortDescription: 'Returns the slope of a linear regression line.', - parameters: [{name: 'Array1', description: ''}, {name: 'Array2', description: ''}], + parameters: [{name: 'array1', description: ''}, {name: 'array2', description: ''}], }, SMALL: { category: 'Statistical', shortDescription: 'Returns k-th smallest value in a range.', - parameters: [{name: 'Range', description: ''}, {name: 'K', description: ''}], + parameters: [{name: 'range', description: ''}, {name: 'k', description: ''}], }, STANDARDIZE: { category: 'Statistical', shortDescription: 'Returns normalized value wrt expected value and standard deviation.', - parameters: [{name: 'X', description: ''}, {name: 'Mean', description: ''}, {name: 'Stddev', description: ''}], + parameters: [{name: 'x', description: ''}, {name: 'mean', description: ''}, {name: 'stddev', description: ''}], }, 'STDEV.P': { category: 'Statistical', shortDescription: 'Returns standard deviation of a population.', - parameters: [{name: 'Value1', description: ''}], + parameters: [{name: 'value1', description: ''}], }, 'STDEV.S': { category: 'Statistical', shortDescription: 'Returns standard deviation of a sample.', - parameters: [{name: 'Value1', description: ''}], + parameters: [{name: 'value1', description: ''}], }, STDEVA: { category: 'Statistical', shortDescription: 'Returns standard deviation of a sample.', - parameters: [{name: 'Value1', description: ''}], + parameters: [{name: 'value1', description: ''}], }, STDEVPA: { category: 'Statistical', shortDescription: 'Returns standard deviation of a population.', - parameters: [{name: 'Value1', description: ''}], + parameters: [{name: 'value1', description: ''}], }, STEYX: { category: 'Statistical', shortDescription: 'Returns standard error for predicted of the predicted y value for each x value.', - parameters: [{name: 'Array1', description: ''}, {name: 'Array2', description: ''}], + parameters: [{name: 'array1', description: ''}, {name: 'array2', description: ''}], }, 'T.DIST': { category: 'Statistical', shortDescription: 'Returns density of Student-t distribution.', - parameters: [{name: 'X', description: ''}, {name: 'Degrees', description: ''}, {name: 'Mode', description: ''}], + parameters: [{name: 'x', description: ''}, {name: 'degrees', description: ''}, {name: 'mode', description: ''}], }, 'T.DIST.2T': { category: 'Statistical', shortDescription: 'Returns density of Student-t distribution, both-sided.', - parameters: [{name: 'X', description: ''}, {name: 'Degrees', description: ''}], + parameters: [{name: 'x', description: ''}, {name: 'degrees', description: ''}], }, 'T.DIST.RT': { category: 'Statistical', shortDescription: 'Returns density of Student-t distribution, right-tailed.', - parameters: [{name: 'X', description: ''}, {name: 'Degrees', description: ''}], + parameters: [{name: 'x', description: ''}, {name: 'degrees', description: ''}], }, 'T.INV': { category: 'Statistical', shortDescription: 'Returns inverse Student-t distribution.', - parameters: [{name: 'P', description: ''}, {name: 'Degrees', description: ''}], + parameters: [{name: 'p', description: ''}, {name: 'degrees', description: ''}], }, 'T.INV.2T': { category: 'Statistical', shortDescription: 'Returns inverse Student-t distribution, both-sided.', - parameters: [{name: 'P', description: ''}, {name: 'Degrees', description: ''}], + parameters: [{name: 'p', description: ''}, {name: 'degrees', description: ''}], }, 'T.TEST': { category: 'Statistical', shortDescription: 'Returns t-test value for a dataset.', - parameters: [{name: 'Array1', description: ''}, {name: 'Array2', description: ''}, {name: 'Tails', description: ''}, {name: 'Type', description: ''}], + parameters: [{name: 'array1', description: ''}, {name: 'array2', description: ''}, {name: 'tails', description: ''}, {name: 'type', description: ''}], }, TDIST: { category: 'Statistical', shortDescription: 'Returns density of Student-t distribution, both-sided or right-tailed.', - parameters: [{name: 'X', description: ''}, {name: 'Degrees', description: ''}, {name: 'Mode', description: ''}], + parameters: [{name: 'x', description: ''}, {name: 'degrees', description: ''}, {name: 'mode', description: ''}], }, 'VAR.P': { category: 'Statistical', shortDescription: 'Returns variance of a population.', - parameters: [{name: 'Value1', description: ''}], + parameters: [{name: 'value1', description: ''}], }, 'VAR.S': { category: 'Statistical', shortDescription: 'Returns variance of a sample.', - parameters: [{name: 'Value1', description: ''}], + parameters: [{name: 'value1', description: ''}], }, VARA: { category: 'Statistical', shortDescription: 'Returns variance of a sample.', - parameters: [{name: 'Value1', description: ''}], + parameters: [{name: 'value1', description: ''}], }, VARPA: { category: 'Statistical', shortDescription: 'Returns variance of a population.', - parameters: [{name: 'Value1', description: ''}], + parameters: [{name: 'value1', description: ''}], }, 'WEIBULL.DIST': { category: 'Statistical', shortDescription: 'Returns density of Weibull distribution.', - parameters: [{name: 'Number1', description: ''}, {name: 'Number2', description: ''}, {name: 'Number3', description: ''}, {name: 'Boolean', description: ''}], + parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'number3', description: ''}, {name: 'boolean', description: ''}], }, 'Z.TEST': { category: 'Statistical', shortDescription: 'Returns z-test value for a dataset.', - parameters: [{name: 'Array', description: ''}, {name: 'X', description: ''}, {name: 'Sigma', description: ''}], + parameters: [{name: 'array', description: ''}, {name: 'x', description: ''}, {name: 'sigma', description: ''}], }, } diff --git a/src/interpreter/functionMetadata/categories/text.ts b/src/interpreter/functionMetadata/categories/text.ts index 5b19fe850..c669cb14e 100644 --- a/src/interpreter/functionMetadata/categories/text.ts +++ b/src/interpreter/functionMetadata/categories/text.ts @@ -13,131 +13,131 @@ export const TEXT_DOCS: Record = { CHAR: { category: 'Text', shortDescription: 'Converts a number into a character according to the current code table.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, CLEAN: { category: 'Text', shortDescription: 'Returns text that has been "cleaned" of line breaks and other non-printable characters.', - parameters: [{name: 'Text', description: ''}], + parameters: [{name: 'text', description: ''}], }, CODE: { category: 'Text', shortDescription: 'Returns a numeric code for the first character in a text string.', - parameters: [{name: 'Text', description: ''}], + parameters: [{name: 'text', description: ''}], }, CONCATENATE: { category: 'Text', shortDescription: 'Combines several text strings into one string.', - parameters: [{name: 'Text1', description: ''}], + parameters: [{name: 'text1', description: ''}], }, EXACT: { category: 'Text', shortDescription: 'Returns TRUE if both text strings are exactly the same.', - parameters: [{name: 'Text1', description: ''}, {name: 'Text2', description: ''}], + parameters: [{name: 'text1', description: ''}, {name: 'text2', description: ''}], }, FIND: { category: 'Text', shortDescription: 'Returns the location of one text string inside another.', - parameters: [{name: 'Text1', description: ''}, {name: 'Text2', description: ''}, {name: 'Number', description: ''}], + parameters: [{name: 'text1', description: ''}, {name: 'text2', description: ''}, {name: 'number', description: ''}], }, LEFT: { category: 'Text', shortDescription: 'Extracts a given number of characters from the left side of a text string.', - parameters: [{name: 'Text', description: ''}, {name: 'Number', description: ''}], + parameters: [{name: 'text', description: ''}, {name: 'number', description: ''}], }, LEN: { category: 'Text', shortDescription: 'Returns length of a given text.', - parameters: [{name: 'Text', description: ''}], + parameters: [{name: 'text', description: ''}], }, LOWER: { category: 'Text', shortDescription: 'Returns text converted to lowercase.', - parameters: [{name: 'Text', description: ''}], + parameters: [{name: 'text', description: ''}], }, MID: { category: 'Text', shortDescription: 'Returns substring of a given length starting from Start_position.', - parameters: [{name: 'Text', description: ''}, {name: 'Start_position', description: ''}, {name: 'Length', description: ''}], + parameters: [{name: 'text', description: ''}, {name: 'start_position', description: ''}, {name: 'length', description: ''}], }, N: { category: 'Text', shortDescription: 'Converts a value to a number.', - parameters: [{name: 'Value', description: ''}], + parameters: [{name: 'value', description: ''}], }, PROPER: { category: 'Text', shortDescription: 'Capitalizes words given text string.', - parameters: [{name: 'Text', description: ''}], + parameters: [{name: 'text', description: ''}], }, REPLACE: { category: 'Text', shortDescription: 'Replaces substring of a text of a given length that starts at given position.', - parameters: [{name: 'Text', description: ''}, {name: 'Start_position', description: ''}, {name: 'Length', description: ''}, {name: 'New_text', description: ''}], + parameters: [{name: 'text', description: ''}, {name: 'start_position', description: ''}, {name: 'length', description: ''}, {name: 'new_text', description: ''}], }, REPT: { category: 'Text', shortDescription: 'Repeats text a given number of times.', - parameters: [{name: 'Text', description: ''}, {name: 'Number', description: ''}], + parameters: [{name: 'text', description: ''}, {name: 'number', description: ''}], }, RIGHT: { category: 'Text', shortDescription: 'Extracts a given number of characters from the right side of a text string.', - parameters: [{name: 'Text', description: ''}, {name: 'Number', description: ''}], + parameters: [{name: 'text', description: ''}, {name: 'number', description: ''}], }, SEARCH: { category: 'Text', shortDescription: 'Returns the location of Search_string inside Text. Case-insensitive. Allows the use of wildcards.', - parameters: [{name: 'Search_string', description: ''}, {name: 'Text', description: ''}, {name: 'Start_position', description: ''}], + parameters: [{name: 'search_string', description: ''}, {name: 'text', description: ''}, {name: 'start_position', description: ''}], }, SPLIT: { category: 'Text', shortDescription: 'Divides the provided text using the space character as a separator and returns the substring at the zero-based position specified by the second argument.
`SPLIT("Lorem ipsum", 0) -> "Lorem"`
`SPLIT("Lorem ipsum", 1) -> "ipsum"`', - parameters: [{name: 'Text', description: ''}, {name: 'Index', description: ''}], + parameters: [{name: 'text', description: ''}, {name: 'index', description: ''}], }, SUBSTITUTE: { category: 'Text', shortDescription: 'Returns string where occurrences of Old_text are replaced by New_text. Replaces only specific occurrence if last parameter is provided.', - parameters: [{name: 'Text', description: ''}, {name: 'Old_text', description: ''}, {name: 'New_text', description: ''}, {name: 'Occurrence', description: ''}], + parameters: [{name: 'text', description: ''}, {name: 'old_text', description: ''}, {name: 'new_text', description: ''}, {name: 'occurrence', description: ''}], }, T: { category: 'Text', shortDescription: 'Returns text if given value is text, empty string otherwise.', - parameters: [{name: 'Value', description: ''}], + parameters: [{name: 'value', description: ''}], }, TEXT: { category: 'Text', shortDescription: 'Converts a number into text according to a given format.
By default, accepts the same formats that can be passed to the [`dateFormats`](../api/interfaces/configparams.md#dateformats) option, but can be further customized with the [`stringifyDateTime`](../api/interfaces/configparams.md#stringifydatetime) option.', - parameters: [{name: 'Number', description: ''}, {name: 'Format', description: ''}], + parameters: [{name: 'number', description: ''}, {name: 'format', description: ''}], }, TEXTJOIN: { category: 'Text', shortDescription: 'Joins text from multiple strings and/or ranges with a delimiter. Supports array/range delimiters that cycle through gaps. When ignore_empty is TRUE, empty strings are skipped. Returns #VALUE! if result exceeds 32,767 characters.', - parameters: [{name: 'Delimiter', description: ''}, {name: 'Ignore_empty', description: ''}, {name: 'Text1', description: ''}], + parameters: [{name: 'delimiter', description: ''}, {name: 'ignore_empty', description: ''}, {name: 'text1', description: ''}], }, TRIM: { category: 'Text', shortDescription: 'Strips extra spaces from text.', - parameters: [{name: 'Text', description: ''}], + parameters: [{name: 'text', description: ''}], }, UNICHAR: { category: 'Text', shortDescription: 'Returns the character created by using provided code point.', - parameters: [{name: 'Number', description: ''}], + parameters: [{name: 'number', description: ''}], }, UNICODE: { category: 'Text', shortDescription: 'Returns the Unicode code point of a first character of a text.', - parameters: [{name: 'Text', description: ''}], + parameters: [{name: 'text', description: ''}], }, UPPER: { category: 'Text', shortDescription: 'Returns text converted to uppercase.', - parameters: [{name: 'Text', description: ''}], + parameters: [{name: 'text', description: ''}], }, VALUE: { category: 'Text', shortDescription: 'Parses a number, date, time, datetime, currency, or percentage from a text string.', - parameters: [{name: 'Text', description: ''}], + parameters: [{name: 'text', description: ''}], }, } From 2d9196e1d98c19fd78001b01735717cf6d19eb49 Mon Sep 17 00:00:00 2001 From: Kuba Sekowski Date: Tue, 14 Jul 2026 15:37:14 +0200 Subject: [PATCH 30/35] fix(metadata): guard getAvailableFunctions against invalid locale codes (HF-249) (#1710) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Context Addresses a code-review finding on #1692: `getAvailableFunctions` can throw a `RangeError` for a caller-registered, malformed language code. `buildAvailableFunctions` built its sort collator with `new Intl.Collator(toBcp47Locale(code))`. `toBcp47Locale` only hyphenates the canonical `` shape and passes any other string through unchanged, and `registerLanguage` performs **no** shape validation on the code. `Intl.Collator` throws a `RangeError` on a *structurally invalid* language tag (it does **not** silently fall back to the default locale). So a caller who registers an underscore-style code such as `'pt_BR'` (or `'en_US'`, `'x'`, `'12'`) and then calls `getAvailableFunctions` (static **or** instance) crashes. Built-in language codes are all safe, so this only affects consumer-registered malformed codes → important, not critical. The `toBcp47Locale` JSDoc was also wrong: it claimed unrecognized tags "fall back to the default locale," which `Intl.Collator` does not do for invalid tags. ### Fix - Extract `createLocaleCollator(languageCode)` which wraps the `Intl.Collator` construction in a `try/catch` and falls back to the environment-default collator (`new Intl.Collator()`) on `RangeError`, so listing functions never crashes on a non-BCP-47 code. - Use it in `buildAvailableFunctions`. - Correct the `toBcp47Locale` JSDoc to describe the real behavior (invalid tags throw; the throw is handled by `createLocaleCollator`). `getFunctionDetails` is unaffected — it does not sort and never constructs a collator. ### How did you test your changes? - Reproduced the crash before the fix: registering `'pt_BR'` then calling `getAvailableFunctions('pt_BR')` threw `RangeError: Incorrect locale information provided`. - After the fix, `'pt_BR'`, `'en_US'`, `'x'`, and `'12'` each return the full, alphabetically-sorted 419-entry list; well-formed `'enGB'` is unchanged. - Confirmed via Node that `new Intl.Collator('pt_BR'|'en_US'|'x'|'12')` throw while `'zz-ZZ'`/`'qqq'` do not. - `tsc --noEmit` clean; `eslint src/HyperFormula.ts` 0 errors; `test/smoke.spec.ts` 4/4. ### Types of changes - [ ] Breaking change (a fix or a feature because of which an existing functionality doesn't work as expected anymore) - [ ] New feature or improvement (a non-breaking change that adds functionality) - [x] Bug fix (a non-breaking change that fixes an issue) - [ ] Additional language file, or a change to an existing language file (translations) - [ ] Change to the documentation ### Related issues: 1. Follow-up to #1692 (HF-249); targets that branch. ### Notes for reviewers - Behavior on a malformed code is now "sort using the default collator" rather than throwing. The alternative (validating codes in `registerLanguage`) would be a broader, potentially breaking change, so it's intentionally out of scope here. - A unit test for this belongs in the paired private suite (`hyperformula-tests`): register a `'pt_BR'`-style code and assert `getAvailableFunctions` returns a sorted list instead of throwing.
Open in Web Open in Cursor 
Co-authored-by: Cursor Agent Co-authored-by: Kuba Sekowski --- src/HyperFormula.ts | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/HyperFormula.ts b/src/HyperFormula.ts index 87a5f1026..7a3c1b043 100644 --- a/src/HyperFormula.ts +++ b/src/HyperFormula.ts @@ -760,8 +760,9 @@ export class HyperFormula implements TypedEmitter { /** * Converts a HyperFormula language code (e.g. `'enGB'`, `'plPL'`) to a BCP-47 locale (e.g. `'en-GB'`, `'pl-PL'`) * so the function list collator is deterministic across hosts. Codes in the canonical `` shape get a - * hyphen inserted; any other shape is passed through and left for `Intl.Collator` to interpret (it falls back to - * the default locale for an unrecognized tag, which is still applied consistently within a single call). + * hyphen inserted; any other shape is passed through unchanged. A structurally valid but unknown tag is accepted + * by `Intl.Collator`, but a structurally invalid tag (e.g. an underscore-style `'pt_BR'`) makes `Intl.Collator` + * throw a `RangeError`; that case is handled by [[createLocaleCollator]], not here. * * @param {string} languageCode - the HyperFormula language code */ @@ -770,6 +771,23 @@ export class HyperFormula implements TypedEmitter { return match !== null ? `${match[1]}-${match[2]}` : languageCode } + /** + * Builds a collator for the given HyperFormula language code, using the BCP-47 form of the code so ordering is + * deterministic across hosts. `registerLanguage` does not constrain the shape of a language code, so a caller may + * register a structurally invalid one (e.g. an underscore-style `'pt_BR'`); such a tag makes `Intl.Collator` + * throw a `RangeError`, so we fall back to the environment default collator to keep the function list from + * crashing on a caller-registered, non-BCP-47 code. + * + * @param {string} languageCode - the HyperFormula language code + */ + private static createLocaleCollator(languageCode: string): Intl.Collator { + try { + return new Intl.Collator(HyperFormula.toBcp47Locale(languageCode)) + } catch (e) { + return new Intl.Collator() + } + } + /** * Builds the function list for a set of registered ids. Documented functions use their catalogue entry; custom * functions are listed with their name only. Sorted by localized name under an explicit, language-derived collator @@ -778,7 +796,7 @@ export class HyperFormula implements TypedEmitter { */ private static buildAvailableFunctions(functionIds: string[], getPlugin: (id: string) => FunctionPluginDefinition | undefined, language: TranslationPackage, languageCode: string): FunctionListEntry[] { const translate = (id: string) => language.getMaybeFunctionTranslation(id) - const collator = new Intl.Collator(HyperFormula.toBcp47Locale(languageCode)) + const collator = HyperFormula.createLocaleCollator(languageCode) return functionIds .map(id => { const resolved = HyperFormula.resolveFunctionMetadata(id, getPlugin(id)) From 40b64683ece825ea9554f207992b55fef3d3cbbd Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Wed, 15 Jul 2026 10:37:02 +0000 Subject: [PATCH 31/35] fix(metadata): correct migrated shortDescriptions (HF-249) A traceability audit (run during HF-300) found migrated shortDescriptions that either misstate behavior or leak markup into the plain-text metadata API. Per Kuba's call (Slack #hyperformula-dev, 2026-07-15) they belong on the parent HF-249 branch, since the catalogue is becoming the single source of truth (docs/guide generated from it at build): - XNPV: was verbatim identical to NPV; now conveys its non-periodic/date-based nature. - MIRR: "modified internal value" -> "modified internal rate of return". - SPLIT/TEXT: dropped
+ markdown (rendered literally through the API); TEXT now also mentions the stringifyCurrency option. - SECH: "given angle (in radians)" -> "given value" (the argument is a plain number). - BASE: "positive integer" -> "non-negative integer" (0 is accepted by the impl). - typos: MROUND "neares"/"multiplicity", Fischer->Fisher, densitity->density, skeweness->skewness (x2). Catalogue-only; docs/guide regenerates from these once #1699 lands. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/interpreter/functionMetadata/categories/financial.ts | 4 ++-- .../functionMetadata/categories/math-and-trigonometry.ts | 6 +++--- .../functionMetadata/categories/statistical.ts | 8 ++++---- src/interpreter/functionMetadata/categories/text.ts | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/interpreter/functionMetadata/categories/financial.ts b/src/interpreter/functionMetadata/categories/financial.ts index c4cb31e5b..3eb88d999 100644 --- a/src/interpreter/functionMetadata/categories/financial.ts +++ b/src/interpreter/functionMetadata/categories/financial.ts @@ -72,7 +72,7 @@ export const FINANCIAL_DOCS: Record = { }, MIRR: { category: 'Financial', - shortDescription: 'Returns modified internal value for cashflows.', + shortDescription: 'Returns the modified internal rate of return for a series of cash flows.', parameters: [{name: 'flows', description: ''}, {name: 'f_rate', description: ''}, {name: 'r_rate', description: ''}], }, NOMINAL: { @@ -147,7 +147,7 @@ export const FINANCIAL_DOCS: Record = { }, XNPV: { category: 'Financial', - shortDescription: 'Returns net present value.', + shortDescription: 'Returns the net present value for a schedule of cash flows that is not necessarily periodic.', parameters: [{name: 'rate', description: ''}, {name: 'payments', description: ''}, {name: 'dates', description: ''}], }, XIRR: { diff --git a/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts b/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts index 008202a50..29f51f8f7 100644 --- a/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts +++ b/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts @@ -67,7 +67,7 @@ export const MATH_AND_TRIGONOMETRY_DOCS: Record = { }, BASE: { category: 'Math and trigonometry', - shortDescription: 'Converts a positive integer to a specified base into a text from the numbering system.', + shortDescription: 'Converts a non-negative integer to a specified base into a text from the numbering system.', parameters: [{name: 'number', description: ''}, {name: 'radix', description: ''}, {name: 'minimum_length', description: ''}], }, CEILING: { @@ -212,7 +212,7 @@ export const MATH_AND_TRIGONOMETRY_DOCS: Record = { }, MROUND: { category: 'Math and trigonometry', - shortDescription: 'Rounds number to the neares multiplicity.', + shortDescription: 'Rounds a number to the nearest multiple.', parameters: [{name: 'number', description: ''}, {name: 'base', description: ''}], }, MULTINOMIAL: { @@ -287,7 +287,7 @@ export const MATH_AND_TRIGONOMETRY_DOCS: Record = { }, SECH: { category: 'Math and trigonometry', - shortDescription: 'Returns the hyperbolic secant of the given angle (in radians).', + shortDescription: 'Returns the hyperbolic secant of the given value.', parameters: [{name: 'number', description: ''}], }, SERIESSUM: { diff --git a/src/interpreter/functionMetadata/categories/statistical.ts b/src/interpreter/functionMetadata/categories/statistical.ts index 9e9ce0f53..91751b9e8 100644 --- a/src/interpreter/functionMetadata/categories/statistical.ts +++ b/src/interpreter/functionMetadata/categories/statistical.ts @@ -187,7 +187,7 @@ export const STATISTICAL_DOCS: Record = { }, FISHERINV: { category: 'Statistical', - shortDescription: 'Returns inverse Fischer transformation value.', + shortDescription: 'Returns inverse Fisher transformation value.', parameters: [{name: 'number', description: ''}], }, GAMMA: { @@ -317,7 +317,7 @@ export const STATISTICAL_DOCS: Record = { }, PHI: { category: 'Statistical', - shortDescription: 'Returns probability densitity of normal distribution.', + shortDescription: 'Returns probability density of normal distribution.', parameters: [{name: 'x', description: ''}], }, 'POISSON.DIST': { @@ -342,12 +342,12 @@ export const STATISTICAL_DOCS: Record = { }, SKEW: { category: 'Statistical', - shortDescription: 'Returns skeweness of a sample.', + shortDescription: 'Returns skewness of a sample.', parameters: [{name: 'number1', description: ''}], }, 'SKEW.P': { category: 'Statistical', - shortDescription: 'Returns skeweness of a population.', + shortDescription: 'Returns skewness of a population.', parameters: [{name: 'number1', description: ''}], }, SLOPE: { diff --git a/src/interpreter/functionMetadata/categories/text.ts b/src/interpreter/functionMetadata/categories/text.ts index c669cb14e..b07c2347f 100644 --- a/src/interpreter/functionMetadata/categories/text.ts +++ b/src/interpreter/functionMetadata/categories/text.ts @@ -92,7 +92,7 @@ export const TEXT_DOCS: Record = { }, SPLIT: { category: 'Text', - shortDescription: 'Divides the provided text using the space character as a separator and returns the substring at the zero-based position specified by the second argument.
`SPLIT("Lorem ipsum", 0) -> "Lorem"`
`SPLIT("Lorem ipsum", 1) -> "ipsum"`', + shortDescription: 'Divides the provided text using the space character as a separator and returns the substring at the zero-based position specified by the second argument. For example, SPLIT("Lorem ipsum", 0) returns "Lorem" and SPLIT("Lorem ipsum", 1) returns "ipsum".', parameters: [{name: 'text', description: ''}, {name: 'index', description: ''}], }, SUBSTITUTE: { @@ -107,7 +107,7 @@ export const TEXT_DOCS: Record = { }, TEXT: { category: 'Text', - shortDescription: 'Converts a number into text according to a given format.
By default, accepts the same formats that can be passed to the [`dateFormats`](../api/interfaces/configparams.md#dateformats) option, but can be further customized with the [`stringifyDateTime`](../api/interfaces/configparams.md#stringifydatetime) option.', + shortDescription: 'Converts a number into text according to a given format. By default it accepts the same formats as the dateFormats option, and can be further customized with the stringifyDateTime and stringifyCurrency options.', parameters: [{name: 'number', description: ''}, {name: 'format', description: ''}], }, TEXTJOIN: { From d5d77bd95a5a83249250ef8bc11535608b229c19 Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Thu, 16 Jul 2026 15:29:57 +0200 Subject: [PATCH 32/35] Function metadata: usage examples, documentation URL, parameter descriptions (HF-300) (#1705) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What & why HF-300 enriches the function-metadata API (`getFunctionDetails`) so every built-in function returns, in addition to the existing short description and parameter names: - a **usage example** (≥1 per function), - a **documentation URL** — a single shared URL for all functions in v1 (`https://hyperformula.handsontable.com/docs/guide/built-in-functions.html`), and - a **short description for each parameter**. Everything is English (translations are a later phase; the structure is already i18n-ready). Extends the `SUM`/`SUMIF` exemplar already on the base branch to the whole catalogue (363 functions). Base: `feature/hf-249-function-metadata-api` (#1692). Sibling: #1699 (docs single source). ## How - The single documentation URL is defined once as `DEFAULT_DOCUMENTATION_URL` in `buildFunctionDescriptions.ts` and applied as the built-in default — not repeated per function. Custom (user-registered) functions keep `''`. - `examples` + per-parameter `description` authored per category file (`categories/*.ts`). Parameter counts/names and entry order are unchanged; only bodies were filled. ## Testing (in the paired hyperformula-tests PR) - Coverage-parity: every listable built-in exposes the shared URL, ≥1 example, and a non-empty description for every parameter. - Example-validity: every authored example is built in HyperFormula and asserted not to be a parse (`#ERROR!`) or unknown-function (`#NAME?`) error. - Existing `SUM`/`SUMIF` assertions updated to the `.html` URL. - Arity guard (`buildFunctionDetails`) stays green across all 363 functions. Local gates: `tsc` (src+test) clean · `eslint` clean · full `jest` 0 failures · metadata+coverage+example-validity specs pass. ## Notes for review - **No i18n changes — by design.** DoD scopes HF-300 to English; no functions are added/renamed, so the 17-language-pack rule does not apply. English-form examples show under every locale for now (accepted "translations later" trade-off). - **Operators** (`HF.ADD`, …) are listable built-ins, so they get examples/descriptions per the DoD's "each function". - **Aliases** inherit their target's authored doc automatically (`resolveFunctionMetadata`), so they need no separate authoring. - **Guide table untouched** → the #1699 docs drift-check stays green (none of the new fields are rendered in the Function ID/Description/Syntax table). - Descriptions describe **HyperFormula's actual behavior** (verified against the plugins), not Excel where they diverge — e.g. `MOD` result takes the sign of the dividend, `FILTER` accepts a single row/column, `XNPV`'s first date is the reference point. Decisions and citations: ADR in the paired hyperformula-tests repo (`adr/2026-07-13-hf300-function-metadata-enrichment.md`). Source: https://app.clickup.com/t/86caprtgj --- > [!NOTE] > **Medium Risk** > Large, user-facing metadata expansion for every built-in via `getFunctionDetails`, but no formula-engine behavior changes; main risk is stale or incorrect authored docs and accidental loss if the migration script is re-run. > > **Overview** > **HF-300** fills out the built-in `FunctionDoc` catalogue so `getFunctionDetails` can return real **parameter descriptions**, at least one **usage example** per function, and a shared **documentation URL** (`.html` guide link) across the category files—not the previous empty placeholders. > > `FunctionDescription` / `buildFunctionDetails` comments and contracts are updated to treat those fields as authored for built-ins (custom functions still get `''` / `[]`). `buildFunctionDetails` now passes `documentationUrl` straight from the catalogue instead of defaulting missing values to `''`. > > The HF-249 migration script and category file headers **warn that re-running the generator wipes** hand-authored `examples` and parameter `description` text. One wording fix: **`INT`**’s short description now matches truncate-toward-zero behavior. > > Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 1c6b6a9e079e657e0a5167c70c6e6806ce4231e3. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot). --------- Co-authored-by: Claude Opus 4.8 (1M context) Co-authored-by: Cursor Agent Co-authored-by: Kuba Sekowski Co-authored-by: Kuba Sekowski --- scripts/hf249-migrate-function-docs.ts | 7 +- .../functionMetadata/FunctionDescription.ts | 22 +- .../buildFunctionDescriptions.ts | 6 +- .../categories/array-manipulation.ts | 27 +- .../functionMetadata/categories/database.ts | 51 ++- .../categories/date-and-time.ts | 103 +++-- .../categories/engineering.ts | 187 ++++++--- .../functionMetadata/categories/financial.ts | 119 ++++-- .../categories/information.ts | 65 +++- .../functionMetadata/categories/logical.ts | 43 ++- .../categories/lookup-and-reference.ts | 55 ++- .../categories/math-and-trigonometry.ts | 295 ++++++++++---- .../categories/matrix-functions.ts | 19 +- .../functionMetadata/categories/operator.ts | 63 ++- .../categories/statistical.ts | 359 +++++++++++++----- .../functionMetadata/categories/text.ts | 107 ++++-- 16 files changed, 1134 insertions(+), 394 deletions(-) diff --git a/scripts/hf249-migrate-function-docs.ts b/scripts/hf249-migrate-function-docs.ts index 6b40bb8fe..ae8d18e66 100644 --- a/scripts/hf249-migrate-function-docs.ts +++ b/scripts/hf249-migrate-function-docs.ts @@ -16,6 +16,10 @@ * - parameter names come from the "Syntax" column, but their COUNT and optionality are governed by the * implementation arity — the syntax column is only a (sometimes dirty) source of human-readable names. * + * WARNING: this regenerates each category file from scratch and does NOT preserve the hand-authored + * `examples` and parameter `description` fields (HF-300). Re-running it silently wipes them — re-author + * afterwards, or extend this tool to carry those fields forward, before committing the result. + * * Run with: `npm run tsnode scripts/hf249-migrate-function-docs.ts` */ @@ -198,7 +202,8 @@ import {FunctionDoc} from '../FunctionDescription' /** * Catalogue entries for the "${category}" category. Generated from \`docs/guide/built-in-functions.md\` by - * \`scripts/hf249-migrate-function-docs.ts\`; parameter descriptions are authored in a later phase. + * \`scripts/hf249-migrate-function-docs.ts\`. The \`examples\` and parameter + * descriptions are hand-authored; re-running that script overwrites them. */ export const ${constName(category)}: Record = { ${body} diff --git a/src/interpreter/functionMetadata/FunctionDescription.ts b/src/interpreter/functionMetadata/FunctionDescription.ts index f68ccfefa..b7e7d7ebb 100644 --- a/src/interpreter/functionMetadata/FunctionDescription.ts +++ b/src/interpreter/functionMetadata/FunctionDescription.ts @@ -29,28 +29,24 @@ export type FunctionCategory = typeof FUNCTION_CATEGORIES[number] export interface ParameterDoc { /** Display name as shown in the syntax, Google-Sheets style, e.g. `'Factor1'`. */ name: string, - /** What the argument does. Present but empty (`''`) in the MVP; authored in a later phase. */ + /** What the argument does. Authored for every built-in parameter (English). */ description: string, } /** - * Storage: authored metadata for one canonical function. English in the MVP. + * Storage: authored metadata for one canonical function. English (translations are a later phase). */ export interface FunctionDoc { category: FunctionCategory, - /** One-liner, sentence-case description. English in the MVP. (A separate long description may follow later.) */ + /** One-liner, sentence-case description (English). (A separate long description may follow later.) */ shortDescription: string, /** Ordered; length MUST equal the function's `implementedFunctions.parameters` length (implementation arity). */ parameters: ParameterDoc[], /** - * Link to the function's documentation. Optional and absent for most functions in the MVP (surfaced as `''`); - * authored per function in a later phase. + * Link to the function's documentation. Required for all functions. */ documentationUrl?: string, - /** - * Usage examples. Optional and absent for most functions in the MVP (surfaced as `[]`); authored per function - * in a later phase. - */ + /** Usage examples (English). Authored for every built-in function; at least one per function. */ examples?: string[], } @@ -74,7 +70,7 @@ export interface FunctionListEntry { export interface FunctionParameterDescription { /** Human-readable parameter name. */ name: string, - /** What the argument does. Present but empty (`''`) in the MVP; populated in a later phase. */ + /** What the argument does (English). Populated for every built-in parameter; `''` for custom functions. */ description: string, /** `true` when the argument may be omitted. */ optional: boolean, @@ -100,8 +96,8 @@ export interface FunctionDetails { * (Criteria range, Criterion) pair repeats. The caller renders the syntax string from this. */ repeatLastArgs: number, - /** Link to the function's documentation. Authored per function; `''` for functions not yet documented. */ - documentationUrl: string, - /** Usage examples. Authored per function; `[]` for functions not yet documented. */ + /** Link to the function's documentation. The single shared docs URL for built-ins; `''` for custom functions. */ + documentationUrl?: string, + /** Usage examples (English). At least one per built-in function; `[]` for custom functions. */ examples: string[], } diff --git a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts index b3845b4df..2b87bc949 100644 --- a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts +++ b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts @@ -53,8 +53,8 @@ export function buildFunctionListEntry(canonicalName: string, doc: FunctionDoc, /** * Builds a Tier-2 details object: the list fields plus the parameter list (name, description, optionality) and * `repeatLastArgs` (how many trailing parameters repeat). The caller renders the syntax string from these. - * `documentationUrl` and `examples` come from the catalogue doc when authored, and fall back to `''`/`[]` - * otherwise; each parameter `description` is present but empty for functions not yet authored. + * `documentationUrl` comes from the catalogue doc; `examples` falls back to `[]`. Built-in parameters carry authored + * descriptions; custom functions surface empty values. * * @param {string} canonicalName - the language-independent function id * @param {FunctionDoc} doc - the function's authored catalogue entry @@ -80,7 +80,7 @@ export function buildFunctionDetails(canonicalName: string, doc: FunctionDoc, me shortDescription: doc.shortDescription, parameters, repeatLastArgs: metadata.repeatLastArgs ?? 0, - documentationUrl: doc.documentationUrl ?? '', + documentationUrl: doc.documentationUrl, examples: doc.examples ?? [], } } diff --git a/src/interpreter/functionMetadata/categories/array-manipulation.ts b/src/interpreter/functionMetadata/categories/array-manipulation.ts index bf03946af..c83de7630 100644 --- a/src/interpreter/functionMetadata/categories/array-manipulation.ts +++ b/src/interpreter/functionMetadata/categories/array-manipulation.ts @@ -7,37 +7,50 @@ import {FunctionDoc} from '../FunctionDescription' /** * Catalogue entries for the "Array manipulation" category. Generated from `docs/guide/built-in-functions.md` by - * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + * `scripts/hf249-migrate-function-docs.ts`. The `examples` and parameter + * descriptions are hand-authored; re-running that script overwrites them. */ export const ARRAY_MANIPULATION_DOCS: Record = { ARRAY_CONSTRAIN: { category: 'Array manipulation', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Truncates an array to given dimensions.', - parameters: [{name: 'array', description: ''}, {name: 'height', description: ''}, {name: 'width', description: ''}], + parameters: [{name: 'array', description: 'The array or range to truncate.'}, {name: 'height', description: 'The maximum number of rows to keep, automatically capped at the height of Array.'}, {name: 'width', description: 'The maximum number of columns to keep, automatically capped at the width of Array.'}], + examples: ['=ARRAY_CONSTRAIN(A1:C3, 2, 2)', '=ARRAY_CONSTRAIN(A1:C3, 1, 3)'], }, ARRAYFORMULA: { category: 'Array manipulation', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Enables the array arithmetic mode for a single formula.', - parameters: [{name: 'formula', description: ''}], + parameters: [{name: 'formula', description: 'The formula or expression to evaluate in array arithmetic mode, so operations are applied element-by-element across the referenced ranges.'}], + examples: ['=ARRAYFORMULA(A1:A3*B1:B3)', '=SUM(ARRAYFORMULA(A1:A3*B1:B3))'], }, FILTER: { category: 'Array manipulation', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Filters an array, based on multiple conditions (boolean arrays).', - parameters: [{name: 'source_array', description: ''}, {name: 'bool_array1', description: ''}], + parameters: [{name: 'source_array', description: 'The range of values to filter; it must be a single row or a single column (a two-dimensional range is not supported).'}, {name: 'bool_array1', description: 'A range of boolean values, with the same dimensions as SourceArray, marking which rows or columns to keep; only entries where every boolean array is TRUE are returned. Further boolean arrays can be passed as additional arguments, and all of them must evaluate to TRUE for an entry to be kept.'}], + examples: ['=FILTER(A1:C1, A2:C2)', '=FILTER(A1:A5, A1:A5>10)', '=FILTER(A1:C1, A2:C2, A3:C3)'], }, SEQUENCE: { category: 'Array manipulation', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns an array of sequential numbers.', - parameters: [{name: 'rows', description: ''}, {name: 'cols', description: ''}, {name: 'start', description: ''}, {name: 'step', description: ''}], + parameters: [{name: 'rows', description: 'The number of rows in the returned array. The size must be resolvable at parse time, so use a literal (e.g. 3); a cell reference or formula yields a #VALUE! error whenever the result would span more than one cell, since the array size cannot be determined at parse time.'}, {name: 'cols', description: 'The number of columns in the returned array. Defaults to 1 when omitted; like rows, it must be resolvable at parse time.'}, {name: 'start', description: 'The first value of the sequence. Defaults to 1 when omitted.'}, {name: 'step', description: 'The increment between consecutive values, filled row by row. Defaults to 1 when omitted.'}], + examples: ['=SEQUENCE(4)', '=SEQUENCE(3, 2)', '=SEQUENCE(3, 1, 10, 5)'], }, VSTACK: { category: 'Array manipulation', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Stacks arrays vertically into a single array.', - parameters: [{name: 'array1', description: ''}], + parameters: [{name: 'array1', description: 'A range or array to stack. Further ranges or arrays can be passed as additional arguments; they are stacked top to bottom into one array.'}], + examples: ['=VSTACK(A1:B2, A3:B4)', '=VSTACK(A1:C1, A2:C2)'], }, HSTACK: { category: 'Array manipulation', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Stacks arrays horizontally into a single array.', - parameters: [{name: 'array1', description: ''}], + parameters: [{name: 'array1', description: 'A range or array to stack. Further ranges or arrays can be passed as additional arguments; they are stacked left to right into one array.'}], + examples: ['=HSTACK(A1:A3, B1:B3)', '=HSTACK(A1:B2, C1:D2)'], }, } diff --git a/src/interpreter/functionMetadata/categories/database.ts b/src/interpreter/functionMetadata/categories/database.ts index 4a2d3e1d7..c1e894359 100644 --- a/src/interpreter/functionMetadata/categories/database.ts +++ b/src/interpreter/functionMetadata/categories/database.ts @@ -7,67 +7,92 @@ import {FunctionDoc} from '../FunctionDescription' /** * Catalogue entries for the "Database" category. Generated from `docs/guide/built-in-functions.md` by - * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + * `scripts/hf249-migrate-function-docs.ts`. The `examples` and parameter + * descriptions are hand-authored; re-running that script overwrites them. */ export const DATABASE_DOCS: Record = { DAVERAGE: { category: 'Database', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the average of all values in a database field that match the given criteria.', - parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], + parameters: [{name: 'database', description: 'The range of cells holding the database table, including a header row with field names in the first row.'}, {name: 'field', description: 'The field whose values are averaged, given as a matching header name or as a 1-based column index within Database.'}, {name: 'criteria', description: 'The range of condition cells, with a header row matching field names in Database and one or more rows below it; conditions within the same row are combined with AND, and separate rows are combined with OR.'}], + examples: ['=DAVERAGE(A1:C10, "Sales", E1:E2)', '=DAVERAGE(A1:C10, 3, E1:F2)'], }, DCOUNT: { category: 'Database', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Counts the cells containing numbers in a database field that match the given criteria.', - parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], + parameters: [{name: 'database', description: 'The range of cells holding the database table, including a header row with field names in the first row.'}, {name: 'field', description: 'The field whose numeric values are counted, given as a matching header name or as a 1-based column index within Database.'}, {name: 'criteria', description: 'The range of condition cells, with a header row matching field names in Database and one or more rows below it; conditions within the same row are combined with AND, and separate rows are combined with OR.'}], + examples: ['=DCOUNT(A1:C10, "Sales", E1:E2)', '=DCOUNT(A1:C10, 3, E1:F2)'], }, DCOUNTA: { category: 'Database', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Counts the non-empty cells in a database field that match the given criteria.', - parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], + parameters: [{name: 'database', description: 'The range of cells holding the database table, including a header row with field names in the first row.'}, {name: 'field', description: 'The field whose non-empty values are counted, given as a matching header name or as a 1-based column index within Database.'}, {name: 'criteria', description: 'The range of condition cells, with a header row matching field names in Database and one or more rows below it; conditions within the same row are combined with AND, and separate rows are combined with OR.'}], + examples: ['=DCOUNTA(A1:C10, "Name", E1:E2)', '=DCOUNTA(A1:C10, 1, E1:F2)'], }, DGET: { category: 'Database', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the single value from a database field that matches the given criteria. Returns #VALUE! if no records match, and #NUM! if more than one record matches.', - parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], + parameters: [{name: 'database', description: 'The range of cells holding the database table, including a header row with field names in the first row.'}, {name: 'field', description: 'The field whose value is returned, given as a matching header name or as a 1-based column index within Database.'}, {name: 'criteria', description: 'The range of condition cells, with a header row matching field names in Database and one or more rows below it; conditions within the same row are combined with AND, and separate rows are combined with OR.'}], + examples: ['=DGET(A1:C10, "Name", E1:E2)', '=DGET(A1:C10, 2, E1:F2)'], }, DMAX: { category: 'Database', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the maximum value in a database field that matches the given criteria.', - parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], + parameters: [{name: 'database', description: 'The range of cells holding the database table, including a header row with field names in the first row.'}, {name: 'field', description: 'The field whose maximum value is returned, given as a matching header name or as a 1-based column index within Database.'}, {name: 'criteria', description: 'The range of condition cells, with a header row matching field names in Database and one or more rows below it; conditions within the same row are combined with AND, and separate rows are combined with OR.'}], + examples: ['=DMAX(A1:C10, "Sales", E1:E2)', '=DMAX(A1:C10, 3, E1:F2)'], }, DMIN: { category: 'Database', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the minimum value in a database field that matches the given criteria.', - parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], + parameters: [{name: 'database', description: 'The range of cells holding the database table, including a header row with field names in the first row.'}, {name: 'field', description: 'The field whose minimum value is returned, given as a matching header name or as a 1-based column index within Database.'}, {name: 'criteria', description: 'The range of condition cells, with a header row matching field names in Database and one or more rows below it; conditions within the same row are combined with AND, and separate rows are combined with OR.'}], + examples: ['=DMIN(A1:C10, "Sales", E1:E2)', '=DMIN(A1:C10, 3, E1:F2)'], }, DPRODUCT: { category: 'Database', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the product of all values in a database field that match the given criteria.', - parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], + parameters: [{name: 'database', description: 'The range of cells holding the database table, including a header row with field names in the first row.'}, {name: 'field', description: 'The field whose matching values are multiplied together, given as a matching header name or as a 1-based column index within Database.'}, {name: 'criteria', description: 'The range of condition cells, with a header row matching field names in Database and one or more rows below it; conditions within the same row are combined with AND, and separate rows are combined with OR.'}], + examples: ['=DPRODUCT(A1:C10, "Sales", E1:E2)', '=DPRODUCT(A1:C10, 3, E1:F2)'], }, DSTDEV: { category: 'Database', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the sample standard deviation of all values in a database field that match the given criteria.', - parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], + parameters: [{name: 'database', description: 'The range of cells holding the database table, including a header row with field names in the first row.'}, {name: 'field', description: 'The field whose sample standard deviation is calculated, given as a matching header name or as a 1-based column index within Database.'}, {name: 'criteria', description: 'The range of condition cells, with a header row matching field names in Database and one or more rows below it; conditions within the same row are combined with AND, and separate rows are combined with OR.'}], + examples: ['=DSTDEV(A1:C10, "Sales", E1:E2)', '=DSTDEV(A1:C10, 3, E1:F2)'], }, DSTDEVP: { category: 'Database', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the population standard deviation of all values in a database field that match the given criteria.', - parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], + parameters: [{name: 'database', description: 'The range of cells holding the database table, including a header row with field names in the first row.'}, {name: 'field', description: 'The field whose population standard deviation is calculated, given as a matching header name or as a 1-based column index within Database.'}, {name: 'criteria', description: 'The range of condition cells, with a header row matching field names in Database and one or more rows below it; conditions within the same row are combined with AND, and separate rows are combined with OR.'}], + examples: ['=DSTDEVP(A1:C10, "Sales", E1:E2)', '=DSTDEVP(A1:C10, 3, E1:F2)'], }, DSUM: { category: 'Database', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the sum of all values in a database field that match the given criteria.', - parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], + parameters: [{name: 'database', description: 'The range of cells holding the database table, including a header row with field names in the first row.'}, {name: 'field', description: 'The field whose values are summed, given as a matching header name or as a 1-based column index within Database.'}, {name: 'criteria', description: 'The range of condition cells, with a header row matching field names in Database and one or more rows below it; conditions within the same row are combined with AND, and separate rows are combined with OR.'}], + examples: ['=DSUM(A1:C10, "Sales", E1:E2)', '=DSUM(A1:C10, 3, E1:F2)'], }, DVAR: { category: 'Database', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the sample variance of all values in a database field that match the given criteria.', - parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], + parameters: [{name: 'database', description: 'The range of cells holding the database table, including a header row with field names in the first row.'}, {name: 'field', description: 'The field whose sample variance is calculated, given as a matching header name or as a 1-based column index within Database.'}, {name: 'criteria', description: 'The range of condition cells, with a header row matching field names in Database and one or more rows below it; conditions within the same row are combined with AND, and separate rows are combined with OR.'}], + examples: ['=DVAR(A1:C10, "Sales", E1:E2)', '=DVAR(A1:C10, 3, E1:F2)'], }, DVARP: { category: 'Database', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the population variance of all values in a database field that match the given criteria.', - parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}], + parameters: [{name: 'database', description: 'The range of cells holding the database table, including a header row with field names in the first row.'}, {name: 'field', description: 'The field whose population variance is calculated, given as a matching header name or as a 1-based column index within Database.'}, {name: 'criteria', description: 'The range of condition cells, with a header row matching field names in Database and one or more rows below it; conditions within the same row are combined with AND, and separate rows are combined with OR.'}], + examples: ['=DVARP(A1:C10, "Sales", E1:E2)', '=DVARP(A1:C10, 3, E1:F2)'], }, } diff --git a/src/interpreter/functionMetadata/categories/date-and-time.ts b/src/interpreter/functionMetadata/categories/date-and-time.ts index fce033bb0..3d22283d8 100644 --- a/src/interpreter/functionMetadata/categories/date-and-time.ts +++ b/src/interpreter/functionMetadata/categories/date-and-time.ts @@ -7,137 +7,190 @@ import {FunctionDoc} from '../FunctionDescription' /** * Catalogue entries for the "Date and time" category. Generated from `docs/guide/built-in-functions.md` by - * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + * `scripts/hf249-migrate-function-docs.ts`. The `examples` and parameter + * descriptions are hand-authored; re-running that script overwrites them. */ export const DATE_AND_TIME_DOCS: Record = { DATE: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the specified date as the number of full days since [`nullDate`](../api/interfaces/configparams.md#nulldate).', - parameters: [{name: 'year', description: ''}, {name: 'month', description: ''}, {name: 'day', description: ''}], + parameters: [{name: 'year', description: 'The year of the date; values below HyperFormula\'s epoch year (derived from nullDate) are added to that epoch year.'}, {name: 'month', description: 'The month of the date. Values outside 1-12 roll over into adjacent years.'}, {name: 'day', description: 'The day of the month. Values outside the month\'s range roll over into adjacent months.'}], + examples: ['=DATE(2020, 1, 15)', '=DATE(2020, 13, 1)'], }, DATEDIF: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Calculates distance between two dates.
Supported units: "D" (days), "M" (months), "Y" (years), "MD" (days ignoring months and years), "YM" (months ignoring years), or "YD" (days ignoring years).', - parameters: [{name: 'date1', description: ''}, {name: 'date2', description: ''}, {name: 'unit', description: ''}], + parameters: [{name: 'date1', description: 'The earlier (start) date of the period; must not be later than Date2.'}, {name: 'date2', description: 'The later (end) date of the period.'}, {name: 'unit', description: 'A code selecting the unit of the result: "D", "M", "Y", "MD", "YM", or "YD".'}], + examples: ['=DATEDIF(DATE(2020,1,1), DATE(2020,6,15), "M")', '=DATEDIF(A1, A2, "D")'], }, DATEVALUE: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Parses a date string and returns it as the number of full days since [`nullDate`](../api/interfaces/configparams.md#nulldate).
Accepts formats set by the [`dateFormats`](../api/interfaces/configparams.md#dateformats) option.', - parameters: [{name: 'date_string', description: ''}], + parameters: [{name: 'date_string', description: 'A text string representing a date, in one of the formats configured via dateFormats.'}], + examples: ['=DATEVALUE("30/03/2020")', '=DATEVALUE("31/12/2020")'], }, DAY: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the day of the given date value.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A date value (serial number of days since nullDate) whose day-of-month is returned.'}], + examples: ['=DAY(DATE(2020, 3, 30))', '=DAY(A1)'], }, DAYS: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Calculates the difference between two date values.', - parameters: [{name: 'date2', description: ''}, {name: 'date1', description: ''}], + parameters: [{name: 'date2', description: 'The end (more recent) date value.'}, {name: 'date1', description: 'The start (earlier) date value; the result is Date2 minus Date1, in days.'}], + examples: ['=DAYS(DATE(2020,3,31), DATE(2020,3,1))', '=DAYS(A2, A1)'], }, DAYS360: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Calculates the difference between two date values in days, in 360-day basis.', - parameters: [{name: 'date2', description: ''}, {name: 'date1', description: ''}, {name: 'format', description: ''}], + parameters: [{name: 'date2', description: 'The start date of the 360-day (30-day-month) period.'}, {name: 'date1', description: 'The end date of the 360-day period; the result is Date1 minus Date2 measured with 30-day months.'}, {name: 'format', description: 'TRUE uses the European 30/360 method; FALSE (default) uses the US (NASD) method.'}], + examples: ['=DAYS360(DATE(2020,3,1), DATE(2020,3,31))', '=DAYS360(A1, A2, TRUE())'], }, EDATE: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Shifts the given startdate by given number of months and returns it as the number of full days since [`nullDate`](../api/interfaces/configparams.md#nulldate).[^non-odff]', - parameters: [{name: 'start_date', description: ''}, {name: 'months', description: ''}], + parameters: [{name: 'start_date', description: 'The date value to shift.'}, {name: 'months', description: 'The number of months to shift Startdate by; negative values shift backwards.'}], + examples: ['=EDATE(A1, 3)', '=EDATE(DATE(2020, 1, 15), -2)'], }, EOMONTH: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the date of the last day of a month which falls months away from the start date. Returns the value in the form of number of full days since [`nullDate`](../api/interfaces/configparams.md#nulldate).[^non-odff]', - parameters: [{name: 'start_date', description: ''}, {name: 'months', description: ''}], + parameters: [{name: 'start_date', description: 'The date value to start counting from.'}, {name: 'months', description: 'The number of months to add to Startdate before finding the end of that month; negative values go backwards.'}], + examples: ['=EOMONTH(A1, 1)', '=EOMONTH(DATE(2020, 1, 15), 0)'], }, HOUR: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns hour component of given time.', - parameters: [{name: 'time', description: ''}], + parameters: [{name: 'time', description: 'A time value (fraction of a full day) whose hour component is returned.'}], + examples: ['=HOUR(TIME(14, 30, 0))', '=HOUR(A1)'], }, INTERVAL: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns interval string from given number of seconds.', - parameters: [{name: 'seconds', description: ''}], + parameters: [{name: 'seconds', description: 'The total number of seconds to convert into an ISO 8601 duration string.'}], + examples: ['=INTERVAL(3665)', '=INTERVAL(A1)'], }, ISOWEEKNUM: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns an ISO week number that corresponds to the week of year.', - parameters: [{name: 'date', description: ''}], + parameters: [{name: 'date', description: 'The date value whose ISO-8601 week number (Monday-based) is returned.'}], + examples: ['=ISOWEEKNUM(DATE(2020, 1, 1))', '=ISOWEEKNUM(A1)'], }, MINUTE: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns minute component of given time.', - parameters: [{name: 'time', description: ''}], + parameters: [{name: 'time', description: 'A time value (fraction of a full day) whose minute component is returned.'}], + examples: ['=MINUTE(TIME(14, 30, 0))', '=MINUTE(A1)'], }, MONTH: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the month for the given date value.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A date value (serial number of days since nullDate) whose month is returned.'}], + examples: ['=MONTH(DATE(2020, 3, 30))', '=MONTH(A1)'], }, NETWORKDAYS: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the number of working days between two given dates.', - parameters: [{name: 'date1', description: ''}, {name: 'date2', description: ''}, {name: 'holidays', description: ''}], + parameters: [{name: 'date1', description: 'The start date of the range.'}, {name: 'date2', description: 'The end date of the range.'}, {name: 'holidays', description: 'An optional range of dates to exclude from the working-day count, in addition to weekends (Saturday and Sunday).'}], + examples: ['=NETWORKDAYS(A1, A2)', '=NETWORKDAYS(DATE(2020,1,1), DATE(2020,1,31), C1:C3)'], }, 'NETWORKDAYS.INTL': { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the number of working days between two given dates.', - parameters: [{name: 'date1', description: ''}, {name: 'date2', description: ''}, {name: 'mode', description: ''}, {name: 'holidays', description: ''}], + parameters: [{name: 'date1', description: 'The start date of the range.'}, {name: 'date2', description: 'The end date of the range.'}, {name: 'mode', description: 'A weekend code (1-7, 11-17; default 1 for Saturday/Sunday) or a 7-character string of 0s and 1s marking weekend days, starting from Monday.'}, {name: 'holidays', description: 'An optional range of dates to exclude from the working-day count, in addition to the weekend days.'}], + examples: ['=NETWORKDAYS.INTL(A1, A2, 2)', '=NETWORKDAYS.INTL(DATE(2020,1,1), DATE(2020,1,31), "0000011", C1:C3)'], }, NOW: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns current date + time as a number of days since [`nullDate`](../api/interfaces/configparams.md#nulldate).', parameters: [], + examples: ['=NOW()'], }, SECOND: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns second component of given time.', - parameters: [{name: 'time', description: ''}], + parameters: [{name: 'time', description: 'A time value (fraction of a full day) whose second component is returned.'}], + examples: ['=SECOND(TIME(14, 30, 45))', '=SECOND(A1)'], }, TIME: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the number that represents a given time as a fraction of full day.', - parameters: [{name: 'hour', description: ''}, {name: 'minute', description: ''}, {name: 'second', description: ''}], + parameters: [{name: 'hour', description: 'The hour component of the time.'}, {name: 'minute', description: 'The minute component of the time.'}, {name: 'second', description: 'The second component of the time.'}], + examples: ['=TIME(14, 30, 0)', '=TIME(A1, A2, A3)'], }, TIMEVALUE: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Parses a time string and returns a number that represents it as a fraction of a full day.
Accepts formats set by the [`timeFormats`](../api/interfaces/configparams.md#timeformats) option.', - parameters: [{name: 'time_string', description: ''}], + parameters: [{name: 'time_string', description: 'A text string representing a time, in one of the formats configured via timeFormats.'}], + examples: ['=TIMEVALUE("14:30:00")', '=TIMEVALUE(A1)'], }, TODAY: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns an integer representing the current date as the number of full days since [`nullDate`](../api/interfaces/configparams.md#nulldate).', parameters: [], + examples: ['=TODAY()'], }, WEEKDAY: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Computes a number between 1-7 representing the day of week.', - parameters: [{name: 'date', description: ''}, {name: 'type', description: ''}], + parameters: [{name: 'date', description: 'The date value whose day of the week is returned.'}, {name: 'type', description: 'A code selecting the numbering scheme (default 1: Sunday=1; 2: Monday=1; 3: Monday=0; 11-17: week starting on each successive weekday, numbered 1-7).'}], + examples: ['=WEEKDAY(DATE(2020, 1, 1))', '=WEEKDAY(A1, 2)'], }, WEEKNUM: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns a week number that corresponds to the week of year.', - parameters: [{name: 'date', description: ''}, {name: 'type', description: ''}], + parameters: [{name: 'date', description: 'The date value whose week-of-year number is returned.'}, {name: 'type', description: 'A code selecting which weekday starts the week (default 1: Sunday; 2: Monday; 11-17: each successive weekday; 21: ISO week numbering, Monday-based).'}], + examples: ['=WEEKNUM(DATE(2020, 3, 15))', '=WEEKNUM(A1, 21)'], }, WORKDAY: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the working day number of days from start day.', - parameters: [{name: 'date', description: ''}, {name: 'shift', description: ''}, {name: 'holidays', description: ''}], + parameters: [{name: 'date', description: 'The start date to count from.'}, {name: 'shift', description: 'The number of working days to add (positive) or subtract (negative), skipping weekends (Saturday and Sunday).'}, {name: 'holidays', description: 'An optional range of dates to also skip, in addition to weekends.'}], + examples: ['=WORKDAY(A1, 10)', '=WORKDAY(DATE(2020,1,1), 5, C1:C3)'], }, 'WORKDAY.INTL': { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the working day number of days from start day.', - parameters: [{name: 'date', description: ''}, {name: 'shift', description: ''}, {name: 'mode', description: ''}, {name: 'holidays', description: ''}], + parameters: [{name: 'date', description: 'The start date to count from.'}, {name: 'shift', description: 'The number of working days to add (positive) or subtract (negative).'}, {name: 'mode', description: 'A weekend code (1-7, 11-17; default 1 for Saturday/Sunday) or a 7-character string of 0s and 1s marking weekend days, starting from Monday.'}, {name: 'holidays', description: 'An optional range of dates to also skip, in addition to the weekend days.'}], + examples: ['=WORKDAY.INTL(A1, 10, 2)', '=WORKDAY.INTL(DATE(2020,1,1), 5, "0000011", C1:C3)'], }, YEAR: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the year as a number according to the internal calculation rules.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A date value (serial number of days since nullDate) whose year is returned.'}], + examples: ['=YEAR(DATE(2020, 3, 30))', '=YEAR(A1)'], }, YEARFRAC: { category: 'Date and time', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Computes the difference between two date values, in fraction of years.', - parameters: [{name: 'date2', description: ''}, {name: 'date1', description: ''}, {name: 'format', description: ''}], + parameters: [{name: 'date2', description: 'One of the two boundary dates of the period; HyperFormula automatically reorders Date1/Date2 so the result is never negative.'}, {name: 'date1', description: 'The other boundary date of the period.'}, {name: 'format', description: 'A basis code selecting the day-count convention: 0 = US 30/360 (default), 1 = actual/actual, 2 = actual/360, 3 = actual/365, or 4 = European 30/360.'}], + examples: ['=YEARFRAC(DATE(2020,1,1), DATE(2020,7,1))', '=YEARFRAC(A1, A2, 1)'], }, } diff --git a/src/interpreter/functionMetadata/categories/engineering.ts b/src/interpreter/functionMetadata/categories/engineering.ts index eb15286fc..1a4d74dd4 100644 --- a/src/interpreter/functionMetadata/categories/engineering.ts +++ b/src/interpreter/functionMetadata/categories/engineering.ts @@ -7,237 +7,330 @@ import {FunctionDoc} from '../FunctionDescription' /** * Catalogue entries for the "Engineering" category. Generated from `docs/guide/built-in-functions.md` by - * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + * `scripts/hf249-migrate-function-docs.ts`. The `examples` and parameter + * descriptions are hand-authored; re-running that script overwrites them. */ export const ENGINEERING_DOCS: Record = { BIN2DEC: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'The result is the decimal number for the binary number entered.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'The binary number (as text, up to 10 digits) to convert to decimal.'}], + examples: ['=BIN2DEC(1100100)', '=BIN2DEC(111)'], }, BIN2HEX: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'The result is the hexadecimal number for the binary number entered.', - parameters: [{name: 'number', description: ''}, {name: 'places', description: ''}], + parameters: [{name: 'number', description: 'The binary number (as text, up to 10 digits) to convert to hexadecimal.'}, {name: 'places', description: 'The minimum number of digits to pad the result to with leading zeros; if omitted, no padding is applied.'}], + examples: ['=BIN2HEX(1100100)', '=BIN2HEX(1100100, 4)'], }, BIN2OCT: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'The result is the octal number for the binary number entered.', - parameters: [{name: 'number', description: ''}, {name: 'places', description: ''}], + parameters: [{name: 'number', description: 'The binary number (as text, up to 10 digits) to convert to octal.'}, {name: 'places', description: 'The minimum number of digits to pad the result to with leading zeros; if omitted, no padding is applied.'}], + examples: ['=BIN2OCT(1100100)', '=BIN2OCT(1100100, 4)'], }, BITAND: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns a bitwise logical "and" of the parameters.', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], + parameters: [{name: 'number1', description: 'The first non-negative integer to combine with a bitwise AND.'}, {name: 'number2', description: 'The second non-negative integer to combine with a bitwise AND.'}], + examples: ['=BITAND(5, 3)', '=BITAND(12, 10)'], }, BITLSHIFT: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Shifts a number left by n bits.', - parameters: [{name: 'number', description: ''}, {name: 'shift', description: ''}], + parameters: [{name: 'number', description: 'The non-negative integer whose bits are shifted.'}, {name: 'shift', description: 'The number of bits to shift left by; a negative value shifts right instead.'}], + examples: ['=BITLSHIFT(4, 2)', '=BITLSHIFT(1, 5)'], }, BITOR: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns a bitwise logical "or" of the parameters.', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], + parameters: [{name: 'number1', description: 'The first non-negative integer to combine with a bitwise OR.'}, {name: 'number2', description: 'The second non-negative integer to combine with a bitwise OR.'}], + examples: ['=BITOR(5, 3)', '=BITOR(8, 4)'], }, BITRSHIFT: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Shifts a number right by n bits.', - parameters: [{name: 'number', description: ''}, {name: 'shift', description: ''}], + parameters: [{name: 'number', description: 'The non-negative integer whose bits are shifted.'}, {name: 'shift', description: 'The number of bits to shift right by; a negative value shifts left instead.'}], + examples: ['=BITRSHIFT(16, 2)', '=BITRSHIFT(8, 1)'], }, BITXOR: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns a bitwise logical "exclusive or" of the parameters.', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], + parameters: [{name: 'number1', description: 'The first non-negative integer to combine with a bitwise exclusive OR.'}, {name: 'number2', description: 'The second non-negative integer to combine with a bitwise exclusive OR.'}], + examples: ['=BITXOR(5, 3)', '=BITXOR(12, 10)'], }, COMPLEX: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns complex number from Re and Im parts.', - parameters: [{name: 're', description: ''}, {name: 'im', description: ''}, {name: 'symbol', description: ''}], + parameters: [{name: 're', description: 'The real coefficient of the complex number.'}, {name: 'im', description: 'The imaginary coefficient of the complex number.'}, {name: 'symbol', description: 'The suffix used for the imaginary unit, either "i" or "j"; defaults to "i" when omitted.'}], + examples: ['=COMPLEX(3, 4)', '=COMPLEX(2, -1, "j")'], }, DEC2BIN: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the binary number for the decimal number entered between –512 and 511.', - parameters: [{name: 'number', description: ''}, {name: 'places', description: ''}], + parameters: [{name: 'number', description: 'The decimal integer, between -512 and 511, to convert to binary.'}, {name: 'places', description: 'The minimum number of digits to pad the result to with leading zeros; if omitted, no padding is applied.'}], + examples: ['=DEC2BIN(10)', '=DEC2BIN(10, 8)'], }, DEC2HEX: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the hexadecimal number for the decimal number entered.', - parameters: [{name: 'number', description: ''}, {name: 'places', description: ''}], + parameters: [{name: 'number', description: 'The decimal integer to convert to hexadecimal.'}, {name: 'places', description: 'The minimum number of digits to pad the result to with leading zeros; if omitted, no padding is applied.'}], + examples: ['=DEC2HEX(100)', '=DEC2HEX(100, 4)'], }, DEC2OCT: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the octal number for the decimal number entered.', - parameters: [{name: 'number', description: ''}, {name: 'places', description: ''}], + parameters: [{name: 'number', description: 'The decimal integer to convert to octal.'}, {name: 'places', description: 'The minimum number of digits to pad the result to with leading zeros; if omitted, no padding is applied.'}], + examples: ['=DEC2OCT(58)', '=DEC2OCT(58, 4)'], }, DELTA: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns TRUE (1) if both numbers are equal, otherwise returns FALSE (0).', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], + parameters: [{name: 'number1', description: 'The first number to compare.'}, {name: 'number2', description: 'The second number to compare; defaults to 0 when omitted.'}], + examples: ['=DELTA(5, 5)', '=DELTA(5, 4)', '=DELTA(0)'], }, ERF: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns values of the Gaussian error integral.', - parameters: [{name: 'lower_limit', description: ''}, {name: 'upper_limit', description: ''}], + parameters: [{name: 'lower_limit', description: 'The lower bound of the integral, or the single integration limit from 0 when Upper_Limit is omitted.'}, {name: 'upper_limit', description: 'The upper bound of the integral; when omitted, the integral is calculated from 0 to Lower_Limit.'}], + examples: ['=ERF(1)', '=ERF(0, 1)'], }, ERFC: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns complementary values of the Gaussian error integral between x and infinity.', - parameters: [{name: 'lower_limit', description: ''}], + parameters: [{name: 'lower_limit', description: 'The lower bound of the integral, calculated from this value to infinity.'}], + examples: ['=ERFC(1)', '=ERFC(0.5)'], }, HEX2BIN: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'The result is the binary number for the hexadecimal number entered.', - parameters: [{name: 'number', description: ''}, {name: 'places', description: ''}], + parameters: [{name: 'number', description: 'The hexadecimal number (as text, up to 10 digits) to convert to binary.'}, {name: 'places', description: 'The minimum number of digits to pad the result to with leading zeros; if omitted, no padding is applied.'}], + examples: ['=HEX2BIN("2A")', '=HEX2BIN("2A", 8)'], }, HEX2DEC: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'The result is the decimal number for the hexadecimal number entered.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'The hexadecimal number (as text, up to 10 digits) to convert to decimal.'}], + examples: ['=HEX2DEC("2A")', '=HEX2DEC("FF")'], }, HEX2OCT: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'The result is the octal number for the hexadecimal number entered.', - parameters: [{name: 'number', description: ''}, {name: 'places', description: ''}], + parameters: [{name: 'number', description: 'The hexadecimal number (as text, up to 10 digits) to convert to octal.'}, {name: 'places', description: 'The minimum number of digits to pad the result to with leading zeros; if omitted, no padding is applied.'}], + examples: ['=HEX2OCT("2A")', '=HEX2OCT("2A", 4)'], }, IMABS: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns modulus of a complex number.', - parameters: [{name: 'complex', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", whose modulus is calculated.'}], + examples: ['=IMABS("3+4i")', '=IMABS("-i")'], }, IMAGINARY: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns imaginary part of a complex number.', - parameters: [{name: 'complex', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", whose imaginary coefficient is returned.'}], + examples: ['=IMAGINARY("3+4i")'], }, IMARGUMENT: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns argument of a complex number.', - parameters: [{name: 'complex', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", whose argument (angle in radians) is calculated.'}], + examples: ['=IMARGUMENT("3+4i")'], }, IMCONJUGATE: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns conjugate of a complex number.', - parameters: [{name: 'complex', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", whose complex conjugate is returned.'}], + examples: ['=IMCONJUGATE("3+4i")'], }, IMCOS: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns cosine of a complex number.', - parameters: [{name: 'complex', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", whose cosine is calculated.'}], + examples: ['=IMCOS("3+4i")'], }, IMCOSH: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns hyperbolic cosine of a complex number.', - parameters: [{name: 'complex', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", whose hyperbolic cosine is calculated.'}], + examples: ['=IMCOSH("3+4i")'], }, IMCOT: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns cotangent of a complex number.', - parameters: [{name: 'complex', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", whose cotangent is calculated.'}], + examples: ['=IMCOT("3+4i")'], }, IMCSC: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns cosecant of a complex number.', - parameters: [{name: 'complex', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", whose cosecant is calculated.'}], + examples: ['=IMCSC("3+4i")'], }, IMCSCH: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns hyperbolic cosecant of a complex number.', - parameters: [{name: 'complex', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", whose hyperbolic cosecant is calculated.'}], + examples: ['=IMCSCH("3+4i")'], }, IMDIV: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Divides two complex numbers.', - parameters: [{name: 'complex1', description: ''}, {name: 'complex2', description: ''}], + parameters: [{name: 'complex1', description: 'The complex number to divide (dividend), given as text such as "3+4i".'}, {name: 'complex2', description: 'The complex number to divide by (divisor), given as text such as "1+2i".'}], + examples: ['=IMDIV("3+4i", "1+2i")'], }, IMEXP: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns exponent of a complex number.', - parameters: [{name: 'complex', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", whose exponential is calculated.'}], + examples: ['=IMEXP("3+4i")'], }, IMLN: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns natural logarithm of a complex number.', - parameters: [{name: 'complex', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", whose natural logarithm is calculated.'}], + examples: ['=IMLN("3+4i")'], }, IMLOG10: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns base-10 logarithm of a complex number.', - parameters: [{name: 'complex', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", whose base-10 logarithm is calculated.'}], + examples: ['=IMLOG10("3+4i")'], }, IMLOG2: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns binary logarithm of a complex number.', - parameters: [{name: 'complex', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", whose base-2 logarithm is calculated.'}], + examples: ['=IMLOG2("3+4i")'], }, IMPOWER: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns a complex number raised to a given power.', - parameters: [{name: 'complex', description: ''}, {name: 'number', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", to raise to a power.'}, {name: 'number', description: 'The exponent to raise the complex number to.'}], + examples: ['=IMPOWER("3+4i", 2)'], }, IMPRODUCT: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Multiplies complex numbers.', - parameters: [{name: 'complex1', description: ''}], + parameters: [{name: 'complex1', description: 'A complex number, cell, or range to multiply. Further complex numbers or ranges can be passed as additional arguments.'}], + examples: ['=IMPRODUCT("3+4i", "1-2i")', '=IMPRODUCT(A1:A5)'], }, IMREAL: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns real part of a complex number.', - parameters: [{name: 'complex', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", whose real coefficient is returned.'}], + examples: ['=IMREAL("3+4i")'], }, IMSEC: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the secant of a complex number.', - parameters: [{name: 'complex', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", whose secant is calculated.'}], + examples: ['=IMSEC("3+4i")'], }, IMSECH: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the hyperbolic secant of a complex number.', - parameters: [{name: 'complex', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", whose hyperbolic secant is calculated.'}], + examples: ['=IMSECH("3+4i")'], }, IMSIN: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns sine of a complex number.', - parameters: [{name: 'complex', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", whose sine is calculated.'}], + examples: ['=IMSIN("3+4i")'], }, IMSINH: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns hyperbolic sine of a complex number.', - parameters: [{name: 'complex', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", whose hyperbolic sine is calculated.'}], + examples: ['=IMSINH("3+4i")'], }, IMSQRT: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns a square root of a complex number.', - parameters: [{name: 'complex', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", whose square root is calculated.'}], + examples: ['=IMSQRT("3+4i")', '=IMSQRT("-1")'], }, IMSUB: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Subtracts two complex numbers.', - parameters: [{name: 'complex1', description: ''}, {name: 'complex2', description: ''}], + parameters: [{name: 'complex1', description: 'The complex number to subtract from, given as text such as "3+4i".'}, {name: 'complex2', description: 'The complex number to subtract, given as text such as "1+2i".'}], + examples: ['=IMSUB("3+4i", "1+2i")'], }, IMSUM: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Adds complex numbers.', - parameters: [{name: 'complex1', description: ''}], + parameters: [{name: 'complex1', description: 'A complex number, cell, or range to add. Further complex numbers or ranges can be passed as additional arguments.'}], + examples: ['=IMSUM("3+4i", "1-2i")', '=IMSUM(A1:A5)'], }, IMTAN: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the tangent of a complex number.', - parameters: [{name: 'complex', description: ''}], + parameters: [{name: 'complex', description: 'The complex number, given as text such as "3+4i", whose tangent is calculated.'}], + examples: ['=IMTAN("3+4i")'], }, OCT2BIN: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'The result is the binary number for the octal number entered.', - parameters: [{name: 'number', description: ''}, {name: 'places', description: ''}], + parameters: [{name: 'number', description: 'The octal number (as text, up to 10 digits) to convert to binary.'}, {name: 'places', description: 'The minimum number of digits to pad the result to with leading zeros; if omitted, no padding is applied.'}], + examples: ['=OCT2BIN(14)', '=OCT2BIN(14, 8)'], }, OCT2DEC: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'The result is the decimal number for the octal number entered.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'The octal number (as text, up to 10 digits) to convert to decimal.'}], + examples: ['=OCT2DEC(14)', '=OCT2DEC(17)'], }, OCT2HEX: { category: 'Engineering', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'The result is the hexadecimal number for the octal number entered.', - parameters: [{name: 'number', description: ''}, {name: 'places', description: ''}], + parameters: [{name: 'number', description: 'The octal number (as text, up to 10 digits) to convert to hexadecimal.'}, {name: 'places', description: 'The minimum number of digits to pad the result to with leading zeros; if omitted, no padding is applied.'}], + examples: ['=OCT2HEX(14)', '=OCT2HEX(14, 4)'], }, } diff --git a/src/interpreter/functionMetadata/categories/financial.ts b/src/interpreter/functionMetadata/categories/financial.ts index 3eb88d999..8f6971348 100644 --- a/src/interpreter/functionMetadata/categories/financial.ts +++ b/src/interpreter/functionMetadata/categories/financial.ts @@ -7,152 +7,211 @@ import {FunctionDoc} from '../FunctionDescription' /** * Catalogue entries for the "Financial" category. Generated from `docs/guide/built-in-functions.md` by - * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + * `scripts/hf249-migrate-function-docs.ts`. The `examples` and parameter + * descriptions are hand-authored; re-running that script overwrites them. */ export const FINANCIAL_DOCS: Record = { CUMIPMT: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the cumulative interest paid on a loan between a start period and an end period.', - parameters: [{name: 'rate', description: ''}, {name: 'nper', description: ''}, {name: 'pv', description: ''}, {name: 'start', description: ''}, {name: 'end', description: ''}, {name: 'type', description: ''}], + parameters: [{name: 'rate', description: 'The interest rate per period.'}, {name: 'nper', description: 'The total number of payment periods.'}, {name: 'pv', description: 'The present value, i.e. the loan principal.'}, {name: 'start', description: 'The first period to include in the calculation, numbered starting at 1.'}, {name: 'end', description: 'The last period to include in the calculation; must not be smaller than Start.'}, {name: 'type', description: 'When payments are due: 0 for the end of each period, 1 for the beginning.'}], + examples: ['=CUMIPMT(0.05/12, 60, 20000, 1, 12, 0)', '=CUMIPMT(0.04/12, 360, 200000, 13, 24, 1)'], }, CUMPRINC: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the cumulative principal paid on a loan between a start period and an end period.', - parameters: [{name: 'rate', description: ''}, {name: 'nper', description: ''}, {name: 'pv', description: ''}, {name: 'start', description: ''}, {name: 'end', description: ''}, {name: 'type', description: ''}], + parameters: [{name: 'rate', description: 'The interest rate per period.'}, {name: 'nper', description: 'The total number of payment periods.'}, {name: 'pv', description: 'The present value, i.e. the loan principal.'}, {name: 'start', description: 'The first period to include in the calculation, numbered starting at 1.'}, {name: 'end', description: 'The last period to include in the calculation; must not be smaller than Start.'}, {name: 'type', description: 'When payments are due: 0 for the end of each period, 1 for the beginning.'}], + examples: ['=CUMPRINC(0.05/12, 60, 20000, 1, 12, 0)', '=CUMPRINC(0.04/12, 360, 200000, 13, 24, 1)'], }, DB: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the depreciation of an asset for a period using the fixed-declining balance method.', - parameters: [{name: 'cost', description: ''}, {name: 'salvage', description: ''}, {name: 'life', description: ''}, {name: 'period', description: ''}, {name: 'month', description: ''}], + parameters: [{name: 'cost', description: 'The initial cost of the asset.'}, {name: 'salvage', description: 'The value of the asset at the end of its depreciation.'}, {name: 'life', description: 'The number of periods over which the asset is depreciated.'}, {name: 'period', description: 'The period, in the same units as Life, for which depreciation is calculated.'}, {name: 'month', description: 'The number of months in the first year; defaults to 12 (a full year).'}], + examples: ['=DB(10000, 1000, 6, 2)', '=DB(10000, 1000, 6, 1, 7)'], }, DDB: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the depreciation of an asset for a period using the double-declining balance method.', - parameters: [{name: 'cost', description: ''}, {name: 'salvage', description: ''}, {name: 'life', description: ''}, {name: 'period', description: ''}, {name: 'factor', description: ''}], + parameters: [{name: 'cost', description: 'The initial cost of the asset.'}, {name: 'salvage', description: 'The value of the asset at the end of its depreciation.'}, {name: 'life', description: 'The number of periods over which the asset is depreciated.'}, {name: 'period', description: 'The period, in the same units as Life, for which depreciation is calculated.'}, {name: 'factor', description: 'The rate at which the balance declines; defaults to 2 (double-declining).'}], + examples: ['=DDB(10000, 1000, 6, 2)', '=DDB(10000, 1000, 6, 1, 1.5)'], }, DOLLARDE: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Converts a price entered with a special notation to a price displayed as a decimal number.', - parameters: [{name: 'price', description: ''}, {name: 'fraction', description: ''}], + parameters: [{name: 'price', description: 'The price expressed as an integer part plus a fractional part, e.g. 1.02 for 1 and 2/16.'}, {name: 'fraction', description: 'The denominator used in the fractional notation, e.g. 16 for sixteenths.'}], + examples: ['=DOLLARDE(1.02, 16)', '=DOLLARDE(1.1, 32)'], }, DOLLARFR: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Converts a price displayed as a decimal number to a price entered with a special notation.', - parameters: [{name: 'price', description: ''}, {name: 'fraction', description: ''}], + parameters: [{name: 'price', description: 'The price expressed as a decimal number.'}, {name: 'fraction', description: 'The denominator to use in the fractional notation, e.g. 16 for sixteenths.'}], + examples: ['=DOLLARFR(1.125, 16)', '=DOLLARFR(1.3, 32)'], }, EFFECT: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Calculates the effective annual interest rate from a nominal interest rate and the number of compounding periods per year.', - parameters: [{name: 'nominal_rate', description: ''}, {name: 'npery', description: ''}], + parameters: [{name: 'nominal_rate', description: 'The nominal (stated) annual interest rate.'}, {name: 'npery', description: 'The number of compounding periods per year.'}], + examples: ['=EFFECT(0.1, 4)', '=EFFECT(0.08, 12)'], }, FV: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the future value of an investment.', - parameters: [{name: 'rate', description: ''}, {name: 'nper', description: ''}, {name: 'pmt', description: ''}, {name: 'pv', description: ''}, {name: 'type', description: ''}], + parameters: [{name: 'rate', description: 'The interest rate per period.'}, {name: 'nper', description: 'The total number of payment periods.'}, {name: 'pmt', description: 'The payment made each period; paid-out amounts are negative.'}, {name: 'pv', description: 'The present value, i.e. the lump-sum amount the future payments are worth right now; defaults to 0.'}, {name: 'type', description: 'When payments are due: 0 for the end of each period, 1 for the beginning; defaults to 0.'}], + examples: ['=FV(0.05/12, 60, -100)', '=FV(0.06/12, 24, -200, -500, 1)'], }, FVSCHEDULE: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the future value of an investment based on a rate schedule.', - parameters: [{name: 'pv', description: ''}, {name: 'schedule', description: ''}], + parameters: [{name: 'pv', description: 'The initial present value of the investment.'}, {name: 'schedule', description: 'A range of interest rates applied successively over each period.'}], + examples: ['=FVSCHEDULE(1000, A1:A3)', '=FVSCHEDULE(5000, B2:B5)'], }, IPMT: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the interest portion of a given loan payment in a given payment period.', - parameters: [{name: 'rate', description: ''}, {name: 'per', description: ''}, {name: 'nper', description: ''}, {name: 'pv', description: ''}, {name: 'fv', description: ''}, {name: 'type', description: ''}], + parameters: [{name: 'rate', description: 'The interest rate per period.'}, {name: 'per', description: 'The period, between 1 and Nper, for which the interest portion is calculated.'}, {name: 'nper', description: 'The total number of payment periods.'}, {name: 'pv', description: 'The present value, i.e. the loan principal.'}, {name: 'fv', description: 'The future value, i.e. the desired cash balance after the last payment; defaults to 0.'}, {name: 'type', description: 'When payments are due: 0 for the end of each period, 1 for the beginning; defaults to 0.'}], + examples: ['=IPMT(0.05/12, 1, 60, 20000)', '=IPMT(0.04/12, 12, 360, 200000, 0, 1)'], }, IRR: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the internal rate of return for a series of cash flows.', - parameters: [{name: 'values', description: ''}, {name: 'guess', description: ''}], + parameters: [{name: 'values', description: 'A range of cash flow values; must contain at least one negative and one positive value.'}, {name: 'guess', description: 'An estimated rate used as the starting point for the iterative calculation; defaults to 0.1 (10%).'}], + examples: ['=IRR(A1:A5)', '=IRR(A1:A5, 0.2)'], }, ISPMT: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the interest paid for a given period of an investment with equal principal payments.', - parameters: [{name: 'rate', description: ''}, {name: 'per', description: ''}, {name: 'nper', description: ''}, {name: 'value', description: ''}], + parameters: [{name: 'rate', description: 'The interest rate per period.'}, {name: 'per', description: 'The period for which the interest is calculated.'}, {name: 'nper', description: 'The total number of payment periods.'}, {name: 'value', description: 'The present value, i.e. the loan principal.'}], + examples: ['=ISPMT(0.05/12, 1, 60, 20000)', '=ISPMT(0.04/12, 12, 360, 200000)'], }, MIRR: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the modified internal rate of return for a series of cash flows.', - parameters: [{name: 'flows', description: ''}, {name: 'f_rate', description: ''}, {name: 'r_rate', description: ''}], + parameters: [{name: 'flows', description: 'A range of cash flow values; must contain at least one negative and one positive value.'}, {name: 'f_rate', description: 'The finance rate paid on the money used in the negative cash flows.'}, {name: 'r_rate', description: 'The reinvestment rate received on the positive cash flows.'}], + examples: ['=MIRR(A1:A5, 0.08, 0.1)', '=MIRR(B2:B6, 0.06, 0.12)'], }, NOMINAL: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the nominal interest rate.', - parameters: [{name: 'effect_rate', description: ''}, {name: 'npery', description: ''}], + parameters: [{name: 'effect_rate', description: 'The effective annual interest rate.'}, {name: 'npery', description: 'The number of compounding periods per year.'}], + examples: ['=NOMINAL(0.1, 4)', '=NOMINAL(0.08, 12)'], }, NPER: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the number of periods for an investment assuming periodic, constant payments and a constant interest rate.', - parameters: [{name: 'rate', description: ''}, {name: 'pmt', description: ''}, {name: 'pv', description: ''}, {name: 'fv', description: ''}, {name: 'type', description: ''}], + parameters: [{name: 'rate', description: 'The interest rate per period.'}, {name: 'pmt', description: 'The payment made each period; paid-out amounts are negative.'}, {name: 'pv', description: 'The present value, i.e. the loan principal or initial investment.'}, {name: 'fv', description: 'The future value, i.e. the desired cash balance after the last payment; defaults to 0.'}, {name: 'type', description: 'When payments are due: 0 for the end of each period, 1 for the beginning; defaults to 0.'}], + examples: ['=NPER(0.05/12, -100, 5000)', '=NPER(0.04/12, -200, 8000, 0, 1)'], }, NPV: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns net present value.', - parameters: [{name: 'rate', description: ''}, {name: 'value1', description: ''}], + parameters: [{name: 'rate', description: 'The discount rate applied over one period.'}, {name: 'value1', description: 'A cash flow value, cell reference, or range occurring at the end of a period. Further cash flow values can be passed as additional arguments.'}], + examples: ['=NPV(0.1, -1000, 300, 400, 500)', '=NPV(0.08, A1:A5)'], }, PDURATION: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns number of periods to reach specific value.', - parameters: [{name: 'rate', description: ''}, {name: 'pv', description: ''}, {name: 'fv', description: ''}], + parameters: [{name: 'rate', description: 'The fixed interest rate per period.'}, {name: 'pv', description: 'The present value of the investment.'}, {name: 'fv', description: 'The desired future value of the investment.'}], + examples: ['=PDURATION(0.05, 1000, 2000)', '=PDURATION(0.08, 500, 1500)'], }, PMT: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the periodic payment for a loan.', - parameters: [{name: 'rate', description: ''}, {name: 'nper', description: ''}, {name: 'pv', description: ''}, {name: 'fv', description: ''}, {name: 'type', description: ''}], + parameters: [{name: 'rate', description: 'The interest rate per period.'}, {name: 'nper', description: 'The total number of payment periods.'}, {name: 'pv', description: 'The present value, i.e. the loan principal.'}, {name: 'fv', description: 'The future value, i.e. the desired cash balance after the last payment; defaults to 0.'}, {name: 'type', description: 'When payments are due: 0 for the end of each period, 1 for the beginning; defaults to 0.'}], + examples: ['=PMT(0.05/12, 60, -20000)', '=PMT(0.04/12, 360, -200000, 0, 1)'], }, PPMT: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Calculates the principal portion of a given loan payment.', - parameters: [{name: 'rate', description: ''}, {name: 'per', description: ''}, {name: 'nper', description: ''}, {name: 'pv', description: ''}, {name: 'fv', description: ''}, {name: 'type', description: ''}], + parameters: [{name: 'rate', description: 'The interest rate per period.'}, {name: 'per', description: 'The period, between 1 and Nper, for which the principal portion is calculated.'}, {name: 'nper', description: 'The total number of payment periods.'}, {name: 'pv', description: 'The present value, i.e. the loan principal.'}, {name: 'fv', description: 'The future value, i.e. the desired cash balance after the last payment; defaults to 0.'}, {name: 'type', description: 'When payments are due: 0 for the end of each period, 1 for the beginning; defaults to 0.'}], + examples: ['=PPMT(0.05/12, 1, 60, 20000)', '=PPMT(0.04/12, 12, 360, 200000, 0, 1)'], }, PV: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the present value of an investment.', - parameters: [{name: 'rate', description: ''}, {name: 'nper', description: ''}, {name: 'pmt', description: ''}, {name: 'fv', description: ''}, {name: 'type', description: ''}], + parameters: [{name: 'rate', description: 'The interest rate per period.'}, {name: 'nper', description: 'The total number of payment periods.'}, {name: 'pmt', description: 'The payment made each period; paid-out amounts are negative.'}, {name: 'fv', description: 'The future value, i.e. the desired cash balance after the last payment; defaults to 0.'}, {name: 'type', description: 'When payments are due: 0 for the end of each period, 1 for the beginning; defaults to 0.'}], + examples: ['=PV(0.05/12, 60, -100)', '=PV(0.04/12, 360, -1000, 0, 1)'], }, RATE: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the interest rate per period of an annuity.', - parameters: [{name: 'nper', description: ''}, {name: 'pmt', description: ''}, {name: 'pv', description: ''}, {name: 'fv', description: ''}, {name: 'type', description: ''}, {name: 'guess', description: ''}], + parameters: [{name: 'nper', description: 'The total number of payment periods.'}, {name: 'pmt', description: 'The payment made each period; paid-out amounts are negative.'}, {name: 'pv', description: 'The present value, i.e. the loan principal or initial investment.'}, {name: 'fv', description: 'The future value, i.e. the desired cash balance after the last payment; defaults to 0.'}, {name: 'type', description: 'When payments are due: 0 for the end of each period, 1 for the beginning; defaults to 0.'}, {name: 'guess', description: 'An estimated rate used as the starting point for the iterative calculation; defaults to 0.1 (10%).'}], + examples: ['=RATE(60, -100, 5000)', '=RATE(360, -1000, 200000, 0, 0, 0.05)'], }, RRI: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns an equivalent interest rate for the growth of an investment.', - parameters: [{name: 'nper', description: ''}, {name: 'pv', description: ''}, {name: 'fv', description: ''}], + parameters: [{name: 'nper', description: 'The number of periods over which the investment grows.'}, {name: 'pv', description: 'The present value of the investment.'}, {name: 'fv', description: 'The future value of the investment.'}], + examples: ['=RRI(10, 1000, 2000)', '=RRI(5, 5000, 6000)'], }, SLN: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the depreciation of an asset for one period, based on a straight-line method.', - parameters: [{name: 'cost', description: ''}, {name: 'salvage', description: ''}, {name: 'life', description: ''}], + parameters: [{name: 'cost', description: 'The initial cost of the asset.'}, {name: 'salvage', description: 'The value of the asset at the end of its depreciation.'}, {name: 'life', description: 'The number of periods over which the asset is depreciated.'}], + examples: ['=SLN(10000, 1000, 6)', '=SLN(5000, 500, 10)'], }, SYD: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the "sum-of-years" depreciation for an asset in a period.', - parameters: [{name: 'cost', description: ''}, {name: 'salvage', description: ''}, {name: 'life', description: ''}, {name: 'period', description: ''}], + parameters: [{name: 'cost', description: 'The initial cost of the asset.'}, {name: 'salvage', description: 'The value of the asset at the end of its depreciation.'}, {name: 'life', description: 'The number of periods over which the asset is depreciated.'}, {name: 'period', description: 'The period, in the same units as Life, for which depreciation is calculated.'}], + examples: ['=SYD(10000, 1000, 6, 2)', '=SYD(5000, 500, 10, 1)'], }, TBILLEQ: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the bond-equivalent yield for a Treasury bill.', - parameters: [{name: 'settlement', description: ''}, {name: 'maturity', description: ''}, {name: 'discount', description: ''}], + parameters: [{name: 'settlement', description: 'The settlement (purchase) date of the Treasury bill, as a date serial number.'}, {name: 'maturity', description: 'The maturity date of the Treasury bill, as a date serial number; must be within one year of Settlement.'}, {name: 'discount', description: 'The discount rate of the Treasury bill.'}], + examples: ['=TBILLEQ(DATE(2023,1,1), DATE(2023,6,1), 0.05)', '=TBILLEQ(A1, B1, 0.04)'], }, TBILLPRICE: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the price per $100 face value for a Treasury bill.', - parameters: [{name: 'settlement', description: ''}, {name: 'maturity', description: ''}, {name: 'discount', description: ''}], + parameters: [{name: 'settlement', description: 'The settlement (purchase) date of the Treasury bill, as a date serial number.'}, {name: 'maturity', description: 'The maturity date of the Treasury bill, as a date serial number; must be within one year of Settlement.'}, {name: 'discount', description: 'The discount rate of the Treasury bill.'}], + examples: ['=TBILLPRICE(DATE(2023,1,1), DATE(2023,6,1), 0.05)', '=TBILLPRICE(A1, B1, 0.04)'], }, TBILLYIELD: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the yield for a Treasury bill.', - parameters: [{name: 'settlement', description: ''}, {name: 'maturity', description: ''}, {name: 'price', description: ''}], + parameters: [{name: 'settlement', description: 'The settlement (purchase) date of the Treasury bill, as a date serial number.'}, {name: 'maturity', description: 'The maturity date of the Treasury bill, as a date serial number; must be within one year of Settlement.'}, {name: 'price', description: 'The price per $100 face value of the Treasury bill.'}], + examples: ['=TBILLYIELD(DATE(2023,1,1), DATE(2023,6,1), 98)', '=TBILLYIELD(A1, B1, 99.5)'], }, XNPV: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the net present value for a schedule of cash flows that is not necessarily periodic.', - parameters: [{name: 'rate', description: ''}, {name: 'payments', description: ''}, {name: 'dates', description: ''}], + parameters: [{name: 'rate', description: 'The discount rate applied to the cash flows.'}, {name: 'payments', description: 'A range of cash flow values; paid-out amounts are negative, received amounts are positive.'}, {name: 'dates', description: 'A range of dates, one per payment, that must be the same length as Payments; the first date is the reference point, and every other date must fall on or after it.'}], + examples: ['=XNPV(0.09, A1:A4, B1:B4)', '=XNPV(0.1, C2:C6, D2:D6)'], }, XIRR: { category: 'Financial', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the internal rate of return for a schedule of cash flows that is not necessarily periodic.', - parameters: [{name: 'values', description: ''}, {name: 'dates', description: ''}, {name: 'guess', description: ''}], + parameters: [{name: 'values', description: 'A range of cash flow values; must contain at least one negative and one positive value.'}, {name: 'dates', description: 'A range of payment dates, one per value in Values and the same length; the first date is the reference point and every other date must fall on or after it.'}, {name: 'guess', description: 'An estimated rate used as the starting point for the iterative calculation; defaults to 0.1 (10%).'}], + examples: ['=XIRR(A1:A4, B1:B4)', '=XIRR(A1:A5, B1:B5, 0.1)'], }, } diff --git a/src/interpreter/functionMetadata/categories/information.ts b/src/interpreter/functionMetadata/categories/information.ts index 1799f73a6..85e484294 100644 --- a/src/interpreter/functionMetadata/categories/information.ts +++ b/src/interpreter/functionMetadata/categories/information.ts @@ -7,87 +7,120 @@ import {FunctionDoc} from '../FunctionDescription' /** * Catalogue entries for the "Information" category. Generated from `docs/guide/built-in-functions.md` by - * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + * `scripts/hf249-migrate-function-docs.ts`. The `examples` and parameter + * descriptions are hand-authored; re-running that script overwrites them. */ export const INFORMATION_DOCS: Record = { ISBINARY: { category: 'Information', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns TRUE if provided value is a valid binary number.', - parameters: [{name: 'value', description: ''}], + parameters: [{name: 'value', description: 'The value to test, coerced to a string and checked for containing only the digits 0 and 1 (up to 10 characters).'}], + examples: ['=ISBINARY("1010")', '=ISBINARY(1001)', '=ISBINARY("2")'], }, ISBLANK: { category: 'Information', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns TRUE if the reference to a cell is blank.', - parameters: [{name: 'value', description: ''}], + parameters: [{name: 'value', description: 'The value or cell reference to test; returns TRUE only for a genuinely empty cell, not for a cell holding an empty string or another value.'}], + examples: ['=ISBLANK(A1)', '=ISBLANK("")'], }, ISERR: { category: 'Information', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns TRUE if the value is error value except #N/A!.', - parameters: [{name: 'value', description: ''}], + parameters: [{name: 'value', description: 'The value or expression to test; returns TRUE for any error except #N/A.'}], + examples: ['=ISERR(1/0)', '=ISERR(NA())'], }, ISERROR: { category: 'Information', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns TRUE if the value is general error value.', - parameters: [{name: 'value', description: ''}], + parameters: [{name: 'value', description: 'The value or expression to test; returns TRUE for any error value, including #N/A.'}], + examples: ['=ISERROR(1/0)', '=ISERROR(NA())'], }, ISEVEN: { category: 'Information', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns TRUE if the value is an even integer, or FALSE if the value is odd.', - parameters: [{name: 'value', description: ''}], + parameters: [{name: 'value', description: 'The number to test; it is checked by its remainder without truncation, so a fractional value may return FALSE for both ISEVEN and ISODD.'}], + examples: ['=ISEVEN(4)', '=ISEVEN(A1)'], }, ISFORMULA: { category: 'Information', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Checks whether referenced cell is a formula.', - parameters: [{name: 'value', description: ''}], + parameters: [{name: 'value', description: 'A cell or range reference to check; passing a non-reference expression instead returns the #N/A error.'}], + examples: ['=ISFORMULA(A1)', '=ISFORMULA(B1:B3)'], }, ISLOGICAL: { category: 'Information', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Tests for a logical value (TRUE or FALSE).', - parameters: [{name: 'value', description: ''}], + parameters: [{name: 'value', description: 'The value to test; returns TRUE only when the value is the logical TRUE or FALSE.'}], + examples: ['=ISLOGICAL(TRUE())', '=ISLOGICAL(1<2)', '=ISLOGICAL(1)'], }, ISNA: { category: 'Information', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns TRUE if the value is #N/A! error.', - parameters: [{name: 'value', description: ''}], + parameters: [{name: 'value', description: 'The value or expression to test; returns TRUE only for the #N/A error.'}], + examples: ['=ISNA(NA())', '=ISNA(1/0)'], }, ISNONTEXT: { category: 'Information', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Tests if the cell contents are text or numbers, and returns FALSE if the contents are text.', - parameters: [{name: 'value', description: ''}], + parameters: [{name: 'value', description: 'The value to test; returns FALSE only when the value is text, and TRUE for numbers, logical values, errors, and blank cells.'}], + examples: ['=ISNONTEXT(A1)', '=ISNONTEXT("abc")'], }, ISNUMBER: { category: 'Information', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns TRUE if the value refers to a number.', - parameters: [{name: 'value', description: ''}], + parameters: [{name: 'value', description: 'The value to test; returns TRUE only when the value is a number.'}], + examples: ['=ISNUMBER(1+1)', '=ISNUMBER("abc")'], }, ISODD: { category: 'Information', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns TRUE if the value is odd, or FALSE if the number is even.', - parameters: [{name: 'value', description: ''}], + parameters: [{name: 'value', description: 'The number to test; it is checked by its remainder without truncation, so a fractional value may return FALSE for both ISODD and ISEVEN.'}], + examples: ['=ISODD(3)', '=ISODD(A1)'], }, ISREF: { category: 'Information', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns TRUE if provided value is #REF! error.', - parameters: [{name: 'value', description: ''}], + parameters: [{name: 'value', description: 'The value or expression to test; returns TRUE only when it evaluates to a #REF! (or #CYCLE!) error, not merely because it looks like a reference.'}], + examples: ['=ISREF(A1)', '=ISREF(OFFSET(A1, -1, 0))'], }, ISTEXT: { category: 'Information', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns TRUE if the cell contents reference text.', - parameters: [{name: 'value', description: ''}], + parameters: [{name: 'value', description: 'The value to test; returns TRUE only when the value is text.'}], + examples: ['=ISTEXT("abc")', '=ISTEXT(A1)'], }, NA: { category: 'Information', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns #N/A! error value.', parameters: [], + examples: ['=NA()'], }, SHEET: { category: 'Information', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns sheet number of a given value or a formula sheet number if no argument is provided.', - parameters: [{name: 'value', description: ''}], + parameters: [{name: 'value', description: 'An optional sheet name (as text) or a cell/range reference identifying the sheet to look up; when omitted, returns the number of the sheet containing the formula.'}], + examples: ['=SHEET()', '=SHEET(A1)', '=SHEET("Sheet2")'], }, SHEETS: { category: 'Information', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns number of sheet of a given reference or number of all sheets in workbook when no argument is provided.', - parameters: [{name: 'value', description: ''}], + parameters: [{name: 'value', description: 'An optional cell or range reference; when omitted, returns the total number of sheets in the workbook, otherwise returns 1 for the sheet containing the reference.'}], + examples: ['=SHEETS()', '=SHEETS(A1:B3)'], }, } diff --git a/src/interpreter/functionMetadata/categories/logical.ts b/src/interpreter/functionMetadata/categories/logical.ts index 87a20b9ec..b700d5936 100644 --- a/src/interpreter/functionMetadata/categories/logical.ts +++ b/src/interpreter/functionMetadata/categories/logical.ts @@ -7,62 +7,85 @@ import {FunctionDoc} from '../FunctionDescription' /** * Catalogue entries for the "Logical" category. Generated from `docs/guide/built-in-functions.md` by - * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + * `scripts/hf249-migrate-function-docs.ts`. The `examples` and parameter + * descriptions are hand-authored; re-running that script overwrites them. */ export const LOGICAL_DOCS: Record = { AND: { category: 'Logical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns TRUE if all arguments are TRUE.', - parameters: [{name: 'logical_value1', description: ''}], + parameters: [{name: 'logical_value1', description: 'A logical value, expression, or range to test. Further logical values can be passed as additional arguments; the result is TRUE only if all of them are TRUE.'}], + examples: ['=AND(TRUE(), TRUE())', '=AND(A1>0, A2>0)', '=AND(A1:A5)'], }, FALSE: { category: 'Logical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the logical value FALSE.', parameters: [], + examples: ['=FALSE()'], }, IF: { category: 'Logical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Specifies a logical test to be performed.', - parameters: [{name: 'test', description: ''}, {name: 'then_value', description: ''}, {name: 'otherwise_value', description: ''}], + parameters: [{name: 'test', description: 'The logical expression or value to evaluate.'}, {name: 'then_value', description: 'The value returned when Test evaluates to TRUE.'}, {name: 'otherwise_value', description: 'The value returned when Test evaluates to FALSE. When omitted, FALSE is returned instead.'}], + examples: ['=IF(A1>10, "big", "small")', '=IF(B1="", "empty", B1)'], }, IFERROR: { category: 'Logical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the value if the cell does not contains an error value, or the alternative value if it does.', - parameters: [{name: 'value', description: ''}, {name: 'alternate_value', description: ''}], + parameters: [{name: 'value', description: 'The value or formula checked for an error.'}, {name: 'alternate_value', description: 'The value returned when Value evaluates to any error; otherwise Value itself is returned.'}], + examples: ['=IFERROR(A1/B1, "error")', '=IFERROR(VLOOKUP(A1, B1:C10, 2, FALSE()), "not found")'], }, IFNA: { category: 'Logical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the value if the cell does not contains the #N/A (value not available) error value, or the alternative value if it does.', - parameters: [{name: 'value', description: ''}, {name: 'alternate_value', description: ''}], + parameters: [{name: 'value', description: 'The value or formula checked for the #N/A error.'}, {name: 'alternate_value', description: 'The value returned when Value evaluates to #N/A; other error types and non-error values are returned unchanged.'}], + examples: ['=IFNA(VLOOKUP(A1, B1:C10, 2, FALSE()), "not found")', '=IFNA(A1, "n/a")'], }, IFS: { category: 'Logical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Evaluates multiple logical tests and returns a value that corresponds to the first true condition.', - parameters: [{name: 'condition1', description: ''}, {name: 'value1', description: ''}], + parameters: [{name: 'condition1', description: 'A logical test to evaluate. Further condition/value pairs can be passed as additional arguments and are checked in order.'}, {name: 'value1', description: 'The value returned when the preceding condition is the first one to evaluate to TRUE. Further condition/value pairs can be passed as additional arguments.'}], + examples: ['=IFS(A1>90, "A", A1>80, "B")', '=IFS(A1<0, "negative", A1=0, "zero", A1>0, "positive")'], }, NOT: { category: 'Logical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Complements (inverts) a logical value.', - parameters: [{name: 'logical_value', description: ''}], + parameters: [{name: 'logical_value', description: 'The logical value or expression to invert: TRUE becomes FALSE and vice versa.'}], + examples: ['=NOT(TRUE())', '=NOT(A1>10)'], }, OR: { category: 'Logical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns TRUE if at least one argument is TRUE.', - parameters: [{name: 'logical_value1', description: ''}], + parameters: [{name: 'logical_value1', description: 'A logical value, expression, or range to test. Further logical values can be passed as additional arguments; the result is TRUE if any of them is TRUE.'}], + examples: ['=OR(TRUE(), FALSE())', '=OR(A1>10, A2>10)', '=OR(A1:A5)'], }, SWITCH: { category: 'Logical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Evaluates a list of arguments, consisting of an expression followed by a value.', - parameters: [{name: 'expression1', description: ''}, {name: 'value1', description: ''}, {name: 'expression2', description: ''}], + parameters: [{name: 'expression1', description: 'The expression or value compared against the candidate values that follow.'}, {name: 'value1', description: 'The first candidate value compared to Expression1.'}, {name: 'expression2', description: 'The value returned when the preceding candidate matches Expression1. Further Value/Expression pairs can be passed as additional arguments, and a final unpaired argument is returned as the default when no candidate matches.'}], + examples: ['=SWITCH(A1, 1, "one", 2, "two", "other")', '=SWITCH(WEEKDAY(A1), 1, "Sunday", 7, "Saturday", "weekday")'], }, TRUE: { category: 'Logical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'The logical value is set to TRUE.', parameters: [], + examples: ['=TRUE()'], }, XOR: { category: 'Logical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns true if an odd number of arguments evaluates to TRUE.', - parameters: [{name: 'logical_value1', description: ''}], + parameters: [{name: 'logical_value1', description: 'A logical value, expression, or range to test. Further logical values can be passed as additional arguments; the result is TRUE when an odd number of them are TRUE.'}], + examples: ['=XOR(TRUE(), FALSE())', '=XOR(A1>0, A2>0)'], }, } diff --git a/src/interpreter/functionMetadata/categories/lookup-and-reference.ts b/src/interpreter/functionMetadata/categories/lookup-and-reference.ts index 456e76265..98c44554b 100644 --- a/src/interpreter/functionMetadata/categories/lookup-and-reference.ts +++ b/src/interpreter/functionMetadata/categories/lookup-and-reference.ts @@ -7,72 +7,99 @@ import {FunctionDoc} from '../FunctionDescription' /** * Catalogue entries for the "Lookup and reference" category. Generated from `docs/guide/built-in-functions.md` by - * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + * `scripts/hf249-migrate-function-docs.ts`. The `examples` and parameter + * descriptions are hand-authored; re-running that script overwrites them. */ export const LOOKUP_AND_REFERENCE_DOCS: Record = { ADDRESS: { category: 'Lookup and reference', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns a cell reference as a string.', - parameters: [{name: 'row', description: ''}, {name: 'column', description: ''}, {name: 'absolute_relative_mode', description: ''}, {name: 'use_a1_notation', description: ''}, {name: 'sheet', description: ''}], + parameters: [{name: 'row', description: 'The row number to use in the constructed cell reference.'}, {name: 'column', description: 'The column number to use in the constructed cell reference.'}, {name: 'absolute_relative_mode', description: '1 for a fully absolute reference (default), 2 for absolute row with relative column, 3 for relative row with absolute column, or 4 for a fully relative reference.'}, {name: 'use_a1_notation', description: 'TRUE (default) returns the reference in A1 notation, FALSE returns it in R1C1 notation.'}, {name: 'sheet', description: 'The name of the sheet to prefix the reference with. When omitted, no sheet name is included.'}], + examples: ['=ADDRESS(2, 3)', '=ADDRESS(2, 3, 4)', '=ADDRESS(1, 1, 1, FALSE(), "Sheet2")'], }, CHOOSE: { category: 'Lookup and reference', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Uses an index to return a value from a list of values.', - parameters: [{name: 'index', description: ''}, {name: 'value1', description: ''}], + parameters: [{name: 'index', description: 'The 1-based position of the value to return from the list of values that follow.'}, {name: 'value1', description: 'A value that can be returned when Index selects its position. Further values can be passed as additional arguments to extend the list Index selects from.'}], + examples: ['=CHOOSE(2, "apple", "banana", "cherry")', '=CHOOSE(1, A1, A2, A3)'], }, COLUMN: { category: 'Lookup and reference', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns column number of a given reference or formula reference if argument not provided.', - parameters: [{name: 'reference', description: ''}], + parameters: [{name: 'reference', description: 'A cell reference whose column number is returned. When omitted, returns the column number of the cell containing the formula.'}], + examples: ['=COLUMN(C5)', '=COLUMN()'], }, COLUMNS: { category: 'Lookup and reference', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the number of columns in the given reference.', - parameters: [{name: 'array', description: ''}], + parameters: [{name: 'array', description: 'The range whose number of columns is counted.'}], + examples: ['=COLUMNS(A1:C5)', '=COLUMNS(A1:F1)'], }, FORMULATEXT: { category: 'Lookup and reference', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns a formula in a given cell as a string.', - parameters: [{name: 'reference', description: ''}], + parameters: [{name: 'reference', description: 'The cell reference whose formula is returned as text.'}], + examples: ['=FORMULATEXT(A1)', '=FORMULATEXT(Sheet2!B2)'], }, HLOOKUP: { category: 'Lookup and reference', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Searches horizontally with reference to adjacent cells to the bottom.', - parameters: [{name: 'search_criterion', description: ''}, {name: 'array', description: ''}, {name: 'index', description: ''}, {name: 'sort_order', description: ''}], + parameters: [{name: 'search_criterion', description: 'The value to search for in the first row of Array.'}, {name: 'array', description: 'The range to search, with values compared against its first row.'}, {name: 'index', description: 'The row number within Array (counting from 1) whose value in the matching column is returned.'}, {name: 'sort_order', description: 'TRUE (default) performs an approximate match against ascending-sorted data, FALSE performs an exact match.'}], + examples: ['=HLOOKUP("apple", A1:D5, 3, FALSE())', '=HLOOKUP(5, A1:F2, 2)'], }, HYPERLINK: { category: 'Lookup and reference', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Stores the url in the cell\'s metadata. It can be read using method [`getCellHyperlink`](../api/classes/hyperformula.md#getcellhyperlink)', - parameters: [{name: 'url', description: ''}, {name: 'link_label', description: ''}], + parameters: [{name: 'url', description: 'The URL stored in the cell\'s metadata, readable via getCellHyperlink.'}, {name: 'link_label', description: 'The text displayed in the cell. When omitted, Url is displayed instead.'}], + examples: ['=HYPERLINK("https://hyperformula.handsontable.com")', '=HYPERLINK("https://hyperformula.handsontable.com", "HyperFormula docs")'], }, INDEX: { category: 'Lookup and reference', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the contents of a cell specified by row and column number. The column number is optional and defaults to 1.', - parameters: [{name: 'range', description: ''}, {name: 'row', description: ''}, {name: 'column', description: ''}], + parameters: [{name: 'range', description: 'The range from which a value is returned.'}, {name: 'row', description: 'The row number within Range (counting from 1) of the value to return.'}, {name: 'column', description: 'The column number within Range (counting from 1) of the value to return. Defaults to 1 when omitted.'}], + examples: ['=INDEX(A1:C10, 2, 3)', '=INDEX(A1:A10, 5)'], }, MATCH: { category: 'Lookup and reference', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the relative position of an item in an array that matches a specified value.', - parameters: [{name: 'search_criterion', description: ''}, {name: 'lookup_array', description: ''}, {name: 'match_type', description: ''}], + parameters: [{name: 'search_criterion', description: 'The value to search for in LookupArray.'}, {name: 'lookup_array', description: 'The single row or column of cells to search.'}, {name: 'match_type', description: '1 (default) finds the largest value less than or equal to Searchcriterion in ascending-sorted data, -1 finds the smallest value greater than or equal to it in descending-sorted data, and 0 finds an exact match.'}], + examples: ['=MATCH(5, A1:A10, 0)', '=MATCH("apple", B1:B10)'], }, ROW: { category: 'Lookup and reference', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns row number of a given reference or formula reference if argument not provided.', - parameters: [{name: 'reference', description: ''}], + parameters: [{name: 'reference', description: 'A cell reference whose row number is returned. When omitted, returns the row number of the cell containing the formula.'}], + examples: ['=ROW(B5)', '=ROW()'], }, ROWS: { category: 'Lookup and reference', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the number of rows in the given reference.', - parameters: [{name: 'array', description: ''}], + parameters: [{name: 'array', description: 'The range whose number of rows is counted.'}], + examples: ['=ROWS(A1:C5)', '=ROWS(A1:A9)'], }, VLOOKUP: { category: 'Lookup and reference', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Searches vertically with reference to adjacent cells to the right.', - parameters: [{name: 'search_criterion', description: ''}, {name: 'array', description: ''}, {name: 'index', description: ''}, {name: 'sort_order', description: ''}], + parameters: [{name: 'search_criterion', description: 'The value to search for in the first column of Array.'}, {name: 'array', description: 'The range to search, with values compared against its first column.'}, {name: 'index', description: 'The column number within Array (counting from 1) whose value in the matching row is returned.'}, {name: 'sort_order', description: 'TRUE (default) performs an approximate match against ascending-sorted data, FALSE performs an exact match.'}], + examples: ['=VLOOKUP("apple", A1:B10, 2, FALSE())', '=VLOOKUP(5, A1:C10, 3)'], }, XLOOKUP: { category: 'Lookup and reference', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Searches for a key in a range and returns the item corresponding to the match it finds. If no match exists, then XLOOKUP can return the closest (approximate) match.', - parameters: [{name: 'lookup_value', description: ''}, {name: 'lookup_array', description: ''}, {name: 'return_array', description: ''}, {name: 'if_not_found', description: ''}, {name: 'match_mode', description: ''}, {name: 'search_mode', description: ''}], + parameters: [{name: 'lookup_value', description: 'The value to search for in LookupArray.'}, {name: 'lookup_array', description: 'The single row or column of cells to search.'}, {name: 'return_array', description: 'The range that values are returned from once a match is found; it must align in size with LookupArray.'}, {name: 'if_not_found', description: 'The value returned when no match is found. Defaults to the #N/A error.'}, {name: 'match_mode', description: '0 (default) for an exact match, -1 for an exact match or the next smaller item, 1 for an exact match or the next larger item, or 2 for a wildcard match.'}, {name: 'search_mode', description: '1 (default) searches from first to last, -1 searches from last to first, and 2 or -2 perform a binary search on ascending- or descending-sorted data respectively.'}], + examples: ['=XLOOKUP("apple", A1:A10, B1:B10)', '=XLOOKUP(5, A1:A10, B1:B10, "not found")'], }, } diff --git a/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts b/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts index 29f51f8f7..e31739f3d 100644 --- a/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts +++ b/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts @@ -7,384 +7,525 @@ import {FunctionDoc} from '../FunctionDescription' /** * Catalogue entries for the "Math and trigonometry" category. Generated from `docs/guide/built-in-functions.md` by - * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + * `scripts/hf249-migrate-function-docs.ts`. The `examples` and parameter + * descriptions are hand-authored; re-running that script overwrites them. */ export const MATH_AND_TRIGONOMETRY_DOCS: Record = { ABS: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the absolute value of a number.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A number, or a cell reference to one, whose absolute value is returned.'}], + examples: ['=ABS(-5)', '=ABS(A1)'], }, ACOS: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the inverse trigonometric cosine of a number.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A number between -1 and 1 whose arccosine, in radians, is returned.'}], + examples: ['=ACOS(1)', '=ACOS(0.5)'], }, ACOSH: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the inverse hyperbolic cosine of a number.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A number greater than or equal to 1 whose inverse hyperbolic cosine is returned.'}], + examples: ['=ACOSH(1)', '=ACOSH(10)'], }, ACOT: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the inverse trigonometric cotangent of a number.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A number whose arccotangent, in radians, is returned.'}], + examples: ['=ACOT(1)', '=ACOT(0)'], }, ACOTH: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the inverse hyperbolic cotangent of a number.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A number with an absolute value greater than 1 whose inverse hyperbolic cotangent is returned.'}], + examples: ['=ACOTH(2)', '=ACOTH(-5)'], }, ARABIC: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Converts number from roman form.', - parameters: [{name: 'string', description: ''}], + parameters: [{name: 'string', description: 'A Roman numeral text (e.g. "MCMXC") to convert to its Arabic number equivalent.'}], + examples: ['=ARABIC("MCMXC")', '=ARABIC("IV")'], }, ASIN: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the inverse trigonometric sine of a number.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A number between -1 and 1 whose arcsine, in radians, is returned.'}], + examples: ['=ASIN(1)', '=ASIN(0.5)'], }, ASINH: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the inverse hyperbolic sine of a number.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A number whose inverse hyperbolic sine is returned.'}], + examples: ['=ASINH(1)', '=ASINH(-2.5)'], }, ATAN: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the inverse trigonometric tangent of a number.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A number whose arctangent, in radians, is returned.'}], + examples: ['=ATAN(1)', '=ATAN(0)'], }, ATAN2: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the inverse trigonometric tangent of the specified x and y coordinates.', - parameters: [{name: 'number_x', description: ''}, {name: 'number_y', description: ''}], + parameters: [{name: 'number_x', description: 'The x-coordinate of the point.'}, {name: 'number_y', description: 'The y-coordinate of the point.'}], + examples: ['=ATAN2(1, 1)', '=ATAN2(-1, 2)'], }, ATANH: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the inverse hyperbolic tangent of a number.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A number between -1 and 1 (exclusive) whose inverse hyperbolic tangent is returned.'}], + examples: ['=ATANH(0.5)', '=ATANH(-0.2)'], }, BASE: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Converts a non-negative integer to a specified base into a text from the numbering system.', - parameters: [{name: 'number', description: ''}, {name: 'radix', description: ''}, {name: 'minimum_length', description: ''}], + parameters: [{name: 'number', description: 'The non-negative integer to convert.'}, {name: 'radix', description: 'The base (from 2 to 36) to convert the number into.'}, {name: 'minimum_length', description: 'The minimum length of the returned string; the result is left-padded with zeros when shorter.'}], + examples: ['=BASE(15, 2)', '=BASE(100, 16, 4)'], }, CEILING: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Rounds a number up to the nearest multiple of Significance.', - parameters: [{name: 'number', description: ''}, {name: 'significance', description: ''}], + parameters: [{name: 'number', description: 'The value to round up.'}, {name: 'significance', description: 'The multiple to round up to. When Number is positive, Significance must also be positive; otherwise the result is a #NUM! error.'}], + examples: ['=CEILING(4.3, 1)', '=CEILING(22.5, 5)'], }, 'CEILING.MATH': { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Rounds a number up to the nearest multiple of Significance.', - parameters: [{name: 'number', description: ''}, {name: 'significance', description: ''}, {name: 'mode', description: ''}], + parameters: [{name: 'number', description: 'The value to round up.'}, {name: 'significance', description: 'The multiple to round up to. Defaults to 1 when omitted.'}, {name: 'mode', description: 'For negative numbers, when non-zero, rounds away from zero instead of toward it.'}], + examples: ['=CEILING.MATH(4.3)', '=CEILING.MATH(-4.3, 2, 1)'], }, 'CEILING.PRECISE': { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Rounds a number up to the nearest multiple of Significance.', - parameters: [{name: 'number', description: ''}, {name: 'significance', description: ''}], + parameters: [{name: 'number', description: 'The value to round up.'}, {name: 'significance', description: 'The multiple to round up to; its sign is ignored. Defaults to 1 when omitted.'}], + examples: ['=CEILING.PRECISE(4.3, 1)', '=CEILING.PRECISE(-4.3, 2)'], }, COMBIN: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns number of combinations (without repetitions).', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], + parameters: [{name: 'number1', description: 'The total number of items.'}, {name: 'number2', description: 'The number of items in each combination.'}], + examples: ['=COMBIN(8, 2)', '=COMBIN(52, 5)'], }, COMBINA: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns number of combinations (with repetitions).', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], + parameters: [{name: 'number1', description: 'The total number of items.'}, {name: 'number2', description: 'The number of items in each combination, where an item may repeat.'}], + examples: ['=COMBINA(4, 3)', '=COMBINA(10, 2)'], }, COS: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the cosine of the given angle (in radians).', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'An angle in radians whose cosine is returned.'}], + examples: ['=COS(0)', '=COS(PI())'], }, COSH: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the hyperbolic cosine of the given value.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A number whose hyperbolic cosine is returned.'}], + examples: ['=COSH(0)', '=COSH(1)'], }, COT: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the cotangent of the given angle (in radians).', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A non-zero angle in radians whose cotangent is returned.'}], + examples: ['=COT(1)', '=COT(PI()/4)'], }, COTH: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the hyperbolic cotangent of the given value.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A non-zero number whose hyperbolic cotangent is returned.'}], + examples: ['=COTH(2)', '=COTH(-1)'], }, COUNTUNIQUE: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Counts the number of unique values in a list of specified values and ranges.', - parameters: [{name: 'value1', description: ''}], + parameters: [{name: 'value1', description: 'A value, cell reference, or range to check for uniqueness. Further values or ranges can be passed as additional arguments.'}], + examples: ['=COUNTUNIQUE(1, 2, 2, 3)', '=COUNTUNIQUE(A1:A10)'], }, CSC: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the cosecant of the given angle (in radians).', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A non-zero angle in radians whose cosecant is returned.'}], + examples: ['=CSC(1)', '=CSC(PI()/2)'], }, CSCH: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the hyperbolic cosecant of the given value.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A non-zero number whose hyperbolic cosecant is returned.'}], + examples: ['=CSCH(1)', '=CSCH(-2)'], }, DECIMAL: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Converts text with characters from a number system to a positive integer in the base radix given.', - parameters: [{name: 'text', description: ''}, {name: 'radix', description: ''}], + parameters: [{name: 'text', description: 'The text representation of the number to convert.'}, {name: 'radix', description: 'The base (from 2 to 36) that Text is expressed in.'}], + examples: ['=DECIMAL("1100", 2)', '=DECIMAL("FF", 16)'], }, DEGREES: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Converts radians into degrees.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'An angle in radians to convert to degrees.'}], + examples: ['=DEGREES(PI())', '=DEGREES(1)'], }, EVEN: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Rounds a positive number up to the next even integer and a negative number down to the next even integer.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'The number to round away from zero to the next even integer.'}], + examples: ['=EVEN(3)', '=EVEN(-3)'], }, EXP: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns constant e raised to the power of a number.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'The exponent to which the constant e is raised.'}], + examples: ['=EXP(1)', '=EXP(0)'], }, FACT: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns a factorial of a number.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A non-negative number whose factorial is returned; the value is truncated to an integer.'}], + examples: ['=FACT(5)', '=FACT(0)'], }, FACTDOUBLE: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns a double factorial of a number.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A non-negative number whose double factorial is returned; the value is truncated to an integer.'}], + examples: ['=FACTDOUBLE(6)', '=FACTDOUBLE(7)'], }, FLOOR: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Rounds a number down to the nearest multiple of Significance.', - parameters: [{name: 'number', description: ''}, {name: 'significance', description: ''}], + parameters: [{name: 'number', description: 'The value to round down.'}, {name: 'significance', description: 'The multiple to round down to. When Number is positive, Significance must also be positive; otherwise the result is a #NUM! error.'}], + examples: ['=FLOOR(4.7, 1)', '=FLOOR(22.5, 5)'], }, 'FLOOR.MATH': { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Rounds a number down to the nearest multiple of Significance.', - parameters: [{name: 'number', description: ''}, {name: 'significance', description: ''}, {name: 'mode', description: ''}], + parameters: [{name: 'number', description: 'The value to round down.'}, {name: 'significance', description: 'The multiple to round down to. Defaults to 1 when omitted.'}, {name: 'mode', description: 'For negative numbers, when non-zero, rounds toward zero instead of away from it.'}], + examples: ['=FLOOR.MATH(4.7)', '=FLOOR.MATH(-4.7, 2, 1)'], }, 'FLOOR.PRECISE': { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Rounds a number down to the nearest multiple of Significance.', - parameters: [{name: 'number', description: ''}, {name: 'significance', description: ''}], + parameters: [{name: 'number', description: 'The value to round down.'}, {name: 'significance', description: 'The multiple to round down to; its sign is ignored. Defaults to 1 when omitted.'}], + examples: ['=FLOOR.PRECISE(4.7, 1)', '=FLOOR.PRECISE(-4.7, 2)'], }, GCD: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Computes greatest common divisor of numbers.', - parameters: [{name: 'number1', description: ''}], + parameters: [{name: 'number1', description: 'A non-negative number, cell reference, or range. Further numbers or ranges can be passed as additional arguments.'}], + examples: ['=GCD(12, 18)', '=GCD(24, 36, 60)'], }, INT: { category: 'Math and trigonometry', - shortDescription: 'Rounds a number down to the nearest integer.', - parameters: [{name: 'number', description: ''}], + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', + shortDescription: 'Returns the integer part of a number by discarding its fractional part.', + parameters: [{name: 'number', description: 'The number to convert to an integer by dropping its fractional part (rounding toward zero, so INT(-8.9) is -8).'}], + examples: ['=INT(8.9)', '=INT(-8.9)'], }, LCM: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Computes least common multiple of numbers.', - parameters: [{name: 'number1', description: ''}], + parameters: [{name: 'number1', description: 'A non-negative number, cell reference, or range. Further numbers or ranges can be passed as additional arguments.'}], + examples: ['=LCM(4, 6)', '=LCM(A1:A5)'], }, LN: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the natural logarithm based on the constant e of a number.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A positive number whose natural logarithm is returned.'}], + examples: ['=LN(1)', '=LN(2.718281828)'], }, LOG: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the logarithm of a number to the specified base.', - parameters: [{name: 'number', description: ''}, {name: 'base', description: ''}], + parameters: [{name: 'number', description: 'A positive number whose logarithm is returned.'}, {name: 'base', description: 'The base of the logarithm. Defaults to 10 when omitted.'}], + examples: ['=LOG(100, 10)', '=LOG(8, 2)'], }, LOG10: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the base-10 logarithm of a number.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A positive number whose base-10 logarithm is returned.'}], + examples: ['=LOG10(100)', '=LOG10(1000)'], }, MOD: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the remainder when one integer is divided by another.', - parameters: [{name: 'dividend', description: ''}, {name: 'divisor', description: ''}], + parameters: [{name: 'dividend', description: 'The number to be divided.'}, {name: 'divisor', description: 'The non-zero number to divide by. The result has the same sign as the dividend.'}], + examples: ['=MOD(10, 3)', '=MOD(-7, 2)'], }, MROUND: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Rounds a number to the nearest multiple.', - parameters: [{name: 'number', description: ''}, {name: 'base', description: ''}], + parameters: [{name: 'number', description: 'The value to round.'}, {name: 'base', description: 'The multiple to round Number to; must have the same sign as Number.'}], + examples: ['=MROUND(10, 3)', '=MROUND(-10, -3)'], }, MULTINOMIAL: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns number of multiset combinations.', - parameters: [{name: 'number1', description: ''}], + parameters: [{name: 'number1', description: 'A non-negative number, cell reference, or range. Further numbers or ranges can be passed as additional arguments.'}], + examples: ['=MULTINOMIAL(2, 3, 4)', '=MULTINOMIAL(A1:A3)'], }, ODD: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Rounds a positive number up to the nearest odd integer and a negative number down to the nearest odd integer.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'The number to round away from zero to the next odd integer.'}], + examples: ['=ODD(2)', '=ODD(-2)'], }, PI: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns 3.14159265358979, the value of the mathematical constant PI to 14 decimal places.', parameters: [], + examples: ['=PI()'], }, POWER: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns a number raised to another number.', - parameters: [{name: 'base', description: ''}, {name: 'exponent', description: ''}], + parameters: [{name: 'base', description: 'The number to raise to a power.'}, {name: 'exponent', description: 'The exponent to raise Base to.'}], + examples: ['=POWER(2, 10)', '=POWER(9, 0.5)'], }, PRODUCT: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns product of numbers.', - parameters: [{name: 'number1', description: ''}], + parameters: [{name: 'number1', description: 'A number, cell reference, or range whose values are multiplied together. Further numbers or ranges can be passed as additional arguments.'}], + examples: ['=PRODUCT(2, 3, 4)', '=PRODUCT(A1:A10)'], }, QUOTIENT: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns integer part of a division.', - parameters: [{name: 'dividend', description: ''}, {name: 'divisor', description: ''}], + parameters: [{name: 'dividend', description: 'The number to be divided.'}, {name: 'divisor', description: 'The non-zero number to divide by.'}], + examples: ['=QUOTIENT(10, 3)', '=QUOTIENT(-10, 3)'], }, RADIANS: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Converts degrees to radians.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'An angle in degrees to convert to radians.'}], + examples: ['=RADIANS(180)', '=RADIANS(90)'], }, RAND: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns a random number between 0 and 1.', parameters: [], + examples: ['=RAND()'], }, RANDBETWEEN: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns a random integer between two numbers.', - parameters: [{name: 'lower_bound', description: ''}, {name: 'upper_bound', description: ''}], + parameters: [{name: 'lower_bound', description: 'The smallest integer that can be returned.'}, {name: 'upper_bound', description: 'The largest integer that can be returned.'}], + examples: ['=RANDBETWEEN(1, 10)', '=RANDBETWEEN(-5, 5)'], }, ROMAN: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Converts number to roman form.', - parameters: [{name: 'number', description: ''}, {name: 'mode', description: ''}], + parameters: [{name: 'number', description: 'An integer between 1 and 3999 to convert to a Roman numeral.'}, {name: 'mode', description: 'Controls how concise the result is, from 0 (classic) to 4 (most abbreviated). Defaults to 0 when omitted.'}], + examples: ['=ROMAN(1990)', '=ROMAN(1990, 4)'], }, ROUND: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Rounds a number to a certain number of decimal places.', - parameters: [{name: 'number', description: ''}, {name: 'count', description: ''}], + parameters: [{name: 'number', description: 'The value to round.'}, {name: 'count', description: 'The number of decimal places to round to. Defaults to 0 when omitted; negative values round to the left of the decimal point.'}], + examples: ['=ROUND(3.14159, 2)', '=ROUND(1234.5, -2)'], }, ROUNDDOWN: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Rounds a number down, toward zero, to a certain precision.', - parameters: [{name: 'number', description: ''}, {name: 'count', description: ''}], + parameters: [{name: 'number', description: 'The value to round down toward zero.'}, {name: 'count', description: 'The number of decimal places to round to. Defaults to 0 when omitted; negative values round to the left of the decimal point.'}], + examples: ['=ROUNDDOWN(3.789, 2)', '=ROUNDDOWN(-3.789, 1)'], }, ROUNDUP: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Rounds a number up, away from zero, to a certain precision.', - parameters: [{name: 'number', description: ''}, {name: 'count', description: ''}], + parameters: [{name: 'number', description: 'The value to round up, away from zero.'}, {name: 'count', description: 'The number of decimal places to round to. Defaults to 0 when omitted; negative values round to the left of the decimal point.'}], + examples: ['=ROUNDUP(3.14159, 2)', '=ROUNDUP(-3.14159, 1)'], }, SEC: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the secant of the given angle (in radians).', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'An angle in radians whose secant is returned.'}], + examples: ['=SEC(0)', '=SEC(PI()/4)'], }, SECH: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the hyperbolic secant of the given value.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A number whose hyperbolic secant is returned.'}], + examples: ['=SECH(0)', '=SECH(1)'], }, SERIESSUM: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Evaluates series at a point.', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'number3', description: ''}, {name: 'coefficients', description: ''}], + parameters: [{name: 'number1', description: 'The input value x to the power series.'}, {name: 'number2', description: 'The initial power n to raise x to.'}, {name: 'number3', description: 'The step m by which the power increases for each successive term.'}, {name: 'coefficients', description: 'A range of coefficients multiplying each successive power of x.'}], + examples: ['=SERIESSUM(1, 0, 1, A1:A3)', '=SERIESSUM(2, 1, 2, B1:B4)'], }, SIGN: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns sign of a number.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A number to test; returns 1 for positive, -1 for negative, and 0 for zero.'}], + examples: ['=SIGN(-5)', '=SIGN(0)'], }, SIN: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the sine of the given angle (in radians).', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'An angle in radians whose sine is returned.'}], + examples: ['=SIN(0)', '=SIN(PI()/2)'], }, SINH: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the hyperbolic sine of the given value.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A number whose hyperbolic sine is returned.'}], + examples: ['=SINH(0)', '=SINH(1)'], }, SQRT: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the positive square root of a number.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A non-negative number whose positive square root is returned.'}], + examples: ['=SQRT(16)', '=SQRT(2)'], }, SQRTPI: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns sqrt of number times pi.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A non-negative number to multiply by PI before taking the square root.'}], + examples: ['=SQRTPI(1)', '=SQRTPI(2)'], }, SUBTOTAL: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Computes aggregation using function specified by number.', - parameters: [{name: 'function', description: ''}, {name: 'number1', description: ''}], + parameters: [{name: 'function', description: 'A number (1-11 or 101-111) selecting the aggregation function to apply, e.g. 9 for SUM or 1 for AVERAGE.'}, {name: 'number1', description: 'A number, cell reference, or range to aggregate. Further numbers or ranges can be passed as additional arguments.'}], + examples: ['=SUBTOTAL(9, A1:A10)', '=SUBTOTAL(1, B1:B10)'], }, - // HAND-AUTHORED reference functions (HF-249): SUM and SUMIF carry real parameter descriptions, examples and a - // documentationUrl so the Formula Builder team can test rendering of populated metadata. The migration generator - // (scripts/hf249-migrate-function-docs.ts) does NOT emit `examples`/`documentationUrl`, so DO NOT re-run it over - // this file without merge-preserving these two entries, or they will be silently reset to empty. + // HAND-AUTHORED reference functions (HF-249): SUM and SUMIF carry real parameter descriptions and examples so + // the Formula Builder team can test rendering of populated metadata. SUM: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Sums up the values of the specified cells.', parameters: [{name: 'number1', description: 'A number, cell reference, or range whose values are added together. Further numbers or ranges can be passed as additional arguments.'}], - documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions', examples: ['=SUM(1, 2, 3)', '=SUM(A1:A10)', '=SUM(B1:B5, 100)'], }, SUMIF: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Sums up the values of cells that belong to the specified range and meet the specified condition.', parameters: [ {name: 'range', description: 'The range of cells tested against the criterion.'}, {name: 'criteria', description: 'The condition that selects which cells are summed, e.g. ">5", "apples", or a cell reference.'}, {name: 'sum_range', description: 'The range of cells to sum. When omitted, the cells in Range are summed instead.'}, ], - documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions', examples: ['=SUMIF(A1:A10, ">5")', '=SUMIF(B1:B10, "apples", C1:C10)'], }, SUMIFS: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Sums up the values of cells that belong to the specified range and meet the specified sets of conditions.', - parameters: [{name: 'sum_range', description: ''}, {name: 'criterion_range1', description: ''}, {name: 'criterion1', description: ''}], + parameters: [{name: 'sum_range', description: 'The range of cells to sum.'}, {name: 'criterion_range1', description: 'A range of cells tested against the paired criterion. Further criterion-range/criterion pairs can be passed as additional arguments; only cells that satisfy every pair are summed.'}, {name: 'criterion1', description: 'The condition applied to Criterion_range1, e.g. ">5", "apples", or a cell reference.'}], + examples: ['=SUMIFS(C1:C10, A1:A10, ">5", B1:B10, "apples")'], }, SUMPRODUCT: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Multiplies corresponding elements in the given arrays, and returns the sum of those products.', - parameters: [{name: 'array1', description: ''}], + parameters: [{name: 'array1', description: 'A range whose elements are multiplied element-wise with the corresponding elements of the other arrays before summing. Further same-sized ranges can be passed as additional arguments.'}], + examples: ['=SUMPRODUCT(A1:A5, B1:B5)', '=SUMPRODUCT(A1:A3)'], }, SUMSQ: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the sum of the squares of the arguments', - parameters: [{name: 'number1', description: ''}], + parameters: [{name: 'number1', description: 'A number, cell reference, or range whose values are squared and summed. Further numbers or ranges can be passed as additional arguments.'}], + examples: ['=SUMSQ(3, 4)', '=SUMSQ(A1:A10)'], }, SUMX2MY2: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the sum of the square differences.', - parameters: [{name: 'range1', description: ''}, {name: 'range2', description: ''}], + parameters: [{name: 'range1', description: 'The range providing the first value (x) of each pair.'}, {name: 'range2', description: 'The range, of the same size as Range1, providing the second value (y) of each pair.'}], + examples: ['=SUMX2MY2(A1:A5, B1:B5)'], }, SUMX2PY2: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the sum of the square sums.', - parameters: [{name: 'range1', description: ''}, {name: 'range2', description: ''}], + parameters: [{name: 'range1', description: 'The range providing the first value (x) of each pair.'}, {name: 'range2', description: 'The range, of the same size as Range1, providing the second value (y) of each pair.'}], + examples: ['=SUMX2PY2(A1:A5, B1:B5)'], }, SUMXMY2: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the sum of the square of differences.', - parameters: [{name: 'range1', description: ''}, {name: 'range2', description: ''}], + parameters: [{name: 'range1', description: 'The range providing the first value (x) of each pair.'}, {name: 'range2', description: 'The range, of the same size as Range1, providing the second value (y) of each pair.'}], + examples: ['=SUMXMY2(A1:A5, B1:B5)'], }, TAN: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the tangent of the given angle (in radians).', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'An angle in radians whose tangent is returned.'}], + examples: ['=TAN(0)', '=TAN(PI()/4)'], }, TANH: { category: 'Math and trigonometry', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the hyperbolic tangent of the given value.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A number whose hyperbolic tangent is returned.'}], + examples: ['=TANH(0)', '=TANH(1)'], }, } diff --git a/src/interpreter/functionMetadata/categories/matrix-functions.ts b/src/interpreter/functionMetadata/categories/matrix-functions.ts index fc3f4ded3..8b2ae215a 100644 --- a/src/interpreter/functionMetadata/categories/matrix-functions.ts +++ b/src/interpreter/functionMetadata/categories/matrix-functions.ts @@ -7,27 +7,36 @@ import {FunctionDoc} from '../FunctionDescription' /** * Catalogue entries for the "Matrix functions" category. Generated from `docs/guide/built-in-functions.md` by - * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + * `scripts/hf249-migrate-function-docs.ts`. The `examples` and parameter + * descriptions are hand-authored; re-running that script overwrites them. */ export const MATRIX_FUNCTIONS_DOCS: Record = { MAXPOOL: { category: 'Matrix functions', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Calculates a smaller range which is a maximum of a Window_size, in a given Range, for every Stride element.', - parameters: [{name: 'range', description: ''}, {name: 'window_size', description: ''}, {name: 'stride', description: ''}], + parameters: [{name: 'range', description: 'The range of numeric values to pool; must contain only numbers.'}, {name: 'window_size', description: 'The width and height, in cells, of the square window whose maximum is taken at each step.'}, {name: 'stride', description: 'The number of cells the window moves between steps; defaults to Window_size when omitted.'}], + examples: ['=MAXPOOL(A1:D4, 2)', '=MAXPOOL(A1:D4, 2, 1)'], }, MEDIANPOOL: { category: 'Matrix functions', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Calculates a smaller range which is a median of a Window_size, in a given Range, for every Stride element.', - parameters: [{name: 'range', description: ''}, {name: 'window_size', description: ''}, {name: 'stride', description: ''}], + parameters: [{name: 'range', description: 'The range of numeric values to pool; must contain only numbers.'}, {name: 'window_size', description: 'The width and height, in cells, of the square window whose median is taken at each step.'}, {name: 'stride', description: 'The number of cells the window moves between steps; defaults to Window_size when omitted.'}], + examples: ['=MEDIANPOOL(A1:D4, 2)', '=MEDIANPOOL(A1:D4, 2, 1)'], }, MMULT: { category: 'Matrix functions', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Calculates the array product of two arrays.', - parameters: [{name: 'array1', description: ''}, {name: 'array2', description: ''}], + parameters: [{name: 'array1', description: 'The first range of numbers in the matrix multiplication; its column count must equal the row count of Array2.'}, {name: 'array2', description: 'The second range of numbers in the matrix multiplication; its row count must equal the column count of Array1.'}], + examples: ['=MMULT(A1:B2, D1:E2)', '=MMULT(A1:C2, A4:B6)'], }, TRANSPOSE: { category: 'Matrix functions', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Transposes the rows and columns of an array.', - parameters: [{name: 'array', description: ''}], + parameters: [{name: 'array', description: 'The range of cells whose rows and columns are swapped in the returned array.'}], + examples: ['=TRANSPOSE(A1:C2)', '=TRANSPOSE(A1:A5)'], }, } diff --git a/src/interpreter/functionMetadata/categories/operator.ts b/src/interpreter/functionMetadata/categories/operator.ts index d7a7258b8..92eea6717 100644 --- a/src/interpreter/functionMetadata/categories/operator.ts +++ b/src/interpreter/functionMetadata/categories/operator.ts @@ -7,82 +7,113 @@ import {FunctionDoc} from '../FunctionDescription' /** * Catalogue entries for the "Operator" category. Generated from `docs/guide/built-in-functions.md` by - * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + * `scripts/hf249-migrate-function-docs.ts`. The `examples` and parameter + * descriptions are hand-authored; re-running that script overwrites them. */ export const OPERATOR_DOCS: Record = { 'HF.ADD': { category: 'Operator', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Adds two values.', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], + parameters: [{name: 'number1', description: 'The first number in the addition.'}, {name: 'number2', description: 'The second number, added to Number1.'}], + examples: ['=HF.ADD(2, 3)', '=HF.ADD(A1, B1)'], }, 'HF.CONCAT': { category: 'Operator', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Concatenates two strings.', - parameters: [{name: 'string1', description: ''}, {name: 'string2', description: ''}], + parameters: [{name: 'string1', description: 'The first string in the concatenation.'}, {name: 'string2', description: 'The second string, appended to the end of String1.'}], + examples: ['=HF.CONCAT("Hello, ", "World!")', '=HF.CONCAT(A1, B1)'], }, 'HF.DIVIDE': { category: 'Operator', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Divides two values.', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], + parameters: [{name: 'number1', description: 'The dividend, i.e. the number being divided.'}, {name: 'number2', description: 'The divisor. Dividing by 0 returns the #DIV/0! error.'}], + examples: ['=HF.DIVIDE(10, 2)', '=HF.DIVIDE(A1, B1)'], }, 'HF.EQ': { category: 'Operator', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Tests two values for equality.', - parameters: [{name: 'value1', description: ''}, {name: 'value2', description: ''}], + parameters: [{name: 'value1', description: 'The first value to compare.'}, {name: 'value2', description: 'The second value, compared with Value1; the result is TRUE when the two values are equal.'}], + examples: ['=HF.EQ(5, 5)', '=HF.EQ(A1, B1)'], }, 'HF.GT': { category: 'Operator', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Tests two values for greater-than relation.', - parameters: [{name: 'value1', description: ''}, {name: 'value2', description: ''}], + parameters: [{name: 'value1', description: 'The value tested against Value2.'}, {name: 'value2', description: 'The value that Value1 is compared against; the result is TRUE when Value1 is greater than Value2.'}], + examples: ['=HF.GT(5, 3)', '=HF.GT(A1, B1)'], }, 'HF.GTE': { category: 'Operator', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Tests two values for greater-equal relation.', - parameters: [{name: 'value1', description: ''}, {name: 'value2', description: ''}], + parameters: [{name: 'value1', description: 'The value tested against Value2.'}, {name: 'value2', description: 'The value that Value1 is compared against; the result is TRUE when Value1 is greater than or equal to Value2.'}], + examples: ['=HF.GTE(5, 5)', '=HF.GTE(A1, B1)'], }, 'HF.LT': { category: 'Operator', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Tests two values for less-than relation.', - parameters: [{name: 'value1', description: ''}, {name: 'value2', description: ''}], + parameters: [{name: 'value1', description: 'The value tested against Value2.'}, {name: 'value2', description: 'The value that Value1 is compared against; the result is TRUE when Value1 is less than Value2.'}], + examples: ['=HF.LT(3, 5)', '=HF.LT(A1, B1)'], }, 'HF.LTE': { category: 'Operator', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Tests two values for less-equal relation.', - parameters: [{name: 'value1', description: ''}, {name: 'value2', description: ''}], + parameters: [{name: 'value1', description: 'The value tested against Value2.'}, {name: 'value2', description: 'The value that Value1 is compared against; the result is TRUE when Value1 is less than or equal to Value2.'}], + examples: ['=HF.LTE(5, 5)', '=HF.LTE(A1, B1)'], }, 'HF.MINUS': { category: 'Operator', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Subtracts two values.', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], + parameters: [{name: 'number1', description: 'The number to subtract from.'}, {name: 'number2', description: 'The number subtracted from Number1.'}], + examples: ['=HF.MINUS(10, 4)', '=HF.MINUS(A1, B1)'], }, 'HF.MULTIPLY': { category: 'Operator', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Multiplies two values.', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], + parameters: [{name: 'number1', description: 'The first factor in the multiplication.'}, {name: 'number2', description: 'The second factor, multiplied by Number1.'}], + examples: ['=HF.MULTIPLY(4, 5)', '=HF.MULTIPLY(A1, B1)'], }, 'HF.NE': { category: 'Operator', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Tests two values for inequality.', - parameters: [{name: 'value1', description: ''}, {name: 'value2', description: ''}], + parameters: [{name: 'value1', description: 'The first value to compare.'}, {name: 'value2', description: 'The second value, compared with Value1; the result is TRUE when the two values are not equal.'}], + examples: ['=HF.NE(5, 3)', '=HF.NE(A1, B1)'], }, 'HF.POW': { category: 'Operator', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Computes power of two values.', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}], + parameters: [{name: 'number1', description: 'The base number.'}, {name: 'number2', description: 'The exponent that Number1 is raised to.'}], + examples: ['=HF.POW(2, 3)', '=HF.POW(A1, 2)'], }, 'HF.UMINUS': { category: 'Operator', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Negates the value.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'The number to negate.'}], + examples: ['=HF.UMINUS(5)', '=HF.UMINUS(A1)'], }, 'HF.UNARY_PERCENT': { category: 'Operator', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Applies percent operator.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'The number to convert to a percentage, i.e. divided by 100.'}], + examples: ['=HF.UNARY_PERCENT(50)', '=HF.UNARY_PERCENT(A1)'], }, 'HF.UPLUS': { category: 'Operator', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Applies unary plus.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'The number that the unary plus operator is applied to; the value is returned unchanged.'}], + examples: ['=HF.UPLUS(5)', '=HF.UPLUS(A1)'], }, } diff --git a/src/interpreter/functionMetadata/categories/statistical.ts b/src/interpreter/functionMetadata/categories/statistical.ts index 91751b9e8..d5faf7008 100644 --- a/src/interpreter/functionMetadata/categories/statistical.ts +++ b/src/interpreter/functionMetadata/categories/statistical.ts @@ -7,452 +7,631 @@ import {FunctionDoc} from '../FunctionDescription' /** * Catalogue entries for the "Statistical" category. Generated from `docs/guide/built-in-functions.md` by - * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + * `scripts/hf249-migrate-function-docs.ts`. The `examples` and parameter + * descriptions are hand-authored; re-running that script overwrites them. */ export const STATISTICAL_DOCS: Record = { AVEDEV: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the average deviation of the arguments.', - parameters: [{name: 'number1', description: ''}], + parameters: [{name: 'number1', description: 'A number, cell reference, or range included in the deviation calculation. Further numbers or ranges can be passed as additional arguments.'}], + examples: ['=AVEDEV(1, 2, 3)', '=AVEDEV(A1:A10)'], }, AVERAGE: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the average of the arguments.', - parameters: [{name: 'number1', description: ''}], + parameters: [{name: 'number1', description: 'A number, cell reference, or range whose values are averaged. Further numbers or ranges can be passed as additional arguments.'}], + examples: ['=AVERAGE(1, 2, 3)', '=AVERAGE(A1:A10)'], }, AVERAGEA: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the average of the arguments.', - parameters: [{name: 'value1', description: ''}], + parameters: [{name: 'value1', description: 'A value, cell reference, or range whose values are averaged; text and FALSE are treated as 0, and TRUE as 1. Further values or ranges can be passed as additional arguments.'}], + examples: ['=AVERAGEA(1, 2, TRUE())', '=AVERAGEA(A1:A10)'], }, AVERAGEIF: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the arithmetic mean of all cells in a range that satisfy a given condition.', - parameters: [{name: 'range', description: ''}, {name: 'criterion', description: ''}, {name: 'average_range', description: ''}], + parameters: [{name: 'range', description: 'The range of cells tested against the criterion.'}, {name: 'criterion', description: 'The condition that selects which cells are averaged, e.g. ">5", "apples", or a cell reference.'}, {name: 'average_range', description: 'The range of cells to average. When omitted, the cells in Range are averaged instead.'}], + examples: ['=AVERAGEIF(A1:A10, ">5")', '=AVERAGEIF(B1:B10, "apples", C1:C10)'], }, BESSELI: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns value of Bessel function.', - parameters: [{name: 'x', description: ''}, {name: 'n', description: ''}], + parameters: [{name: 'x', description: 'The value at which the modified Bessel function is evaluated.'}, {name: 'n', description: 'The order of the Bessel function; a non-negative integer.'}], + examples: ['=BESSELI(1.5, 1)'], }, BESSELJ: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns value of Bessel function.', - parameters: [{name: 'x', description: ''}, {name: 'n', description: ''}], + parameters: [{name: 'x', description: 'The value at which the Bessel function is evaluated.'}, {name: 'n', description: 'The order of the Bessel function; a non-negative integer.'}], + examples: ['=BESSELJ(1.9, 2)'], }, BESSELK: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns value of Bessel function.', - parameters: [{name: 'x', description: ''}, {name: 'n', description: ''}], + parameters: [{name: 'x', description: 'The value at which the modified Bessel function is evaluated; must be greater than 0.'}, {name: 'n', description: 'The order of the Bessel function; a non-negative integer.'}], + examples: ['=BESSELK(1.5, 1)'], }, BESSELY: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns value of Bessel function.', - parameters: [{name: 'x', description: ''}, {name: 'n', description: ''}], + parameters: [{name: 'x', description: 'The value at which the Bessel function is evaluated; must be greater than 0.'}, {name: 'n', description: 'The order of the Bessel function; a non-negative integer.'}], + examples: ['=BESSELY(1.5, 1)'], }, 'BETA.DIST': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the density of Beta distribution.', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'number3', description: ''}, {name: 'boolean', description: ''}, {name: 'number4', description: ''}, {name: 'number5', description: ''}], + parameters: [{name: 'number1', description: 'The value at which to evaluate the distribution, within the interval bounded by Number4 and Number5.'}, {name: 'number2', description: 'The alpha shape parameter of the distribution; must be greater than 0.'}, {name: 'number3', description: 'The beta shape parameter of the distribution; must be greater than 0.'}, {name: 'boolean', description: 'TRUE returns the cumulative distribution function; FALSE returns the probability density function.'}, {name: 'number4', description: 'The lower bound of the interval of Number1; defaults to 0 when omitted.'}, {name: 'number5', description: 'The upper bound of the interval of Number1; defaults to 1 when omitted.'}], + examples: ['=BETA.DIST(0.5, 2, 3, TRUE())', '=BETA.DIST(2, 2, 3, TRUE(), 0, 4)'], }, 'BETA.INV': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the inverse Beta distribution value.', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'number3', description: ''}, {name: 'number4', description: ''}, {name: 'number5', description: ''}], + parameters: [{name: 'number1', description: 'The probability associated with the Beta distribution, between 0 and 1.'}, {name: 'number2', description: 'The alpha shape parameter of the distribution; must be greater than 0.'}, {name: 'number3', description: 'The beta shape parameter of the distribution; must be greater than 0.'}, {name: 'number4', description: 'The lower bound of the interval of the result; defaults to 0 when omitted.'}, {name: 'number5', description: 'The upper bound of the interval of the result; defaults to 1 when omitted.'}], + examples: ['=BETA.INV(0.5, 2, 3)', '=BETA.INV(0.25, 2, 3, 0, 4)'], }, 'BINOM.DIST': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns density of binomial distribution.', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'number3', description: ''}, {name: 'boolean', description: ''}], + parameters: [{name: 'number1', description: 'The number of successes in the trials.'}, {name: 'number2', description: 'The total number of independent trials.'}, {name: 'number3', description: 'The probability of success on a single trial.'}, {name: 'boolean', description: 'TRUE returns the cumulative distribution function; FALSE returns the probability mass function.'}], + examples: ['=BINOM.DIST(3, 10, 0.5, FALSE())', '=BINOM.DIST(3, 10, 0.5, TRUE())'], }, 'BINOM.INV': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns inverse binomial distribution value.', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'number3', description: ''}], + parameters: [{name: 'number1', description: 'The total number of Bernoulli trials.'}, {name: 'number2', description: 'The probability of success on a single trial.'}, {name: 'number3', description: 'The criterion probability value; the function returns the smallest value for which the cumulative binomial distribution is greater than or equal to it.'}], + examples: ['=BINOM.INV(10, 0.5, 0.75)'], }, 'CHISQ.DIST': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns value of chi-square distribution.', - parameters: [{name: 'x', description: ''}, {name: 'degrees', description: ''}, {name: 'mode', description: ''}], + parameters: [{name: 'x', description: 'The value at which to evaluate the distribution; must be non-negative.'}, {name: 'degrees', description: 'The number of degrees of freedom.'}, {name: 'mode', description: 'TRUE returns the cumulative distribution function; FALSE returns the probability density function.'}], + examples: ['=CHISQ.DIST(2, 3, TRUE())', '=CHISQ.DIST(2, 3, FALSE())'], }, 'CHISQ.DIST.RT': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns probability of chi-square right-side distribution.', - parameters: [{name: 'x', description: ''}, {name: 'degrees', description: ''}], + parameters: [{name: 'x', description: 'The value at which to evaluate the distribution; must be non-negative.'}, {name: 'degrees', description: 'The number of degrees of freedom.'}], + examples: ['=CHISQ.DIST.RT(2, 3)'], }, 'CHISQ.INV': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns inverse of chi-square distribution.', - parameters: [{name: 'p', description: ''}, {name: 'degrees', description: ''}], + parameters: [{name: 'p', description: 'The probability associated with the chi-square distribution, between 0 and 1.'}, {name: 'degrees', description: 'The number of degrees of freedom.'}], + examples: ['=CHISQ.INV(0.9, 3)'], }, 'CHISQ.INV.RT': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns inverse of chi-square right-side distribution.', - parameters: [{name: 'p', description: ''}, {name: 'degrees', description: ''}], + parameters: [{name: 'p', description: 'The right-tail probability associated with the chi-square distribution, between 0 and 1.'}, {name: 'degrees', description: 'The number of degrees of freedom.'}], + examples: ['=CHISQ.INV.RT(0.1, 3)'], }, 'CHISQ.TEST': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns chisquared-test value for a dataset.', - parameters: [{name: 'array1', description: ''}, {name: 'array2', description: ''}], + parameters: [{name: 'array1', description: 'The range of observed values.'}, {name: 'array2', description: 'The range of expected values, matching the size of Array1.'}], + examples: ['=CHISQ.TEST(A1:B3, D1:E3)'], }, 'CONFIDENCE.NORM': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns upper confidence bound for normal distribution.', - parameters: [{name: 'alpha', description: ''}, {name: 'stdev', description: ''}, {name: 'size', description: ''}], + parameters: [{name: 'alpha', description: 'The significance level used to compute the confidence level, between 0 and 1.'}, {name: 'stdev', description: 'The population standard deviation; must be greater than 0.'}, {name: 'size', description: 'The sample size.'}], + examples: ['=CONFIDENCE.NORM(0.05, 2.5, 50)'], }, 'CONFIDENCE.T': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns upper confidence bound for T distribution.', - parameters: [{name: 'alpha', description: ''}, {name: 'stdev', description: ''}, {name: 'size', description: ''}], + parameters: [{name: 'alpha', description: 'The significance level used to compute the confidence level, between 0 and 1.'}, {name: 'stdev', description: 'The sample standard deviation; must be greater than 0.'}, {name: 'size', description: 'The sample size.'}], + examples: ['=CONFIDENCE.T(0.05, 2.5, 10)'], }, CORREL: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the correlation coefficient between two data sets.', - parameters: [{name: 'data1', description: ''}, {name: 'data2', description: ''}], + parameters: [{name: 'data1', description: 'The first range of numeric values.'}, {name: 'data2', description: 'The second range of numeric values, matching the size of Data1.'}], + examples: ['=CORREL(A1:A10, B1:B10)'], }, COUNT: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Counts how many numbers are in the list of arguments.', - parameters: [{name: 'value1', description: ''}], + parameters: [{name: 'value1', description: 'A number, cell reference, or range counted if it contains a number. Further numbers or ranges can be passed as additional arguments.'}], + examples: ['=COUNT(1, 2, "text")', '=COUNT(A1:A10)'], }, COUNTA: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Counts how many values are in the list of arguments.', - parameters: [{name: 'value1', description: ''}], + parameters: [{name: 'value1', description: 'A value, cell reference, or range counted if it is not empty. Further values or ranges can be passed as additional arguments.'}], + examples: ['=COUNTA(A1:A10)', '=COUNTA(1, "text", TRUE())'], }, COUNTBLANK: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the number of empty cells.', - parameters: [{name: 'range', description: ''}], + parameters: [{name: 'range', description: 'A value, cell reference, or range checked for emptiness. Further values or ranges can be passed as additional arguments.'}], + examples: ['=COUNTBLANK(A1:A10)', '=COUNTBLANK(A1:A10, C1:C10)'], }, COUNTIF: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the number of cells that meet with certain criteria within a cell range.', - parameters: [{name: 'range', description: ''}, {name: 'criteria', description: ''}], + parameters: [{name: 'range', description: 'The range of cells tested against the criteria.'}, {name: 'criteria', description: 'The condition that selects which cells are counted, e.g. ">5", "apples", or a cell reference.'}], + examples: ['=COUNTIF(A1:A10, ">5")', '=COUNTIF(B1:B10, "apples")'], }, COUNTIFS: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the count of rows or columns that meet criteria in multiple ranges.', - parameters: [{name: 'range1', description: ''}, {name: 'criterion1', description: ''}], + parameters: [{name: 'range1', description: 'A range of cells tested against the paired criterion. Further range/criterion pairs can be passed as additional arguments, and only cells meeting every criterion are counted.'}, {name: 'criterion1', description: 'The condition applied to the preceding range, e.g. ">5", "apples", or a cell reference.'}], + examples: ['=COUNTIFS(A1:A10, ">5")', '=COUNTIFS(A1:A10, ">5", B1:B10, "apples")'], }, 'COVARIANCE.P': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the covariance between two data sets, population normalized.', - parameters: [{name: 'data1', description: ''}, {name: 'data2', description: ''}], + parameters: [{name: 'data1', description: 'The first range of numeric values.'}, {name: 'data2', description: 'The second range of numeric values, matching the size of Data1.'}], + examples: ['=COVARIANCE.P(A1:A10, B1:B10)'], }, 'COVARIANCE.S': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the covariance between two data sets, sample normalized.', - parameters: [{name: 'data1', description: ''}, {name: 'data2', description: ''}], + parameters: [{name: 'data1', description: 'The first range of numeric values.'}, {name: 'data2', description: 'The second range of numeric values, matching the size of Data1.'}], + examples: ['=COVARIANCE.S(A1:A10, B1:B10)'], }, DEVSQ: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns sum of squared deviations.', - parameters: [{name: 'number1', description: ''}], + parameters: [{name: 'number1', description: 'A number, cell reference, or range included in the sum of squared deviations. Further numbers or ranges can be passed as additional arguments.'}], + examples: ['=DEVSQ(1, 2, 3)', '=DEVSQ(A1:A10)'], }, 'EXPON.DIST': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns density of a exponential distribution.', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'boolean', description: ''}], + parameters: [{name: 'number1', description: 'The value at which to evaluate the distribution; must be non-negative.'}, {name: 'number2', description: 'The lambda rate parameter of the distribution; must be greater than 0.'}, {name: 'boolean', description: 'TRUE returns the cumulative distribution function; FALSE returns the probability density function.'}], + examples: ['=EXPON.DIST(1, 0.5, TRUE())', '=EXPON.DIST(1, 0.5, FALSE())'], }, 'F.DIST': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns value of F distribution.', - parameters: [{name: 'x', description: ''}, {name: 'degree1', description: ''}, {name: 'degree2', description: ''}, {name: 'mode', description: ''}], + parameters: [{name: 'x', description: 'The value at which to evaluate the distribution; must be non-negative.'}, {name: 'degree1', description: 'The numerator degrees of freedom.'}, {name: 'degree2', description: 'The denominator degrees of freedom.'}, {name: 'mode', description: 'TRUE returns the cumulative distribution function; FALSE returns the probability density function.'}], + examples: ['=F.DIST(2, 3, 10, TRUE())', '=F.DIST(2, 3, 10, FALSE())'], }, 'F.DIST.RT': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns probability of F right-side distribution.', - parameters: [{name: 'x', description: ''}, {name: 'degree1', description: ''}, {name: 'degree2', description: ''}], + parameters: [{name: 'x', description: 'The value at which to evaluate the distribution; must be non-negative.'}, {name: 'degree1', description: 'The numerator degrees of freedom.'}, {name: 'degree2', description: 'The denominator degrees of freedom.'}], + examples: ['=F.DIST.RT(2, 3, 10)'], }, 'F.INV': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns inverse of F distribution.', - parameters: [{name: 'p', description: ''}, {name: 'degree1', description: ''}, {name: 'degree2', description: ''}], + parameters: [{name: 'p', description: 'The probability associated with the F distribution, between 0 and 1.'}, {name: 'degree1', description: 'The numerator degrees of freedom.'}, {name: 'degree2', description: 'The denominator degrees of freedom.'}], + examples: ['=F.INV(0.9, 3, 10)'], }, 'F.INV.RT': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns inverse of F right-side distribution.', - parameters: [{name: 'p', description: ''}, {name: 'degree1', description: ''}, {name: 'degree2', description: ''}], + parameters: [{name: 'p', description: 'The right-tail probability associated with the F distribution, between 0 and 1.'}, {name: 'degree1', description: 'The numerator degrees of freedom.'}, {name: 'degree2', description: 'The denominator degrees of freedom.'}], + examples: ['=F.INV.RT(0.1, 3, 10)'], }, 'F.TEST': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns f-test value for a dataset.', - parameters: [{name: 'array1', description: ''}, {name: 'array2', description: ''}], + parameters: [{name: 'array1', description: 'The first range or array of sample values.'}, {name: 'array2', description: 'The second range or array of sample values.'}], + examples: ['=F.TEST(A1:A10, B1:B10)'], }, FISHER: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns Fisher transformation value.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'The value to transform; must be greater than -1 and less than 1.'}], + examples: ['=FISHER(0.5)'], }, FISHERINV: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns inverse Fisher transformation value.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'The value of the Fisher transformation to invert.'}], + examples: ['=FISHERINV(0.5)'], }, GAMMA: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns value of Gamma function.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'The value at which to evaluate the Gamma function; must not be zero or a negative integer.'}], + examples: ['=GAMMA(5)'], }, 'GAMMA.DIST': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns density of Gamma distribution.', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'number3', description: ''}, {name: 'boolean', description: ''}], + parameters: [{name: 'number1', description: 'The value at which to evaluate the distribution; must be non-negative.'}, {name: 'number2', description: 'The alpha shape parameter of the distribution; must be greater than 0.'}, {name: 'number3', description: 'The beta scale parameter of the distribution; must be greater than 0.'}, {name: 'boolean', description: 'TRUE returns the cumulative distribution function; FALSE returns the probability density function.'}], + examples: ['=GAMMA.DIST(2, 1, 2, TRUE())', '=GAMMA.DIST(2, 1, 2, FALSE())'], }, 'GAMMA.INV': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns inverse Gamma distribution value.', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'number3', description: ''}], + parameters: [{name: 'number1', description: 'The probability associated with the Gamma distribution, between 0 and 1.'}, {name: 'number2', description: 'The alpha shape parameter of the distribution; must be greater than 0.'}, {name: 'number3', description: 'The beta scale parameter of the distribution; must be greater than 0.'}], + examples: ['=GAMMA.INV(0.5, 1, 2)'], }, GAMMALN: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns natural logarithm of Gamma function.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'The value at which to evaluate the natural logarithm of the Gamma function; must be greater than 0.'}], + examples: ['=GAMMALN(5)'], }, GAUSS: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the probability of gaussian variable falling more than this many times standard deviation from mean.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'The number of standard deviations from the mean, Z, of a standard normal variable.'}], + examples: ['=GAUSS(2)'], }, GEOMEAN: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the geometric average.', - parameters: [{name: 'number1', description: ''}], + parameters: [{name: 'number1', description: 'A number, cell reference, or range to average geometrically; all values must be positive, otherwise the result is #NUM!. Further numbers or ranges can be passed as additional arguments.'}], + examples: ['=GEOMEAN(1, 2, 3)', '=GEOMEAN(A1:A10)'], }, HARMEAN: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the harmonic average.', - parameters: [{name: 'number1', description: ''}], + parameters: [{name: 'number1', description: 'A number, cell reference, or range to average harmonically; all values must be positive, otherwise the result is #NUM!. Further numbers or ranges can be passed as additional arguments.'}], + examples: ['=HARMEAN(1, 2, 4)', '=HARMEAN(A1:A10)'], }, 'HYPGEOM.DIST': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns density of hypergeometric distribution.', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'number3', description: ''}, {name: 'number4', description: ''}, {name: 'boolean', description: ''}], + parameters: [{name: 'number1', description: 'The number of successes in the sample.'}, {name: 'number2', description: 'The size of the sample.'}, {name: 'number3', description: 'The number of successes in the population.'}, {name: 'number4', description: 'The size of the population.'}, {name: 'boolean', description: 'TRUE returns the cumulative distribution function; FALSE returns the probability mass function.'}], + examples: ['=HYPGEOM.DIST(1, 4, 8, 20, FALSE())', '=HYPGEOM.DIST(1, 4, 8, 20, TRUE())'], }, LARGE: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns k-th largest value in a range.', - parameters: [{name: 'range', description: ''}, {name: 'k', description: ''}], + parameters: [{name: 'range', description: 'The range of values to evaluate.'}, {name: 'k', description: 'The position, from the largest, of the value to return; 1 returns the largest value.'}], + examples: ['=LARGE(A1:A10, 1)', '=LARGE(A1:A10, 3)'], }, 'LOGNORM.DIST': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns density of lognormal distribution.', - parameters: [{name: 'x', description: ''}, {name: 'mean', description: ''}, {name: 'stddev', description: ''}, {name: 'mode', description: ''}], + parameters: [{name: 'x', description: 'The value at which to evaluate the distribution; must be greater than 0.'}, {name: 'mean', description: 'The mean of the natural logarithm of the distribution.'}, {name: 'stddev', description: 'The standard deviation of the natural logarithm of the distribution; must be greater than 0.'}, {name: 'mode', description: 'TRUE returns the cumulative distribution function; FALSE returns the probability density function.'}], + examples: ['=LOGNORM.DIST(4, 0, 1, TRUE())', '=LOGNORM.DIST(4, 0, 1, FALSE())'], }, 'LOGNORM.INV': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns value of inverse lognormal distribution.', - parameters: [{name: 'p', description: ''}, {name: 'mean', description: ''}, {name: 'stddev', description: ''}], + parameters: [{name: 'p', description: 'The probability associated with the lognormal distribution, between 0 and 1.'}, {name: 'mean', description: 'The mean of the natural logarithm of the distribution.'}, {name: 'stddev', description: 'The standard deviation of the natural logarithm of the distribution; must be greater than 0.'}], + examples: ['=LOGNORM.INV(0.5, 0, 1)'], }, MAX: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the maximum value in a list of arguments.', - parameters: [{name: 'number1', description: ''}], + parameters: [{name: 'number1', description: 'A number, cell reference, or range compared against the current maximum. Further numbers or ranges can be passed as additional arguments.'}], + examples: ['=MAX(1, 2, 3)', '=MAX(A1:A10)'], }, MAXA: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the maximum value in a list of arguments.', - parameters: [{name: 'value1', description: ''}], + parameters: [{name: 'value1', description: 'A value, cell reference, or range compared against the current maximum; text and FALSE are treated as 0, and TRUE as 1. Further values or ranges can be passed as additional arguments.'}], + examples: ['=MAXA(1, 2, TRUE())', '=MAXA(A1:A10)'], }, MAXIFS: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the maximum value of the cells in a range that meet a set of criteria.', - parameters: [{name: 'max_range', description: ''}, {name: 'criterion_range1', description: ''}, {name: 'criterion1', description: ''}], + parameters: [{name: 'max_range', description: 'The range of cells to evaluate for the maximum.'}, {name: 'criterion_range1', description: 'A range of cells tested against the paired criterion. Further range/criterion pairs can be passed as additional arguments, and only cells meeting every criterion are considered.'}, {name: 'criterion1', description: 'The condition applied to the preceding range, e.g. ">5", "apples", or a cell reference.'}], + examples: ['=MAXIFS(A1:A10, B1:B10, ">5")', '=MAXIFS(A1:A10, B1:B10, ">5", C1:C10, "apples")'], }, MEDIAN: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the median of a set of numbers.', - parameters: [{name: 'number1', description: ''}], + parameters: [{name: 'number1', description: 'A number, cell reference, or range included in the median calculation. Further numbers or ranges can be passed as additional arguments.'}], + examples: ['=MEDIAN(1, 2, 3)', '=MEDIAN(A1:A10)'], }, MIN: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the minimum value in a list of arguments.', - parameters: [{name: 'number1', description: ''}], + parameters: [{name: 'number1', description: 'A number, cell reference, or range compared against the current minimum. Further numbers or ranges can be passed as additional arguments.'}], + examples: ['=MIN(1, 2, 3)', '=MIN(A1:A10)'], }, MINA: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the minimum value in a list of arguments.', - parameters: [{name: 'value1', description: ''}], + parameters: [{name: 'value1', description: 'A value, cell reference, or range compared against the current minimum; text and FALSE are treated as 0, and TRUE as 1. Further values or ranges can be passed as additional arguments.'}], + examples: ['=MINA(1, 2, FALSE())', '=MINA(A1:A10)'], }, MINIFS: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the minimum value of the cells in a range that meet a set of criteria.', - parameters: [{name: 'min_range', description: ''}, {name: 'criterion_range1', description: ''}, {name: 'criterion1', description: ''}], + parameters: [{name: 'min_range', description: 'The range of cells to evaluate for the minimum.'}, {name: 'criterion_range1', description: 'A range of cells tested against the paired criterion. Further range/criterion pairs can be passed as additional arguments, and only cells meeting every criterion are considered.'}, {name: 'criterion1', description: 'The condition applied to the preceding range, e.g. ">5", "apples", or a cell reference.'}], + examples: ['=MINIFS(A1:A10, B1:B10, ">5")', '=MINIFS(A1:A10, B1:B10, ">5", C1:C10, "apples")'], }, 'NEGBINOM.DIST': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns density of negative binomial distribution.', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'number3', description: ''}, {name: 'mode', description: ''}], + parameters: [{name: 'number1', description: 'The number of failures.'}, {name: 'number2', description: 'The threshold number of successes.'}, {name: 'number3', description: 'The probability of success on a single trial.'}, {name: 'mode', description: 'TRUE returns the cumulative distribution function; FALSE returns the probability mass function.'}], + examples: ['=NEGBINOM.DIST(3, 5, 0.5, FALSE())', '=NEGBINOM.DIST(3, 5, 0.5, TRUE())'], }, 'NORM.DIST': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns density of normal distribution.', - parameters: [{name: 'x', description: ''}, {name: 'mean', description: ''}, {name: 'stddev', description: ''}, {name: 'mode', description: ''}], + parameters: [{name: 'x', description: 'The value at which to evaluate the distribution.'}, {name: 'mean', description: 'The arithmetic mean of the distribution.'}, {name: 'stddev', description: 'The standard deviation of the distribution; must be greater than 0.'}, {name: 'mode', description: 'TRUE returns the cumulative distribution function; FALSE returns the probability density function.'}], + examples: ['=NORM.DIST(1, 0, 1, TRUE())', '=NORM.DIST(1, 0, 1, FALSE())'], }, 'NORM.INV': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns value of inverse normal distribution.', - parameters: [{name: 'p', description: ''}, {name: 'mean', description: ''}, {name: 'stddev', description: ''}], + parameters: [{name: 'p', description: 'The probability associated with the normal distribution, between 0 and 1.'}, {name: 'mean', description: 'The arithmetic mean of the distribution.'}, {name: 'stddev', description: 'The standard deviation of the distribution; must be greater than 0.'}], + examples: ['=NORM.INV(0.5, 0, 1)'], }, 'NORM.S.DIST': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns density of normal distribution.', - parameters: [{name: 'x', description: ''}, {name: 'mode', description: ''}], + parameters: [{name: 'x', description: 'The value at which to evaluate the standard normal distribution.'}, {name: 'mode', description: 'TRUE returns the cumulative distribution function; FALSE returns the probability density function.'}], + examples: ['=NORM.S.DIST(1, TRUE())', '=NORM.S.DIST(1, FALSE())'], }, 'NORM.S.INV': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns value of inverse normal distribution.', - parameters: [{name: 'p', description: ''}], + parameters: [{name: 'p', description: 'The probability associated with the standard normal distribution, between 0 and 1.'}], + examples: ['=NORM.S.INV(0.5)'], }, 'PERCENTILE.EXC': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the k-th percentile of values in a range, exclusive of 0 and 1.', - parameters: [{name: 'data', description: ''}, {name: 'k', description: ''}], + parameters: [{name: 'data', description: 'The range of values to evaluate.'}, {name: 'k', description: 'The percentile to return, exclusive of 0 and 1, e.g. 0.25.'}], + examples: ['=PERCENTILE.EXC(A1:A10, 0.25)'], }, 'PERCENTILE.INC': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the k-th percentile of values in a range, inclusive of 0 and 1.', - parameters: [{name: 'data', description: ''}, {name: 'k', description: ''}], + parameters: [{name: 'data', description: 'The range of values to evaluate.'}, {name: 'k', description: 'The percentile to return, inclusive of 0 and 1, e.g. 0.9.'}], + examples: ['=PERCENTILE.INC(A1:A10, 0.9)'], }, PHI: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns probability density of normal distribution.', - parameters: [{name: 'x', description: ''}], + parameters: [{name: 'x', description: 'The value at which to evaluate the standard normal probability density function.'}], + examples: ['=PHI(1)'], }, 'POISSON.DIST': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns density of Poisson distribution.', - parameters: [{name: 'x', description: ''}, {name: 'mean', description: ''}, {name: 'mode', description: ''}], + parameters: [{name: 'x', description: 'The number of events; must be non-negative.'}, {name: 'mean', description: 'The expected number of events; must be non-negative.'}, {name: 'mode', description: 'TRUE returns the cumulative distribution function; FALSE returns the probability mass function.'}], + examples: ['=POISSON.DIST(3, 5, FALSE())', '=POISSON.DIST(3, 5, TRUE())'], }, 'QUARTILE.EXC': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the quartile of a data set, based on exclusive percentile values.', - parameters: [{name: 'data', description: ''}, {name: 'quart', description: ''}], + parameters: [{name: 'data', description: 'The range of values to evaluate.'}, {name: 'quart', description: 'The quartile to return, exclusive of 0 and 4, an integer from 1 to 3.'}], + examples: ['=QUARTILE.EXC(A1:A10, 1)'], }, 'QUARTILE.INC': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the quartile of a data set, based on inclusive percentile values.', - parameters: [{name: 'data', description: ''}, {name: 'quart', description: ''}], + parameters: [{name: 'data', description: 'The range of values to evaluate.'}, {name: 'quart', description: 'The quartile to return, inclusive of 0 and 4, an integer from 0 to 4.'}], + examples: ['=QUARTILE.INC(A1:A10, 3)'], }, RSQ: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the squared correlation coefficient between two data sets.', - parameters: [{name: 'data1', description: ''}, {name: 'data2', description: ''}], + parameters: [{name: 'data1', description: 'The range of dependent (y) values.'}, {name: 'data2', description: 'The range of independent (x) values, matching the size of Data1.'}], + examples: ['=RSQ(A1:A10, B1:B10)'], }, SKEW: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns skewness of a sample.', - parameters: [{name: 'number1', description: ''}], + parameters: [{name: 'number1', description: 'A number, cell reference, or range included in the sample skewness calculation. Further numbers or ranges can be passed as additional arguments.'}], + examples: ['=SKEW(1, 2, 3, 10)', '=SKEW(A1:A10)'], }, 'SKEW.P': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns skewness of a population.', - parameters: [{name: 'number1', description: ''}], + parameters: [{name: 'number1', description: 'A number, cell reference, or range included in the population skewness calculation. Further numbers or ranges can be passed as additional arguments.'}], + examples: ['=SKEW.P(1, 2, 3, 10)', '=SKEW.P(A1:A10)'], }, SLOPE: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the slope of a linear regression line.', - parameters: [{name: 'array1', description: ''}, {name: 'array2', description: ''}], + parameters: [{name: 'array1', description: 'The range of dependent (y) values.'}, {name: 'array2', description: 'The range of independent (x) values, matching the size of Array1.'}], + examples: ['=SLOPE(A1:A10, B1:B10)'], }, SMALL: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns k-th smallest value in a range.', - parameters: [{name: 'range', description: ''}, {name: 'k', description: ''}], + parameters: [{name: 'range', description: 'The range of values to evaluate.'}, {name: 'k', description: 'The position, from the smallest, of the value to return; 1 returns the smallest value.'}], + examples: ['=SMALL(A1:A10, 1)', '=SMALL(A1:A10, 3)'], }, STANDARDIZE: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns normalized value wrt expected value and standard deviation.', - parameters: [{name: 'x', description: ''}, {name: 'mean', description: ''}, {name: 'stddev', description: ''}], + parameters: [{name: 'x', description: 'The value to normalize.'}, {name: 'mean', description: 'The arithmetic mean of the distribution.'}, {name: 'stddev', description: 'The standard deviation of the distribution; must be greater than 0.'}], + examples: ['=STANDARDIZE(5, 3, 2)'], }, 'STDEV.P': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns standard deviation of a population.', - parameters: [{name: 'value1', description: ''}], + parameters: [{name: 'value1', description: 'A number, cell reference, or range included in the population standard deviation calculation. Further values or ranges can be passed as additional arguments.'}], + examples: ['=STDEV.P(1, 2, 3)', '=STDEV.P(A1:A10)'], }, 'STDEV.S': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns standard deviation of a sample.', - parameters: [{name: 'value1', description: ''}], + parameters: [{name: 'value1', description: 'A number, cell reference, or range included in the sample standard deviation calculation. Further values or ranges can be passed as additional arguments.'}], + examples: ['=STDEV.S(1, 2, 3)', '=STDEV.S(A1:A10)'], }, STDEVA: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns standard deviation of a sample.', - parameters: [{name: 'value1', description: ''}], + parameters: [{name: 'value1', description: 'A value, cell reference, or range included in the sample standard deviation calculation; text and FALSE are treated as 0, and TRUE as 1. Further values or ranges can be passed as additional arguments.'}], + examples: ['=STDEVA(1, TRUE(), 3)', '=STDEVA(A1:A10)'], }, STDEVPA: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns standard deviation of a population.', - parameters: [{name: 'value1', description: ''}], + parameters: [{name: 'value1', description: 'A value, cell reference, or range included in the population standard deviation calculation; text and FALSE are treated as 0, and TRUE as 1. Further values or ranges can be passed as additional arguments.'}], + examples: ['=STDEVPA(1, TRUE(), 3)', '=STDEVPA(A1:A10)'], }, STEYX: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns standard error for predicted of the predicted y value for each x value.', - parameters: [{name: 'array1', description: ''}, {name: 'array2', description: ''}], + parameters: [{name: 'array1', description: 'The range of dependent (y) values.'}, {name: 'array2', description: 'The range of independent (x) values, matching the size of Array1.'}], + examples: ['=STEYX(A1:A10, B1:B10)'], }, 'T.DIST': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns density of Student-t distribution.', - parameters: [{name: 'x', description: ''}, {name: 'degrees', description: ''}, {name: 'mode', description: ''}], + parameters: [{name: 'x', description: 'The value at which to evaluate the distribution.'}, {name: 'degrees', description: 'The number of degrees of freedom.'}, {name: 'mode', description: 'TRUE returns the cumulative distribution function; FALSE returns the probability density function.'}], + examples: ['=T.DIST(1, 10, TRUE())', '=T.DIST(1, 10, FALSE())'], }, 'T.DIST.2T': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns density of Student-t distribution, both-sided.', - parameters: [{name: 'x', description: ''}, {name: 'degrees', description: ''}], + parameters: [{name: 'x', description: 'The value at which to evaluate the distribution; must be non-negative.'}, {name: 'degrees', description: 'The number of degrees of freedom.'}], + examples: ['=T.DIST.2T(1, 10)'], }, 'T.DIST.RT': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns density of Student-t distribution, right-tailed.', - parameters: [{name: 'x', description: ''}, {name: 'degrees', description: ''}], + parameters: [{name: 'x', description: 'The value at which to evaluate the distribution.'}, {name: 'degrees', description: 'The number of degrees of freedom.'}], + examples: ['=T.DIST.RT(1, 10)'], }, 'T.INV': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns inverse Student-t distribution.', - parameters: [{name: 'p', description: ''}, {name: 'degrees', description: ''}], + parameters: [{name: 'p', description: 'The probability associated with the left-tailed Student-t distribution, between 0 and 1.'}, {name: 'degrees', description: 'The number of degrees of freedom.'}], + examples: ['=T.INV(0.9, 10)'], }, 'T.INV.2T': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns inverse Student-t distribution, both-sided.', - parameters: [{name: 'p', description: ''}, {name: 'degrees', description: ''}], + parameters: [{name: 'p', description: 'The probability associated with the two-tailed Student-t distribution, between 0 and 1.'}, {name: 'degrees', description: 'The number of degrees of freedom.'}], + examples: ['=T.INV.2T(0.1, 10)'], }, 'T.TEST': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns t-test value for a dataset.', - parameters: [{name: 'array1', description: ''}, {name: 'array2', description: ''}, {name: 'tails', description: ''}, {name: 'type', description: ''}], + parameters: [{name: 'array1', description: 'The first range or array of sample values.'}, {name: 'array2', description: 'The second range or array of sample values.'}, {name: 'tails', description: 'The number of distribution tails to use: 1 for a one-tailed test, or 2 for a two-tailed test.'}, {name: 'type', description: 'The kind of t-test to perform: 1 for paired, 2 for two-sample equal variance, or 3 for two-sample unequal variance.'}], + examples: ['=T.TEST(A1:A10, B1:B10, 2, 1)'], }, TDIST: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns density of Student-t distribution, both-sided or right-tailed.', - parameters: [{name: 'x', description: ''}, {name: 'degrees', description: ''}, {name: 'mode', description: ''}], + parameters: [{name: 'x', description: 'The value at which to evaluate the distribution; must be non-negative.'}, {name: 'degrees', description: 'The number of degrees of freedom.'}, {name: 'mode', description: 'The number of distribution tails to return: 1 for right-tailed, or 2 for two-tailed.'}], + examples: ['=TDIST(1, 10, 1)', '=TDIST(1, 10, 2)'], }, 'VAR.P': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns variance of a population.', - parameters: [{name: 'value1', description: ''}], + parameters: [{name: 'value1', description: 'A number, cell reference, or range included in the population variance calculation. Further values or ranges can be passed as additional arguments.'}], + examples: ['=VAR.P(1, 2, 3)', '=VAR.P(A1:A10)'], }, 'VAR.S': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns variance of a sample.', - parameters: [{name: 'value1', description: ''}], + parameters: [{name: 'value1', description: 'A number, cell reference, or range included in the sample variance calculation. Further values or ranges can be passed as additional arguments.'}], + examples: ['=VAR.S(1, 2, 3)', '=VAR.S(A1:A10)'], }, VARA: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns variance of a sample.', - parameters: [{name: 'value1', description: ''}], + parameters: [{name: 'value1', description: 'A value, cell reference, or range included in the sample variance calculation; text and FALSE are treated as 0, and TRUE as 1. Further values or ranges can be passed as additional arguments.'}], + examples: ['=VARA(1, TRUE(), 3)', '=VARA(A1:A10)'], }, VARPA: { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns variance of a population.', - parameters: [{name: 'value1', description: ''}], + parameters: [{name: 'value1', description: 'A value, cell reference, or range included in the population variance calculation; text and FALSE are treated as 0, and TRUE as 1. Further values or ranges can be passed as additional arguments.'}], + examples: ['=VARPA(1, TRUE(), 3)', '=VARPA(A1:A10)'], }, 'WEIBULL.DIST': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns density of Weibull distribution.', - parameters: [{name: 'number1', description: ''}, {name: 'number2', description: ''}, {name: 'number3', description: ''}, {name: 'boolean', description: ''}], + parameters: [{name: 'number1', description: 'The value at which to evaluate the distribution; must be non-negative.'}, {name: 'number2', description: 'The alpha shape parameter of the distribution; must be greater than 0.'}, {name: 'number3', description: 'The beta scale parameter of the distribution; must be greater than 0.'}, {name: 'boolean', description: 'TRUE returns the cumulative distribution function; FALSE returns the probability density function.'}], + examples: ['=WEIBULL.DIST(2, 1, 2, TRUE())', '=WEIBULL.DIST(2, 1, 2, FALSE())'], }, 'Z.TEST': { category: 'Statistical', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns z-test value for a dataset.', - parameters: [{name: 'array', description: ''}, {name: 'x', description: ''}, {name: 'sigma', description: ''}], + parameters: [{name: 'array', description: 'The range or array of sample values to test against.'}, {name: 'x', description: 'The value to test.'}, {name: 'sigma', description: 'The known population standard deviation; when omitted, the sample standard deviation of Array is used instead.'}], + examples: ['=Z.TEST(A1:A10, 5)', '=Z.TEST(A1:A10, 5, 2)'], }, } diff --git a/src/interpreter/functionMetadata/categories/text.ts b/src/interpreter/functionMetadata/categories/text.ts index b07c2347f..34dcbc075 100644 --- a/src/interpreter/functionMetadata/categories/text.ts +++ b/src/interpreter/functionMetadata/categories/text.ts @@ -7,137 +7,190 @@ import {FunctionDoc} from '../FunctionDescription' /** * Catalogue entries for the "Text" category. Generated from `docs/guide/built-in-functions.md` by - * `scripts/hf249-migrate-function-docs.ts`; parameter descriptions are authored in a later phase. + * `scripts/hf249-migrate-function-docs.ts`. The `examples` and parameter + * descriptions are hand-authored; re-running that script overwrites them. */ export const TEXT_DOCS: Record = { CHAR: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Converts a number into a character according to the current code table.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'A code between 1 and 255 that identifies the character to return.'}], + examples: ['=CHAR(65)', '=CHAR(97)'], }, CLEAN: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns text that has been "cleaned" of line breaks and other non-printable characters.', - parameters: [{name: 'text', description: ''}], + parameters: [{name: 'text', description: 'The text to strip of non-printable characters.'}], + examples: ['=CLEAN(A1)', '=CLEAN("Hello"&CHAR(10)&"World")'], }, CODE: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns a numeric code for the first character in a text string.', - parameters: [{name: 'text', description: ''}], + parameters: [{name: 'text', description: 'The text whose first character\'s numeric code is returned.'}], + examples: ['=CODE("A")', '=CODE(A1)'], }, CONCATENATE: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Combines several text strings into one string.', - parameters: [{name: 'text1', description: ''}], + parameters: [{name: 'text1', description: 'A text value, cell reference, or range to include in the joined string. Further text values or ranges can be passed as additional arguments and are appended in order.'}], + examples: ['=CONCATENATE("Hello", " ", "World")', '=CONCATENATE(A1, A2, A3)'], }, EXACT: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns TRUE if both text strings are exactly the same.', - parameters: [{name: 'text1', description: ''}, {name: 'text2', description: ''}], + parameters: [{name: 'text1', description: 'The first text value to compare.'}, {name: 'text2', description: 'The second text value to compare, matched case-sensitively against Text1.'}], + examples: ['=EXACT("Apple", "apple")', '=EXACT(A1, B1)'], }, FIND: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the location of one text string inside another.', - parameters: [{name: 'text1', description: ''}, {name: 'text2', description: ''}, {name: 'number', description: ''}], + parameters: [{name: 'text1', description: 'The text to search for. The search is case-sensitive.'}, {name: 'text2', description: 'The text to search within.'}, {name: 'number', description: 'The 1-based character position in Text2 at which to start searching. Defaults to 1.'}], + examples: ['=FIND("o", "Hello World")', '=FIND("o", "Hello World", 6)'], }, LEFT: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Extracts a given number of characters from the left side of a text string.', - parameters: [{name: 'text', description: ''}, {name: 'number', description: ''}], + parameters: [{name: 'text', description: 'The text to extract characters from.'}, {name: 'number', description: 'The number of characters to extract, counting from the left. Defaults to 1.'}], + examples: ['=LEFT("Hello", 2)', '=LEFT(A1)'], }, LEN: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns length of a given text.', - parameters: [{name: 'text', description: ''}], + parameters: [{name: 'text', description: 'The text whose number of characters is counted.'}], + examples: ['=LEN("Hello")', '=LEN(A1)'], }, LOWER: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns text converted to lowercase.', - parameters: [{name: 'text', description: ''}], + parameters: [{name: 'text', description: 'The text to convert to lowercase.'}], + examples: ['=LOWER("HELLO")', '=LOWER(A1)'], }, MID: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns substring of a given length starting from Start_position.', - parameters: [{name: 'text', description: ''}, {name: 'start_position', description: ''}, {name: 'length', description: ''}], + parameters: [{name: 'text', description: 'The text to extract a substring from.'}, {name: 'start_position', description: 'The 1-based position of the first character to extract.'}, {name: 'length', description: 'The number of characters to extract, starting at Start_position.'}], + examples: ['=MID("Hello World", 7, 5)', '=MID(A1, 1, 3)'], }, N: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Converts a value to a number.', - parameters: [{name: 'value', description: ''}], + parameters: [{name: 'value', description: 'The value to convert: numbers and dates return themselves, TRUE/FALSE return 1/0, and text or empty values return 0.'}], + examples: ['=N(TRUE())', '=N("5")', '=N(A1)'], }, PROPER: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Capitalizes words given text string.', - parameters: [{name: 'text', description: ''}], + parameters: [{name: 'text', description: 'The text whose words are capitalized, with the first letter of each word converted to uppercase and the rest to lowercase.'}], + examples: ['=PROPER("hello world")', '=PROPER(A1)'], }, REPLACE: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Replaces substring of a text of a given length that starts at given position.', - parameters: [{name: 'text', description: ''}, {name: 'start_position', description: ''}, {name: 'length', description: ''}, {name: 'new_text', description: ''}], + parameters: [{name: 'text', description: 'The text in which characters are replaced.'}, {name: 'start_position', description: 'The 1-based position of the first character to replace.'}, {name: 'length', description: 'The number of characters to replace, starting at Start_position.'}, {name: 'new_text', description: 'The text that replaces the removed characters.'}], + examples: ['=REPLACE("Hello World", 7, 5, "There")', '=REPLACE(A1, 1, 3, "New")'], }, REPT: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Repeats text a given number of times.', - parameters: [{name: 'text', description: ''}, {name: 'number', description: ''}], + parameters: [{name: 'text', description: 'The text to repeat.'}, {name: 'number', description: 'The number of times to repeat Text.'}], + examples: ['=REPT("ab", 3)', '=REPT(A1, 2)'], }, RIGHT: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Extracts a given number of characters from the right side of a text string.', - parameters: [{name: 'text', description: ''}, {name: 'number', description: ''}], + parameters: [{name: 'text', description: 'The text to extract characters from.'}, {name: 'number', description: 'The number of characters to extract, counting from the right. Defaults to 1.'}], + examples: ['=RIGHT("Hello", 2)', '=RIGHT(A1)'], }, SEARCH: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the location of Search_string inside Text. Case-insensitive. Allows the use of wildcards.', - parameters: [{name: 'search_string', description: ''}, {name: 'text', description: ''}, {name: 'start_position', description: ''}], + parameters: [{name: 'search_string', description: 'The text to search for. The search is case-insensitive and may contain "?" and "*" wildcards.'}, {name: 'text', description: 'The text to search within.'}, {name: 'start_position', description: 'The 1-based character position in Text at which to start searching. Defaults to 1.'}], + examples: ['=SEARCH("o", "Hello World")', '=SEARCH("w*d", "Hello World")'], }, SPLIT: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Divides the provided text using the space character as a separator and returns the substring at the zero-based position specified by the second argument. For example, SPLIT("Lorem ipsum", 0) returns "Lorem" and SPLIT("Lorem ipsum", 1) returns "ipsum".', - parameters: [{name: 'text', description: ''}, {name: 'index', description: ''}], + parameters: [{name: 'text', description: 'The text to split on the space character.'}, {name: 'index', description: 'The zero-based position of the chunk to return after splitting.'}], + examples: ['=SPLIT("Lorem ipsum", 0)', '=SPLIT(A1, 1)'], }, SUBSTITUTE: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns string where occurrences of Old_text are replaced by New_text. Replaces only specific occurrence if last parameter is provided.', - parameters: [{name: 'text', description: ''}, {name: 'old_text', description: ''}, {name: 'new_text', description: ''}, {name: 'occurrence', description: ''}], + parameters: [{name: 'text', description: 'The text in which occurrences of Old_text are replaced.'}, {name: 'old_text', description: 'The text to search for and replace.'}, {name: 'new_text', description: 'The text that replaces each matched occurrence of Old_text.'}, {name: 'occurrence', description: 'The 1-based occurrence of Old_text to replace. When omitted, every occurrence is replaced.'}], + examples: ['=SUBSTITUTE("a-b-c", "-", ":")', '=SUBSTITUTE("a-b-c", "-", ":", 2)'], }, T: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns text if given value is text, empty string otherwise.', - parameters: [{name: 'value', description: ''}], + parameters: [{name: 'value', description: 'The value to check; returned unchanged if it is text, otherwise an empty string is returned.'}], + examples: ['=T("Hello")', '=T(A1)', '=T(123)'], }, TEXT: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Converts a number into text according to a given format. By default it accepts the same formats as the dateFormats option, and can be further customized with the stringifyDateTime and stringifyCurrency options.', - parameters: [{name: 'number', description: ''}, {name: 'format', description: ''}], + parameters: [{name: 'number', description: 'The number or date serial value to format as text.'}, {name: 'format', description: 'The format pattern used to render Number as text, e.g. "0.00" or "YYYY-MM-DD".'}], + examples: ['=TEXT(1234.5, "0.00")', '=TEXT(TODAY(), "YYYY-MM-DD")'], }, TEXTJOIN: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Joins text from multiple strings and/or ranges with a delimiter. Supports array/range delimiters that cycle through gaps. When ignore_empty is TRUE, empty strings are skipped. Returns #VALUE! if result exceeds 32,767 characters.', - parameters: [{name: 'delimiter', description: ''}, {name: 'ignore_empty', description: ''}, {name: 'text1', description: ''}], + parameters: [{name: 'delimiter', description: 'The text (or range/array of texts, cycled through the gaps) inserted between joined values.'}, {name: 'ignore_empty', description: 'When TRUE, empty strings among the joined values are skipped instead of producing an extra delimiter.'}, {name: 'text1', description: 'A text value, cell reference, or range to join. Further text values or ranges can be passed as additional arguments and are appended in order.'}], + examples: ['=TEXTJOIN(", ", TRUE(), A1:A3)', '=TEXTJOIN("-", FALSE(), "a", "b", "c")'], }, TRIM: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Strips extra spaces from text.', - parameters: [{name: 'text', description: ''}], + parameters: [{name: 'text', description: 'The text to strip of leading, trailing, and repeated inner spaces.'}], + examples: ['=TRIM(" Hello World ")', '=TRIM(A1)'], }, UNICHAR: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the character created by using provided code point.', - parameters: [{name: 'number', description: ''}], + parameters: [{name: 'number', description: 'The Unicode code point that identifies the character to return.'}], + examples: ['=UNICHAR(65)', '=UNICHAR(8364)'], }, UNICODE: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns the Unicode code point of a first character of a text.', - parameters: [{name: 'text', description: ''}], + parameters: [{name: 'text', description: 'The text whose first character\'s Unicode code point is returned.'}], + examples: ['=UNICODE("A")', '=UNICODE(A1)'], }, UPPER: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Returns text converted to uppercase.', - parameters: [{name: 'text', description: ''}], + parameters: [{name: 'text', description: 'The text to convert to uppercase.'}], + examples: ['=UPPER("hello")', '=UPPER(A1)'], }, VALUE: { category: 'Text', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', shortDescription: 'Parses a number, date, time, datetime, currency, or percentage from a text string.', - parameters: [{name: 'text', description: ''}], + parameters: [{name: 'text', description: 'The text to parse as a number, date, time, datetime, currency, or percentage.'}], + examples: ['=VALUE("123")', '=VALUE("50%")', '=VALUE(A1)'], }, } From e36e0d15328760f533b9d29057f436761ec3c423 Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Thu, 23 Jul 2026 03:26:55 +0000 Subject: [PATCH 33/35] fix(hf-249): restore DEFAULT_DOCUMENTATION_URL export (HF-300) The shared documentation-URL constant was dropped during the #1705 merge's conflict resolution, so the paired metadata tests (get-available-functions and function-metadata-enrichment) fail to compile (TS2305: no exported member). Restore it verbatim from the HF-300 branch. Base built-ins already carry the .html URL and protected OFFSET/VERSION are excluded from the metadata API, so this alone greens the pair. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../functionMetadata/buildFunctionDescriptions.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts index 2b87bc949..7830ad2de 100644 --- a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts +++ b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts @@ -12,6 +12,12 @@ type TranslateName = (canonicalName: string) => string | undefined /** The structural subset of `FunctionMetadata` the builders read (so callers/tests need not supply `method`). */ export type StructuralMetadata = Pick +/** + * The single shared documentation URL for the built-in catalogue (HF-300). Every non-protected built-in points at + * this one page in v1 (no per-function anchors); the metadata-enrichment tests import it to assert coverage. + */ +export const DEFAULT_DOCUMENTATION_URL = 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html' + /** * Returns whether a parameter may be omitted: it declares `optionalArg`, or it has a `defaultValue`. * From b620b81e7bad8851692df9575fe97e09bed64504 Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Thu, 23 Jul 2026 13:35:25 +0000 Subject: [PATCH 34/35] chore(ci): re-trigger tests against updated HF-249 tests branch Empty commit to force a fresh cross-repo test run that fetches the current hyperformula-tests feature/hf-249-function-metadata-api (rename + dev_docs + guard cleanup); prior reruns raced an intermediate tests SHA. Co-Authored-By: Claude Opus 4.8 (1M context) From 08a7bd7c2daf437d6315a5a52580ffb3ccfb40a2 Mon Sep 17 00:00:00 2001 From: marcin-kordas-hoc Date: Thu, 23 Jul 2026 15:12:24 +0000 Subject: [PATCH 35/35] docs(hf-249): add SORT and UNIQUE to the function-metadata catalogue Merging develop into this branch brought the SORT (HF-69) and UNIQUE (HF-68) plugins, which are listable but had no FUNCTION_DOCS catalogue entries, so the metadata-enrichment coverage flagged them as offenders (missing documentation URL, examples, and parameter descriptions). Added both under "Array manipulation" with authored parameter descriptions and examples, matching the plugin arity (SORT: 4 params, UNIQUE: 3). Co-Authored-By: Claude Opus 4.8 (1M context) --- .../categories/array-manipulation.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/interpreter/functionMetadata/categories/array-manipulation.ts b/src/interpreter/functionMetadata/categories/array-manipulation.ts index c83de7630..f3ee74bd7 100644 --- a/src/interpreter/functionMetadata/categories/array-manipulation.ts +++ b/src/interpreter/functionMetadata/categories/array-manipulation.ts @@ -39,6 +39,20 @@ export const ARRAY_MANIPULATION_DOCS: Record = { parameters: [{name: 'rows', description: 'The number of rows in the returned array. The size must be resolvable at parse time, so use a literal (e.g. 3); a cell reference or formula yields a #VALUE! error whenever the result would span more than one cell, since the array size cannot be determined at parse time.'}, {name: 'cols', description: 'The number of columns in the returned array. Defaults to 1 when omitted; like rows, it must be resolvable at parse time.'}, {name: 'start', description: 'The first value of the sequence. Defaults to 1 when omitted.'}, {name: 'step', description: 'The increment between consecutive values, filled row by row. Defaults to 1 when omitted.'}], examples: ['=SEQUENCE(4)', '=SEQUENCE(3, 2)', '=SEQUENCE(3, 1, 10, 5)'], }, + SORT: { + category: 'Array manipulation', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', + shortDescription: 'Sorts the rows or columns of an array.', + parameters: [{name: 'array', description: 'The range or array whose rows (or columns) are sorted.'}, {name: 'sort_index', description: 'The 1-based row or column index within Array to sort by. Defaults to 1 (the first row or column).'}, {name: 'sort_order', description: '1 (default) sorts in ascending order; -1 sorts in descending order.'}, {name: 'by_col', description: 'FALSE (default) sorts the rows of Array; TRUE sorts its columns.'}], + examples: ['=SORT(A1:A10)', '=SORT(A1:B10, 2, -1)'], + }, + UNIQUE: { + category: 'Array manipulation', + documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html', + shortDescription: 'Returns the unique rows or columns of an array.', + parameters: [{name: 'array', description: 'The range or array to return distinct entries from.'}, {name: 'by_col', description: 'FALSE (default) compares and returns rows; TRUE compares and returns columns.'}, {name: 'exactly_once', description: 'FALSE (default) returns every distinct entry once; TRUE returns only the entries that appear exactly once in Array.'}], + examples: ['=UNIQUE(A1:A10)', '=UNIQUE(A1:B10)'], + }, VSTACK: { category: 'Array manipulation', documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html',