BuildForwardBody composes the text/plain body of a forward: the caller's optional comment, a Gmail-style divider, the original headers as a quote block, then the original text body if extraction succeeded.
(comment string, ctx ForwardContext)
| 198 | // as a quote block, then the original text body if extraction |
| 199 | // succeeded. |
| 200 | func BuildForwardBody(comment string, ctx ForwardContext) string { |
| 201 | var buf strings.Builder |
| 202 | if c := strings.TrimRight(comment, "\r\n"); c != "" { |
| 203 | buf.WriteString(c) |
| 204 | buf.WriteString("\r\n\r\n") |
| 205 | } |
| 206 | buf.WriteString("---------- Forwarded message ---------\r\n") |
| 207 | writeHeaderLine(&buf, "From", ctx.From) |
| 208 | writeHeaderLine(&buf, "Date", ctx.Date) |
| 209 | writeHeaderLine(&buf, "Subject", ctx.Subject) |
| 210 | writeHeaderLine(&buf, "To", ctx.To) |
| 211 | writeHeaderLine(&buf, "Cc", ctx.Cc) |
| 212 | buf.WriteString("\r\n") |
| 213 | if ctx.Text != "" { |
| 214 | // Normalize line endings before re-emitting: a naive |
| 215 | // ReplaceAll("\n","\r\n") turns existing "\r\n" into "\r\r\n", |
| 216 | // which mail clients render as a literal CR. Real-world bodies |
| 217 | // almost always arrive CRLF-terminated, so the lazy form would |
| 218 | // fire on virtually every multi-line forward. |
| 219 | text := strings.ReplaceAll(ctx.Text, "\r\n", "\n") |
| 220 | text = strings.ReplaceAll(text, "\n", "\r\n") |
| 221 | buf.WriteString(text) |
| 222 | if !strings.HasSuffix(text, "\r\n") { |
| 223 | buf.WriteString("\r\n") |
| 224 | } |
| 225 | } |
| 226 | return buf.String() |
| 227 | } |
| 228 | |
| 229 | // BuildForwardHTMLBody composes the text/html body of a forward. The |
| 230 | // caller's HTML comment is emitted as-is (the API contract treats |