From 80498cd781af5efbf6720a56cdde2dddbcd30a23 Mon Sep 17 00:00:00 2001 From: Georg Bremer Date: Wed, 4 Sep 2019 15:36:20 +0000 Subject: [PATCH] Allow to preserve linebreaks with backslash Other markdown parsers (e.g. flexmark, XCode documentation parser) allow to add a linebreak by prefixing it with backslash. Signed-off-by: Georg Bremer --- ext/redcarpet/markdown.c | 8 ++++++-- test/markdown_test.rb | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/ext/redcarpet/markdown.c b/ext/redcarpet/markdown.c index 95222214..60f49c15 100644 --- a/ext/redcarpet/markdown.c +++ b/ext/redcarpet/markdown.c @@ -745,13 +745,17 @@ char_emphasis(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t of } -/* char_linebreak • '\n' preceded by two spaces (assuming linebreak != 0) */ +/* char_linebreak • '\n' preceded by two spaces or backslash (assuming linebreak != 0) */ static size_t char_linebreak(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size) { - if (offset < 2 || data[-1] != ' ' || data[-2] != ' ') + if (!(offset >= 1 && data[-1] == '\\') && !(offset >= 2 && data[-1] == ' ' && data[-2] == ' ')) return 0; + /* removing escaping backslash if there was any */ + if (ob->size && ob->data[ob->size - 1] == '\\') + ob->size--; + /* removing the last space from ob and rendering */ while (ob->size && ob->data[ob->size - 1] == ' ') ob->size--; diff --git a/test/markdown_test.rb b/test/markdown_test.rb index 4347be9b..979bde04 100644 --- a/test/markdown_test.rb +++ b/test/markdown_test.rb @@ -403,4 +403,25 @@ def test_single_dashes_on_table_headers assert_match //, output end + + def test_double_space_inserts_linebreak + result = %(

here comes a break:
\nThere it was.

) + output = render("here comes a break: \nThere it was.") + + assert_equal result, output + end + + def test_backslash_escapes_linebreak + result = %(

here comes a break:
\nThere it was.

) + output = render("here comes a break:\\\nThere it was.") + + assert_equal result, output + end + + def test_double_backslash_does_not_escape_linebreak + result = %(

here comes a backslash, not a break:\\There it was.

) + output = render("here comes a backslash, not a break:\\There it was.") + + assert_equal result, output + end end