diff --git a/ext/glamour/extension.c b/ext/glamour/extension.c index 5c01739..ec6dff9 100644 --- a/ext/glamour/extension.c +++ b/ext/glamour/extension.c @@ -33,7 +33,7 @@ static VALUE glamour_render_rb(int argc, VALUE *argv, VALUE self) { const char *style = "auto"; const char *base_url = NULL; - int width = 0; + int width = -1; int emoji = 0; int preserve_newlines = 0; int color_profile = COLOR_PROFILE_AUTO; @@ -90,7 +90,7 @@ static VALUE glamour_render_rb(int argc, VALUE *argv, VALUE self) { char *result; - if (has_advanced_options || width > 0) { + if (has_advanced_options || width >= 0) { result = glamour_render_with_options( (char *) StringValueCStr(markdown), (char *) style, @@ -128,7 +128,7 @@ static VALUE glamour_render_with_json_rb(int argc, VALUE *argv, VALUE self) { Check_Type(markdown, T_STRING); Check_Type(json_style, T_STRING); - int width = 0; + int width = -1; if (!NIL_P(options)) { VALUE width_value = rb_hash_lookup(options, ID2SYM(rb_intern("width"))); @@ -197,7 +197,7 @@ static VALUE renderer_initialize(int argc, VALUE *argv, VALUE self) { rb_scan_args(argc, argv, "0:", &options); rb_iv_set(self, "@style", rb_str_new_cstr("auto")); - rb_iv_set(self, "@width", INT2FIX(0)); + rb_iv_set(self, "@width", Qnil); rb_iv_set(self, "@emoji", Qfalse); rb_iv_set(self, "@preserve_newlines", Qfalse); rb_iv_set(self, "@base_url", Qnil); @@ -236,7 +236,8 @@ static VALUE renderer_render(VALUE self, VALUE markdown) { VALUE json_style = rb_iv_get(self, "@json_style"); if (!NIL_P(json_style)) { - int width = NUM2INT(rb_iv_get(self, "@width")); + VALUE width_iv = rb_iv_get(self, "@width"); + int width = NIL_P(width_iv) ? -1 : NUM2INT(width_iv); char *result = glamour_render_with_json_style( (char *)StringValueCStr(markdown), @@ -251,7 +252,8 @@ static VALUE renderer_render(VALUE self, VALUE markdown) { VALUE style_value = rb_iv_get(self, "@style"); const char *style = NIL_P(style_value) ? "auto" : StringValueCStr(style_value); - int width = NUM2INT(rb_iv_get(self, "@width")); + VALUE width_iv = rb_iv_get(self, "@width"); + int width = NIL_P(width_iv) ? -1 : NUM2INT(width_iv); int emoji = RTEST(rb_iv_get(self, "@emoji")) ? 1 : 0; int preserve_newlines = RTEST(rb_iv_get(self, "@preserve_newlines")) ? 1 : 0; diff --git a/go/glamour.go b/go/glamour.go index 3c67edb..ccff20e 100644 --- a/go/glamour.go +++ b/go/glamour.go @@ -64,7 +64,7 @@ func glamour_render_with_options( options = append(options, glamour.WithAutoStyle()) } - if width > 0 { + if width >= 0 { options = append(options, glamour.WithWordWrap(int(width))) } @@ -118,7 +118,7 @@ func glamour_render_with_json_style(markdown *C.char, jsonStyle *C.char, width C jsonBytes := []byte(C.GoString(jsonStyle)) options = append(options, glamour.WithStylesFromJSONBytes(jsonBytes)) - if width > 0 { + if width >= 0 { options = append(options, glamour.WithWordWrap(int(width))) } diff --git a/lib/glamour.rb b/lib/glamour.rb index decd231..5d2b42a 100644 --- a/lib/glamour.rb +++ b/lib/glamour.rb @@ -24,7 +24,7 @@ class << self # @rbs style: String | singleton(Glamour::Style) -- style name or Style subclass # @rbs width: Integer -- optional word wrap width # @rbs return: String -- rendered output with ANSI escape codes - def render(markdown, style: "auto", width: 0, **options) + def render(markdown, style: "auto", width: nil, **options) if style_class?(style) render_with_style_class(markdown, style, width: width, **options) else @@ -36,7 +36,7 @@ def render(markdown, style: "auto", width: 0, **options) # @rbs style: Hash[Symbol, untyped] | String | singleton(Glamour::Style) -- style definition # @rbs width: Integer -- optional word wrap width # @rbs return: String -- rendered output with ANSI escape codes - def render_with_style(markdown, style, width: 0) + def render_with_style(markdown, style, width: nil) json_style = style_to_json(style) render_with_json(markdown, json_style, width: width) @@ -71,7 +71,7 @@ def style_to_json(style) # @rbs style_class: singleton(Glamour::Style) -- the Style subclass # @rbs width: Integer -- optional word wrap width # @rbs return: String -- rendered output with ANSI escape codes - def render_with_style_class(markdown, style_class, width: 0, **_options) + def render_with_style_class(markdown, style_class, width: nil, **_options) styles = style_class.to_h if styles.empty? diff --git a/lib/glamour/renderer.rb b/lib/glamour/renderer.rb index f216388..12d394d 100644 --- a/lib/glamour/renderer.rb +++ b/lib/glamour/renderer.rb @@ -21,7 +21,7 @@ def style_hash=(hash) # @rbs json_style: String? -- JSON style definition # @rbs style_hash: Hash[Symbol, untyped]? -- style definition hash # @rbs return: void - def initialize(style: "auto", width: 0, emoji: false, preserve_newlines: false, base_url: nil, + def initialize(style: "auto", width: nil, emoji: false, preserve_newlines: false, base_url: nil, color_profile: :auto, json_style: nil, style_hash: nil) actual_style = style actual_json_style = json_style diff --git a/lib/glamour/style.rb b/lib/glamour/style.rb index bf2929c..e60e1c6 100644 --- a/lib/glamour/style.rb +++ b/lib/glamour/style.rb @@ -33,7 +33,7 @@ def to_json(*_args) # @rbs markdown: String -- the markdown content to render # @rbs width: Integer -- optional word wrap width # @rbs return: String -- rendered output with ANSI escape codes - def render(markdown, width: 0, **options) + def render(markdown, width: nil, **options) Glamour.render(markdown, style: self, width: width, **options) end diff --git a/test/glamour_test.rb b/test/glamour_test.rb index 8f52b0f..cd82f75 100644 --- a/test/glamour_test.rb +++ b/test/glamour_test.rb @@ -59,6 +59,20 @@ class GlamourTest < Minitest::Spec assert_kind_of String, result end + it "renders with word wrap by default" do + long_text = "This is a very very long paragraph" * 10 + result = Glamour.render(long_text, style: "notty") + lines = result.strip.lines.map(&:rstrip).reject(&:empty?) + assert_operator lines.length, :>, 1 + end + + it "renders without word wrap with width: 0" do + long_text = "This is a very very long paragraph" * 10 + result = Glamour.render(long_text, style: "notty", width: 0) + lines = result.strip.lines.map(&:rstrip).reject(&:empty?) + assert_equal 1, lines.length + end + it "renders with style and width" do result = Glamour.render("# Hello World", style: "dark", width: 80) refute_nil result @@ -134,6 +148,22 @@ class GlamourTest < Minitest::Spec assert_kind_of String, result end + it "enables word wrap by default with json style" do + json_style = '{"document": {"margin": 0}}' + long_text = "This is a very very long paragraph" * 10 + result = Glamour.render_with_json(long_text, json_style) + lines = result.strip.lines.reject(&:empty?) + assert_operator lines.length, :>, 1 + end + + it "disables word wrap with width: 0 and json style" do + json_style = '{"document": {"margin": 0}}' + long_text = "This is a very very long paragraph" * 10 + result = Glamour.render_with_json(long_text, json_style, width: 0) + lines = result.strip.lines.map(&:rstrip).reject(&:empty?) + assert_equal 1, lines.length + end + it "renders with json style and width" do json_style = '{"document": {"margin": 2}}' result = Glamour.render_with_json("# Hello World", json_style, width: 40) @@ -152,6 +182,20 @@ class GlamourTest < Minitest::Spec assert_includes result, "Hello" end + it "wraps by default when rendering with style hash" do + long_text = "This is a very long paragraph " * 10 + result = Glamour.render_with_style(long_text, { document: { margin: 0 } }) + lines = result.strip.lines.map(&:rstrip).reject(&:empty?) + assert_operator lines.length, :>, 1 + end + + it "disables word wrap when rendering with style hash and width: 0" do + long_text = "This is a very long paragraph " * 10 + result = Glamour.render_with_style(long_text, { document: { margin: 0 } }, width: 0) + lines = result.strip.lines.map(&:rstrip).reject(&:empty?) + assert_equal 1, lines.length + end + it "renders with style json string" do json_style = '{"document": {"margin": 2}}' result = Glamour.render_with_style("# Hello", json_style) diff --git a/test/renderer_test.rb b/test/renderer_test.rb index 36e9595..6fc51ee 100644 --- a/test/renderer_test.rb +++ b/test/renderer_test.rb @@ -8,7 +8,7 @@ class RendererTest < Minitest::Spec renderer = Glamour::Renderer.new refute_nil renderer assert_equal "auto", renderer.style - assert_equal 0, renderer.width + assert_nil renderer.width assert_equal false, renderer.emoji end @@ -33,6 +33,22 @@ class RendererTest < Minitest::Spec assert_includes result, "Hello" end + it "renders markdown with word wrap by default" do + long_text = "This is a very very long paragraph" * 10 + renderer = Glamour::Renderer.new(style: "notty") + result = renderer.render(long_text) + lines = result.strip.lines.map(&:strip).reject(&:empty?) + assert_operator lines.length, :>, 1 + end + + it "renders markdown with word wrap disabled with width: 0" do + long_text = "This is a very very long paragraph" * 10 + renderer = Glamour::Renderer.new(style: "notty", width: 0) + result = renderer.render(long_text) + lines = result.strip.lines.map(&:strip).reject(&:empty?) + assert_equal 1, lines.length, "Expected no word wrap with width: 0, but got multiple lines: #{lines.inspect}" + end + it "renders with json_style option" do json_style = '{"document": {"margin": 2}}' renderer = Glamour::Renderer.new(json_style: json_style) diff --git a/test/style_dsl_test.rb b/test/style_dsl_test.rb index a8bfedb..2f3ecc6 100644 --- a/test/style_dsl_test.rb +++ b/test/style_dsl_test.rb @@ -117,6 +117,21 @@ class StyleTest < Minitest::Spec assert_kind_of String, result end + it "renders with word wrap by default" do + long_text = "This is a very very long paragraph" * 10 + klass = Class.new(Glamour::Style) + result = klass.render(long_text, width: 40) + assert_operator result.strip.lines.reject(&:empty?).length, :>, 1 + end + + it "renders without word wrap with width: 0" do + long_text = "This is a very very long paragraph" * 10 + klass = Class.new(Glamour::Style) + result = klass.render(long_text, width: 0) + lines = result.strip.lines.map(&:rstrip).reject(&:empty?) + assert_equal 1, lines.length + end + it "handles empty style class" do klass = Class.new(Glamour::Style)