{"id":45944236,"url":"https://github.com/time-loop/formula-parser","last_synced_at":"2026-02-28T10:59:07.892Z","repository":{"id":66061755,"uuid":"257259502","full_name":"time-loop/formula-parser","owner":"time-loop","description":"Javascript Library parsing Excel Formulas and more","archived":false,"fork":false,"pushed_at":"2025-04-17T15:52:02.000Z","size":10193,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-04-18T06:20:53.893Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"handsontable/formula-parser","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/time-loop.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-04-20T11:27:43.000Z","updated_at":"2025-04-17T15:52:05.000Z","dependencies_parsed_at":null,"dependency_job_id":"d63c97d3-9952-4f1b-b2db-2bc063c97c39","html_url":"https://github.com/time-loop/formula-parser","commit_stats":null,"previous_names":[],"tags_count":43,"template":false,"template_full_name":null,"purl":"pkg:github/time-loop/formula-parser","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/time-loop%2Fformula-parser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/time-loop%2Fformula-parser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/time-loop%2Fformula-parser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/time-loop%2Fformula-parser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/time-loop","download_url":"https://codeload.github.com/time-loop/formula-parser/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/time-loop%2Fformula-parser/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29930948,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-28T09:58:13.507Z","status":"ssl_error","status_checked_at":"2026-02-28T09:57:57.047Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-28T10:59:07.370Z","updated_at":"2026-02-28T10:59:07.883Z","avatar_url":"https://github.com/time-loop.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"Formula Parser [![@time-loop/hot-formula-parser](https://img.shields.io/badge/npm-v4.1.0-blue)](https://github.com/time-loop/github-packages/pkgs/npm/hot-formula-parser)\n==========\nLibrary provides a `Parser` class that evaluates excel and mathematical formulas.\n\n- - -\n\n## Install\n\nA recommended way to install Formula Parser is through [NPM](https://www.npmjs.com/) using the following command:\n\n```sh\n$ npm install --save @time-loop/hot-formula-parser\n```\n\nSimple usage:\n```js\nimport { ClickUpParser } from '@time-loop/hot-formula-parser';\n\nconst parser = ClickUpParser.create();\n\nparser.parse('SUM(1, 6, 7)'); // It returns `Object {error: null, result: 14}`\n```\n\n## Features\n\nIt supports:\n\n * Any numbers, negative and positive as float or integer;\n * Arithmetic operations like `+`, `-`, `/`, `*`, `%`, `^`;\n * Logical operations like `AND()`, `OR()`, `NOT()`, `XOR()`;\n * Comparison operations like `=`, `\u003e`, `\u003e=`, `\u003c`, `\u003c=`, `\u003c\u003e`;\n * All JavaScript Math constants like `PI()`, `E()`, `LN10()`, `LN2()`, `LOG10E()`, `LOG2E()`, `SQRT1_2()`, `SQRT2()`;\n * String operations like `\u0026` (concatenation eq. `parser.parse('-(2\u00265)');` will return `-25`);\n * All excel formulas defined in [formula.js](https://github.com/handsontable/formula.js);\n * Relative and absolute cell coordinates like `A1`, `$A1`, `A$1`, `$A$1`;\n * Build-in variables like `TRUE`, `FALSE`, `NULL`\n * Custom variables;\n * Custom functions/formulas;\n * Node and Browser environment.\n\n## API (methods)\n\n```js\nimport { ClickUpParser } from '@time-loop/hot-formula-parser';\n\nconst parser = ClickUpParser.create();\n```\n\n### .parse(expression)\n\nParses and evaluates provided expression. It always returns an object with `result` and `error` properties. `result` property\nalways keep evaluated value. If error occurs `error` property will be set as:\n * `#ERROR!` General error;\n * `#DIV/0!` Divide by zero error;\n * `#NAME?` Not recognised function name or variable name;\n * `#N/A` Indicates that a value is not available to a formula;\n * `#NUM!` Occurs when formula encounters an invalid number;\n * `#VALUE!` Occurs when one of formula arguments is of the wrong type.\n\n```js\nparser.parse('(1 + 5 + (5 * 10)) / 10'); // returns `Object {error: null, result: 5.6}`\nparser.parse('SUM(MY_VAR)'); // returns `Object {error: \"#NAME?\", result: null}`\nparser.parse('1;;1'); // returns `Object {error: \"#ERROR!\", result: null}`\n```\n\n### .setVariable(name, value)\n\nSet predefined variable name which can be visible while parsing formula expression.\n\n```js\nparser.setVariable('MY_VARIABLE', 5);\nparser.setVariable('fooBar', 10);\n\nparser.parse('(1 + MY_VARIABLE + (5 * fooBar)) / fooBar'); // returns `5.6`\n```\n\n### .getVariable(name)\n\nGet variable name.\n\n```js\nparser.setVariable('fooBar', 10);\n\nparser.getVariable('fooBar'); // returns `10`\n```\n\n### .setFunction(name, fn)\n\nSet custom function which can be visible while parsing formula expression.\n\n```js\nparser.setFunction('ADD_5', function(params) {\n  return params[0] + 5;\n});\nparser.setFunction('GET_LETTER', function(params) {\n  var string = params[0];\n  var index = params[1] - 1;\n\n  return string.charAt(index);\n});\n\nparser.parse('SUM(4, ADD_5(1))'); // returns `10`\nparser.parse('GET_LETTER(\"Some string\", 3)'); // returns `m`\n```\n\n### .getFunction(name)\n\nGet custom function.\n\n```js\nparser.setFunction('ADD_5', function(params) {\n  return params[0] + 5;\n});\n\nparser.getFunction('ADD_5')([1]); // returns `6`\n```\n\n### .SUPPORTED_FORMULAS\n\nList of all supported formulas function.\n\n```js\nimport { SUPPORTED_FORMULAS } from '@time-loop/hot-formula-parser'; // An array of formula names\n```\n\n## API (hooks)\n\n### 'callVariable' (name, done)\n\nFired while retrieving variable. If variable was defined earlier using `setVariable` you can overwrite it by this hook.\n\n```js\nparser.on('callVariable', function(name, done) {\n  if (name === 'foo') {\n    done(Math.PI / 2);\n  }\n});\n\nparser.parse('SUM(SIN(foo), COS(foo))'); // returns `1`\n```\n\n### 'callFunction' (name, params, done)\n\nFired while calling function. If function was defined earlier using `setFunction` you can overwrite it's result by this hook.\nYou can also use this to override result of build-in formulas.\n\n```js\nparser.on('callFunction', function(name, params, done) {\n  if (name === 'ADD_5') {\n    done(params[0] + 5);\n  }\n});\n\nparser.parse('ADD_5(3)'); // returns `8`\n```\n\n### 'callCellValue' (cellCoord, done)\n\nFired while retrieving cell value by its label (eq: `B3`, `B$3`, `B$3`, `$B$3`).\n\n```js\nparser.on('callCellValue', function(cellCoord, done) {\n  // using label\n  if (cellCoord.label === 'B$6') {\n    done('hello');\n  }\n  // or using indexes\n  if (cellCoord.row.index === 5 \u0026\u0026 cellCoord.row.isAbsolute \u0026\u0026 cellCoord.column.index === 1 \u0026\u0026 !cellCoord.column.isAbsolute) {\n    done('hello');\n  }\n\n  if (cellCoord.label === 'C6') {\n    done(0.75);\n  }\n});\n\nparser.parse('B$6'); // returns `\"hello\"`\nparser.parse('B$6\u0026\" world\"'); // returns `\"hello world\"`\nparser.parse('FISHER(C6)'); // returns `0.9729550745276566`\n```\n\n### 'callRangeValue' (startCellCoord, endCellCoord, done)\n\nFired while retrieving cells range value (eq: `A1:B3`, `$A1:B$3`, `A$1:B$3`, `$A$1:$B$3`).\n\n```js\nparser.on('callRangeValue', function(startCellCoord, endCellCoord, done) {\n  var data = [\n    [1, 2, 3, 4, 5],\n    [6, 7, 8, 9, 10],\n    [11, 12, 13, 14, 15],\n    [16, 17, 18, 19, 20],\n  ];\n  var fragment = [];\n\n  for (var row = startCellCoord.row.index; row \u003c= endCellCoord.row.index; row++) {\n    var rowData = data[row];\n    var colFragment = [];\n\n    for (var col = startCellCoord.column.index; col \u003c= endCellCoord.column.index; col++) {\n      colFragment.push(rowData[col]);\n    }\n    fragment.push(colFragment);\n  }\n\n  if (fragment) {\n    done(fragment);\n  }\n});\n\nparser.parse('JOIN(A1:E2)'); // returns `\"1,2,3,4,5,6,7,8,9,10\"`\nparser.parse('COLUMNS(A1:E2)'); // returns `5`\nparser.parse('ROWS(A1:E2)'); // returns `2`\nparser.parse('COUNT(A1:E2)'); // returns `10`\nparser.parse('COUNTIF(A1:E2, \"\u003e5\")'); // returns `5`\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftime-loop%2Fformula-parser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftime-loop%2Fformula-parser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftime-loop%2Fformula-parser/lists"}