@nachoggodino/cello 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BYLAWS.md +446 -0
- package/CHANGELOG.md +11 -0
- package/LICENSE +12 -0
- package/README.md +211 -0
- package/dist/cli/cli.d.ts +16 -0
- package/dist/cli/cli.js +360 -0
- package/dist/cli/serve.d.ts +15 -0
- package/dist/cli/serve.js +226 -0
- package/dist/evaluator/evaluate.d.ts +2 -0
- package/dist/evaluator/evaluate.js +129 -0
- package/dist/evaluator/formula.d.ts +13 -0
- package/dist/evaluator/formula.js +141 -0
- package/dist/formatter/format.d.ts +1 -0
- package/dist/formatter/format.js +112 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +6 -0
- package/dist/parser/parse.d.ts +2 -0
- package/dist/parser/parse.js +552 -0
- package/dist/renderer/render.d.ts +2 -0
- package/dist/renderer/render.js +295 -0
- package/dist/serializer/serialize.d.ts +2 -0
- package/dist/serializer/serialize.js +104 -0
- package/dist/shared/types.d.ts +88 -0
- package/dist/shared/types.js +1 -0
- package/dist/shared/utils.d.ts +16 -0
- package/dist/shared/utils.js +142 -0
- package/dist/validator/validate.d.ts +8 -0
- package/dist/validator/validate.js +10 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +1 -0
- package/docs/ARCHITECTURE.md +43 -0
- package/docs/CLI.md +58 -0
- package/docs/COMPLIANCE.md +82 -0
- package/docs/ERROR_MODEL.md +25 -0
- package/docs/FORMULA_SUPPORT.md +33 -0
- package/docs/SPEC.md +723 -0
- package/docs/SYNTAX_HIGHLIGHTING.md +91 -0
- package/examples/advanced_kpi.cel +42 -0
- package/examples/basic.cel +8 -0
- package/examples/feature_showcase.cel +37 -0
- package/package.json +96 -0
- package/syntaxes/cel.language-configuration.json +31 -0
- package/syntaxes/cel.tmLanguage.json +250 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Cello Syntax Highlighting
|
|
2
|
+
|
|
3
|
+
Cello ships a TextMate grammar as the portable syntax-highlighting standard for `.cel` files:
|
|
4
|
+
|
|
5
|
+
- Grammar: [`syntaxes/cel.tmLanguage.json`](../syntaxes/cel.tmLanguage.json)
|
|
6
|
+
- Editor configuration: [`syntaxes/cel.language-configuration.json`](../syntaxes/cel.language-configuration.json)
|
|
7
|
+
- Language id: `cel`
|
|
8
|
+
- File extension: `.cel`
|
|
9
|
+
- Root scope: `source.cel`
|
|
10
|
+
|
|
11
|
+
TextMate grammars are supported directly by VS Code and can be consumed by Shiki, GitHub Linguist-derived tooling, Monaco bridges, and many other editor integrations.
|
|
12
|
+
|
|
13
|
+
## VS Code Contribution
|
|
14
|
+
|
|
15
|
+
Use this contribution block in a VS Code extension package:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"contributes": {
|
|
20
|
+
"languages": [
|
|
21
|
+
{
|
|
22
|
+
"id": "cel",
|
|
23
|
+
"aliases": ["Cello", "cel"],
|
|
24
|
+
"extensions": [".cel"],
|
|
25
|
+
"configuration": "./syntaxes/cel.language-configuration.json"
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"grammars": [
|
|
29
|
+
{
|
|
30
|
+
"language": "cel",
|
|
31
|
+
"scopeName": "source.cel",
|
|
32
|
+
"path": "./syntaxes/cel.tmLanguage.json"
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Scope Map
|
|
40
|
+
|
|
41
|
+
| Cello construct | Primary scope |
|
|
42
|
+
|---|---|
|
|
43
|
+
| `@sheet` | `keyword.control.sheet.cel` |
|
|
44
|
+
| Sheet name | `entity.name.section.sheet.cel` |
|
|
45
|
+
| Sheet format | `storage.type.format.cel` |
|
|
46
|
+
| `@header` | `keyword.control.header.cel` |
|
|
47
|
+
| `@defaults` | `keyword.control.defaults.cel` |
|
|
48
|
+
| External source `->` | `keyword.operator.source.cel` |
|
|
49
|
+
| External path | `string.unquoted.path.cel` |
|
|
50
|
+
| Comment line | `comment.line.double-slash.cel` |
|
|
51
|
+
| Cell separator `|` | `punctuation.separator.cell.cel` |
|
|
52
|
+
| Formula cell | `meta.formula.cel` |
|
|
53
|
+
| Formula function | `support.function.formula.cel` |
|
|
54
|
+
| Sheet reference | `variable.other.sheet-reference.cel` |
|
|
55
|
+
| Cell reference | `constant.other.cell-reference.cel` |
|
|
56
|
+
| Range slice | `constant.other.range.cel` |
|
|
57
|
+
| Merge token `<` or `^` | `keyword.operator.merge.cel` |
|
|
58
|
+
| Modifier block | `meta.modifier.cel` |
|
|
59
|
+
| Tone modifier | `support.constant.tone.cel` |
|
|
60
|
+
| Color literal | `constant.other.color.rgb-value.cel` |
|
|
61
|
+
| Forced text string | `string.quoted.double.cel` |
|
|
62
|
+
| ISO date | `constant.other.date.iso.cel` |
|
|
63
|
+
| Boolean | `constant.language.boolean.cel` |
|
|
64
|
+
| Number | `constant.numeric.cel` |
|
|
65
|
+
| Inline heading | `markup.heading.*.cel` |
|
|
66
|
+
| Inline bold/italic/strike | `markup.bold.cel`, `markup.italic.cel`, `markup.strikethrough.cel` |
|
|
67
|
+
|
|
68
|
+
## Recommended Theme Treatment
|
|
69
|
+
|
|
70
|
+
Themes that want a distinctive Cello look can add these VS Code `tokenColors`. The palette is warm and spreadsheet-like: amber for workbook structure, blue for modifiers, green for references, and rose for formula operators/errors.
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
[
|
|
74
|
+
{ "scope": "keyword.control.sheet.cel, keyword.control.header.cel, keyword.control.defaults.cel", "settings": { "foreground": "#D97706", "fontStyle": "bold" } },
|
|
75
|
+
{ "scope": "entity.name.section.sheet.cel", "settings": { "foreground": "#0F766E", "fontStyle": "bold" } },
|
|
76
|
+
{ "scope": "storage.type.format.cel, support.constant.format.cel", "settings": { "foreground": "#2563EB" } },
|
|
77
|
+
{ "scope": "meta.formula.cel", "settings": { "foreground": "#BE123C" } },
|
|
78
|
+
{ "scope": "support.function.formula.cel", "settings": { "foreground": "#9333EA", "fontStyle": "bold" } },
|
|
79
|
+
{ "scope": "variable.other.sheet-reference.cel, variable.other.identifier.cel", "settings": { "foreground": "#15803D" } },
|
|
80
|
+
{ "scope": "meta.modifier.cel, support.constant.tone.cel", "settings": { "foreground": "#0284C7" } },
|
|
81
|
+
{ "scope": "punctuation.separator.cell.cel", "settings": { "foreground": "#94A3B8" } },
|
|
82
|
+
{ "scope": "keyword.operator.merge.cel", "settings": { "foreground": "#EA580C", "fontStyle": "bold" } },
|
|
83
|
+
{ "scope": "comment.line.double-slash.cel", "settings": { "foreground": "#78716C", "fontStyle": "italic" } }
|
|
84
|
+
]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Design Notes
|
|
88
|
+
|
|
89
|
+
The grammar highlights Cello's native syntax first and gracefully recognizes useful tokens in imported CSV, TSV, Markdown, and JSON sheet bodies. TextMate grammars do not track full workbook parse state, so imported sheet contents are highlighted heuristically rather than by the active `@sheet [format]` declaration.
|
|
90
|
+
|
|
91
|
+
The grammar deliberately uses common TextMate parent scopes such as `keyword`, `entity.name.section`, `constant.numeric`, `string.quoted.double`, and `markup.*` so existing themes look good without Cello-specific theme rules. The `.cel` suffix on every specific scope lets dedicated themes add richer treatment.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Advanced KPI workbook using named refs, slices, cross-sheet refs and !! alias
|
|
2
|
+
|
|
3
|
+
@sheet RawData [csv]
|
|
4
|
+
date,region,agent,amount,units
|
|
5
|
+
2026-01-01,Madrid,Ana,1200,4
|
|
6
|
+
2026-01-01,Barcelona,Luis,980,3
|
|
7
|
+
2026-01-02,Madrid,Sara,1420,5
|
|
8
|
+
2026-01-02,Valencia,Pedro,760,2
|
|
9
|
+
2026-01-03,Madrid,Ana,1660,6
|
|
10
|
+
2026-01-03,Barcelona,Luis,1100,4
|
|
11
|
+
2026-01-04,Valencia,Pedro,920,3
|
|
12
|
+
2026-01-04,Madrid,Sara,1510,5
|
|
13
|
+
2026-01-05,Barcelona,Luis,1340,5
|
|
14
|
+
2026-01-05,Madrid,Ana,1720,6
|
|
15
|
+
|
|
16
|
+
@sheet KPIs
|
|
17
|
+
|
|
18
|
+
@header | Metric | Value |
|
|
19
|
+
| ## Revenue KPIs | < |
|
|
20
|
+
| Total revenue | =SUM(!!amount) |
|
|
21
|
+
| Total units | =SUM(!!units) |
|
|
22
|
+
| Avg ticket | =SUM(!!amount)/SUM(!!units) |
|
|
23
|
+
| Best single sale | =MAX(!!amount) |
|
|
24
|
+
| First 5 rows revenue | =SUM(!!amount[2:6]) |
|
|
25
|
+
|
|
26
|
+
@sheet Regions
|
|
27
|
+
|
|
28
|
+
@header | Region | Revenue[€][2d] | Units[0d] | Avg_ticket[€][2d] | Target[€][0d] | Variance[€][2d] | Attainment[%][1d] |
|
|
29
|
+
@defaults | | =SUMIF(RawData!region,Region,RawData!amount) | =SUMIF(RawData!region,Region,RawData!units) | =Revenue/Units | | =Revenue-Target | =Revenue/Target |
|
|
30
|
+
| Madrid | | | | 7200 | | |
|
|
31
|
+
| Barcelona | | | | 3900 | | |
|
|
32
|
+
| Valencia | | | | 1800 | | |
|
|
33
|
+
[bold][bg:#f3f4f6] | ## TOTAL | =SUM(Revenue) | =SUM(Units) | =SUM(Revenue)/SUM(Units) | =SUM(Target) | =SUM(Variance) | =SUM(Revenue)/SUM(Target) |
|
|
34
|
+
|
|
35
|
+
@sheet Agents
|
|
36
|
+
|
|
37
|
+
@header | Agent | Revenue[€][2d] | Units[0d] | Avg_ticket[€][2d] |
|
|
38
|
+
@defaults | | =SUMIF(RawData!agent,Agent,RawData!amount) | =SUMIF(RawData!agent,Agent,RawData!units) | =Revenue/Units |
|
|
39
|
+
| Ana | | | |
|
|
40
|
+
| Luis | | | |
|
|
41
|
+
| Sara | | | |
|
|
42
|
+
| Pedro | | | |
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Feature showcase: merges, modifiers, markdown import, json import, formulas
|
|
2
|
+
|
|
3
|
+
@sheet Board
|
|
4
|
+
@header | Section | Owner | Status |
|
|
5
|
+
| ## Sprint Board | < | < |
|
|
6
|
+
| API | Nacho | *In progress* |
|
|
7
|
+
| UI | Carla | ~~Blocked~~ |
|
|
8
|
+
| Data | Mario | _Review_ |
|
|
9
|
+
|
|
10
|
+
@sheet Budget
|
|
11
|
+
@header | Item | Plan[€][2d] | Actual[€][2d] | Diff[€][2d] | Flag |
|
|
12
|
+
@defaults | | | | =Actual-Plan | |
|
|
13
|
+
| Hosting | 300 | 340 | | over[bg:#fee2e2][#991b1b] |
|
|
14
|
+
| Tools | 120 | 90 | | ok[bg:#dcfce7][#166534] |
|
|
15
|
+
| Ops | 210 | 210 | | ok[bg:#dcfce7][#166534] |
|
|
16
|
+
[bold] | TOTAL | =SUM(Plan) | =SUM(Actual) | =SUM(Diff) | < |
|
|
17
|
+
|
|
18
|
+
@sheet ImportedMd [markdown]
|
|
19
|
+
| label | score |
|
|
20
|
+
|------|------:|
|
|
21
|
+
| quality | 9 |
|
|
22
|
+
| speed | 8 |
|
|
23
|
+
| scope | 7 |
|
|
24
|
+
|
|
25
|
+
@sheet ImportedJson [json]
|
|
26
|
+
[
|
|
27
|
+
{"team":"A","velocity":30,"bugs":2},
|
|
28
|
+
{"team":"B","velocity":24,"bugs":5},
|
|
29
|
+
{"team":"C","velocity":28,"bugs":3}
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
@sheet Summary
|
|
33
|
+
@header | Metric | Value |
|
|
34
|
+
| Budget diff total | =SUM(Budget!Diff) |
|
|
35
|
+
| Avg imported score | =AVG(ImportedMd!score) |
|
|
36
|
+
| Total bugs | =SUM(ImportedJson!bugs) |
|
|
37
|
+
| Max velocity | =MAX(ImportedJson!velocity) |
|
package/package.json
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nachoggodino/cello",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Markdown, but for spreadsheets. Plain-text tabular data with formulas.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"cello": "./dist/cli/cli.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"docs",
|
|
20
|
+
"examples",
|
|
21
|
+
"syntaxes",
|
|
22
|
+
"BYLAWS.md",
|
|
23
|
+
"README.md",
|
|
24
|
+
"CHANGELOG.md",
|
|
25
|
+
"LICENSE"
|
|
26
|
+
],
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=22"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsc -p tsconfig.json",
|
|
32
|
+
"clean": "Remove-Item -Recurse -Force dist -ErrorAction SilentlyContinue",
|
|
33
|
+
"dev": "tsc -w -p tsconfig.json",
|
|
34
|
+
"prepack": "npm run build",
|
|
35
|
+
"playground:dev": "vite --config playground/vite.config.ts",
|
|
36
|
+
"playground:build": "vite build --config playground/vite.config.ts",
|
|
37
|
+
"playground:preview": "vite preview --config playground/vite.config.ts",
|
|
38
|
+
"playground:typecheck": "tsc -p playground/tsconfig.json --noEmit",
|
|
39
|
+
"lint": "eslint \"playground/**/*.{ts,tsx}\"",
|
|
40
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p playground/tsconfig.json --noEmit",
|
|
41
|
+
"test": "vitest run",
|
|
42
|
+
"test:unit": "vitest run tests/unit playground/src/**/*.test.ts",
|
|
43
|
+
"test:it": "vitest run tests/it",
|
|
44
|
+
"test:e2e": "vitest run tests/e2e",
|
|
45
|
+
"test:watch": "vitest",
|
|
46
|
+
"coverage": "vitest run --coverage"
|
|
47
|
+
},
|
|
48
|
+
"keywords": [
|
|
49
|
+
"spreadsheet",
|
|
50
|
+
"parser",
|
|
51
|
+
"formula",
|
|
52
|
+
"cello",
|
|
53
|
+
"tabular"
|
|
54
|
+
],
|
|
55
|
+
"license": "GPL-3.0-only",
|
|
56
|
+
"author": "Nacho Godino",
|
|
57
|
+
"repository": {
|
|
58
|
+
"type": "git",
|
|
59
|
+
"url": "git+https://github.com/nachoggodino/cello.git"
|
|
60
|
+
},
|
|
61
|
+
"bugs": {
|
|
62
|
+
"url": "https://github.com/nachoggodino/cello/issues"
|
|
63
|
+
},
|
|
64
|
+
"homepage": "https://github.com/nachoggodino/cello#readme",
|
|
65
|
+
"overrides": {
|
|
66
|
+
"glob": "^13.0.0"
|
|
67
|
+
},
|
|
68
|
+
"dependencies": {
|
|
69
|
+
"hyperformula": "^3.0.0"
|
|
70
|
+
},
|
|
71
|
+
"devDependencies": {
|
|
72
|
+
"@codemirror/autocomplete": "^6.18.7",
|
|
73
|
+
"@codemirror/commands": "^6.8.1",
|
|
74
|
+
"@codemirror/language": "^6.11.3",
|
|
75
|
+
"@codemirror/search": "^6.5.11",
|
|
76
|
+
"@codemirror/state": "^6.5.2",
|
|
77
|
+
"@codemirror/view": "^6.38.8",
|
|
78
|
+
"@eslint/js": "^10.0.1",
|
|
79
|
+
"@lezer/highlight": "^1.2.1",
|
|
80
|
+
"@types/node": "^25.8.0",
|
|
81
|
+
"@types/react": "^19.2.7",
|
|
82
|
+
"@types/react-dom": "^19.2.3",
|
|
83
|
+
"@vitejs/plugin-react": "^6.0.2",
|
|
84
|
+
"@vitest/coverage-v8": "^4.1.6",
|
|
85
|
+
"eslint": "^10.4.0",
|
|
86
|
+
"eslint-plugin-react-hooks": "^7.1.1",
|
|
87
|
+
"eslint-plugin-react-refresh": "^0.5.2",
|
|
88
|
+
"globals": "^17.6.0",
|
|
89
|
+
"react": "^19.2.3",
|
|
90
|
+
"react-dom": "^19.2.3",
|
|
91
|
+
"typescript": "^6.0.3",
|
|
92
|
+
"typescript-eslint": "^8.59.3",
|
|
93
|
+
"vite": "^8.0.13",
|
|
94
|
+
"vitest": "^4.1.6"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"comments": {
|
|
3
|
+
"lineComment": "//"
|
|
4
|
+
},
|
|
5
|
+
"brackets": [
|
|
6
|
+
["[", "]"],
|
|
7
|
+
["(", ")"],
|
|
8
|
+
["{", "}"]
|
|
9
|
+
],
|
|
10
|
+
"autoClosingPairs": [
|
|
11
|
+
{ "open": "[", "close": "]" },
|
|
12
|
+
{ "open": "(", "close": ")" },
|
|
13
|
+
{ "open": "{", "close": "}" },
|
|
14
|
+
{ "open": "\"", "close": "\"" },
|
|
15
|
+
{ "open": "|", "close": " |", "notIn": ["string"] }
|
|
16
|
+
],
|
|
17
|
+
"surroundingPairs": [
|
|
18
|
+
{ "open": "[", "close": "]" },
|
|
19
|
+
{ "open": "(", "close": ")" },
|
|
20
|
+
{ "open": "{", "close": "}" },
|
|
21
|
+
{ "open": "\"", "close": "\"" },
|
|
22
|
+
{ "open": "|", "close": "|" }
|
|
23
|
+
],
|
|
24
|
+
"folding": {
|
|
25
|
+
"markers": {
|
|
26
|
+
"start": "^\\s*@sheet\\b",
|
|
27
|
+
"end": "^\\s*(?=@sheet\\b)"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"wordPattern": "(-?\\d*\\.\\d\\w*)|([^`~!@#$%^&*()=+[{\\]}\\\\|;:'\",.<>/?\\s]+)"
|
|
31
|
+
}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
|
|
3
|
+
"name": "Cello",
|
|
4
|
+
"scopeName": "source.cel",
|
|
5
|
+
"fileTypes": ["cel"],
|
|
6
|
+
"patterns": [
|
|
7
|
+
{ "include": "#comments" },
|
|
8
|
+
{ "include": "#sheet-declaration" },
|
|
9
|
+
{ "include": "#external-source" },
|
|
10
|
+
{ "include": "#header-row" },
|
|
11
|
+
{ "include": "#defaults-row" },
|
|
12
|
+
{ "include": "#native-row" },
|
|
13
|
+
{ "include": "#json" },
|
|
14
|
+
{ "include": "#delimited-values" }
|
|
15
|
+
],
|
|
16
|
+
"repository": {
|
|
17
|
+
"comments": {
|
|
18
|
+
"name": "comment.line.double-slash.cel",
|
|
19
|
+
"match": "^\\s*(//).*$",
|
|
20
|
+
"captures": {
|
|
21
|
+
"1": { "name": "punctuation.definition.comment.cel" }
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"sheet-declaration": {
|
|
25
|
+
"name": "meta.sheet.declaration.cel",
|
|
26
|
+
"match": "^\\s*(@sheet)\\b(?:\\s+([^\\[\\r\\n]+?))?(?:\\s+(\\[)([^\\]\\r\\n]+)(\\]))?\\s*$",
|
|
27
|
+
"captures": {
|
|
28
|
+
"1": { "name": "keyword.control.sheet.cel" },
|
|
29
|
+
"2": {
|
|
30
|
+
"name": "entity.name.section.sheet.cel",
|
|
31
|
+
"patterns": [{ "include": "#identifiers" }]
|
|
32
|
+
},
|
|
33
|
+
"3": { "name": "punctuation.definition.format.begin.cel" },
|
|
34
|
+
"4": {
|
|
35
|
+
"name": "storage.type.format.cel",
|
|
36
|
+
"patterns": [
|
|
37
|
+
{ "match": "\\b(?:csv|tsv|excel|markdown|json|noheader)\\b", "name": "support.constant.format.cel" },
|
|
38
|
+
{ "match": "\\\\t|[,;|:]", "name": "constant.character.delimiter.cel" }
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
"5": { "name": "punctuation.definition.format.end.cel" }
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"external-source": {
|
|
45
|
+
"name": "meta.external-source.cel",
|
|
46
|
+
"match": "^\\s*(->)\\s*(.+)$",
|
|
47
|
+
"captures": {
|
|
48
|
+
"1": { "name": "keyword.operator.source.cel" },
|
|
49
|
+
"2": { "name": "string.unquoted.path.cel" }
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"header-row": {
|
|
53
|
+
"name": "meta.header.row.cel",
|
|
54
|
+
"begin": "^\\s*(@header)\\b",
|
|
55
|
+
"beginCaptures": {
|
|
56
|
+
"1": { "name": "keyword.control.header.cel" }
|
|
57
|
+
},
|
|
58
|
+
"end": "$",
|
|
59
|
+
"patterns": [{ "include": "#row-content" }]
|
|
60
|
+
},
|
|
61
|
+
"defaults-row": {
|
|
62
|
+
"name": "meta.defaults.row.cel",
|
|
63
|
+
"begin": "^\\s*(@defaults)\\b",
|
|
64
|
+
"beginCaptures": {
|
|
65
|
+
"1": { "name": "keyword.control.defaults.cel" }
|
|
66
|
+
},
|
|
67
|
+
"end": "$",
|
|
68
|
+
"patterns": [{ "include": "#row-content" }]
|
|
69
|
+
},
|
|
70
|
+
"native-row": {
|
|
71
|
+
"name": "meta.table.row.cel",
|
|
72
|
+
"begin": "^\\s*(?=(?:\\[[^\\]\\r\\n]+\\]\\s*)*\\|)",
|
|
73
|
+
"end": "$",
|
|
74
|
+
"patterns": [
|
|
75
|
+
{ "include": "#row-modifiers" },
|
|
76
|
+
{ "include": "#row-content" }
|
|
77
|
+
]
|
|
78
|
+
},
|
|
79
|
+
"row-content": {
|
|
80
|
+
"patterns": [
|
|
81
|
+
{ "include": "#cell-separator" },
|
|
82
|
+
{ "include": "#formula" },
|
|
83
|
+
{ "include": "#merge-token" },
|
|
84
|
+
{ "include": "#modifiers" },
|
|
85
|
+
{ "include": "#forced-string" },
|
|
86
|
+
{ "include": "#inline-heading" },
|
|
87
|
+
{ "include": "#inline-strong" },
|
|
88
|
+
{ "include": "#inline-emphasis" },
|
|
89
|
+
{ "include": "#inline-strike" },
|
|
90
|
+
{ "include": "#dates" },
|
|
91
|
+
{ "include": "#booleans" },
|
|
92
|
+
{ "include": "#numbers" },
|
|
93
|
+
{ "include": "#identifiers" }
|
|
94
|
+
]
|
|
95
|
+
},
|
|
96
|
+
"row-modifiers": {
|
|
97
|
+
"name": "meta.modifier.row.cel",
|
|
98
|
+
"match": "\\G\\s*(\\[[^\\]\\r\\n]+\\]\\s*)+(?=\\|)",
|
|
99
|
+
"captures": {
|
|
100
|
+
"1": {
|
|
101
|
+
"name": "meta.modifier.cel",
|
|
102
|
+
"patterns": [{ "include": "#modifiers" }]
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
"cell-separator": {
|
|
107
|
+
"name": "punctuation.separator.cell.cel",
|
|
108
|
+
"match": "\\|"
|
|
109
|
+
},
|
|
110
|
+
"merge-token": {
|
|
111
|
+
"name": "keyword.operator.merge.cel",
|
|
112
|
+
"match": "\\s*(<|\\^)\\s*(?=\\||$)"
|
|
113
|
+
},
|
|
114
|
+
"formula": {
|
|
115
|
+
"name": "meta.formula.cel",
|
|
116
|
+
"begin": "\\s*(=)",
|
|
117
|
+
"beginCaptures": {
|
|
118
|
+
"1": { "name": "punctuation.definition.formula.cel" }
|
|
119
|
+
},
|
|
120
|
+
"end": "(?=\\||$)",
|
|
121
|
+
"patterns": [
|
|
122
|
+
{ "include": "#formula-functions" },
|
|
123
|
+
{ "include": "#formula-ranges" },
|
|
124
|
+
{ "include": "#formula-operators" },
|
|
125
|
+
{ "include": "#forced-string" },
|
|
126
|
+
{ "include": "#dates" },
|
|
127
|
+
{ "include": "#booleans" },
|
|
128
|
+
{ "include": "#numbers" },
|
|
129
|
+
{ "include": "#identifiers" }
|
|
130
|
+
]
|
|
131
|
+
},
|
|
132
|
+
"formula-functions": {
|
|
133
|
+
"name": "support.function.formula.cel",
|
|
134
|
+
"match": "\\b[A-Z][A-Z0-9_]*(?=\\s*\\()"
|
|
135
|
+
},
|
|
136
|
+
"formula-ranges": {
|
|
137
|
+
"patterns": [
|
|
138
|
+
{
|
|
139
|
+
"name": "variable.other.sheet-reference.cel",
|
|
140
|
+
"match": "(?:!!|[A-Za-z_][\\w.-]*!)"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"name": "constant.other.cell-reference.cel",
|
|
144
|
+
"match": "\\b[A-Z]+[1-9][0-9]*\\b"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"name": "meta.range.slice.cel",
|
|
148
|
+
"match": "\\[(?:\\*|[1-9][0-9]*:[1-9][0-9]*)\\]",
|
|
149
|
+
"captures": {
|
|
150
|
+
"0": { "name": "constant.other.range.cel" }
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
]
|
|
154
|
+
},
|
|
155
|
+
"formula-operators": {
|
|
156
|
+
"name": "keyword.operator.formula.cel",
|
|
157
|
+
"match": "<=|>=|<>|[+\\-*/^&=<>(),:]|!"
|
|
158
|
+
},
|
|
159
|
+
"modifiers": {
|
|
160
|
+
"name": "meta.modifier.cel",
|
|
161
|
+
"begin": "\\[",
|
|
162
|
+
"beginCaptures": {
|
|
163
|
+
"0": { "name": "punctuation.definition.modifier.begin.cel" }
|
|
164
|
+
},
|
|
165
|
+
"end": "\\]",
|
|
166
|
+
"endCaptures": {
|
|
167
|
+
"0": { "name": "punctuation.definition.modifier.end.cel" }
|
|
168
|
+
},
|
|
169
|
+
"patterns": [
|
|
170
|
+
{ "match": "\\b(?:bold|italic|hidden)\\b", "name": "storage.modifier.style.cel" },
|
|
171
|
+
{ "match": "\\b(?:tone)(:)(?:ok|warn|error|info|muted|accent)\\b", "name": "support.constant.tone.cel", "captures": { "1": { "name": "punctuation.separator.key-value.cel" } } },
|
|
172
|
+
{ "match": "\\b(?:bg|default)(:)", "name": "support.type.modifier-key.cel", "captures": { "1": { "name": "punctuation.separator.key-value.cel" } } },
|
|
173
|
+
{ "match": "#(?:[0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})\\b", "name": "constant.other.color.rgb-value.cel" },
|
|
174
|
+
{ "match": "#bg:", "name": "support.type.color-shorthand.cel" },
|
|
175
|
+
{ "match": "[€$£%]", "name": "constant.character.currency.cel" },
|
|
176
|
+
{ "match": "\\b[0-9]+d\\b", "name": "constant.numeric.decimal-places.cel" },
|
|
177
|
+
{ "match": "\\b[a-zA-Z][a-zA-Z0-9-]*\\b", "name": "constant.language.color-name.cel" },
|
|
178
|
+
{ "include": "#formula" }
|
|
179
|
+
]
|
|
180
|
+
},
|
|
181
|
+
"forced-string": {
|
|
182
|
+
"name": "string.quoted.double.cel",
|
|
183
|
+
"begin": "\"",
|
|
184
|
+
"beginCaptures": {
|
|
185
|
+
"0": { "name": "punctuation.definition.string.begin.cel" }
|
|
186
|
+
},
|
|
187
|
+
"end": "\"",
|
|
188
|
+
"endCaptures": {
|
|
189
|
+
"0": { "name": "punctuation.definition.string.end.cel" }
|
|
190
|
+
},
|
|
191
|
+
"patterns": [
|
|
192
|
+
{ "name": "constant.character.escape.cel", "match": "\\\\." }
|
|
193
|
+
]
|
|
194
|
+
},
|
|
195
|
+
"inline-heading": {
|
|
196
|
+
"patterns": [
|
|
197
|
+
{ "name": "markup.heading.1.cel", "match": "\\s*##\\s+[^|\\r\\n]+" },
|
|
198
|
+
{ "name": "markup.heading.2.cel", "match": "\\s*#\\s+[^|\\r\\n]+" }
|
|
199
|
+
]
|
|
200
|
+
},
|
|
201
|
+
"inline-strong": {
|
|
202
|
+
"name": "markup.bold.cel",
|
|
203
|
+
"begin": "(?<!\\*)\\*",
|
|
204
|
+
"end": "\\*(?!\\*)"
|
|
205
|
+
},
|
|
206
|
+
"inline-emphasis": {
|
|
207
|
+
"name": "markup.italic.cel",
|
|
208
|
+
"begin": "(?<!\\w)_",
|
|
209
|
+
"end": "_(?!\\w)"
|
|
210
|
+
},
|
|
211
|
+
"inline-strike": {
|
|
212
|
+
"name": "markup.strikethrough.cel",
|
|
213
|
+
"begin": "~~",
|
|
214
|
+
"end": "~~"
|
|
215
|
+
},
|
|
216
|
+
"dates": {
|
|
217
|
+
"name": "constant.other.date.iso.cel",
|
|
218
|
+
"match": "\\b[0-9]{4}-[0-9]{2}-[0-9]{2}\\b"
|
|
219
|
+
},
|
|
220
|
+
"booleans": {
|
|
221
|
+
"name": "constant.language.boolean.cel",
|
|
222
|
+
"match": "\\b(?:TRUE|FALSE|true|false|null)\\b"
|
|
223
|
+
},
|
|
224
|
+
"numbers": {
|
|
225
|
+
"name": "constant.numeric.cel",
|
|
226
|
+
"match": "(?<![\\w.])-?(?:\\d+\\.\\d+|\\d+|\\.\\d+)\\b"
|
|
227
|
+
},
|
|
228
|
+
"identifiers": {
|
|
229
|
+
"name": "variable.other.identifier.cel",
|
|
230
|
+
"match": "\\b[A-Za-z_][\\w.-]*\\b"
|
|
231
|
+
},
|
|
232
|
+
"json": {
|
|
233
|
+
"patterns": [
|
|
234
|
+
{ "include": "#forced-string" },
|
|
235
|
+
{ "match": "[{}\\[\\],:]", "name": "punctuation.definition.json.cel" },
|
|
236
|
+
{ "include": "#booleans" },
|
|
237
|
+
{ "include": "#numbers" }
|
|
238
|
+
]
|
|
239
|
+
},
|
|
240
|
+
"delimited-values": {
|
|
241
|
+
"patterns": [
|
|
242
|
+
{ "include": "#forced-string" },
|
|
243
|
+
{ "include": "#dates" },
|
|
244
|
+
{ "include": "#booleans" },
|
|
245
|
+
{ "include": "#numbers" },
|
|
246
|
+
{ "match": "[,;\\t]", "name": "punctuation.separator.delimited.cel" }
|
|
247
|
+
]
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|