Genogram
About genograms
A genogram is a family diagram that goes beyond the names-and-dates of a traditional family tree: it records the emotional and medical texture of a family across three or more generations. Therapists, social workers, and genetic counselors use them to surface patterns — cut-offs, over-involvement, recurring illnesses — that are hard to see in prose case notes.
Schematex follows the McGoldrick, Gerson & Petry (2020) standard used in clinical training, plus the widely adopted GenoPro 32-type emotional-relationship taxonomy. For theory and history see Wikipedia: Genogram. This page documents what the parser accepts today.
1. Your first genogram
The smallest clinically useful genogram: two parents, one child.
Four rules cover 80% of usage:
- Start with the keyword
genogram, optionally followed by a quoted title. - Declare each person on their own line:
id [attributes]. Attributes go in square brackets, comma-separated. - Connect two people with a couple operator —
--(marriage) here; see §4.1 for all six. A trailing quoted string is the relationship label. - Indent under the couple line to add their children.
Comments must be on their own line, starting with
#,//, or Mermaid-style%%. Trailing inline comments (bob [male, 1978] # ...) are not supported and will break the parser — see §8.
2. Individuals
An individual line is id [attr1, attr2, …]. Attributes are comma-separated, order-independent, all optional.
ID rules. Must match [a-zA-Z][a-zA-Z0-9_-]*. IDs are case-insensitive internally but preserve their original casing as the display label (override with label:"…").
Attributes accepted by the parser today:
| Attribute | Values | Effect |
|---|---|---|
| Sex | male, female, unknown, other | Shape: square, circle, diamond, diamond |
| Status | deceased, stillborn, miscarriage, abortion | Visual modifier (X-out, scaled shape, etc.) |
| Birth year | 4-digit number, e.g. 1980 | First 4-digit token = birth year |
| Death year | 4-digit number after birth, e.g. 1980, 2055 | Second 4-digit token = death year |
index | flag | Concentric shape = identified patient |
unknown-siblings | flag | Diamond with ? — placeholder for ≥1 siblings of unknown count |
age:N | e.g. age:42 | Age shown inside shape |
death:YYYY | e.g. death:2020 | Explicit death year |
label:"…" | e.g. label:"Dr. Smith" | Display label override |
sibling-of:<id> | e.g. sibling-of:monica | Pins same generation as the referenced sibling, draws a dashed bracket — for known relatives with unknown ancestry. |
conditions:… | see §5 | Medical/psychological conditions |
key:value | any custom | Stored as metadata |
3. Shapes
| Visual | Sex value | Meaning |
|---|---|---|
| ☐ Square | male | Male |
| ○ Circle | female | Female |
| ◇ Diamond | unknown, other, or attribute omitted | Unknown / unspecified |
Status modifiers layer on top of the base shape:
4. Connections
4.1 Couple operators
The parser tries these in order. The first one that matches wins — so -x- beats --.
| Operator | Type | Example | Meaning |
|---|---|---|---|
-x- | divorced | a -x- b | Divorce |
-/- | separated | a -/- b | Separation (married) |
-// | separated | a -// b | Separation (alias for -/-) |
-o- | engaged | a -o- b | Engagement |
== | consanguineous | a == b | Blood-related couple |
-- | married | a -- b | Marriage |
~ | cohabiting | a ~ b | Cohabiting / LTR (current) |
~/~ | cohabiting-ended | a ~/~ b | Cohabitation has ended (never-married). Common in LATAM child-protection caseloads where biological parents lived together unmarried and the relationship has since broken — distinct from -x- divorce (no marriage) and -/- separation (still married). |
A trailing quoted string becomes the relationship label (a -- b "m. 2005").
4.2 Inline individual on the right side
If the right-hand person hasn't been declared yet, you can declare them in-place:
4.3 Children (indented under a couple)
Indentation under a couple line = "these are the children of this couple." Any indent greater than the couple's indent works; by convention use 2 more spaces. Children are rendered in order of declaration (render also sorts by birth year when present).
Special child attributes:
| Attribute | Effect |
|---|---|
adopted | Adoption line style |
foster | Foster relationship |
guardian | Guardianship by a non-parent relative (e.g. grandparent custody). Same primitive as foster — drawn as a secondary "current caregiver" link when biological parents are also declared. |
twin-identical | Grouped with other twin-identical children of the same couple |
twin-fraternal | Grouped with other twin-fraternal children |
unknown-siblings | Single diamond with ? glyph — "≥1 siblings, count and identities unknown" (pedigree convention). |
4.3.1 Dual-parent families (foster, adoption, guardianship)
Children placed with a non-biological caregiver while biological parents are still part of the case can be declared under both couples. Declare the child with full attributes the first time (under the biological couple), then redeclare with just [foster] / [adopted] / [guardian] under the current caregiver. The first declaration wins layout; the second is drawn as a secondary dotted "current caregiver" link that does not pull the child away from their biological position.
The same primitive serves adoption (closed/open), foster placement, and guardianship by a relative — only the keyword differs. Re-declaration merges non-conflicting attributes (sex, birth year, label, index marker) into the original; declaring a conflicting male vs female raises a parse error rather than silently overwriting.
4.3.2 Unknown-count siblings
When a case file mentions "the child has siblings" without naming them, use either the ? shorthand on its own line, or [unknown-siblings] on a regular id. Both render as a single diamond with a "?" glyph — the standard pedigree marker for "one or more siblings, identities unknown."
4.3.3 Sibling-of (known relative, unknown ancestry)
To express "X is a sibling of Y" without inventing parents, use the sibling-of: <id> property. The renderer pins X to Y's generation and draws a dashed bracket above the two — the standard pedigree convention for a known relative whose ancestry is not part of the case.
4.4 Emotional relationships
Separate line, parser pattern A -TYPE- B (non-directional) or A -TYPE-> B (directional). An optional quoted label goes at the end. Both individuals must already be declared before the emotional line.
harry -cutoff- petunia # non-directional
harry -hostile- dudley "since 1991"
uncle -abuse-> nephew # directional (arrow)All 32 types the parser accepts today:
| Category | Types |
|---|---|
| Positive / close | harmony, close, bestfriends, love, inlove, friendship |
| Negative / hostile | hostile, conflict, enmity, distant-hostile, cutoff |
| Ambivalent | close-hostile, fused, fused-hostile |
| Distance | distant, normal, nevermet |
| Abuse (directional) | abuse, physical-abuse, emotional-abuse, sexual-abuse, neglect |
| Control (directional) | manipulative, controlling, jealous |
| Special | focused, focused-neg, distrust, admirer, limerence |
5. Medical conditions
Syntax: conditions: name(fill) [+ name(fill, #color)]…
father [male, 1945, conditions: heart(full, #E53935)]
mother [female, 1948, conditions: diabetes(half-left) + anxiety(half-right, #26A69A)]name— any identifier you choose (displayed in legend/tooltip).fill— required, controls which region of the shape is colored. See table below.color— optional hex. Default depends on the renderer theme.- Multiple conditions are joined with
+. Each needs its own(fill).
Fill positions:
fill value | Region |
|---|---|
full | Entire shape |
half-left / half-right | Left / right half |
half-top / half-bottom | Top / bottom half |
quad-tl / quad-tr / quad-bl / quad-br | One quadrant |
striped | Diagonal stripe pattern (asymptomatic carrier) |
dotted | Dot pattern |
6. Labels & comments
- Title:
genogram "Smith Family"— first line only. - Person label override:
alice [female, label:"Dr. Alice Smith"]. - Relationship label: trailing quoted string on a couple or emotional line —
alice -- bob "m. 2005". - Comments:
#,//, or%%at the start of a line (after leading whitespace). Inline comments are not supported.
genogram "Smith Family"
# this line is a comment — fine
%% Mermaid-style comment — also fine
alice [female, 1980] # ← THIS trailing comment breaks the parser7. Reserved words & escaping
Reserved at line start: genogram (header keyword).
Reserved operator tokens inside a line — avoid using these sequences in IDs:
--, ~, ~/~, ==, -x-, -/-, -//, -o-, and any -<type>- / -<type>-> matching an emotional-relationship type.
Reserved id ? — bare ? on a child line auto-generates a synthetic placeholder with the unknown-siblings marker. Do not use ? as a real id.
Strings with spaces must be double-quoted: titles, labels, label:"…". Single quotes and backticks are not recognized.
8. Common mistakes
Real parser errors, what triggers them, and how to fix.
| You wrote | Parser says | Fix |
|---|---|---|
alex [nonbinary, 1995] | Unknown property 'nonbinary' | Use unknown or other (nonbinary is §13 Roadmap) |
alice [female, transgender] | Unknown property 'transgender' | Not yet parseable (§13 Roadmap) |
dad -- mom ← followed by child [male, 2010] at the same indent | Child parsed as a new top-level individual, not as their child | Indent the child line deeper than the couple line (2 spaces is enough) |
A -- B where A was never declared | Unknown individual 'A' | Declare A [sex, year] on a line above |
father -- mother "married" on line 1 (no genogram header) | Expected "genogram" header | Start the file with genogram or genogram "Title" |
conditions: diabetes + cancer (no parens) | Invalid condition format 'diabetes' | Add fill: conditions: diabetes(half-left) + cancer(half-right) |
[triplet-identical] | Unknown property 'triplet-identical' | Triplets not yet parseable (§13 Roadmap) |
dad -- mom # first marriage | Trailing inline # comment is treated as part of the label / errors | Move the comment to its own line |
Same id declared twice with different sex (x [male] then x [female]) | Conflicting sex for 'x': previously 'male', now 'female' | Pick one or rename one of the ids |
child [foster] redeclared but biological parents never declared | child becomes the foster couple's regular child (no secondary link drawn) | This is intentional — secondary links require an existing primary parent-child rel from a prior declaration |
9. Grammar (EBNF)
document = header (blank | comment | individual | couple-block | emotional)*
header = "genogram" ( WS quoted-string )? NEWLINE
quoted-string = '"' any-char-but-quote* '"'
individual = INDENT id ( "[" attrs "]" )? NEWLINE
couple-block = INDENT id WS coupleOp WS right-side ( WS quoted-string )? NEWLINE
( deeper-indent child )*
child = INDENT id ( "[" attrs "]" )? NEWLINE
| INDENT "?" NEWLINE // unknown-count sibling shorthand
right-side = id ( "[" attrs "]" )?
emotional = INDENT id WS "-" type "-" id ( WS quoted-string )? NEWLINE
| INDENT id WS "-" type "->" id ( WS quoted-string )? NEWLINE
coupleOp = "~/~" | "-//" | "-x-" | "-/-" | "-o-" | "==" | "--" | "~"
type = "harmony" | "close" | "bestfriends" | "love" | "inlove"
| "friendship" | "hostile" | "conflict" | "enmity"
| "distant-hostile" | "cutoff" | "close-hostile" | "fused"
| "fused-hostile" | "distant" | "normal" | "nevermet"
| "abuse" | "physical-abuse" | "emotional-abuse"
| "sexual-abuse" | "neglect" | "manipulative" | "controlling"
| "jealous" | "focused" | "focused-neg" | "distrust"
| "admirer" | "limerence"
id = [a-zA-Z] [a-zA-Z0-9_-]*
attrs = attr ("," attr)*
attr = "male" | "female" | "unknown" | "other"
| "deceased" | "stillborn" | "miscarriage" | "abortion"
| "adopted" | "foster" | "guardian"
| "twin-identical" | "twin-fraternal"
| "index" | "unknown-siblings"
| digit digit digit digit // year
| "age" ":" digits
| "death" ":" digit digit digit digit
| "label" ":" quoted-string
| "sibling-of" ":" id
| "conditions" ":" condition ("+" condition)*
| key ":" value // custom
condition = name "(" fill ("," "#" hex)? ")"
fill = "full" | "half-left" | "half-right" | "half-top" | "half-bottom"
| "quad-tl" | "quad-tr" | "quad-bl" | "quad-br"
| "striped" | "dotted"
comment = INDENT ( "#" | "//" | "%%" ) any NEWLINEAuthoritative source: src/diagrams/genogram/parser.ts. If this diverges from the parser, the parser wins — please open an issue.
10. Standard compliance
Schematex genograms follow McGoldrick, Gerson & Petry (2020), Genograms: Assessment and Treatment, 4th ed. for structural symbols, couple operators, and generation alignment. Emotional-relationship taxonomy follows GenoPro's 32-type classification (we do not implement GenoPro's 34-type set in full; focused-admirer and one duplicate are folded into focused and admirer).
What is implemented today vs. the standard:
- ✅ Core structural symbols (male/female/unknown, deceased, stillborn, miscarriage, abortion)
- ✅ McGoldrick 6-operator couple system
- ✅ GenoPro 32 emotional types, directional where clinically specified
- ✅ Medical condition quadrant fill system (4-position + stripe/dot patterns)
- ✅ Index person (concentric shape)
- ✅ Twin groupings (identical / fraternal)
- ⏳ Bennett 2022 gender inclusivity additions — see §13
- ⏳ Donor / surrogate / step-child connection types — see §13
References:
- McGoldrick, M., Gerson, R., & Petry, S. (2020). Genograms: Assessment and Treatment (4th ed.).
- Hardy, K.V. & Laszloffy, T.A. (1995). The cultural genogram. J Marital Fam Ther, 21(3), 227–237.
- GenoPro symbol reference — https://genopro.com/genogram/
11. Related examples
Ready-to-use scenarios from the examples gallery:
13. Roadmap
Planned — not yet parseable. Do not use these in generated DSL today; the parser will reject them.
- Bennett 2022 gender inclusivity —
nonbinary,intersexas sex values;transgenderas a marker. Currently typed insrc/core/types.tsbut the parser'sVALID_SEXset does not yet include them. - Triplets and higher-order births —
triplet-identical,triplet-fraternal. - Modern family structures —
surrogate,donor,stepas child-type attributes. - Category shorthand for conditions —
conditions: cardiovascular + depressionwithout(fill), auto-assigning quadrants and default colors. - Domestic partnership operator —
~dp~/ explicit DP label. - Heritage annotations — cultural-genogram heritage identifiers on individuals.
- Household boundary boxes — group nodes that share a roof (foster placement, multi-generational household).
Track in the GitHub issues if you need any of these sooner.