Parse 'HTML' with a Bundled 'Gumbo' Parser
Overview
Parses real-world 'HTML' with a bundled copy of the 'Gumbo' parser (https://codeberg.org/gumbo-parser/gumbo-parser), which follows the 'WHATWG' parsing algorithm, so that no system library is required. Documents become immutable trees navigated with a documented subset of 'CSS' selectors. Attributes, text, lists, tables, links, forms and page metadata ('JSON-LD', microdata) are extracted into ordinary character vectors, lists and data frames, and nodes convert to 'Markdown'. Input is a string, raw bytes, a file, a URL or a connection, and raw input is decoded as browsers decode it, from a byte-order mark or a '<meta>' declaration. Parsing is bounded by limits on input size, native memory and nesting depth.
First release.
- Bundles the 'Gumbo' HTML5 parser 0.14.0 from the maintained fork at <https://codeberg.org/gumbo-parser/gumbo-parser>, with local patches that add a parse-time nesting-depth limit, remove the library's only
printf(), and fix two memory-safety bugs in its<selectedcontent>support that fuzzing found (a use-after-free and a NULL dereference, both reachable from untrusted HTML) and an uninitialized read in fragment parsing. No system library is needed. - New
html_parse()andhtml_read()parse HTML from a string, raw vector or local file under explicit resource limits from the newhtml_limits(). Nesting depth is bounded while parsing, and all parser memory goes through an allocation ledger with a budget, so a failed parse always releases everything. Raw input is decoded from a byte-order mark, an explicit encoding, the page's<meta>declaration or UTF-8; invalid input is an error, never silently replaced.
Show all changes in 0.1.0Hide the rest of the changes in 0.1.0
- Parsed documents are converted into a compact immutable tree that holds no reference to the parser or the input. All 1,686 applicable html5lib tree-construction tests that the bundled parser ships produce the expected tree.
- New
html_fragment()parses markup in the context of a given element, asinnerHTMLdoes. - Nodes are
zuhtml_nodesets: vectors of nodes tied to their document, with missing nodes where an aligned operation has no answer. Navigate withhtml_children(),html_parent(),html_ancestors(),html_next_sibling(),html_previous_sibling(),html_root(),html_document()andhtml_template_content(); read values withhtml_name(),html_namespace(),html_type(),html_attr(),html_attrs(),html_classes()andhtml_text().html_info()describes a document.lapply()and friends over a nodeset pass one node at a time;rep(),rev(),unique()andc()keep nodesets nodesets. - New extraction functions.
html_text_clean()gives text as a reader wants it: scripts and styles skipped, whitespace collapsed outside<pre>, line breaks at<br>and block elements.html_list()reads a<ul>/<ol>as text or a tree, without nested items leaking into their parents.html_table()andhtml_tables()read tables into data frames of character columns, with row and column spans,rowspan="0", row groups, header detection and an error rather than a silent overwrite for overlapping cells.html_url()resolves URL attributes with RFC 3986 reference resolution, honouring<base href>, andhtml_links()lists a page's links. - New
html_elements(),html_element(),html_matches()andhtml_filter()select elements with a documented subset of CSS selectors: type, universal, ID, class and attribute selectors (with theiandsflags), the four combinators, selector lists,:scope,:root,:empty,:first-child,:last-child,:only-child,:nth-child(),:nth-of-type()and:not(). Anything else is azuhtml_selector_errorpointing at the offending position.html_element()keeps one result per input node, so extracted columns stay aligned. - New
html_closest()finds each node's nearest ancestor matching a selector, andhtml_strings()returns the text pieceshtml_text()joins, keeping element boundaries.html_serialize(pretty = TRUE)lays block-level elements out on indented lines for reading. - New
html_title(),html_meta(),html_json_ld()andhtml_microdata()read page metadata: the document title, every<meta>tag (OpenGraph, Twitter cards and Dublin Core included), JSON-LD blocks (parsed with jsonlite if asked) and microdata items per the HTML standard,itemrefincluded. - New
html_table_cells()returns one row per table cell with its grid position, spans, section, whether it is a header, and its links.html_tables()gainsmatch =to keep tables whose text matches a regular expression.html_table()gainsconvert =,decimal =andthousands =to convert columns that are entirely numbers or logicals, keeping identifiers with leading zeros as text. - New
html_markdown()converts nodes to CommonMark: headings, paragraphs, emphasis, code, fenced code blocks, block quotes, nested lists, links and images with resolved URLs, and GFM pipe tables for data tables. Markdown-significant characters in text are escaped, and only emphasis that CommonMark parses back is written. - The
<meta>declaration of raw input is found as browsers find it, by the HTML standard's prescan of the first 1024 bytes, and read with the Encoding Standard's labels (soiso-8859-1means windows-1252).html_info()reports where the encoding came from inencoding_source. - New
html_forms()describes each form and the controls it owns, by the HTML standard's form-owner rules (form=references included), with DOM values for every control type and the options of each select. It only inspects: nothing is submitted. html_read()reads a URL (through base R'surl(), which also sets the defaultbase_url) or any connection, such asgzfile(), as well as a file path. Reading stops once the input passes four timesmax_input.- New
html_serialize()(andas.character()on nodesets) writes nodes as normalized HTML following the WHATWG serialization algorithm, outer or inner. - New
html_problems()lists the parse errors the parser repaired, with package-owned codes and positions. - Errors are classed conditions under
zuhtml_error; see?zuhtml-conditions. - New
zuhtml_info()reports the bundled parser version and patches, and self-tests the compiled parser.
From NEWS.md in the release
Install
Health
- OK13 OKNow
- OK6 OK2026-10-07
Documentation
The repository also keeps web-only articles.
- Help pages
- 28 (1 internal)includes a package overview page
- Examples that run
- 100%26 run in a plain check
- Exported functions with examples
- 100%
- Documented parameters
- 100%
- Return-value docs
- 100%
- Help pages citing references
- 0%
Downloads
Repository
- PRs merged (all time)
- 100%
- Median days to close, 50 most recently updated closed issues
- 0
- Median days to close, 50 most recently updated closed PRs
- 0
Releases over time
Issues over time
PRs over time
Commits over time
7 development-tooling and community-health practices detected across 4 families in the upstream repository
Checks run against github.com/pedrobtz/zuhtml on 2026-10-18.
The R CMD check workflow runs on Linux
GitHub Pages site last deployed 2026-10-13 · The repository has a site deploy workflow
pkgdown site last built 2026-10-13
This repository shows signs of AI coding tools.
- Claude Codefirst seen 2026-09-24Seen in the repository: CLAUDE.mdNamed in .Rbuildignore: CLAUDE.mdPull request it wrote: opened by a project memberCommits: at least 34 crediting it in the message
- Claude Opus 5.533 commits · Sep to Oct 2026
- Claude Fable 5.11 commit · Sep 2026
Dependencies
Installing zuhtml adds no packages beyond those that come with R.
Code & Tests
People & History
- 0.1.0Latest2026-10-06 · current release ·
2 days in CRAN's queue
Listed in CRAN's incoming queue from 2026-10-03 21:57 to 2026-10-06 08:22 UTC, in 12 readings. - RR 4.6.0 released · 2026-04-24
Package metadata
- First published
- 2026-10-06
- Total releases
- 1 / 1 yrs
- License
- MIT + file LICENSE OSI
- Copyright
- See inst/COPYRIGHTS in the package
- Minimum R
- ≥ 4.1
- Download size
- 323 KB
Cite
Cite this package
Run in R for the authors' preferred citation:
citation("zuhtml")This package has no citation file, so citation() returns this entry built from DESCRIPTION.
Cite the R Observatory
For a number measured here: a download total, a coverage figure, an archival date.
From data release v2026-10-22, which the citation names so these numbers can be found later. More on citing and the projects behind them.