Skip to content

Commit 761bda0

Browse files
author
Alex Bikeyev
committed
docs: clarify group purpose, add multi-dimensional view guidance, expand formatting with presets, and update script workflow examples
Update groups-and-hierarchies.md to describe groups as used for hierarchy, outline, navigation, and presentation (not just rules and views). Add multi-dimensional view example to views.md showing how third and subsequent dimensions become page/filter axes. Expand formatting.md with OM Core preset expressions section documenting preset:number() syntax and common parameters
1 parent 906cb38 commit 761bda0

10 files changed

Lines changed: 122 additions & 58 deletions

File tree

‎docs/concepts/groups-and-hierarchies.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ This separation lets the same dimension item participate in multiple hierarchies
1616
| Node | Graph occurrence or hierarchy node, identified by a node ID |
1717
| Edge | Parent/child or relation link between nodes |
1818
| Hierarchy | A tree of nodes built from parent/child edges |
19-
| Group | A named collection of dimension items or nodes used in rules and views |
19+
| Group | A named collection of dimension items or nodes used for hierarchy, outline, navigation, and presentation |
2020
| Outline | A read-only projection of a hierarchy for display |
2121

2222
## Graph primitives

‎docs/concepts/views.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ view SalesByProductAndMonth = Sales::Product:Month
3636

3737
Here, `Product` is the row dimension and `Month` is the column dimension.
3838

39+
A view with more than two dimensions:
40+
41+
```openm
42+
view SalesByProductAndMonthAndRegion = Sales::Product:Month:Region
43+
```
44+
45+
The first dimension is used for rows, the second for columns, and remaining dimensions become page or filter axes. The UI displays the selected page values and lets you switch between them. If you need a different layout, create a separate view with the dimensions in a different order.
46+
3947
## Activating a view
4048

4149
You can activate a view by giving its name without the cube assignment:

‎docs/reference/formatting.md‎

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,35 @@ CLDR also defines compact patterns for values like `1M` or `1 million`. These pa
5151

5252
## OM Core usage
5353

54-
When you set a format string in OM Core, you are writing a CLDR-style pattern. The engine resolves the pattern against the locale and value type of the cell or cube. This means the same model can be displayed correctly across different locales without changing the underlying data.
54+
When you set a format string in OM Core, you can write either a CLDR-style pattern or an OM Core preset expression.
5555

56-
For the full specification, see the CLDR documentation:
56+
### CLDR-style patterns
57+
58+
A CLDR-style pattern is a locale-aware pattern resolved against the cell or cube locale:
59+
60+
```openm
61+
rule PL::@.format_number:Account.*:Year.*:Scenario.* = "#,##0.00"
62+
```
63+
64+
This means the same model can be displayed correctly across different locales without changing the underlying data.
65+
66+
### OM Core preset expressions
67+
68+
A preset expression is a higher-level, readable directive that the engine maps to a concrete format. Presets are useful when you want explicit control over decimals, grouping, negative numbers, and zero display without writing a raw CLDR pattern:
69+
70+
```openm
71+
rule PL::@.format_number:Account.*:Year.*:Scenario.* = 'preset:number(decimals=2; group=true; negative=parentheses; zero=dash)'
72+
```
73+
74+
Common preset parameters include:
75+
76+
| Parameter | Meaning |
77+
| --- | --- |
78+
| `decimals` | Number of decimal places |
79+
| `group` | Use thousands grouping |
80+
| `negative` | Negative number style, e.g. `parentheses` |
81+
| `zero` | Zero display, e.g. `dash` |
82+
83+
For the full CLDR specification, see:
5784

5885
[Number and currency patterns — CLDR](https://cldr.unicode.org/translation/number-currency-formats/number-and-currency-patterns)

‎docs/reference/scripting.md‎

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,28 @@ OM Core scripts use the `.openm` extension. They are executed inside the OM Core
44

55
## Run a script
66

7-
Start OM Core and source the script file:
7+
For a single-terminal workflow, start the TUI and source the script directly:
88

99
```bash
10-
# Start the engine
10+
./start.sh --tui
11+
```
12+
13+
Then run the script inside the REPL:
14+
15+
```text
16+
om> source scripts/build_financial_model.openm
17+
```
18+
19+
For a multi-process workflow, use two terminals:
20+
21+
```bash
22+
# Terminal 1 — start the engine
1123
./start.sh --runtime
24+
```
1225

13-
# ... run commands in repl mode ...
26+
```bash
27+
# Terminal 2 — connect a client
1428
./start.sh --tui
15-
om> source scripts/build_financial_model.openm
1629
```
1730

1831
You can also run specific runtime modes directly:
@@ -23,8 +36,6 @@ You can also run specific runtime modes directly:
2336
./start.sh --tui # terminal interface
2437
```
2538

26-
`--runtime` starts the engine alone. In a multi-process setup, start `--runtime` in one terminal, then connect a client such as `--tui` or `--gui` in another. For a single-terminal workflow, use `--tui` after launching the engine via `--runtime` or the default `./start.sh`.
27-
2839
## First two commands
2940

3041
Once the REPL or TUI is running, start with `help` to see all documented commands.
@@ -58,7 +69,7 @@ dim Year --seq Y1 Y2 Y3 Y4 Y5
5869

5970
## Script structure
6071

61-
A typical `.openm` script follows this order:
72+
A small `.openm` script can follow this order:
6273

6374
1. Define dimensions
6475
2. Define cubes
@@ -67,6 +78,23 @@ A typical `.openm` script follows this order:
6778
5. Calculate
6879
6. Assert or save
6980

81+
For model bundles, use the numbered structure shown in the agent skill:
82+
83+
```text
84+
00_variables
85+
01_dimensions
86+
02_cubes
87+
03_inputs
88+
04_rules
89+
05_checks
90+
06_views
91+
07_formatting
92+
08_groups
93+
build.openm
94+
```
95+
96+
`build.openm` sources the other files in order and then runs `calc`. Tiny one-file scripts may use a simpler order.
97+
7098
```openm
7199
# Define dimensions
72100
dim Asset Vehicle
@@ -268,23 +296,28 @@ source scripts/depreciation_schedule.openm
268296

269297
Visual styling is applied through rule channels, not through a separate formatting command. The channel determines which property the rule sets.
270298

271-
OM Core stores values and presentation attributes in channels. The default value channel is `@.value` and is implied when no channel is specified. Style channels change only the appearance:
299+
OM Core stores values and presentation attributes in channels. The default value channel is `@.value` and is implied when no channel is specified. Style and format channels change only the appearance:
272300

301+
- `@.value` — the default value channel (implied when no channel is given)
302+
- `@.format_number` — number or currency display format
273303
- `@.fill` — the background fill color
274304
- `@.font_color` — the font color
305+
- `@.font_weight` — the font weight (e.g. `700` for bold)
275306

276-
Set a style with a rule:
307+
Set a style or format with a rule:
277308

278309
```openm
279310
rule C::@.fill:PL.Revenue:Year.2026 = #3B82F6
280311
rule C::@.font_color:PL.Revenue:Year.2026 = #FFFFFF
312+
rule C::@.font_weight:PL.Revenue:Year.2026 = 700
313+
rule C::@.format_number:PL.Revenue:Year.2026 = 'preset:number(decimals=2; group=true; negative=parentheses; zero=dash)'
281314
```
282315

283-
Style rules follow the same semantic addressing as value rules. A single semantic address can have both a value rule and multiple style rules.
316+
Style and format rules follow the same semantic addressing as value rules. A single semantic address can have both a value rule and multiple style rules.
284317

285318
### Number formatting
286319

287-
For number and currency display patterns, OM Core uses CLDR-style format strings. See [Formatting](formatting.md).
320+
For number and currency display patterns, OM Core supports both CLDR-style patterns and OM Core preset expressions. See [Formatting](formatting.md).
288321

289322
### Debugging
290323

‎docs/skills/om-core-financial-modeling/SKILLS.md‎

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,12 @@ Use variables to avoid repeating important names.
7777
Example:
7878

7979
```openm
80-
var model_name = "SaaS Revenue Model"
81-
var pl_cube = PL
82-
var account_dim = Account
83-
var month_dim = Month
84-
var scenario_dim = Scenario
85-
var base_scenario = Base
80+
model_name="SaaS Revenue Model"
81+
pl_cube="PL"
82+
account_dim="Account"
83+
month_dim="Month"
84+
scenario_dim="Scenario"
85+
base_scenario="Base"
8686
```
8787

8888
Use `{{...}}` macro expansion to compose commands:
@@ -101,7 +101,7 @@ Use macro expansion for:
101101
* reusable script templates
102102
* model variants
103103

104-
Avoid using macro expansion to hide business logic. Rules should remain readable after expansion.
104+
Avoid using macro expansion to hide business logic. Rules should remain readable after expansion. In concrete example bundles, variables are typically used for cube and dimension declarations, while cube names in rules and views may be hardcoded for readability. Reserve full macro saturation for reusable templates and model variants.
105105

106106
## 5. Naming Conventions
107107

@@ -296,9 +296,7 @@ cube Checks Check Month Scenario
296296
Example rules:
297297

298298
```openm
299-
rule Checks::Check.GrossProfitCheck:Month.*:Scenario.* =
300-
PL::[Account.GrossProfit]
301-
- (PL::[Account.Revenue] - PL::[Account.COGS])
299+
rule Checks::Check.GrossProfitCheck:Month.*:Scenario.* = PL::[Account.GrossProfit] - (PL::[Account.Revenue] - PL::[Account.COGS])
302300
```
303301

304302
A check should equal zero when the model is valid.
@@ -326,16 +324,14 @@ For reusable model templates, use variables at the top.
326324
Example template:
327325

328326
```openm
329-
var pl_cube = {{pl_cube}}
330-
var account_dim = {{account_dim}}
331-
var time_dim = {{time_dim}}
332-
var scenario_dim = {{scenario_dim}}
327+
pl_cube="{{pl_cube}}"
328+
account_dim="{{account_dim}}"
329+
time_dim="{{time_dim}}"
330+
scenario_dim="{{scenario_dim}}"
333331
334332
cube {{pl_cube}} {{account_dim}} {{time_dim}} {{scenario_dim}}
335333
336-
rule {{pl_cube}}::{{account_dim}}.GrossProfit:{{time_dim}}.*:{{scenario_dim}}.* =
337-
{{pl_cube}}::[{{account_dim}}.Revenue]
338-
- {{pl_cube}}::[{{account_dim}}.COGS]
334+
rule {{pl_cube}}::{{account_dim}}.GrossProfit:{{time_dim}}.*:{{scenario_dim}}.* = {{pl_cube}}::[{{account_dim}}.Revenue] - {{pl_cube}}::[{{account_dim}}.COGS]
339335
```
340336

341337
When generating a concrete model from a template, substitute variables before execution.
@@ -402,8 +398,8 @@ calc
402398
Example P&L grouping:
403399

404400
```text
405-
om> group create PLAccount "Revenue" Revenue
406-
om> group create PLAccount "COGS" COGS
401+
om> group create PLAccount "Revenue Section" Revenue
402+
om> group create PLAccount "COGS Section" COGS
407403
om> group create PLAccount "Operating Expenses" Salaries Marketing Rent
408404
om> group create PLAccount "Totals" GrossProfit EBITDA NetIncome
409405
```
@@ -414,7 +410,7 @@ Example balance sheet grouping:
414410
om> group create BSAccount "Current Assets" Cash AccountsReceivable Inventory
415411
om> group create BSAccount "Fixed Assets" GrossPPE AccumulatedDepreciation NetPPE
416412
om> group create BSAccount "Liabilities" AccountsPayable Debt
417-
om> group create BSAccount "Equity" Equity
413+
om> group create BSAccount "Equity Section" Equity
418414
om> group create BSAccount "Total" TotalAssets TotalLiabilitiesAndEquity
419415
```
420416

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
var plant_dim = Plant
2-
var plant_data_dim = PlantData
3-
var initial_cost_dim = InitialCost
4-
var plant_age_dim = PlantAge
5-
var lifecycle_cost_dim = LifecycleCost
6-
var assumption_dim = Assumption
7-
var metric_dim = Metric
8-
var check_dim = Check
1+
plant_dim="Plant"
2+
plant_data_dim="PlantData"
3+
initial_cost_dim="InitialCost"
4+
plant_age_dim="PlantAge"
5+
lifecycle_cost_dim="LifecycleCost"
6+
assumption_dim="Assumption"
7+
metric_dim="Metric"
8+
check_dim="Check"
99

10-
var inventory_cube = Inventory
11-
var initial_costs_cube = InitialCosts
12-
var lifecycle_costs_cube = LifecycleCosts
13-
var assumptions_cube = Assumptions
14-
var summary_cube = Summary
15-
var checks_cube = Checks
10+
inventory_cube="Inventory"
11+
initial_costs_cube="InitialCosts"
12+
lifecycle_costs_cube="LifecycleCosts"
13+
assumptions_cube="Assumptions"
14+
summary_cube="Summary"
15+
checks_cube="Checks"

‎docs/skills/om-core-financial-modeling/examples/business-valuation-model/08_groups.openm‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Dimension outline groups for presentation
22

3-
group create PLAccount Revenue Revenue
3+
group create PLAccount "Revenue Section" Revenue
44

5-
group create PLAccount COGS COGS
5+
group create PLAccount "COGS Section" COGS
66

77
group create PLAccount "Operating Expenses" SGA Depreciation
88

@@ -16,7 +16,7 @@ group create BSAccount "Total Assets" TotalAssets
1616

1717
group create BSAccount Liabilities AccountsPayable Debt
1818

19-
group create BSAccount Equity Equity
19+
group create BSAccount "Equity Section" Equity
2020

2121
group create BSAccount "Total Liabilities & Equity" TotalLiabilitiesAndEquity
2222

‎docs/skills/om-core-financial-modeling/examples/manufacturing-capex-model/08_groups.openm‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Dimension outline groups for presentation
22

3-
group create Account Inputs CapEx OpeningGrossBlock
3+
group create Account "Input Items" CapEx OpeningGrossBlock
44

55
group create Account "Asset Value" GrossBlock AccumulatedDepreciation NetBookValue
66

‎docs/skills/om-core-financial-modeling/examples/saas-revenue-model/08_groups.openm‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
group create Account "Revenue Metrics" Revenue ARPU
44

5-
group create Account Customers Customers NewCustomers ChurnedCustomers ChurnRate
5+
group create Account "Customer Metrics" Customers NewCustomers ChurnedCustomers ChurnRate
66

77
group create Account Profitability COGS GrossProfit OperatingExpense EBITDA
88

‎docs/skills/om-core-group-management/SKILLS.md‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@ om> dim PLAccount Revenue COGS GrossProfit Salaries Marketing Rent EBITDA
121121
Create an outline:
122122

123123
```text
124-
om> group create PLAccount "Revenue" Revenue
125-
om> group create PLAccount "COGS" COGS
124+
om> group create PLAccount "Revenue Section" Revenue
125+
om> group create PLAccount "COGS Section" COGS
126126
om> group create PLAccount "Operating Expenses" Salaries Marketing Rent
127127
om> group list PLAccount
128128
```
@@ -131,8 +131,8 @@ Expected outline:
131131

132132
```text
133133
PLAccount
134-
Revenue
135-
COGS
134+
Revenue Section
135+
COGS Section
136136
Operating Expenses
137137
Salaries
138138
Marketing
@@ -150,7 +150,7 @@ om> dim BSAccount Cash AccountsReceivable Inventory GrossPPE AccumulatedDeprecia
150150
om> group create BSAccount "Current Assets" Cash AccountsReceivable Inventory
151151
om> group create BSAccount "Fixed Assets" GrossPPE AccumulatedDepreciation NetPPE
152152
om> group create BSAccount "Liabilities" AccountsPayable Debt
153-
om> group create BSAccount "Equity" Equity
153+
om> group create BSAccount "Equity Section" Equity
154154
om> group list BSAccount
155155
```
156156

0 commit comments

Comments
 (0)