diff --git a/lib/reverse_markdown/converters/base.rb b/lib/reverse_markdown/converters/base.rb
index cfdf7c9..1d1e4fe 100644
--- a/lib/reverse_markdown/converters/base.rb
+++ b/lib/reverse_markdown/converters/base.rb
@@ -15,6 +15,26 @@ def escape_keychars(string)
string.gsub(/(? '\*', '_' => '\_')
end
+ # Wrap content with markers (e.g., ** or _), splitting at paragraph breaks
+ # so markers don't span across breaks (which breaks markdown rendering)
+ def wrap_with_markers(content, marker)
+ # Split on paragraph breaks, preserving the breaks
+ segments = content.split(/(\s*\n\s*\n\s*)/)
+
+ segments.map.with_index do |segment, i|
+ if i.odd? # This is a break segment (captured delimiter)
+ segment
+ elsif segment.strip.empty?
+ segment
+ else
+ # Wrap with markers, preserving border whitespace
+ leading = segment[/\A\s*/]
+ trailing = segment[/\s*\z/]
+ "#{leading}#{marker}#{segment.strip}#{marker}#{trailing}"
+ end
+ end.join
+ end
+
def extract_title(node)
title = escape_keychars(node['title'].to_s)
title.empty? ? '' : %[ "#{title}"]
diff --git a/lib/reverse_markdown/converters/em.rb b/lib/reverse_markdown/converters/em.rb
index e31582a..5d7167a 100644
--- a/lib/reverse_markdown/converters/em.rb
+++ b/lib/reverse_markdown/converters/em.rb
@@ -6,7 +6,7 @@ def convert(node, state = {})
if content.strip.empty? || state[:already_italic]
content
else
- "#{content[/^\s*/]}_#{content.strip}_#{content[/\s*$/]}"
+ wrap_with_markers(content, '_')
end
end
end
diff --git a/lib/reverse_markdown/converters/h.rb b/lib/reverse_markdown/converters/h.rb
index 1aa50c3..bf929aa 100644
--- a/lib/reverse_markdown/converters/h.rb
+++ b/lib/reverse_markdown/converters/h.rb
@@ -3,7 +3,10 @@ module Converters
class H < Base
def convert(node, state = {})
prefix = '#' * node.name[/\d/].to_i
- ["\n", prefix, ' ', treat_children(node, state), "\n"].join
+ content = treat_children(node, state).strip
+ # Merge lines into one (markdown headings can't span multiple lines)
+ content = content.split(/\s*\n\s*/).join(' ')
+ "\n#{prefix} #{content}\n"
end
end
diff --git a/lib/reverse_markdown/converters/strong.rb b/lib/reverse_markdown/converters/strong.rb
index b513096..6993939 100644
--- a/lib/reverse_markdown/converters/strong.rb
+++ b/lib/reverse_markdown/converters/strong.rb
@@ -6,7 +6,7 @@ def convert(node, state = {})
if content.strip.empty? || state[:already_strong]
content
else
- "#{content[/^\s*/]}**#{content.strip}**#{content[/\s*$/]}"
+ wrap_with_markers(content, '**')
end
end
end
diff --git a/spec/lib/reverse_markdown/converters/em_spec.rb b/spec/lib/reverse_markdown/converters/em_spec.rb
new file mode 100644
index 0000000..ab98c2e
--- /dev/null
+++ b/spec/lib/reverse_markdown/converters/em_spec.rb
@@ -0,0 +1,28 @@
+require 'spec_helper'
+
+describe ReverseMarkdown::Converters::Em do
+ let(:converter) { ReverseMarkdown::Converters::Em.new }
+
+ it 'returns an empty string if the node is empty' do
+ input = node_for('')
+ expect(converter.convert(input)).to eq ''
+ end
+
+ it 'returns just the content if the em tag is nested in another em' do
+ input = node_for('foo')
+ expect(converter.convert(input.children.first, already_italic: true)).to eq 'foo'
+ end
+
+ it 'moves border whitespaces outside of the delimiters tag' do
+ input = node_for(" \n foo ")
+ expect(converter.convert(input)).to eq " _foo_ "
+ end
+
+ it 'splits markers at paragraph breaks' do
+ # Issue #95:
inside em creates a paragraph break
+ # Markers must be split so markdown renders correctly
+ result = ReverseMarkdown.convert('hello
world')
+ expect(result).to include('_hello_')
+ expect(result).to include('_world_')
+ end
+end
diff --git a/spec/lib/reverse_markdown/converters/h_spec.rb b/spec/lib/reverse_markdown/converters/h_spec.rb
new file mode 100644
index 0000000..9f87090
--- /dev/null
+++ b/spec/lib/reverse_markdown/converters/h_spec.rb
@@ -0,0 +1,16 @@
+require 'spec_helper'
+
+describe ReverseMarkdown::Converters::H do
+ let(:converter) { ReverseMarkdown::Converters::H.new }
+
+ it 'merges line breaks into single line' do
+ # Markdown headings can't span multiple lines, so merge them
+ result = ReverseMarkdown.convert('