예제 #1
0
def render_usage(text):
    """
    Reformat a command line program's usage message to reStructuredText_.

    :param text: The plain text usage message (a string).
    :returns: The usage message rendered to reStructuredText_ (a string).
    """
    meta_variables = find_meta_variables(text)
    introduction, options = parse_usage(text)
    output = [render_paragraph(p, meta_variables) for p in introduction]
    if options:
        output.append('\n'.join([
            '.. csv-table::',
            '   :header: Option, Description',
            '   :widths: 30, 70',
            '',
        ]))
        csv_buffer = StringIO()
        csv_writer = csv.writer(csv_buffer)
        while options:
            variants = options.pop(0)
            description = options.pop(0)
            csv_writer.writerow([
                render_paragraph(variants, meta_variables),
                ('\n\n'.join(
                    render_paragraph(p, meta_variables)
                    for p in split_paragraphs(description))).rstrip(),
            ])
        csv_lines = csv_buffer.getvalue().splitlines()
        output.append('\n'.join('   %s' % l for l in csv_lines))
    logger.debug("Rendered output: %s", output)
    return '\n\n'.join(trim_empty_lines(o) for o in output)
예제 #2
0
def render_usage(text):
    """
    Reformat a command line program's usage message to reStructuredText_.

    :param text: The plain text usage message (a string).
    :returns: The usage message rendered to reStructuredText_ (a string).
    """
    meta_variables = find_meta_variables(text)
    introduction, options = parse_usage(text)
    output = [render_paragraph(p, meta_variables) for p in introduction]
    if options:
        output.append('\n'.join([
            '.. csv-table::',
            '   :header: Option, Description',
            '   :widths: 30, 70',
            '',
        ]))
        csv_buffer = StringIO()
        csv_writer = csv.writer(csv_buffer)
        while options:
            variants = options.pop(0)
            description = options.pop(0)
            csv_writer.writerow([
                render_paragraph(variants, meta_variables),
                '\n\n'.join(render_paragraph(p, meta_variables) for p in split_paragraphs(description)),
            ])
        csv_lines = csv_buffer.getvalue().splitlines()
        output.append('\n'.join('   %s' % l for l in csv_lines))
    logger.debug("Rendered output: %s", output)
    return '\n\n'.join(trim_empty_lines(o) for o in output)
예제 #3
0
    def format_text(self, include_password=True, use_colors=None, padding=True, filters=()):
        """
        Format :attr:`text` for viewing on a terminal.

        :param include_password: :data:`True` to include the password in the
                                 formatted text, :data:`False` to exclude the
                                 password from the formatted text.
        :param use_colors: :data:`True` to use ANSI escape sequences,
                           :data:`False` otherwise. When this is :data:`None`
                           :func:`~humanfriendly.terminal.terminal_supports_colors()`
                           will be used to detect whether ANSI escape sequences
                           are supported.
        :param padding: :data:`True` to add empty lines before and after the
                        entry and indent the entry's text with two spaces,
                        :data:`False` to skip the padding.
        :param filters: An iterable of regular expression patterns (defaults to
                        an empty tuple). If a line in the entry's text matches
                        one of these patterns it won't be shown on the
                        terminal.
        :returns: The formatted entry (a string).
        """
        # Determine whether we can use ANSI escape sequences.
        if use_colors is None:
            use_colors = terminal_supports_colors()
        # Extract the password (first line) from the entry.
        lines = self.text.splitlines()
        password = lines.pop(0).strip()
        # Compile the given patterns to case insensitive regular expressions
        # and use them to ignore lines that match any of the given filters.
        patterns = [coerce_pattern(f, re.IGNORECASE) for f in filters]
        lines = [l for l in lines if not any(p.search(l) for p in patterns)]
        text = trim_empty_lines("\n".join(lines))
        # Include the password in the formatted text?
        if include_password:
            text = "Password: %s\n%s" % (password, text)
        # Add the name to the entry (only when there's something to show).
        if text and not text.isspace():
            title = " / ".join(split(self.name, "/"))
            if use_colors:
                title = ansi_wrap(title, bold=True)
            text = "%s\n\n%s" % (title, text)
        # Highlight the entry's text using ANSI escape sequences.
        lines = []
        for line in text.splitlines():
            # Check for a "Key: Value" line.
            match = KEY_VALUE_PATTERN.match(line)
            if match:
                key = "%s:" % match.group(1).strip()
                value = match.group(2).strip()
                if use_colors:
                    # Highlight the key.
                    key = ansi_wrap(key, color=HIGHLIGHT_COLOR)
                    # Underline hyperlinks in the value.
                    tokens = value.split()
                    for i in range(len(tokens)):
                        if "://" in tokens[i]:
                            tokens[i] = ansi_wrap(tokens[i], underline=True)
                    # Replace the line with a highlighted version.
                    line = key + " " + " ".join(tokens)
            if padding:
                line = "  " + line
            lines.append(line)
        text = "\n".join(lines)
        text = trim_empty_lines(text)
        if text and padding:
            text = "\n%s\n" % text
        return text
예제 #4
0
    def format_text(self,
                    include_password=True,
                    use_colors=None,
                    padding=True):
        """
        Format :attr:`text` for viewing on a terminal.

        :param include_password: :data:`True` to include the password in the
                                 formatted text, :data:`False` to exclude the
                                 password from the formatted text.
        :param use_colors: :data:`True` to use ANSI escape sequences,
                           :data:`False` otherwise. When this is :data:`None`
                           :func:`~humanfriendly.terminal.terminal_supports_colors()`
                           will be used to detect whether ANSI escape sequences
                           are supported.
        :param padding: :data:`True` to add empty lines before and after the
                        entry and indent the entry's text with two spaces,
                        :data:`False` to skip the padding.
        :returns: The formatted entry (a string).
        """
        # Determine whether we can use ANSI escape sequences.
        if use_colors is None:
            use_colors = terminal_supports_colors()
        # Extract the password (first line) from the entry.
        lines = self.text.splitlines()
        password = lines.pop(0).strip()
        text = trim_empty_lines('\n'.join(lines))
        # Include the password in the formatted text?
        if include_password:
            text = "Password: %s\n%s" % (password, text)
        # Add the name to the entry (only when there's something to show).
        if text and not text.isspace():
            title = ' / '.join(split(self.name, '/'))
            if use_colors:
                title = ansi_wrap(title, bold=True)
            text = "%s\n\n%s" % (title, text)
        # Highlight the entry's text using ANSI escape sequences.
        lines = []
        for line in text.splitlines():
            # Check for a "Key: Value" line.
            match = KEY_VALUE_PATTERN.match(line)
            if match:
                key = "%s:" % match.group(1).strip()
                value = match.group(2).strip()
                if use_colors:
                    # Highlight the key.
                    key = ansi_wrap(key, color=HIGHLIGHT_COLOR)
                    # Underline hyperlinks in the value.
                    tokens = value.split()
                    for i in range(len(tokens)):
                        if '://' in tokens[i]:
                            tokens[i] = ansi_wrap(tokens[i], underline=True)
                    # Replace the line with a highlighted version.
                    line = key + ' ' + ' '.join(tokens)
            if padding:
                line = '  ' + line
            lines.append(line)
        text = '\n'.join(lines)
        if text and padding:
            text = '\n%s\n' % text
        return text