We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
How do we work with documentation redirects from rediraffe in the repo?
[...] to make a decision on what to do with regards to how we work with the redirects in this repo for now. If experience is gained and you start feeling confident on a practice, we try go for that more systematically in other repos long term.

I think the options on how to work with the redirects are:

1. Fully manual as now, where we figure out ourselves if we need to add a redirect
2. Mostly manual, where we can go fully manual but also suggest that `make rediraffecheckdiff` can be used to get informed on what redirects we should make.
3. Semi automated, where we suggest using `make rediraffewritediff` to update a file (not overwrite right?)
4. Mostly automated, where we have a github workflow triggered when docs change to inspect if a redirect needs to be setup and otherwise fails to let us know.
5. Almost fully automated, where we also push a commit with the relevant redirects.

If I understand this correctly, we need to consider this ourselves no matter what because the tools can't figure it out fully in all cases. That makes me think we shouldn't go for option 5. Maybe option 2-4? No matter what, I'm a big :+1: for going for something you feel like going for!

_Originally posted by @consideRatio in https://github.com/jupyterhub/jupyterhub/pull/4331#discussion_r1092331738_
            

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `docs/source/conf.py`
Content:
```
1 # Configuration file for Sphinx to build our documentation to HTML.
2 #
3 # Configuration reference: https://www.sphinx-doc.org/en/master/usage/configuration.html
4 #
5 import contextlib
6 import datetime
7 import io
8 import os
9 import subprocess
10 
11 from docutils import nodes
12 from sphinx.directives.other import SphinxDirective
13 
14 import jupyterhub
15 from jupyterhub.app import JupyterHub
16 
17 # -- Project information -----------------------------------------------------
18 # ref: https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
19 #
20 project = "JupyterHub"
21 author = "Project Jupyter Contributors"
22 copyright = f"{datetime.date.today().year}, {author}"
23 
24 
25 # -- General Sphinx configuration --------------------------------------------
26 # ref: https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
27 #
28 extensions = [
29     "sphinx.ext.autodoc",
30     "sphinx.ext.intersphinx",
31     "sphinx.ext.napoleon",
32     "autodoc_traits",
33     "sphinx_copybutton",
34     "sphinx-jsonschema",
35     "sphinxext.opengraph",
36     "sphinxext.rediraffe",
37     "jupyterhub_sphinx_theme",
38     "myst_parser",
39 ]
40 root_doc = "index"
41 source_suffix = [".md"]
42 # default_role let's use use `foo` instead of ``foo`` in rST
43 default_role = "literal"
44 
45 
46 # -- MyST configuration ------------------------------------------------------
47 # ref: https://myst-parser.readthedocs.io/en/latest/configuration.html
48 #
49 myst_heading_anchors = 2
50 
51 myst_enable_extensions = [
52     # available extensions: https://myst-parser.readthedocs.io/en/latest/syntax/optional.html
53     "attrs_inline",
54     "colon_fence",
55     "deflist",
56     "fieldlist",
57     "substitution",
58 ]
59 
60 myst_substitutions = {
61     # date example: Dev 07, 2022
62     "date": datetime.date.today().strftime("%b %d, %Y").title(),
63     "version": jupyterhub.__version__,
64 }
65 
66 
67 # -- Custom directives to generate documentation -----------------------------
68 # ref: https://myst-parser.readthedocs.io/en/latest/syntax/roles-and-directives.html
69 #
70 # We define custom directives to help us generate documentation using Python on
71 # demand when referenced from our documentation files.
72 #
73 
74 # Create a temp instance of JupyterHub for use by two separate directive classes
75 # to get the output from using the "--generate-config" and "--help-all" CLI
76 # flags respectively.
77 #
78 jupyterhub_app = JupyterHub()
79 
80 
81 class ConfigDirective(SphinxDirective):
82     """Generate the configuration file output for use in the documentation."""
83 
84     has_content = False
85     required_arguments = 0
86     optional_arguments = 0
87     final_argument_whitespace = False
88     option_spec = {}
89 
90     def run(self):
91         # The generated configuration file for this version
92         generated_config = jupyterhub_app.generate_config_file()
93         # post-process output
94         home_dir = os.environ["HOME"]
95         generated_config = generated_config.replace(home_dir, "$HOME", 1)
96         par = nodes.literal_block(text=generated_config)
97         return [par]
98 
99 
100 class HelpAllDirective(SphinxDirective):
101     """Print the output of jupyterhub help --all for use in the documentation."""
102 
103     has_content = False
104     required_arguments = 0
105     optional_arguments = 0
106     final_argument_whitespace = False
107     option_spec = {}
108 
109     def run(self):
110         # The output of the help command for this version
111         buffer = io.StringIO()
112         with contextlib.redirect_stdout(buffer):
113             jupyterhub_app.print_help("--help-all")
114         all_help = buffer.getvalue()
115         # post-process output
116         home_dir = os.environ["HOME"]
117         all_help = all_help.replace(home_dir, "$HOME", 1)
118         par = nodes.literal_block(text=all_help)
119         return [par]
120 
121 
122 def setup(app):
123     app.add_css_file("custom.css")
124     app.add_directive("jupyterhub-generate-config", ConfigDirective)
125     app.add_directive("jupyterhub-help-all", HelpAllDirective)
126 
127 
128 # -- Read The Docs -----------------------------------------------------------
129 #
130 # Since RTD runs sphinx-build directly without running "make html", we run the
131 # pre-requisite steps for "make html" from here if needed.
132 #
133 if os.environ.get("READTHEDOCS"):
134     docs = os.path.dirname(os.path.dirname(__file__))
135     subprocess.check_call(["make", "metrics", "scopes"], cwd=docs)
136 
137 
138 # -- Spell checking ----------------------------------------------------------
139 # ref: https://sphinxcontrib-spelling.readthedocs.io/en/latest/customize.html#configuration-options
140 #
141 # The "sphinxcontrib.spelling" extension is optionally enabled if its available.
142 #
143 try:
144     import sphinxcontrib.spelling  # noqa
145 except ImportError:
146     pass
147 else:
148     extensions.append("sphinxcontrib.spelling")
149 spelling_word_list_filename = "spelling_wordlist.txt"
150 
151 
152 # -- Options for HTML output -------------------------------------------------
153 # ref: https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
154 #
155 html_logo = "_static/images/logo/logo.png"
156 html_favicon = "_static/images/logo/favicon.ico"
157 html_static_path = ["_static"]
158 
159 html_theme = "jupyterhub_sphinx_theme"
160 html_theme_options = {
161     "icon_links": [
162         {
163             "name": "GitHub",
164             "url": "https://github.com/jupyterhub/jupyterhub",
165             "icon": "fa-brands fa-github",
166         },
167     ],
168     "use_edit_page_button": True,
169     "navbar_align": "left",
170 }
171 html_context = {
172     "github_user": "jupyterhub",
173     "github_repo": "jupyterhub",
174     "github_version": "main",
175     "doc_path": "docs/source",
176 }
177 
178 
179 # -- Options for linkcheck builder -------------------------------------------
180 # ref: https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-the-linkcheck-builder
181 #
182 linkcheck_ignore = [
183     r"(.*)github\.com(.*)#",  # javascript based anchors
184     r"(.*)/#%21(.*)/(.*)",  # /#!forum/jupyter - encoded anchor edge case
185     r"https://github.com/[^/]*$",  # too many github usernames / searches in changelog
186     "https://github.com/jupyterhub/jupyterhub/pull/",  # too many PRs in changelog
187     "https://github.com/jupyterhub/jupyterhub/compare/",  # too many comparisons in changelog
188     r"https?://(localhost|127.0.0.1).*",  # ignore localhost references in auto-links
189     r".*/rest-api.html#.*",  # ignore javascript-resolved internal rest-api links
190     r"https://jupyter.chameleoncloud.org",  # FIXME: ignore (presumably) short-term SSL issue
191 ]
192 linkcheck_anchors_ignore = [
193     "/#!",
194     "/#%21",
195 ]
196 
197 # -- Intersphinx -------------------------------------------------------------
198 # ref: https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#configuration
199 #
200 intersphinx_mapping = {
201     "python": ("https://docs.python.org/3/", None),
202     "tornado": ("https://www.tornadoweb.org/en/stable/", None),
203     "jupyter-server": ("https://jupyter-server.readthedocs.io/en/stable/", None),
204 }
205 
206 # -- Options for the opengraph extension -------------------------------------
207 # ref: https://github.com/wpilibsuite/sphinxext-opengraph#options
208 #
209 # ogp_site_url is set automatically by RTD
210 ogp_image = "_static/logo.png"
211 ogp_use_first_image = True
212 
213 
214 # -- Options for the rediraffe extension -------------------------------------
215 # ref: https://github.com/wpilibsuite/sphinxext-rediraffe#readme
216 #
217 # This extension helps us relocate content without breaking links. If a
218 # document is moved internally, a redirect link should be configured as below to
219 # help us not break links.
220 #
221 # The workflow for adding redirects can be as follows:
222 # 1. Change "rediraffe_branch" below to point to the commit/ branch you
223 #    want to base off the changes.
224 # 2. Option 1: run "make rediraffecheckdiff"
225 #       a. Analyze the output of this command.
226 #       b. Manually add the redirect entries to the "redirects.txt" file.
227 #    Option 2: run "make rediraffewritediff"
228 #       a. rediraffe will then automatically add the obvious redirects to redirects.txt.
229 #       b. Analyze the output of the command for broken links.
230 #       c. Check the "redirects.txt" file for any files that were moved/ renamed but are not listed.
231 #       d. Manually add the redirects that have been mised by the automatic builder to "redirects.txt".
232 #    Option 3: Do not use the commands above and, instead, do everything manually - by taking
233 #    note of the files you have moved or renamed and adding them to the "redirects.txt" file.
234 #
235 # If you are basing changes off another branch/ commit, always change back
236 # rediraffe_branch to main before pushing your changes upstream.
237 #
238 rediraffe_branch = "main"
239 rediraffe_redirects = "redirects.txt"
240 # rediraffe_redirects = {
241 # "old-file": "new-folder/new-file-name",
242 # }
243
```
--- 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()

```

diff --git a/docs/source/conf.py b/docs/source/conf.py
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -235,8 +235,12 @@
 # If you are basing changes off another branch/ commit, always change back
 # rediraffe_branch to main before pushing your changes upstream.
 #
-rediraffe_branch = "main"
+rediraffe_branch = os.environ.get("REDIRAFFE_BRANCH", "main")
 rediraffe_redirects = "redirects.txt"
+
+# allow 80% match for autogenerated redirects
+rediraffe_auto_redirect_perc = 80
+
 # rediraffe_redirects = {
 # "old-file": "new-folder/new-file-name",
 # }

{"golden_diff": "diff --git a/docs/source/conf.py b/docs/source/conf.py\n--- a/docs/source/conf.py\n+++ b/docs/source/conf.py\n@@ -235,8 +235,12 @@\n # If you are basing changes off another branch/ commit, always change back\n # rediraffe_branch to main before pushing your changes upstream.\n #\n-rediraffe_branch = \"main\"\n+rediraffe_branch = os.environ.get(\"REDIRAFFE_BRANCH\", \"main\")\n rediraffe_redirects = \"redirects.txt\"\n+\n+# allow 80% match for autogenerated redirects\n+rediraffe_auto_redirect_perc = 80\n+\n # rediraffe_redirects = {\n # \"old-file\": \"new-folder/new-file-name\",\n # }\n", "issue": "How do we work with documentation redirects from rediraffe in the repo?\n[...] to make a decision on what to do with regards to how we work with the redirects in this repo for now. If experience is gained and you start feeling confident on a practice, we try go for that more systematically in other repos long term.\r\n\r\nI think the options on how to work with the redirects are:\r\n\r\n1. Fully manual as now, where we figure out ourselves if we need to add a redirect\r\n2. Mostly manual, where we can go fully manual but also suggest that `make rediraffecheckdiff` can be used to get informed on what redirects we should make.\r\n3. Semi automated, where we suggest using `make rediraffewritediff` to update a file (not overwrite right?)\r\n4. Mostly automated, where we have a github workflow triggered when docs change to inspect if a redirect needs to be setup and otherwise fails to let us know.\r\n5. Almost fully automated, where we also push a commit with the relevant redirects.\r\n\r\nIf I understand this correctly, we need to consider this ourselves no matter what because the tools can't figure it out fully in all cases. That makes me think we shouldn't go for option 5. Maybe option 2-4? No matter what, I'm a big :+1: for going for something you feel like going for!\r\n\r\n_Originally posted by @consideRatio in https://github.com/jupyterhub/jupyterhub/pull/4331#discussion_r1092331738_\r\n            \n", "before_files": [{"content": "# Configuration file for Sphinx to build our documentation to HTML.\n#\n# Configuration reference: https://www.sphinx-doc.org/en/master/usage/configuration.html\n#\nimport contextlib\nimport datetime\nimport io\nimport os\nimport subprocess\n\nfrom docutils import nodes\nfrom sphinx.directives.other import SphinxDirective\n\nimport jupyterhub\nfrom jupyterhub.app import JupyterHub\n\n# -- Project information -----------------------------------------------------\n# ref: https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information\n#\nproject = \"JupyterHub\"\nauthor = \"Project Jupyter Contributors\"\ncopyright = f\"{datetime.date.today().year}, {author}\"\n\n\n# -- General Sphinx configuration --------------------------------------------\n# ref: https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration\n#\nextensions = [\n    \"sphinx.ext.autodoc\",\n    \"sphinx.ext.intersphinx\",\n    \"sphinx.ext.napoleon\",\n    \"autodoc_traits\",\n    \"sphinx_copybutton\",\n    \"sphinx-jsonschema\",\n    \"sphinxext.opengraph\",\n    \"sphinxext.rediraffe\",\n    \"jupyterhub_sphinx_theme\",\n    \"myst_parser\",\n]\nroot_doc = \"index\"\nsource_suffix = [\".md\"]\n# default_role let's use use `foo` instead of ``foo`` in rST\ndefault_role = \"literal\"\n\n\n# -- MyST configuration ------------------------------------------------------\n# ref: https://myst-parser.readthedocs.io/en/latest/configuration.html\n#\nmyst_heading_anchors = 2\n\nmyst_enable_extensions = [\n    # available extensions: https://myst-parser.readthedocs.io/en/latest/syntax/optional.html\n    \"attrs_inline\",\n    \"colon_fence\",\n    \"deflist\",\n    \"fieldlist\",\n    \"substitution\",\n]\n\nmyst_substitutions = {\n    # date example: Dev 07, 2022\n    \"date\": datetime.date.today().strftime(\"%b %d, %Y\").title(),\n    \"version\": jupyterhub.__version__,\n}\n\n\n# -- Custom directives to generate documentation -----------------------------\n# ref: https://myst-parser.readthedocs.io/en/latest/syntax/roles-and-directives.html\n#\n# We define custom directives to help us generate documentation using Python on\n# demand when referenced from our documentation files.\n#\n\n# Create a temp instance of JupyterHub for use by two separate directive classes\n# to get the output from using the \"--generate-config\" and \"--help-all\" CLI\n# flags respectively.\n#\njupyterhub_app = JupyterHub()\n\n\nclass ConfigDirective(SphinxDirective):\n    \"\"\"Generate the configuration file output for use in the documentation.\"\"\"\n\n    has_content = False\n    required_arguments = 0\n    optional_arguments = 0\n    final_argument_whitespace = False\n    option_spec = {}\n\n    def run(self):\n        # The generated configuration file for this version\n        generated_config = jupyterhub_app.generate_config_file()\n        # post-process output\n        home_dir = os.environ[\"HOME\"]\n        generated_config = generated_config.replace(home_dir, \"$HOME\", 1)\n        par = nodes.literal_block(text=generated_config)\n        return [par]\n\n\nclass HelpAllDirective(SphinxDirective):\n    \"\"\"Print the output of jupyterhub help --all for use in the documentation.\"\"\"\n\n    has_content = False\n    required_arguments = 0\n    optional_arguments = 0\n    final_argument_whitespace = False\n    option_spec = {}\n\n    def run(self):\n        # The output of the help command for this version\n        buffer = io.StringIO()\n        with contextlib.redirect_stdout(buffer):\n            jupyterhub_app.print_help(\"--help-all\")\n        all_help = buffer.getvalue()\n        # post-process output\n        home_dir = os.environ[\"HOME\"]\n        all_help = all_help.replace(home_dir, \"$HOME\", 1)\n        par = nodes.literal_block(text=all_help)\n        return [par]\n\n\ndef setup(app):\n    app.add_css_file(\"custom.css\")\n    app.add_directive(\"jupyterhub-generate-config\", ConfigDirective)\n    app.add_directive(\"jupyterhub-help-all\", HelpAllDirective)\n\n\n# -- Read The Docs -----------------------------------------------------------\n#\n# Since RTD runs sphinx-build directly without running \"make html\", we run the\n# pre-requisite steps for \"make html\" from here if needed.\n#\nif os.environ.get(\"READTHEDOCS\"):\n    docs = os.path.dirname(os.path.dirname(__file__))\n    subprocess.check_call([\"make\", \"metrics\", \"scopes\"], cwd=docs)\n\n\n# -- Spell checking ----------------------------------------------------------\n# ref: https://sphinxcontrib-spelling.readthedocs.io/en/latest/customize.html#configuration-options\n#\n# The \"sphinxcontrib.spelling\" extension is optionally enabled if its available.\n#\ntry:\n    import sphinxcontrib.spelling  # noqa\nexcept ImportError:\n    pass\nelse:\n    extensions.append(\"sphinxcontrib.spelling\")\nspelling_word_list_filename = \"spelling_wordlist.txt\"\n\n\n# -- Options for HTML output -------------------------------------------------\n# ref: https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output\n#\nhtml_logo = \"_static/images/logo/logo.png\"\nhtml_favicon = \"_static/images/logo/favicon.ico\"\nhtml_static_path = [\"_static\"]\n\nhtml_theme = \"jupyterhub_sphinx_theme\"\nhtml_theme_options = {\n    \"icon_links\": [\n        {\n            \"name\": \"GitHub\",\n            \"url\": \"https://github.com/jupyterhub/jupyterhub\",\n            \"icon\": \"fa-brands fa-github\",\n        },\n    ],\n    \"use_edit_page_button\": True,\n    \"navbar_align\": \"left\",\n}\nhtml_context = {\n    \"github_user\": \"jupyterhub\",\n    \"github_repo\": \"jupyterhub\",\n    \"github_version\": \"main\",\n    \"doc_path\": \"docs/source\",\n}\n\n\n# -- Options for linkcheck builder -------------------------------------------\n# ref: https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-the-linkcheck-builder\n#\nlinkcheck_ignore = [\n    r\"(.*)github\\.com(.*)#\",  # javascript based anchors\n    r\"(.*)/#%21(.*)/(.*)\",  # /#!forum/jupyter - encoded anchor edge case\n    r\"https://github.com/[^/]*$\",  # too many github usernames / searches in changelog\n    \"https://github.com/jupyterhub/jupyterhub/pull/\",  # too many PRs in changelog\n    \"https://github.com/jupyterhub/jupyterhub/compare/\",  # too many comparisons in changelog\n    r\"https?://(localhost|127.0.0.1).*\",  # ignore localhost references in auto-links\n    r\".*/rest-api.html#.*\",  # ignore javascript-resolved internal rest-api links\n    r\"https://jupyter.chameleoncloud.org\",  # FIXME: ignore (presumably) short-term SSL issue\n]\nlinkcheck_anchors_ignore = [\n    \"/#!\",\n    \"/#%21\",\n]\n\n# -- Intersphinx -------------------------------------------------------------\n# ref: https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#configuration\n#\nintersphinx_mapping = {\n    \"python\": (\"https://docs.python.org/3/\", None),\n    \"tornado\": (\"https://www.tornadoweb.org/en/stable/\", None),\n    \"jupyter-server\": (\"https://jupyter-server.readthedocs.io/en/stable/\", None),\n}\n\n# -- Options for the opengraph extension -------------------------------------\n# ref: https://github.com/wpilibsuite/sphinxext-opengraph#options\n#\n# ogp_site_url is set automatically by RTD\nogp_image = \"_static/logo.png\"\nogp_use_first_image = True\n\n\n# -- Options for the rediraffe extension -------------------------------------\n# ref: https://github.com/wpilibsuite/sphinxext-rediraffe#readme\n#\n# This extension helps us relocate content without breaking links. If a\n# document is moved internally, a redirect link should be configured as below to\n# help us not break links.\n#\n# The workflow for adding redirects can be as follows:\n# 1. Change \"rediraffe_branch\" below to point to the commit/ branch you\n#    want to base off the changes.\n# 2. Option 1: run \"make rediraffecheckdiff\"\n#       a. Analyze the output of this command.\n#       b. Manually add the redirect entries to the \"redirects.txt\" file.\n#    Option 2: run \"make rediraffewritediff\"\n#       a. rediraffe will then automatically add the obvious redirects to redirects.txt.\n#       b. Analyze the output of the command for broken links.\n#       c. Check the \"redirects.txt\" file for any files that were moved/ renamed but are not listed.\n#       d. Manually add the redirects that have been mised by the automatic builder to \"redirects.txt\".\n#    Option 3: Do not use the commands above and, instead, do everything manually - by taking\n#    note of the files you have moved or renamed and adding them to the \"redirects.txt\" file.\n#\n# If you are basing changes off another branch/ commit, always change back\n# rediraffe_branch to main before pushing your changes upstream.\n#\nrediraffe_branch = \"main\"\nrediraffe_redirects = \"redirects.txt\"\n# rediraffe_redirects = {\n# \"old-file\": \"new-folder/new-file-name\",\n# }\n", "path": "docs/source/conf.py"}], "after_files": [{"content": "# Configuration file for Sphinx to build our documentation to HTML.\n#\n# Configuration reference: https://www.sphinx-doc.org/en/master/usage/configuration.html\n#\nimport contextlib\nimport datetime\nimport io\nimport os\nimport subprocess\n\nfrom docutils import nodes\nfrom sphinx.directives.other import SphinxDirective\n\nimport jupyterhub\nfrom jupyterhub.app import JupyterHub\n\n# -- Project information -----------------------------------------------------\n# ref: https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information\n#\nproject = \"JupyterHub\"\nauthor = \"Project Jupyter Contributors\"\ncopyright = f\"{datetime.date.today().year}, {author}\"\n\n\n# -- General Sphinx configuration --------------------------------------------\n# ref: https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration\n#\nextensions = [\n    \"sphinx.ext.autodoc\",\n    \"sphinx.ext.intersphinx\",\n    \"sphinx.ext.napoleon\",\n    \"autodoc_traits\",\n    \"sphinx_copybutton\",\n    \"sphinx-jsonschema\",\n    \"sphinxext.opengraph\",\n    \"sphinxext.rediraffe\",\n    \"jupyterhub_sphinx_theme\",\n    \"myst_parser\",\n]\nroot_doc = \"index\"\nsource_suffix = [\".md\"]\n# default_role let's use use `foo` instead of ``foo`` in rST\ndefault_role = \"literal\"\n\n\n# -- MyST configuration ------------------------------------------------------\n# ref: https://myst-parser.readthedocs.io/en/latest/configuration.html\n#\nmyst_heading_anchors = 2\n\nmyst_enable_extensions = [\n    # available extensions: https://myst-parser.readthedocs.io/en/latest/syntax/optional.html\n    \"attrs_inline\",\n    \"colon_fence\",\n    \"deflist\",\n    \"fieldlist\",\n    \"substitution\",\n]\n\nmyst_substitutions = {\n    # date example: Dev 07, 2022\n    \"date\": datetime.date.today().strftime(\"%b %d, %Y\").title(),\n    \"version\": jupyterhub.__version__,\n}\n\n\n# -- Custom directives to generate documentation -----------------------------\n# ref: https://myst-parser.readthedocs.io/en/latest/syntax/roles-and-directives.html\n#\n# We define custom directives to help us generate documentation using Python on\n# demand when referenced from our documentation files.\n#\n\n# Create a temp instance of JupyterHub for use by two separate directive classes\n# to get the output from using the \"--generate-config\" and \"--help-all\" CLI\n# flags respectively.\n#\njupyterhub_app = JupyterHub()\n\n\nclass ConfigDirective(SphinxDirective):\n    \"\"\"Generate the configuration file output for use in the documentation.\"\"\"\n\n    has_content = False\n    required_arguments = 0\n    optional_arguments = 0\n    final_argument_whitespace = False\n    option_spec = {}\n\n    def run(self):\n        # The generated configuration file for this version\n        generated_config = jupyterhub_app.generate_config_file()\n        # post-process output\n        home_dir = os.environ[\"HOME\"]\n        generated_config = generated_config.replace(home_dir, \"$HOME\", 1)\n        par = nodes.literal_block(text=generated_config)\n        return [par]\n\n\nclass HelpAllDirective(SphinxDirective):\n    \"\"\"Print the output of jupyterhub help --all for use in the documentation.\"\"\"\n\n    has_content = False\n    required_arguments = 0\n    optional_arguments = 0\n    final_argument_whitespace = False\n    option_spec = {}\n\n    def run(self):\n        # The output of the help command for this version\n        buffer = io.StringIO()\n        with contextlib.redirect_stdout(buffer):\n            jupyterhub_app.print_help(\"--help-all\")\n        all_help = buffer.getvalue()\n        # post-process output\n        home_dir = os.environ[\"HOME\"]\n        all_help = all_help.replace(home_dir, \"$HOME\", 1)\n        par = nodes.literal_block(text=all_help)\n        return [par]\n\n\ndef setup(app):\n    app.add_css_file(\"custom.css\")\n    app.add_directive(\"jupyterhub-generate-config\", ConfigDirective)\n    app.add_directive(\"jupyterhub-help-all\", HelpAllDirective)\n\n\n# -- Read The Docs -----------------------------------------------------------\n#\n# Since RTD runs sphinx-build directly without running \"make html\", we run the\n# pre-requisite steps for \"make html\" from here if needed.\n#\nif os.environ.get(\"READTHEDOCS\"):\n    docs = os.path.dirname(os.path.dirname(__file__))\n    subprocess.check_call([\"make\", \"metrics\", \"scopes\"], cwd=docs)\n\n\n# -- Spell checking ----------------------------------------------------------\n# ref: https://sphinxcontrib-spelling.readthedocs.io/en/latest/customize.html#configuration-options\n#\n# The \"sphinxcontrib.spelling\" extension is optionally enabled if its available.\n#\ntry:\n    import sphinxcontrib.spelling  # noqa\nexcept ImportError:\n    pass\nelse:\n    extensions.append(\"sphinxcontrib.spelling\")\nspelling_word_list_filename = \"spelling_wordlist.txt\"\n\n\n# -- Options for HTML output -------------------------------------------------\n# ref: https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output\n#\nhtml_logo = \"_static/images/logo/logo.png\"\nhtml_favicon = \"_static/images/logo/favicon.ico\"\nhtml_static_path = [\"_static\"]\n\nhtml_theme = \"jupyterhub_sphinx_theme\"\nhtml_theme_options = {\n    \"icon_links\": [\n        {\n            \"name\": \"GitHub\",\n            \"url\": \"https://github.com/jupyterhub/jupyterhub\",\n            \"icon\": \"fa-brands fa-github\",\n        },\n    ],\n    \"use_edit_page_button\": True,\n    \"navbar_align\": \"left\",\n}\nhtml_context = {\n    \"github_user\": \"jupyterhub\",\n    \"github_repo\": \"jupyterhub\",\n    \"github_version\": \"main\",\n    \"doc_path\": \"docs/source\",\n}\n\n\n# -- Options for linkcheck builder -------------------------------------------\n# ref: https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-the-linkcheck-builder\n#\nlinkcheck_ignore = [\n    r\"(.*)github\\.com(.*)#\",  # javascript based anchors\n    r\"(.*)/#%21(.*)/(.*)\",  # /#!forum/jupyter - encoded anchor edge case\n    r\"https://github.com/[^/]*$\",  # too many github usernames / searches in changelog\n    \"https://github.com/jupyterhub/jupyterhub/pull/\",  # too many PRs in changelog\n    \"https://github.com/jupyterhub/jupyterhub/compare/\",  # too many comparisons in changelog\n    r\"https?://(localhost|127.0.0.1).*\",  # ignore localhost references in auto-links\n    r\".*/rest-api.html#.*\",  # ignore javascript-resolved internal rest-api links\n    r\"https://jupyter.chameleoncloud.org\",  # FIXME: ignore (presumably) short-term SSL issue\n]\nlinkcheck_anchors_ignore = [\n    \"/#!\",\n    \"/#%21\",\n]\n\n# -- Intersphinx -------------------------------------------------------------\n# ref: https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#configuration\n#\nintersphinx_mapping = {\n    \"python\": (\"https://docs.python.org/3/\", None),\n    \"tornado\": (\"https://www.tornadoweb.org/en/stable/\", None),\n    \"jupyter-server\": (\"https://jupyter-server.readthedocs.io/en/stable/\", None),\n}\n\n# -- Options for the opengraph extension -------------------------------------\n# ref: https://github.com/wpilibsuite/sphinxext-opengraph#options\n#\n# ogp_site_url is set automatically by RTD\nogp_image = \"_static/logo.png\"\nogp_use_first_image = True\n\n\n# -- Options for the rediraffe extension -------------------------------------\n# ref: https://github.com/wpilibsuite/sphinxext-rediraffe#readme\n#\n# This extension helps us relocate content without breaking links. If a\n# document is moved internally, a redirect link should be configured as below to\n# help us not break links.\n#\n# The workflow for adding redirects can be as follows:\n# 1. Change \"rediraffe_branch\" below to point to the commit/ branch you\n#    want to base off the changes.\n# 2. Option 1: run \"make rediraffecheckdiff\"\n#       a. Analyze the output of this command.\n#       b. Manually add the redirect entries to the \"redirects.txt\" file.\n#    Option 2: run \"make rediraffewritediff\"\n#       a. rediraffe will then automatically add the obvious redirects to redirects.txt.\n#       b. Analyze the output of the command for broken links.\n#       c. Check the \"redirects.txt\" file for any files that were moved/ renamed but are not listed.\n#       d. Manually add the redirects that have been mised by the automatic builder to \"redirects.txt\".\n#    Option 3: Do not use the commands above and, instead, do everything manually - by taking\n#    note of the files you have moved or renamed and adding them to the \"redirects.txt\" file.\n#\n# If you are basing changes off another branch/ commit, always change back\n# rediraffe_branch to main before pushing your changes upstream.\n#\nrediraffe_branch = os.environ.get(\"REDIRAFFE_BRANCH\", \"main\")\nrediraffe_redirects = \"redirects.txt\"\n\n# allow 80% match for autogenerated redirects\nrediraffe_auto_redirect_perc = 80\n\n# rediraffe_redirects = {\n# \"old-file\": \"new-folder/new-file-name\",\n# }\n", "path": "docs/source/conf.py"}]}