203 lines
3.4 KiB
Go
203 lines
3.4 KiB
Go
package wand
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
func printer(out io.Writer) (printf func(f string, args ...any), println func(args ...any), finish func() error) {
|
|
var err error
|
|
printf = func(f string, args ...any) {
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
_, err = fmt.Fprintf(out, f, args...)
|
|
}
|
|
|
|
println = func(args ...any) {
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
_, err = fmt.Fprintln(out, args...)
|
|
}
|
|
|
|
finish = func() error {
|
|
return err
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func paragraphs(s string) string {
|
|
var (
|
|
paragraph []string
|
|
paragraphs [][]string
|
|
)
|
|
|
|
l := strings.Split(s, "\n")
|
|
for i := range l {
|
|
l[i] = strings.TrimSpace(l[i])
|
|
if l[i] == "" {
|
|
if len(paragraph) > 0 {
|
|
paragraphs, paragraph = append(paragraphs, paragraph), nil
|
|
}
|
|
|
|
continue
|
|
}
|
|
|
|
paragraph = append(paragraph, l[i])
|
|
}
|
|
|
|
if len(paragraph) > 0 {
|
|
paragraphs = append(paragraphs, paragraph)
|
|
}
|
|
|
|
var cparagraphs []string
|
|
for _, p := range paragraphs {
|
|
cparagraphs = append(cparagraphs, strings.Join(p, " "))
|
|
}
|
|
|
|
return strings.Join(cparagraphs, "\n\n")
|
|
}
|
|
|
|
func lines(s string) string {
|
|
p := paragraphs(s)
|
|
pp := strings.Split(p, "\n\n")
|
|
return strings.Join(pp, "\n")
|
|
}
|
|
|
|
func manParagraphs(s string) string {
|
|
p := paragraphs(s)
|
|
pp := strings.Split(p, "\n\n")
|
|
for i := range pp {
|
|
pp[i] = fmt.Sprintf(".PP\n%s", pp[i])
|
|
}
|
|
|
|
return strings.Join(pp, "\n")
|
|
}
|
|
|
|
func manLines(s string) string {
|
|
l := lines(s)
|
|
ll := strings.Split(l, "\n")
|
|
for i := range ll {
|
|
ll[i] = fmt.Sprintf(".br\n%s", ll[i])
|
|
}
|
|
|
|
return strings.Join(ll, "\n")
|
|
}
|
|
|
|
func escapeTeletype(s string) string {
|
|
r := []rune(s)
|
|
for i := range r {
|
|
if r[i] >= 0x00 && r[i] <= 0x1f && r[i] != '\n' && r[i] != '\t' {
|
|
r[i] = 0xb7
|
|
}
|
|
|
|
if r[i] >= 0x7f && r[i] <= 0x9f {
|
|
r[i] = 0xb7
|
|
}
|
|
}
|
|
|
|
return string(r)
|
|
}
|
|
|
|
func escapeRoff(s string) string {
|
|
var (
|
|
rr []rune
|
|
lastNewline bool
|
|
)
|
|
|
|
r := []rune(s)
|
|
for _, ri := range r {
|
|
switch ri {
|
|
case '\\', '-', '"':
|
|
rr = append(rr, '\\', ri)
|
|
case '.', '\'':
|
|
if lastNewline {
|
|
rr = append(rr, '\\')
|
|
}
|
|
|
|
rr = append(rr, ri)
|
|
case 0x2013:
|
|
rr = append(rr, []rune("\\(en")...)
|
|
case 0x2014:
|
|
rr = append(rr, []rune("\\(em")...)
|
|
case 0x201c:
|
|
rr = append(rr, []rune("\\(lq")...)
|
|
case 0x201d:
|
|
rr = append(rr, []rune("\\(rq")...)
|
|
case 0x2018:
|
|
rr = append(rr, []rune("\\(oq")...)
|
|
case 0x2019:
|
|
rr = append(rr, []rune("\\(cq")...)
|
|
default:
|
|
rr = append(rr, ri)
|
|
}
|
|
|
|
lastNewline = ri == '\n'
|
|
}
|
|
|
|
return string(rr)
|
|
}
|
|
|
|
func escapeMD(s string) string {
|
|
var (
|
|
rr []rune
|
|
lastDigit bool
|
|
)
|
|
|
|
r := []rune(s)
|
|
for _, ri := range r {
|
|
switch ri {
|
|
case '*', '_', '#', '-', '+', '[', ']', '`', '<', '>', '|', '\\':
|
|
rr = append(rr, '\\', ri)
|
|
case '.':
|
|
if lastDigit {
|
|
rr = append(rr, '\\')
|
|
}
|
|
|
|
rr = append(rr, ri)
|
|
default:
|
|
rr = append(rr, ri)
|
|
}
|
|
|
|
lastDigit = ri >= 0 && ri <= 9
|
|
}
|
|
|
|
return string(rr)
|
|
}
|
|
|
|
func prepareOptions(o []docOption) (names []string, descriptions map[string]string) {
|
|
for _, oi := range o {
|
|
ons := []string{fmt.Sprintf("--%s", oi.name)}
|
|
for _, sn := range oi.shortNames {
|
|
ons = append(ons, fmt.Sprintf("-%s", sn))
|
|
}
|
|
|
|
n := strings.Join(ons, ", ")
|
|
if oi.isBool {
|
|
n = fmt.Sprintf("%s [b]", n)
|
|
} else {
|
|
n = fmt.Sprintf("%s %s", n, oi.typ)
|
|
}
|
|
|
|
if oi.acceptsMultiple {
|
|
n = fmt.Sprintf("%s [*]", n)
|
|
}
|
|
|
|
names = append(names, n)
|
|
if descriptions == nil {
|
|
descriptions = make(map[string]string)
|
|
}
|
|
|
|
descriptions[n] = oi.description
|
|
}
|
|
|
|
sort.Strings(names)
|
|
return
|
|
}
|