From c1b06c883eb471187a1725f2f2e646bb266adad8 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@3165 929543f6-e4f2-0310-98a6-ba3bd3dd1d04 --- docutils/HISTORY.txt | 10 +++ docutils/docs/ref/docutils.dtd | 4 +- docutils/docs/ref/rst/directives.txt | 8 ++ docutils/docutils/parsers/rst/directives/tables.py | 43 ++++++++--- docutils/docutils/parsers/rst/states.py | 14 ++-- docutils/docutils/writers/html4css1.py | 8 +- .../expected/standalone_rst_html4css1.html | 90 +++++++++++++++------- docutils/test/functional/input/data/list_table.txt | 24 ++++++ .../functional/input/standalone_rst_html4css1.txt | 1 + .../test_rst/test_directives/test_tables.py | 44 ++++++++++- 10 files changed, 200 insertions(+), 46 deletions(-) create mode 100644 docutils/test/functional/input/data/list_table.txt (limited to 'docutils') diff --git a/docutils/HISTORY.txt b/docutils/HISTORY.txt index 2bc6e02ed..e8200d037 100644 --- a/docutils/HISTORY.txt +++ b/docutils/HISTORY.txt @@ -59,6 +59,7 @@ Changes Since 0.3.7 - Added auto-enumerated list items. - Fixed bug that assumed ``.. _`` and ``.. |`` were invariably followed by text. + - Added support for table stub columns. * docutils/parsers/rst/directives/__init__.py: @@ -85,6 +86,8 @@ Changes Since 0.3.7 - Caught empty CSV table bug. - Added support for the ``file_insertion_enabled`` setting in the "csv-table" directive. + - Added ``stub-columns`` option to "csv-table" and "list-table" + directives. * docutils/parsers/rst/languages/nl.py: Added to project; Dutch mappings by Martijn Pieters. @@ -106,6 +109,8 @@ Changes Since 0.3.7 tags). - Added support for multiple IDs per node by creating empty ``span`` tags. + - Added the ``field_name_limit`` setting & support. + - Added support for table stub columns. * docutils/writers/latex2e.py: @@ -117,6 +122,11 @@ Changes Since 0.3.7 - Made sure that latex doesn't fill in today's date if no date field was given. +* docs/ref/docutils.dtd: + + - Added ``stub`` attribute to ``colspec`` element via the + ``tbl.colspec.att`` parameter entity. + Release 0.3.7 (2004-12-24) ========================== diff --git a/docutils/docs/ref/docutils.dtd b/docutils/docs/ref/docutils.dtd index a18eae36b..d9a76ce2e 100644 --- a/docutils/docs/ref/docutils.dtd +++ b/docutils/docs/ref/docutils.dtd @@ -166,7 +166,9 @@ http://www.oasis-open.org/html/tm9901.htm). - + 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() diff --git a/docutils/docutils/parsers/rst/states.py b/docutils/docutils/parsers/rst/states.py index a44f47027..f779df8b2 100644 --- a/docutils/docutils/parsers/rst/states.py +++ b/docutils/docutils/parsers/rst/states.py @@ -1657,13 +1657,17 @@ class Body(RSTState): line=lineno) return [error] - def build_table(self, tabledata, tableline): - colspecs, headrows, bodyrows = tabledata + def build_table(self, tabledata, tableline, stub_columns=0): + colwidths, headrows, bodyrows = tabledata table = nodes.table() - tgroup = nodes.tgroup(cols=len(colspecs)) + tgroup = nodes.tgroup(cols=len(colwidths)) table += tgroup - for colspec in colspecs: - tgroup += nodes.colspec(colwidth=colspec) + for colwidth in colwidths: + colspec = nodes.colspec(colwidth=colwidth) + if stub_columns: + colspec.attributes['stub'] = 1 + stub_columns -= 1 + tgroup += colspec if headrows: thead = nodes.thead() tgroup += thead diff --git a/docutils/docutils/writers/html4css1.py b/docutils/docutils/writers/html4css1.py index af18e2745..27442e6ca 100644 --- a/docutils/docutils/writers/html4css1.py +++ b/docutils/docutils/writers/html4css1.py @@ -456,6 +456,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_colspec(self, node): self.colspecs.append(node) + node.parent.stubs.append(node.attributes.get('stub')) def depart_colspec(self, node): pass @@ -603,15 +604,18 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append('') def visit_entry(self, node): - if isinstance(node.parent.parent, nodes.thead): + if ( isinstance(node.parent.parent, nodes.thead) + or node.parent.parent.parent.stubs[node.parent.column]): tagname = 'th' else: tagname = 'td' + node.parent.column += 1 atts = {} if node.has_key('morerows'): atts['rowspan'] = node['morerows'] + 1 if node.has_key('morecols'): atts['colspan'] = node['morecols'] + 1 + node.parent.column += node['morecols'] self.body.append(self.starttag(node, tagname, '', **atts)) self.context.append('\n' % tagname.lower()) if len(node) == 0: # empty cell @@ -1092,6 +1096,7 @@ class HTMLTranslator(nodes.NodeVisitor): def visit_row(self, node): self.body.append(self.starttag(node, 'tr', '')) + node.column = 0 def depart_row(self, node): self.body.append('\n') @@ -1249,6 +1254,7 @@ class HTMLTranslator(nodes.NodeVisitor): self.body.append(self.starttag(node, 'colgroup')) # Appended by thead or tbody: self.context.append('\n') + node.stubs = [] def depart_tgroup(self, node): pass diff --git a/docutils/test/functional/expected/standalone_rst_html4css1.html b/docutils/test/functional/expected/standalone_rst_html4css1.html index f9cf0a59b..f3b49e496 100644 --- a/docutils/test/functional/expected/standalone_rst_html4css1.html +++ b/docutils/test/functional/expected/standalone_rst_html4css1.html @@ -127,9 +127,10 @@ They are transformed from section titles after parsing. -->
  • 2.18   Colspanning tables
  • 2.19   Rowspanning tables
  • 2.20   Complex tables
  • +
  • 2.21   List Tables
  • -
  • 3   Error Handling
  • +
  • 3   Error Handling
  • @@ -472,7 +473,7 @@ Here's a reference to the next footnote: [4]Here's an unreferenced footnote, with a reference to a -nonexistent footnote: [5]_. +nonexistent footnote: [5]_.
    @@ -485,7 +486,7 @@ nonexistent footnote: [CIT2002], and a [nonexistent]_ +

    Here's a reference to the above, [CIT2002], and a [nonexistent]_ citation.

    @@ -499,7 +500,7 @@ hyperlink targets are also possible.

    "Python [5]".

    Targets may be indirect and anonymous. Thus this phrase may also refer to the Targets section.

    -

    Here's a `hyperlink reference without a target`_, which generates an +

    Here's a `hyperlink reference without a target`_, which generates an error.

    2.13.1   Duplicate Target Names

    @@ -511,33 +512,33 @@ explicit targets will generate "warning" (level-2) system messages.

    2.13.2   Duplicate Target Names

    Since there are two "Duplicate Target Names" section headers, we cannot uniquely refer to either of them by name. If we try to (like -this: `Duplicate Target Names`_), an error is generated.

    +this: `Duplicate Target Names`_), an error is generated.

    2.14   Directives

    These are just a sample of the many reStructuredText Directives. For others, please see http://docutils.sourceforge.net/docs/ref/rst/directives.html.

    -

    2.14.1   Document Parts

    +

    2.14.1   Document Parts

    An example of the "contents" directive can be seen above this section (a local, untitled table of contents) and at the beginning of the document (a document-wide table of contents).

    -

    2.14.2   Images

    +

    2.14.2   Images

    An image directive (also clickable -- a hyperlink reference):

    ../../../docs/user/rst/images/title.png

    A figure directive:

    @@ -567,7 +568,7 @@ document (a document-wide table o
    -

    2.14.3   Admonitions

    +

    2.14.3   Admonitions

    Attention!

    Directives at large.

    @@ -616,7 +617,7 @@ Reader discretion is strongly advised.

    -

    2.14.4   Topics, Sidebars, and Rubrics

    +

    2.14.4   Topics, Sidebars, and Rubrics

    -

    2.14.5   Target Footnotes

    +

    2.14.5   Target Footnotes

    @@ -642,11 +643,11 @@ background color.

    -

    2.14.7   Compound Paragraph

    +

    2.14.7   Compound Paragraph

    Compound 1, paragraph 1.

    Compound 1, paragraph 2.

    @@ -857,9 +858,42 @@ empty: -->
    +
    +

    2.21   List Tables

    +

    Here's a list table exercising all features:

    + + +++++ + + + + + + + + + + + + + + + + + + + + +
    list table with integral header
    TreatQuantityDescription
    Albatross2.99On a stick!
    Crunchy Frog1.49If we took the bones out, it wouldn't be +crunchy, now would it?
    Gannet Ripple1.99On a stick!
    +
    -

    3   Error Handling

    +

    3   Error Handling

    Any errors caught during processing will generate system messages.

    There should be five messages in the following, auto-generated section, "Docutils System Messages":

    @@ -870,17 +904,17 @@ section, "Docutils System Messages":

    System Message: ERROR/3 (functional/input/data/standard.txt, line 98); backlink

    Undefined substitution referenced: "problematic".
    -
    -

    System Message: ERROR/3 (functional/input/standalone_rst_html4css1.txt, line 352); backlink

    +
    +

    System Message: ERROR/3 (functional/input/standalone_rst_html4css1.txt, line 352); backlink

    Unknown target name: "5".
    -
    -

    System Message: ERROR/3 (functional/input/data/standard.txt, line 361); backlink

    +
    +

    System Message: ERROR/3 (functional/input/data/standard.txt, line 361); backlink

    Unknown target name: "nonexistent".
    -
    -

    System Message: ERROR/3 (functional/input/data/standard.txt, line 386); backlink

    +
    +

    System Message: ERROR/3 (functional/input/data/standard.txt, line 386); backlink

    Unknown target name: "hyperlink reference without a target".
    -
    -

    System Message: ERROR/3 (functional/input/data/standard.txt, line 399); backlink

    +
    +

    System Message: ERROR/3 (functional/input/data/standard.txt, line 399); backlink

    Duplicate target name, cannot be used as a unique reference: "duplicate target names".
    diff --git a/docutils/test/functional/input/data/list_table.txt b/docutils/test/functional/input/data/list_table.txt new file mode 100644 index 000000000..632285e36 --- /dev/null +++ b/docutils/test/functional/input/data/list_table.txt @@ -0,0 +1,24 @@ +List Tables +----------- + +Here's a list table exercising all features: + +.. list-table:: list table with integral header + :class: test + :widths: 10 20 30 + :header-rows: 1 + :stub-columns: 1 + + * - Treat + - Quantity + - Description + * - Albatross + - 2.99 + - On a stick! + * - Crunchy Frog + - 1.49 + - If we took the bones out, it wouldn't be + crunchy, now would it? + * - Gannet Ripple + - 1.99 + - On a stick! diff --git a/docutils/test/functional/input/standalone_rst_html4css1.txt b/docutils/test/functional/input/standalone_rst_html4css1.txt index 68f9de864..3847a089e 100644 --- a/docutils/test/functional/input/standalone_rst_html4css1.txt +++ b/docutils/test/functional/input/standalone_rst_html4css1.txt @@ -2,4 +2,5 @@ .. include:: data/table_colspan.txt .. include:: data/table_rowspan.txt .. include:: data/table_complex.txt +.. include:: data/list_table.txt .. include:: data/errors.txt diff --git a/docutils/test/test_parsers/test_rst/test_directives/test_tables.py b/docutils/test/test_parsers/test_rst/test_directives/test_tables.py index a38e8b343..da88510e7 100755 --- a/docutils/test/test_parsers/test_rst/test_directives/test_tables.py +++ b/docutils/test/test_parsers/test_rst/test_directives/test_tables.py @@ -116,6 +116,7 @@ else: .. csv-table:: inline with integral header :widths: 10, 20, 30 :header-rows: 1 + :stub-columns: 1 "Treat", "Quantity", "Description" "Albatross", 2.99, "On a stick!" @@ -129,7 +130,7 @@ else: inline with integral header <tgroup cols="3"> - <colspec colwidth="10"> + <colspec colwidth="10" stub="1"> <colspec colwidth="20"> <colspec colwidth="30"> <thead> @@ -815,6 +816,7 @@ totest['list-table'] = [ .. list-table:: list table with integral header :widths: 10 20 30 :header-rows: 1 + :stub-columns: 1 * - Treat - Quantity @@ -836,7 +838,7 @@ totest['list-table'] = [ <title> list table with integral header <tgroup cols="3"> - <colspec colwidth="10"> + <colspec colwidth="10" stub="1"> <colspec colwidth="20"> <colspec colwidth="30"> <thead> @@ -949,6 +951,44 @@ totest['list-table'] = [ \n\ * - ":widths:" option doesn\'t match columns """], +["""\ +.. list-table:: + :stub-columns: 3 + + * - column 1 + - column 2 +""", +"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + 3 stub column(s) specified but only 2 columns(s) of data supplied ("list-table" directive). + <literal_block xml:space="preserve"> + .. list-table:: + :stub-columns: 3 + \n\ + * - column 1 + - column 2 +"""], +["""\ +.. list-table:: + :stub-columns: 2 + + * - column 1 + - column 2 +""", +"""\ +<document source="test data"> + <system_message level="3" line="1" source="test data" type="ERROR"> + <paragraph> + Insufficient data supplied (2 columns(s)); no data remaining for table body, required by "list-table" directive. + <literal_block xml:space="preserve"> + .. list-table:: + :stub-columns: 2 + \n\ + * - column 1 + - column 2 +"""], ] -- cgit v1.2.1