Repository navigation
feat: parse rustdoc item pages (decl, fields, variants, methods) - #34
Conversation
parseDocsRsDocument only understood module/index pages (title, overview, dl.item-table). On item pages the URL resolved and the page loaded, but the parser never looked at where the real content lives, so reading a struct/enum/fn/trait yielded just the title, a one-line overview, and a few empty section headers — forcing a raw HTML fetch to see signatures. Add matchers, scoped under the existing section#main-content root, for: - pre.item-decl -> fenced code block with the canonical declaration (uniform across struct/enum/fn/trait/type alias). - Impl/trait methods: h3.code-header (impl header) + h4.code-header (method signature) + docblock, scoped to the inherent- and trait-impl lists. Auto-trait and blanket-impl lists (Send/Sync/From<T>/…) are skipped as noise, along with their now-empty section headers. - Enum variants: div.variants > section.variant h3.code-header + docs. - Struct fields: span.structfield code + the following div.docblock, gated on an inFields flag (HasPrefix "Fields", so #[non_exhaustive] "Fields (Non-exhaustive)" headers still match) since field spans and their docblocks are bare direct children of section#main-content. Signatures use RawInnerText so punctuation from text nodes is preserved exactly (e.g. pub fn insert(&mut self, k: String, v: Value) -> Option<Value>). Add golden fixtures for a struct (serde_json::Map), function (serde_json::to_string), enum (serde_json::Value), and a struct with documented fields (httparse::Request). Module-page goldens are unchanged (module pages have none of this markup), so there is no regression. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
🤖 AI Review (klein) — turn 2The change extends rustdoc parsing to item declarations, implementations, variants, fields, and richer nested documentation. The previously reported loss of headings, lists, and code examples in item docblocks is fixed by routing those blocks through turn 2 (incremental review of e8b089f) · comments: total 1, active 0 (+0 new, −1 resolved) · verdict: approve |
| dq.NewMatchFunc("div.docblock"), | ||
| nil, | ||
| dq.NewNodeMatcher( | ||
| dq.NewMatchFunc("p"), | ||
| func(n *html.Node) { | ||
| text := strings.TrimSpace(dq.InnerText(n, true)) | ||
| if text != "" { | ||
| builder.WriteString(fmt.Sprintf(" %s\n", text)) | ||
| } | ||
| }, | ||
| ), |
There was a problem hiding this comment.
[major] Do not limit impl/variant documentation to direct p elements; reuse the existing docblock content matchers (or add equivalent handling for headings, lists, and <pre> blocks) so the full docblock is emitted.
Rationale
Verified against the parser above: overview docblocks preserve headings, code blocks, and lists via docblockHeaderMatcher, docblockPreMatcher, and docblockListMatcher, but this matcher only visits p. Any method or enum-variant documentation containing an example, list, nested heading, or code block is therefore silently omitted; the new fixtures already show variant examples in the HTML (for example rustdoc_doc_serdejson_value.html:329-345).
There was a problem hiding this comment.
Fixed in e8b089f. Added a shared writeRustDocBlock helper that renders the full docblock — paragraphs, <pre> code blocks, lists, and headings — for method, enum-variant, and struct-field docs, indented to nest under each item. Headings are emitted as bold text to avoid clashing with the document's ## section structure. Overview matchers are untouched, so module-page goldens are unchanged. The serde_json::Value golden now carries 104 method/variant example code blocks that were previously dropped.
The reduced matcher for method/variant/field docs only visited <p>, so code examples, lists, and headings in that documentation were silently dropped — unlike overview docblocks, which preserve them. Add a shared writeRustDocBlock helper that renders paragraphs, <pre> code blocks, lists, and headings from a div.docblock, indented to nest under the enclosing item. Headings become bold text to avoid clashing with the document's "##" section structure. Overview matchers are unchanged, so module-page goldens are unaffected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Superseded: the latest AI review no longer requests changes.
Problem
read_rustdoc(and the underlyingparseDocsRsDocument) only understood module/index pages — title, overview, anddl.item-tablelists. On item pages (struct.*,enum.*,fn.*,trait.*) the URL resolved and the page loaded, but the parser never looked at where the real content lives. Reading e.g.serde_json/struct.Map.htmlorrlua/struct.Lua.htmlreturned just the title, a one-line overview, and a few empty section headers — forcing a raw HTML fetch to confirm method signatures.Change
Additive matchers under the existing
section#main-contentroot (verified against the live docs.rs DOM):pre.item-decl→ fenced code block with the canonical declaration. Uniform across every item kind (struct/enum/fn/trait/type alias).h3.code-header(impl header) +h4.code-header(method signature) + docblock, scoped to the inherent-impl and trait-impl lists. The auto-trait and blanket-impl lists (Send/Sync/From<T>/…) are skipped as noise, along with their now-empty section headers.div.variants > section.varianth3.code-header+ variant docs.span.structfieldcode+ the followingdiv.docblock, gated on aninFieldsflag (HasPrefix "Fields", so#[non_exhaustive]Fields (Non-exhaustive)headers still match) since field spans and their docblocks are bare direct children ofsection#main-content.Signatures use
RawInnerTextso punctuation from text nodes is preserved exactly, e.g.pub fn insert(&mut self, k: String, v: Value) -> Option<Value>.Example (
httparse::Request)```
Fields
The request method, such as GET .
...
Implementations
impl<'h, 'b> Request<'h, 'b>
Try to parse a buffer of bytes into the Request.
```
Tests
serde_json::Map), function (serde_json::to_string), enum (serde_json::Value), and a documented-field struct (httparse::Request).make lintclean,make testgreen, plus live end-to-end reads of the affected pages.🤖 Generated with Claude Code