Repository: RasaHQ/rasa

Issue:
Converting from JSON to Markdown writes newlines
Having a `\n` in the text of an intent example works for JSON, but when we use `rasa.nlu.convert` to dump to Markdown, this prints newlines, which splits the example in two at train time

Discussion:

Patch:
diff --git a/rasa/nlu/training_data/formats/markdown.py b/rasa/nlu/training_data/formats/markdown.py
index e87b58dfb35..17715581b06 100644
--- a/rasa/nlu/training_data/formats/markdown.py
+++ b/rasa/nlu/training_data/formats/markdown.py
@@ -27,6 +27,22 @@ item_regex = re.compile(r"\s*[-*+]\s*(.+)")
 comment_regex = re.compile(r"<!--[\s\S]*?--!*>", re.MULTILINE)
 fname_regex = re.compile(r"\s*([^-*+]+)")
 
+ESCAPE_DCT = {"\b": "\\b", "\f": "\\f", "\n": "\\n", "\r": "\\r", "\t": "\\t"}
+
+ESCAPE = re.compile(r"[\b\f\n\r\t]")
+
+
+def encode_string(s):
+    """Return a encoded python string
+
+    """
+
+    def replace(match):
+        return ESCAPE_DCT[match.group(0)]
+
+    return ESCAPE.sub(replace, s)
+
+
 logger = logging.getLogger(__name__)
 
 
@@ -258,17 +274,17 @@ class MarkdownWriter(TrainingDataWriter):
     def _generate_section_header_md(section_type, title, prepend_newline=True):
         """generates markdown section header."""
         prefix = "\n" if prepend_newline else ""
-        return prefix + "## {}:{}\n".format(section_type, title)
+        return prefix + "## {}:{}\n".format(section_type, encode_string(title))
 
     @staticmethod
     def _generate_item_md(text):
         """generates markdown for a list item."""
-        return "- {}\n".format(text)
+        return "- {}\n".format(encode_string(text))
 
     @staticmethod
     def _generate_fname_md(text):
         """generates markdown for a lookup table file path."""
-        return "  {}\n".format(text)
+        return "  {}\n".format(encode_string(text))
 
     def _generate_message_md(self, message):
         """generates markdown for a message object."""


Test patch:
diff --git a/data/test/json_with_special_chars_convered_to_md.md b/data/test/json_with_special_chars_convered_to_md.md
new file mode 100644
index 00000000000..60433f35015
--- /dev/null
+++ b/data/test/json_with_special_chars_convered_to_md.md
@@ -0,0 +1,10 @@
+## intent:affirm
+- yes\n
+
+## intent:restaurant_search
+- i'm looking for a place in the [n\north\n](location) of town
+
+## synonym:chinese
+- C\thi\rne\bs
+- chines
+- Chinese
diff --git a/data/test/training_data_containing_special_chars.json b/data/test/training_data_containing_special_chars.json
new file mode 100644
index 00000000000..e16261c86ef
--- /dev/null
+++ b/data/test/training_data_containing_special_chars.json
@@ -0,0 +1,33 @@
+{
+  "rasa_nlu_data": {
+    "common_examples": [
+      {
+        "text": "yes\n",
+        "intent": "affirm"
+      },
+      {
+        "entities": [
+          {
+            "start": 31, 
+            "end": 38,
+            "value": "n\north\n",
+            "entity": "location"
+          }
+        ], 
+        "intent": "restaurant_search\t",
+        "text": "i'm looking for a place in the n\north\n of town"
+      }
+    ], 
+    "entity_synonyms": [
+      {
+        "synonyms": [
+          "C\thi\rne\bs",
+          "chines", 
+          "Chinese"
+        ], 
+        "value": "chinese"
+      }
+    ], 
+    "regex_features": []
+  }
+}
\ No newline at end of file
diff --git a/tests/nlu/base/test_training_data.py b/tests/nlu/base/test_training_data.py
index cdb3e243fb5..07f36edf385 100644
--- a/tests/nlu/base/test_training_data.py
+++ b/tests/nlu/base/test_training_data.py
@@ -396,6 +396,12 @@ def cmp_dict_list(firsts, seconds):
             "md",
             None,
         ),
+        (
+            "data/test/training_data_containing_special_chars.json",
+            "data/test/json_with_special_chars_convered_to_md.md",
+            "md",
+            None,
+        ),
     ],
 )
 def test_training_data_conversion(