Group
A Group is a parenthesised sub-formula with an outer multiplicity.
Bracket variants are preserved: (, [, {.
Fields
Section titled “Fields”| Field | Type | Source | Example |
|---|---|---|---|
nodes | Array of Node | inside the brackets | OH |
multiplicity | String | suffix _N | 2 |
bracket | Symbol | the bracket chars | :paren, :square, :brace |
Bracket kinds
Section titled “Bracket kinds”| Kind | Open / Close | Use |
|---|---|---|
:paren | ( ) | Generic grouping (Ca(OH)_2) |
:square | [ ] | Coordination complexes ([Fe(CN)_6]^4-) |
:brace | { } | Rare / optional |
Diagram
Section titled “Diagram” ┌───────────────────────┐ open_bracket ───►│ Group │ │ │ │ nodes[0] ──┐ │ │ nodes[1] ──┤ │ │ ... │ │ │ │ │ close_bracket ──►│ multiplicity ─── `_N`│ │ bracket ─────── which kind └───────────────────────┘Grammar production
Section titled “Grammar production”group := group_open nodes group_close multiplicity?nodes := node+group_open := "(" | "[" | "{"group_close:= ")" | "]" | "}"multiplicity := "_" digitsThe grammar preserves which bracket was used; the model’s bracket
field carries it through.
Formatter behaviour
Section titled “Formatter behaviour”| Formatter | Brackets | Multiplicity |
|---|---|---|
| MathML | <mo>(</mo> / <mo>)</mo> around inner | <msub> wrapping the inner <mrow> |
| Text | Literal bracket chars preserved | _N suffix |
| HTML | Literal bracket chars | <sub>N</sub> |
| LaTeX | mhchem bracket chars | _N (bare digits) |
| SVG | Literal bracket chars | _N suffix |
Round-trip
Section titled “Round-trip”AsciiChem.parse("Ca(OH)_2").to_text # => "Ca(OH)_2"AsciiChem.parse("[Fe(CN)_6]^4-").to_text # => "[Fe(CN)_6]^4-" (square preserved)AsciiChem.parse("{CH_3}").to_text # => "{CH_3}" (brace preserved)Bracket kind is preserved exactly — (OH)_2 stays as (OH)_2, not
canonicalised to [OH]_2.
Children contract
Section titled “Children contract”class Group def children nodes endendThe linter’s BalanceCheck recurses into groups, applying the
multiplicity to the inner atom counts.
Linter checks
Section titled “Linter checks”- BracketBalanceCheck — verifies
bracketfield matches the stored open/close characters. Defensive depth — the grammar already enforces matching pairs, but direct model construction might not.