113 lines
2.4 KiB
Go
113 lines
2.4 KiB
Go
package repository
|
|
|
|
import (
|
|
"bytes"
|
|
"go/doc"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
// commentTrimSurrounding is a regex to trim surrounding new line and tabs.
|
|
// This is needed to find the correct level of indentation.
|
|
commentTrimSurrounding = regexp.MustCompile(`(^\n)|(\n\t+$)`)
|
|
)
|
|
|
|
// TabWidth is used to format comments.
|
|
var TabWidth = 4
|
|
|
|
// Comment represents a raw comment string. Most use cases should use GoString()
|
|
// to get the comment's content.
|
|
type Comment struct {
|
|
Raw string
|
|
}
|
|
|
|
// IsEmpty returns true if the comment is empty.
|
|
func (c Comment) IsEmpty() bool {
|
|
return c.Raw == ""
|
|
}
|
|
|
|
// GoString formats the documentation string in 80 columns wide paragraphs and
|
|
// prefix each line with "// ". The ident argument controls the nested level. If
|
|
// less than or equal to zero, then it is changed to 1, which is the top level.
|
|
func (c Comment) GoString(ident int) string {
|
|
if c.Raw == "" {
|
|
return ""
|
|
}
|
|
|
|
if ident < 1 {
|
|
ident = 1
|
|
}
|
|
|
|
ident-- // 0th-indexed
|
|
ident *= TabWidth
|
|
|
|
var lines = strings.Split(c.WrapText(80-len("// ")-ident), "\n")
|
|
for i, line := range lines {
|
|
if line != "" {
|
|
line = "// " + line
|
|
} else {
|
|
line = "//"
|
|
}
|
|
lines[i] = line
|
|
}
|
|
|
|
return strings.Join(lines, "\n")
|
|
}
|
|
|
|
// WrapText wraps the raw text in n columns wide paragraphs.
|
|
func (c Comment) WrapText(column int) string {
|
|
var txt = c.Unindent()
|
|
if txt == "" {
|
|
return ""
|
|
}
|
|
|
|
buf := bytes.Buffer{}
|
|
doc.ToText(&buf, txt, "", strings.Repeat(" ", TabWidth-1), column)
|
|
|
|
text := strings.TrimRight(buf.String(), "\n")
|
|
text = strings.Replace(text, "\t", strings.Repeat(" ", TabWidth), -1)
|
|
|
|
return text
|
|
}
|
|
|
|
// Unindent removes the indentations that were there for the sake of syntax in
|
|
// RawText. It gets the lowest indentation level from each line and trim it.
|
|
func (c Comment) Unindent() string {
|
|
if c.IsEmpty() {
|
|
return ""
|
|
}
|
|
|
|
// Trim new lines.
|
|
txt := commentTrimSurrounding.ReplaceAllString(c.Raw, "")
|
|
|
|
// Split the lines and rejoin them later to trim the indentation.
|
|
var lines = strings.Split(txt, "\n")
|
|
var indent = 0
|
|
|
|
// Get the minimum indentation count.
|
|
for _, line := range lines {
|
|
linedent := strings.Count(line, "\t")
|
|
if linedent < 0 {
|
|
continue
|
|
}
|
|
if linedent < indent || indent == 0 {
|
|
indent = linedent
|
|
}
|
|
}
|
|
|
|
// Trim the indentation.
|
|
if indent > 0 {
|
|
for i, line := range lines {
|
|
if len(line) > 0 {
|
|
lines[i] = line[indent-1:]
|
|
}
|
|
}
|
|
}
|
|
|
|
// Rejoin.
|
|
txt = strings.Join(lines, "\n")
|
|
|
|
return txt
|
|
}
|