chiark / gitweb /
m.code: take over the whole .. include:: directive.
authorVladimír Vondruš <mosra@centrum.cz>
Thu, 14 May 2020 09:02:25 +0000 (11:02 +0200)
committerVladimír Vondruš <mosra@centrum.cz>
Thu, 14 May 2020 12:14:44 +0000 (14:14 +0200)
Until now it was overriding it only if the :code: option was present,
but I need to extend it also for direct include, so copying over the
whole implementation from docutils. And removing the :encoding:,
:literal: and :name: options as I don't see any use for them nowadays.

doc/plugins/math-and-code.rst
plugins/m/code.py

index b99f1b5fb9a744c9a4e9dc98ef799c591b22b19c..904c893611b248c5cfd082d2772bbb4d6f2afcb3 100644 (file)
@@ -361,9 +361,14 @@ option to highlight lines; if you want to add additional CSS classes, use the
         }
 
 The builtin `include directive <http://docutils.sourceforge.net/docs/ref/rst/directives.html#include>`_
-is also patched to use the improved code directive. Simply specify external
-code snippets filename and set the language using the :rst:`:code:` option.
-All options of the :rst:`.. code::` directive are supported as well.
+is also patched to use the improved code directive, and:
+
+-   Drops the rarely useful :rst:`:encoding:`, :rst:`:literal:` and
+    :rst:`:name:` options
+
+Simply specify external code snippets filename and set the language using the
+:rst:`:code:` option. All options of the :rst:`.. code::` directive are
+supported as well.
 
 .. code-figure::
 
index 9142a9f2f12cb3608593a2c99f44b034cd9251bd..ccc09cd8f0dc38399b759c8b36aa2a9a6747d98c 100644 (file)
@@ -122,19 +122,22 @@ class Code(Directive):
 
 class Include(docutils.parsers.rst.directives.misc.Include):
     option_spec = {
-        **docutils.parsers.rst.directives.misc.Include.option_spec,
+        'code': directives.unchanged,
+        'tab-width': int,
+        'start-line': int,
+        'end-line': int,
+        'start-after': directives.unchanged_required,
+        'end-before': directives.unchanged_required,
+        'class': directives.class_option,
         'filters': directives.unchanged
     }
 
     def run(self):
         """
         Verbatim copy of docutils.parsers.rst.directives.misc.Include.run()
-        that just calls to our Code instead of builtin CodeBlock but otherwise
-        just passes it back to the parent implementation.
+        that just calls to our Code instead of builtin CodeBlock, and is
+        without the rarely useful :encoding:, :literal: and :name: options
         """
-        if not 'code' in self.options:
-            return docutils.parsers.rst.directives.misc.Include.run(self)
-
         source = self.state_machine.input_lines.source(
             self.lineno - self.state_machine.input_offset - 1)
         source_dir = os.path.dirname(os.path.abspath(source))
@@ -144,15 +147,12 @@ class Include(docutils.parsers.rst.directives.misc.Include):
         path = os.path.normpath(os.path.join(source_dir, path))
         path = utils.relative_path(None, path)
         path = nodes.reprunicode(path)
-        encoding = self.options.get(
-            'encoding', self.state.document.settings.input_encoding)
         e_handler=self.state.document.settings.input_encoding_error_handler
         tab_width = self.options.get(
             'tab-width', self.state.document.settings.tab_width)
         try:
             self.state.document.settings.record_dependencies.add(path)
             include_file = io.FileInput(source_path=path,
-                                        encoding=encoding,
                                         error_handler=e_handler)
         except UnicodeEncodeError as error:
             raise self.severe('Problems with "%s" directive path:\n'
@@ -194,18 +194,23 @@ class Include(docutils.parsers.rst.directives.misc.Include):
 
         include_lines = statemachine.string2lines(rawtext, tab_width,
                                                   convert_whitespace=True)
-
-        self.options['source'] = path
-        codeblock = Code(self.name,
-                            [self.options.pop('code')], # arguments
-                            self.options,
-                            include_lines, # content
-                            self.lineno,
-                            self.content_offset,
-                            self.block_text,
-                            self.state,
-                            self.state_machine)
-        return codeblock.run()
+        if 'code' in self.options:
+            self.options['source'] = path
+            # Don't convert tabs to spaces, if `tab_width` is negative:
+            if tab_width < 0:
+                include_lines = rawtext.splitlines()
+            codeblock = Code(self.name,
+                                  [self.options.pop('code')], # arguments
+                                  self.options,
+                                  include_lines, # content
+                                  self.lineno,
+                                  self.content_offset,
+                                  self.block_text,
+                                  self.state,
+                                  self.state_machine)
+            return codeblock.run()
+        self.state_machine.insert_input(include_lines, path)
+        return []
 
 def code(role, rawtext, text, lineno, inliner, options={}, content=[]):
     # In order to properly preserve backslashes (well, and backticks)