Files
undent/undent.go

99 lines
2.4 KiB
Go

// Package undent removes leading indentation/white-space from strings and byte
// slices.
package undent
import (
"fmt"
"io"
"regexp"
)
var matcher = regexp.MustCompile(`(?m)^([ \t]*)(?:\S)`)
// Bytes removes leading indentation/white-space from given string and returns
// it as a byte slice.
func Bytes(s string) []byte {
return []byte(String(s))
}
// Bytesf removes leading indentation/white-space from given format string
// before passing format and all additional arguments to fmt.Sprintf, returning
// the result as a byte slice.
func Bytesf(format string, a ...interface{}) []byte {
return []byte(Stringf(format, a...))
}
// String removes leading indentation/white-space from given string.
func String(s string) string {
if len(s) > 0 && s[0] == '\n' {
s = s[1:]
}
matches := matcher.FindAllString(s, -1)
if len(matches) == 0 {
return s
}
index := 0
length := len(matches[0])
for i, s := range matches[1:] {
l := len(s)
if l < length {
index = i + 1
length = l
}
}
if length <= 1 {
return s
}
indent := matches[index][0 : length-1]
return regexp.MustCompile(
`(?m)^`+regexp.QuoteMeta(indent),
).ReplaceAllLiteralString(s, "")
}
// Stringf removes leading indentation/white-space from given format string
// before passing format and all additional arguments to fmt.Sprintf, returning
// the result.
func Stringf(format string, a ...interface{}) string {
return fmt.Sprintf(String(format), a...)
}
// Print will undent any strings arguments before passing them to fmt.Print.
func Print(a ...interface{}) (n int, err error) {
return fmt.Print(undentInterfaces(a)...)
}
// Printf will undent the given format string before passing it and all
// arguments to fmt.Printf.
func Printf(format string, a ...interface{}) (n int, err error) {
return fmt.Printf(String(format), a...)
}
// Fprint will undent any string arguments before passing them to fmt.Fprint.
func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
return fmt.Fprint(w, undentInterfaces(a)...)
}
// Fprintf will undent the given format string before passing it and all
// arguments to fmt.Fprintf.
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
return fmt.Fprintf(w, String(format), a...)
}
func undentInterfaces(a []interface{}) []interface{} {
var r []interface{}
for _, v := range a {
if s, ok := v.(string); ok {
v = String(s)
}
r = append(r, v)
}
return r
}