prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Improve formatting for "arguments" sections with long examples.
  The line-wrapping for this endpoint's API documentation looks really ugly:
  
  ![image](https://user-images.githubusercontent.com/2746074/47042583-7e303200-d140-11e8-9b4f-d6fc1325dcba.png)
  
  We should either remove the maximum width on "description", or figure out a way to use more than one line for a given endpoint that doesn't look so bad (e.g. having the example be on the next line after the rest of the endpoint description).
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `zerver/lib/bugdown/api_arguments_table_generator.py`
  Content:
  ```
  1 import re
  2 import os
  3 import ujson
  4 
  5 from django.utils.html import escape as escape_html
  6 from markdown.extensions import Extension
  7 from markdown.preprocessors import Preprocessor
  8 from zerver.lib.openapi import get_openapi_parameters
  9 from typing import Any, Dict, Optional, List
  10 import markdown
  11 
  12 REGEXP = re.compile(r'\{generate_api_arguments_table\|\s*(.+?)\s*\|\s*(.+)\s*\}')
  13 
  14 
  15 class MarkdownArgumentsTableGenerator(Extension):
  16     def __init__(self, configs: Optional[Dict[str, Any]]=None) -> None:
  17         if configs is None:
  18             configs = {}
  19         self.config = {
  20             'base_path': ['.', 'Default location from which to evaluate relative paths for the JSON files.'],
  21         }
  22         for key, value in configs.items():
  23             self.setConfig(key, value)
  24 
  25     def extendMarkdown(self, md: markdown.Markdown, md_globals: Dict[str, Any]) -> None:
  26         md.preprocessors.add(
  27             'generate_api_arguments', APIArgumentsTablePreprocessor(md, self.getConfigs()), '_begin'
  28         )
  29 
  30 
  31 class APIArgumentsTablePreprocessor(Preprocessor):
  32     def __init__(self, md: markdown.Markdown, config: Dict[str, Any]) -> None:
  33         super(APIArgumentsTablePreprocessor, self).__init__(md)
  34         self.base_path = config['base_path']
  35 
  36     def run(self, lines: List[str]) -> List[str]:
  37         done = False
  38         while not done:
  39             for line in lines:
  40                 loc = lines.index(line)
  41                 match = REGEXP.search(line)
  42 
  43                 if not match:
  44                     continue
  45 
  46                 filename = match.group(1)
  47                 doc_name = match.group(2)
  48                 filename = os.path.expanduser(filename)
  49 
  50                 is_openapi_format = filename.endswith('.yaml')
  51 
  52                 if not os.path.isabs(filename):
  53                     parent_dir = self.base_path
  54                     filename = os.path.normpath(os.path.join(parent_dir, filename))
  55 
  56                 if is_openapi_format:
  57                     endpoint, method = doc_name.rsplit(':', 1)
  58                     arguments = []  # type: List[Dict[str, Any]]
  59 
  60                     try:
  61                         arguments = get_openapi_parameters(endpoint, method)
  62                     except KeyError as e:
  63                         # Don't raise an exception if the "parameters"
  64                         # field is missing; we assume that's because the
  65                         # endpoint doesn't accept any parameters
  66                         if e.args != ('parameters',):
  67                             raise e
  68                 else:
  69                     with open(filename, 'r') as fp:
  70                         json_obj = ujson.load(fp)
  71                         arguments = json_obj[doc_name]
  72 
  73                 if arguments:
  74                     text = self.render_table(arguments)
  75                 else:
  76                     text = ['This endpoint does not consume any arguments.']
  77                 # The line that contains the directive to include the macro
  78                 # may be preceded or followed by text or tags, in that case
  79                 # we need to make sure that any preceding or following text
  80                 # stays the same.
  81                 line_split = REGEXP.split(line, maxsplit=0)
  82                 preceding = line_split[0]
  83                 following = line_split[-1]
  84                 text = [preceding] + text + [following]
  85                 lines = lines[:loc] + text + lines[loc+1:]
  86                 break
  87             else:
  88                 done = True
  89         return lines
  90 
  91     def render_table(self, arguments: List[Dict[str, Any]]) -> List[str]:
  92         table = []
  93         beginning = """
  94 <table class="table">
  95   <thead>
  96     <tr>
  97       <th>Argument</th>
  98       <th>Example</th>
  99       <th>Required</th>
  100       <th>Description</th>
  101     </tr>
  102   </thead>
  103 <tbody>
  104 """
  105         tr = """
  106 <tr>
  107   <td><code>{argument}</code></td>
  108   <td><code>{example}</code></td>
  109   <td>{required}</td>
  110   <td>{description}</td>
  111 </tr>
  112 """
  113 
  114         table.append(beginning)
  115 
  116         md_engine = markdown.Markdown(extensions=[])
  117 
  118         for argument in arguments:
  119             description = argument['description']
  120 
  121             oneof = ['`' + item + '`'
  122                      for item in argument.get('schema', {}).get('enum', [])]
  123             if oneof:
  124                 description += '\nMust be one of: {}.'.format(', '.join(oneof))
  125 
  126             default = argument.get('schema', {}).get('default')
  127             if default is not None:
  128                 description += '\nDefaults to `{}`.'.format(ujson.dumps(default))
  129 
  130             # TODO: Swagger allows indicating where the argument goes
  131             # (path, querystring, form data...). A column in the table should
  132             # be added for this.
  133             table.append(tr.format(
  134                 argument=argument.get('argument') or argument.get('name'),
  135                 # Show this as JSON to avoid changing the quoting style, which
  136                 # may cause problems with JSON encoding.
  137                 example=escape_html(ujson.dumps(argument['example'])),
  138                 required='Yes' if argument.get('required') else 'No',
  139                 description=md_engine.convert(description),
  140             ))
  141 
  142         table.append("</tbody>")
  143         table.append("</table>")
  144 
  145         return table
  146 
  147 def makeExtension(*args: Any, **kwargs: str) -> MarkdownArgumentsTableGenerator:
  148     return MarkdownArgumentsTableGenerator(kwargs)
  149
  ```
  --- 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/zerver/lib/bugdown/api_arguments_table_generator.py b/zerver/lib/bugdown/api_arguments_table_generator.py
  --- a/zerver/lib/bugdown/api_arguments_table_generator.py
  +++ b/zerver/lib/bugdown/api_arguments_table_generator.py
  @@ -105,7 +105,7 @@
           tr = """
   <tr>
     <td><code>{argument}</code></td>
  -  <td><code>{example}</code></td>
  +  <td class="json-api-example"><code>{example}</code></td>
     <td>{required}</td>
     <td>{description}</td>
   </tr>
  
verification_info: {"golden_diff": "diff --git a/zerver/lib/bugdown/api_arguments_table_generator.py b/zerver/lib/bugdown/api_arguments_table_generator.py\n--- a/zerver/lib/bugdown/api_arguments_table_generator.py\n+++ b/zerver/lib/bugdown/api_arguments_table_generator.py\n@@ -105,7 +105,7 @@\n         tr = \"\"\"\n <tr>\n   <td><code>{argument}</code></td>\n-  <td><code>{example}</code></td>\n+  <td class=\"json-api-example\"><code>{example}</code></td>\n   <td>{required}</td>\n   <td>{description}</td>\n </tr>\n", "issue": "Improve formatting for \"arguments\" sections with long examples.\nThe line-wrapping for this endpoint's API documentation looks really ugly:\r\n\r\n![image](https://user-images.githubusercontent.com/2746074/47042583-7e303200-d140-11e8-9b4f-d6fc1325dcba.png)\r\n\r\nWe should either remove the maximum width on \"description\", or figure out a way to use more than one line for a given endpoint that doesn't look so bad (e.g. having the example be on the next line after the rest of the endpoint description).\n", "before_files": [{"content": "import re\nimport os\nimport ujson\n\nfrom django.utils.html import escape as escape_html\nfrom markdown.extensions import Extension\nfrom markdown.preprocessors import Preprocessor\nfrom zerver.lib.openapi import get_openapi_parameters\nfrom typing import Any, Dict, Optional, List\nimport markdown\n\nREGEXP = re.compile(r'\\{generate_api_arguments_table\\|\\s*(.+?)\\s*\\|\\s*(.+)\\s*\\}')\n\n\nclass MarkdownArgumentsTableGenerator(Extension):\n    def __init__(self, configs: Optional[Dict[str, Any]]=None) -> None:\n        if configs is None:\n            configs = {}\n        self.config = {\n            'base_path': ['.', 'Default location from which to evaluate relative paths for the JSON files.'],\n        }\n        for key, value in configs.items():\n            self.setConfig(key, value)\n\n    def extendMarkdown(self, md: markdown.Markdown, md_globals: Dict[str, Any]) -> None:\n        md.preprocessors.add(\n            'generate_api_arguments', APIArgumentsTablePreprocessor(md, self.getConfigs()), '_begin'\n        )\n\n\nclass APIArgumentsTablePreprocessor(Preprocessor):\n    def __init__(self, md: markdown.Markdown, config: Dict[str, Any]) -> None:\n        super(APIArgumentsTablePreprocessor, self).__init__(md)\n        self.base_path = config['base_path']\n\n    def run(self, lines: List[str]) -> List[str]:\n        done = False\n        while not done:\n            for line in lines:\n                loc = lines.index(line)\n                match = REGEXP.search(line)\n\n                if not match:\n                    continue\n\n                filename = match.group(1)\n                doc_name = match.group(2)\n                filename = os.path.expanduser(filename)\n\n                is_openapi_format = filename.endswith('.yaml')\n\n                if not os.path.isabs(filename):\n                    parent_dir = self.base_path\n                    filename = os.path.normpath(os.path.join(parent_dir, filename))\n\n                if is_openapi_format:\n                    endpoint, method = doc_name.rsplit(':', 1)\n                    arguments = []  # type: List[Dict[str, Any]]\n\n                    try:\n                        arguments = get_openapi_parameters(endpoint, method)\n                    except KeyError as e:\n                        # Don't raise an exception if the \"parameters\"\n                        # field is missing; we assume that's because the\n                        # endpoint doesn't accept any parameters\n                        if e.args != ('parameters',):\n                            raise e\n                else:\n                    with open(filename, 'r') as fp:\n                        json_obj = ujson.load(fp)\n                        arguments = json_obj[doc_name]\n\n                if arguments:\n                    text = self.render_table(arguments)\n                else:\n                    text = ['This endpoint does not consume any arguments.']\n                # The line that contains the directive to include the macro\n                # may be preceded or followed by text or tags, in that case\n                # we need to make sure that any preceding or following text\n                # stays the same.\n                line_split = REGEXP.split(line, maxsplit=0)\n                preceding = line_split[0]\n                following = line_split[-1]\n                text = [preceding] + text + [following]\n                lines = lines[:loc] + text + lines[loc+1:]\n                break\n            else:\n                done = True\n        return lines\n\n    def render_table(self, arguments: List[Dict[str, Any]]) -> List[str]:\n        table = []\n        beginning = \"\"\"\n<table class=\"table\">\n  <thead>\n    <tr>\n      <th>Argument</th>\n      <th>Example</th>\n      <th>Required</th>\n      <th>Description</th>\n    </tr>\n  </thead>\n<tbody>\n\"\"\"\n        tr = \"\"\"\n<tr>\n  <td><code>{argument}</code></td>\n  <td><code>{example}</code></td>\n  <td>{required}</td>\n  <td>{description}</td>\n</tr>\n\"\"\"\n\n        table.append(beginning)\n\n        md_engine = markdown.Markdown(extensions=[])\n\n        for argument in arguments:\n            description = argument['description']\n\n            oneof = ['`' + item + '`'\n                     for item in argument.get('schema', {}).get('enum', [])]\n            if oneof:\n                description += '\\nMust be one of: {}.'.format(', '.join(oneof))\n\n            default = argument.get('schema', {}).get('default')\n            if default is not None:\n                description += '\\nDefaults to `{}`.'.format(ujson.dumps(default))\n\n            # TODO: Swagger allows indicating where the argument goes\n            # (path, querystring, form data...). A column in the table should\n            # be added for this.\n            table.append(tr.format(\n                argument=argument.get('argument') or argument.get('name'),\n                # Show this as JSON to avoid changing the quoting style, which\n                # may cause problems with JSON encoding.\n                example=escape_html(ujson.dumps(argument['example'])),\n                required='Yes' if argument.get('required') else 'No',\n                description=md_engine.convert(description),\n            ))\n\n        table.append(\"</tbody>\")\n        table.append(\"</table>\")\n\n        return table\n\ndef makeExtension(*args: Any, **kwargs: str) -> MarkdownArgumentsTableGenerator:\n    return MarkdownArgumentsTableGenerator(kwargs)\n", "path": "zerver/lib/bugdown/api_arguments_table_generator.py"}], "after_files": [{"content": "import re\nimport os\nimport ujson\n\nfrom django.utils.html import escape as escape_html\nfrom markdown.extensions import Extension\nfrom markdown.preprocessors import Preprocessor\nfrom zerver.lib.openapi import get_openapi_parameters\nfrom typing import Any, Dict, Optional, List\nimport markdown\n\nREGEXP = re.compile(r'\\{generate_api_arguments_table\\|\\s*(.+?)\\s*\\|\\s*(.+)\\s*\\}')\n\n\nclass MarkdownArgumentsTableGenerator(Extension):\n    def __init__(self, configs: Optional[Dict[str, Any]]=None) -> None:\n        if configs is None:\n            configs = {}\n        self.config = {\n            'base_path': ['.', 'Default location from which to evaluate relative paths for the JSON files.'],\n        }\n        for key, value in configs.items():\n            self.setConfig(key, value)\n\n    def extendMarkdown(self, md: markdown.Markdown, md_globals: Dict[str, Any]) -> None:\n        md.preprocessors.add(\n            'generate_api_arguments', APIArgumentsTablePreprocessor(md, self.getConfigs()), '_begin'\n        )\n\n\nclass APIArgumentsTablePreprocessor(Preprocessor):\n    def __init__(self, md: markdown.Markdown, config: Dict[str, Any]) -> None:\n        super(APIArgumentsTablePreprocessor, self).__init__(md)\n        self.base_path = config['base_path']\n\n    def run(self, lines: List[str]) -> List[str]:\n        done = False\n        while not done:\n            for line in lines:\n                loc = lines.index(line)\n                match = REGEXP.search(line)\n\n                if not match:\n                    continue\n\n                filename = match.group(1)\n                doc_name = match.group(2)\n                filename = os.path.expanduser(filename)\n\n                is_openapi_format = filename.endswith('.yaml')\n\n                if not os.path.isabs(filename):\n                    parent_dir = self.base_path\n                    filename = os.path.normpath(os.path.join(parent_dir, filename))\n\n                if is_openapi_format:\n                    endpoint, method = doc_name.rsplit(':', 1)\n                    arguments = []  # type: List[Dict[str, Any]]\n\n                    try:\n                        arguments = get_openapi_parameters(endpoint, method)\n                    except KeyError as e:\n                        # Don't raise an exception if the \"parameters\"\n                        # field is missing; we assume that's because the\n                        # endpoint doesn't accept any parameters\n                        if e.args != ('parameters',):\n                            raise e\n                else:\n                    with open(filename, 'r') as fp:\n                        json_obj = ujson.load(fp)\n                        arguments = json_obj[doc_name]\n\n                if arguments:\n                    text = self.render_table(arguments)\n                else:\n                    text = ['This endpoint does not consume any arguments.']\n                # The line that contains the directive to include the macro\n                # may be preceded or followed by text or tags, in that case\n                # we need to make sure that any preceding or following text\n                # stays the same.\n                line_split = REGEXP.split(line, maxsplit=0)\n                preceding = line_split[0]\n                following = line_split[-1]\n                text = [preceding] + text + [following]\n                lines = lines[:loc] + text + lines[loc+1:]\n                break\n            else:\n                done = True\n        return lines\n\n    def render_table(self, arguments: List[Dict[str, Any]]) -> List[str]:\n        table = []\n        beginning = \"\"\"\n<table class=\"table\">\n  <thead>\n    <tr>\n      <th>Argument</th>\n      <th>Example</th>\n      <th>Required</th>\n      <th>Description</th>\n    </tr>\n  </thead>\n<tbody>\n\"\"\"\n        tr = \"\"\"\n<tr>\n  <td><code>{argument}</code></td>\n  <td class=\"json-api-example\"><code>{example}</code></td>\n  <td>{required}</td>\n  <td>{description}</td>\n</tr>\n\"\"\"\n\n        table.append(beginning)\n\n        md_engine = markdown.Markdown(extensions=[])\n\n        for argument in arguments:\n            description = argument['description']\n\n            oneof = ['`' + item + '`'\n                     for item in argument.get('schema', {}).get('enum', [])]\n            if oneof:\n                description += '\\nMust be one of: {}.'.format(', '.join(oneof))\n\n            default = argument.get('schema', {}).get('default')\n            if default is not None:\n                description += '\\nDefaults to `{}`.'.format(ujson.dumps(default))\n\n            # TODO: Swagger allows indicating where the argument goes\n            # (path, querystring, form data...). A column in the table should\n            # be added for this.\n            table.append(tr.format(\n                argument=argument.get('argument') or argument.get('name'),\n                # Show this as JSON to avoid changing the quoting style, which\n                # may cause problems with JSON encoding.\n                example=escape_html(ujson.dumps(argument['example'])),\n                required='Yes' if argument.get('required') else 'No',\n                description=md_engine.convert(description),\n            ))\n\n        table.append(\"</tbody>\")\n        table.append(\"</table>\")\n\n        return table\n\ndef makeExtension(*args: Any, **kwargs: str) -> MarkdownArgumentsTableGenerator:\n    return MarkdownArgumentsTableGenerator(kwargs)\n", "path": "zerver/lib/bugdown/api_arguments_table_generator.py"}]}