Initial commit
This commit is contained in:
142
scripts/rsw/internal/render/markdown.go
Normal file
142
scripts/rsw/internal/render/markdown.go
Normal file
@@ -0,0 +1,142 @@
|
||||
package render
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Builder accumulates markdown output.
|
||||
type Builder struct {
|
||||
sb strings.Builder
|
||||
}
|
||||
|
||||
// New creates a new markdown builder.
|
||||
func New() *Builder {
|
||||
return &Builder{}
|
||||
}
|
||||
|
||||
// H1 writes a level-1 heading.
|
||||
func (b *Builder) H1(text string) {
|
||||
fmt.Fprintf(&b.sb, "# %s\n\n", text)
|
||||
}
|
||||
|
||||
// H2 writes a level-2 heading.
|
||||
func (b *Builder) H2(text string) {
|
||||
fmt.Fprintf(&b.sb, "## %s\n\n", text)
|
||||
}
|
||||
|
||||
// H3 writes a level-3 heading.
|
||||
func (b *Builder) H3(text string) {
|
||||
fmt.Fprintf(&b.sb, "### %s\n\n", text)
|
||||
}
|
||||
|
||||
// P writes a paragraph.
|
||||
func (b *Builder) P(text string) {
|
||||
fmt.Fprintf(&b.sb, "%s\n\n", text)
|
||||
}
|
||||
|
||||
// Bold writes bold text inline (no newline).
|
||||
func (b *Builder) Bold(text string) {
|
||||
fmt.Fprintf(&b.sb, "**%s**", text)
|
||||
}
|
||||
|
||||
// KV writes a key: value line.
|
||||
func (b *Builder) KV(key, value string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(&b.sb, "- **%s:** %s\n", key, value)
|
||||
}
|
||||
|
||||
// Bullet writes a bullet point.
|
||||
func (b *Builder) Bullet(text string) {
|
||||
fmt.Fprintf(&b.sb, "- %s\n", text)
|
||||
}
|
||||
|
||||
// NumberedItem writes a numbered list item.
|
||||
func (b *Builder) NumberedItem(n int, text string) {
|
||||
fmt.Fprintf(&b.sb, "%d. %s\n", n, text)
|
||||
}
|
||||
|
||||
// Table writes a markdown table.
|
||||
func (b *Builder) Table(headers []string, rows [][]string) {
|
||||
if len(headers) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Header row
|
||||
fmt.Fprintf(&b.sb, "| %s |\n", strings.Join(headers, " | "))
|
||||
|
||||
// Separator
|
||||
seps := make([]string, len(headers))
|
||||
for i := range seps {
|
||||
seps[i] = "---"
|
||||
}
|
||||
fmt.Fprintf(&b.sb, "| %s |\n", strings.Join(seps, " | "))
|
||||
|
||||
// Data rows
|
||||
for _, row := range rows {
|
||||
// Pad row to match header length
|
||||
for len(row) < len(headers) {
|
||||
row = append(row, "")
|
||||
}
|
||||
fmt.Fprintf(&b.sb, "| %s |\n", strings.Join(row[:len(headers)], " | "))
|
||||
}
|
||||
b.sb.WriteString("\n")
|
||||
}
|
||||
|
||||
// Line writes a raw line.
|
||||
func (b *Builder) Line(text string) {
|
||||
fmt.Fprintf(&b.sb, "%s\n", text)
|
||||
}
|
||||
|
||||
// Newline writes an empty line.
|
||||
func (b *Builder) Newline() {
|
||||
b.sb.WriteString("\n")
|
||||
}
|
||||
|
||||
// HR writes a horizontal rule.
|
||||
func (b *Builder) HR() {
|
||||
b.sb.WriteString("---\n\n")
|
||||
}
|
||||
|
||||
// String returns the accumulated markdown.
|
||||
func (b *Builder) String() string {
|
||||
return b.sb.String()
|
||||
}
|
||||
|
||||
// FormatGP formats a coin amount with commas (e.g., 1,234,567 gp).
|
||||
func FormatGP(amount int) string {
|
||||
if amount < 0 {
|
||||
return fmt.Sprintf("-%s gp", addCommas(-amount))
|
||||
}
|
||||
return fmt.Sprintf("%s gp", addCommas(amount))
|
||||
}
|
||||
|
||||
// FormatNumber formats a number with commas.
|
||||
func FormatNumber(n int) string {
|
||||
return addCommas(n)
|
||||
}
|
||||
|
||||
func addCommas(n int) string {
|
||||
s := fmt.Sprintf("%d", n)
|
||||
if len(s) <= 3 {
|
||||
return s
|
||||
}
|
||||
|
||||
var result strings.Builder
|
||||
remainder := len(s) % 3
|
||||
if remainder > 0 {
|
||||
result.WriteString(s[:remainder])
|
||||
if len(s) > remainder {
|
||||
result.WriteString(",")
|
||||
}
|
||||
}
|
||||
for i := remainder; i < len(s); i += 3 {
|
||||
if i > remainder {
|
||||
result.WriteString(",")
|
||||
}
|
||||
result.WriteString(s[i : i+3])
|
||||
}
|
||||
return result.String()
|
||||
}
|
||||
Reference in New Issue
Block a user