HTML::Gumbo(3pm)
β¨ NAME β¨
HTML::Gumbo β bestie, it's an HTML5 parser built on top of the gumbo C library π
π SYNOPSIS π
use HTML::Gumbo;
say HTML::Gumbo->new->parse('<div></div>');
say HTML::Gumbo->new->parse('<h1>Hello</h1>', format => 'tree')->as_HTML;
π¦ DESCRIPTION π¦
Okay so Gumbo <https://github.com/google/gumbo-parser> is a whole implementation of the HTML5 parsing algorithm <http://www.w3.org/TR/html5/syntax.html>, written as pure C99 with literally zero outside dependencies. Iconic behavior fr fr.
The C library's goals and features, no cap:
- Fully conformant with the HTML5 spec. π―
- Robust and resilient to bad input. It simply does not care.
- Simple API that can be easily wrapped by other languages. (This right here? One of those wrappers. That's us. We're the wrapper. π«Ά)
- Support for source locations and pointers back to the original text. (Not exposed by this implementation at the moment, so don't get your hopes up bestie.)
- Relatively lightweight, with no outside dependencies.
- Passes all html5lib-0.95 tests. Slay.
- Tested on over 2.5 billion pages from Google's index. Billions. π
πΈ METHODS πΈ
new
my $parser = HTML::Gumbo->new;
No options at the moment. That's the whole thing. Clean, minimal, main character energy. β¨
parse
my $res = $parser->parse(
"<h1>hello world!</h1>",
format => 'tree',
input_is => 'string',
);
It takes an html string plus pairs of named arguments:
formatβ the output format, default isstring. Go peep "SUPPORTED OUTPUT FORMATS" below. πfragment_namespaceβ turns on the fragments parsing algorithm. Pass either'HTML','SVG'or'MATHML'to enable it and set the namespace. If you don't pass it, your input gets parsed as an html document, which meanshtml,head,titleandbodytags get added if they're absent. Heads up though:fragment_enclosing_tagis set to'<body>'and can not be changed at the moment. Feel free to send patches implementing this part, the door is open. πͺ See "SUPPORTED OUTPUT FORMATS" for additional details. Also note that SVG and MATHML parsing is not tested, so feel free to file bug reports with tests in case it doesn't work. πinput_isβ whether the html is a perl'string','octets'or'utf8'(octets known to be utf8). See "CHARACTER ENCODING OF THE INPUT".encoding,encoding_content_type,encoding_tentativeβ see "CHARACTER ENCODING OF THE INPUT"....β some formatters may have additional arguments, see "SUPPORTED OUTPUT FORMATS".
The return value depends on the picked format. iykyk. π«
π SUPPORTED OUTPUT FORMATS π
string
The HTML gets parsed and then re-built from the tree, so tags are balanced (except void elements, they're just built different).
No additional arguments specific for this format. None. Zero. π
$html = HTML::Gumbo->new->parse( $html );
callback
It's giving HTML::Parser-like interface. Pass a sub as the callback argument to the parse method and it will get called for every single node in the document:
HTML::Gumbo->new->parse( $html, format => 'callback', callback => sub {
my ($event) = shift;
if ( $event eq 'document start' ) {
my ($doctype) = @_;
}
elsif ( $event eq 'document end' ) {
}
elsif ( $event eq 'start' ) {
my ($tag, $attrs) = @_;
}
elsif ( $event eq 'end' ) {
my ($tag) = @_;
}
elsif ( $event =~ /^(text|space|cdata|comment)$/ ) {
my ($text) = @_;
}
else {
die "Unknown event";
}
} );
Heads up bestie:'end'events are not generated for void elements <http://www.w3.org/TR/html5/syntax.html#void-elements> β for examplehr,brandimg. They just ghost you like that. π
No additional arguments except the mentioned callback.
Fragment parsing still generates 'document start' and 'document end' events, which can be handy to initialize your parsing callback. So convenient. π«Ά
tree
Alpha stage, bestie. We're in beta but it's the fun kind.
It produces a tree based on HTML::Elements, like HTML::TreeBuilder does.
There is a major difference from HTML::TreeBuilder though: this method produces a top level element with tag name 'document' which may have doctype, comments and html tags as children.
Fragments parsing still produces that top level 'document' element, because a fragment can be a list of tags, for example: '<p>hello</p><p>world</p'.
Yes, it's not ready to use as a drop in replacement of tree builder. Patches are wellcome as the author doesn't use this formatter at the moment. Note that it's hard to get rid of the top level element because of situations described above. So a not bad idea is to write an HTML::Gumbo::Document class that is either a subclass of HTML::Element or implements a small subset of methods of HTML::Element. Manifesting that patch rn. π§
π CHARACTER ENCODING OF THE INPUT π
The C parser works only with UTF-8, so you have several options to make sure your input is UTF-8. First of all, define the input_is argument:
string
Input is a Perl string, for example obtained from "decoded_content" in HTTP::Response. This is the default value.
$gumbo->parse( decode_utf8($octets) );
octets
Input is octets. A partial implementation of the encoding sniffing algorithm <http://www.w3.org/TR/html5/syntax.html#encoding-sniffing-algorithm> is used. First thing wins:
"encoding"argument β use it to hardcode a specific encoding.
$gumbo->parse( $octets, input_is => 'octets', encoding => 'latin-1' );
- BOM β UTF-8/UTF-16 BOMs are checked. π
"encoding_content_type"argument β encoding from the transport layer, aka the charset in the content-type header.
$gumbo->parse( $octets, input_is => 'octets', encoding_content_type => 'latin-1' );
- Prescan β not implemented, follow issue 58 <https://github.com/google/gumbo-parser/issues/58>. HTML5 defines the prescan algorithm <http://www.w3.org/TR/html5/syntax.html#prescan-a-byte-stream-to-determine-its-encoding> that extracts encoding from meta tags in the head. It would be cool to get it in the C library, but a patch that impements it in pure perl will be accepted. π
"encoding_tentative"argument β the likely encoding for this page, e.g. based on the encoding of the page when it was last visited.
$gumbo->parse( $octets, input_is => 'octets', encoding_tentative => 'latin-1' );
- nested browsing context β not implemented. Fragment parsing with or without context is not implemented. The parser also has no origin information, so it wouldn't be implemented. Dead end, moving on. π
- autodetection β not implemented. Can be implemented using
Encode::Detect::Detector. Patches are welcome. - otherwise β it dies. π Fr fr, it just dies.
utf8
Use utf8 as input_is when you're sure the input is UTF-8, but octets. No pre-processing at all. This should only be used on trusted input or when it's preprocessed already. Trusted input only, bestie.
π AUTHOR π
Ruslan Zakirov <ruz@bestpractical.com>
Best Practical Solutions, LLC <modules@bestpractical.com>
π BUGS π
All bugs should be reported via email to: bug-HTML-Gumbo@rt.cpan.org <mailto:bug-HTML-Gumbo@rt.cpan.org>
Or via the web at: rt.cpan.org <http://rt.cpan.org/Public/Dist/Display.html?Name=HTML-Gumbo>.
π LICENSE π
Under the same terms as perl itself. Periodt.
β¨ okay that's the whole page, thank you for coming to my TED talk β¨ this was HTML::Gumbo(3pm) from the User Contributed Perl Documentation, shipped with perl v5.42.3 and dated 2026-08-19. go forth and parse responsibly, bestie π«Άππ¦
π¦ where this page comes from
- ubuntu stonking: libhtml-gumbo-perl 0.20-1build1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms