diff --git a/tests/test_block.py b/tests/test_block.py
index c69105c2..2d3ed2bf 100644
--- a/tests/test_block.py
+++ b/tests/test_block.py
@@ -69,3 +69,25 @@ def test_blockcode_comment():
t = textile.Textile()
result = t.parse(input)
assert result == expect
+
+def test_extended_pre_block_with_many_newlines():
+ """Extra newlines in an extended pre block should not get cut down to only
+ two."""
+ text = '''pre.. word
+
+another
+
+word
+
+
+yet anothe word'''
+ expect = '''
word
+
+another
+
+word
+
+
+yet anothe word
'''
+ result = textile.textile(text)
+ assert result == expect
diff --git a/tests/test_github_issues.py b/tests/test_github_issues.py
index 26162906..eeace4ac 100644
--- a/tests/test_github_issues.py
+++ b/tests/test_github_issues.py
@@ -137,3 +137,22 @@ def test_github_issue_45():
result = textile.textile(text)
expect = '\ttest
'
assert result == expect
+
+def test_github_issue_47():
+ """Incorrect wrap pre-formatted value"""
+ text = '''pre.. word
+
+another
+
+word
+
+yet anothe word'''
+ result = textile.textile(text)
+ expect = '''word
+
+another
+
+word
+
+yet anothe word
'''
+ assert result == expect
diff --git a/textile/core.py b/textile/core.py
index 28f8db40..2c7a25b9 100644
--- a/textile/core.py
+++ b/textile/core.py
@@ -433,12 +433,12 @@ def block(self, text):
r'(?::(?P\S+))? (?P.*)$'.format(tre,
align_re_s, cls_re_s))
match = re.search(pattern, line, flags=re.S | re.U)
+ if out:
+ last_item_is_a_shelf = out[-1] in self.shelf
# tag specified on this line.
if match:
# if we had a previous extended tag but not this time, close up
# the tag
- if out:
- last_item_is_a_shelf = out[-1] in self.shelf
if ext and match.group('tag') and last_item_is_a_shelf:
content = out.pop()
content = generate_tag(block.inner_tag, content,
@@ -467,9 +467,14 @@ def block(self, text):
if ext and out:
line = '{0}\n\n{1}'.format(out.pop(), line)
whitespace = ' \t\n\r\f\v'
- if ext or not line[0] in whitespace:
+ try:
+ line_first_char_blank = line[0] in whitespace
+ except IndexError:
+ line_first_char_blank = True
+ if ext or not line_first_char_blank:
block = Block(self, tag, atts, ext, cite, line)
- if block.tag == 'p' and not has_raw_text(block.content):
+ if (block.tag == 'p' and not has_raw_text(block.content)
+ or last_item_is_a_shelf):
line = block.content
else:
line = generate_tag(block.outer_tag, block.content,
diff --git a/textile/utils.py b/textile/utils.py
index 00da8315..5f5d1a51 100644
--- a/textile/utils.py
+++ b/textile/utils.py
@@ -110,9 +110,8 @@ def list_type(list_string):
def normalize_newlines(string):
out = string.strip()
- out = re.sub(r'\r\n', '\n', out)
- out = re.sub(r'\n{3,}', '\n\n', out)
- out = re.sub(r'\n\s*\n', '\n\n', out)
+ out = re.sub(r'\r\n?', '\n', out)
+ out = re.sub(r'^[ \t]*\n', '\n', out, flags=re.M)
out = re.sub(r'"$', '" ', out)
return out