129 lines
1.9 KiB
Go
129 lines
1.9 KiB
Go
package textfmt
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"strings"
|
|
"unicode"
|
|
)
|
|
|
|
func timesn(s string, n int) string {
|
|
if n < 0 {
|
|
return ""
|
|
}
|
|
|
|
ss := make([]string, n+1)
|
|
return strings.Join(ss, s)
|
|
}
|
|
|
|
// non-negative numbers only
|
|
func numDigits(n int) int {
|
|
if n == 0 {
|
|
return 1
|
|
}
|
|
|
|
var d int
|
|
for n > 0 {
|
|
d++
|
|
n /= 10
|
|
}
|
|
|
|
return d
|
|
}
|
|
|
|
func maxLength(names []string) int {
|
|
var m int
|
|
for _, n := range names {
|
|
if len([]rune(n)) > m {
|
|
m = len([]rune(n))
|
|
}
|
|
}
|
|
|
|
return m
|
|
}
|
|
|
|
func padRight(s string, n int) string {
|
|
if len([]rune(s)) >= n {
|
|
return s
|
|
}
|
|
|
|
n -= len([]rune(s))
|
|
return s + timesn("\u00a0", n)
|
|
}
|
|
|
|
func trim(s string) string {
|
|
return strings.TrimFunc(
|
|
s,
|
|
func(r rune) bool { return r != '\u00a0' && unicode.IsSpace(r) },
|
|
)
|
|
}
|
|
|
|
func singleLine(text string) string {
|
|
var l []string
|
|
p := strings.Split(text, "\n")
|
|
for _, part := range p {
|
|
part = trim(part)
|
|
if part == "" {
|
|
continue
|
|
}
|
|
|
|
l = append(l, part)
|
|
}
|
|
|
|
return strings.Join(l, " ")
|
|
}
|
|
|
|
func textToString(t Txt) string {
|
|
if len(t.cat) == 0 && t.link == "" {
|
|
return trim(t.text)
|
|
}
|
|
|
|
if len(t.cat) == 0 && t.text == "" {
|
|
return trim(t.link)
|
|
}
|
|
|
|
if len(t.cat) == 0 {
|
|
return fmt.Sprintf("%s (%s)", t.text, t.link)
|
|
}
|
|
|
|
b := bytes.NewBuffer(nil)
|
|
for i := range t.cat {
|
|
if i > 0 {
|
|
b.WriteRune(' ')
|
|
}
|
|
|
|
b.WriteString(textToString(t.cat[i]))
|
|
}
|
|
|
|
return singleLine(b.String())
|
|
}
|
|
|
|
func itemToParagraph(list Entry, itemText Txt, prefix ...string) Entry {
|
|
p := Entry{
|
|
typ: paragraph,
|
|
wrapWidth: list.wrapWidth,
|
|
indent: list.indent,
|
|
indentFirst: list.indentFirst,
|
|
}
|
|
|
|
if len(prefix) == 0 {
|
|
p.text = itemText
|
|
return p
|
|
}
|
|
|
|
var prefixLength int
|
|
for _, p := range prefix {
|
|
prefixLength += len([]rune(p)) + 1
|
|
}
|
|
|
|
var prefixText []Txt
|
|
for _, p := range prefix {
|
|
prefixText = append(prefixText, Text(p))
|
|
}
|
|
|
|
p.indent += prefixLength
|
|
p.indentFirst -= prefixLength
|
|
p.text.cat = append(prefixText, itemText)
|
|
return p
|
|
}
|