Good contribution! Your simplified text syntax is prettier and more intuitive.
The corner case where an empty element contains code is a small blemish and an easy price to pay for the benefits of the simplified text syntax. Maybe we can even reduce the blemish by introducing another helper that declares a block to represent an empty content model:
sub empty(&) { shift->(); undef }
Then the corner-case becomes:
doc {
br { empty { ++$breaks } }
}
It's still not perfect, but maybe we can think of yet another improvement.
Cheers,
Tom