diff --git a/tabulate/__init__.py b/tabulate/__init__.py index 12a2950..3648350 100644 --- a/tabulate/__init__.py +++ b/tabulate/__init__.py @@ -754,8 +754,8 @@ def escape_empty(val): # - tsv: TBD # - textile: Replace \n with
(must be well-formed XML) -_multiline_codes = re.compile(r"\r|\n|\r\n") -_multiline_codes_bytes = re.compile(b"\r|\n|\r\n") +_multiline_codes = re.compile(r"\r\n|\r|\n") +_multiline_codes_bytes = re.compile(b"\r\n|\r|\n") # Handle ANSI escape sequences for both control sequence introducer (CSI) and # operating system command (OSC). Both of these begin with 0x1b (or octal 033), diff --git a/test/test_regression.py b/test/test_regression.py index 9555676..8a48c30 100644 --- a/test/test_regression.py +++ b/test/test_regression.py @@ -598,3 +598,21 @@ def test_github_escape_pipe_character(): result = tabulate([["foo|bar"]], headers=("spam|eggs",), tablefmt="github") expected = "| spam\\|eggs |\n|:------------|\n| foo\\|bar |" assert_equal(expected, result) + + +def test_crlf_multiline_header_matches_lf(): + "Regression: CRLF in a header is one line break, same as LF (issue #488)" + expected = "\n".join( + [ + "+-----+", + "| A |", + "| B |", + "+=====+", + "| 1 |", + "+-----+", + ] + ) + lf = tabulate([[1]], headers=["A\nB"], tablefmt="grid") + crlf = tabulate([[1]], headers=["A\r\nB"], tablefmt="grid") + assert_equal(expected, lf) + assert_equal(expected, crlf)