in doc/src/sphinx/exts/includecode.py [0:0]
def run(self):
document = self.state.document
arg0 = self.arguments[0]
(filename, sep, section) = arg0.partition('#')
if not document.settings.file_insertion_enabled:
return [document.reporter.warning('File insertion disabled',
line=self.lineno)]
env = document.settings.env
if filename.startswith('/') or filename.startswith(os.sep):
rel_fn = filename[1:]
else:
docdir = path.dirname(env.doc2path(env.docname, base=None))
rel_fn = path.join(docdir, filename)
try:
fn = path.join(env.srcdir, rel_fn)
except UnicodeDecodeError:
# the source directory is a bytestring with non-ASCII characters;
# let's try to encode the rel_fn in the file system encoding
rel_fn = rel_fn.encode(sys.getfilesystemencoding())
fn = path.join(env.srcdir, rel_fn)
encoding = self.options.get('encoding', env.config.source_encoding)
codec_info = codecs.lookup(encoding)
try:
f = codecs.StreamReaderWriter(open(fn, 'Ub'),
codec_info[2], codec_info[3], 'strict')
lines = f.readlines()
f.close()
except (IOError, OSError):
return [document.reporter.warning(
'Include file %r not found or reading it failed' % filename,
line=self.lineno)]
except UnicodeError:
return [document.reporter.warning(
'Encoding %r used for reading included file %r seems to '
'be wrong, try giving an :encoding: option' %
(encoding, filename))]
comment = self.options.get('comment', '//')
endcomment = self.options.get('endcomment', '')
marker = self.options.get('marker', comment + '#')
len_marker = len(marker)
len_end_comment = len(endcomment)
if not section:
section = self.options.get('section')
include_sections = self.options.get('include', '')
exclude_sections = self.options.get('exclude', '')
include = set(include_sections.split(',')) if include_sections else set()
exclude = set(exclude_sections.split(',')) if exclude_sections else set()
hideexcludes = 'hideexcludes' in self.options
if section:
include |= set([section])
within = set()
res = []
excluding = False
for line in lines:
index = line.find(marker)
if index >= 0:
start_section = index + len_marker
if len_end_comment > 0:
end_section = -1 * (len_end_comment + 1) # + 1 for newline
section_name = line[start_section:end_section].strip()
else:
section_name = line[start_section:].strip()
if section_name in within:
within ^= set([section_name])
if excluding and not (exclude & within):
excluding = False
else:
within |= set([section_name])
if not excluding and (exclude & within):
excluding = True
if not hideexcludes:
res.append(' ' * index + comment + ' ' + section_name.replace('-', ' ') + ' ...\n')
elif not (exclude & within) and (not include or (include & within)):
res.append(line)
lines = res
def countwhile(predicate, iterable):
count = 0
for x in iterable:
if predicate(x):
count += 1
else:
return count
nonempty = [l for l in lines if l.strip()]
tabcounts = [countwhile(lambda c: c == ' ', l) for l in nonempty]
tabshift = min(tabcounts) if tabcounts else 0
if tabshift > 0:
lines = [l[tabshift:] if len(l) > tabshift else l for l in lines]
prepend = self.options.get('prepend')
append = self.options.get('append')
if prepend:
lines.insert(0, prepend + '\n')
if append:
lines.append(append + '\n')
text = ''.join(lines)
retnode = nodes.literal_block(text, text, source=fn)
retnode.line = 1
retnode.attributes['line_number'] = self.lineno
language = self.options.get('language')
if language:
retnode['language'] = language
if 'linenos' in self.options:
retnode['linenos'] = True
document.settings.env.note_dependency(rel_fn)
return [retnode]