summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgoodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04>2005-04-05 02:55:06 +0000
committergoodger <goodger@929543f6-e4f2-0310-98a6-ba3bd3dd1d04>2005-04-05 02:55:06 +0000
commitc1b06c883eb471187a1725f2f2e646bb266adad8 (patch)
tree6a6278b3f41ea8bfdf1eaa0607d3ba8ddb78d4a1
parentb4d89cccc3f3901bb15b38b1b2dd65224f23b44b (diff)
downloaddocutils-c1b06c883eb471187a1725f2f2e646bb266adad8.tar.gz
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
-rw-r--r--docutils/HISTORY.txt10
-rw-r--r--docutils/docs/ref/docutils.dtd4
-rw-r--r--docutils/docs/ref/rst/directives.txt8
-rw-r--r--docutils/docutils/parsers/rst/directives/tables.py43
-rw-r--r--docutils/docutils/parsers/rst/states.py14
-rw-r--r--docutils/docutils/writers/html4css1.py8
-rw-r--r--docutils/test/functional/expected/standalone_rst_html4css1.html90
-rw-r--r--docutils/test/functional/input/data/list_table.txt24
-rw-r--r--docutils/test/functional/input/standalone_rst_html4css1.txt1
-rwxr-xr-xdocutils/test/test_parsers/test_rst/test_directives/test_tables.py44
10 files changed, 200 insertions, 46 deletions
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).
<!ENTITY % tbl.tgroup.att " %basic.atts; ">
<!ENTITY % tbl.thead.att " %basic.atts; ">
<!ENTITY % tbl.tbody.att " %basic.atts; ">
-<!ENTITY % tbl.colspec.att " %basic.atts; ">
+<!ENTITY % tbl.colspec.att
+ " %basic.atts;
+ stub %yesorno; #IMPLIED ">
<!ENTITY % tbl.row.att " %basic.atts; ">
<!ENTITY % tbl.entry.mdl " (%body.elements;)* ">
<!ENTITY % tbl.entry.att
diff --git a/docutils/docs/ref/rst/directives.txt b/docutils/docs/ref/rst/directives.txt
index ff5862680..8be376eb6 100644
--- a/docutils/docs/ref/rst/directives.txt
+++ b/docutils/docs/ref/rst/directives.txt
@@ -735,6 +735,10 @@ The following options are recognized:
The number of rows of CSV data to use in the table header.
Defaults to 0.
+``stub-columns`` : integer
+ The number of table columns to use as stubs (row titles, on the
+ left). Defaults to 0.
+
``header`` : CSV data
Supplemental data for the table header, added independently of and
before any ``header-rows`` from the main CSV data. Must use the
@@ -829,6 +833,10 @@ The following options are recognized:
The number of rows of list data to use in the table header.
Defaults to 0.
+``stub-columns`` : integer
+ The number of table columns to use as stubs (row titles, on the
+ left). Defaults to 0.
+
----------------
Document Parts
diff --git a/docutils/docutils/parsers/rst/directives/tables.py b/docutils/docutils/parsers/rst/directives/tables.py
index 8f16beda0..87131277d 100644
--- a/docutils/docutils/parsers/rst/directives/tables.py
+++ b/docutils/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()
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('</em>')
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('</%s>\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('</tr>\n')
@@ -1249,6 +1254,7 @@ class HTMLTranslator(nodes.NodeVisitor):
self.body.append(self.starttag(node, 'colgroup'))
# Appended by thead or tbody:
self.context.append('</colgroup>\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. -->
<li><a class="reference" href="#colspanning-tables" id="id57" name="id57">2.18&nbsp;&nbsp;&nbsp;Colspanning tables</a></li>
<li><a class="reference" href="#rowspanning-tables" id="id58" name="id58">2.19&nbsp;&nbsp;&nbsp;Rowspanning tables</a></li>
<li><a class="reference" href="#complex-tables" id="id59" name="id59">2.20&nbsp;&nbsp;&nbsp;Complex tables</a></li>
+<li><a class="reference" href="#list-tables" id="id60" name="id60">2.21&nbsp;&nbsp;&nbsp;List Tables</a></li>
</ul>
</li>
-<li><a class="reference" href="#error-handling" id="id60" name="id60">3&nbsp;&nbsp;&nbsp;Error Handling</a></li>
+<li><a class="reference" href="#error-handling" id="id61" name="id61">3&nbsp;&nbsp;&nbsp;Error Handling</a></li>
</ul>
</div>
<div class="section" id="structural-elements">
@@ -472,7 +473,7 @@ Here's a reference to the next footnote: <a class="footnote-reference" href="#id
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="id13">[4]</a></td><td>Here's an unreferenced footnote, with a reference to a
-nonexistent footnote: <a href="#id68" name="id69"><span class="problematic" id="id69">[5]_</span></a>.</td></tr>
+nonexistent footnote: <a href="#id69" name="id70"><span class="problematic" id="id70">[5]_</span></a>.</td></tr>
</tbody>
</table>
</div>
@@ -485,7 +486,7 @@ nonexistent footnote: <a href="#id68" name="id69"><span class="problematic" id="
rendered separately and differently from footnotes.</td></tr>
</tbody>
</table>
-<p>Here's a reference to the above, <a class="citation-reference" href="#cit2002" id="id15" name="id15">[CIT2002]</a>, and a <a href="#id70" name="id71"><span class="problematic" id="id71">[nonexistent]_</span></a>
+<p>Here's a reference to the above, <a class="citation-reference" href="#cit2002" id="id15" name="id15">[CIT2002]</a>, and a <a href="#id71" name="id72"><span class="problematic" id="id72">[nonexistent]_</span></a>
citation.</p>
</div>
<div class="section" id="targets">
@@ -499,7 +500,7 @@ hyperlink targets</a> are also possible.</p>
&quot;<a class="reference" href="http://www.python.org/">Python</a> <a class="footnote-reference" href="#id21" id="id23" name="id23">[5]</a>&quot;.</p>
<p>Targets may be indirect and anonymous. Thus <a class="reference" href="#targets">this phrase</a> may also
refer to the <a class="reference" href="#targets">Targets</a> section.</p>
-<p>Here's a <a href="#id72" name="id73"><span class="problematic" id="id73">`hyperlink reference without a target`_</span></a>, which generates an
+<p>Here's a <a href="#id73" name="id74"><span class="problematic" id="id74">`hyperlink reference without a target`_</span></a>, which generates an
error.</p>
<div class="section" id="duplicate-target-names">
<h3><a class="toc-backref" href="#id44" name="duplicate-target-names">2.13.1&nbsp;&nbsp;&nbsp;Duplicate Target Names</a></h3>
@@ -511,33 +512,33 @@ explicit targets will generate &quot;warning&quot; (level-2) system messages.</p
<h3><a class="toc-backref" href="#id45" name="id18">2.13.2&nbsp;&nbsp;&nbsp;Duplicate Target Names</a></h3>
<p>Since there are two &quot;Duplicate Target Names&quot; section headers, we
cannot uniquely refer to either of them by name. If we try to (like
-this: <a href="#id74" name="id75"><span class="problematic" id="id75">`Duplicate Target Names`_</span></a>), an error is generated.</p>
+this: <a href="#id75" name="id76"><span class="problematic" id="id76">`Duplicate Target Names`_</span></a>), an error is generated.</p>
</div>
</div>
<div class="section" id="directives">
<h2><a class="toc-backref" href="#id46" name="directives">2.14&nbsp;&nbsp;&nbsp;Directives</a></h2>
<div class="contents topic" id="contents">
<ul class="auto-toc simple">
-<li><a class="reference" href="#document-parts" id="id61" name="id61">2.14.1&nbsp;&nbsp;&nbsp;Document Parts</a></li>
-<li><a class="reference" href="#images" id="id62" name="id62">2.14.2&nbsp;&nbsp;&nbsp;Images</a></li>
-<li><a class="reference" href="#admonitions" id="id63" name="id63">2.14.3&nbsp;&nbsp;&nbsp;Admonitions</a></li>
-<li><a class="reference" href="#topics-sidebars-and-rubrics" id="id64" name="id64">2.14.4&nbsp;&nbsp;&nbsp;Topics, Sidebars, and Rubrics</a></li>
-<li><a class="reference" href="#target-footnotes" id="id65" name="id65">2.14.5&nbsp;&nbsp;&nbsp;Target Footnotes</a></li>
-<li><a class="reference" href="#replacement-text" id="id66" name="id66">2.14.6&nbsp;&nbsp;&nbsp;Replacement Text</a></li>
-<li><a class="reference" href="#compound-paragraph" id="id67" name="id67">2.14.7&nbsp;&nbsp;&nbsp;Compound Paragraph</a></li>
+<li><a class="reference" href="#document-parts" id="id62" name="id62">2.14.1&nbsp;&nbsp;&nbsp;Document Parts</a></li>
+<li><a class="reference" href="#images" id="id63" name="id63">2.14.2&nbsp;&nbsp;&nbsp;Images</a></li>
+<li><a class="reference" href="#admonitions" id="id64" name="id64">2.14.3&nbsp;&nbsp;&nbsp;Admonitions</a></li>
+<li><a class="reference" href="#topics-sidebars-and-rubrics" id="id65" name="id65">2.14.4&nbsp;&nbsp;&nbsp;Topics, Sidebars, and Rubrics</a></li>
+<li><a class="reference" href="#target-footnotes" id="id66" name="id66">2.14.5&nbsp;&nbsp;&nbsp;Target Footnotes</a></li>
+<li><a class="reference" href="#replacement-text" id="id67" name="id67">2.14.6&nbsp;&nbsp;&nbsp;Replacement Text</a></li>
+<li><a class="reference" href="#compound-paragraph" id="id68" name="id68">2.14.7&nbsp;&nbsp;&nbsp;Compound Paragraph</a></li>
</ul>
</div>
<p>These are just a sample of the many reStructuredText Directives. For
others, please see
<a class="reference" href="http://docutils.sourceforge.net/docs/ref/rst/directives.html">http://docutils.sourceforge.net/docs/ref/rst/directives.html</a>.</p>
<div class="section" id="document-parts">
-<h3><a class="toc-backref" href="#id61" name="document-parts">2.14.1&nbsp;&nbsp;&nbsp;Document Parts</a></h3>
+<h3><a class="toc-backref" href="#id62" name="document-parts">2.14.1&nbsp;&nbsp;&nbsp;Document Parts</a></h3>
<p>An example of the &quot;contents&quot; directive can be seen above this section
(a local, untitled table of <a class="reference" href="#contents">contents</a>) and at the beginning of the
document (a document-wide <a class="reference" href="#table-of-contents">table of contents</a>).</p>
</div>
<div class="section" id="images">
-<h3><a class="toc-backref" href="#id62" name="images">2.14.2&nbsp;&nbsp;&nbsp;Images</a></h3>
+<h3><a class="toc-backref" href="#id63" name="images">2.14.2&nbsp;&nbsp;&nbsp;Images</a></h3>
<p>An image directive (also clickable -- a hyperlink reference):</p>
<div class="image class1 class2 image-reference"><a class="reference" href="#directives"><img alt="../../../docs/user/rst/images/title.png" class="class1 class2" src="../../../docs/user/rst/images/title.png" /></a></div>
<p>A figure directive:</p>
@@ -567,7 +568,7 @@ document (a document-wide <a class="reference" href="#table-of-contents">table o
</div>
</div>
<div class="section" id="admonitions">
-<h3><a class="toc-backref" href="#id63" name="admonitions">2.14.3&nbsp;&nbsp;&nbsp;Admonitions</a></h3>
+<h3><a class="toc-backref" href="#id64" name="admonitions">2.14.3&nbsp;&nbsp;&nbsp;Admonitions</a></h3>
<div class="attention">
<p class="first admonition-title">Attention!</p>
<p class="last">Directives at large.</p>
@@ -616,7 +617,7 @@ Reader discretion is strongly advised.</p>
</div>
</div>
<div class="section" id="topics-sidebars-and-rubrics">
-<h3><a class="toc-backref" href="#id64" name="topics-sidebars-and-rubrics">2.14.4&nbsp;&nbsp;&nbsp;Topics, Sidebars, and Rubrics</a></h3>
+<h3><a class="toc-backref" href="#id65" name="topics-sidebars-and-rubrics">2.14.4&nbsp;&nbsp;&nbsp;Topics, Sidebars, and Rubrics</a></h3>
<div class="sidebar">
<p class="first sidebar-title">Sidebar Title</p>
<p class="sidebar-subtitle">Optional Subtitle</p>
@@ -633,7 +634,7 @@ background color.</p>
<p class="rubric">This is a rubric</p>
</div>
<div class="section" id="target-footnotes">
-<h3><a class="toc-backref" href="#id65" name="target-footnotes">2.14.5&nbsp;&nbsp;&nbsp;Target Footnotes</a></h3>
+<h3><a class="toc-backref" href="#id66" name="target-footnotes">2.14.5&nbsp;&nbsp;&nbsp;Target Footnotes</a></h3>
<table class="docutils footnote" frame="void" id="id21" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
@@ -642,11 +643,11 @@ background color.</p>
</table>
</div>
<div class="section" id="replacement-text">
-<h3><a class="toc-backref" href="#id66" name="replacement-text">2.14.6&nbsp;&nbsp;&nbsp;Replacement Text</a></h3>
+<h3><a class="toc-backref" href="#id67" name="replacement-text">2.14.6&nbsp;&nbsp;&nbsp;Replacement Text</a></h3>
<p>I recommend you try <a class="reference" href="http://www.python.org/">Python, <em>the</em> best language around</a> <a class="footnote-reference" href="#id21" id="id24" name="id24">[5]</a>.</p>
</div>
<div class="section" id="compound-paragraph">
-<h3><a class="toc-backref" href="#id67" name="compound-paragraph">2.14.7&nbsp;&nbsp;&nbsp;Compound Paragraph</a></h3>
+<h3><a class="toc-backref" href="#id68" name="compound-paragraph">2.14.7&nbsp;&nbsp;&nbsp;Compound Paragraph</a></h3>
<div class="some-class compound">
<p class="compound-first">Compound 1, paragraph 1.</p>
<p class="compound-middle">Compound 1, paragraph 2.</p>
@@ -857,9 +858,42 @@ empty: <tt class="docutils literal"><span class="pre">--&gt;</span></tt></td>
</tbody>
</table>
</div>
+<div class="section" id="list-tables">
+<h2><a class="toc-backref" href="#id60" name="list-tables">2.21&nbsp;&nbsp;&nbsp;List Tables</a></h2>
+<p>Here's a list table exercising all features:</p>
+<table border="1" class="test docutils">
+<caption>list table with integral header</caption>
+<colgroup>
+<col width="17%" />
+<col width="33%" />
+<col width="50%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th>Treat</th>
+<th>Quantity</th>
+<th>Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><th>Albatross</th>
+<td>2.99</td>
+<td>On a stick!</td>
+</tr>
+<tr><th>Crunchy Frog</th>
+<td>1.49</td>
+<td>If we took the bones out, it wouldn't be
+crunchy, now would it?</td>
+</tr>
+<tr><th>Gannet Ripple</th>
+<td>1.99</td>
+<td>On a stick!</td>
+</tr>
+</tbody>
+</table>
+</div>
</div>
<div class="section" id="error-handling">
-<h1><a class="toc-backref" href="#id60" name="error-handling">3&nbsp;&nbsp;&nbsp;Error Handling</a></h1>
+<h1><a class="toc-backref" href="#id61" name="error-handling">3&nbsp;&nbsp;&nbsp;Error Handling</a></h1>
<p>Any errors caught during processing will generate system messages.</p>
<p>There should be five messages in the following, auto-generated
section, &quot;Docutils System Messages&quot;:</p>
@@ -870,17 +904,17 @@ section, &quot;Docutils System Messages&quot;:</p>
<div class="system-message" id="id19">
<p class="system-message-title">System Message: <a name="id19">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 98); <em><a href="#id20">backlink</a></em></p>
Undefined substitution referenced: &quot;problematic&quot;.</div>
-<div class="system-message" id="id68">
-<p class="system-message-title">System Message: <a name="id68">ERROR/3</a> (<tt class="docutils">functional/input/standalone_rst_html4css1.txt</tt>, line 352); <em><a href="#id69">backlink</a></em></p>
+<div class="system-message" id="id69">
+<p class="system-message-title">System Message: <a name="id69">ERROR/3</a> (<tt class="docutils">functional/input/standalone_rst_html4css1.txt</tt>, line 352); <em><a href="#id70">backlink</a></em></p>
Unknown target name: &quot;5&quot;.</div>
-<div class="system-message" id="id70">
-<p class="system-message-title">System Message: <a name="id70">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 361); <em><a href="#id71">backlink</a></em></p>
+<div class="system-message" id="id71">
+<p class="system-message-title">System Message: <a name="id71">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 361); <em><a href="#id72">backlink</a></em></p>
Unknown target name: &quot;nonexistent&quot;.</div>
-<div class="system-message" id="id72">
-<p class="system-message-title">System Message: <a name="id72">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 386); <em><a href="#id73">backlink</a></em></p>
+<div class="system-message" id="id73">
+<p class="system-message-title">System Message: <a name="id73">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 386); <em><a href="#id74">backlink</a></em></p>
Unknown target name: &quot;hyperlink reference without a target&quot;.</div>
-<div class="system-message" id="id74">
-<p class="system-message-title">System Message: <a name="id74">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 399); <em><a href="#id75">backlink</a></em></p>
+<div class="system-message" id="id75">
+<p class="system-message-title">System Message: <a name="id75">ERROR/3</a> (<tt class="docutils">functional/input/data/standard.txt</tt>, line 399); <em><a href="#id76">backlink</a></em></p>
Duplicate target name, cannot be used as a unique reference: &quot;duplicate target names&quot;.</div>
</div>
</div>
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:
<title>
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
+"""],
]