We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add "Edit on Github" links to the pages
Currently there's a link at the bottom to the RST in the generated site. It would be valuable to have the link to the github sources to facilitate opening a pull request. 

There are ways to add this to the theme or side bar. There may be plugins to add this 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: `conf.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 #
3 # rosindex documentation build configuration file, created by
4 # sphinx-quickstart on Tue Oct  2 16:34:57 2018.
5 #
6 # This file is execfile()d with the current directory set to its
7 # containing dir.
8 #
9 # Note that not all possible configuration values are present in this
10 # autogenerated file.
11 #
12 # All configuration values have a default; values that are commented out
13 # serve to show the default.
14 
15 # If extensions (or modules to document with autodoc) are in another directory,
16 # add these directories to sys.path here. If the directory is relative to the
17 # documentation root, use os.path.abspath to make it absolute, like shown here.
18 #
19 import sys, os
20 import itertools
21 from docutils.parsers.rst import Directive
22 
23 sys.path.append(os.path.abspath('./sphinx-multiversion'))
24 
25 
26 # The suffix(es) of source filenames.
27 # You can specify multiple suffix as a list of string:
28 #
29 # The master toctree document.
30 master_doc = 'index'
31 
32 # The default role
33 default_role = 'any'
34 
35 # The set of warnings to suppress.
36 suppress_warnings = ['image.nonlocal_uri']
37 
38 # General information about the project.
39 project = u'ros2 documentation'
40 copyright = u'2018-2021, Open Robotics'
41 author = u'Open Robotics'
42 
43 # The version info for the project you're documenting, acts as replacement for
44 # |version| and |release|, also used in various other places throughout the
45 # built documents.
46 #
47 # The short X.Y version.
48 version = u''
49 # The full version, including alpha/beta/rc tags.
50 release = u''
51 
52 # Define the default role to use for links
53 default_role = 'any'
54 
55 # The language for content autogenerated by Sphinx. Refer to documentation
56 # for a list of supported languages.
57 #
58 # This is also used if you do content translation via gettext catalogs.
59 # Usually you set "language" from the command line for these cases.
60 language = None
61 
62 # List of patterns, relative to source directory, that match files and
63 # directories to ignore when looking for source files.
64 # This patterns also effect to html_static_path and html_extra_path
65 exclude_patterns = ['**/_*.rst']
66 
67 # The name of the Pygments (syntax highlighting) style to use.
68 pygments_style = 'sphinx'
69 
70 # Add any Sphinx extension module names here, as strings. They can be
71 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
72 extensions = ['sphinx.ext.intersphinx', 'sphinx_tabs.tabs', 'sphinx_multiversion']
73 
74 # Intersphinx mapping
75 
76 intersphinx_mapping = {
77     'catkin_pkg':    ('http://docs.ros.org/en/independent/api/catkin_pkg/html', None),
78     'jenkins_tools': ('http://docs.ros.org/en/independent/api/jenkins_tools/html', None),
79     'rosdep':        ('http://docs.ros.org/en/independent/api/rosdep/html', None),
80     'rosdistro':     ('http://docs.ros.org/en/independent/api/rosdistro/html', None),
81     'rosinstall':    ('http://docs.ros.org/en/independent/api/rosinstall/html', None),
82     'rospkg':        ('http://docs.ros.org/en/independent/api/rospkg/html', None),
83     'vcstools':      ('http://docs.ros.org/en/independent/api/vcstools/html', None)
84 }
85 
86 # -- Options for HTML output ----------------------------------------------
87 
88 # The theme to use for HTML and HTML Help pages.  See the documentation for
89 # a list of builtin themes.
90 #
91 #html_theme = 'alabaster'
92 
93 templates_path = [
94     "source/_templates",
95 ]
96 
97 html_sidebars = {
98     '**': ['navigation.html', 'versioning.html'],
99 }
100 
101 # smv_tag_whitelist = None
102 
103 smv_branch_whitelist = r'^(rolling|foxy|eloquent|dashing)$'
104 
105 
106 smv_released_pattern = r'^refs/(heads|remotes/[^/]+)/(foxy|eloquent|dashing).*$'
107 smv_remote_whitelist = r'^(origin)$'
108 smv_latest_version = 'foxy'
109 
110 
111 
112 html_favicon = 'favicon.ico'
113 
114 # Add any paths that contain custom static files (such as style sheets) here,
115 # relative to this directory. They are copied after the builtin static files,
116 # so a file named "default.css" will overwrite the builtin "default.css".
117 # html_static_path = ['_static']
118 
119 # Drop any source link suffix
120 html_sourcelink_suffix = ''
121 
122 # -- Options for HTMLHelp output ------------------------------------------
123 
124 # Output file base name for HTML help builder.
125 htmlhelp_basename = 'ros2_docsdoc'
126 
127 html_baseurl = 'https://docs.ros.org/en'
128 
129 class RedirectFrom(Directive):
130 
131     has_content = True
132     template_name = 'layout.html'
133     redirections = {}
134 
135     @classmethod
136     def register(cls, app):
137         app.connect('html-collect-pages', cls.generate)
138         app.add_directive('redirect-from', cls)
139         return app
140 
141     @classmethod
142     def generate(cls, app):
143         from sphinx.builders.html import StandaloneHTMLBuilder
144         if not isinstance(app.builder, StandaloneHTMLBuilder):
145             return
146 
147         redirect_html_fragment = """
148             <link rel="canonical" href="{base_url}/{url}" />
149             <meta http-equiv="refresh" content="0; url={url}" />
150             <script>
151                 window.location.href = '{url}';
152             </script>
153         """
154         redirections = {
155             os.path.splitext(os.path.relpath(
156                 document_path, app.srcdir
157             ))[0]: redirect_urls
158             for document_path, redirect_urls in cls.redirections.items()
159         }
160         redirection_conflict = next((
161             (canon_1, canon_2, redirs_1.intersection(redirs_2))
162             for (canon_1, redirs_1), (canon_2, redirs_2)
163             in itertools.combinations(redirections.items(), 2)
164             if redirs_1.intersection(redirs_2)
165         ), None)
166         if redirection_conflict:
167             canonical_url_1, canonical_url_2 = redirection_conflict[:2]
168             conflicting_redirect_urls = redirection_conflict[-1]
169             raise RuntimeError(
170                 'Documents {} and {} define conflicting redirects: {}'.format(
171                     canonical_url_1, canonical_url_2, conflicting_redirect_urls
172                 )
173             )
174         all_canonical_urls = set(redirections.keys())
175         all_redirect_urls = {
176             redirect_url
177             for redirect_urls in redirections.values()
178             for redirect_url in redirect_urls
179         }
180         conflicting_urls = all_canonical_urls.intersection(all_redirect_urls)
181         if conflicting_urls:
182             raise RuntimeError(
183                 'Some redirects conflict with existing documents: {}'.format(
184                     conflicting_urls
185                 )
186             )
187 
188         for canonical_url, redirect_urls in redirections.items():
189             for redirect_url in redirect_urls:
190                 context = {
191                     'canonical_url': os.path.relpath(
192                         canonical_url, redirect_url
193                     ),
194                     'title': os.path.basename(redirect_url),
195                     'metatags': redirect_html_fragment.format(
196                         base_url=app.config.html_baseurl,
197                         url=app.builder.get_relative_uri(
198                             redirect_url, canonical_url
199                         )
200                     )
201                 }
202                 yield (redirect_url, context, cls.template_name)
203 
204     def run(self):
205         document_path = self.state.document.current_source
206         if document_path not in RedirectFrom.redirections:
207             RedirectFrom.redirections[document_path] = set()
208         RedirectFrom.redirections[document_path].update(self.content)
209         return []
210 
211 
212 def make_router(origin, destination):
213     def _missing_reference(app, env, node, contnode):
214         from docutils import nodes
215         from docutils.utils import relative_path
216         from sphinx.util import docname_join
217 
218         doctarget = docname_join(node['refdoc'], node['reftarget'])
219         if doctarget.startswith(origin):
220             routed_doctarget = doctarget.replace(origin, destination)
221             if routed_doctarget in env.all_docs:
222                 newnode = nodes.reference(
223                     '', contnode.astext(), internal=True
224                 )
225                 newnode['refuri'] = app.builder.get_relative_uri(
226                     node['refdoc'], routed_doctarget
227                 )
228                 return newnode
229     return _missing_reference
230 
231 def smv_rewrite_baseurl(app, config):
232     # When using Sphinx multiversion, there is no way at initial configuration time
233     # to determine the distribution we are currently targeting (conf.py is read before
234     # external defines are setup, and environment variables aren't passed through to
235     # conf.py).  Instead, hook into the 'config-inited' event which is late enough
236     # to rewrite the html_baseurl with the current version.
237     if app.config.smv_current_version != '':
238         app.config.html_baseurl = app.config.html_baseurl + '/' + app.config.smv_current_version
239 
240 def setup(app):
241     app.connect('config-inited', smv_rewrite_baseurl)
242     RedirectFrom.register(app)
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/conf.py b/conf.py
--- a/conf.py
+++ b/conf.py
@@ -69,7 +69,7 @@
 
 # Add any Sphinx extension module names here, as strings. They can be
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
-extensions = ['sphinx.ext.intersphinx', 'sphinx_tabs.tabs', 'sphinx_multiversion']
+extensions = ['sphinx.ext.intersphinx', 'sphinx_tabs.tabs', 'sphinx_multiversion', 'sphinxcontrib.srclinks']
 
 # Intersphinx mapping
 
@@ -90,12 +90,16 @@
 #
 #html_theme = 'alabaster'
 
+srclink_project = 'https://github.com/ros2/ros2_documentation'
+srclink_src_path = 'source/'
+srclink_branch = 'rolling'
+
 templates_path = [
     "source/_templates",
 ]
 
 html_sidebars = {
-    '**': ['navigation.html', 'versioning.html'],
+    '**': ['navigation.html', 'srclinks.html', 'versioning.html'],
 }
 
 # smv_tag_whitelist = None
@@ -237,6 +241,11 @@
     if app.config.smv_current_version != '':
         app.config.html_baseurl = app.config.html_baseurl + '/' + app.config.smv_current_version
 
+def srclink_rewrite_branch(app, config):
+    if app.config.smv_current_version != '':
+        app.config.srclink_branch = app.config.smv_current_version
+
 def setup(app):
     app.connect('config-inited', smv_rewrite_baseurl)
+    app.connect('config-inited', srclink_rewrite_branch)
     RedirectFrom.register(app)

{"golden_diff": "diff --git a/conf.py b/conf.py\n--- a/conf.py\n+++ b/conf.py\n@@ -69,7 +69,7 @@\n \n # Add any Sphinx extension module names here, as strings. They can be\n # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n-extensions = ['sphinx.ext.intersphinx', 'sphinx_tabs.tabs', 'sphinx_multiversion']\n+extensions = ['sphinx.ext.intersphinx', 'sphinx_tabs.tabs', 'sphinx_multiversion', 'sphinxcontrib.srclinks']\n \n # Intersphinx mapping\n \n@@ -90,12 +90,16 @@\n #\n #html_theme = 'alabaster'\n \n+srclink_project = 'https://github.com/ros2/ros2_documentation'\n+srclink_src_path = 'source/'\n+srclink_branch = 'rolling'\n+\n templates_path = [\n     \"source/_templates\",\n ]\n \n html_sidebars = {\n-    '**': ['navigation.html', 'versioning.html'],\n+    '**': ['navigation.html', 'srclinks.html', 'versioning.html'],\n }\n \n # smv_tag_whitelist = None\n@@ -237,6 +241,11 @@\n     if app.config.smv_current_version != '':\n         app.config.html_baseurl = app.config.html_baseurl + '/' + app.config.smv_current_version\n \n+def srclink_rewrite_branch(app, config):\n+    if app.config.smv_current_version != '':\n+        app.config.srclink_branch = app.config.smv_current_version\n+\n def setup(app):\n     app.connect('config-inited', smv_rewrite_baseurl)\n+    app.connect('config-inited', srclink_rewrite_branch)\n     RedirectFrom.register(app)\n", "issue": "Add \"Edit on Github\" links to the pages\nCurrently there's a link at the bottom to the RST in the generated site. It would be valuable to have the link to the github sources to facilitate opening a pull request. \r\n\r\nThere are ways to add this to the theme or side bar. There may be plugins to add this too. \r\n\r\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n#\n# rosindex documentation build configuration file, created by\n# sphinx-quickstart on Tue Oct  2 16:34:57 2018.\n#\n# This file is execfile()d with the current directory set to its\n# containing dir.\n#\n# Note that not all possible configuration values are present in this\n# autogenerated file.\n#\n# All configuration values have a default; values that are commented out\n# serve to show the default.\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\n#\nimport sys, os\nimport itertools\nfrom docutils.parsers.rst import Directive\n\nsys.path.append(os.path.abspath('./sphinx-multiversion'))\n\n\n# The suffix(es) of source filenames.\n# You can specify multiple suffix as a list of string:\n#\n# The master toctree document.\nmaster_doc = 'index'\n\n# The default role\ndefault_role = 'any'\n\n# The set of warnings to suppress.\nsuppress_warnings = ['image.nonlocal_uri']\n\n# General information about the project.\nproject = u'ros2 documentation'\ncopyright = u'2018-2021, Open Robotics'\nauthor = u'Open Robotics'\n\n# The version info for the project you're documenting, acts as replacement for\n# |version| and |release|, also used in various other places throughout the\n# built documents.\n#\n# The short X.Y version.\nversion = u''\n# The full version, including alpha/beta/rc tags.\nrelease = u''\n\n# Define the default role to use for links\ndefault_role = 'any'\n\n# The language for content autogenerated by Sphinx. Refer to documentation\n# for a list of supported languages.\n#\n# This is also used if you do content translation via gettext catalogs.\n# Usually you set \"language\" from the command line for these cases.\nlanguage = None\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\n# This patterns also effect to html_static_path and html_extra_path\nexclude_patterns = ['**/_*.rst']\n\n# The name of the Pygments (syntax highlighting) style to use.\npygments_style = 'sphinx'\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\nextensions = ['sphinx.ext.intersphinx', 'sphinx_tabs.tabs', 'sphinx_multiversion']\n\n# Intersphinx mapping\n\nintersphinx_mapping = {\n    'catkin_pkg':    ('http://docs.ros.org/en/independent/api/catkin_pkg/html', None),\n    'jenkins_tools': ('http://docs.ros.org/en/independent/api/jenkins_tools/html', None),\n    'rosdep':        ('http://docs.ros.org/en/independent/api/rosdep/html', None),\n    'rosdistro':     ('http://docs.ros.org/en/independent/api/rosdistro/html', None),\n    'rosinstall':    ('http://docs.ros.org/en/independent/api/rosinstall/html', None),\n    'rospkg':        ('http://docs.ros.org/en/independent/api/rospkg/html', None),\n    'vcstools':      ('http://docs.ros.org/en/independent/api/vcstools/html', None)\n}\n\n# -- Options for HTML output ----------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\n#\n#html_theme = 'alabaster'\n\ntemplates_path = [\n    \"source/_templates\",\n]\n\nhtml_sidebars = {\n    '**': ['navigation.html', 'versioning.html'],\n}\n\n# smv_tag_whitelist = None\n\nsmv_branch_whitelist = r'^(rolling|foxy|eloquent|dashing)$'\n\n\nsmv_released_pattern = r'^refs/(heads|remotes/[^/]+)/(foxy|eloquent|dashing).*$'\nsmv_remote_whitelist = r'^(origin)$'\nsmv_latest_version = 'foxy'\n\n\n\nhtml_favicon = 'favicon.ico'\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\n# html_static_path = ['_static']\n\n# Drop any source link suffix\nhtml_sourcelink_suffix = ''\n\n# -- Options for HTMLHelp output ------------------------------------------\n\n# Output file base name for HTML help builder.\nhtmlhelp_basename = 'ros2_docsdoc'\n\nhtml_baseurl = 'https://docs.ros.org/en'\n\nclass RedirectFrom(Directive):\n\n    has_content = True\n    template_name = 'layout.html'\n    redirections = {}\n\n    @classmethod\n    def register(cls, app):\n        app.connect('html-collect-pages', cls.generate)\n        app.add_directive('redirect-from', cls)\n        return app\n\n    @classmethod\n    def generate(cls, app):\n        from sphinx.builders.html import StandaloneHTMLBuilder\n        if not isinstance(app.builder, StandaloneHTMLBuilder):\n            return\n\n        redirect_html_fragment = \"\"\"\n            <link rel=\"canonical\" href=\"{base_url}/{url}\" />\n            <meta http-equiv=\"refresh\" content=\"0; url={url}\" />\n            <script>\n                window.location.href = '{url}';\n            </script>\n        \"\"\"\n        redirections = {\n            os.path.splitext(os.path.relpath(\n                document_path, app.srcdir\n            ))[0]: redirect_urls\n            for document_path, redirect_urls in cls.redirections.items()\n        }\n        redirection_conflict = next((\n            (canon_1, canon_2, redirs_1.intersection(redirs_2))\n            for (canon_1, redirs_1), (canon_2, redirs_2)\n            in itertools.combinations(redirections.items(), 2)\n            if redirs_1.intersection(redirs_2)\n        ), None)\n        if redirection_conflict:\n            canonical_url_1, canonical_url_2 = redirection_conflict[:2]\n            conflicting_redirect_urls = redirection_conflict[-1]\n            raise RuntimeError(\n                'Documents {} and {} define conflicting redirects: {}'.format(\n                    canonical_url_1, canonical_url_2, conflicting_redirect_urls\n                )\n            )\n        all_canonical_urls = set(redirections.keys())\n        all_redirect_urls = {\n            redirect_url\n            for redirect_urls in redirections.values()\n            for redirect_url in redirect_urls\n        }\n        conflicting_urls = all_canonical_urls.intersection(all_redirect_urls)\n        if conflicting_urls:\n            raise RuntimeError(\n                'Some redirects conflict with existing documents: {}'.format(\n                    conflicting_urls\n                )\n            )\n\n        for canonical_url, redirect_urls in redirections.items():\n            for redirect_url in redirect_urls:\n                context = {\n                    'canonical_url': os.path.relpath(\n                        canonical_url, redirect_url\n                    ),\n                    'title': os.path.basename(redirect_url),\n                    'metatags': redirect_html_fragment.format(\n                        base_url=app.config.html_baseurl,\n                        url=app.builder.get_relative_uri(\n                            redirect_url, canonical_url\n                        )\n                    )\n                }\n                yield (redirect_url, context, cls.template_name)\n\n    def run(self):\n        document_path = self.state.document.current_source\n        if document_path not in RedirectFrom.redirections:\n            RedirectFrom.redirections[document_path] = set()\n        RedirectFrom.redirections[document_path].update(self.content)\n        return []\n\n\ndef make_router(origin, destination):\n    def _missing_reference(app, env, node, contnode):\n        from docutils import nodes\n        from docutils.utils import relative_path\n        from sphinx.util import docname_join\n\n        doctarget = docname_join(node['refdoc'], node['reftarget'])\n        if doctarget.startswith(origin):\n            routed_doctarget = doctarget.replace(origin, destination)\n            if routed_doctarget in env.all_docs:\n                newnode = nodes.reference(\n                    '', contnode.astext(), internal=True\n                )\n                newnode['refuri'] = app.builder.get_relative_uri(\n                    node['refdoc'], routed_doctarget\n                )\n                return newnode\n    return _missing_reference\n\ndef smv_rewrite_baseurl(app, config):\n    # When using Sphinx multiversion, there is no way at initial configuration time\n    # to determine the distribution we are currently targeting (conf.py is read before\n    # external defines are setup, and environment variables aren't passed through to\n    # conf.py).  Instead, hook into the 'config-inited' event which is late enough\n    # to rewrite the html_baseurl with the current version.\n    if app.config.smv_current_version != '':\n        app.config.html_baseurl = app.config.html_baseurl + '/' + app.config.smv_current_version\n\ndef setup(app):\n    app.connect('config-inited', smv_rewrite_baseurl)\n    RedirectFrom.register(app)\n", "path": "conf.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n#\n# rosindex documentation build configuration file, created by\n# sphinx-quickstart on Tue Oct  2 16:34:57 2018.\n#\n# This file is execfile()d with the current directory set to its\n# containing dir.\n#\n# Note that not all possible configuration values are present in this\n# autogenerated file.\n#\n# All configuration values have a default; values that are commented out\n# serve to show the default.\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\n#\nimport sys, os\nimport itertools\nfrom docutils.parsers.rst import Directive\n\nsys.path.append(os.path.abspath('./sphinx-multiversion'))\n\n\n# The suffix(es) of source filenames.\n# You can specify multiple suffix as a list of string:\n#\n# The master toctree document.\nmaster_doc = 'index'\n\n# The default role\ndefault_role = 'any'\n\n# The set of warnings to suppress.\nsuppress_warnings = ['image.nonlocal_uri']\n\n# General information about the project.\nproject = u'ros2 documentation'\ncopyright = u'2018-2021, Open Robotics'\nauthor = u'Open Robotics'\n\n# The version info for the project you're documenting, acts as replacement for\n# |version| and |release|, also used in various other places throughout the\n# built documents.\n#\n# The short X.Y version.\nversion = u''\n# The full version, including alpha/beta/rc tags.\nrelease = u''\n\n# Define the default role to use for links\ndefault_role = 'any'\n\n# The language for content autogenerated by Sphinx. Refer to documentation\n# for a list of supported languages.\n#\n# This is also used if you do content translation via gettext catalogs.\n# Usually you set \"language\" from the command line for these cases.\nlanguage = None\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\n# This patterns also effect to html_static_path and html_extra_path\nexclude_patterns = ['**/_*.rst']\n\n# The name of the Pygments (syntax highlighting) style to use.\npygments_style = 'sphinx'\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\nextensions = ['sphinx.ext.intersphinx', 'sphinx_tabs.tabs', 'sphinx_multiversion', 'sphinxcontrib.srclinks']\n\n# Intersphinx mapping\n\nintersphinx_mapping = {\n    'catkin_pkg':    ('http://docs.ros.org/en/independent/api/catkin_pkg/html', None),\n    'jenkins_tools': ('http://docs.ros.org/en/independent/api/jenkins_tools/html', None),\n    'rosdep':        ('http://docs.ros.org/en/independent/api/rosdep/html', None),\n    'rosdistro':     ('http://docs.ros.org/en/independent/api/rosdistro/html', None),\n    'rosinstall':    ('http://docs.ros.org/en/independent/api/rosinstall/html', None),\n    'rospkg':        ('http://docs.ros.org/en/independent/api/rospkg/html', None),\n    'vcstools':      ('http://docs.ros.org/en/independent/api/vcstools/html', None)\n}\n\n# -- Options for HTML output ----------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\n#\n#html_theme = 'alabaster'\n\nsrclink_project = 'https://github.com/ros2/ros2_documentation'\nsrclink_src_path = 'source/'\nsrclink_branch = 'rolling'\n\ntemplates_path = [\n    \"source/_templates\",\n]\n\nhtml_sidebars = {\n    '**': ['navigation.html', 'srclinks.html', 'versioning.html'],\n}\n\n# smv_tag_whitelist = None\n\nsmv_branch_whitelist = r'^(rolling|foxy|eloquent|dashing)$'\n\n\nsmv_released_pattern = r'^refs/(heads|remotes/[^/]+)/(foxy|eloquent|dashing).*$'\nsmv_remote_whitelist = r'^(origin)$'\nsmv_latest_version = 'foxy'\n\n\n\nhtml_favicon = 'favicon.ico'\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\n# html_static_path = ['_static']\n\n# Drop any source link suffix\nhtml_sourcelink_suffix = ''\n\n# -- Options for HTMLHelp output ------------------------------------------\n\n# Output file base name for HTML help builder.\nhtmlhelp_basename = 'ros2_docsdoc'\n\nhtml_baseurl = 'https://docs.ros.org/en'\n\nclass RedirectFrom(Directive):\n\n    has_content = True\n    template_name = 'layout.html'\n    redirections = {}\n\n    @classmethod\n    def register(cls, app):\n        app.connect('html-collect-pages', cls.generate)\n        app.add_directive('redirect-from', cls)\n        return app\n\n    @classmethod\n    def generate(cls, app):\n        from sphinx.builders.html import StandaloneHTMLBuilder\n        if not isinstance(app.builder, StandaloneHTMLBuilder):\n            return\n\n        redirect_html_fragment = \"\"\"\n            <link rel=\"canonical\" href=\"{base_url}/{url}\" />\n            <meta http-equiv=\"refresh\" content=\"0; url={url}\" />\n            <script>\n                window.location.href = '{url}';\n            </script>\n        \"\"\"\n        redirections = {\n            os.path.splitext(os.path.relpath(\n                document_path, app.srcdir\n            ))[0]: redirect_urls\n            for document_path, redirect_urls in cls.redirections.items()\n        }\n        redirection_conflict = next((\n            (canon_1, canon_2, redirs_1.intersection(redirs_2))\n            for (canon_1, redirs_1), (canon_2, redirs_2)\n            in itertools.combinations(redirections.items(), 2)\n            if redirs_1.intersection(redirs_2)\n        ), None)\n        if redirection_conflict:\n            canonical_url_1, canonical_url_2 = redirection_conflict[:2]\n            conflicting_redirect_urls = redirection_conflict[-1]\n            raise RuntimeError(\n                'Documents {} and {} define conflicting redirects: {}'.format(\n                    canonical_url_1, canonical_url_2, conflicting_redirect_urls\n                )\n            )\n        all_canonical_urls = set(redirections.keys())\n        all_redirect_urls = {\n            redirect_url\n            for redirect_urls in redirections.values()\n            for redirect_url in redirect_urls\n        }\n        conflicting_urls = all_canonical_urls.intersection(all_redirect_urls)\n        if conflicting_urls:\n            raise RuntimeError(\n                'Some redirects conflict with existing documents: {}'.format(\n                    conflicting_urls\n                )\n            )\n\n        for canonical_url, redirect_urls in redirections.items():\n            for redirect_url in redirect_urls:\n                context = {\n                    'canonical_url': os.path.relpath(\n                        canonical_url, redirect_url\n                    ),\n                    'title': os.path.basename(redirect_url),\n                    'metatags': redirect_html_fragment.format(\n                        base_url=app.config.html_baseurl,\n                        url=app.builder.get_relative_uri(\n                            redirect_url, canonical_url\n                        )\n                    )\n                }\n                yield (redirect_url, context, cls.template_name)\n\n    def run(self):\n        document_path = self.state.document.current_source\n        if document_path not in RedirectFrom.redirections:\n            RedirectFrom.redirections[document_path] = set()\n        RedirectFrom.redirections[document_path].update(self.content)\n        return []\n\n\ndef make_router(origin, destination):\n    def _missing_reference(app, env, node, contnode):\n        from docutils import nodes\n        from docutils.utils import relative_path\n        from sphinx.util import docname_join\n\n        doctarget = docname_join(node['refdoc'], node['reftarget'])\n        if doctarget.startswith(origin):\n            routed_doctarget = doctarget.replace(origin, destination)\n            if routed_doctarget in env.all_docs:\n                newnode = nodes.reference(\n                    '', contnode.astext(), internal=True\n                )\n                newnode['refuri'] = app.builder.get_relative_uri(\n                    node['refdoc'], routed_doctarget\n                )\n                return newnode\n    return _missing_reference\n\ndef smv_rewrite_baseurl(app, config):\n    # When using Sphinx multiversion, there is no way at initial configuration time\n    # to determine the distribution we are currently targeting (conf.py is read before\n    # external defines are setup, and environment variables aren't passed through to\n    # conf.py).  Instead, hook into the 'config-inited' event which is late enough\n    # to rewrite the html_baseurl with the current version.\n    if app.config.smv_current_version != '':\n        app.config.html_baseurl = app.config.html_baseurl + '/' + app.config.smv_current_version\n\ndef srclink_rewrite_branch(app, config):\n    if app.config.smv_current_version != '':\n        app.config.srclink_branch = app.config.smv_current_version\n\ndef setup(app):\n    app.connect('config-inited', smv_rewrite_baseurl)\n    app.connect('config-inited', srclink_rewrite_branch)\n    RedirectFrom.register(app)\n", "path": "conf.py"}]}