Initial commit

This commit is contained in:
2026-03-05 01:13:19 -06:00
commit 1ae223a1dc
21 changed files with 2404 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
package wiki
import (
"net/url"
"strconv"
"strings"
)
// SearchResult represents a single search hit from the wiki.
type SearchResult struct {
Title string `json:"title"`
Snippet string `json:"snippet"`
PageID int `json:"pageid"`
Size int `json:"size"`
}
// searchResponse is the raw API response shape for action=query&list=search.
type searchResponse struct {
Query struct {
Search []SearchResult `json:"search"`
} `json:"query"`
}
// Search performs a full-text search across wiki pages.
func (c *Client) Search(query string, limit int) ([]SearchResult, error) {
if limit <= 0 {
limit = 10
}
params := url.Values{
"action": {"query"},
"list": {"search"},
"srsearch": {query},
"srlimit": {strconv.Itoa(limit)},
"srprop": {"snippet|size"},
}
var resp searchResponse
if err := c.get(params, &resp); err != nil {
return nil, err
}
// Strip HTML tags from snippets (the API returns <span class="searchmatch">...</span>)
for i := range resp.Query.Search {
resp.Query.Search[i].Snippet = stripHTML(resp.Query.Search[i].Snippet)
}
return resp.Query.Search, nil
}
// stripHTML removes HTML tags from a string. Lightweight, no external dep.
func stripHTML(s string) string {
var b strings.Builder
inTag := false
for _, r := range s {
switch {
case r == '<':
inTag = true
case r == '>':
inTag = false
case !inTag:
b.WriteRune(r)
}
}
return b.String()
}