Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 49 additions & 7 deletions scripts/hf249-migrate-function-docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,47 @@ const DOC_PATH = path.join(REPO_ROOT, 'docs/guide/built-in-functions.md')
const CATEGORIES_DIR = path.join(REPO_ROOT, 'src/interpreter/functionMetadata/categories')
const INDEX_PATH = path.join(REPO_ROOT, 'src/interpreter/functionMetadata/index.ts')

/** Parameter names the documentation under-specifies relative to the implementation arity. */
/** Parameter names the documentation under-specifies relative to the implementation arity (already snake_case). */
const PARAMETER_NAME_OVERRIDES: Record<string, string[]> = {
'T.TEST': ['Array1', 'Array2', 'Tails', 'Type'],
'T.TEST': ['array1', 'array2', 'tails', 'type'],
}

/**
* Word-segmentation fixes for parameter tokens the documentation writes as a single run-on word (e.g. `Sumrange`),
* so they read consistently with their multi-word siblings (`Sum_Range` -> `sum_range`). Keyed by the mechanically
* snake-cased token; the value is the corrected snake_case name.
*/
const SNAKE_CASE_SEGMENTATION: Record<string, string> = {
sumrange: 'sum_range',
searchcriterion: 'search_criterion',
logicalvalue: 'logical_value',
datestring: 'date_string',
timestring: 'time_string',
startdate: 'start_date',
minimumlength: 'minimum_length',
lowerbound: 'lower_bound',
upperbound: 'upper_bound',
numberx: 'number_x',
numbery: 'number_y',
}

/**
* Converts a raw parameter name to snake_case: lowercase words joined by underscores, with camelCase/PascalCase and
* acronym boundaries split, existing separators unified, and trailing digits kept attached to their word
* (`Number1`, `Number_1` -> `number1`). A small segmentation table then fixes run-on tokens the docs left unsplit.
*
* @param {string} name - the raw parameter name from the syntax column
*/
export function toSnakeCase(name: string): string {
const mechanical = name
.replace(/([a-z0-9])([A-Z])/g, '$1_$2')
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
.replace(/[\s.\-]+/g, '_')
.toLowerCase()
.replace(/_+(\d)/g, '$1')
.replace(/_+/g, '_')
.replace(/^_|_$/g, '')
return SNAKE_CASE_SEGMENTATION[mechanical] ?? mechanical
}

interface DocRow {
Expand Down Expand Up @@ -94,8 +132,9 @@ function uniquify(names: string[]): string[] {
}

/**
* Produces exactly `arity` unique, non-empty parameter names. The syntax column lists `Name1, Name2, ...NameN`
* for repeating groups, so the first `arity` names already collapse those groups onto the implementation arity.
* Produces exactly `arity` unique, non-empty snake_case parameter names. The syntax column lists
* `Name1, Name2, ...NameN` for repeating groups, so the first `arity` names already collapse those groups onto the
* implementation arity; each is normalized to snake_case and any shortfall is padded with `arg1`, `arg2`, ...
*/
function deriveParameterNames(id: string, syntax: string, arity: number): string[] {
const override = PARAMETER_NAME_OVERRIDES[id]
Expand All @@ -105,9 +144,9 @@ function deriveParameterNames(id: string, syntax: string, arity: number): string
}
return override
}
const names = parseSyntaxNames(syntax).slice(0, arity)
const names = parseSyntaxNames(syntax).slice(0, arity).map(toSnakeCase)
while (names.length < arity) {
names.push(`Arg${names.length + 1}`)
names.push(`arg${names.length + 1}`)
}
return uniquify(names)
}
Expand Down Expand Up @@ -231,4 +270,7 @@ function main(): void {
console.log(`wrote ${path.relative(REPO_ROOT, INDEX_PATH)}; ${total} functions across ${categories.length} categories`)
}

main()
// Only regenerate when executed directly; guarded so helpers (e.g. `toSnakeCase`) can be imported without side effects.
if (require.main === module) {
main()
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,31 @@ export const ARRAY_MANIPULATION_DOCS: Record<string, FunctionDoc> = {
ARRAY_CONSTRAIN: {
category: 'Array manipulation',
shortDescription: 'Truncates an array to given dimensions.',
parameters: [{name: 'Array', description: ''}, {name: 'Height', description: ''}, {name: 'Width', description: ''}],
parameters: [{name: 'array', description: ''}, {name: 'height', description: ''}, {name: 'width', description: ''}],
},
ARRAYFORMULA: {
category: 'Array manipulation',
shortDescription: 'Enables the array arithmetic mode for a single formula.',
parameters: [{name: 'Formula', description: ''}],
parameters: [{name: 'formula', description: ''}],
},
FILTER: {
category: 'Array manipulation',
shortDescription: 'Filters an array, based on multiple conditions (boolean arrays).',
parameters: [{name: 'SourceArray', description: ''}, {name: 'BoolArray1', description: ''}],
parameters: [{name: 'source_array', description: ''}, {name: 'bool_array1', description: ''}],
},
SEQUENCE: {
category: 'Array manipulation',
shortDescription: 'Returns an array of sequential numbers.',
parameters: [{name: 'Rows', description: ''}, {name: 'Cols', description: ''}, {name: 'Start', description: ''}, {name: 'Step', description: ''}],
parameters: [{name: 'rows', description: ''}, {name: 'cols', description: ''}, {name: 'start', description: ''}, {name: 'step', description: ''}],
},
VSTACK: {
category: 'Array manipulation',
shortDescription: 'Stacks arrays vertically into a single array.',
parameters: [{name: 'Array1', description: ''}],
parameters: [{name: 'array1', description: ''}],
},
HSTACK: {
category: 'Array manipulation',
shortDescription: 'Stacks arrays horizontally into a single array.',
parameters: [{name: 'Array1', description: ''}],
parameters: [{name: 'array1', description: ''}],
},
}
24 changes: 12 additions & 12 deletions src/interpreter/functionMetadata/categories/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,61 +13,61 @@ export const DATABASE_DOCS: Record<string, FunctionDoc> = {
DAVERAGE: {
category: 'Database',
shortDescription: 'Returns the average of all values in a database field that match the given criteria.',
parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}],
parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}],
},
DCOUNT: {
category: 'Database',
shortDescription: 'Counts the cells containing numbers in a database field that match the given criteria.',
parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}],
parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}],
},
DCOUNTA: {
category: 'Database',
shortDescription: 'Counts the non-empty cells in a database field that match the given criteria.',
parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}],
parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}],
},
DGET: {
category: 'Database',
shortDescription: 'Returns the single value from a database field that matches the given criteria. Returns #VALUE! if no records match, and #NUM! if more than one record matches.',
parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}],
parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}],
},
DMAX: {
category: 'Database',
shortDescription: 'Returns the maximum value in a database field that matches the given criteria.',
parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}],
parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}],
},
DMIN: {
category: 'Database',
shortDescription: 'Returns the minimum value in a database field that matches the given criteria.',
parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}],
parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}],
},
DPRODUCT: {
category: 'Database',
shortDescription: 'Returns the product of all values in a database field that match the given criteria.',
parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}],
parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}],
},
DSTDEV: {
category: 'Database',
shortDescription: 'Returns the sample standard deviation of all values in a database field that match the given criteria.',
parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}],
parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}],
},
DSTDEVP: {
category: 'Database',
shortDescription: 'Returns the population standard deviation of all values in a database field that match the given criteria.',
parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}],
parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}],
},
DSUM: {
category: 'Database',
shortDescription: 'Returns the sum of all values in a database field that match the given criteria.',
parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}],
parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}],
},
DVAR: {
category: 'Database',
shortDescription: 'Returns the sample variance of all values in a database field that match the given criteria.',
parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}],
parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}],
},
DVARP: {
category: 'Database',
shortDescription: 'Returns the population variance of all values in a database field that match the given criteria.',
parameters: [{name: 'Database', description: ''}, {name: 'Field', description: ''}, {name: 'Criteria', description: ''}],
parameters: [{name: 'database', description: ''}, {name: 'field', description: ''}, {name: 'criteria', description: ''}],
},
}
48 changes: 24 additions & 24 deletions src/interpreter/functionMetadata/categories/date-and-time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,77 +13,77 @@ export const DATE_AND_TIME_DOCS: Record<string, FunctionDoc> = {
DATE: {
category: 'Date and time',
shortDescription: 'Returns the specified date as the number of full days since [`nullDate`](../api/interfaces/configparams.md#nulldate).',
parameters: [{name: 'Year', description: ''}, {name: 'Month', description: ''}, {name: 'Day', description: ''}],
parameters: [{name: 'year', description: ''}, {name: 'month', description: ''}, {name: 'day', description: ''}],
},
DATEDIF: {
category: 'Date and time',
shortDescription: 'Calculates distance between two dates.<br>Supported units: "D" (days), "M" (months), "Y" (years), "MD" (days ignoring months and years), "YM" (months ignoring years), or "YD" (days ignoring years).',
parameters: [{name: 'Date1', description: ''}, {name: 'Date2', description: ''}, {name: 'Unit', description: ''}],
parameters: [{name: 'date1', description: ''}, {name: 'date2', description: ''}, {name: 'unit', description: ''}],
},
DATEVALUE: {
category: 'Date and time',
shortDescription: 'Parses a date string and returns it as the number of full days since [`nullDate`](../api/interfaces/configparams.md#nulldate).<br>Accepts formats set by the [`dateFormats`](../api/interfaces/configparams.md#dateformats) option.',
parameters: [{name: 'Datestring', description: ''}],
parameters: [{name: 'date_string', description: ''}],
},
DAY: {
category: 'Date and time',
shortDescription: 'Returns the day of the given date value.',
parameters: [{name: 'Number', description: ''}],
parameters: [{name: 'number', description: ''}],
},
DAYS: {
category: 'Date and time',
shortDescription: 'Calculates the difference between two date values.',
parameters: [{name: 'Date2', description: ''}, {name: 'Date1', description: ''}],
parameters: [{name: 'date2', description: ''}, {name: 'date1', description: ''}],
},
DAYS360: {
category: 'Date and time',
shortDescription: 'Calculates the difference between two date values in days, in 360-day basis.',
parameters: [{name: 'Date2', description: ''}, {name: 'Date1', description: ''}, {name: 'Format', description: ''}],
parameters: [{name: 'date2', description: ''}, {name: 'date1', description: ''}, {name: 'format', description: ''}],
},
EDATE: {
category: 'Date and time',
shortDescription: 'Shifts the given startdate by given number of months and returns it as the number of full days since [`nullDate`](../api/interfaces/configparams.md#nulldate).[^non-odff]',
parameters: [{name: 'Startdate', description: ''}, {name: 'Months', description: ''}],
parameters: [{name: 'start_date', description: ''}, {name: 'months', description: ''}],
},
EOMONTH: {
category: 'Date and time',
shortDescription: 'Returns the date of the last day of a month which falls months away from the start date. Returns the value in the form of number of full days since [`nullDate`](../api/interfaces/configparams.md#nulldate).[^non-odff]',
parameters: [{name: 'Startdate', description: ''}, {name: 'Months', description: ''}],
parameters: [{name: 'start_date', description: ''}, {name: 'months', description: ''}],
},
HOUR: {
category: 'Date and time',
shortDescription: 'Returns hour component of given time.',
parameters: [{name: 'Time', description: ''}],
parameters: [{name: 'time', description: ''}],
},
INTERVAL: {
category: 'Date and time',
shortDescription: 'Returns interval string from given number of seconds.',
parameters: [{name: 'Seconds', description: ''}],
parameters: [{name: 'seconds', description: ''}],
},
ISOWEEKNUM: {
category: 'Date and time',
shortDescription: 'Returns an ISO week number that corresponds to the week of year.',
parameters: [{name: 'Date', description: ''}],
parameters: [{name: 'date', description: ''}],
},
MINUTE: {
category: 'Date and time',
shortDescription: 'Returns minute component of given time.',
parameters: [{name: 'Time', description: ''}],
parameters: [{name: 'time', description: ''}],
},
MONTH: {
category: 'Date and time',
shortDescription: 'Returns the month for the given date value.',
parameters: [{name: 'Number', description: ''}],
parameters: [{name: 'number', description: ''}],
},
NETWORKDAYS: {
category: 'Date and time',
shortDescription: 'Returns the number of working days between two given dates.',
parameters: [{name: 'Date1', description: ''}, {name: 'Date2', description: ''}, {name: 'Holidays', description: ''}],
parameters: [{name: 'date1', description: ''}, {name: 'date2', description: ''}, {name: 'holidays', description: ''}],
},
'NETWORKDAYS.INTL': {
category: 'Date and time',
shortDescription: 'Returns the number of working days between two given dates.',
parameters: [{name: 'Date1', description: ''}, {name: 'Date2', description: ''}, {name: 'Mode', description: ''}, {name: 'Holidays', description: ''}],
parameters: [{name: 'date1', description: ''}, {name: 'date2', description: ''}, {name: 'mode', description: ''}, {name: 'holidays', description: ''}],
},
NOW: {
category: 'Date and time',
Expand All @@ -93,17 +93,17 @@ export const DATE_AND_TIME_DOCS: Record<string, FunctionDoc> = {
SECOND: {
category: 'Date and time',
shortDescription: 'Returns second component of given time.',
parameters: [{name: 'Time', description: ''}],
parameters: [{name: 'time', description: ''}],
},
TIME: {
category: 'Date and time',
shortDescription: 'Returns the number that represents a given time as a fraction of full day.',
parameters: [{name: 'Hour', description: ''}, {name: 'Minute', description: ''}, {name: 'Second', description: ''}],
parameters: [{name: 'hour', description: ''}, {name: 'minute', description: ''}, {name: 'second', description: ''}],
},
TIMEVALUE: {
category: 'Date and time',
shortDescription: 'Parses a time string and returns a number that represents it as a fraction of a full day.<br>Accepts formats set by the [`timeFormats`](../api/interfaces/configparams.md#timeformats) option.',
parameters: [{name: 'Timestring', description: ''}],
parameters: [{name: 'time_string', description: ''}],
},
TODAY: {
category: 'Date and time',
Expand All @@ -113,31 +113,31 @@ export const DATE_AND_TIME_DOCS: Record<string, FunctionDoc> = {
WEEKDAY: {
category: 'Date and time',
shortDescription: 'Computes a number between 1-7 representing the day of week.',
parameters: [{name: 'Date', description: ''}, {name: 'Type', description: ''}],
parameters: [{name: 'date', description: ''}, {name: 'type', description: ''}],
},
WEEKNUM: {
category: 'Date and time',
shortDescription: 'Returns a week number that corresponds to the week of year.',
parameters: [{name: 'Date', description: ''}, {name: 'Type', description: ''}],
parameters: [{name: 'date', description: ''}, {name: 'type', description: ''}],
},
WORKDAY: {
category: 'Date and time',
shortDescription: 'Returns the working day number of days from start day.',
parameters: [{name: 'Date', description: ''}, {name: 'Shift', description: ''}, {name: 'Holidays', description: ''}],
parameters: [{name: 'date', description: ''}, {name: 'shift', description: ''}, {name: 'holidays', description: ''}],
},
'WORKDAY.INTL': {
category: 'Date and time',
shortDescription: 'Returns the working day number of days from start day.',
parameters: [{name: 'Date', description: ''}, {name: 'Shift', description: ''}, {name: 'Mode', description: ''}, {name: 'Holidays', description: ''}],
parameters: [{name: 'date', description: ''}, {name: 'shift', description: ''}, {name: 'mode', description: ''}, {name: 'holidays', description: ''}],
},
YEAR: {
category: 'Date and time',
shortDescription: 'Returns the year as a number according to the internal calculation rules.',
parameters: [{name: 'Number', description: ''}],
parameters: [{name: 'number', description: ''}],
},
YEARFRAC: {
category: 'Date and time',
shortDescription: 'Computes the difference between two date values, in fraction of years.',
parameters: [{name: 'Date2', description: ''}, {name: 'Date1', description: ''}, {name: 'Format', description: ''}],
parameters: [{name: 'date2', description: ''}, {name: 'date1', description: ''}, {name: 'format', description: ''}],
},
}
Loading
Loading