tables.py

来自「Requirement ===========================」· Python 代码 · 共 445 行 · 第 1/2 页

PY
445
字号
    elif options.has_key('url'):        # CSV data is from a URL        if not urllib2:            severe = state_machine.reporter.severe(                  'Problems with the "%s" directive and its "url" option: '                  'unable to access the required functionality (from the '                  '"urllib2" module).' % name,                  nodes.literal_block(block_text, block_text), line=lineno)            raise SystemMessagePropagation(severe)        source = options['url']        try:            csv_text = urllib2.urlopen(source).read()        except (urllib2.URLError, IOError, OSError, ValueError), error:            severe = state_machine.reporter.severe(                  'Problems with "%s" directive URL "%s":\n%s.'                  % (name, options['url'], error),                  nodes.literal_block(block_text, block_text), line=lineno)            raise SystemMessagePropagation(severe)        csv_file = io.StringInput(            source=csv_text, source_path=source, encoding=encoding,            error_handler=state.document.settings.input_encoding_error_handler)        csv_data = csv_file.read().splitlines()    else:        error = state_machine.reporter.warning(            'The "%s" directive requires content; none supplied.' % (name),            nodes.literal_block(block_text, block_text), line=lineno)        raise SystemMessagePropagation(error)    return csv_data, sourcedef process_header_option(options, state_machine, lineno):    source = state_machine.get_source(lineno - 1)    table_head = []    max_header_cols = 0    if options.has_key('header'):       # separate table header in option        rows, max_header_cols = parse_csv_data_into_rows(            options['header'].split('\n'), HeaderDialect(), source, options)        table_head.extend(rows)    return table_head, max_header_colsdef parse_csv_data_into_rows(csv_data, dialect, source, options):    # csv.py doesn't do Unicode; encode temporarily as UTF-8    csv_reader = csv.reader([line.encode('utf-8') for line in csv_data],                            dialect=dialect)    rows = []    max_cols = 0    for row in csv_reader:        row_data = []        for cell in row:            # decode UTF-8 back to Unicode            cell_text = unicode(cell, 'utf-8')            cell_data = (0, 0, 0, statemachine.StringList(                cell_text.splitlines(), source=source))            row_data.append(cell_data)        rows.append(row_data)        max_cols = max(max_cols, len(row))    return rows, max_colsdef check_table_dimensions(rows, header_rows, stub_columns, name, lineno,                           block_text, state_machine):    if len(rows) < header_rows:        error = state_machine.reporter.error(            '%s header row(s) specified but only %s row(s) of data supplied '            '("%s" directive).' % (header_rows, len(rows), name),            nodes.literal_block(block_text, block_text), line=lineno)        raise SystemMessagePropagation(error)    if len(rows) == header_rows > 0:        error = state_machine.reporter.error(            'Insufficient data supplied (%s row(s)); no data remaining for '            'table body, required by "%s" directive.' % (len(rows), name),            nodes.literal_block(block_text, block_text), line=lineno)        raise SystemMessagePropagation(error)    for row in rows:        if len(row) < stub_columns:            error = state_machine.reporter.error(                '%s stub column(s) specified but only %s columns(s) of data '                'supplied ("%s" directive).' % (stub_columns, len(row), name),                nodes.literal_block(block_text, block_text), line=lineno)            raise SystemMessagePropagation(error)        if len(row) == stub_columns > 0:            error = state_machine.reporter.error(                'Insufficient data supplied (%s columns(s)); no data remaining '                'for table body, required by "%s" directive.'                % (len(row), name),                nodes.literal_block(block_text, block_text), line=lineno)            raise SystemMessagePropagation(error)def get_column_widths(max_cols, name, options, lineno, block_text,                      state_machine):    if options.has_key('widths'):        col_widths = options['widths']        if len(col_widths) != max_cols:            error = state_machine.reporter.error(              '"%s" widths do not match the number of columns in table (%s).'              % (name, max_cols),              nodes.literal_block(block_text, block_text), line=lineno)            raise SystemMessagePropagation(error)    elif max_cols:        col_widths = [100 / max_cols] * max_cols    else:        error = state_machine.reporter.error(            'No table data detected in CSV file.',            nodes.literal_block(block_text, block_text), line=lineno)        raise SystemMessagePropagation(error)    return col_widthsdef extend_short_rows_with_empty_cells(columns, parts):    for part in parts:        for row in part:            if len(row) < columns:                row.extend([(0, 0, 0, [])] * (columns - len(row)))def list_table(name, arguments, options, content, lineno,               content_offset, block_text, state, state_machine):    """    Implement tables whose data is encoded as a uniform two-level bullet list.    For further ideas, see    http://docutils.sf.net/docs/dev/rst/alternatives.html#list-driven-tables    """     if not content:        error = state_machine.reporter.error(            'The "%s" directive is empty; content required.' % name,            nodes.literal_block(block_text, block_text), line=lineno)        return [error]    title, messages = make_title(arguments, state, lineno)    node = nodes.Element()          # anonymous container for parsing    state.nested_parse(content, content_offset, node)    try:        num_cols, col_widths = check_list_content(            node, name, options, content, lineno, block_text, state_machine)        table_data = [[item.children for item in row_list[0]]                      for row_list in node[0]]        header_rows = options.get('header-rows', 0) # default 0        stub_columns = options.get('stub-columns', 0) # default 0        check_table_dimensions(            table_data, header_rows, stub_columns, name, lineno,            block_text, state_machine)    except SystemMessagePropagation, detail:        return [detail.args[0]]    table_node = build_table_from_list(table_data, col_widths,                                       header_rows, stub_columns)    table_node['classes'] += options.get('class', [])    if title:        table_node.insert(0, title)    return [table_node] + messageslist_table.arguments = (0, 1, 1)list_table.options = {'header-rows': directives.nonnegative_int,                      'stub-columns': directives.nonnegative_int,                      'widths': directives.positive_int_list,                      'class': directives.class_option}list_table.content = 1def check_list_content(node, name, options, content, lineno, block_text,                       state_machine):    if len(node) != 1 or not isinstance(node[0], nodes.bullet_list):        error = state_machine.reporter.error(            'Error parsing content block for the "%s" directive: '            'exactly one bullet list expected.' % name,            nodes.literal_block(block_text, block_text), line=lineno)        raise SystemMessagePropagation(error)    list_node = node[0]    # Check for a uniform two-level bullet list:    for item_index in range(len(list_node)):        item = list_node[item_index]        if len(item) != 1 or not isinstance(item[0], nodes.bullet_list):            error = state_machine.reporter.error(                'Error parsing content block for the "%s" directive: '                'two-level bullet list expected, but row %s does not contain '                'a second-level bullet list.' % (name, item_index + 1),                nodes.literal_block(block_text, block_text), line=lineno)            raise SystemMessagePropagation(error)        elif item_index:            # ATTN pychecker users: num_cols is guaranteed to be set in the            # "else" clause below for item_index==0, before this branch is            # triggered.            if len(item[0]) != num_cols:                error = state_machine.reporter.error(                    'Error parsing content block for the "%s" directive: '                    'uniform two-level bullet list expected, but row %s does '                    'not contain the same number of items as row 1 (%s vs %s).'                    % (name, item_index + 1, len(item[0]), num_cols),                    nodes.literal_block(block_text, block_text), line=lineno)                raise SystemMessagePropagation(error)        else:            num_cols = len(item[0])    col_widths = get_column_widths(        num_cols, name, options, lineno, block_text, state_machine)    if len(col_widths) != num_cols:        error = state_machine.reporter.error(            'Error parsing "widths" option of the "%s" directive: '            'number of columns does not match the table data (%s vs %s).'            % (name, len(col_widths), num_cols),            nodes.literal_block(block_text, block_text), line=lineno)        raise SystemMessagePropagation(error)    return num_cols, col_widthsdef build_table_from_list(table_data, col_widths, header_rows, stub_columns):    table = nodes.table()    tgroup = nodes.tgroup(cols=len(col_widths))    table += tgroup    for col_width in col_widths:        colspec = nodes.colspec(colwidth=col_width)        if stub_columns:            colspec.attributes['stub'] = 1            stub_columns -= 1        tgroup += colspec    rows = []    for row in table_data:        row_node = nodes.row()        for cell in row:            entry = nodes.entry()            entry += cell            row_node += entry        rows.append(row_node)    if header_rows:        thead = nodes.thead()        thead.extend(rows[:header_rows])        tgroup += thead    tbody = nodes.tbody()    tbody.extend(rows[header_rows:])    tgroup += tbody    return table

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?