Files
sow-tools/internal/topdata/wiki_formatters.go
T

114 lines
3.7 KiB
Go

package topdata
import (
"fmt"
"strings"
)
func (ctx *wikiContext) renderWikiFormatter(spec string, page wikiTemplatePage) (string, error) {
name := strings.Fields(spec)
if len(name) == 0 {
return "", fmt.Errorf("render wiki template for %s: empty formatter", page.PageID)
}
switch name[0] {
case "Description":
return dokuWikiToNodeBBHTML(toDokuWiki(ctx.resolveRowDescription(page.Category, page.Row))), nil
case "FactsTable":
return dokuWikiToNodeBBHTML(ctx.renderFacts(page.Category, page.Key, page.Row)), nil
case "Prerequisites":
return dokuWikiToNodeBBHTML(formatFact("Prerequisites", ctx.renderFeatPrerequisites(page.Row))), nil
case "SkillList":
if page.Category != "classes" {
return "", nil
}
return dokuWikiToNodeBBHTML(ctx.renderClassSkillList(page.Row)), nil
case "ClassFeatureTable":
if page.Category != "classes" {
return "", nil
}
return dokuWikiToNodeBBHTML(ctx.renderClassFeatureTable(page.Row)), nil
case "FeatProgression":
if page.Category != "classes" {
return "", nil
}
return dokuWikiToNodeBBHTML(ctx.renderClassFeatProgression(page.Row)), nil
case "SpellTable", "SavesProgression", "BABProgression":
return "", nil
case "RaceFeatList":
return dokuWikiToNodeBBHTML(formatFact("Racial Feats", ctx.renderRaceFeatList(page.Row))), nil
case "StatusCallout":
return buildWikiStatusBlock(page.Status, page.Category), nil
case "RaceNameForms":
return dokuWikiToNodeBBHTML(ctx.renderRaceNameForms(page.Row)), nil
case "UserBottomFallback":
return "", nil
default:
return "", fmt.Errorf("render wiki template for %s: unknown formatter %q", page.PageID, name[0])
}
}
func (ctx *wikiContext) renderClassSkillList(row map[string]any) string {
table := ctx.tableForValue(fieldValue(row, "SkillsTable"), ctx.classSkillTables)
if table == nil {
return ""
}
skills := []string{}
for _, skillRow := range table.Rows {
if stringValue(skillRow, "ClassSkill") != "1" {
continue
}
name := ctx.renderReference(fieldValue(skillRow, "SkillIndex"), ctx.skillIDToKey, ctx.resolveSkillName)
if name != "" {
skills = append(skills, name)
}
}
if len(skills) == 0 {
return ""
}
return "==== Class Skills ====\n\n * " + strings.Join(skills, ", ")
}
func (ctx *wikiContext) renderClassFeatProgression(row map[string]any) string {
table := ctx.tableForValue(fieldValue(row, "FeatsTable"), ctx.classFeatTables)
if table == nil {
return ""
}
lines := []string{}
byLevel := map[string][]string{}
selectable := []string{}
for _, featRow := range table.Rows {
name := ctx.renderReference(fieldValue(featRow, "FeatIndex"), ctx.featIDToKey, ctx.resolveFeatName)
if name == "" {
name = ctx.renderReference(fieldValue(featRow, "FeatIndex"), nil, func(string) string { return "" })
}
if name == "" {
continue
}
level := stringValue(featRow, "GrantedOnLevel")
if level == "" || strings.HasPrefix(level, "-") {
selectable = append(selectable, name)
continue
}
byLevel[level] = append(byLevel[level], name)
}
if len(byLevel) > 0 {
lines = append(lines, "==== Granted Feats ====", "")
for _, level := range sortedKeys(byLevel) {
lines = append(lines, " * Level "+level+": "+strings.Join(byLevel[level], ", "))
}
lines = append(lines, "")
}
if len(selectable) > 0 {
lines = append(lines, "==== Selectable Feats ====", "", " * "+strings.Join(selectable, ", "), "")
}
return strings.TrimSpace(strings.Join(lines, "\n"))
}
func (ctx *wikiContext) renderClassFeatureTable(row map[string]any) string {
table := ctx.tableForValue(fieldValue(row, "BonusFeatsTable"), ctx.classBonusTables)
if table == nil || len(table.Rows) == 0 {
return ""
}
return "==== Bonus Feats ====\n\n * Bonus feat table: " + table.OutputStem
}