-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhancement request: OutputLinePrefix - Add function to allow for >2 line only #15
Comments
I have a patch that makes this work, but I need to think about it a bit more to make sure I'm not overfitting the solution specifically for email header folding/making the options confusing 😄 diff --git a/wrapper.go b/wrapper.go
index 2d2e421..c08beb0 100644
--- a/wrapper.go
+++ b/wrapper.go
@@ -26,6 +26,11 @@ type Wrapper struct {
// Default: ""
OutputLinePrefix string
+ // If set, OutputFirstLinePrefix overrides OutputLinePrefix for the first line of output.
+ // Can be set to an empty string to avoid prepending a space in the case of email header folding.
+ // Default: nil
+ OutputFirstLinePrefix *string
+
// OutputLineSuffix is appended to any output lines.
// Default: ""
OutputLineSuffix string
@@ -82,7 +87,7 @@ func (w Wrapper) Wrap(s string, limit int) string {
for _, str := range strings.Split(s, w.Newline) {
str = strings.TrimPrefix(str, w.TrimInputPrefix)
str = strings.TrimSuffix(str, w.TrimInputSuffix)
- ret += w.line(str, limit) + w.Newline
+ ret += w.line(str, limit, 0) + w.Newline
}
if w.StripTrailingNewline {
@@ -93,9 +98,14 @@ func (w Wrapper) Wrap(s string, limit int) string {
// line will wrap a single line of text at the given length.
// If limit is less than 1, the string remains unwrapped.
-func (w Wrapper) line(s string, limit int) string {
+func (w Wrapper) line(s string, limit int, depth int) string {
+ outputLinePrefix := w.OutputLinePrefix
+ if depth == 0 && w.OutputFirstLinePrefix != nil {
+ outputLinePrefix = *w.OutputFirstLinePrefix
+ }
+
if limit < 1 || utf8.RuneCountInString(s) < limit+1 {
- return w.OutputLinePrefix + s + w.OutputLineSuffix
+ return outputLinePrefix + s + w.OutputLineSuffix
}
// Find the index of the last breakpoint within the limit.
@@ -114,11 +124,11 @@ func (w Wrapper) line(s string, limit int) string {
i = strings.IndexAny(s, w.Breakpoints)
// Nothing left to do!
if i < 0 {
- return w.OutputLinePrefix + s + w.OutputLineSuffix
+ return outputLinePrefix + s + w.OutputLineSuffix
}
}
}
// Recurse until we have nothing left to do.
- return w.OutputLinePrefix + s[:i] + w.OutputLineSuffix + w.Newline + w.line(s[i+breakpointWidth:], limit)
+ return outputLinePrefix + s[:i] + w.OutputLineSuffix + w.Newline + w.line(s[i+breakpointWidth:], limit, depth+1)
}
diff --git a/wrapper_test.go b/wrapper_test.go
index 7d115bf..d4e6432 100644
--- a/wrapper_test.go
+++ b/wrapper_test.go
@@ -105,3 +105,38 @@ oooooord`,
})
}
}
+
+func TestWrapper_Wrap_EmailHeaderFolding(t *testing.T) {
+ const limit = 14
+
+ tests := []struct {
+ input string
+ expected string
+ }{
+ {
+ input: "Subject: This is a test",
+ expected: `Subject: This
+ is a test`,
+ },
+ }
+
+ for i, test := range tests {
+ t.Run(strconv.FormatInt(int64(i), 10), func(t *testing.T) {
+ w := wrap.NewWrapper()
+ w.CutLongWords = true
+ w.OutputLinePrefix = " "
+ w.OutputFirstLinePrefix = strPtr("")
+ w.StripTrailingNewline = true
+
+ actual := w.Wrap(test.input, limit)
+
+ if actual != test.expected {
+ t.Errorf("expected %q but got %q", test.expected, actual)
+ }
+ })
+ }
+}
+
+func strPtr(s string) *string {
+ return &s
+} |
I thought about it a bit more and found a neater solution without any library changes. You can set the newline character to be Currently Wrap doesn't take into account the width of a custom Newline string, but I think it should so I'll fix that. For now, you can subtract 1 from limit to always be within your specified width. https://play.golang.org/p/pMyy2u043Xr package main
import (
"fmt"
"github.com/bbrks/wrap/v2"
)
func main() {
w := wrap.NewWrapper()
// break with a newline and then a space
w.Newline = "\n "
const width = 80
const text = "Subject: This is a test of wrapping where folded lines should be indented with whitespace. Each time Wrap breaks a line, the newline is followed by a single space character. We've managed to do this with existing options, rather than adding a special case for line prefixes."
// width-1 to account for the space after \n
fmt.Println(w.Wrap(text, width-1))
} |
Thanks for your thoughts on this. I'll go play with that suggestion you made. Only comment to make for now is that newline in mail is |
Hmm....is it just me or have I inadvertently stumbled across a bug ? https://play.golang.org/p/OB0h83c2BiN The splitting behavior, even with Might (?) be the expected behavior with |
It's sort of intentional for breaking in English prose, but in this case it can be fixed by limiting what characters can be considered breakpoints to only spaces:
|
Ps: You'll still want to |
Thanks ! |
Use case : using
bbrks/wrap
with email headers (https://tools.ietf.org/html/rfc2822#section-2.2.3)i.e. ability to add a whitespace only to line numbers >=2, leaving first line untouched.
The text was updated successfully, but these errors were encountered: