We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
reST doc directive: slugs with slashes in no longer work
At some point in the previous few versions, slugs with slashes in no longer work - links pointing to them have their slashes removed before the link is resolved, leading to an error like `"swowndata" slug doesn't exist` for a slug called `sw/owndata`. I can't find this being mentioned in the release notes or the other issues here, so I assume this was done by accident, is a bug, and should be fixed.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `nikola/plugins/compile/rest/doc.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 
3 # Copyright © 2012-2020 Roberto Alsina and others.
4 
5 # Permission is hereby granted, free of charge, to any
6 # person obtaining a copy of this software and associated
7 # documentation files (the "Software"), to deal in the
8 # Software without restriction, including without limitation
9 # the rights to use, copy, modify, merge, publish,
10 # distribute, sublicense, and/or sell copies of the
11 # Software, and to permit persons to whom the Software is
12 # furnished to do so, subject to the following conditions:
13 #
14 # The above copyright notice and this permission notice
15 # shall be included in all copies or substantial portions of
16 # the Software.
17 #
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
19 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
20 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
21 # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
22 # OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 
27 """reST role for linking to other documents."""
28 
29 from docutils import nodes
30 from docutils.parsers.rst import roles
31 
32 from nikola.utils import split_explicit_title, LOGGER, slugify
33 from nikola.plugin_categories import RestExtension
34 
35 
36 class Plugin(RestExtension):
37     """Plugin for doc role."""
38 
39     name = 'rest_doc'
40 
41     def set_site(self, site):
42         """Set Nikola site."""
43         self.site = site
44         roles.register_canonical_role('doc', doc_role)
45         self.site.register_shortcode('doc', doc_shortcode)
46         doc_role.site = site
47         return super().set_site(site)
48 
49 
50 def _doc_link(rawtext, text, options={}, content=[]):
51     """Handle the doc role."""
52     # split link's text and post's slug in role content
53     has_explicit_title, title, slug = split_explicit_title(text)
54     if '#' in slug:
55         slug, fragment = slug.split('#', 1)
56     else:
57         fragment = None
58     slug = slugify(slug)
59     # check if the slug given is part of our blog posts/pages
60     twin_slugs = False
61     post = None
62     for p in doc_role.site.timeline:
63         if p.meta('slug') == slug:
64             if post is None:
65                 post = p
66             else:
67                 twin_slugs = True
68                 break
69 
70     try:
71         if post is None:
72             raise ValueError("No post with matching slug found.")
73     except ValueError:
74         return False, False, None, None, slug
75 
76     if not has_explicit_title:
77         # use post's title as link's text
78         title = post.title()
79     permalink = post.permalink()
80     if fragment:
81         permalink += '#' + fragment
82 
83     return True, twin_slugs, title, permalink, slug
84 
85 
86 def doc_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
87     """Handle the doc role."""
88     success, twin_slugs, title, permalink, slug = _doc_link(rawtext, text, options, content)
89     if success:
90         if twin_slugs:
91             inliner.reporter.warning(
92                 'More than one post with the same slug. Using "{0}"'.format(permalink))
93             LOGGER.warning(
94                 'More than one post with the same slug. Using "{0}" for doc role'.format(permalink))
95         node = make_link_node(rawtext, title, permalink, options)
96         return [node], []
97     else:
98         msg = inliner.reporter.error(
99             '"{0}" slug doesn\'t exist.'.format(slug),
100             line=lineno)
101         prb = inliner.problematic(rawtext, rawtext, msg)
102         return [prb], [msg]
103 
104 
105 def doc_shortcode(*args, **kwargs):
106     """Implement the doc shortcode."""
107     text = kwargs['data']
108     success, twin_slugs, title, permalink, slug = _doc_link(text, text, LOGGER)
109     if success:
110         if twin_slugs:
111             LOGGER.warning(
112                 'More than one post with the same slug. Using "{0}" for doc shortcode'.format(permalink))
113         return '<a href="{0}">{1}</a>'.format(permalink, title)
114     else:
115         LOGGER.error(
116             '"{0}" slug doesn\'t exist.'.format(slug))
117         return '<span class="error text-error" style="color: red;">Invalid link: {0}</span>'.format(text)
118 
119 
120 def make_link_node(rawtext, text, url, options):
121     """Make a reST link node."""
122     node = nodes.reference(rawtext, text, refuri=url, *options)
123     return node
124
```
--- 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/nikola/plugins/compile/rest/doc.py b/nikola/plugins/compile/rest/doc.py
--- a/nikola/plugins/compile/rest/doc.py
+++ b/nikola/plugins/compile/rest/doc.py
@@ -47,16 +47,8 @@
         return super().set_site(site)
 
 
-def _doc_link(rawtext, text, options={}, content=[]):
-    """Handle the doc role."""
-    # split link's text and post's slug in role content
-    has_explicit_title, title, slug = split_explicit_title(text)
-    if '#' in slug:
-        slug, fragment = slug.split('#', 1)
-    else:
-        fragment = None
-    slug = slugify(slug)
-    # check if the slug given is part of our blog posts/pages
+def _find_post(slug):
+    """Find a post with the given slug in posts or pages."""
     twin_slugs = False
     post = None
     for p in doc_role.site.timeline:
@@ -66,6 +58,23 @@
             else:
                 twin_slugs = True
                 break
+    return post, twin_slugs
+
+
+def _doc_link(rawtext, text, options={}, content=[]):
+    """Handle the doc role."""
+    # split link's text and post's slug in role content
+    has_explicit_title, title, slug = split_explicit_title(text)
+    if '#' in slug:
+        slug, fragment = slug.split('#', 1)
+    else:
+        fragment = None
+
+    # Look for the unslugified input first, then try to slugify (Issue #3450)
+    post, twin_slugs = _find_post(slug)
+    if post is None:
+        slug = slugify(slug)
+        post, twin_slugs = _find_post(slug)
 
     try:
         if post is None:

{"golden_diff": "diff --git a/nikola/plugins/compile/rest/doc.py b/nikola/plugins/compile/rest/doc.py\n--- a/nikola/plugins/compile/rest/doc.py\n+++ b/nikola/plugins/compile/rest/doc.py\n@@ -47,16 +47,8 @@\n         return super().set_site(site)\n \n \n-def _doc_link(rawtext, text, options={}, content=[]):\n-    \"\"\"Handle the doc role.\"\"\"\n-    # split link's text and post's slug in role content\n-    has_explicit_title, title, slug = split_explicit_title(text)\n-    if '#' in slug:\n-        slug, fragment = slug.split('#', 1)\n-    else:\n-        fragment = None\n-    slug = slugify(slug)\n-    # check if the slug given is part of our blog posts/pages\n+def _find_post(slug):\n+    \"\"\"Find a post with the given slug in posts or pages.\"\"\"\n     twin_slugs = False\n     post = None\n     for p in doc_role.site.timeline:\n@@ -66,6 +58,23 @@\n             else:\n                 twin_slugs = True\n                 break\n+    return post, twin_slugs\n+\n+\n+def _doc_link(rawtext, text, options={}, content=[]):\n+    \"\"\"Handle the doc role.\"\"\"\n+    # split link's text and post's slug in role content\n+    has_explicit_title, title, slug = split_explicit_title(text)\n+    if '#' in slug:\n+        slug, fragment = slug.split('#', 1)\n+    else:\n+        fragment = None\n+\n+    # Look for the unslugified input first, then try to slugify (Issue #3450)\n+    post, twin_slugs = _find_post(slug)\n+    if post is None:\n+        slug = slugify(slug)\n+        post, twin_slugs = _find_post(slug)\n \n     try:\n         if post is None:\n", "issue": "reST doc directive: slugs with slashes in no longer work\nAt some point in the previous few versions, slugs with slashes in no longer work - links pointing to them have their slashes removed before the link is resolved, leading to an error like `\"swowndata\" slug doesn't exist` for a slug called `sw/owndata`. I can't find this being mentioned in the release notes or the other issues here, so I assume this was done by accident, is a bug, and should be fixed.\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\n# Copyright \u00a9 2012-2020 Roberto Alsina and others.\n\n# Permission is hereby granted, free of charge, to any\n# person obtaining a copy of this software and associated\n# documentation files (the \"Software\"), to deal in the\n# Software without restriction, including without limitation\n# the rights to use, copy, modify, merge, publish,\n# distribute, sublicense, and/or sell copies of the\n# Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice\n# shall be included in all copies or substantial portions of\n# the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY\n# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\n# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS\n# OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\"\"\"reST role for linking to other documents.\"\"\"\n\nfrom docutils import nodes\nfrom docutils.parsers.rst import roles\n\nfrom nikola.utils import split_explicit_title, LOGGER, slugify\nfrom nikola.plugin_categories import RestExtension\n\n\nclass Plugin(RestExtension):\n    \"\"\"Plugin for doc role.\"\"\"\n\n    name = 'rest_doc'\n\n    def set_site(self, site):\n        \"\"\"Set Nikola site.\"\"\"\n        self.site = site\n        roles.register_canonical_role('doc', doc_role)\n        self.site.register_shortcode('doc', doc_shortcode)\n        doc_role.site = site\n        return super().set_site(site)\n\n\ndef _doc_link(rawtext, text, options={}, content=[]):\n    \"\"\"Handle the doc role.\"\"\"\n    # split link's text and post's slug in role content\n    has_explicit_title, title, slug = split_explicit_title(text)\n    if '#' in slug:\n        slug, fragment = slug.split('#', 1)\n    else:\n        fragment = None\n    slug = slugify(slug)\n    # check if the slug given is part of our blog posts/pages\n    twin_slugs = False\n    post = None\n    for p in doc_role.site.timeline:\n        if p.meta('slug') == slug:\n            if post is None:\n                post = p\n            else:\n                twin_slugs = True\n                break\n\n    try:\n        if post is None:\n            raise ValueError(\"No post with matching slug found.\")\n    except ValueError:\n        return False, False, None, None, slug\n\n    if not has_explicit_title:\n        # use post's title as link's text\n        title = post.title()\n    permalink = post.permalink()\n    if fragment:\n        permalink += '#' + fragment\n\n    return True, twin_slugs, title, permalink, slug\n\n\ndef doc_role(name, rawtext, text, lineno, inliner, options={}, content=[]):\n    \"\"\"Handle the doc role.\"\"\"\n    success, twin_slugs, title, permalink, slug = _doc_link(rawtext, text, options, content)\n    if success:\n        if twin_slugs:\n            inliner.reporter.warning(\n                'More than one post with the same slug. Using \"{0}\"'.format(permalink))\n            LOGGER.warning(\n                'More than one post with the same slug. Using \"{0}\" for doc role'.format(permalink))\n        node = make_link_node(rawtext, title, permalink, options)\n        return [node], []\n    else:\n        msg = inliner.reporter.error(\n            '\"{0}\" slug doesn\\'t exist.'.format(slug),\n            line=lineno)\n        prb = inliner.problematic(rawtext, rawtext, msg)\n        return [prb], [msg]\n\n\ndef doc_shortcode(*args, **kwargs):\n    \"\"\"Implement the doc shortcode.\"\"\"\n    text = kwargs['data']\n    success, twin_slugs, title, permalink, slug = _doc_link(text, text, LOGGER)\n    if success:\n        if twin_slugs:\n            LOGGER.warning(\n                'More than one post with the same slug. Using \"{0}\" for doc shortcode'.format(permalink))\n        return '<a href=\"{0}\">{1}</a>'.format(permalink, title)\n    else:\n        LOGGER.error(\n            '\"{0}\" slug doesn\\'t exist.'.format(slug))\n        return '<span class=\"error text-error\" style=\"color: red;\">Invalid link: {0}</span>'.format(text)\n\n\ndef make_link_node(rawtext, text, url, options):\n    \"\"\"Make a reST link node.\"\"\"\n    node = nodes.reference(rawtext, text, refuri=url, *options)\n    return node\n", "path": "nikola/plugins/compile/rest/doc.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\n# Copyright \u00a9 2012-2020 Roberto Alsina and others.\n\n# Permission is hereby granted, free of charge, to any\n# person obtaining a copy of this software and associated\n# documentation files (the \"Software\"), to deal in the\n# Software without restriction, including without limitation\n# the rights to use, copy, modify, merge, publish,\n# distribute, sublicense, and/or sell copies of the\n# Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice\n# shall be included in all copies or substantial portions of\n# the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY\n# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\n# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS\n# OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\"\"\"reST role for linking to other documents.\"\"\"\n\nfrom docutils import nodes\nfrom docutils.parsers.rst import roles\n\nfrom nikola.utils import split_explicit_title, LOGGER, slugify\nfrom nikola.plugin_categories import RestExtension\n\n\nclass Plugin(RestExtension):\n    \"\"\"Plugin for doc role.\"\"\"\n\n    name = 'rest_doc'\n\n    def set_site(self, site):\n        \"\"\"Set Nikola site.\"\"\"\n        self.site = site\n        roles.register_canonical_role('doc', doc_role)\n        self.site.register_shortcode('doc', doc_shortcode)\n        doc_role.site = site\n        return super().set_site(site)\n\n\ndef _find_post(slug):\n    \"\"\"Find a post with the given slug in posts or pages.\"\"\"\n    twin_slugs = False\n    post = None\n    for p in doc_role.site.timeline:\n        if p.meta('slug') == slug:\n            if post is None:\n                post = p\n            else:\n                twin_slugs = True\n                break\n    return post, twin_slugs\n\n\ndef _doc_link(rawtext, text, options={}, content=[]):\n    \"\"\"Handle the doc role.\"\"\"\n    # split link's text and post's slug in role content\n    has_explicit_title, title, slug = split_explicit_title(text)\n    if '#' in slug:\n        slug, fragment = slug.split('#', 1)\n    else:\n        fragment = None\n\n    # Look for the unslugified input first, then try to slugify (Issue #3450)\n    post, twin_slugs = _find_post(slug)\n    if post is None:\n        slug = slugify(slug)\n        post, twin_slugs = _find_post(slug)\n\n    try:\n        if post is None:\n            raise ValueError(\"No post with matching slug found.\")\n    except ValueError:\n        return False, False, None, None, slug\n\n    if not has_explicit_title:\n        # use post's title as link's text\n        title = post.title()\n    permalink = post.permalink()\n    if fragment:\n        permalink += '#' + fragment\n\n    return True, twin_slugs, title, permalink, slug\n\n\ndef doc_role(name, rawtext, text, lineno, inliner, options={}, content=[]):\n    \"\"\"Handle the doc role.\"\"\"\n    success, twin_slugs, title, permalink, slug = _doc_link(rawtext, text, options, content)\n    if success:\n        if twin_slugs:\n            inliner.reporter.warning(\n                'More than one post with the same slug. Using \"{0}\"'.format(permalink))\n            LOGGER.warning(\n                'More than one post with the same slug. Using \"{0}\" for doc role'.format(permalink))\n        node = make_link_node(rawtext, title, permalink, options)\n        return [node], []\n    else:\n        msg = inliner.reporter.error(\n            '\"{0}\" slug doesn\\'t exist.'.format(slug),\n            line=lineno)\n        prb = inliner.problematic(rawtext, rawtext, msg)\n        return [prb], [msg]\n\n\ndef doc_shortcode(*args, **kwargs):\n    \"\"\"Implement the doc shortcode.\"\"\"\n    text = kwargs['data']\n    success, twin_slugs, title, permalink, slug = _doc_link(text, text, LOGGER)\n    if success:\n        if twin_slugs:\n            LOGGER.warning(\n                'More than one post with the same slug. Using \"{0}\" for doc shortcode'.format(permalink))\n        return '<a href=\"{0}\">{1}</a>'.format(permalink, title)\n    else:\n        LOGGER.error(\n            '\"{0}\" slug doesn\\'t exist.'.format(slug))\n        return '<span class=\"error text-error\" style=\"color: red;\">Invalid link: {0}</span>'.format(text)\n\n\ndef make_link_node(rawtext, text, url, options):\n    \"\"\"Make a reST link node.\"\"\"\n    node = nodes.reference(rawtext, text, refuri=url, *options)\n    return node\n", "path": "nikola/plugins/compile/rest/doc.py"}]}