SYNOPSIS
use PDF::Make::Markup::Parse;
my $root = PDF::Make::Markup::Parse->parse(<<'MARKUP');
<doc size="A4" margin="36">
<h1>Invoice 1042</h1>
<text>Amount due: <b>1,240.00</b> by 30 September.</text>
</doc>
MARKUP
DESCRIPTION
The markup is a closed tag set, not HTML and not XML. Anything outside the grammar is an error with a position rather than a best guess, because a document that renders slightly wrong is worse than one that refuses to render: the wrong one reaches a customer with a number on it.
Nodes
An element:
{ kind => 'elem', tag => 'row', attrs => { weight => '2' },
children => [ ... ], line => 4, col => 3 }
Text:
{ kind => 'text', text => 'Amount due: ', line => 5, col => 12 }
What the grammar allows
The root element must be
<doc>.Tags come from the fixed set.
tags()returns it, with thevoid,containerandinlineflags the parser itself uses.Attribute values are always quoted, with
"or'. A repeated attribute is an error rather than a silent winner.Entities are
&<>"'and numeric character references&#NNN;and&#xHH;. There is no wider entity table: and friends are a slope that ends in an HTML specification.<!-- comments -->are skipped.Whitespace between the children of a container element is indentation and is dropped. Inside a text-bearing element it is content and survives, so
Total <b>due</b>keeps its space.Nesting deeper than 64 levels is an error. Templates arrive from customers, and unbounded depth is a stack overflow waiting for someone else to find.