From b514245823ade13164c47f8cdc769d5a358611c7 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 18 Jun 2004 21:41:31 +0000 Subject: table-related directives git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2309 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 269 ++++++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 docutils/parsers/rst/directives/tables.py (limited to 'docutils/parsers/rst/directives/tables.py') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py new file mode 100644 index 000000000..90c392117 --- /dev/null +++ b/docutils/parsers/rst/directives/tables.py @@ -0,0 +1,269 @@ +# Authors: David Goodger, David Priest +# Contact: goodger@python.org +# Revision: $Revision$ +# Date: $Date$ +# Copyright: This module has been placed in the public domain. + +""" +Directives for table elements. +""" + +__docformat__ = 'reStructuredText' + + +import sys +import os.path +import csv +from docutils import nodes, statemachine, utils +from docutils.utils import SystemMessagePropagation +from docutils.parsers.rst import directives + +try: + import urllib2 +except ImportError: + urllib2 = None + +try: + True +except NameError: # Python 2.2 & 2.1 compatibility + True = not 0 + False = not 1 + + +def table(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + if not content: + warning = state_machine.reporter.warning( + 'Content block expected for the "%s" directive; none found.' + % name, nodes.literal_block(block_text, block_text), + line=lineno) + return [warning] + title, messages = make_title(arguments, state, lineno) + node = nodes.Element() # anonymous container for parsing + text = '\n'.join(content) + state.nested_parse(content, content_offset, node) + if len(node) != 1 or not isinstance(node[0], nodes.table): + error = state_machine.reporter.error( + 'Error parsing content block for the "%s" directive: ' + 'exactly one table expected.' + % name, nodes.literal_block(block_text, block_text), + line=lineno) + return [error] + table_node = node[0] + if options.has_key('class'): + table_node.set_class(options['class']) + if title: + table_node.insert(0, title) + return [table_node] + messages + +table.arguments = (0, 1, 1) +table.options = {'class': directives.class_option} +table.content = 1 + +def make_title(arguments, state, lineno): + if arguments: + title_text = arguments[0] + text_nodes, messages = state.inline_text(title_text, lineno) + title = nodes.title(title_text, '', *text_nodes) + else: + title = None + messages = [] + return title, messages + + +class DocutilsDialect(csv.Dialect): + + """CSV dialect for `csv_table` directive function.""" + + delimiter = ',' + quotechar = '"' + doublequote = True + skipinitialspace = True + lineterminator = '\n' + quoting = csv.QUOTE_MINIMAL + + def __init__(self, options): + if options.has_key('delim'): + self.delimiter = str(options['delim']) + if options.has_key('keepspace'): + self.skipinitialspace = False + if options.has_key('quote'): + self.quotechar = str(options['quote']) + if options.has_key('escape'): + self.doublequote = False + self.escapechar = str(options['escape']) + csv.Dialect.__init__(self) + + +class HeaderDialect(csv.Dialect): + + """CSV dialect to use for the "header" option data.""" + + delimiter = ',' + quotechar = '"' + escapechar = '\\' + doublequote = False + skipinitialspace = True + lineterminator = '\n' + quoting = csv.QUOTE_MINIMAL + + +def csv_table(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + + title, messages = make_title(arguments, state, lineno) + try: + csv_data, source = get_csv_data( + name, options, content, lineno, block_text, state, state_machine) + table_head, max_header_cols = process_header_option( + options, state_machine, lineno) + rows, max_cols = parse_csv_data_into_rows( + csv_data, DocutilsDialect(options), source, options) + max_cols = max(max_cols, max_header_cols) + header_rows = options.get('header-rows', 0) # default 0 + table_head.extend(rows[:header_rows]) + table_body = rows[header_rows:] + if not table_body: + error = state_machine.reporter.error( + '"%s" directive requires table body content.' % name, + nodes.literal_block(block_text, block_text), line=lineno) + return [error] + col_widths = get_column_widths( + max_cols, name, options, lineno, block_text, state_machine) + extend_short_rows_with_empty_cells(max_cols, (table_head, table_body)) + except SystemMessagePropagation, detail: + return [detail.args[0]] + except csv.Error, detail: + error = state_machine.reporter.error( + 'Error with CSV data in "%s" directive:\n%s' % (name, detail), + nodes.literal_block(block_text, block_text), line=lineno) + return [error] + table = (col_widths, table_head, table_body) + table_node = state.build_table(table, content_offset) + if options.has_key('class'): + table_node.set_class(options['class']) + if title: + table_node.insert(0, title) + return [table_node] + messages + +csv_table.arguments = (0, 1, 1) +csv_table.options = {'header-rows': directives.nonnegative_int, + 'header': directives.unchanged, + 'widths': directives.positive_int_list, + 'file': directives.path, + 'url': directives.path, + 'class': directives.class_option, + # field delimiter char + 'delim': directives.single_char_or_whitespace_or_unicode, + # treat whitespace after delimiter as significant + 'keepspace': directives.flag, + # text field quote/unquote char: + 'quote': directives.single_char_or_unicode, + # char used to escape delim & quote as-needed: + 'escape': directives.single_char_or_unicode,} +csv_table.content = 1 + +def get_csv_data(name, options, content, lineno, block_text, + state, state_machine): + """ + CSV data can come from the directive content, from an external file, or + from a URL reference. + """ + if content: # CSV data is from directive content + if options.has_key('file') or options.has_key('url'): + error = state_machine.reporter.error( + '"%s" directive may not both specify an external file and ' + 'have content.' % name, + nodes.literal_block(block_text, block_text), line=lineno) + raise SystemMessagePropagation(error) + source = content.source(0) + csv_data = content + elif options.has_key('file'): # CSV data is from an external file + if options.has_key('url'): + error = state_machine.reporter.error( + 'The "file" and "url" options may not be simultaneously ' + 'specified for the "%s" directive.' % name, + nodes.literal_block(block_text, block_text), line=lineno) + raise SystemMessagePropagation(error) + source_dir = os.path.dirname( + os.path.abspath(state.document.current_source)) + source = os.path.normpath(os.path.join(source_dir, options['file'])) + source = utils.relative_path(None, source) + try: + csv_file = open(source, 'rb') + try: + csv_data = csv_file.read().splitlines() + finally: + csv_file.close() + except IOError, error: + severe = state_machine.reporter.severe( + 'Problems with "%s" directive path:\n%s.' % (name, error), + nodes.literal_block(block_text, block_text), line=lineno) + raise SystemMessagePropagation(severe) + 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_data = urllib2.urlopen(source).read().splitlines() + 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) + 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, source + +def 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_cols + +def parse_csv_data_into_rows(csv_data, dialect, source, options): + csv_reader = csv.reader(csv_data, dialect=dialect) + rows = [] + max_cols = 0 + for row in csv_reader: + row_data = [] + for cell in row: + cell_data = (0, 0, 0, statemachine.StringList(cell.splitlines(), + source=source)) + row_data.append(cell_data) + rows.append(row_data) + max_cols = max(max_cols, len(row)) + return rows, max_cols + +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) + else: + col_widths = [100 / max_cols] * max_cols + return col_widths + +def 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))) -- cgit v1.2.1 From f2b64c0ff06f8682e71bc5bd12098b2f4a5d53b8 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 19 Jun 2004 22:53:32 +0000 Subject: added checks for cvs.py module (Python 2.3+), and table dimensions; added guarding for Python 2.1/2.2 (no CSV support) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2314 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 98 +++++++++++++++++++------------ 1 file changed, 62 insertions(+), 36 deletions(-) (limited to 'docutils/parsers/rst/directives/tables.py') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 90c392117..e34e54b20 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -13,11 +13,15 @@ __docformat__ = 'reStructuredText' import sys import os.path -import csv from docutils import nodes, statemachine, utils from docutils.utils import SystemMessagePropagation from docutils.parsers.rst import directives +try: + import csv # new in Python 2.3 +except ImportError: + csv = None + try: import urllib2 except ImportError: @@ -71,48 +75,49 @@ def make_title(arguments, state, lineno): return title, messages -class DocutilsDialect(csv.Dialect): +if csv: + class DocutilsDialect(csv.Dialect): - """CSV dialect for `csv_table` directive function.""" + """CSV dialect for `csv_table` directive function.""" - delimiter = ',' - quotechar = '"' - doublequote = True - skipinitialspace = True - lineterminator = '\n' - quoting = csv.QUOTE_MINIMAL + delimiter = ',' + quotechar = '"' + doublequote = True + skipinitialspace = True + lineterminator = '\n' + quoting = csv.QUOTE_MINIMAL - def __init__(self, options): - if options.has_key('delim'): - self.delimiter = str(options['delim']) - if options.has_key('keepspace'): - self.skipinitialspace = False - if options.has_key('quote'): - self.quotechar = str(options['quote']) - if options.has_key('escape'): - self.doublequote = False - self.escapechar = str(options['escape']) - csv.Dialect.__init__(self) + def __init__(self, options): + if options.has_key('delim'): + self.delimiter = str(options['delim']) + if options.has_key('keepspace'): + self.skipinitialspace = False + if options.has_key('quote'): + self.quotechar = str(options['quote']) + if options.has_key('escape'): + self.doublequote = False + self.escapechar = str(options['escape']) + csv.Dialect.__init__(self) -class HeaderDialect(csv.Dialect): + class HeaderDialect(csv.Dialect): - """CSV dialect to use for the "header" option data.""" + """CSV dialect to use for the "header" option data.""" - delimiter = ',' - quotechar = '"' - escapechar = '\\' - doublequote = False - skipinitialspace = True - lineterminator = '\n' - quoting = csv.QUOTE_MINIMAL + delimiter = ',' + quotechar = '"' + escapechar = '\\' + doublequote = False + skipinitialspace = True + lineterminator = '\n' + quoting = csv.QUOTE_MINIMAL def csv_table(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): - - title, messages = make_title(arguments, state, lineno) try: + check_requirements(name, lineno, block_text, state_machine) + title, messages = make_title(arguments, state, lineno) csv_data, source = get_csv_data( name, options, content, lineno, block_text, state, state_machine) table_head, max_header_cols = process_header_option( @@ -121,13 +126,10 @@ def csv_table(name, arguments, options, content, lineno, csv_data, DocutilsDialect(options), source, options) max_cols = max(max_cols, max_header_cols) header_rows = options.get('header-rows', 0) # default 0 + check_table_dimensions( + rows, header_rows, name, lineno, block_text, state_machine) table_head.extend(rows[:header_rows]) table_body = rows[header_rows:] - if not table_body: - error = state_machine.reporter.error( - '"%s" directive requires table body content.' % name, - nodes.literal_block(block_text, block_text), line=lineno) - return [error] col_widths = get_column_widths( max_cols, name, options, lineno, block_text, state_machine) extend_short_rows_with_empty_cells(max_cols, (table_head, table_body)) @@ -163,6 +165,15 @@ csv_table.options = {'header-rows': directives.nonnegative_int, 'escape': directives.single_char_or_unicode,} csv_table.content = 1 +def check_requirements(name, lineno, block_text, state_machine): + if not csv: + error = state_machine.reporter.error( + 'The "%s" directive is not compatible with this version of ' + 'Python (%s). Requires the "csv" module, new in Python 2.3.' + % (name, sys.version.split()[0]), + nodes.literal_block(block_text, block_text), line=lineno) + raise SystemMessagePropagation(error) + def get_csv_data(name, options, content, lineno, block_text, state, state_machine): """ @@ -248,6 +259,21 @@ def parse_csv_data_into_rows(csv_data, dialect, source, options): max_cols = max(max_cols, len(row)) return rows, max_cols +def check_table_dimensions(rows, header_rows, 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) + elif 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) + def get_column_widths(max_cols, name, options, lineno, block_text, state_machine): if options.has_key('widths'): -- cgit v1.2.1 From 144f2976e1b8ac8619acfbb2bf333771b33d2e86 Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 11 Sep 2004 13:27:03 +0000 Subject: fixed non-ASCII-character bug with csv-table directive git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2568 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'docutils/parsers/rst/directives/tables.py') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index e34e54b20..787278b3e 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -13,6 +13,7 @@ __docformat__ = 'reStructuredText' import sys import os.path +from types import UnicodeType from docutils import nodes, statemachine, utils from docutils.utils import SystemMessagePropagation from docutils.parsers.rst import directives @@ -246,10 +247,18 @@ def process_header_option(options, state_machine, lineno): return table_head, max_header_cols def parse_csv_data_into_rows(csv_data, dialect, source, options): + isunicode = (csv_data and type(csv_data[0]) == UnicodeType) + if isunicode: + # Encode unicode in UTF-8, because the csv module doesn't + # support unicode strings. + csv_data = [item.encode('utf-8') for item in csv_data] csv_reader = csv.reader(csv_data, dialect=dialect) rows = [] max_cols = 0 for row in csv_reader: + if isunicode: + # Decode UTF-8 back to unicode + row = [item.decode('utf-8') for item in row] row_data = [] for cell in row: cell_data = (0, 0, 0, statemachine.StringList(cell.splitlines(), -- cgit v1.2.1 From dabc9aa76be60ffea41afc00b33103307d54d59a Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 12 Sep 2004 20:43:32 +0000 Subject: reverted rev1.3 (Unicode check for CSV table) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2587 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 9 --------- 1 file changed, 9 deletions(-) (limited to 'docutils/parsers/rst/directives/tables.py') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 787278b3e..e34e54b20 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -13,7 +13,6 @@ __docformat__ = 'reStructuredText' import sys import os.path -from types import UnicodeType from docutils import nodes, statemachine, utils from docutils.utils import SystemMessagePropagation from docutils.parsers.rst import directives @@ -247,18 +246,10 @@ def process_header_option(options, state_machine, lineno): return table_head, max_header_cols def parse_csv_data_into_rows(csv_data, dialect, source, options): - isunicode = (csv_data and type(csv_data[0]) == UnicodeType) - if isunicode: - # Encode unicode in UTF-8, because the csv module doesn't - # support unicode strings. - csv_data = [item.encode('utf-8') for item in csv_data] csv_reader = csv.reader(csv_data, dialect=dialect) rows = [] max_cols = 0 for row in csv_reader: - if isunicode: - # Decode UTF-8 back to unicode - row = [item.decode('utf-8') for item in row] row_data = [] for cell in row: cell_data = (0, 0, 0, statemachine.StringList(cell.splitlines(), -- cgit v1.2.1 From 82924f762267c60ed71fd26c87e1fa533a2f1882 Mon Sep 17 00:00:00 2001 From: goodger Date: Sun, 12 Sep 2004 21:13:54 +0000 Subject: Added "encoding" directive to "csv-table" directive. Added workaround for lack of Unicode support in csv.py, for non-ASCII CSV input. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2588 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'docutils/parsers/rst/directives/tables.py') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index e34e54b20..1966d2ab2 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -13,7 +13,7 @@ __docformat__ = 'reStructuredText' import sys import os.path -from docutils import nodes, statemachine, utils +from docutils import io, nodes, statemachine, utils from docutils.utils import SystemMessagePropagation from docutils.parsers.rst import directives @@ -154,6 +154,7 @@ csv_table.options = {'header-rows': directives.nonnegative_int, 'widths': directives.positive_int_list, 'file': directives.path, 'url': directives.path, + 'encoding': directives.encoding, 'class': directives.class_option, # field delimiter char 'delim': directives.single_char_or_whitespace_or_unicode, @@ -180,6 +181,7 @@ def get_csv_data(name, options, content, lineno, block_text, CSV data can come from the directive content, from an external file, or from a URL reference. """ + encoding = options.get('encoding', state.document.settings.input_encoding) if content: # CSV data is from directive content if options.has_key('file') or options.has_key('url'): error = state_machine.reporter.error( @@ -201,11 +203,9 @@ def get_csv_data(name, options, content, lineno, block_text, source = os.path.normpath(os.path.join(source_dir, options['file'])) source = utils.relative_path(None, source) try: - csv_file = open(source, 'rb') - try: - csv_data = csv_file.read().splitlines() - finally: - csv_file.close() + csv_file = io.FileInput(source_path=source, encoding=encoding, + handle_io_errors=None) + csv_data = csv_file.read().splitlines() except IOError, error: severe = state_machine.reporter.severe( 'Problems with "%s" directive path:\n%s.' % (name, error), @@ -221,13 +221,16 @@ def get_csv_data(name, options, content, lineno, block_text, raise SystemMessagePropagation(severe) source = options['url'] try: - csv_data = urllib2.urlopen(source).read().splitlines() + 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) + csv_data = csv_file.read().splitlines() else: error = state_machine.reporter.warning( 'The "%s" directive requires content; none supplied.' % (name), @@ -246,14 +249,18 @@ def process_header_option(options, state_machine, lineno): return table_head, max_header_cols def parse_csv_data_into_rows(csv_data, dialect, source, options): - csv_reader = csv.reader(csv_data, dialect=dialect) + # 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: - cell_data = (0, 0, 0, statemachine.StringList(cell.splitlines(), - source=source)) + # 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)) -- cgit v1.2.1 From 09522775bb77029bc2a4cbfbbde5ebe5e43fabe1 Mon Sep 17 00:00:00 2001 From: goodger Date: Mon, 13 Sep 2004 00:18:57 +0000 Subject: added input_encoding_error_handler to external file processing (include, raw, csv-table directives) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2598 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'docutils/parsers/rst/directives/tables.py') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 1966d2ab2..104a99480 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -203,8 +203,10 @@ def get_csv_data(name, options, content, lineno, block_text, source = os.path.normpath(os.path.join(source_dir, options['file'])) source = utils.relative_path(None, source) try: - csv_file = io.FileInput(source_path=source, encoding=encoding, - handle_io_errors=None) + csv_file = io.FileInput( + source_path=source, encoding=encoding, + error_handler=state.document.settings.input_encoding_error_handler, + handle_io_errors=None) csv_data = csv_file.read().splitlines() except IOError, error: severe = state_machine.reporter.severe( @@ -228,8 +230,9 @@ def get_csv_data(name, options, content, lineno, block_text, % (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) + 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( -- cgit v1.2.1 From 26e823e026f5b9be93d71437039d9b7eb3e0c76d Mon Sep 17 00:00:00 2001 From: wiemann Date: Sun, 19 Sep 2004 00:34:03 +0000 Subject: added --dependency-file option git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2622 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docutils/parsers/rst/directives/tables.py') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 104a99480..5e90e7d3c 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -206,7 +206,8 @@ def get_csv_data(name, options, content, lineno, block_text, csv_file = io.FileInput( source_path=source, encoding=encoding, error_handler=state.document.settings.input_encoding_error_handler, - handle_io_errors=None) + handle_io_errors=None, + dep_file=state.document.settings.dependency_file) csv_data = csv_file.read().splitlines() except IOError, error: severe = state_machine.reporter.severe( -- cgit v1.2.1 From 965d763d192aabd0d71ed3a088b994170bc8219f Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 25 Sep 2004 23:44:06 +0000 Subject: use new DependencyList (in settings.record_dependencies) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2647 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils/parsers/rst/directives/tables.py') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 5e90e7d3c..5b4cf8313 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -203,11 +203,11 @@ def get_csv_data(name, options, content, lineno, block_text, source = os.path.normpath(os.path.join(source_dir, options['file'])) source = utils.relative_path(None, source) try: + state.document.settings.record_dependencies.add(source) csv_file = io.FileInput( source_path=source, encoding=encoding, error_handler=state.document.settings.input_encoding_error_handler, - handle_io_errors=None, - dep_file=state.document.settings.dependency_file) + handle_io_errors=None) csv_data = csv_file.read().splitlines() except IOError, error: severe = state_machine.reporter.severe( -- cgit v1.2.1 From dd317b4e446e8c3666bf6e30e13ebf3a39e168f3 Mon Sep 17 00:00:00 2001 From: goodger Date: Fri, 11 Feb 2005 15:49:20 +0000 Subject: Added "list-table" directive. git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2963 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 103 +++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) (limited to 'docutils/parsers/rst/directives/tables.py') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 5b4cf8313..b0d633079 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -44,7 +44,6 @@ def table(name, arguments, options, content, lineno, return [warning] title, messages = make_title(arguments, state, lineno) node = nodes.Element() # anonymous container for parsing - text = '\n'.join(content) state.nested_parse(content, content_offset, node) if len(node) != 1 or not isinstance(node[0], nodes.table): error = state_machine.reporter.error( @@ -304,3 +303,105 @@ def extend_short_rows_with_empty_cells(columns, 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 + check_table_dimensions( + table_data, header_rows, 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) + if options.has_key('class'): + table_node.set_class(options['class']) + if title: + table_node.insert(0, title) + return [table_node] + messages + +list_table.arguments = (0, 1, 1) +list_table.options = {'header-rows': directives.nonnegative_int, + 'widths': directives.positive_int_list, + 'class': directives.class_option} +list_table.content = 1 + +def 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: + 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_widths + +def build_table_from_list(table_data, col_widths, header_rows): + table = nodes.table() + tgroup = nodes.tgroup(cols=len(col_widths)) + table += tgroup + for col_width in col_widths: + tgroup += nodes.colspec(colwidth=col_width) + 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 -- cgit v1.2.1 From a3e14f83bb27fe386e91b58604f7cf77810793cf Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 22 Feb 2005 01:29:17 +0000 Subject: Caught empty CSV table bug git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@2980 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'docutils/parsers/rst/directives/tables.py') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index b0d633079..6940bc72f 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -294,8 +294,13 @@ def get_column_widths(max_cols, name, options, lineno, block_text, % (name, max_cols), nodes.literal_block(block_text, block_text), line=lineno) raise SystemMessagePropagation(error) - else: + 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_widths def extend_short_rows_with_empty_cells(columns, parts): -- cgit v1.2.1 From aa76cea304f331ad416e6f4623c2e5f00f995c58 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 4 Mar 2005 22:52:04 +0000 Subject: removed direct references to Element.children attribute outside nodes.py git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3004 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils/parsers/rst/directives/tables.py') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 6940bc72f..653499c20 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -327,7 +327,7 @@ def list_table(name, arguments, options, content, lineno, 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]] + table_data = [[item.get_children() for item in row_list[0]] for row_list in node[0]] header_rows = options.get('header-rows', 0) # default 0 check_table_dimensions( -- cgit v1.2.1 From 43ca6a79125d28fce6c2ab2142f93733319382d4 Mon Sep 17 00:00:00 2001 From: wiemann Date: Mon, 14 Mar 2005 16:16:57 +0000 Subject: removed redundant get_children(); in case we want to change the behavior later, be can use __getattr__ or a descriptor; (the list is modified in place anyway, so there'd be not much to change about get_children) git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3038 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils/parsers/rst/directives/tables.py') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 653499c20..6940bc72f 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -327,7 +327,7 @@ def list_table(name, arguments, options, content, lineno, try: num_cols, col_widths = check_list_content( node, name, options, content, lineno, block_text, state_machine) - table_data = [[item.get_children() for item in row_list[0]] + 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 check_table_dimensions( -- cgit v1.2.1 From 0a938a279683da492acd6512d0af6fa636c5a51c Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 15 Mar 2005 00:37:51 +0000 Subject: differentiate between paths and URIs git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3046 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docutils/parsers/rst/directives/tables.py') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 6940bc72f..116a2759f 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -152,7 +152,7 @@ csv_table.options = {'header-rows': directives.nonnegative_int, 'header': directives.unchanged, 'widths': directives.positive_int_list, 'file': directives.path, - 'url': directives.path, + 'url': directives.uri, 'encoding': directives.encoding, 'class': directives.class_option, # field delimiter char -- cgit v1.2.1 From b559771f98c67ca07b71c41dd947c2be6df75fee Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 22 Mar 2005 19:18:06 +0000 Subject: added csv-table directive support for the file_insertion_enabled setting git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3083 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'docutils/parsers/rst/directives/tables.py') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 116a2759f..e47c9f9e4 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -115,6 +115,12 @@ if csv: def csv_table(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): try: + if ( not state.document.settings.file_insertion_enabled + and (options.has_key('file') or options.has_key('url')) ): + warning = state_machine.reporter.warning( + '"%s" directive disabled.' % name, + nodes.literal_block(block_text, block_text), line=lineno) + return [warning] check_requirements(name, lineno, block_text, state_machine) title, messages = make_title(arguments, state, lineno) csv_data, source = get_csv_data( @@ -205,7 +211,8 @@ def get_csv_data(name, options, content, lineno, block_text, state.document.settings.record_dependencies.add(source) csv_file = io.FileInput( source_path=source, encoding=encoding, - error_handler=state.document.settings.input_encoding_error_handler, + error_handler + =state.document.settings.input_encoding_error_handler, handle_io_errors=None) csv_data = csv_file.read().splitlines() except IOError, error: -- cgit v1.2.1 From 232e7e218a2c4b14569bd11890ad26ab2d5cb76c Mon Sep 17 00:00:00 2001 From: wiemann Date: Sat, 2 Apr 2005 21:57:06 +0000 Subject: removed nodes.Element.set_class() method; directives.class_option now returns a *list* of classes; added test for :figclass: option of figure directive; the raw role's :format: option is now "unchanged", not "class_option"; some fixes: the :class: option should now always be propagated correctly from directives git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3155 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'docutils/parsers/rst/directives/tables.py') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index e47c9f9e4..8f16beda0 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -53,8 +53,7 @@ def table(name, arguments, options, content, lineno, line=lineno) return [error] table_node = node[0] - if options.has_key('class'): - table_node.set_class(options['class']) + table_node['classes'] += options.get('class', []) if title: table_node.insert(0, title) return [table_node] + messages @@ -147,8 +146,7 @@ def csv_table(name, arguments, options, content, lineno, return [error] table = (col_widths, table_head, table_body) table_node = state.build_table(table, content_offset) - if options.has_key('class'): - table_node.set_class(options['class']) + table_node['classes'] += options.get('class', []) if title: table_node.insert(0, title) return [table_node] + messages @@ -342,8 +340,7 @@ def list_table(name, arguments, options, content, lineno, except SystemMessagePropagation, detail: return [detail.args[0]] table_node = build_table_from_list(table_data, col_widths, header_rows) - if options.has_key('class'): - table_node.set_class(options['class']) + table_node['classes'] += options.get('class', []) if title: table_node.insert(0, title) return [table_node] + messages -- cgit v1.2.1 From dc3284ca85006e72f0e3b2c4ffbe078aa9148f76 Mon Sep 17 00:00:00 2001 From: goodger Date: Tue, 5 Apr 2005 02:55:06 +0000 Subject: added "stub-columns" options to "csv-table" and "list-table" directives, plus support, docs, and tests git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3165 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 43 ++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 9 deletions(-) (limited to 'docutils/parsers/rst/directives/tables.py') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 8f16beda0..87131277d 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -130,8 +130,10 @@ def csv_table(name, arguments, options, content, lineno, csv_data, DocutilsDialect(options), source, options) max_cols = max(max_cols, max_header_cols) header_rows = options.get('header-rows', 0) # default 0 + stub_columns = options.get('stub-columns', 0) # default 0 check_table_dimensions( - rows, header_rows, name, lineno, block_text, state_machine) + rows, header_rows, stub_columns, name, lineno, + block_text, state_machine) table_head.extend(rows[:header_rows]) table_body = rows[header_rows:] col_widths = get_column_widths( @@ -145,7 +147,7 @@ def csv_table(name, arguments, options, content, lineno, nodes.literal_block(block_text, block_text), line=lineno) return [error] table = (col_widths, table_head, table_body) - table_node = state.build_table(table, content_offset) + table_node = state.build_table(table, content_offset, stub_columns) table_node['classes'] += options.get('class', []) if title: table_node.insert(0, title) @@ -153,6 +155,7 @@ def csv_table(name, arguments, options, content, lineno, csv_table.arguments = (0, 1, 1) csv_table.options = {'header-rows': directives.nonnegative_int, + 'stub-columns': directives.nonnegative_int, 'header': directives.unchanged, 'widths': directives.positive_int_list, 'file': directives.path, @@ -274,20 +277,34 @@ def parse_csv_data_into_rows(csv_data, dialect, source, options): max_cols = max(max_cols, len(row)) return rows, max_cols -def check_table_dimensions(rows, header_rows, name, lineno, block_text, - state_machine): +def 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) - elif len(rows) == header_rows > 0: + 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): @@ -335,11 +352,14 @@ def list_table(name, arguments, options, content, lineno, 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, name, lineno, block_text, state_machine) + 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) + 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) @@ -347,6 +367,7 @@ def list_table(name, arguments, options, content, lineno, list_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 = 1 @@ -392,12 +413,16 @@ def check_list_content(node, name, options, content, lineno, block_text, raise SystemMessagePropagation(error) return num_cols, col_widths -def build_table_from_list(table_data, col_widths, header_rows): +def 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: - tgroup += nodes.colspec(colwidth=col_width) + 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() -- cgit v1.2.1 From dc98554c2fc0308774c70dcebc6fe45617f22e00 Mon Sep 17 00:00:00 2001 From: wiemann Date: Fri, 15 Jul 2005 21:28:22 +0000 Subject: more precise error message git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3759 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docutils/parsers/rst/directives/tables.py') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index 87131277d..dadcdae68 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -117,8 +117,8 @@ def csv_table(name, arguments, options, content, lineno, if ( not state.document.settings.file_insertion_enabled and (options.has_key('file') or options.has_key('url')) ): warning = state_machine.reporter.warning( - '"%s" directive disabled.' % name, - nodes.literal_block(block_text, block_text), line=lineno) + 'File and URL access deactivated; ignoring "%s" directive.' % + name, nodes.literal_block(block_text,block_text), line=lineno) return [warning] check_requirements(name, lineno, block_text, state_machine) title, messages = make_title(arguments, state, lineno) -- cgit v1.2.1 From f80815602799ff058440771456e212325fd6d2f6 Mon Sep 17 00:00:00 2001 From: goodger Date: Sat, 24 Sep 2005 15:11:20 +0000 Subject: added clarifying comment; thanks to Anthony Baxter for pointing this out git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3900 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/parsers/rst/directives/tables.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docutils/parsers/rst/directives/tables.py') diff --git a/docutils/parsers/rst/directives/tables.py b/docutils/parsers/rst/directives/tables.py index dadcdae68..70a0de5ab 100644 --- a/docutils/parsers/rst/directives/tables.py +++ b/docutils/parsers/rst/directives/tables.py @@ -392,6 +392,9 @@ def check_list_content(node, name, options, content, lineno, block_text, 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: ' -- cgit v1.2.1