Download
54 lines 1.3 KiBGoModified 2026-10-18 raw
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
package render

import (
	"fmt"
	"strconv"
	"strings"
)

// trimZero drops a trailing ".0" ("300.0" → "300").
func trimZero(s string) string { return strings.TrimSuffix(s, ".0") }

// humanSize formats a byte count.
func humanSize(n int64) string {
	switch {
	case n < 1024:
		return fmt.Sprintf("%d B", n)
	case n < 1<<20:
		return trimZero(fmt.Sprintf("%.1f", float64(n)/1024)) + " KiB"
	case n < 1<<30:
		return trimZero(fmt.Sprintf("%.1f", float64(n)/(1<<20))) + " MiB"
	default:
		return trimZero(fmt.Sprintf("%.1f", float64(n)/(1<<30))) + " GiB"
	}
}

// wordsPerPage is a typical printed book page, for showing doc word counts
// as pages.
const wordsPerPage = 300

// pagesText describes a word count as rough pages: "3K words ≈ 12 pages".
func pagesText(words int) string {
	return humanCount(words) + " words ≈ " + pageCount(words)
}

// pageCount is a word count as rough pages, at least one: "12 pages".
func pageCount(words int) string {
	n := max(1, (words+wordsPerPage/2)/wordsPerPage)
	if n == 1 {
		return "1 page"
	}
	return humanCount(n) + " pages"
}

// humanCount formats a count compactly: 999, 4.4K, 1.2M.
func humanCount(n int) string {
	switch {
	case n < 1000:
		return strconv.Itoa(n)
	case n < 1000000:
		return trimZero(fmt.Sprintf("%.1f", float64(n)/1000)) + "K"
	default:
		return trimZero(fmt.Sprintf("%.1f", float64(n)/1000000)) + "M"
	}
}