our $__frag; # points to fragment under active construction sub doc(&) { my ($content_fn) = @_; local $__frag = [undef,undef,undef]; $content_fn->(); $__frag->[2][0]; } sub _elem { my ($elem_name, $content_fn) = @_; # an element is represented by the triple [name, attrs, children] my $elem = [$elem_name, undef, undef]; do { local $__frag = $elem; $content_fn->() }; push @{$__frag->[2]}, $elem; } sub _attr { my ($attr_name, $val) = @_; push @{$__frag->[1]}, [$attr_name, $val]; } sub text($) { push @{$__frag->[2]}, @_; }