Files
claude-plugin-runescape/scripts/rsw/internal/wiki/parse.go
2026-03-05 12:51:31 -06:00

138 lines
3.2 KiB
Go

package wiki
import (
"fmt"
"net/url"
"strconv"
)
// Section represents a section of a wiki page.
type Section struct {
Index string `json:"index"`
Level string `json:"level"`
Line string `json:"line"`
Number string `json:"number"`
Anchor string `json:"anchor"`
}
// ParsedPage contains the result of parsing a wiki page.
type ParsedPage struct {
Title string `json:"title"`
PageID int `json:"pageid"`
Wikitext string // Raw wikitext of the page or section
HTML string // Rendered HTML
Sections []Section // Table of contents
}
// parseResponse wraps the API response for action=parse.
type parseResponse struct {
Parse struct {
Title string `json:"title"`
PageID int `json:"pageid"`
Wikitext struct {
Content string `json:"*"`
} `json:"wikitext"`
Text struct {
Content string `json:"*"`
} `json:"text"`
Sections []Section `json:"sections"`
} `json:"parse"`
Error *struct {
Code string `json:"code"`
Info string `json:"info"`
} `json:"error"`
}
// GetPage fetches the full wikitext and section list for a page.
func (c *Client) GetPage(title string) (*ParsedPage, error) {
params := url.Values{
"action": {"parse"},
"page": {title},
"prop": {"wikitext|sections"},
"redirects": {"1"},
}
var resp parseResponse
if err := c.get(params, &resp); err != nil {
return nil, err
}
if resp.Error != nil {
return nil, fmt.Errorf("wiki API error: %s — %s", resp.Error.Code, resp.Error.Info)
}
return &ParsedPage{
Title: resp.Parse.Title,
PageID: resp.Parse.PageID,
Wikitext: resp.Parse.Wikitext.Content,
Sections: resp.Parse.Sections,
}, nil
}
// GetPageSection fetches the wikitext for a specific section of a page.
func (c *Client) GetPageSection(title string, sectionIndex int) (*ParsedPage, error) {
params := url.Values{
"action": {"parse"},
"page": {title},
"prop": {"wikitext"},
"section": {strconv.Itoa(sectionIndex)},
}
var resp parseResponse
if err := c.get(params, &resp); err != nil {
return nil, err
}
if resp.Error != nil {
return nil, fmt.Errorf("wiki API error: %s — %s", resp.Error.Code, resp.Error.Info)
}
return &ParsedPage{
Title: resp.Parse.Title,
PageID: resp.Parse.PageID,
Wikitext: resp.Parse.Wikitext.Content,
}, nil
}
// GetPageHTML fetches the rendered HTML for a page.
func (c *Client) GetPageHTML(title string) (*ParsedPage, error) {
params := url.Values{
"action": {"parse"},
"page": {title},
"prop": {"text|sections"},
"redirects": {"1"},
}
var resp parseResponse
if err := c.get(params, &resp); err != nil {
return nil, err
}
if resp.Error != nil {
return nil, fmt.Errorf("wiki API error: %s — %s", resp.Error.Code, resp.Error.Info)
}
return &ParsedPage{
Title: resp.Parse.Title,
PageID: resp.Parse.PageID,
HTML: resp.Parse.Text.Content,
Sections: resp.Parse.Sections,
}, nil
}
// FindSectionIndex searches the section list for a section matching the given name.
// Returns -1 if not found.
func FindSectionIndex(sections []Section, name string) int {
for _, s := range sections {
if s.Line == name {
idx, err := strconv.Atoi(s.Index)
if err != nil {
continue
}
return idx
}
}
return -1
}