Exemplo n.º 1
0
class Input(TransformSpec):
    """
    Abstract base class for input wrappers.
    """

    component_type = 'input'

    default_source_path = None

    def __init__(self,
                 source=None,
                 source_path=None,
                 encoding=None,
                 error_handler='strict'):
        self.encoding = encoding
        """Text encoding for the input source."""

        self.error_handler = error_handler
        """Text decoding error handler."""

        self.source = source
        """The source of input data."""

        self.source_path = source_path
        """A text reference to the source."""

        if not source_path:
            self.source_path = self.default_source_path

        self.successful_encoding = None
        """The encoding that successfully decoded the source data."""

    def __repr__(self):
        return '%s: source=%r, source_path=%r' % (self.__class__, self.source,
                                                  self.source_path)

    def read(self):
        raise NotImplementedError

    def decode(self, data):
        """
        Decode a string, `data`, heuristically.
        Raise UnicodeError if unsuccessful.

        The client application should call ``locale.setlocale`` at the
        beginning of processing::

            locale.setlocale(locale.LC_ALL, '')
        """
        if self.encoding and self.encoding.lower() == 'unicode':
            assert isinstance(data,
                              unicode), ('input encoding is "unicode" '
                                         'but input is not a unicode object')
        if isinstance(data, unicode):
            # Accept unicode even if self.encoding != 'unicode'.
            return data
        if self.encoding:
            # We believe the user/application when the encoding is
            # explicitly given.
            encodings = [self.encoding]
        else:
            data_encoding = self.determine_encoding_from_data(data)
            if data_encoding:
                # If the data declares its encoding (explicitly or via a BOM),
                # we believe it.
                encodings = [data_encoding]
            else:
                # Apply heuristics only if no encoding is explicitly given and
                # no BOM found.  Start with UTF-8, because that only matches
                # data that *IS* UTF-8:
                encodings = ['utf-8', 'latin-1']
                if locale_encoding:
                    encodings.insert(1, locale_encoding)
        for enc in encodings:
            try:
                decoded = unicode(data, enc, self.error_handler)
                self.successful_encoding = enc
                # Return decoded, removing BOMs.
                return decoded.replace(u'\ufeff', u'')
            except (UnicodeError, LookupError), err:
                error = err  # in Python 3, the <exception instance> is
                # local to the except clause
        raise UnicodeError(
            'Unable to decode input data.  Tried the following encodings: '
            '%s.\n(%s)' %
            (', '.join([repr(enc) for enc in encodings]), ErrorString(error)))
Exemplo n.º 2
0
    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.
        """
        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))
        path = directives.path(self.arguments[0])
        if path.startswith('<') and path.endswith('>'):
            path = os.path.join(self.standard_include_path, path[1:-1])
        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'
                              'Cannot encode input file path "%s" '
                              '(wrong locale?).' %
                              (self.name, SafeString(path)))
        except IOError as error:
            raise self.severe('Problems with "%s" directive path:\n%s.' %
                              (self.name, ErrorString(error)))
        startline = self.options.get('start-line', None)
        endline = self.options.get('end-line', None)
        try:
            if startline or (endline is not None):
                lines = include_file.readlines()
                rawtext = ''.join(lines[startline:endline])
            else:
                rawtext = include_file.read()
        except UnicodeError as error:
            raise self.severe('Problem with "%s" directive:\n%s' %
                              (self.name, ErrorString(error)))
        # start-after/end-before: no restrictions on newlines in match-text,
        # and no restrictions on matching inside lines vs. line boundaries
        after_text = self.options.get('start-after', None)
        if after_text:
            # skip content in rawtext before *and incl.* a matching text
            after_index = rawtext.find(after_text)
            if after_index < 0:
                raise self.severe('Problem with "start-after" option of "%s" '
                                  'directive:\nText not found.' % self.name)
            rawtext = rawtext[after_index + len(after_text):]
        before_text = self.options.get('end-before', None)
        if before_text:
            # skip content in rawtext after *and incl.* a matching text
            before_index = rawtext.find(before_text)
            if before_index < 0:
                raise self.severe('Problem with "end-before" option of "%s" '
                                  'directive:\nText not found.' % self.name)
            rawtext = rawtext[:before_index]

        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()
Exemplo n.º 3
0
    def run(self):
        messages = []

        try:
            options = parse_keys(self.content)
        except ParseError as err:
            return [
                self.state.document.reporter.error(str(err),
                                                   line=(self.lineno +
                                                         err.lineno + 1))
            ]

        for key, validation_function in self.guide_keys.items():
            if key not in options:
                if key in self.optional_keys:
                    options[key] = ''
                else:
                    messages.append(
                        self.state.document.reporter.warning(
                            'Missing required guide option: {}'.format(key),
                            line=self.lineno))
                    continue

            try:
                options[key] = validation_function(options[key])
            except ValueError as err:
                message = 'Invalid guide option value: {}'.format(key)
                if err.message:
                    message += ': {}'.format(err.message)

                return [
                    self.state.document.reporter.error(message,
                                                       line=self.lineno)
                ]

        try:
            rendered = GUIDES_TEMPLATE.render(options)
        except Exception as error:
            raise self.severe('Failed to render template: {}'.format(
                ErrorString(error)))

        rendered_lines = statemachine.string2lines(rendered,
                                                   4,
                                                   convert_whitespace=1)
        self.state_machine.insert_input(rendered_lines, '')

        env = self.state.document.settings.env
        if not hasattr(env, 'guide_all_guides'):
            env.guide_all_guides = []

        guide = {
            'docname':
            env.docname,
            'title':
            options['title'],
            'time':
            options['time'],
            'category':
            options['type'],
            'all_languages': [{
                'title': LANGUAGES_DICT[lang],
                'id': lang
            } for lang in options['languages']],
            'card_languages': [],
            'languages_truncated':
            False,
            'jumbo':
            False
        }

        total_length = 0
        for language in guide['all_languages']:
            if total_length > 50:
                guide['languages_truncated'] = True
                break

            total_length += len(language['title']) + 4
            guide['card_languages'].append(language)

        env.guide_all_guides.append(guide)

        return messages
Exemplo n.º 4
0
    def run(self):
        env = self.state.document.settings.env
        if not hasattr(env, 'guide_all_guides'):
            return []

        guides = {}
        for guide in env.guide_all_guides:
            guides[guide['docname']] = guide

        cardset = CardSet()

        previous_line = None
        pending_card = [None]

        def handle_single_guide():
            if pending_card[0] is None:
                if previous_line not in guides:
                    return

                guide = guides[previous_line]
                cardset.add_guide(env, guide)
            else:
                cardset_guides = [
                    guides[docname] for docname in pending_card[0]['guides']
                    if docname in guides
                ]
                cardset.add_guides(env, cardset_guides,
                                   pending_card[0]['title'])
                pending_card[0] = None

        for is_indented, lineno, line in parse_indentation(self.content):
            if not line:
                continue

            if is_indented:
                # A card containing multiple guides
                if pending_card[0] is None:
                    pending_card[0] = {
                        'title': previous_line,
                        'jumbo': False,
                        'guides': []
                    }

                pending_card[0]['guides'].append(line)
            elif previous_line is not None:
                # A card containing a single guide
                handle_single_guide()

            previous_line = line

        if previous_line is not None:
            handle_single_guide()

        try:
            rendered = GUIDES_INDEX_TEMPLATE.render({
                'categories': [
                    cat for cat in cardset.categories.values()
                    if cat['n_guides'] > 0
                ],
                'link_suffix':
                env.app.builder.link_suffix
            })
        except Exception as error:
            raise self.severe('Failed to render template: {}'.format(
                ErrorString(error)))

        rendered_lines = statemachine.string2lines(rendered,
                                                   4,
                                                   convert_whitespace=1)
        self.state_machine.insert_input(rendered_lines, '')

        # Add guides to the TOC
        subnode = addnodes.toctree()
        subnode['hidden'] = True
        subnode['glob'] = False
        subnode['includefiles'] = list(guides.keys())
        subnode['parent'] = env.docname
        subnode['entries'] = [(guide['title'], guide['docname'])
                              for guide in guides.values()]
        set_source_info(self, subnode)

        return [subnode]
Exemplo n.º 5
0
    def run(self):
        """Include a file as part of the content of this reST file."""
        if not self.state.document.settings.file_insertion_enabled:
            raise self.warning('"%s" directive disabled.' % self.name)
        source = self.state_machine.input_lines.source(
            self.lineno - self.state_machine.input_offset - 1)
        source_dir = os.path.dirname(os.path.abspath(source))
        path = directives.path(self.arguments[0])
        if path.startswith('<') and path.endswith('>'):
            path = os.path.join(self.standard_include_path, path[1:-1])
        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(u'Problems with "%s" directive path:\n'
                              'Cannot encode input file path "%s" '
                              '(wrong locale?).' %
                              (self.name, SafeString(path)))
        except IOError as error:
            raise self.severe(u'Problems with "%s" directive path:\n%s.' %
                              (self.name, ErrorString(error)))

        # Get to-be-included content
        startline = self.options.get('start-line', None)
        endline = self.options.get('end-line', None)
        try:
            if startline or (endline is not None):
                lines = include_file.readlines()
                rawtext = ''.join(lines[startline:endline])
            else:
                rawtext = include_file.read()
        except UnicodeError as error:
            raise self.severe(u'Problem with "%s" directive:\n%s' %
                              (self.name, ErrorString(error)))
        # start-after/end-before: no restrictions on newlines in match-text,
        # and no restrictions on matching inside lines vs. line boundaries
        after_text = self.options.get('start-after', None)
        if after_text:
            # skip content in rawtext before *and incl.* a matching text
            after_index = rawtext.find(after_text)
            if after_index < 0:
                raise self.severe('Problem with "start-after" option of "%s" '
                                  'directive:\nText not found.' % self.name)
            rawtext = rawtext[after_index + len(after_text):]
        before_text = self.options.get('end-before', None)
        if before_text:
            # skip content in rawtext after *and incl.* a matching text
            before_index = rawtext.find(before_text)
            if before_index < 0:
                raise self.severe('Problem with "end-before" option of "%s" '
                                  'directive:\nText not found.' % self.name)
            rawtext = rawtext[:before_index]

        include_lines = statemachine.string2lines(rawtext,
                                                  tab_width,
                                                  convert_whitespace=True)
        for i, line in enumerate(include_lines):
            if len(line) > self.state.document.settings.line_length_limit:
                raise self.warning('"%s": line %d exceeds the'
                                   ' line-length-limit.' % (path, i + 1))

        if 'literal' in self.options:
            # Don't convert tabs to spaces, if `tab_width` is negative.
            if tab_width >= 0:
                text = rawtext.expandtabs(tab_width)
            else:
                text = rawtext
            literal_block = nodes.literal_block(rawtext,
                                                source=path,
                                                classes=self.options.get(
                                                    'class', []))
            literal_block.line = 1
            self.add_name(literal_block)
            if 'number-lines' in self.options:
                try:
                    startline = int(self.options['number-lines'] or 1)
                except ValueError:
                    raise self.error(':number-lines: with non-integer '
                                     'start value')
                endline = startline + len(include_lines)
                if text.endswith('\n'):
                    text = text[:-1]
                tokens = NumberLines([([], text)], startline, endline)
                for classes, value in tokens:
                    if classes:
                        literal_block += nodes.inline(value,
                                                      value,
                                                      classes=classes)
                    else:
                        literal_block += nodes.Text(value)
            else:
                literal_block += nodes.Text(text)
            return [literal_block]

        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 = CodeBlock(
                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 'parser' in self.options:
            parser = self.options['parser']()
            # parse into a new (dummy) document
            document = utils.new_document(path, self.state.document.settings)
            parser.parse('\n'.join(include_lines), document)
            return document.children

        # include as rST source
        #
        # Prevent circular inclusion:
        source = utils.relative_path(None, source)
        clip_options = (startline, endline, before_text, after_text)
        include_log = self.state.document.include_log
        if not include_log:  # new document:
            # log entries: (<source>, <clip-options>, <insertion end index>)
            include_log = [(source, (None, None, None, None), sys.maxsize / 2)]
        # cleanup: we may have passed the last inclusion(s):
        include_log = [
            entry for entry in include_log if entry[2] >= self.lineno
        ]
        if (path, clip_options) in [(pth, opt)
                                    for (pth, opt, e) in include_log]:
            raise self.warning(
                'circular inclusion in "%s" directive: %s' %
                (self.name,
                 ' < '.join([path] +
                            [pth for (pth, opt, e) in include_log[::-1]])))
        # include as input
        self.state_machine.insert_input(include_lines, path)
        # update include-log
        include_log.append((path, clip_options, self.lineno))
        self.state.document.include_log = [(pth, opt,
                                            e + len(include_lines) + 2)
                                           for (pth, opt, e) in include_log]
        return []
Exemplo n.º 6
0
    def run(self):
        """
        Verbatim copy of docutils.parsers.rst.directives.misc.Include.run()
        that just calls to our Code instead of builtin CodeBlock, is without
        the rarely useful :encoding:, :literal: and :name: options and adds
        support for :start-on:, empty :end-before: and :strip-prefix:.
        """
        source = self.state_machine.input_lines.source(
            self.lineno - self.state_machine.input_offset - 1)
        source_dir = os.path.dirname(os.path.abspath(source))
        path = directives.path(self.arguments[0])
        if path.startswith('<') and path.endswith('>'):
            path = os.path.join(self.standard_include_path, path[1:-1])
        path = os.path.normpath(os.path.join(source_dir, path))
        path = utils.relative_path(None, path)
        path = nodes.reprunicode(path)
        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,
                                        error_handler=e_handler)
        except UnicodeEncodeError as error:
            raise self.severe('Problems with "%s" directive path:\n'
                              'Cannot encode input file path "%s" '
                              '(wrong locale?).' %
                              (self.name, SafeString(path)))
        except IOError as error:
            raise self.severe('Problems with "%s" directive path:\n%s.' %
                      (self.name, ErrorString(error)))
        startline = self.options.get('start-line', None)
        endline = self.options.get('end-line', None)
        try:
            if startline or (endline is not None):
                lines = include_file.readlines()
                rawtext = ''.join(lines[startline:endline])
            else:
                rawtext = include_file.read()
        except UnicodeError as error:
            raise self.severe('Problem with "%s" directive:\n%s' %
                              (self.name, ErrorString(error)))
        # start-after/end-before: no restrictions on newlines in match-text,
        # and no restrictions on matching inside lines vs. line boundaries
        after_text = self.options.get('start-after', None)
        if after_text:
            # skip content in rawtext before *and incl.* a matching text
            after_index = rawtext.find(after_text)
            if after_index < 0:
                raise self.severe('Problem with "start-after" option of "%s" '
                                  'directive:\nText not found.' % self.name)
            rawtext = rawtext[after_index + len(after_text):]
        # Compared to start-after, this includes the matched line
        on_text = self.options.get('start-on', None)
        if on_text:
            on_index = rawtext.find('\n' + on_text)
            if on_index < 0:
                raise self.severe('Problem with "start-on" option of "%s" '
                                  'directive:\nText not found.' % self.name)
            rawtext = rawtext[on_index:]
        # Compared to builtin include directive, the end-before can be empty,
        # in which case it simply matches the first empty line (which is
        # usually end of the code block)
        before_text = self.options.get('end-before', None)
        if before_text is not None:
            # skip content in rawtext after *and incl.* a matching text
            if before_text == '':
                before_index = rawtext.find('\n\n')
            else:
                before_index = rawtext.find(before_text)
            if before_index < 0:
                raise self.severe('Problem with "end-before" option of "%s" '
                                  'directive:\nText not found.' % self.name)
            rawtext = rawtext[:before_index]

        include_lines = statemachine.string2lines(rawtext, tab_width,
                                                  convert_whitespace=True)

        # Strip a common prefix from all lines. Useful for example when
        # including a reST snippet that's embedded in a comment, or cutting
        # away excessive indentation. Can be wrapped in quotes in order to
        # avoid trailing whitespace in reST markup.
        if 'strip-prefix' in self.options and self.options['strip-prefix']:
            prefix = self.options['strip-prefix']
            if prefix[0] == prefix[-1] and prefix[0] in ['\'', '"']:
                prefix = prefix[1:-1]
            for i, line in enumerate(include_lines):
                if line.startswith(prefix): include_lines[i] = line[len(prefix):]
                # Strip the prefix also if the line is just the prefix alone,
                # with trailing whitespace removed
                elif line.rstrip() == prefix.rstrip(): include_lines[i] = ''

        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 []
Exemplo n.º 7
0
class Include(Directive):

    """
    Include content read from a separate source file.

    Content may be parsed by the parser, or included as a literal
    block.  The encoding of the included file can be specified.  Only
    a part of the given file argument may be included by specifying
    start and end line or text to match before and/or after the text
    to be used.
    """

    required_arguments = 1
    optional_arguments = 0
    final_argument_whitespace = True
    option_spec = {'literal': directives.flag,
                   'code': directives.unchanged,
                   'encoding': directives.encoding,
                   'tab-width': int,
                   'start-line': int,
                   'end-line': int,
                   'start-after': directives.unchanged_required,
                   'end-before': directives.unchanged_required,
                   # ignored except for 'literal' or 'code':
                   'number-lines': directives.unchanged, # integer or None
                   'class': directives.class_option,
                   'name': directives.unchanged}

    standard_include_path = os.path.join(docutils._datadir(states.__file__),
                                         'include')

    def run(self):
        """Include a file as part of the content of this reST file."""
        if not self.state.document.settings.file_insertion_enabled:
            raise self.warning('"%s" directive disabled.' % self.name)
        source = self.state_machine.input_lines.source(
            self.lineno - self.state_machine.input_offset - 1)
        source_dir = os.path.dirname(os.path.abspath(source))
        path = directives.path(self.arguments[0])
        if path.startswith('<') and path.endswith('>'):
            path = os.path.join(self.standard_include_path, path[1:-1])
        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, error:
            raise self.severe(u'Problems with "%s" directive path:\n'
                              'Cannot encode input file path "%s" '
                              '(wrong locale?).' %
                              (self.name, SafeString(path)))
        except IOError, error:
            raise self.severe(u'Problems with "%s" directive path:\n%s.' %
                      (self.name, ErrorString(error)))
Exemplo n.º 8
0
    def run(self):

        # For code or literal include blocks we run the normal include
        if 'literal' in self.options or 'code' in self.options:
            return super(FormatedInclude, self).run()
        """Include a file as part of the content of this reST file."""
        if not self.state.document.settings.file_insertion_enabled:
            raise self.warning('"%s" directive disabled.' % self.name)
        source = self.state_machine.input_lines.source(
            self.lineno - self.state_machine.input_offset - 1)

        source_dir = os.path.dirname(os.path.abspath(source))

        rel_filename, filename = self.env.relfn2path(self.arguments[0])
        self.arguments[0] = filename
        self.env.note_included(filename)
        path = directives.path(self.arguments[0])

        if path.startswith('<') and path.endswith('>'):
            path = os.path.join(self.standard_include_path, path[1:-1])
        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:
            raise self.severe(u'Problems with "%s" directive path:\n'
                              'Cannot encode input file path "%s" '
                              '(wrong locale?).' %
                              (self.name, SafeString(path)))
        except IOError as error:
            raise self.severe(u'Problems with "%s" directive path:\n%s.' %
                              (self.name, ErrorString(error)))
        startline = self.options.get('start-line', None)
        endline = self.options.get('end-line', None)
        try:
            if startline or (endline is not None):
                lines = include_file.readlines()
                rawtext = ''.join(lines[startline:endline])
            else:
                rawtext = include_file.read()
        except UnicodeError as error:
            raise self.severe(u'Problem with "%s" directive:\n%s' %
                              (self.name, ErrorString(error)))

        # Format input
        sub = StringSubstituter()
        config = self.state.document.settings.env.config
        sub.init_sub_strings(config)
        rawtext = sub.substitute(rawtext)

        # start-after/end-before: no restrictions on newlines in match-text,
        # and no restrictions on matching inside lines vs. line boundaries
        after_text = self.options.get('start-after', None)
        if after_text:
            # skip content in rawtext before *and incl.* a matching text
            after_index = rawtext.find(after_text)
            if after_index < 0:
                raise self.severe('Problem with "start-after" option of "%s" '
                                  'directive:\nText not found.' % self.name)
            rawtext = rawtext[after_index + len(after_text):]
        before_text = self.options.get('end-before', None)
        if before_text:
            # skip content in rawtext after *and incl.* a matching text
            before_index = rawtext.find(before_text)
            if before_index < 0:
                raise self.severe('Problem with "end-before" option of "%s" '
                                  'directive:\nText not found.' % self.name)
            rawtext = rawtext[:before_index]

        include_lines = statemachine.string2lines(rawtext,
                                                  tab_width,
                                                  convert_whitespace=True)

        self.state_machine.insert_input(include_lines, path)
        return []
Exemplo n.º 9
0
    def run(self):
        """Include a file as part of the content of this reST file."""

        # from sphynx Include Directive in https://github.com/sphinx-doc/sphinx/blob/master/sphinx/directives/other.py
        # type: () -> List[nodes.Node]
        env = self.state.document.settings.env
        if self.arguments[0].startswith('<') and \
           self.arguments[0].endswith('>'):
            # docutils "standard" includes, do not do path processing
            return BaseInclude.run(self)
        rel_filename, filename = env.relfn2path(self.arguments[0])
        self.arguments[0] = filename
        env.note_included(filename)
        #end

        if not self.state.document.settings.file_insertion_enabled:
            raise self.warning('"%s" directive disabled.' % self.name)
        source = self.state_machine.input_lines.source(
            self.lineno - self.state_machine.input_offset - 1)
        source_dir = os.path.dirname(os.path.abspath(source))
        path = directives.path(self.arguments[0])
        if path.startswith('<') and path.endswith('>'):
            path = os.path.join(self.standard_include_path, path[1:-1])
        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(u'Problems with "%s" directive path:\n'
                              'Cannot encode input file path "%s" '
                              '(wrong locale?).' %
                              (self.name, SafeString(path)))
        except IOError as error:
            raise self.severe(u'Problems with "%s" directive path:\n%s.' %
                              (self.name, ErrorString(error)))
        startline = self.options.get('start-line', None)
        endline = self.options.get('end-line', None)
        try:
            if startline or (endline is not None):
                lines = include_file.readlines()
                rawtext = ''.join(lines[startline:endline])
            else:
                rawtext = include_file.read()
        except UnicodeError as error:
            raise self.severe(u'Problem with "%s" directive:\n%s' %
                              (self.name, ErrorString(error)))
        # start-after/end-before: no restrictions on newlines in match-text,
        # and no restrictions on matching inside lines vs. line boundaries
        after_text = self.options.get('start-after', None)
        if after_text:
            # skip content in rawtext before *and incl.* a matching text
            after_index = rawtext.find(after_text)
            if after_index < 0:
                raise self.severe('Problem with "start-after" option of "%s" '
                                  'directive:\nText not found.' % self.name)
            rawtext = rawtext[after_index + len(after_text):]
        before_text = self.options.get('end-before', None)
        if before_text:
            # skip content in rawtext after *and incl.* a matching text
            before_index = rawtext.find(before_text)
            if before_index < 0:
                raise self.severe('Problem with "end-before" option of "%s" '
                                  'directive:\nText not found.' % self.name)
            rawtext = rawtext[:before_index]

        rawtext = self.filterText(rawtext)
        #if (path == "../examples/neuropil_hydra.c"):
        #raise self.severe('filterd text from %s:\n%s' % (path, rawtext))

        include_lines = statemachine.string2lines(rawtext,
                                                  tab_width,
                                                  convert_whitespace=True)
        if 'literal' in self.options:
            # Convert tabs to spaces, if `tab_width` is positive.
            if tab_width >= 0:
                text = rawtext.expandtabs(tab_width)
            else:
                text = rawtext
            literal_block = nodes.literal_block(rawtext,
                                                source=path,
                                                classes=self.options.get(
                                                    'class', []))
            literal_block.line = 1
            self.add_name(literal_block)
            if 'number-lines' in self.options:
                try:
                    startline = int(self.options['number-lines'] or 1)
                except ValueError:
                    raise self.error(':number-lines: with non-integer '
                                     'start value')
                endline = startline + len(include_lines)
                if text.endswith('\n'):
                    text = text[:-1]
                tokens = NumberLines([([], text)], startline, endline)
                for classes, value in tokens:
                    if classes:
                        literal_block += nodes.inline(value,
                                                      value,
                                                      classes=classes)
                    else:
                        literal_block += nodes.Text(value, value)
            else:
                literal_block += nodes.Text(text, text)
            return [literal_block]
        if 'code' in self.options:
            self.options['source'] = path
            codeblock = CodeBlock(
                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 []
Exemplo n.º 10
0
                       '(wrong locale?).' %
                       (self.name, SafeString(path)))
 except IOError, error:
     raise self.severe(u'Problems with "%s" directive path:\n%s.' %
               (self.name, ErrorString(error)))
 startline = self.options.get('start-line', None)
 endline = self.options.get('end-line', None)
 try:
     if startline or (endline is not None):
         lines = include_file.readlines()
         rawtext = ''.join(lines[startline:endline])
     else:
         rawtext = include_file.read()
 except UnicodeError, error:
     raise self.severe(u'Problem with "%s" directive:\n%s' %
                       (self.name, ErrorString(error)))
 # start-after/end-before: no restrictions on newlines in match-text,
 # and no restrictions on matching inside lines vs. line boundaries
 after_text = self.options.get('start-after', None)
 if after_text:
     # skip content in rawtext before *and incl.* a matching text
     after_index = rawtext.find(after_text)
     if after_index < 0:
         raise self.severe('Problem with "start-after" option of "%s" '
                           'directive:\nText not found.' % self.name)
     rawtext = rawtext[after_index + len(after_text):]
 before_text = self.options.get('end-before', None)
 if before_text:
     # skip content in rawtext after *and incl.* a matching text
     before_index = rawtext.find(before_text)
     if before_index < 0:
Exemplo n.º 11
0
    def run(self):
        if not isinstance(self.config.tsn_include_mapping, dict):
            raise self.severe('Invalid "tsn_include_mapping" config')

        docset = self.options.get('docset', None)
        if docset is not None and \
                docset not in self.config.tsn_include_mapping:
            raise self.severe('The supplied "docset" was not found: "%s"' %
                              docset)

        indent = self.options.get('indent', 0)
        dedent = self.options.get('dedent', 0)
        auto_dedent = 'auto-dedent' in self.options

        if indent and (dedent or auto_dedent):
            raise self.severe('Both "indent" and one of the "dedent" options '
                              'are set, please use only one')

        if dedent and auto_dedent:
            raise self.severe('Choose one of "dedent" and "auto-dedent" only')

        if not self.state.document.settings.file_insertion_enabled:
            raise self.warning('"%s" directive disabled.' % self.name)

        if docset is None:
            # without a docset fallback to Sphinx style include
            _, path = self.env.relfn2path(self.arguments[0])
        else:
            path = os.path.join(self.config.tsn_include_mapping[docset],
                                self.arguments[0])

        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:
            raise self.severe('Problems with "%s" directive path:\n'
                              'Cannot encode input file path "%s" '
                              '(wrong locale?).' %
                              (self.name, SafeString(path)))
        except IOError as error:
            raise self.severe('Problems with "%s" directive path:\n%s.' %
                              (self.name, ErrorString(error)))

        # Get to-be-included content
        startline = self.options.get('start-line', None)
        endline = self.options.get('end-line', None)
        try:
            if startline or (endline is not None):
                lines = include_file.readlines()
                rawtext = ''.join(lines[startline:endline])
            else:
                rawtext = include_file.read()
        except UnicodeError as error:
            raise self.severe(u'Problem with "%s" directive:\n%s' %
                              (self.name, ErrorString(error)))
        # start-after/end-before: no restrictions on newlines in match-text,
        # and no restrictions on matching inside lines vs. line boundaries
        after_text = self.options.get('start-after', None)
        if after_text:
            # skip content in rawtext before *and incl.* a matching text
            after_index = rawtext.find(after_text)
            if after_index < 0:
                raise self.severe('Problem with "start-after" option of "%s" '
                                  'directive:\nText not found.' % self.name)
            rawtext = rawtext[after_index + len(after_text):]
        before_text = self.options.get('end-before', None)
        if before_text:
            # skip content in rawtext after *and incl.* a matching text
            before_index = rawtext.find(before_text)
            if before_index < 0:
                raise self.severe('Problem with "end-before" option of "%s" '
                                  'directive:\nText not found.' % self.name)
            rawtext = rawtext[:before_index]

        include_lines = statemachine.string2lines(rawtext,
                                                  tab_width,
                                                  convert_whitespace=True)

        def is_blank(line):
            # XXX might need to check for a stripped line
            return len(line) == 0

        if auto_dedent:
            min_spaces = None
            for i, line in enumerate(include_lines):
                if is_blank(line):
                    continue
                spaces = len(line) - len(line.lstrip(' '))
                if min_spaces is None:
                    min_spaces = spaces
                else:
                    min_spaces = min(spaces, min_spaces)
                print(min_spaces, line)
                # it can't get smaller, so leave early
                if min_spaces == 0:
                    break
            amount = min_spaces

            for i, line in enumerate(include_lines):
                if is_blank(line):
                    continue
                include_lines[i] = line[amount:]

        if dedent:
            for i, line in enumerate(include_lines):
                if is_blank(line):
                    continue
                spaces = len(line) - len(line.lstrip())
                amount = min(spaces, dedent)
                include_lines[i] = line[amount:]

        if indent:
            spaces = ' ' * indent
            for i, line in enumerate(include_lines):
                if is_blank(line):
                    continue
                include_lines[i] = spaces + line

        self.state_machine.insert_input(include_lines, path)
        return []
    def run(self):
        """Include a file as part of the content of this reST file."""
        if not self.state.document.settings.file_insertion_enabled:
            raise self.warning('"%s" directive disabled.' % self.name)
        source = self.state_machine.input_lines.source(
            self.lineno - self.state_machine.input_offset - 1)
        source_dir = os.path.dirname(os.path.abspath(source))
        path = directives.path(self.arguments[0])
        if path.startswith("<") and path.endswith(">"):
            path = os.path.join(self.standard_include_path, path[1:-1])
        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(u'Problems with "%s" directive path:\n'
                              'Cannot encode input file path "%s" '
                              "(wrong locale?)." %
                              (self.name, SafeString(path)))
        except IOError as error:
            raise self.severe(u'Problems with "%s" directive path:\n%s.' %
                              (self.name, ErrorString(error)))
        startline = self.options.get("start-line", None)
        endline = self.options.get("end-line", None)
        try:
            if startline or (endline is not None):
                lines = include_file.readlines()
                rawtext = "".join(lines[startline:endline])
            else:
                rawtext = include_file.read()
        except UnicodeError as error:
            raise self.severe(u'Problem with "%s" directive:\n%s' %
                              (self.name, ErrorString(error)))
        # start-after/end-before: no restrictions on newlines in match-text,
        # and no restrictions on matching inside lines vs. line boundaries
        after_text = self.options.get("start-after", None)
        if after_text:
            # skip content in rawtext before *and incl.* a matching text
            after_index = rawtext.find(after_text)
            if after_index < 0:
                raise self.severe('Problem with "start-after" option of "%s" '
                                  "directive:\nText not found." % self.name)
            rawtext = rawtext[after_index + len(after_text):]
        before_text = self.options.get("end-before", None)
        if before_text:
            # skip content in rawtext after *and incl.* a matching text
            before_index = rawtext.find(before_text)
            if before_index < 0:
                raise self.severe('Problem with "end-before" option of "%s" '
                                  "directive:\nText not found." % self.name)
            rawtext = rawtext[:before_index]

        # **Added code** from here...
        ##---------------------------
        # Only Sphinx has the ``env`` attribute.
        env = getattr(self.state.document.settings, "env", None)

        # If the lexer is specified, include it.
        code_to_rest_options = {}
        lexer_alias = self.options.get("lexer")
        if lexer_alias:
            code_to_rest_options["alias"] = lexer_alias
        elif env:
            # If Sphinx is running, try getting a user-specified lexer from the Sphinx configuration.
            lfg = env.app.config.CodeChat_lexer_for_glob
            for glob, lexer_alias in lfg.items():
                if Path(path).match(glob):
                    code_to_rest_options["alias"] = lexer_alias

        # Translate the source code to reST.
        lexer = get_lexer(filename=path, code=rawtext, **code_to_rest_options)
        rawtext = code_to_rest_string(rawtext, lexer=lexer)

        # If the ``class`` option is specified, wrap the code in a div with the specified classes.
        classes = self.options.get("class")
        if classes:
            rawtext = (".. raw:: html\n"
                       "\n"
                       " <div class='" + html.escape(" ".join(classes)) +
                       "'>\n"
                       "\n" + rawtext + "\n"
                       ".. raw:: html\n"
                       "\n"
                       " </div>\n")

        # If Sphinx is running, insert the appropriate highlight directive.
        if env:
            rawtext = add_highlight_language(rawtext, lexer)
        ##------------
        # ... to here.

        include_lines = statemachine.string2lines(rawtext,
                                                  tab_width,
                                                  convert_whitespace=True)
        # **Deleted code**: Options for ``literal`` and ``code`` don't apply.
        self.state_machine.insert_input(include_lines, path)
        return []
Exemplo n.º 13
0
    def run(self):

        if len(self.arguments) > 0:
            key = self.arguments[0]
        else:
            raise SphinxError('Missing active element input id')

        env = self.state.document.settings.env

        name = u"{}_{}".format(env.docname.replace(u'/', u'_'), key)
        override = env.config.override

        classes = []
        if 'class' in self.options:
            classes.extend(self.options['class'])

        # Add document nodes.
        args = {
            u'class': u' '.join(classes),
            u'data-aplus-active-element': u'in',
            u'id': u'' + key,
        }

        if 'title' in self.options:
            args['data-title'] = self.options['title']

        if 'default' in self.options:
            args['data-default'] = self.options['default']

        if 'type' in self.options:
            args['data-type'] = self.options['type']

        if 'width' in self.options:
            args['style'] = 'width:' + self.options['width'] + ';'

        if 'height' in self.options:
            if 'style' not in args:
                args['style'] = 'height:' + self.options['height'] + ';'
            else:
                args['style'] = args['style'] + 'height:' + self.options[
                    'height'] + ';'

        if 'clear' in self.options:
            args['style'] = args['style'] + 'clear:' + self.options[
                'clear'] + ';'

        node = aplus_nodes.html(u'div', args)
        paragraph = aplus_nodes.html(u'p', {})
        paragraph.append(
            nodes.Text(translations.get(env, 'active_element_placeholder')))
        node.append(paragraph)

        # For clickable inputs the pre-generated html
        # needs to be added after the regular a+ exercise node
        if 'type' in self.options and self.options['type'] == 'clickable':
            if 'file' not in self.options:
                logger.warning(
                    'Clickable active element input "{}" missing template file.'
                    .format(name),
                    location=node)
                return [node]

            # Read given html file (from docutils.directives.misc.raw)
            source_dir = os.path.dirname(
                os.path.abspath(self.state.document.current_source))
            path = os.path.join(env.app.srcdir, self.options['file'])
            path = utils.relative_path(None, path)
            try:
                raw_file = io.FileInput(
                    source_path=path,
                    encoding=self.state.document.settings.input_encoding,
                    error_handler=self.state.document.settings.
                    input_encoding_error_handler)
            except IOError as error:
                logger.error(u'Problem with "%s" directive:\n%s.' %
                             (self.name, ErrorString(error)),
                             location=node)
                return []
            try:
                text = raw_file.read()
            except UnicodeError as error:
                logger.error(u'Problem with "%s" directive:\n%s.' %
                             (self.name, ErrorString(error)),
                             location=node)
                return []

            # Generate raw node
            rawnode = nodes.raw('', text, **{'format': 'html'})
            wrapnode = aplus_nodes.html(u'div', {
                u'id': u'' + key + '-wrap',
                u'class': u'clickable-ae-wrapper'
            })
            wrapnode.append(node)
            wrapnode.append(rawnode)
            return [wrapnode]

        return [node]
Exemplo n.º 14
0
Arquivo: cmake.py Projeto: zpc930/CGAL
    def run(self):
        settings = self.state.document.settings
        if not settings.file_insertion_enabled:
            raise self.warning('"%s" directive disabled.' % self.name)

        env = self.state.document.settings.env
        rel_path, path = env.relfn2path(self.arguments[0])
        path = os.path.normpath(path)
        encoding = self.options.get('encoding', settings.input_encoding)
        e_handler = settings.input_encoding_error_handler
        try:
            settings.record_dependencies.add(path)
            f = io.FileInput(source_path=path,
                             encoding=encoding,
                             error_handler=e_handler)
        except UnicodeEncodeError as error:
            raise self.severe('Problems with "%s" directive path:\n'
                              'Cannot encode input file path "%s" '
                              '(wrong locale?).' %
                              (self.name, SafeString(path)))
        except IOError as error:
            raise self.severe('Problems with "%s" directive path:\n%s.' %
                              (self.name, ErrorString(error)))
        raw_lines = f.read().splitlines()
        f.close()
        rst = None
        lines = []
        for line in raw_lines:
            if rst is not None and rst != '#':
                # Bracket mode: check for end bracket
                pos = line.find(rst)
                if pos >= 0:
                    if line[0] == '#':
                        line = ''
                    else:
                        line = line[0:pos]
                    rst = None
            else:
                # Line mode: check for .rst start (bracket or line)
                m = self.re_start.match(line)
                if m:
                    rst = ']%s]' % m.group('eq')
                    line = ''
                elif line == '#.rst:':
                    rst = '#'
                    line = ''
                elif rst == '#':
                    if line == '#' or line[:2] == '# ':
                        line = line[2:]
                    else:
                        rst = None
                        line = ''
                elif rst is None:
                    line = ''
            lines.append(line)
        if rst is not None and rst != '#':
            raise self.warning(
                '"%s" found unclosed bracket "#[%s[.rst:" in %s' %
                (self.name, rst[1:-1], path))
        self.state_machine.insert_input(lines, path)
        return []
Exemplo n.º 15
0
    def run(self):
        """Include a file as part of the content of this reST file."""
        if not self.state.document.settings.file_insertion_enabled:
            raise self.warning('"%s" directive disabled.' % self.name)
        source = self.state_machine.input_lines.source(
            self.lineno - self.state_machine.input_offset - 1)
        source_dir = os.path.dirname(os.path.abspath(source))

        path = directives.path(self.arguments[0])
        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'
                              'Cannot encode input file path "%s" '
                              '(wrong locale?).' %
                              (self.name, SafeString(path)))
        except IOError as error:
            raise self.severe('Problems with "%s" directive path:\n%s.' %
                              (self.name, ErrorString(error)))
        startline = self.options.get('start-line', None)
        endline = self.options.get('end-line', None)
        try:
            if startline or (endline is not None):
                lines = include_file.readlines()
                rawtext = ''.join(lines[startline:endline])
            else:
                rawtext = include_file.read()
        except UnicodeError as error:
            raise self.severe('Problem with "%s" directive:\n%s' %
                              (self.name, ErrorString(error)))

        include_lines = statemachine.string2lines(rawtext,
                                                  tab_width,
                                                  convert_whitespace=True)

        # default lexer to 'text'
        lexer = self.options.get('lexer', 'text')

        self.options['source'] = path
        codeblock = Pygments(
            self.name,
            [lexer],  # arguments
            {},  # no options for this directive
            include_lines,  # content
            self.lineno,
            self.content_offset,
            self.block_text,
            self.state,
            self.state_machine)
        return codeblock.run()
Exemplo n.º 16
0
    def _run(self):
        """Include a file as part of the content of this reST file."""

        # HINT: I had to copy&paste the whole Include.run method. I'am not happy
        # with this, but due to security reasons, the Include.run method does
        # not allow absolute or relative pathnames pointing to locations *above*
        # the filesystem tree where the reST document is placed.

        if not self.state.document.settings.file_insertion_enabled:
            raise self.warning('"%s" directive disabled.' % self.name)
        source = self.state_machine.input_lines.source(
            self.lineno - self.state_machine.input_offset - 1)
        source_dir = os.path.dirname(os.path.abspath(source))
        path = directives.path(self.arguments[0])
        if path.startswith('<') and path.endswith('>'):
            path = os.path.join(self.standard_include_path, path[1:-1])
        path = os.path.normpath(os.path.join(source_dir, path))

        # HINT: this is the only line I had to change / commented out:
        #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'
                              'Cannot encode input file path "%s" '
                              '(wrong locale?).' %
                              (self.name, SafeString(path)))
        except IOError as error:
            raise self.severe('Problems with "%s" directive path:\n%s.' %
                      (self.name, ErrorString(error)))
        startline = self.options.get('start-line', None)
        endline = self.options.get('end-line', None)
        try:
            if startline or (endline is not None):
                lines = include_file.readlines()
                rawtext = ''.join(lines[startline:endline])
            else:
                rawtext = include_file.read()
        except UnicodeError as error:
            raise self.severe('Problem with "%s" directive:\n%s' %
                              (self.name, ErrorString(error)))
        # start-after/end-before: no restrictions on newlines in match-text,
        # and no restrictions on matching inside lines vs. line boundaries
        after_text = self.options.get('start-after', None)
        if after_text:
            # skip content in rawtext before *and incl.* a matching text
            after_index = rawtext.find(after_text)
            if after_index < 0:
                raise self.severe('Problem with "start-after" option of "%s" '
                                  'directive:\nText not found.' % self.name)
            rawtext = rawtext[after_index + len(after_text):]
        before_text = self.options.get('end-before', None)
        if before_text:
            # skip content in rawtext after *and incl.* a matching text
            before_index = rawtext.find(before_text)
            if before_index < 0:
                raise self.severe('Problem with "end-before" option of "%s" '
                                  'directive:\nText not found.' % self.name)
            rawtext = rawtext[:before_index]

        include_lines = statemachine.string2lines(rawtext, tab_width,
                                                  convert_whitespace=True)
        if 'literal' in self.options:
            # Convert tabs to spaces, if `tab_width` is positive.
            if tab_width >= 0:
                text = rawtext.expandtabs(tab_width)
            else:
                text = rawtext
            literal_block = nodes.literal_block(rawtext, source=path,
                                    classes=self.options.get('class', []))
            literal_block.line = 1
            self.add_name(literal_block)
            if 'number-lines' in self.options:
                try:
                    startline = int(self.options['number-lines'] or 1)
                except ValueError:
                    raise self.error(':number-lines: with non-integer '
                                     'start value')
                endline = startline + len(include_lines)
                if text.endswith('\n'):
                    text = text[:-1]
                tokens = NumberLines([([], text)], startline, endline)
                for classes, value in tokens:
                    if classes:
                        literal_block += nodes.inline(value, value,
                                                      classes=classes)
                    else:
                        literal_block += nodes.Text(value, value)
            else:
                literal_block += nodes.Text(text, text)
            return [literal_block]
        if 'code' in self.options:
            self.options['source'] = path
            codeblock = CodeBlock(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 []
Exemplo n.º 17
0
                try:
                    self.destination.buffer.write(data)
                except AttributeError:
                    if check_encoding(self.destination,
                                      self.encoding) is False:
                        raise ValueError(
                            'Encoding of %s (%s) differs \n'
                            '  from specified encoding (%s)' %
                            (self.destination_path or 'destination',
                             self.destination.encoding, self.encoding))
                    else:
                        raise e
        except (UnicodeError, LookupError), err:
            raise UnicodeError(
                'Unable to encode output data. output-encoding is: '
                '%s.\n(%s)' % (self.encoding, ErrorString(err)))
        finally:
            if self.autoclose:
                self.close()
        return data

    def close(self):
        if self.destination not in (sys.stdout, sys.stderr):
            self.destination.close()
            self.opened = False


class BinaryFileOutput(FileOutput):
    """
    A version of docutils.io.FileOutput which writes to a binary file.
    """
Exemplo n.º 18
0
 def run(self):
     if (not self.state.document.settings.raw_enabled
             or (not self.state.document.settings.file_insertion_enabled and
                 ('file' in self.options or 'url' in self.options))):
         raise self.warning('"%s" directive disabled.' % self.name)
     attributes = {'format': ' '.join(self.arguments[0].lower().split())}
     encoding = self.options.get(
         'encoding', self.state.document.settings.input_encoding)
     e_handler = self.state.document.settings.input_encoding_error_handler
     if self.content:
         if 'file' in self.options or 'url' in self.options:
             raise self.error(
                 '"%s" directive may not both specify an external file '
                 'and have content.' % self.name)
         text = '\n'.join(self.content)
     elif 'file' in self.options:
         if 'url' in self.options:
             raise self.error(
                 'The "file" and "url" options may not be simultaneously '
                 'specified for the "%s" directive.' % self.name)
         source_dir = os.path.dirname(
             os.path.abspath(self.state.document.current_source))
         path = os.path.normpath(
             os.path.join(source_dir, self.options['file']))
         path = utils.relative_path(None, path)
         try:
             raw_file = io.FileInput(source_path=path,
                                     encoding=encoding,
                                     error_handler=e_handler)
             # TODO: currently, raw input files are recorded as
             # dependencies even if not used for the chosen output format.
             self.state.document.settings.record_dependencies.add(path)
         except IOError as error:
             raise self.severe(u'Problems with "%s" directive path:\n%s.' %
                               (self.name, ErrorString(error)))
         try:
             text = raw_file.read()
         except UnicodeError as error:
             raise self.severe(u'Problem with "%s" directive:\n%s' %
                               (self.name, ErrorString(error)))
         attributes['source'] = path
     elif 'url' in self.options:
         source = self.options['url']
         # Do not import urllib2 at the top of the module because
         # it may fail due to broken SSL dependencies, and it takes
         # about 0.15 seconds to load.
         if sys.version_info >= (3, 0):
             from urllib.request import urlopen
             from urllib.error import URLError
         else:
             from urllib2 import urlopen, URLError
         try:
             raw_text = urlopen(source).read()
         except (URLError, IOError, OSError) as error:
             raise self.severe(
                 u'Problems with "%s" directive URL "%s":\n%s.' %
                 (self.name, self.options['url'], ErrorString(error)))
         raw_file = io.StringInput(source=raw_text,
                                   source_path=source,
                                   encoding=encoding,
                                   error_handler=e_handler)
         try:
             text = raw_file.read()
         except UnicodeError as error:
             raise self.severe(u'Problem with "%s" directive:\n%s' %
                               (self.name, ErrorString(error)))
         attributes['source'] = source
     else:
         # This will always fail because there is no content.
         self.assert_has_content()
     raw_node = nodes.raw('', text, **attributes)
     (raw_node.source,
      raw_node.line) = self.state_machine.get_source_and_line(self.lineno)
     return [raw_node]
Exemplo n.º 19
0
    def run(self):
        """Include a file as part of the content of this reST file."""

        # Direct copy from Include with changes noted.

        if not self.state.document.settings.file_insertion_enabled:
            raise self.warning('"%s" directive disabled.' % self.name)
        source = self.state_machine.input_lines.source(
            self.lineno - self.state_machine.input_offset - 1)
        source_dir = os.path.dirname(os.path.abspath(source))

        # CHANGE: for some reason the arg to the include directive is expanded to
        # the full path for the docutils Include directive, but for ours, it
        # remains unchanged from the value supplied in the source, so we have to
        # expand it ourselves
        env = self.state.document.settings.env
        if not os.path.exists(self.arguments[0]):
            self.arguments[0] = env.srcdir + self.arguments[0]

        path = directives.path(self.arguments[0])
        if path.startswith('<') and path.endswith('>'):
            path = os.path.join(self.standard_include_path, path[1:-1])

        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'
                              'Cannot encode input file path "%s" '
                              '(wrong locale?).' %
                              (self.name, SafeString(path)))
        except IOError as error:
            raise self.severe('Problems with "%s" directive path:\n%s.' %
                              (self.name, ErrorString(error)))
        startline = self.options.get('start-line', None)
        endline = self.options.get('end-line', None)
        try:
            if startline or (endline is not None):
                lines = include_file.readlines()
                rawtext = ''.join(lines[startline:endline])
            else:
                rawtext = include_file.read()
        except UnicodeError as error:
            raise self.severe('Problem with "%s" directive:\n%s' %
                              (self.name, ErrorString(error)))
        # start-after/end-before: no restrictions on newlines in match-text,
        # and no restrictions on matching inside lines vs. line boundaries
        after_text = self.options.get('start-after', None)
        if after_text:
            # skip content in rawtext before *and incl.* a matching text
            after_index = rawtext.find(after_text)
            if after_index < 0:
                raise self.severe('Problem with "start-after" option of "%s" '
                                  'directive:\nText not found.' % self.name)
            rawtext = rawtext[after_index + len(after_text):]
        before_text = self.options.get('end-before', None)
        if before_text:
            # skip content in rawtext after *and incl.* a matching text
            before_index = rawtext.find(before_text)
            if before_index < 0:
                raise self.severe('Problem with "end-before" option of "%s" '
                                  'directive:\nText not found.' % self.name)
            rawtext = rawtext[:before_index]

        include_lines = statemachine.string2lines(rawtext,
                                                  tab_width,
                                                  convert_whitespace=True)
        if 'literal' in self.options:
            # Convert tabs to spaces, if `tab_width` is positive.
            if tab_width >= 0:
                text = rawtext.expandtabs(tab_width)
            else:
                text = rawtext
            literal_block = nodes.literal_block(rawtext,
                                                source=path,
                                                classes=self.options.get(
                                                    'class', []))
            literal_block.line = 1
            self.add_name(literal_block)
            if 'number-lines' in self.options:
                try:
                    startline = int(self.options['number-lines'] or 1)
                except ValueError:
                    raise self.error(':number-lines: with non-integer '
                                     'start value')
                endline = startline + len(include_lines)
                if text.endswith('\n'):
                    text = text[:-1]
                tokens = NumberLines([([], text)], startline, endline)
                for classes, value in tokens:
                    if classes:
                        literal_block += nodes.inline(value,
                                                      value,
                                                      classes=classes)
                    else:
                        literal_block += nodes.Text(value, value)
            else:
                literal_block += nodes.Text(text, text)
            return [literal_block]

        if 'code' in self.options:
            self.options['source'] = path
            codeblock = CodeBlock(
                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()

        # CHANGE: add the suffixes to all the references (only do it for vimdocs)
        if isinstance(env.app.builder,
                      VimdocBuilder) and 'ref-suffix' in self.options:
            suffix = self.options['ref-suffix']
            for i, line in enumerate(include_lines):
                # relying on a regex is gross, but it's easy and we just have to worry
                # about the eclim docs, so it'll do.
                match = self.REF.match(line)
                if match:
                    include_lines[i] = '%s_%s%s' % (match.group(1), suffix,
                                                    match.group(2))

        self.state_machine.insert_input(include_lines, path)
        return []