The text generator
Use it when you have a short, fixed list of options to pick from — gender, status, category, payment type, tier. If you need exact shares of each (say, 60% one, 40% the other), that's a single extra attribute.
Example outputs below are illustrative — the exact values a given seed
produces can shift between core versions, but the counts that percent
guarantees never do.
At a glance
| Attribute | Required | What it does |
|---|---|---|
value | yes | The options, comma-separated: "a,b,c" |
percent | no | Exact share of each option; see below |
On top of these, text accepts the cross-cutting generator attributes —
case= / mask= for output formatting and
order= / cycle= for value order.
value — a list of options
The core parameter. For text, value is a comma-separated list of the
options to draw from; the generator picks one at random for each row.
<sequence name="Color">
<gen type="text" value="red,green,blue"/>
</sequence>
blue red green green red blue
With no percent, the choice is uniform — every option is equally likely,
and the same seed always reproduces the same sequence. Values may repeat
freely from row to row (green twice above); if you need every row to differ,
see Unique values.
For strict list order instead of random picks, add
order="sequential" — see Generators overview.
value reads differently per generatorvalue is every generator's main input, but its meaning depends on type.
In text it's a list of whole words; in number it's a numeric
range like 1..100; in date it's a date range or a mode word
like today; in regex it's a pattern. Same attribute, different
grammar — this page covers the text reading only.
Exact proportions with percent
This is what sets text apart from a plain random picker. Add percent and TDC
lays the values out to exact counts using the Hamilton (largest-remainder)
method — the number of times each value appears is guaranteed to match the
percentages. The randomness is only in the order.
<sequence name="Gender">
<gen type="text" value="Male,Female" percent="60,40"/>
</sequence>
The rows come out shuffled:
Female Male Female Male Male Male
…but count all of them and the split is exact. Over count="100":
Male 60 Female 40
Exactly 60 Male and 40 Female — not "about 60%", but 60. That's the whole
point of Hamilton: the totals are exact; only the order depends on the seed.
Shares that don't divide evenly
Three equal shares over 100 rows works out to 33.33% each, which is not a whole number of rows. Hamilton gives the extra row to the largest remainder, so the total is still exactly 100:
<sequence name="Grade">
<gen type="text" value="A,B,C" percent=",,"/>
</sequence>
A 34 B 33 C 33
34 + 33 + 33 = 100 — no row is lost or double-counted. Explicit shares are taken
just as literally:
<sequence name="Tier">
<gen type="text" value="gold,silver,bronze" percent="50,30,20"/>
</sequence>
gold 50 silver 30 bronze 20
Small counts
The guarantee is "the totals sum to count", which only lands on the exact
percentages when count can be split that way. With count="100" and
percent="50,50" you get exactly 50 and 50. With count="3" and the same split
you can't have two-and-a-half of each, so Hamilton rounds to either 2 + 1 or
1 + 2 — which value gets the extra row depends on the seed — but the two counts
always sum to 3. No row is ever dropped or duplicated.
Heads Tails Heads
Partial percent lists
You don't have to fill in every position. The rule is:
- A number fixes that value's share.
- Every empty position takes an equal cut of whatever is left of 100 — and "empty" means both a bare comma inside the list and any position past the end of a list that is shorter than the value list.
The Values column below gives the length of the value list the shares are applied to,
since the same percent expands differently depending on how many values there are:
percent | Values | Expands to | Why |
|---|---|---|---|
60 | 2 | 60,40 | value 1 = 60; value 2 takes the rest |
,58 | 2 | 42,58 | value 2 = 58; value 1 takes the rest |
,10,10 | 4 | 40,40,10,10 | values 3–4 = 10; values 1–2 split the remaining 80 |
46, | 5 | 46,13.5,13.5,13.5,13.5 | value 1 = 46; values 2–5 split the remaining 54 (÷4) |
,,25,, | 5 | 18.75,18.75,25,18.75,18.75 | value 3 = 25; the other four split the remaining 75 (÷4) |
Take 46, on a five-value list: only the first share is set, so the other four
values divide the leftover 100 − 46 = 54 evenly — 13.5 each. The lone trailing
comma just signals "and the rest are open".
So the exact-60/40 example above can be written even shorter — the second share is just "the rest":
<gen type="text" value="Male,Female" percent="60"/>
If every position is filled, the numbers must sum to 100. If any position is empty, the filled numbers must sum to at most 100.
Proportions inside a subset
When the sequence has a parent, the percentages
are computed against the size of the filtered subset, not the whole count.
That's the key to hierarchical dependencies — a "70% Private / 30% Captain" split
that applies only to the men, for example. See
Hierarchical dependencies.
percent beyond text
The same grammar and the same Hamilton layout drive the branch shares of a <mix>
block. There the list is matched against the number of nested <case> branches, and
leaving percent off spreads the cases evenly. Learn percent here and you know it
everywhere it appears.
Formatting
Like any generator, text accepts case= / mask= and order= to transform its
output — for example uppercasing the picked word, or forcing sequential order. See
Masks & case.