From b20d68c9f01be91f8de472e78168370ffaa9d7b5 Mon Sep 17 00:00:00 2001 From: Sam Myers Date: Thu, 5 Mar 2026 01:44:43 -0600 Subject: [PATCH] Improve location displays --- scripts/rsw/internal/cmd/page.go | 26 +++++++++-- scripts/rsw/internal/extract/infobox.go | 59 +++++++++++++++++++++++-- 2 files changed, 78 insertions(+), 7 deletions(-) diff --git a/scripts/rsw/internal/cmd/page.go b/scripts/rsw/internal/cmd/page.go index 8a19ecb..9d41469 100644 --- a/scripts/rsw/internal/cmd/page.go +++ b/scripts/rsw/internal/cmd/page.go @@ -37,14 +37,32 @@ Examples: if pageSection != "" { idx := wiki.FindSectionIndex(page.Sections, pageSection) if idx == -1 { + needle := strings.ToLower(pageSection) + // Case-insensitive exact match for _, s := range page.Sections { - if strings.EqualFold(s.Line, pageSection) { - i := 0 - fmt.Sscanf(s.Index, "%d", &i) - idx = i + if strings.ToLower(s.Line) == needle { + fmt.Sscanf(s.Index, "%d", &idx) break } } + // Case-insensitive prefix match (e.g. "Location" → "Locations") + if idx == -1 { + for _, s := range page.Sections { + if strings.HasPrefix(strings.ToLower(s.Line), needle) { + fmt.Sscanf(s.Index, "%d", &idx) + break + } + } + } + // Case-insensitive contains match + if idx == -1 { + for _, s := range page.Sections { + if strings.Contains(strings.ToLower(s.Line), needle) { + fmt.Sscanf(s.Index, "%d", &idx) + break + } + } + } } if idx == -1 { return fmt.Errorf("section %q not found. Available sections: %s", diff --git a/scripts/rsw/internal/extract/infobox.go b/scripts/rsw/internal/extract/infobox.go index 9566a67..ce48621 100644 --- a/scripts/rsw/internal/extract/infobox.go +++ b/scripts/rsw/internal/extract/infobox.go @@ -239,7 +239,7 @@ func CleanWikitext(s string) string { // ExtractPlainText strips all wikitext markup to produce plain text. func ExtractPlainText(wikitext string) string { s := wikitext - // Remove templates (simplified — just removes {{ ... }} at depth 0) + s = expandKnownTemplates(s) s = removeTemplates(s) s = cleanWikiLinks(s) s = strings.ReplaceAll(s, "'''", "") @@ -322,6 +322,51 @@ func tryExpandTemplate(inner string) (string, bool) { if len(parts) >= 2 { return strings.TrimSpace(parts[1]) + " coins", true } + + case "loctablehead", "loctablebottom": + return "", true + + case "locline": + paramMap := map[string]string{} + for _, p := range parts[1:] { + if idx := strings.Index(p, "="); idx > 0 { + k := strings.ToLower(strings.TrimSpace(p[:idx])) + v := cleanWikiLinks(strings.TrimSpace(p[idx+1:])) + paramMap[k] = v + } + } + // Support both OSRS (location/levels/members) and RS3 (loc/lvls/mem) param names + locVal := paramMap["location"] + if locVal == "" { + locVal = paramMap["loc"] + } + lvlVal := paramMap["levels"] + if lvlVal == "" { + lvlVal = paramMap["lvls"] + } + memVal := paramMap["members"] + if memVal == "" { + memVal = paramMap["mem"] + } + + var segments []string + if locVal != "" { + segments = append(segments, locVal) + } + if lvlVal != "" { + segments = append(segments, "level "+lvlVal) + } + if memVal != "" { + if strings.EqualFold(memVal, "yes") { + segments = append(segments, "members only") + } else { + segments = append(segments, "F2P") + } + } + if len(segments) == 0 { + return "", true + } + return "\n- " + strings.Join(segments, ", "), true } return "", false } @@ -477,15 +522,23 @@ func removeFileRefs(s string) string { func collapseWhitespace(s string) string { var b strings.Builder prevSpace := false + prevNewline := false for _, r := range s { - if unicode.IsSpace(r) { - if !prevSpace { + if r == '\n' { + if !prevNewline { + b.WriteRune('\n') + } + prevNewline = true + prevSpace = false + } else if unicode.IsSpace(r) { + if !prevSpace && !prevNewline { b.WriteRune(' ') } prevSpace = true } else { b.WriteRune(r) prevSpace = false + prevNewline = false } } return b.String()