Example #1
0
    def run(self):
        document = self.state.document
        filename = self.arguments[0]
        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.normpath(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)

        if 'pyobject' in self.options and 'lines' in self.options:
            return [document.reporter.warning(
                'Cannot use both "pyobject" and "lines" options',
                line=self.lineno)]

        encoding = self.options.get('encoding', env.config.source_encoding)
        try:
            f = codecs.open(fn, 'rU', encoding)
            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))]

        objectname = self.options.get('pyobject')
        if objectname is not None:
            from sphinx.pycode import ModuleAnalyzer
            analyzer = ModuleAnalyzer.for_file(fn, '')
            tags = analyzer.find_tags()
            if objectname not in tags:
                return [document.reporter.warning(
                    'Object named %r not found in include file %r' %
                    (objectname, filename), line=self.lineno)]
            else:
                lines = lines[tags[objectname][1]-1 : tags[objectname][2]-1]

        linespec = self.options.get('lines')
        if linespec is not None:
            try:
                linelist = parselinenos(linespec, len(lines))
            except ValueError, err:
                return [document.reporter.warning(str(err), line=self.lineno)]
            lines = [lines[i] for i in linelist]
Example #2
0
    def run(self):
        document = self.state.document
        if not document.settings.file_insertion_enabled:
            return [document.reporter.warning('File insertion disabled',
                                              line=self.lineno)]
        env = document.settings.env
        rel_filename, filename = env.relfn2path(self.arguments[0])

        if 'pyobject' in self.options and 'lines' in self.options:
            return [document.reporter.warning(
                'Cannot use both "pyobject" and "lines" options',
                line=self.lineno)]

        encoding = self.options.get('encoding', env.config.source_encoding)
        codec_info = codecs.lookup(encoding)
        f = None
        try:
            f = codecs.StreamReaderWriter(open(filename, 'rb'),
                    codec_info[2], codec_info[3], 'strict')
            lines = f.readlines()
        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))]
        finally:
            if f is not None:
                f.close()

        objectname = self.options.get('pyobject')
        if objectname is not None:
            from sphinx.pycode import ModuleAnalyzer
            analyzer = ModuleAnalyzer.for_file(filename, '')
            tags = analyzer.find_tags()
            if objectname not in tags:
                return [document.reporter.warning(
                    'Object named %r not found in include file %r' %
                    (objectname, filename), line=self.lineno)]
            else:
                lines = lines[tags[objectname][1]-1 : tags[objectname][2]-1]

        linespec = self.options.get('lines')
        if linespec is not None:
            try:
                linelist = parselinenos(linespec, len(lines))
            except ValueError, err:
                return [document.reporter.warning(str(err), line=self.lineno)]
            # just ignore nonexisting lines
            nlines = len(lines)
            lines = [lines[i] for i in linelist if i < nlines]
            if not lines:
                return [document.reporter.warning(
                    'Line spec %r: no lines pulled from include file %r' %
                    (linespec, filename), line=self.lineno)]
Example #3
0
  def create_node(self, filename, rel_filename, lang):
    document = self.state.document
    env = document.settings.env

    # Read the contents of the file to include
    encoding = self.options.get('encoding', env.config.source_encoding)
    codec_info = codecs.lookup(encoding)

    try:
      f = codecs.StreamReaderWriter(open(filename, 'rb'),
          codec_info[2], codec_info[3], 'strict')
      lines = f.readlines()
      f.close()
    except (IOError, OSError):
      print_err('Failed to read %r' % filename)
      return [document.reporter.warning(
        'Include file %r not found or reading it failed' % filename,
        line=self.lineno)]
    except UnicodeError:
      print_err('Encoding %r used for reading included file %r seems to '
        'be wrong, try giving an :encoding: option' %
        (encoding, filename))
      return [document.reporter.warning(
        'Encoding %r used for reading included file %r seems to '
        'be wrong, try giving an :encoding: option' %
        (encoding, filename))]

    objectname = self.options.get('pyobject')

    if objectname is not None:
      from sphinx.pycode import ModuleAnalyzer
      analyzer = ModuleAnalyzer.for_file(filename, '')
      tags = analyzer.find_tags()

      if objectname not in tags:
        return [document.reporter.warning(
          'Object named %r not found in include file %r' %
          (objectname, filename), line=self.lineno)]
      else:
        lines = lines[tags[objectname][1]-1 : tags[objectname][2]-1]

    linespec = self.options.get('lines')
    if linespec is not None:
      try:
        linelist = parselinenos(linespec, len(lines))
      except ValueError, err:
        return [document.reporter.warning(str(err), line=self.lineno)]

      # just ignore nonexisting lines
      nlines = len(lines)
      lines = [lines[i] for i in linelist if i < nlines]

      if not lines:
        return [document.reporter.warning(
          'Line spec %r: no lines pulled from include file %r' %
          (linespec, filename), line=self.lineno)]
Example #4
0
def test_ModuleAnalyzer_for_file_in_egg(rootdir):
    try:
        path = rootdir / 'test-pycode-egg' / 'sample-0.0.0-py3.7.egg'
        sys.path.insert(0, path)

        import sample
        analyzer = ModuleAnalyzer.for_file(sample.__file__, 'sample')
        docs = analyzer.find_attr_docs()
        assert docs == {('', 'CONSTANT'): ['constant on sample.py', '']}
    finally:
        sys.path.pop(0)
def literalinclude_directive(name, arguments, options, content, lineno,
                             content_offset, block_text, state, state_machine):
    """Like .. include:: :literal:, but only warns if the include file is not found."""
    if not state.document.settings.file_insertion_enabled:
        return [state.document.reporter.warning('File insertion disabled', line=lineno)]
    env = state.document.settings.env
    rel_fn = arguments[0]
    source_dir = path.dirname(path.abspath(state_machine.input_lines.source(
        lineno - state_machine.input_offset - 1)))
    fn = path.normpath(path.join(source_dir, rel_fn))

    if 'pyobject' in options and 'lines' in options:
        return [state.document.reporter.warning(
            'Cannot use both "pyobject" and "lines" options', line=lineno)]

    encoding = options.get('encoding', env.config.source_encoding)
    try:
        f = codecs.open(fn, 'r', encoding)
        #f = open(fn, 'rb')
        lines = f.readlines()
        f.close()
    except (IOError, OSError):
        return [state.document.reporter.warning(
            'Include file %r not found or reading it failed' % arguments[0],
            line=lineno)]
    except UnicodeError:
        return [state.document.reporter.warning(
            'Encoding %r used for reading included file %r seems to '
            'be wrong, try giving an :encoding: option' %
            (encoding, arguments[0]))]

    objectname = options.get('pyobject')
    if objectname is not None:
        from sphinx.pycode import ModuleAnalyzer
        analyzer = ModuleAnalyzer.for_file(fn, '')
        tags = analyzer.find_tags()
        if objectname not in tags:
            return [state.document.reporter.warning(
                'Object named %r not found in include file %r' %
                (objectname, arguments[0]), line=lineno)]
        else:
            lines = lines[tags[objectname][1] - 1 : tags[objectname][2] - 1]

    linespec = options.get('lines')
    if linespec is not None:
        try:
            linelist = parselinenos(linespec, len(lines))
        except ValueError, err:
            return [state.document.reporter.warning(str(err), line=lineno)]
        lines = [lines[i] for i in linelist]
Example #6
0
File: code.py Project: LFYG/sphinx
    def pyobject_filter(self, lines, location=None):
        # type: (List[unicode], Any) -> List[unicode]
        pyobject = self.options.get('pyobject')
        if pyobject:
            from sphinx.pycode import ModuleAnalyzer
            analyzer = ModuleAnalyzer.for_file(self.filename, '')
            tags = analyzer.find_tags()
            if pyobject not in tags:
                raise ValueError(__('Object named %r not found in include file %r') %
                                 (pyobject, self.filename))
            else:
                start = tags[pyobject][1]
                end = tags[pyobject][2]
                lines = lines[start - 1:end]
                if 'lineno-match' in self.options:
                    self.lineno_start = start

        return lines
Example #7
0
    def run(self):
        document = self.state.document
        if not document.settings.file_insertion_enabled:
            return [document.reporter.warning('File insertion disabled',
                                              line=self.lineno)]
        env = document.settings.env
        rel_filename, filename = env.relfn2path(self.arguments[0])

        if 'pyobject' in self.options and 'lines' in self.options:
            return [document.reporter.warning(
                'Cannot use both "pyobject" and "lines" options',
                line=self.lineno)]

        encoding = self.options.get('encoding', env.config.source_encoding)
        codec_info = codecs.lookup(encoding)
        f = None
        try:
            f = codecs.StreamReaderWriter(open(filename, 'rb'),
                    codec_info[2], codec_info[3], 'strict')
            lines = f.readlines()
            if 'dedent' in self.options:
                for i in range(0, len(lines)):
                    if len(lines[i]) <= self.options['dedent']:
                        lines[i] = lines[i][len(lines[i]) - 1:]
                    else:
                        lines[i] = lines[i][self.options['dedent']:]
        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))]
        finally:
            if f is not None:
                f.close()

        objectname = self.options.get('pyobject')
        if objectname is not None:
            from sphinx.pycode import ModuleAnalyzer
            analyzer = ModuleAnalyzer.for_file(filename, '')
            tags = analyzer.find_tags()
            if objectname not in tags:
                return [document.reporter.warning(
                    'Object named %r not found in include file %r' %
                    (objectname, filename), line=self.lineno)]
            else:
                lines = lines[tags[objectname][1]-1 : tags[objectname][2]-1]

        linespec = self.options.get('lines')
        if linespec is not None:
            try:
                linelist = parselinenos(linespec, len(lines))
            except ValueError as err:
                return [document.reporter.warning(str(err), line=self.lineno)]
            # just ignore nonexisting lines
            nlines = len(lines)
            lines = [lines[i] for i in linelist if i < nlines]
            if not lines:
                return [document.reporter.warning(
                    'Line spec %r: no lines pulled from include file %r' %
                    (linespec, filename), line=self.lineno)]

        linespec = self.options.get('emphasize-lines')
        if linespec:
            try:
                hl_lines = [x+1 for x in parselinenos(linespec, len(lines))]
            except ValueError as err:
                return [document.reporter.warning(str(err), line=self.lineno)]
        else:
            hl_lines = None

        startafter = self.options.get('start-after')
        endbefore  = self.options.get('end-before')
        prepend    = self.options.get('prepend')
        append     = self.options.get('append')
        if startafter is not None or endbefore is not None:
            use = not startafter
            res = []
            for line in lines:
                if not use and startafter and startafter in line:
                    use = True
                elif use and endbefore and endbefore in line:
                    use = False
                    break
                elif use:
                    res.append(line)
            lines = res

        if prepend:
           lines.insert(0, prepend + '\n')
        if append:
           lines.append(append + '\n')

        text = ''.join(lines)
        if self.options.get('tab-width'):
            text = text.expandtabs(self.options['tab-width'])
        retnode = nodes.literal_block(text, text, source=filename)
        set_source_info(self, retnode)
        if self.options.get('language', ''):
            retnode['language'] = self.options['language']
        retnode['linenos'] = 'linenos' in self.options or \
                             'lineno-start' in self.options
        filename = self.options.get('filename')
        if filename is not None:
            if not filename:
                filename = self.arguments[0]
            retnode['filename'] = filename
        extra_args = retnode['highlight_args'] = {}
        if hl_lines is not None:
            extra_args['hl_lines'] = hl_lines
        if 'lineno-start' in self.options:
            extra_args['linenostart'] = self.options['lineno-start']
        env.note_dependency(rel_filename)
        return [retnode]
Example #8
0
    def run(self):
        document = self.state.document
        if not document.settings.file_insertion_enabled:
            return [document.reporter.warning("File insertion disabled", line=self.lineno)]
        env = document.settings.env
        rel_filename, filename = env.relfn2path(
            os.path.join("/" + env.config.includefrags_base_dir, self.arguments[0])
        )  ## !!!

        if "pyobject" in self.options and "lines" in self.options:
            return [document.reporter.warning('Cannot use both "pyobject" and "lines" options', line=self.lineno)]

        encoding = self.options.get("encoding", env.config.source_encoding)
        codec_info = codecs.lookup(encoding)
        f = None
        try:
            f = codecs.StreamReaderWriter(open(filename, "rb"), codec_info[2], codec_info[3], "strict")
            lines = f.readlines()
        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)
                )
            ]
        finally:
            if f is not None:
                f.close()

        objectname = self.options.get("pyobject")
        if objectname is not None:
            from sphinx.pycode import ModuleAnalyzer

            analyzer = ModuleAnalyzer.for_file(filename, "")
            tags = analyzer.find_tags()
            if objectname not in tags:
                return [
                    document.reporter.warning(
                        "Object named %r not found in include file %r" % (objectname, filename), line=self.lineno
                    )
                ]
            else:
                lines = lines[tags[objectname][1] - 1 : tags[objectname][2] - 1]

        fragment = self.options.get("fragment")
        if fragment is not None:
            active = False
            needle = "FRAGMENT(%s)" % fragment
            result = []
            for line in lines:
                if "FRAGMENT(" in line and needle not in line:
                    active = False
                elif needle in line:
                    active = True
                    continue
                if active:
                    result.append(line)
            while result and not result[-1].strip():
                result.pop()
            lines = result

        linespec = self.options.get("lines")
        if linespec is not None:
            try:
                linelist = parselinenos(linespec, len(lines))
            except ValueError, err:
                return [document.reporter.warning(str(err), line=self.lineno)]
            # just ignore nonexisting lines
            nlines = len(lines)
            lines = [lines[i] for i in linelist if i < nlines]
            if not lines:
                return [
                    document.reporter.warning(
                        "Line spec %r: no lines pulled from include file %r" % (linespec, filename), line=self.lineno
                    )
                ]
def run(self):
    document = self.state.document
    filename = self.arguments[0]
    #print filename
    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.normpath(path.join(docdir, filename))
    fn = path.join(env.srcdir, rel_fn)

    if 'pyobject' in self.options and 'lines' in self.options:
        return [document.reporter.warning(
            'Cannot use both "pyobject" and "lines" options',
            line=self.lineno)]

    encoding = self.options.get('encoding', env.config.source_encoding)
    try:
        f = codecs.open(fn, 'rU', encoding)
        lines = f.readlines()
        f.close()
        # 去掉编码指示
        if fn.endswith(".py") and lines[0].startswith("#") and "coding" in lines[0]:
            lines = lines[1:]
        # 去掉文档说明
        if fn.endswith(".py"):
            if lines[0].startswith('"""'):
                for lineno, line in enumerate(lines[1:]):
                    if line.strip().endswith('"""'):
                        lines = lines[lineno+2:]
                        break
        # 去掉每行末尾空格
        for i in range(len(lines)):
            lines[i] = lines[i].rstrip() + "\n"
        
    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))]

    objectname = self.options.get('pyobject')
    if objectname is not None:
        from sphinx.pycode import ModuleAnalyzer
        analyzer = ModuleAnalyzer.for_file(fn, '')
        tags = analyzer.find_tags()
        if objectname not in tags:
            return [document.reporter.warning(
                'Object named %r not found in include file %r' %
                (objectname, filename), line=self.lineno)]
        else:
            lines = lines[tags[objectname][1]-1 : tags[objectname][2]-1]

    linespec = self.options.get('lines')
    if linespec is not None:
        try:
            linelist = parselinenos(linespec, len(lines))
        except (ValueError, err):
            return [document.reporter.warning(str(err), line=self.lineno)]
        lines = [lines[i] for i in linelist]

    startafter = self.options.get('start-after')
    endbefore = self.options.get('end-before')
    if startafter is not None or endbefore is not None:
        use = not startafter
        res = []
        for line in lines:
            if not use and startafter in line:
                use = True
            elif use and endbefore in line:
                use = False
                break
            elif use:
                res.append(line)
        lines = res
        
    section = self.options.get("section")
    if section is not None:
        section = "###%s###" % section
        print (section)
        use = False
        res = []
        for line in lines:
            if not use and section in line:
                use = True
                continue
            elif use and section in line:
                use = False
                break
            if use:
                res.append(line)
        lines = res
        indent = len(lines[0]) - len(lines[0].lstrip())
        for i,line in enumerate(lines):
            lines[i] = line[indent:]
      
    text = replace_number_label(''.join(lines))
    text = re.sub(r"(?s)#<\?(.*?)>.+?#<\?/>", lambda mo:u"#<?>%s" % mo.group(1), text)
    #text = (u"#程序文件:%s\n" % filename) + text
    retnode = nodes.literal_block(text, text, source=fn)
    retnode.line = 1
    if self.options.get('language', ''):
        retnode['language'] = self.options['language']
    if 'linenos' in self.options:
        retnode['linenos'] = True
    document.settings.env.note_dependency(rel_fn)
    #print "LiteralInclude hacked"
    return [retnode]    
Example #10
0
def _view_source_node(env, text, state):
    # pretend we're using viewcode fully,
    # install the context it looks for
    if not hasattr(env, '_viewcode_modules'):
        env._viewcode_modules = {}

    modname = text
    text = modname.split(".")[-1] + ".py"

    # imitate sphinx .<modname> syntax
    if modname.startswith("."):
        # see if the modname needs to be corrected in terms
        # of current module context
        base_module = env.temp_data.get('autodoc:module')
        if base_module is None:
            base_module = env.temp_data.get('py:module')

        if base_module:
            modname = base_module + modname

    urito = env.app.builder.get_relative_uri

    # we're showing code examples which may have dependencies
    # which we really don't want to have required so load the
    # module by file, not import (though we are importing)
    # the top level module here...
    pathname = None
    for token in modname.split("."):
        file_, pathname, desc = imp.find_module(token, [pathname] if pathname else None)
        if file_:
            file_.close()

    # unlike viewcode which silently traps exceptions,
    # I want this to totally barf if the file can't be loaded.
    # a failed build better than a complete build missing
    # key content
    analyzer = ModuleAnalyzer.for_file(pathname, modname)
    # copied from viewcode
    analyzer.find_tags()
    if not isinstance(analyzer.code, text_type):
        code = analyzer.code.decode(analyzer.encoding)
    else:
        code = analyzer.code

    if state is not None:
        docstring = _find_mod_docstring(analyzer)
        if docstring:
            # get rid of "foo.py" at the top
            docstring = re.sub(r"^[a-zA-Z_0-9]+\.py", "", docstring)

            # strip
            docstring = docstring.strip()

            # yank only first paragraph
            docstring = docstring.split("\n\n")[0].strip()
    else:
        docstring = None

    entry = code, analyzer.tags, {}
    env._viewcode_modules[modname] = entry
    pagename = '_modules/' + modname.replace('.', '/')

    try:
        refuri = urito(env.docname, pagename)
    except NoUri:
        # if we're in the latex builder etc., this seems
        # to be what we get
        refuri = None


    if docstring:
        # embed the ref with the doc text so that it isn't
        # a separate paragraph
        if refuri:
            docstring = "`%s <%s>`_ - %s" % (text, refuri, docstring)
        else:
            docstring = "``%s`` - %s" % (text, docstring)
        para = nodes.paragraph('', '')
        state.nested_parse(StringList([docstring]), 0, para)
        return_node = para
    else:
        if refuri:
            refnode = nodes.reference('', '',
                    nodes.Text(text, text),
                    refuri=urito(env.docname, pagename)
                )
        else:
            refnode = nodes.Text(text, text)

        if state:
            return_node = nodes.paragraph('', '', refnode)
        else:
            return_node = refnode

    return return_node
Example #11
0
def literalinclude_directive(name, arguments, options, content, lineno,
                             content_offset, block_text, state, state_machine):
    """Like .. include:: :literal:, but only warns if the include file is not found."""
    if not state.document.settings.file_insertion_enabled:
        return [
            state.document.reporter.warning('File insertion disabled',
                                            line=lineno)
        ]
    env = state.document.settings.env
    rel_fn = arguments[0]
    source_dir = path.dirname(
        path.abspath(
            state_machine.input_lines.source(lineno -
                                             state_machine.input_offset - 1)))
    fn = path.normpath(path.join(source_dir, rel_fn))

    if 'pyobject' in options and 'lines' in options:
        return [
            state.document.reporter.warning(
                'Cannot use both "pyobject" and "lines" options', line=lineno)
        ]

    encoding = options.get('encoding', env.config.source_encoding)
    try:
        f = codecs.open(fn, 'r', encoding)
        #f = open(fn, 'rb')
        lines = f.readlines()
        f.close()
    except (IOError, OSError):
        return [
            state.document.reporter.warning(
                'Include file %r not found or reading it failed' %
                arguments[0],
                line=lineno)
        ]
    except UnicodeError:
        return [
            state.document.reporter.warning(
                'Encoding %r used for reading included file %r seems to '
                'be wrong, try giving an :encoding: option' %
                (encoding, arguments[0]))
        ]

    objectname = options.get('pyobject')
    if objectname is not None:
        from sphinx.pycode import ModuleAnalyzer
        analyzer = ModuleAnalyzer.for_file(fn, '')
        tags = analyzer.find_tags()
        if objectname not in tags:
            return [
                state.document.reporter.warning(
                    'Object named %r not found in include file %r' %
                    (objectname, arguments[0]),
                    line=lineno)
            ]
        else:
            lines = lines[tags[objectname][1] - 1:tags[objectname][2] - 1]

    linespec = options.get('lines')
    if linespec is not None:
        try:
            linelist = parselinenos(linespec, len(lines))
        except ValueError, err:
            return [state.document.reporter.warning(str(err), line=lineno)]
        lines = [lines[i] for i in linelist]
Example #12
0
    def run(self):
        document = self.state.document
        if not document.settings.file_insertion_enabled:
            return [document.reporter.warning('File insertion disabled',
                                              line=self.lineno)]
        env = document.settings.env
        rel_filename, filename = env.relfn2path(os.path.join(
            '/' + env.config.includefrags_base_dir, self.arguments[0])) ## !!!

        if 'pyobject' in self.options and 'lines' in self.options:
            return [document.reporter.warning(
                'Cannot use both "pyobject" and "lines" options',
                line=self.lineno)]

        encoding = self.options.get('encoding', env.config.source_encoding)
        codec_info = codecs.lookup(encoding)
        f = None
        try:
            f = codecs.StreamReaderWriter(open(filename, 'rb'),
                    codec_info[2], codec_info[3], 'strict')
            lines = f.readlines()
        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))]
        finally:
            if f is not None:
                f.close()

        objectname = self.options.get('pyobject')
        if objectname is not None:
            from sphinx.pycode import ModuleAnalyzer
            analyzer = ModuleAnalyzer.for_file(filename, '')
            tags = analyzer.find_tags()
            if objectname not in tags:
                return [document.reporter.warning(
                    'Object named %r not found in include file %r' %
                    (objectname, filename), line=self.lineno)]
            else:
                lines = lines[tags[objectname][1]-1 : tags[objectname][2]-1]

        fragment = self.options.get('fragment')
        if fragment is not None:
            result = []
            key = None
            active = False
            for line in lines:
                line = line.rstrip()  # Strip line ending and trailing whitespace.
                line += '\n' # add back line ending
                if line.strip().startswith('//![') and line.strip().endswith(']'):
                    key = line.strip()[4:-1].strip()
                    if key == fragment:
                        active = not active
                        continue
                if active:
                    result.append(line)
            while result and not result[-1].strip():
                result.pop()
            lines = result

        linespec = self.options.get('lines')
        if linespec is not None:
            try:
                linelist = parselinenos(linespec, len(lines))
            except ValueError, err:
                return [document.reporter.warning(str(err), line=self.lineno)]
            # just ignore nonexisting lines
            nlines = len(lines)
            lines = [lines[i] for i in linelist if i < nlines]
            if not lines:
                return [document.reporter.warning(
                    'Line spec %r: no lines pulled from include file %r' %
                    (linespec, filename), line=self.lineno)]
Example #13
0
    def run(self):
        document = self.state.document
        if not document.settings.file_insertion_enabled:
            return [document.reporter.warning("File insertion disabled", line=self.lineno)]
        env = document.settings.env
        rel_filename, filename = env.relfn2path(self.arguments[0])

        if "pyobject" in self.options and "lines" in self.options:
            return [document.reporter.warning('Cannot use both "pyobject" and "lines" options', line=self.lineno)]

        encoding = self.options.get("encoding", env.config.source_encoding)
        codec_info = codecs.lookup(encoding)
        f = None
        try:
            f = codecs.StreamReaderWriter(open(filename, "rb"), codec_info[2], codec_info[3], "strict")
            lines = f.readlines()
        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)
                )
            ]
        finally:
            if f is not None:
                f.close()

        objectname = self.options.get("pyobject")
        if objectname is not None:
            from sphinx.pycode import ModuleAnalyzer

            analyzer = ModuleAnalyzer.for_file(filename, "")
            tags = analyzer.find_tags()
            if objectname not in tags:
                return [
                    document.reporter.warning(
                        "Object named %r not found in include file %r" % (objectname, filename), line=self.lineno
                    )
                ]
            else:
                lines = lines[tags[objectname][1] - 1 : tags[objectname][2] - 1]

        linespec = self.options.get("lines")
        if linespec is not None:
            try:
                linelist = parselinenos(linespec, len(lines))
            except ValueError as err:
                return [document.reporter.warning(str(err), line=self.lineno)]
            # just ignore nonexisting lines
            nlines = len(lines)
            lines = [lines[i] for i in linelist if i < nlines]
            if not lines:
                return [
                    document.reporter.warning(
                        "Line spec %r: no lines pulled from include file %r" % (linespec, filename), line=self.lineno
                    )
                ]

        linespec = self.options.get("emphasize-lines")
        if linespec:
            try:
                hl_lines = [x + 1 for x in parselinenos(linespec, len(lines))]
            except ValueError as err:
                return [document.reporter.warning(str(err), line=self.lineno)]
        else:
            hl_lines = None

        startafter = self.options.get("start-after")
        endbefore = self.options.get("end-before")
        prepend = self.options.get("prepend")
        append = self.options.get("append")
        if startafter is not None or endbefore is not None:
            use = not startafter
            res = []
            for line in lines:
                if not use and startafter and startafter in line:
                    use = True
                elif use and endbefore and endbefore in line:
                    use = False
                    break
                elif use:
                    res.append(line)
            lines = res

        if prepend:
            lines.insert(0, prepend + "\n")
        if append:
            lines.append(append + "\n")

        text = "".join(lines)
        if self.options.get("tab-width"):
            text = text.expandtabs(self.options["tab-width"])
        retnode = nodes.literal_block(text, text, source=filename)
        set_source_info(self, retnode)
        if self.options.get("language", ""):
            retnode["language"] = self.options["language"]
        if "linenos" in self.options:
            retnode["linenos"] = True
        if hl_lines is not None:
            retnode["highlight_args"] = {"hl_lines": hl_lines}
        env.note_dependency(rel_filename)
        return [retnode]
Example #14
0
    def run(self):
        document = self.state.document
        filename = self.arguments[0]
        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)

        if 'pyobject' in self.options and 'lines' in self.options:
            return [document.reporter.warning(
                'Cannot use both "pyobject" and "lines" options',
                line=self.lineno)]

        encoding = self.options.get('encoding', env.config.source_encoding)
        codec_info = codecs.lookup(encoding)
        try:
            f = codecs.StreamReaderWriter(open(fn, 'U'),
                    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))]

        objectname = self.options.get('pyobject')
        if objectname is not None:
            from sphinx.pycode import ModuleAnalyzer
            analyzer = ModuleAnalyzer.for_file(fn, '')
            tags = analyzer.find_tags()
            if objectname not in tags:
                return [document.reporter.warning(
                    'Object named %r not found in include file %r' %
                    (objectname, filename), line=self.lineno)]
            else:
                lines = lines[tags[objectname][1]-1 : tags[objectname][2]-1]

        linespec = self.options.get('lines')
        if linespec is not None:
            try:
                linelist = parselinenos(linespec, len(lines))
            except ValueError, err:
                return [document.reporter.warning(str(err), line=self.lineno)]
            lines = [lines[i] for i in linelist]
Example #15
0
    def run(self):
        document = self.state.document
        if not document.settings.file_insertion_enabled:
            return [
                document.reporter.warning('File insertion disabled',
                                          line=self.lineno)
            ]
        env = document.settings.env
        rel_filename, filename = env.relfn2path(self.arguments[0])

        if 'pyobject' in self.options and 'lines' in self.options:
            return [
                document.reporter.warning(
                    'Cannot use both "pyobject" and "lines" options',
                    line=self.lineno)
            ]

        encoding = self.options.get('encoding', env.config.source_encoding)
        codec_info = codecs.lookup(encoding)
        f = None
        try:
            f = codecs.StreamReaderWriter(open(filename, 'rb'), codec_info[2],
                                          codec_info[3], 'strict')
            lines = f.readlines()
        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))
            ]
        finally:
            if f is not None:
                f.close()

        objectname = self.options.get('pyobject')
        if objectname is not None:
            from sphinx.pycode import ModuleAnalyzer
            analyzer = ModuleAnalyzer.for_file(filename, '')
            tags = analyzer.find_tags()
            if objectname not in tags:
                return [
                    document.reporter.warning(
                        'Object named %r not found in include file %r' %
                        (objectname, filename),
                        line=self.lineno)
                ]
            else:
                lines = lines[tags[objectname][1] - 1:tags[objectname][2] - 1]

        linespec = self.options.get('lines')
        if linespec is not None:
            try:
                linelist = parselinenos(linespec, len(lines))
            except ValueError, err:
                return [document.reporter.warning(str(err), line=self.lineno)]
            # just ignore nonexisting lines
            nlines = len(lines)
            lines = [lines[i] for i in linelist if i < nlines]
            if not lines:
                return [
                    document.reporter.warning(
                        'Line spec %r: no lines pulled from include file %r' %
                        (linespec, filename),
                        line=self.lineno)
                ]
Example #16
0
    def run(self):
        document = self.state.document
        if not document.settings.file_insertion_enabled:
            return [document.reporter.warning('File insertion disabled',
                                              line=self.lineno)]
        env = document.settings.env
        rel_filename, filename = env.relfn2path(self.arguments[0])

        if 'pyobject' in self.options and 'lines' in self.options:
            return [document.reporter.warning(
                'Cannot use both "pyobject" and "lines" options',
                line=self.lineno)]

        if 'lineno-match' in self.options and 'lineno-start' in self.options:
            return [document.reporter.warning(
                'Cannot use both "lineno-match" and "lineno-start"',
                line=self.lineno)]

        if 'lineno-match' in self.options and \
           (set(['append', 'prepend']) & set(self.options.keys())):
            return [document.reporter.warning(
                'Cannot use "lineno-match" and "append" or "prepend"',
                line=self.lineno)]

        if 'start-after' in self.options and 'start-at' in self.options:
            return [document.reporter.warning(
                'Cannot use both "start-after" and "start-at" options',
                line=self.lineno)]

        if 'end-before' in self.options and 'end-at' in self.options:
            return [document.reporter.warning(
                'Cannot use both "end-before" and "end-at" options',
                line=self.lineno)]

        encoding = self.options.get('encoding', env.config.source_encoding)
        codec_info  = codecs.lookup(encoding)

        lines = self.read_with_encoding(filename, document,
                                        codec_info, encoding)
        if lines and not isinstance(lines[0], string_types):
            return lines

        diffsource = self.options.get('diff')
        if diffsource is None:
            return [document.reporter.warning(
                'Must have something to diff against',
                line=self.lineno)]
        else:
            tmp, fulldiffsource = env.relfn2path(diffsource)

            difflines = self.read_with_encoding(fulldiffsource, document,
                                                codec_info, encoding)
            if not isinstance(difflines[0], string_types):
                return difflines

            #
            # Highlight any lines which have been added or and which are not blank
            # or formed entirely from a comment. Other lines are shown unchanged.
            #
            hl_lines = []
            output_lines = []
            #
            # Materialise the differences because we may want to print them
            # out as well as consuming them via the output highlighter
            #
            differences = list(difflib.Differ().compare(difflines, lines))
            #
            # Debug step to help work out why highlighting is out
            #
            ## with open(os.path.basename(filename) + ".txt", "w") as f:
            ##    f.writelines(differences)
            for n, (line, highlight) in enumerate(
                self.output_lines_with_highlight(differences)
            ):
                output_lines.append(line)
                if highlight:
                    hl_lines.append(1 + n)

            lines = output_lines[:]

        linenostart = self.options.get('lineno-start', 1)
        objectname = self.options.get('pyobject')
        if objectname is not None:
            from sphinx.pycode import ModuleAnalyzer
            analyzer = ModuleAnalyzer.for_file(filename, '')
            tags = analyzer.find_tags()
            if objectname not in tags:
                return [document.reporter.warning(
                    'Object named %r not found in include file %r' %
                    (objectname, filename), line=self.lineno)]
            else:
                lines = lines[tags[objectname][1]-1: tags[objectname][2]-1]
                if 'lineno-match' in self.options:
                    linenostart = tags[objectname][1]

        linespec = self.options.get('lines')
        if linespec:
            try:
                linelist = parselinenos(linespec, len(lines))
            except ValueError as err:
                return [document.reporter.warning(str(err), line=self.lineno)]

            if 'lineno-match' in self.options:
                # make sure the line list is not "disjoint".
                previous = linelist[0]
                for line_number in linelist[1:]:
                    if line_number == previous + 1:
                        previous = line_number
                        continue
                    return [document.reporter.warning(
                        'Cannot use "lineno-match" with a disjoint set of '
                        '"lines"', line=self.lineno)]
                linenostart = linelist[0] + 1
            # just ignore non-existing lines
            lines = [lines[i] for i in linelist if i < len(lines)]
            if not lines:
                return [document.reporter.warning(
                    'Line spec %r: no lines pulled from include file %r' %
                    (linespec, filename), line=self.lineno)]

        start_str = self.options.get('start-after')
        start_inclusive = False
        if self.options.get('start-at') is not None:
            start_str = self.options.get('start-at')
            start_inclusive = True
        end_str = self.options.get('end-before')
        end_inclusive = False
        if self.options.get('end-at') is not None:
            end_str = self.options.get('end-at')
            end_inclusive = True
        if start_str is not None or end_str is not None:
            use = not start_str
            res = []
            for line_number, line in enumerate(lines):
                if not use and start_str and start_str in line:
                    if 'lineno-match' in self.options:
                        linenostart += line_number + 1
                    use = True
                    if start_inclusive:
                        res.append(line)
                elif use and end_str and end_str in line:
                    if end_inclusive:
                        res.append(line)
                    break
                elif use:
                    res.append(line)
            lines = res

        prepend = self.options.get('prepend')
        if prepend:
            lines.insert(0, prepend + '\n')

        append = self.options.get('append')
        if append:
            lines.append(append + '\n')

        text = ''.join(lines)
        if self.options.get('tab-width'):
            text = text.expandtabs(self.options['tab-width'])
        retnode = nodes.literal_block(text, text, source=filename)
        set_source_info(self, retnode)
        if 'language' in self.options:
            retnode['language'] = self.options['language']
        retnode['linenos'] = 'linenos' in self.options or \
                             'lineno-start' in self.options or \
                             'lineno-match' in self.options
        retnode['classes'] += self.options.get('class', [])
        extra_args = retnode['highlight_args'] = {}
        if hl_lines:
            extra_args['hl_lines'] = hl_lines
        extra_args['linenostart'] = linenostart
        env.note_dependency(rel_filename)

        caption = self.options.get('caption')
        if caption is not None:
            if not caption:
                caption = self.arguments[0]
            try:
                retnode = container_wrapper(self, retnode, caption)
            except ValueError as exc:
                document = self.state.document
                errmsg = _('Invalid caption: %s' % exc[0][0].astext())
                return [document.reporter.warning(errmsg, line=self.lineno)]

        # retnode will be note_implicit_target that is linked from caption and numref.
        # when options['name'] is provided, it should be primary ID.
        self.add_name(retnode)

        return [retnode]
Example #17
0
    def run(self):
        document = self.state.document
        if not document.settings.file_insertion_enabled:
            return [
                document.reporter.warning('File insertion disabled',
                                          line=self.lineno)
            ]
        env = document.settings.env
        rel_filename, filename = env.relfn2path(self.arguments[0])

        if 'pyobject' in self.options and 'lines' in self.options:
            return [
                document.reporter.warning(
                    'Cannot use both "pyobject" and "lines" options',
                    line=self.lineno)
            ]

        encoding = self.options.get('encoding', env.config.source_encoding)
        codec_info = codecs.lookup(encoding)
        f = None
        try:
            f = codecs.StreamReaderWriter(open(filename, 'rb'), codec_info[2],
                                          codec_info[3], 'strict')
            lines = f.readlines()
        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))
            ]
        finally:
            if f is not None:
                f.close()

        objectname = self.options.get('pyobject')
        if objectname is not None:
            from sphinx.pycode import ModuleAnalyzer
            analyzer = ModuleAnalyzer.for_file(filename, '')
            tags = analyzer.find_tags()
            if objectname not in tags:
                return [
                    document.reporter.warning(
                        'Object named %r not found in include file %r' %
                        (objectname, filename),
                        line=self.lineno)
                ]
            else:
                lines = lines[tags[objectname][1] - 1:tags[objectname][2] - 1]

        linespec = self.options.get('lines')
        if linespec is not None:
            try:
                linelist = parselinenos(linespec, len(lines))
            except ValueError as err:
                return [document.reporter.warning(str(err), line=self.lineno)]
            # just ignore nonexisting lines
            nlines = len(lines)
            lines = [lines[i] for i in linelist if i < nlines]
            if not lines:
                return [
                    document.reporter.warning(
                        'Line spec %r: no lines pulled from include file %r' %
                        (linespec, filename),
                        line=self.lineno)
                ]

        linespec = self.options.get('emphasize-lines')
        if linespec:
            try:
                hl_lines = [x + 1 for x in parselinenos(linespec, len(lines))]
            except ValueError as err:
                return [document.reporter.warning(str(err), line=self.lineno)]
        else:
            hl_lines = None

        startafter = self.options.get('start-after')
        endbefore = self.options.get('end-before')
        prepend = self.options.get('prepend')
        append = self.options.get('append')
        if startafter is not None or endbefore is not None:
            use = not startafter
            res = []
            for line in lines:
                if not use and startafter and startafter in line:
                    use = True
                elif use and endbefore and endbefore in line:
                    use = False
                    break
                elif use:
                    res.append(line)
            lines = res

        if prepend:
            lines.insert(0, prepend + '\n')
        if append:
            lines.append(append + '\n')

        text = ''.join(lines)
        if self.options.get('tab-width'):
            text = text.expandtabs(self.options['tab-width'])
        retnode = nodes.literal_block(text, text, source=filename)
        set_source_info(self, retnode)
        if self.options.get('language', ''):
            retnode['language'] = self.options['language']
        if 'linenos' in self.options:
            retnode['linenos'] = True
        if hl_lines is not None:
            retnode['highlight_args'] = {'hl_lines': hl_lines}
        env.note_dependency(rel_filename)
        return [retnode]
Example #18
0
    def run(self):
        document = self.state.document
        if not document.settings.file_insertion_enabled:
            return [document.reporter.warning('File insertion disabled',
                                              line=self.lineno)]
        env = document.settings.env
        rel_filename, filename = env.relfn2path(self.arguments[0])

        if 'pyobject' in self.options and 'lines' in self.options:
            return [document.reporter.warning(
                'Cannot use both "pyobject" and "lines" options',
                line=self.lineno)]

        if 'lineno-match' in self.options and 'lineno-start' in self.options:
            return [document.reporter.warning(
                'Cannot use both "lineno-match" and "lineno-start"',
                line=self.lineno)]

        if 'lineno-match' in self.options and \
           (set(['append', 'prepend']) & set(self.options.keys())):
            return [document.reporter.warning(
                'Cannot use "lineno-match" and "append" or "prepend"',
                line=self.lineno)]

        encoding = self.options.get('encoding', env.config.source_encoding)
        codec_info = codecs.lookup(encoding)

        lines = self.read_with_encoding(filename, document,
                                        codec_info, encoding)
        if lines and not isinstance(lines[0], string_types):
            return lines

        diffsource = self.options.get('diff')
        if diffsource is not None:
            tmp, fulldiffsource = env.relfn2path(diffsource)

            difflines = self.read_with_encoding(fulldiffsource, document,
                                                codec_info, encoding)
            if not isinstance(difflines[0], string_types):
                return difflines
            diff = unified_diff(
                difflines,
                lines,
                diffsource,
                self.arguments[0])
            lines = list(diff)

        linenostart = self.options.get('lineno-start', 1)
        objectname = self.options.get('pyobject')
        if objectname is not None:
            from sphinx.pycode import ModuleAnalyzer
            analyzer = ModuleAnalyzer.for_file(filename, '')
            tags = analyzer.find_tags()
            if objectname not in tags:
                return [document.reporter.warning(
                    'Object named %r not found in include file %r' %
                    (objectname, filename), line=self.lineno)]
            else:
                lines = lines[tags[objectname][1]-1: tags[objectname][2]-1]
                if 'lineno-match' in self.options:
                    linenostart = tags[objectname][1]

        linespec = self.options.get('lines')
        if linespec:
            try:
                linelist = parselinenos(linespec, len(lines))
            except ValueError as err:
                return [document.reporter.warning(str(err), line=self.lineno)]

            if 'lineno-match' in self.options:
                # make sure the line list is not "disjoint".
                previous = linelist[0]
                for line_number in linelist[1:]:
                    if line_number == previous + 1:
                        previous = line_number
                        continue
                    return [document.reporter.warning(
                        'Cannot use "lineno-match" with a disjoint set of '
                        '"lines"', line=self.lineno)]
                linenostart = linelist[0] + 1
            # just ignore non-existing lines
            lines = [lines[i] for i in linelist if i < len(lines)]
            if not lines:
                return [document.reporter.warning(
                    'Line spec %r: no lines pulled from include file %r' %
                    (linespec, filename), line=self.lineno)]

        linespec = self.options.get('emphasize-lines')
        if linespec:
            try:
                hl_lines = [x+1 for x in parselinenos(linespec, len(lines))]
            except ValueError as err:
                return [document.reporter.warning(str(err), line=self.lineno)]
        else:
            hl_lines = None

        startafter = self.options.get('start-after')
        endbefore = self.options.get('end-before')
        if startafter is not None or endbefore is not None:
            use = not startafter
            res = []
            for line_number, line in enumerate(lines):
                if not use and startafter and startafter in line:
                    if 'lineno-match' in self.options:
                        linenostart += line_number + 1
                    use = True
                elif use and endbefore and endbefore in line:
                    break
                elif use:
                    res.append(line)
            lines = res

        prepend = self.options.get('prepend')
        if prepend:
            lines.insert(0, prepend + '\n')

        append = self.options.get('append')
        if append:
            lines.append(append + '\n')

        text = ''.join(lines)
        if self.options.get('tab-width'):
            text = text.expandtabs(self.options['tab-width'])
        retnode = nodes.literal_block(text, text, source=filename)
        set_source_info(self, retnode)
        if diffsource:  # if diff is set, set udiff
            retnode['language'] = 'udiff'
        if 'language' in self.options:
            retnode['language'] = self.options['language']
        retnode['linenos'] = 'linenos' in self.options or \
                             'lineno-start' in self.options or \
                             'lineno-match' in self.options
        retnode['classes'] += self.options.get('class', [])
        extra_args = retnode['highlight_args'] = {}
        if hl_lines is not None:
            extra_args['hl_lines'] = hl_lines
        extra_args['linenostart'] = linenostart
        env.note_dependency(rel_filename)

        caption = self.options.get('caption')
        if caption is not None:
            if not caption:
                caption = self.arguments[0]
            try:
                retnode = container_wrapper(self, retnode, caption)
            except ValueError as exc:
                document = self.state.document
                errmsg = _('Invalid caption: %s' % exc[0][0].astext())
                return [document.reporter.warning(errmsg, line=self.lineno)]

        # retnode will be note_implicit_target that is linked from caption and numref.
        # when options['name'] is provided, it should be primary ID.
        self.add_name(retnode)

        return [retnode]
Example #19
0
File: code.py Project: xcore/xdoc
    def run(self):        
        document = self.state.document
        filename = self.arguments[0]
        if not document.settings.file_insertion_enabled:
            return [document.reporter.warning('File insertion disabled',
                                              line=self.lineno)]
        env = document.settings.env
        fns = []
 
        docdir = path.dirname(env.doc2path(env.docname, base=None))
        dirs = [docdir,os.path.join(docdir,'_build','.sources')]
        if os.path.exists(os.path.join('_build','.sources')):
            dirs += [os.path.join(docdir,'_build','.sources',x) for x in os.listdir(os.path.join('_build','.sources'))]

        #self.state.document.settings.env.config.include_search_dirs
       
        fns = [path.join(x, filename) for x in dirs]


#        print fns
#        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)

        if 'pyobject' in self.options and 'lines' in self.options:
            return [document.reporter.warning(
                'Cannot use both "pyobject" and "lines" options',
                line=self.lineno)]

        encoding = self.options.get('encoding', env.config.source_encoding)
        codec_info = codecs.lookup(encoding)
        lines = None
        for fn in fns:
            if lines == None:
                try:
                    f = codecs.StreamReaderWriter(open(fn, 'U'),
                                                  codec_info[2], 
                                                  codec_info[3], 'strict')
                    lines = f.readlines()
                    f.close()
                except (IOError, OSError):
                    pass
                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))]
                
        if lines == None:
                return [document.reporter.warning(
                'Include file %r not found or reading it failed' % filename,
                line=self.lineno)]

        objectname = self.options.get('pyobject')
        if objectname is not None:
            from sphinx.pycode import ModuleAnalyzer
            analyzer = ModuleAnalyzer.for_file(fn, '')
            tags = analyzer.find_tags()
            if objectname not in tags:
                return [document.reporter.warning(
                    'Object named %r not found in include file %r' %
                    (objectname, filename), line=self.lineno)]
            else:
                lines = lines[tags[objectname][1]-1 : tags[objectname][2]-1]

        linespec = self.options.get('lines')
        if linespec is not None:
            try:
                linelist = parselinenos(linespec, len(lines))
            except ValueError, err:
                return [document.reporter.warning(str(err), line=self.lineno)]
            lines = [lines[i] for i in linelist]
Example #20
0
def run(self):
    document = self.state.document
    filename = self.arguments[0]
    #print filename
    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.normpath(path.join(docdir, filename))
    fn = path.join(env.srcdir, rel_fn)

    if 'pyobject' in self.options and 'lines' in self.options:
        return [document.reporter.warning(
            'Cannot use both "pyobject" and "lines" options',
            line=self.lineno)]

    encoding = self.options.get('encoding', env.config.source_encoding)
    try:
        f = codecs.open(fn, 'rU', encoding)
        lines = f.readlines()
        f.close()
        # 去掉编码指示
        if fn.endswith(".py") and lines[0].startswith("#") and "coding" in lines[0]:
            lines = lines[1:]
        # 去掉文档说明
        if fn.endswith(".py"):
            if lines[0].startswith('"""'):
                for lineno, line in enumerate(lines[1:]):
                    if line.strip().endswith('"""'):
                        lines = lines[lineno+2:]
                        break
        # 去掉每行末尾空格
        for i in xrange(len(lines)):
            lines[i] = lines[i].rstrip() + "\n"
        
    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))]

    objectname = self.options.get('pyobject')
    if objectname is not None:
        from sphinx.pycode import ModuleAnalyzer
        analyzer = ModuleAnalyzer.for_file(fn, '')
        tags = analyzer.find_tags()
        if objectname not in tags:
            return [document.reporter.warning(
                'Object named %r not found in include file %r' %
                (objectname, filename), line=self.lineno)]
        else:
            lines = lines[tags[objectname][1]-1 : tags[objectname][2]-1]

    linespec = self.options.get('lines')
    if linespec is not None:
        try:
            linelist = parselinenos(linespec, len(lines))
        except ValueError, err:
            return [document.reporter.warning(str(err), line=self.lineno)]
        lines = [lines[i] for i in linelist]
Example #21
0
    def run(self):
        document = self.state.document
        if not document.settings.file_insertion_enabled:
            return [
                document.reporter.warning('File insertion disabled',
                                          line=self.lineno)
            ]
        env = document.settings.env
        rel_filename, filename = env.relfn2path(self.arguments[0])

        if 'pyobject' in self.options and 'lines' in self.options:
            return [
                document.reporter.warning(
                    'Cannot use both "pyobject" and "lines" options',
                    line=self.lineno)
            ]

        if 'lineno-match' in self.options and 'lineno-start' in self.options:
            return [
                document.reporter.warning(
                    'Cannot use both "lineno-match" and "lineno-start"',
                    line=self.lineno)
            ]

        if 'lineno-match' in self.options and \
           (set(['append', 'prepend']) & set(self.options.keys())):
            return [
                document.reporter.warning(
                    'Cannot use "lineno-match" and "append" or "prepend"',
                    line=self.lineno)
            ]

        encoding = self.options.get('encoding', env.config.source_encoding)
        codec_info = codecs.lookup(encoding)

        lines = self.read_with_encoding(filename, document, codec_info,
                                        encoding)
        if lines and not isinstance(lines[0], string_types):
            return lines

        diffsource = self.options.get('diff')
        if diffsource is not None:
            tmp, fulldiffsource = env.relfn2path(diffsource)

            difflines = self.read_with_encoding(fulldiffsource, document,
                                                codec_info, encoding)
            if not isinstance(difflines[0], string_types):
                return difflines
            diff = unified_diff(difflines, lines, diffsource,
                                self.arguments[0])
            lines = list(diff)

        linenostart = self.options.get('lineno-start', 1)
        objectname = self.options.get('pyobject')
        if objectname is not None:
            from sphinx.pycode import ModuleAnalyzer
            analyzer = ModuleAnalyzer.for_file(filename, '')
            tags = analyzer.find_tags()
            if objectname not in tags:
                return [
                    document.reporter.warning(
                        'Object named %r not found in include file %r' %
                        (objectname, filename),
                        line=self.lineno)
                ]
            else:
                lines = lines[tags[objectname][1] - 1:tags[objectname][2] - 1]
                if 'lineno-match' in self.options:
                    linenostart = tags[objectname][1]

        linespec = self.options.get('lines')
        if linespec:
            try:
                linelist = parselinenos(linespec, len(lines))
            except ValueError as err:
                return [document.reporter.warning(str(err), line=self.lineno)]

            if 'lineno-match' in self.options:
                # make sure the line list is not "disjoint".
                previous = linelist[0]
                for line_number in linelist[1:]:
                    if line_number == previous + 1:
                        previous = line_number
                        continue
                    return [
                        document.reporter.warning(
                            'Cannot use "lineno-match" with a disjoint set of '
                            '"lines"',
                            line=self.lineno)
                    ]
                linenostart = linelist[0] + 1
            # just ignore non-existing lines
            lines = [lines[i] for i in linelist if i < len(lines)]
            if not lines:
                return [
                    document.reporter.warning(
                        'Line spec %r: no lines pulled from include file %r' %
                        (linespec, filename),
                        line=self.lineno)
                ]

        linespec = self.options.get('emphasize-lines')
        if linespec:
            try:
                hl_lines = [x + 1 for x in parselinenos(linespec, len(lines))]
            except ValueError as err:
                return [document.reporter.warning(str(err), line=self.lineno)]
        else:
            hl_lines = None

        startafter = self.options.get('start-after')
        endbefore = self.options.get('end-before')
        if startafter is not None or endbefore is not None:
            use = not startafter
            res = []
            for line_number, line in enumerate(lines):
                if not use and startafter and startafter in line:
                    if 'lineno-match' in self.options:
                        linenostart += line_number + 1
                    use = True
                elif use and endbefore and endbefore in line:
                    break
                elif use:
                    res.append(line)
            lines = res

        prepend = self.options.get('prepend')
        if prepend:
            lines.insert(0, prepend + '\n')

        append = self.options.get('append')
        if append:
            lines.append(append + '\n')

        text = ''.join(lines)
        if self.options.get('tab-width'):
            text = text.expandtabs(self.options['tab-width'])
        retnode = nodes.literal_block(text, text, source=filename)
        set_source_info(self, retnode)
        if diffsource:  # if diff is set, set udiff
            retnode['language'] = 'udiff'
        if 'language' in self.options:
            retnode['language'] = self.options['language']
        retnode['linenos'] = 'linenos' in self.options or \
                             'lineno-start' in self.options or \
                             'lineno-match' in self.options
        extra_args = retnode['highlight_args'] = {}
        if hl_lines is not None:
            extra_args['hl_lines'] = hl_lines
        extra_args['linenostart'] = linenostart
        env.note_dependency(rel_filename)

        caption = self.options.get('caption')
        if caption is not None:
            if not caption:
                caption = self.arguments[0]
            self.options.setdefault('name',
                                    nodes.fully_normalize_name(caption))
            retnode = container_wrapper(self, retnode, caption)

        # retnode will be note_implicit_target that is linked from caption and numref.
        # when options['name'] is provided, it should be primary ID.
        self.add_name(retnode)

        return [retnode]