Slicer  5.0
Slicer is a multi-platform, free and open source software package for visualization and medical image computing
workaround_recommonmark_issue_191.py
Go to the documentation of this file.
1 import os
2 
3 from docutils import nodes, io, utils
4 from docutils.parsers import rst
5 from docutils.core import ErrorString
6 from docutils.utils import SafeString
7 
8 from recommonmark.parser import CommonMarkParser
9 
10 
11 class MdInclude(rst.Directive):
12  """Directive class to include markdown in sphinx.
13  Load a file and convert it to rst and insert as a node. Currently
14  directive-specific options are not implemented.
15  See https://github.com/sphinx-doc/sphinx/issues/7000
16  and https://github.com/readthedocs/recommonmark/issues/191
17  """
18  required_arguments = 1
19  optional_arguments = 0
20  option_spec = {
21  'start-line': int,
22  'end-line': int,
23  }
24 
25  def run(self):
26  """Most of this method is from ``docutils.parser.rst.Directive``.
27  docutils version: 0.12
28  """
29  if not self.state.document.settings.file_insertion_enabled:
30  raise self.warning('"%s" directive disabled.' % self.name)
31  source = self.state_machine.input_lines.source(
32  self.lineno - self.state_machine.input_offset - 1)
33  source_dir = os.path.dirname(os.path.abspath(source))
34  path = rst.directives.path(self.arguments[0])
35  path = os.path.normpath(os.path.join(source_dir, path))
36  path = utils.relative_path(None, path)
37  path = nodes.reprunicode(path)
38 
39  # get options (currently not use directive-specific options)
40  encoding = self.options.get(
41  'encoding', self.state.document.settings.input_encoding)
42  e_handler = self.state.document.settings.input_encoding_error_handler
43 
44  # open the including file
45  try:
46  self.state.document.settings.record_dependencies.add(path)
47  include_file = io.FileInput(source_path=path,
48  encoding=encoding,
49  error_handler=e_handler)
50  except UnicodeEncodeError:
51  raise self.severe('Problems with "%s" directive path:\n'
52  'Cannot encode input file path "%s" '
53  '(wrong locale?).' %
54  (self.name, SafeString(path)))
55  except OSError as error:
56  raise self.severe('Problems with "%s" directive path:\n%s.' %
57  (self.name, ErrorString(error)))
58 
59  # read from the file
60  startline = self.options.get('start-line', None)
61  endline = self.options.get('end-line', None)
62  try:
63  if startline or (endline is not None):
64  lines = include_file.readlines()
65  rawtext = ''.join(lines[startline:endline])
66  else:
67  rawtext = include_file.read()
68  except UnicodeError as error:
69  raise self.severe('Problem with "%s" directive:\n%s' %
70  (self.name, ErrorString(error)))
71 
72  class CustomCommonMarkParser(CommonMarkParser):
73  """Temporary workaround to remove multiple build warnings caused by upstream bug.
74  See https://github.com/readthedocs/recommonmark/issues/177 for details.
75  """
76 
77  def visit_document(self, node):
78  pass
79 
80  doc = utils.new_document(self.arguments[0])
81  md_parser = CustomCommonMarkParser()
82  md_parser.parse(rawtext, doc)
83  return [*doc.children]
84 
85 
86 def setup(app):
87  app.add_directive("mdinclude", MdInclude)
88 
89  return {
90  'version': '0.1',
91  'parallel_read_safe': True,
92  'parallel_write_safe': True,
93  }