diff --git a/CHANGELOG.md b/CHANGELOG.md index 683e1da14..d12805028 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. [#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 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 +``` 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/HyperFormula.ts b/src/HyperFormula.ts index 566957270..e7f18b524 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, 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' @@ -649,6 +652,92 @@ 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()) + // 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 + * 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') + // 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, resolved.doc, resolved.metadata, translate) + } + /** * @internal */ @@ -4358,6 +4447,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 Helpers + */ + 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 Helpers + */ + 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, 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[], +} diff --git a/src/interpreter/functionMetadata/buildFunctionDescriptions.ts b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts new file mode 100644 index 000000000..8ece69a48 --- /dev/null +++ b/src/interpreter/functionMetadata/buildFunctionDescriptions.ts @@ -0,0 +1,120 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +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 + +/** + * 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) +} + +/** + * 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})` +} + +/** + * 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 { + const translated = translate(canonicalName) + return translated === undefined || translated === '' ? canonicalName : translated +} + +/** + * 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 + * @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 + 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: [], + } +} 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 new file mode 100644 index 000000000..b9e2e86c0 --- /dev/null +++ b/src/interpreter/functionMetadata/categories/logical.ts @@ -0,0 +1,68 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +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. + */ +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: '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 new file mode 100644 index 000000000..9e864f3e9 --- /dev/null +++ b/src/interpreter/functionMetadata/categories/math-and-trigonometry.ts @@ -0,0 +1,378 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +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. + */ +export const MATH_AND_TRIGONOMETRY_DOCS: Record = { + ABS: { + category: 'Math and trigonometry', + shortDescription: 'Returns the absolute value of a number.', + parameters: [{name: 'Number', description: ''}], + }, + 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: '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 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 new file mode 100644 index 000000000..fe2c5d0d6 --- /dev/null +++ b/src/interpreter/functionMetadata/index.ts @@ -0,0 +1,41 @@ +/** + * @license + * Copyright (c) 2025 Handsoncode. All rights reserved. + */ + +import {FunctionDoc} from './FunctionDescription' +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. + * Generated by `scripts/hf249-migrate-function-docs.ts`. Coverage of the whole canonical set is enforced by test. + */ +export const FUNCTION_DOCS: Record = { + ...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, +}