From 8ea7b1c86cbf04e11f99df702c954ce18ead52c3 Mon Sep 17 00:00:00 2001 From: Brandon Wilson Date: Wed, 11 Aug 2021 21:27:32 -0400 Subject: [PATCH] Optionally Preserving New Lines (#115) --- ansi/paragraph.go | 2 +- ansi/renderer.go | 9 +++++---- glamour.go | 8 ++++++++ glamour_test.go | 30 ++++++++++++++++++++++++++++++ testdata/preserved_newline.in | 4 ++++ testdata/preserved_newline.test | 5 +++++ 6 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 testdata/preserved_newline.in create mode 100644 testdata/preserved_newline.test diff --git a/ansi/paragraph.go b/ansi/paragraph.go index 71e0725..0d3f99a 100644 --- a/ansi/paragraph.go +++ b/ansi/paragraph.go @@ -38,7 +38,7 @@ func (e *ParagraphElement) Finish(w io.Writer, ctx RenderContext) error { mw := NewMarginWriter(ctx, w, rules) if len(strings.TrimSpace(bs.Current().Block.String())) > 0 { flow := wordwrap.NewWriter(int(bs.Width(ctx))) - flow.KeepNewlines = false + flow.KeepNewlines = ctx.options.PreserveNewLines _, _ = flow.Write(bs.Current().Block.Bytes()) flow.Close() diff --git a/ansi/renderer.go b/ansi/renderer.go index ddadbb7..55444ca 100644 --- a/ansi/renderer.go +++ b/ansi/renderer.go @@ -15,10 +15,11 @@ import ( // Options is used to configure an ANSIRenderer. type Options struct { - BaseURL string - WordWrap int - ColorProfile termenv.Profile - Styles StyleConfig + BaseURL string + WordWrap int + PreserveNewLines bool + ColorProfile termenv.Profile + Styles StyleConfig } // ANSIRenderer renders markdown content as ANSI escaped sequences. diff --git a/glamour.go b/glamour.go index 7b4a14c..048d45a 100644 --- a/glamour.go +++ b/glamour.go @@ -185,6 +185,14 @@ func WithWordWrap(wordWrap int) TermRendererOption { } } +// WithWordWrap sets a TermRenderer's word wrap. +func WithPreservedNewLines() TermRendererOption { + return func(tr *TermRenderer) error { + tr.ansiOptions.PreserveNewLines = true + return nil + } +} + // WithEmoji sets a TermRenderer's emoji rendering. func WithEmoji() TermRendererOption { return func(tr *TermRenderer) error { diff --git a/glamour_test.go b/glamour_test.go index 52f59a5..7f36d21 100644 --- a/glamour_test.go +++ b/glamour_test.go @@ -113,6 +113,36 @@ func TestWithEmoji(t *testing.T) { } } +func TestWithPreservedNewLines(t *testing.T) { + r, err := NewTermRenderer( + WithPreservedNewLines(), + ) + if err != nil { + t.Fatal(err) + } + + in, err := ioutil.ReadFile("testdata/preserved_newline.in") + if err != nil { + t.Fatal(err) + } + + b, err := r.Render(string(in)) + if err != nil { + t.Fatal(err) + } + + // verify + td, err := ioutil.ReadFile("testdata/preserved_newline.test") + if err != nil { + t.Fatal(err) + } + + if !bytes.Equal(td, []byte(b)) { + t.Errorf("Rendered output doesn't match!\nExpected: `\n%s`\nGot: `\n%s`\n", + string(td), b) + } +} + func TestStyles(t *testing.T) { _, err := NewTermRenderer( WithAutoStyle(), diff --git a/testdata/preserved_newline.in b/testdata/preserved_newline.in new file mode 100644 index 0000000..f36a086 --- /dev/null +++ b/testdata/preserved_newline.in @@ -0,0 +1,4 @@ +Preserving line breaks will ensure +that this text displays on two separate lines + +While this text appears on one line, it will wrap when the text meets the renderer's default value of 80 characters \ No newline at end of file diff --git a/testdata/preserved_newline.test b/testdata/preserved_newline.test new file mode 100644 index 0000000..54f4f7c --- /dev/null +++ b/testdata/preserved_newline.test @@ -0,0 +1,5 @@ +Preserving line breaks will ensure +that this text displays on two separate lines + +While this text appears on one line, it will wrap when the text meets the +renderer's default value of 80 characters