We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
listing directive explodes badly if used wrong
Example: 

```
.. listing:: hello.py
```

Which is a way too common first attempt to use it, crashes like this:

```
TaskError - taskid:render_posts:cache/posts/foo.html
PythonAction Error
Traceback (most recent call last):
  File "/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/doit/action.py", line 383, in execute
    returned_value = self.py_callable(*self.args, **kwargs)
  File "/home/ralsina/Desktop/proyectos/nikola/master/nikola/post.py", line 485, in compile
    self.is_two_file),
  File "/home/ralsina/Desktop/proyectos/nikola/master/nikola/plugins/compile/rest/__init__.py", line 100, in compile_html
    output, error_level, deps = self.compile_html_string(data, source, is_two_file)
  File "/home/ralsina/Desktop/proyectos/nikola/master/nikola/plugins/compile/rest/__init__.py", line 86, in compile_html_string
    }, logger=self.logger, source_path=source_path, l_add_ln=add_ln, transforms=self.site.rst_transforms)
  File "/home/ralsina/Desktop/proyectos/nikola/master/nikola/plugins/compile/rest/__init__.py", line 276, in rst2html
    pub.publish(enable_exit_status=enable_exit_status)
  File "/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/core.py", line 217, in publish
    self.settings)
  File "/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/readers/__init__.py", line 72, in read
    self.parse()
  File "/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/readers/__init__.py", line 78, in parse
    self.parser.parse(self.input, document)
  File "/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/parsers/rst/__init__.py", line 172, in parse
    self.statemachine.run(inputlines, document, inliner=self.inliner)
  File "/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/parsers/rst/states.py", line 170, in run
    input_source=document['source'])
  File "/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/statemachine.py", line 239, in run
    context, state, transitions)
  File "/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/statemachine.py", line 460, in check_line
    return method(match, context, next_state)
  File "/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/parsers/rst/states.py", line 2299, in explicit_markup
    nodelist, blank_finish = self.explicit_construct(match)
  File "/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/parsers/rst/states.py", line 2311, in explicit_construct
    return method(self, expmatch)
  File "/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/parsers/rst/states.py", line 2054, in directive
    directive_class, match, type_name, option_presets)
  File "/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/parsers/rst/states.py", line 2103, in run_directive
    result = directive_instance.run()
  File "/home/ralsina/Desktop/proyectos/nikola/master/nikola/plugins/compile/rest/listing.py", line 174, in run
    lang = self.arguments.pop(0)
IndexError: pop from empty list
```


--- 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/listing.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 
3 # Copyright © 2012-2015 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 
28 """Define and register a listing directive using the existing CodeBlock."""
29 
30 
31 from __future__ import unicode_literals
32 import io
33 import os
34 import uuid
35 try:
36     from urlparse import urlunsplit
37 except ImportError:
38     from urllib.parse import urlunsplit  # NOQA
39 
40 import docutils.parsers.rst.directives.body
41 import docutils.parsers.rst.directives.misc
42 from docutils import core
43 from docutils import nodes
44 from docutils.parsers.rst import Directive, directives
45 from docutils.parsers.rst.roles import set_classes
46 from docutils.parsers.rst.directives.misc import Include
47 
48 from pygments.lexers import get_lexer_by_name
49 import pygments
50 import pygments.util
51 
52 from nikola import utils
53 from nikola.plugin_categories import RestExtension
54 
55 
56 # A sanitized version of docutils.parsers.rst.directives.body.CodeBlock.
57 class CodeBlock(Directive):
58 
59     """Parse and mark up content of a code block."""
60 
61     optional_arguments = 1
62     option_spec = {'class': directives.class_option,
63                    'name': directives.unchanged,
64                    'number-lines': directives.unchanged,  # integer or None
65                    'linenos': directives.unchanged,
66                    'tab-width': directives.nonnegative_int}
67     has_content = True
68 
69     def run(self):
70         """Run code block directive."""
71         self.assert_has_content()
72 
73         if 'linenos' in self.options:
74             self.options['number-lines'] = self.options['linenos']
75         if 'tab-width' in self.options:
76             self.content = [x.replace('\t', ' ' * self.options['tab-width']) for x in self.content]
77 
78         if self.arguments:
79             language = self.arguments[0]
80         else:
81             language = 'text'
82         set_classes(self.options)
83         classes = ['code']
84         if language:
85             classes.append(language)
86         if 'classes' in self.options:
87             classes.extend(self.options['classes'])
88 
89         code = '\n'.join(self.content)
90 
91         try:
92             lexer = get_lexer_by_name(language)
93         except pygments.util.ClassNotFound:
94             raise self.error('Cannot find pygments lexer for language "{0}"'.format(language))
95 
96         if 'number-lines' in self.options:
97             linenos = 'table'
98             # optional argument `startline`, defaults to 1
99             try:
100                 linenostart = int(self.options['number-lines'] or 1)
101             except ValueError:
102                 raise self.error(':number-lines: with non-integer start value')
103         else:
104             linenos = False
105             linenostart = 1  # actually unused
106 
107         if self.site.invariant:  # for testing purposes
108             anchor_ref = 'rest_code_' + 'fixedvaluethatisnotauuid'
109         else:
110             anchor_ref = 'rest_code_' + uuid.uuid4().hex
111 
112         formatter = utils.NikolaPygmentsHTML(anchor_ref=anchor_ref, classes=classes, linenos=linenos, linenostart=linenostart)
113         out = pygments.highlight(code, lexer, formatter)
114         node = nodes.raw('', out, format='html')
115 
116         self.add_name(node)
117         # if called from "include", set the source
118         if 'source' in self.options:
119             node.attributes['source'] = self.options['source']
120 
121         return [node]
122 
123 # Monkey-patch: replace insane docutils CodeBlock with our implementation.
124 docutils.parsers.rst.directives.body.CodeBlock = CodeBlock
125 docutils.parsers.rst.directives.misc.CodeBlock = CodeBlock
126 
127 
128 class Plugin(RestExtension):
129 
130     """Plugin for listing directive."""
131 
132     name = "rest_listing"
133 
134     def set_site(self, site):
135         """Set Nikola site."""
136         self.site = site
137         # Even though listings don't use CodeBlock anymore, I am
138         # leaving these to make the code directive work with
139         # docutils < 0.9
140         CodeBlock.site = site
141         directives.register_directive('code', CodeBlock)
142         directives.register_directive('code-block', CodeBlock)
143         directives.register_directive('sourcecode', CodeBlock)
144         directives.register_directive('listing', Listing)
145         Listing.folders = site.config['LISTINGS_FOLDERS']
146         return super(Plugin, self).set_site(site)
147 
148 
149 # Add sphinx compatibility option
150 listing_spec = Include.option_spec
151 listing_spec['linenos'] = directives.unchanged
152 
153 
154 class Listing(Include):
155 
156     """Create a highlighted block of code from a file in listings/.
157 
158     Usage:
159 
160         .. listing:: nikola.py python
161            :number-lines:
162 
163     """
164 
165     has_content = False
166     required_arguments = 1
167     optional_arguments = 1
168     option_spec = listing_spec
169 
170     def run(self):
171         """Run listing directive."""
172         _fname = self.arguments.pop(0)
173         fname = _fname.replace('/', os.sep)
174         lang = self.arguments.pop(0)
175         if len(self.folders) == 1:
176             listings_folder = next(iter(self.folders.keys()))
177             if fname.startswith(listings_folder):
178                 fpath = os.path.join(fname)  # new syntax: specify folder name
179             else:
180                 fpath = os.path.join(listings_folder, fname)  # old syntax: don't specify folder name
181         else:
182             fpath = os.path.join(fname)  # must be new syntax: specify folder name
183         self.arguments.insert(0, fpath)
184         self.options['code'] = lang
185         if 'linenos' in self.options:
186             self.options['number-lines'] = self.options['linenos']
187         with io.open(fpath, 'r+', encoding='utf8') as fileobject:
188             self.content = fileobject.read().splitlines()
189         self.state.document.settings.record_dependencies.add(fpath)
190         target = urlunsplit(("link", 'listing', fpath.replace('\\', '/'), '', ''))
191         generated_nodes = (
192             [core.publish_doctree('`{0} <{1}>`_'.format(_fname, target))[0]])
193         generated_nodes += self.get_code_from_file(fileobject)
194         return generated_nodes
195 
196     def get_code_from_file(self, data):
197         """Create CodeBlock nodes from file object content."""
198         return super(Listing, self).run()
199 
200     def assert_has_content(self):
201         """Listing has no content, override check from superclass."""
202         pass
203
```
--- 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/listing.py b/nikola/plugins/compile/rest/listing.py
--- a/nikola/plugins/compile/rest/listing.py
+++ b/nikola/plugins/compile/rest/listing.py
@@ -171,7 +171,12 @@
         """Run listing directive."""
         _fname = self.arguments.pop(0)
         fname = _fname.replace('/', os.sep)
-        lang = self.arguments.pop(0)
+        try:
+            lang = self.arguments.pop(0)
+            self.options['code'] = lang
+        except IndexError:
+            self.options['literal'] = True
+
         if len(self.folders) == 1:
             listings_folder = next(iter(self.folders.keys()))
             if fname.startswith(listings_folder):
@@ -181,7 +186,6 @@
         else:
             fpath = os.path.join(fname)  # must be new syntax: specify folder name
         self.arguments.insert(0, fpath)
-        self.options['code'] = lang
         if 'linenos' in self.options:
             self.options['number-lines'] = self.options['linenos']
         with io.open(fpath, 'r+', encoding='utf8') as fileobject:

{"golden_diff": "diff --git a/nikola/plugins/compile/rest/listing.py b/nikola/plugins/compile/rest/listing.py\n--- a/nikola/plugins/compile/rest/listing.py\n+++ b/nikola/plugins/compile/rest/listing.py\n@@ -171,7 +171,12 @@\n         \"\"\"Run listing directive.\"\"\"\n         _fname = self.arguments.pop(0)\n         fname = _fname.replace('/', os.sep)\n-        lang = self.arguments.pop(0)\n+        try:\n+            lang = self.arguments.pop(0)\n+            self.options['code'] = lang\n+        except IndexError:\n+            self.options['literal'] = True\n+\n         if len(self.folders) == 1:\n             listings_folder = next(iter(self.folders.keys()))\n             if fname.startswith(listings_folder):\n@@ -181,7 +186,6 @@\n         else:\n             fpath = os.path.join(fname)  # must be new syntax: specify folder name\n         self.arguments.insert(0, fpath)\n-        self.options['code'] = lang\n         if 'linenos' in self.options:\n             self.options['number-lines'] = self.options['linenos']\n         with io.open(fpath, 'r+', encoding='utf8') as fileobject:\n", "issue": "listing directive explodes badly if used wrong\nExample: \n\n```\n.. listing:: hello.py\n```\n\nWhich is a way too common first attempt to use it, crashes like this:\n\n```\nTaskError - taskid:render_posts:cache/posts/foo.html\nPythonAction Error\nTraceback (most recent call last):\n  File \"/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/doit/action.py\", line 383, in execute\n    returned_value = self.py_callable(*self.args, **kwargs)\n  File \"/home/ralsina/Desktop/proyectos/nikola/master/nikola/post.py\", line 485, in compile\n    self.is_two_file),\n  File \"/home/ralsina/Desktop/proyectos/nikola/master/nikola/plugins/compile/rest/__init__.py\", line 100, in compile_html\n    output, error_level, deps = self.compile_html_string(data, source, is_two_file)\n  File \"/home/ralsina/Desktop/proyectos/nikola/master/nikola/plugins/compile/rest/__init__.py\", line 86, in compile_html_string\n    }, logger=self.logger, source_path=source_path, l_add_ln=add_ln, transforms=self.site.rst_transforms)\n  File \"/home/ralsina/Desktop/proyectos/nikola/master/nikola/plugins/compile/rest/__init__.py\", line 276, in rst2html\n    pub.publish(enable_exit_status=enable_exit_status)\n  File \"/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/core.py\", line 217, in publish\n    self.settings)\n  File \"/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/readers/__init__.py\", line 72, in read\n    self.parse()\n  File \"/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/readers/__init__.py\", line 78, in parse\n    self.parser.parse(self.input, document)\n  File \"/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/parsers/rst/__init__.py\", line 172, in parse\n    self.statemachine.run(inputlines, document, inliner=self.inliner)\n  File \"/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/parsers/rst/states.py\", line 170, in run\n    input_source=document['source'])\n  File \"/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/statemachine.py\", line 239, in run\n    context, state, transitions)\n  File \"/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/statemachine.py\", line 460, in check_line\n    return method(match, context, next_state)\n  File \"/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/parsers/rst/states.py\", line 2299, in explicit_markup\n    nodelist, blank_finish = self.explicit_construct(match)\n  File \"/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/parsers/rst/states.py\", line 2311, in explicit_construct\n    return method(self, expmatch)\n  File \"/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/parsers/rst/states.py\", line 2054, in directive\n    directive_class, match, type_name, option_presets)\n  File \"/home/ralsina/.virtualenvs/nikola/local/lib/python2.7/site-packages/docutils-0.12-py2.7.egg/docutils/parsers/rst/states.py\", line 2103, in run_directive\n    result = directive_instance.run()\n  File \"/home/ralsina/Desktop/proyectos/nikola/master/nikola/plugins/compile/rest/listing.py\", line 174, in run\n    lang = self.arguments.pop(0)\nIndexError: pop from empty list\n```\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\n# Copyright \u00a9 2012-2015 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\n\"\"\"Define and register a listing directive using the existing CodeBlock.\"\"\"\n\n\nfrom __future__ import unicode_literals\nimport io\nimport os\nimport uuid\ntry:\n    from urlparse import urlunsplit\nexcept ImportError:\n    from urllib.parse import urlunsplit  # NOQA\n\nimport docutils.parsers.rst.directives.body\nimport docutils.parsers.rst.directives.misc\nfrom docutils import core\nfrom docutils import nodes\nfrom docutils.parsers.rst import Directive, directives\nfrom docutils.parsers.rst.roles import set_classes\nfrom docutils.parsers.rst.directives.misc import Include\n\nfrom pygments.lexers import get_lexer_by_name\nimport pygments\nimport pygments.util\n\nfrom nikola import utils\nfrom nikola.plugin_categories import RestExtension\n\n\n# A sanitized version of docutils.parsers.rst.directives.body.CodeBlock.\nclass CodeBlock(Directive):\n\n    \"\"\"Parse and mark up content of a code block.\"\"\"\n\n    optional_arguments = 1\n    option_spec = {'class': directives.class_option,\n                   'name': directives.unchanged,\n                   'number-lines': directives.unchanged,  # integer or None\n                   'linenos': directives.unchanged,\n                   'tab-width': directives.nonnegative_int}\n    has_content = True\n\n    def run(self):\n        \"\"\"Run code block directive.\"\"\"\n        self.assert_has_content()\n\n        if 'linenos' in self.options:\n            self.options['number-lines'] = self.options['linenos']\n        if 'tab-width' in self.options:\n            self.content = [x.replace('\\t', ' ' * self.options['tab-width']) for x in self.content]\n\n        if self.arguments:\n            language = self.arguments[0]\n        else:\n            language = 'text'\n        set_classes(self.options)\n        classes = ['code']\n        if language:\n            classes.append(language)\n        if 'classes' in self.options:\n            classes.extend(self.options['classes'])\n\n        code = '\\n'.join(self.content)\n\n        try:\n            lexer = get_lexer_by_name(language)\n        except pygments.util.ClassNotFound:\n            raise self.error('Cannot find pygments lexer for language \"{0}\"'.format(language))\n\n        if 'number-lines' in self.options:\n            linenos = 'table'\n            # optional argument `startline`, defaults to 1\n            try:\n                linenostart = int(self.options['number-lines'] or 1)\n            except ValueError:\n                raise self.error(':number-lines: with non-integer start value')\n        else:\n            linenos = False\n            linenostart = 1  # actually unused\n\n        if self.site.invariant:  # for testing purposes\n            anchor_ref = 'rest_code_' + 'fixedvaluethatisnotauuid'\n        else:\n            anchor_ref = 'rest_code_' + uuid.uuid4().hex\n\n        formatter = utils.NikolaPygmentsHTML(anchor_ref=anchor_ref, classes=classes, linenos=linenos, linenostart=linenostart)\n        out = pygments.highlight(code, lexer, formatter)\n        node = nodes.raw('', out, format='html')\n\n        self.add_name(node)\n        # if called from \"include\", set the source\n        if 'source' in self.options:\n            node.attributes['source'] = self.options['source']\n\n        return [node]\n\n# Monkey-patch: replace insane docutils CodeBlock with our implementation.\ndocutils.parsers.rst.directives.body.CodeBlock = CodeBlock\ndocutils.parsers.rst.directives.misc.CodeBlock = CodeBlock\n\n\nclass Plugin(RestExtension):\n\n    \"\"\"Plugin for listing directive.\"\"\"\n\n    name = \"rest_listing\"\n\n    def set_site(self, site):\n        \"\"\"Set Nikola site.\"\"\"\n        self.site = site\n        # Even though listings don't use CodeBlock anymore, I am\n        # leaving these to make the code directive work with\n        # docutils < 0.9\n        CodeBlock.site = site\n        directives.register_directive('code', CodeBlock)\n        directives.register_directive('code-block', CodeBlock)\n        directives.register_directive('sourcecode', CodeBlock)\n        directives.register_directive('listing', Listing)\n        Listing.folders = site.config['LISTINGS_FOLDERS']\n        return super(Plugin, self).set_site(site)\n\n\n# Add sphinx compatibility option\nlisting_spec = Include.option_spec\nlisting_spec['linenos'] = directives.unchanged\n\n\nclass Listing(Include):\n\n    \"\"\"Create a highlighted block of code from a file in listings/.\n\n    Usage:\n\n        .. listing:: nikola.py python\n           :number-lines:\n\n    \"\"\"\n\n    has_content = False\n    required_arguments = 1\n    optional_arguments = 1\n    option_spec = listing_spec\n\n    def run(self):\n        \"\"\"Run listing directive.\"\"\"\n        _fname = self.arguments.pop(0)\n        fname = _fname.replace('/', os.sep)\n        lang = self.arguments.pop(0)\n        if len(self.folders) == 1:\n            listings_folder = next(iter(self.folders.keys()))\n            if fname.startswith(listings_folder):\n                fpath = os.path.join(fname)  # new syntax: specify folder name\n            else:\n                fpath = os.path.join(listings_folder, fname)  # old syntax: don't specify folder name\n        else:\n            fpath = os.path.join(fname)  # must be new syntax: specify folder name\n        self.arguments.insert(0, fpath)\n        self.options['code'] = lang\n        if 'linenos' in self.options:\n            self.options['number-lines'] = self.options['linenos']\n        with io.open(fpath, 'r+', encoding='utf8') as fileobject:\n            self.content = fileobject.read().splitlines()\n        self.state.document.settings.record_dependencies.add(fpath)\n        target = urlunsplit((\"link\", 'listing', fpath.replace('\\\\', '/'), '', ''))\n        generated_nodes = (\n            [core.publish_doctree('`{0} <{1}>`_'.format(_fname, target))[0]])\n        generated_nodes += self.get_code_from_file(fileobject)\n        return generated_nodes\n\n    def get_code_from_file(self, data):\n        \"\"\"Create CodeBlock nodes from file object content.\"\"\"\n        return super(Listing, self).run()\n\n    def assert_has_content(self):\n        \"\"\"Listing has no content, override check from superclass.\"\"\"\n        pass\n", "path": "nikola/plugins/compile/rest/listing.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\n# Copyright \u00a9 2012-2015 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\n\"\"\"Define and register a listing directive using the existing CodeBlock.\"\"\"\n\n\nfrom __future__ import unicode_literals\nimport io\nimport os\nimport uuid\ntry:\n    from urlparse import urlunsplit\nexcept ImportError:\n    from urllib.parse import urlunsplit  # NOQA\n\nimport docutils.parsers.rst.directives.body\nimport docutils.parsers.rst.directives.misc\nfrom docutils import core\nfrom docutils import nodes\nfrom docutils.parsers.rst import Directive, directives\nfrom docutils.parsers.rst.roles import set_classes\nfrom docutils.parsers.rst.directives.misc import Include\n\nfrom pygments.lexers import get_lexer_by_name\nimport pygments\nimport pygments.util\n\nfrom nikola import utils\nfrom nikola.plugin_categories import RestExtension\n\n\n# A sanitized version of docutils.parsers.rst.directives.body.CodeBlock.\nclass CodeBlock(Directive):\n\n    \"\"\"Parse and mark up content of a code block.\"\"\"\n\n    optional_arguments = 1\n    option_spec = {'class': directives.class_option,\n                   'name': directives.unchanged,\n                   'number-lines': directives.unchanged,  # integer or None\n                   'linenos': directives.unchanged,\n                   'tab-width': directives.nonnegative_int}\n    has_content = True\n\n    def run(self):\n        \"\"\"Run code block directive.\"\"\"\n        self.assert_has_content()\n\n        if 'linenos' in self.options:\n            self.options['number-lines'] = self.options['linenos']\n        if 'tab-width' in self.options:\n            self.content = [x.replace('\\t', ' ' * self.options['tab-width']) for x in self.content]\n\n        if self.arguments:\n            language = self.arguments[0]\n        else:\n            language = 'text'\n        set_classes(self.options)\n        classes = ['code']\n        if language:\n            classes.append(language)\n        if 'classes' in self.options:\n            classes.extend(self.options['classes'])\n\n        code = '\\n'.join(self.content)\n\n        try:\n            lexer = get_lexer_by_name(language)\n        except pygments.util.ClassNotFound:\n            raise self.error('Cannot find pygments lexer for language \"{0}\"'.format(language))\n\n        if 'number-lines' in self.options:\n            linenos = 'table'\n            # optional argument `startline`, defaults to 1\n            try:\n                linenostart = int(self.options['number-lines'] or 1)\n            except ValueError:\n                raise self.error(':number-lines: with non-integer start value')\n        else:\n            linenos = False\n            linenostart = 1  # actually unused\n\n        if self.site.invariant:  # for testing purposes\n            anchor_ref = 'rest_code_' + 'fixedvaluethatisnotauuid'\n        else:\n            anchor_ref = 'rest_code_' + uuid.uuid4().hex\n\n        formatter = utils.NikolaPygmentsHTML(anchor_ref=anchor_ref, classes=classes, linenos=linenos, linenostart=linenostart)\n        out = pygments.highlight(code, lexer, formatter)\n        node = nodes.raw('', out, format='html')\n\n        self.add_name(node)\n        # if called from \"include\", set the source\n        if 'source' in self.options:\n            node.attributes['source'] = self.options['source']\n\n        return [node]\n\n# Monkey-patch: replace insane docutils CodeBlock with our implementation.\ndocutils.parsers.rst.directives.body.CodeBlock = CodeBlock\ndocutils.parsers.rst.directives.misc.CodeBlock = CodeBlock\n\n\nclass Plugin(RestExtension):\n\n    \"\"\"Plugin for listing directive.\"\"\"\n\n    name = \"rest_listing\"\n\n    def set_site(self, site):\n        \"\"\"Set Nikola site.\"\"\"\n        self.site = site\n        # Even though listings don't use CodeBlock anymore, I am\n        # leaving these to make the code directive work with\n        # docutils < 0.9\n        CodeBlock.site = site\n        directives.register_directive('code', CodeBlock)\n        directives.register_directive('code-block', CodeBlock)\n        directives.register_directive('sourcecode', CodeBlock)\n        directives.register_directive('listing', Listing)\n        Listing.folders = site.config['LISTINGS_FOLDERS']\n        return super(Plugin, self).set_site(site)\n\n\n# Add sphinx compatibility option\nlisting_spec = Include.option_spec\nlisting_spec['linenos'] = directives.unchanged\n\n\nclass Listing(Include):\n\n    \"\"\"Create a highlighted block of code from a file in listings/.\n\n    Usage:\n\n        .. listing:: nikola.py python\n           :number-lines:\n\n    \"\"\"\n\n    has_content = False\n    required_arguments = 1\n    optional_arguments = 1\n    option_spec = listing_spec\n\n    def run(self):\n        \"\"\"Run listing directive.\"\"\"\n        _fname = self.arguments.pop(0)\n        fname = _fname.replace('/', os.sep)\n        try:\n            lang = self.arguments.pop(0)\n            self.options['code'] = lang\n        except IndexError:\n            self.options['literal'] = True\n\n        if len(self.folders) == 1:\n            listings_folder = next(iter(self.folders.keys()))\n            if fname.startswith(listings_folder):\n                fpath = os.path.join(fname)  # new syntax: specify folder name\n            else:\n                fpath = os.path.join(listings_folder, fname)  # old syntax: don't specify folder name\n        else:\n            fpath = os.path.join(fname)  # must be new syntax: specify folder name\n        self.arguments.insert(0, fpath)\n        if 'linenos' in self.options:\n            self.options['number-lines'] = self.options['linenos']\n        with io.open(fpath, 'r+', encoding='utf8') as fileobject:\n            self.content = fileobject.read().splitlines()\n        self.state.document.settings.record_dependencies.add(fpath)\n        target = urlunsplit((\"link\", 'listing', fpath.replace('\\\\', '/'), '', ''))\n        generated_nodes = (\n            [core.publish_doctree('`{0} <{1}>`_'.format(_fname, target))[0]])\n        generated_nodes += self.get_code_from_file(fileobject)\n        return generated_nodes\n\n    def get_code_from_file(self, data):\n        \"\"\"Create CodeBlock nodes from file object content.\"\"\"\n        return super(Listing, self).run()\n\n    def assert_has_content(self):\n        \"\"\"Listing has no content, override check from superclass.\"\"\"\n        pass\n", "path": "nikola/plugins/compile/rest/listing.py"}]}