prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Remove frontmatter and add to `meta` in markdown converter
  **Is your feature request related to a problem? Please describe.**
  We would like to use the markdown converter for the `haystack-tutorials` search
  
  **Describe the solution you'd like**
  Frontmatter is often used to store some meta information of markdown files. So it would be a useful feature to be able to auto add these to the `meta` of the created documents
  It's also a good idea to remove the fronmatter from the created documents too. 
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `haystack/nodes/file_converter/markdown.py`
  Content:
  ```
  1 import logging
  2 import re
  3 from pathlib import Path
  4 from typing import Dict, List, Optional, Tuple, Any
  5 
  6 try:
  7     from bs4 import BeautifulSoup, NavigableString
  8     from markdown import markdown
  9 except (ImportError, ModuleNotFoundError) as ie:
  10     from haystack.utils.import_utils import _optional_component_not_installed
  11 
  12     _optional_component_not_installed(__name__, "preprocessing", ie)
  13 
  14 from haystack.nodes.file_converter.base import BaseConverter
  15 from haystack.schema import Document
  16 
  17 
  18 logger = logging.getLogger(__name__)
  19 
  20 
  21 class MarkdownConverter(BaseConverter):
  22     def __init__(
  23         self,
  24         remove_numeric_tables: bool = False,
  25         valid_languages: Optional[List[str]] = None,
  26         id_hash_keys: Optional[List[str]] = None,
  27         progress_bar: bool = True,
  28         remove_code_snippets: bool = True,
  29         extract_headlines: bool = False,
  30     ):
  31         """
  32         :param remove_numeric_tables: Not applicable.
  33         :param valid_languages: Not applicable.
  34         :param id_hash_keys: Generate the document ID from a custom list of strings that refer to the document's
  35             attributes. To make sure you don't have duplicate documents in your DocumentStore if texts are
  36             not unique, you can modify the metadata and pass for example, `"meta"` to this field ([`"content"`, `"meta"`]).
  37             In this case, the ID is generated by using the content and the defined metadata.
  38         :param progress_bar: Show a progress bar for the conversion.
  39         :param remove_code_snippets: Whether to remove snippets from the markdown file.
  40         :param extract_headlines: Whether to extract headings from the markdown file.
  41         """
  42         super().__init__(
  43             remove_numeric_tables=remove_numeric_tables,
  44             valid_languages=valid_languages,
  45             id_hash_keys=id_hash_keys,
  46             progress_bar=progress_bar,
  47         )
  48 
  49         self.remove_code_snippets = remove_code_snippets
  50         self.extract_headlines = extract_headlines
  51 
  52     def convert(
  53         self,
  54         file_path: Path,
  55         meta: Optional[Dict[str, Any]] = None,
  56         remove_numeric_tables: Optional[bool] = None,
  57         valid_languages: Optional[List[str]] = None,
  58         encoding: Optional[str] = "utf-8",
  59         id_hash_keys: Optional[List[str]] = None,
  60         remove_code_snippets: Optional[bool] = None,
  61         extract_headlines: Optional[bool] = None,
  62     ) -> List[Document]:
  63         """
  64         Reads text from a markdown file and executes optional preprocessing steps.
  65 
  66         :param file_path: path of the file to convert
  67         :param meta: dictionary of meta data key-value pairs to append in the returned document.
  68         :param encoding: Select the file encoding (default is `utf-8`)
  69         :param remove_numeric_tables: Not applicable
  70         :param valid_languages: Not applicable
  71         :param id_hash_keys: Generate the document id from a custom list of strings that refer to the document's
  72             attributes. If you want to ensure you don't have duplicate documents in your DocumentStore but texts are
  73             not unique, you can modify the metadata and pass e.g. `"meta"` to this field (e.g. [`"content"`, `"meta"`]).
  74             In this case the id will be generated by using the content and the defined metadata.
  75         :param remove_code_snippets: Whether to remove snippets from the markdown file.
  76         :param extract_headlines: Whether to extract headings from the markdown file.
  77         """
  78 
  79         id_hash_keys = id_hash_keys if id_hash_keys is not None else self.id_hash_keys
  80         remove_code_snippets = remove_code_snippets if remove_code_snippets is not None else self.remove_code_snippets
  81         extract_headlines = extract_headlines if extract_headlines is not None else self.extract_headlines
  82 
  83         with open(file_path, encoding=encoding, errors="ignore") as f:
  84             markdown_text = f.read()
  85 
  86         # md -> html -> text since BeautifulSoup can extract text cleanly
  87         html = markdown(markdown_text)
  88 
  89         # remove code snippets
  90         if remove_code_snippets:
  91             html = re.sub(r"<pre>(.*?)</pre>", " ", html, flags=re.DOTALL)
  92             html = re.sub(r"<code>(.*?)</code>", " ", html, flags=re.DOTALL)
  93         soup = BeautifulSoup(html, "html.parser")
  94 
  95         if extract_headlines:
  96             text, headlines = self._extract_text_and_headlines(soup)
  97             if meta is None:
  98                 meta = {}
  99             meta["headlines"] = headlines
  100         else:
  101             text = soup.get_text()
  102 
  103         document = Document(content=text, meta=meta, id_hash_keys=id_hash_keys)
  104         return [document]
  105 
  106     @staticmethod
  107     def _extract_text_and_headlines(soup: BeautifulSoup) -> Tuple[str, List[Dict]]:
  108         """
  109         Extracts text and headings from a soup object.
  110         """
  111         headline_tags = {"h1", "h2", "h3", "h4", "h5", "h6"}
  112         headlines = []
  113         text = ""
  114         for desc in soup.descendants:
  115             if desc.name in headline_tags:
  116                 current_headline = desc.get_text()
  117                 current_start_idx = len(text)
  118                 current_level = int(desc.name[-1]) - 1
  119                 headlines.append({"headline": current_headline, "start_idx": current_start_idx, "level": current_level})
  120 
  121             if isinstance(desc, NavigableString):
  122                 text += desc.get_text()
  123 
  124         return text, headlines
  125
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/haystack/nodes/file_converter/markdown.py b/haystack/nodes/file_converter/markdown.py
  --- a/haystack/nodes/file_converter/markdown.py
  +++ b/haystack/nodes/file_converter/markdown.py
  @@ -4,6 +4,7 @@
   from typing import Dict, List, Optional, Tuple, Any
   
   try:
  +    import frontmatter
       from bs4 import BeautifulSoup, NavigableString
       from markdown import markdown
   except (ImportError, ModuleNotFoundError) as ie:
  @@ -27,6 +28,7 @@
           progress_bar: bool = True,
           remove_code_snippets: bool = True,
           extract_headlines: bool = False,
  +        add_frontmatter_to_meta: bool = False,
       ):
           """
           :param remove_numeric_tables: Not applicable.
  @@ -38,6 +40,7 @@
           :param progress_bar: Show a progress bar for the conversion.
           :param remove_code_snippets: Whether to remove snippets from the markdown file.
           :param extract_headlines: Whether to extract headings from the markdown file.
  +        :param add_frontmatter_to_meta: Whether to add the contents of the frontmatter to `meta`.
           """
           super().__init__(
               remove_numeric_tables=remove_numeric_tables,
  @@ -48,6 +51,7 @@
   
           self.remove_code_snippets = remove_code_snippets
           self.extract_headlines = extract_headlines
  +        self.add_frontmatter_to_meta = add_frontmatter_to_meta
   
       def convert(
           self,
  @@ -59,6 +63,7 @@
           id_hash_keys: Optional[List[str]] = None,
           remove_code_snippets: Optional[bool] = None,
           extract_headlines: Optional[bool] = None,
  +        add_frontmatter_to_meta: Optional[bool] = None,
       ) -> List[Document]:
           """
           Reads text from a markdown file and executes optional preprocessing steps.
  @@ -74,14 +79,18 @@
               In this case the id will be generated by using the content and the defined metadata.
           :param remove_code_snippets: Whether to remove snippets from the markdown file.
           :param extract_headlines: Whether to extract headings from the markdown file.
  +        :param add_frontmatter_to_meta: Whether to add the contents of the frontmatter to `meta`.
           """
   
           id_hash_keys = id_hash_keys if id_hash_keys is not None else self.id_hash_keys
           remove_code_snippets = remove_code_snippets if remove_code_snippets is not None else self.remove_code_snippets
           extract_headlines = extract_headlines if extract_headlines is not None else self.extract_headlines
  +        add_frontmatter_to_meta = (
  +            add_frontmatter_to_meta if add_frontmatter_to_meta is not None else self.add_frontmatter_to_meta
  +        )
   
           with open(file_path, encoding=encoding, errors="ignore") as f:
  -            markdown_text = f.read()
  +            metadata, markdown_text = frontmatter.parse(f.read())
   
           # md -> html -> text since BeautifulSoup can extract text cleanly
           html = markdown(markdown_text)
  @@ -92,6 +101,12 @@
               html = re.sub(r"<code>(.*?)</code>", " ", html, flags=re.DOTALL)
           soup = BeautifulSoup(html, "html.parser")
   
  +        if add_frontmatter_to_meta:
  +            if meta is None:
  +                meta = metadata
  +            else:
  +                meta.update(metadata)
  +
           if extract_headlines:
               text, headlines = self._extract_text_and_headlines(soup)
               if meta is None:
  
verification_info: {"golden_diff": "diff --git a/haystack/nodes/file_converter/markdown.py b/haystack/nodes/file_converter/markdown.py\n--- a/haystack/nodes/file_converter/markdown.py\n+++ b/haystack/nodes/file_converter/markdown.py\n@@ -4,6 +4,7 @@\n from typing import Dict, List, Optional, Tuple, Any\n \n try:\n+    import frontmatter\n     from bs4 import BeautifulSoup, NavigableString\n     from markdown import markdown\n except (ImportError, ModuleNotFoundError) as ie:\n@@ -27,6 +28,7 @@\n         progress_bar: bool = True,\n         remove_code_snippets: bool = True,\n         extract_headlines: bool = False,\n+        add_frontmatter_to_meta: bool = False,\n     ):\n         \"\"\"\n         :param remove_numeric_tables: Not applicable.\n@@ -38,6 +40,7 @@\n         :param progress_bar: Show a progress bar for the conversion.\n         :param remove_code_snippets: Whether to remove snippets from the markdown file.\n         :param extract_headlines: Whether to extract headings from the markdown file.\n+        :param add_frontmatter_to_meta: Whether to add the contents of the frontmatter to `meta`.\n         \"\"\"\n         super().__init__(\n             remove_numeric_tables=remove_numeric_tables,\n@@ -48,6 +51,7 @@\n \n         self.remove_code_snippets = remove_code_snippets\n         self.extract_headlines = extract_headlines\n+        self.add_frontmatter_to_meta = add_frontmatter_to_meta\n \n     def convert(\n         self,\n@@ -59,6 +63,7 @@\n         id_hash_keys: Optional[List[str]] = None,\n         remove_code_snippets: Optional[bool] = None,\n         extract_headlines: Optional[bool] = None,\n+        add_frontmatter_to_meta: Optional[bool] = None,\n     ) -> List[Document]:\n         \"\"\"\n         Reads text from a markdown file and executes optional preprocessing steps.\n@@ -74,14 +79,18 @@\n             In this case the id will be generated by using the content and the defined metadata.\n         :param remove_code_snippets: Whether to remove snippets from the markdown file.\n         :param extract_headlines: Whether to extract headings from the markdown file.\n+        :param add_frontmatter_to_meta: Whether to add the contents of the frontmatter to `meta`.\n         \"\"\"\n \n         id_hash_keys = id_hash_keys if id_hash_keys is not None else self.id_hash_keys\n         remove_code_snippets = remove_code_snippets if remove_code_snippets is not None else self.remove_code_snippets\n         extract_headlines = extract_headlines if extract_headlines is not None else self.extract_headlines\n+        add_frontmatter_to_meta = (\n+            add_frontmatter_to_meta if add_frontmatter_to_meta is not None else self.add_frontmatter_to_meta\n+        )\n \n         with open(file_path, encoding=encoding, errors=\"ignore\") as f:\n-            markdown_text = f.read()\n+            metadata, markdown_text = frontmatter.parse(f.read())\n \n         # md -> html -> text since BeautifulSoup can extract text cleanly\n         html = markdown(markdown_text)\n@@ -92,6 +101,12 @@\n             html = re.sub(r\"<code>(.*?)</code>\", \" \", html, flags=re.DOTALL)\n         soup = BeautifulSoup(html, \"html.parser\")\n \n+        if add_frontmatter_to_meta:\n+            if meta is None:\n+                meta = metadata\n+            else:\n+                meta.update(metadata)\n+\n         if extract_headlines:\n             text, headlines = self._extract_text_and_headlines(soup)\n             if meta is None:\n", "issue": "Remove frontmatter and add to `meta` in markdown converter\n**Is your feature request related to a problem? Please describe.**\r\nWe would like to use the markdown converter for the `haystack-tutorials` search\r\n\r\n**Describe the solution you'd like**\r\nFrontmatter is often used to store some meta information of markdown files. So it would be a useful feature to be able to auto add these to the `meta` of the created documents\r\nIt's also a good idea to remove the fronmatter from the created documents too. \n", "before_files": [{"content": "import logging\nimport re\nfrom pathlib import Path\nfrom typing import Dict, List, Optional, Tuple, Any\n\ntry:\n    from bs4 import BeautifulSoup, NavigableString\n    from markdown import markdown\nexcept (ImportError, ModuleNotFoundError) as ie:\n    from haystack.utils.import_utils import _optional_component_not_installed\n\n    _optional_component_not_installed(__name__, \"preprocessing\", ie)\n\nfrom haystack.nodes.file_converter.base import BaseConverter\nfrom haystack.schema import Document\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass MarkdownConverter(BaseConverter):\n    def __init__(\n        self,\n        remove_numeric_tables: bool = False,\n        valid_languages: Optional[List[str]] = None,\n        id_hash_keys: Optional[List[str]] = None,\n        progress_bar: bool = True,\n        remove_code_snippets: bool = True,\n        extract_headlines: bool = False,\n    ):\n        \"\"\"\n        :param remove_numeric_tables: Not applicable.\n        :param valid_languages: Not applicable.\n        :param id_hash_keys: Generate the document ID from a custom list of strings that refer to the document's\n            attributes. To make sure you don't have duplicate documents in your DocumentStore if texts are\n            not unique, you can modify the metadata and pass for example, `\"meta\"` to this field ([`\"content\"`, `\"meta\"`]).\n            In this case, the ID is generated by using the content and the defined metadata.\n        :param progress_bar: Show a progress bar for the conversion.\n        :param remove_code_snippets: Whether to remove snippets from the markdown file.\n        :param extract_headlines: Whether to extract headings from the markdown file.\n        \"\"\"\n        super().__init__(\n            remove_numeric_tables=remove_numeric_tables,\n            valid_languages=valid_languages,\n            id_hash_keys=id_hash_keys,\n            progress_bar=progress_bar,\n        )\n\n        self.remove_code_snippets = remove_code_snippets\n        self.extract_headlines = extract_headlines\n\n    def convert(\n        self,\n        file_path: Path,\n        meta: Optional[Dict[str, Any]] = None,\n        remove_numeric_tables: Optional[bool] = None,\n        valid_languages: Optional[List[str]] = None,\n        encoding: Optional[str] = \"utf-8\",\n        id_hash_keys: Optional[List[str]] = None,\n        remove_code_snippets: Optional[bool] = None,\n        extract_headlines: Optional[bool] = None,\n    ) -> List[Document]:\n        \"\"\"\n        Reads text from a markdown file and executes optional preprocessing steps.\n\n        :param file_path: path of the file to convert\n        :param meta: dictionary of meta data key-value pairs to append in the returned document.\n        :param encoding: Select the file encoding (default is `utf-8`)\n        :param remove_numeric_tables: Not applicable\n        :param valid_languages: Not applicable\n        :param id_hash_keys: Generate the document id from a custom list of strings that refer to the document's\n            attributes. If you want to ensure you don't have duplicate documents in your DocumentStore but texts are\n            not unique, you can modify the metadata and pass e.g. `\"meta\"` to this field (e.g. [`\"content\"`, `\"meta\"`]).\n            In this case the id will be generated by using the content and the defined metadata.\n        :param remove_code_snippets: Whether to remove snippets from the markdown file.\n        :param extract_headlines: Whether to extract headings from the markdown file.\n        \"\"\"\n\n        id_hash_keys = id_hash_keys if id_hash_keys is not None else self.id_hash_keys\n        remove_code_snippets = remove_code_snippets if remove_code_snippets is not None else self.remove_code_snippets\n        extract_headlines = extract_headlines if extract_headlines is not None else self.extract_headlines\n\n        with open(file_path, encoding=encoding, errors=\"ignore\") as f:\n            markdown_text = f.read()\n\n        # md -> html -> text since BeautifulSoup can extract text cleanly\n        html = markdown(markdown_text)\n\n        # remove code snippets\n        if remove_code_snippets:\n            html = re.sub(r\"<pre>(.*?)</pre>\", \" \", html, flags=re.DOTALL)\n            html = re.sub(r\"<code>(.*?)</code>\", \" \", html, flags=re.DOTALL)\n        soup = BeautifulSoup(html, \"html.parser\")\n\n        if extract_headlines:\n            text, headlines = self._extract_text_and_headlines(soup)\n            if meta is None:\n                meta = {}\n            meta[\"headlines\"] = headlines\n        else:\n            text = soup.get_text()\n\n        document = Document(content=text, meta=meta, id_hash_keys=id_hash_keys)\n        return [document]\n\n    @staticmethod\n    def _extract_text_and_headlines(soup: BeautifulSoup) -> Tuple[str, List[Dict]]:\n        \"\"\"\n        Extracts text and headings from a soup object.\n        \"\"\"\n        headline_tags = {\"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\"}\n        headlines = []\n        text = \"\"\n        for desc in soup.descendants:\n            if desc.name in headline_tags:\n                current_headline = desc.get_text()\n                current_start_idx = len(text)\n                current_level = int(desc.name[-1]) - 1\n                headlines.append({\"headline\": current_headline, \"start_idx\": current_start_idx, \"level\": current_level})\n\n            if isinstance(desc, NavigableString):\n                text += desc.get_text()\n\n        return text, headlines\n", "path": "haystack/nodes/file_converter/markdown.py"}], "after_files": [{"content": "import logging\nimport re\nfrom pathlib import Path\nfrom typing import Dict, List, Optional, Tuple, Any\n\ntry:\n    import frontmatter\n    from bs4 import BeautifulSoup, NavigableString\n    from markdown import markdown\nexcept (ImportError, ModuleNotFoundError) as ie:\n    from haystack.utils.import_utils import _optional_component_not_installed\n\n    _optional_component_not_installed(__name__, \"preprocessing\", ie)\n\nfrom haystack.nodes.file_converter.base import BaseConverter\nfrom haystack.schema import Document\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass MarkdownConverter(BaseConverter):\n    def __init__(\n        self,\n        remove_numeric_tables: bool = False,\n        valid_languages: Optional[List[str]] = None,\n        id_hash_keys: Optional[List[str]] = None,\n        progress_bar: bool = True,\n        remove_code_snippets: bool = True,\n        extract_headlines: bool = False,\n        add_frontmatter_to_meta: bool = False,\n    ):\n        \"\"\"\n        :param remove_numeric_tables: Not applicable.\n        :param valid_languages: Not applicable.\n        :param id_hash_keys: Generate the document ID from a custom list of strings that refer to the document's\n            attributes. To make sure you don't have duplicate documents in your DocumentStore if texts are\n            not unique, you can modify the metadata and pass for example, `\"meta\"` to this field ([`\"content\"`, `\"meta\"`]).\n            In this case, the ID is generated by using the content and the defined metadata.\n        :param progress_bar: Show a progress bar for the conversion.\n        :param remove_code_snippets: Whether to remove snippets from the markdown file.\n        :param extract_headlines: Whether to extract headings from the markdown file.\n        :param add_frontmatter_to_meta: Whether to add the contents of the frontmatter to `meta`.\n        \"\"\"\n        super().__init__(\n            remove_numeric_tables=remove_numeric_tables,\n            valid_languages=valid_languages,\n            id_hash_keys=id_hash_keys,\n            progress_bar=progress_bar,\n        )\n\n        self.remove_code_snippets = remove_code_snippets\n        self.extract_headlines = extract_headlines\n        self.add_frontmatter_to_meta = add_frontmatter_to_meta\n\n    def convert(\n        self,\n        file_path: Path,\n        meta: Optional[Dict[str, Any]] = None,\n        remove_numeric_tables: Optional[bool] = None,\n        valid_languages: Optional[List[str]] = None,\n        encoding: Optional[str] = \"utf-8\",\n        id_hash_keys: Optional[List[str]] = None,\n        remove_code_snippets: Optional[bool] = None,\n        extract_headlines: Optional[bool] = None,\n        add_frontmatter_to_meta: Optional[bool] = None,\n    ) -> List[Document]:\n        \"\"\"\n        Reads text from a markdown file and executes optional preprocessing steps.\n\n        :param file_path: path of the file to convert\n        :param meta: dictionary of meta data key-value pairs to append in the returned document.\n        :param encoding: Select the file encoding (default is `utf-8`)\n        :param remove_numeric_tables: Not applicable\n        :param valid_languages: Not applicable\n        :param id_hash_keys: Generate the document id from a custom list of strings that refer to the document's\n            attributes. If you want to ensure you don't have duplicate documents in your DocumentStore but texts are\n            not unique, you can modify the metadata and pass e.g. `\"meta\"` to this field (e.g. [`\"content\"`, `\"meta\"`]).\n            In this case the id will be generated by using the content and the defined metadata.\n        :param remove_code_snippets: Whether to remove snippets from the markdown file.\n        :param extract_headlines: Whether to extract headings from the markdown file.\n        :param add_frontmatter_to_meta: Whether to add the contents of the frontmatter to `meta`.\n        \"\"\"\n\n        id_hash_keys = id_hash_keys if id_hash_keys is not None else self.id_hash_keys\n        remove_code_snippets = remove_code_snippets if remove_code_snippets is not None else self.remove_code_snippets\n        extract_headlines = extract_headlines if extract_headlines is not None else self.extract_headlines\n        add_frontmatter_to_meta = (\n            add_frontmatter_to_meta if add_frontmatter_to_meta is not None else self.add_frontmatter_to_meta\n        )\n\n        with open(file_path, encoding=encoding, errors=\"ignore\") as f:\n            metadata, markdown_text = frontmatter.parse(f.read())\n\n        # md -> html -> text since BeautifulSoup can extract text cleanly\n        html = markdown(markdown_text)\n\n        # remove code snippets\n        if remove_code_snippets:\n            html = re.sub(r\"<pre>(.*?)</pre>\", \" \", html, flags=re.DOTALL)\n            html = re.sub(r\"<code>(.*?)</code>\", \" \", html, flags=re.DOTALL)\n        soup = BeautifulSoup(html, \"html.parser\")\n\n        if add_frontmatter_to_meta:\n            if meta is None:\n                meta = metadata\n            else:\n                meta.update(metadata)\n\n        if extract_headlines:\n            text, headlines = self._extract_text_and_headlines(soup)\n            if meta is None:\n                meta = {}\n            meta[\"headlines\"] = headlines\n        else:\n            text = soup.get_text()\n\n        document = Document(content=text, meta=meta, id_hash_keys=id_hash_keys)\n        return [document]\n\n    @staticmethod\n    def _extract_text_and_headlines(soup: BeautifulSoup) -> Tuple[str, List[Dict]]:\n        \"\"\"\n        Extracts text and headings from a soup object.\n        \"\"\"\n        headline_tags = {\"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\"}\n        headlines = []\n        text = \"\"\n        for desc in soup.descendants:\n            if desc.name in headline_tags:\n                current_headline = desc.get_text()\n                current_start_idx = len(text)\n                current_level = int(desc.name[-1]) - 1\n                headlines.append({\"headline\": current_headline, \"start_idx\": current_start_idx, \"level\": current_level})\n\n            if isinstance(desc, NavigableString):\n                text += desc.get_text()\n\n        return text, headlines\n", "path": "haystack/nodes/file_converter/markdown.py"}]}