Skip to content

Instantly share code, notes, and snippets.

@tk0miya
Last active January 29, 2019 23:03
Show Gist options
  • Save tk0miya/3423680 to your computer and use it in GitHub Desktop.
Save tk0miya/3423680 to your computer and use it in GitHub Desktop.
sphinxcontrib_wikitable.py
Usage
======
.. wiki-table::
:header-rows: 1
:widths: 2 3 5
|id|header1|header2|
|1|hello|world|
|2|foo|:strong:`bar`|
Warnings
=========
* options for wiki-table directive is same as list-table's one
* wiki-table directive does not support extra cell notation
(cf. |*header|LEFT:aligning|COLOR(red):coloring|)
# -*- coding: utf-8 -*-
"""
sphinxcontrib_wikitable
~~~~~~~~~~~~~~~~~~~~~~~~
:copyright: Copyright 2012 by Takeshi KOMIYA
:license: BSD, see LICENSE for details.
"""
import re
from docutils import nodes
from docutils.parsers.rst import directives
from docutils.parsers.rst.directives.tables import ListTable
from docutils.statemachine import ViewList
from docutils.utils import SystemMessagePropagation
class WikiTableDirective(ListTable):
option_spec = {
'header-rows': directives.nonnegative_int,
'stub-columns': directives.nonnegative_int,
'widths': directives.positive_int_list,
'class': directives.class_option,
'name': directives.unchanged
}
def run(self):
if not self.content:
error = self.state_machine.reporter.error(
'The "%s" directive is empty; content required.' % self.name,
nodes.literal_block(self.block_text, self.block_text),
line=self.lineno)
return [error]
self.rows = self.content
self.detect_header()
title, messages = self.make_title()
try:
table_data = list(self.table_data)
num_cols = self.table_cols
col_widths = self.get_column_widths(num_cols)
header_rows = self.options.get('header-rows', 0)
stub_columns = self.options.get('stub-columns', 0)
self.check_table_dimensions(table_data, header_rows, stub_columns)
except SystemMessagePropagation, detail:
return [detail.args[0]]
table_node = self.build_table_from_list(table_data, col_widths,
header_rows, stub_columns)
table_node['classes'] += self.options.get('class', [])
self.add_name(table_node)
if title:
table_node.insert(0, title)
return [table_node] + messages
def detect_header(self):
if self.options.get('header-rows'):
return
for i, line in enumerate(self.rows):
if re.match('^\|-+(\+-+)*|$', line):
self.rows.remove(line)
self.options['header-rows'] = i
break
def _row(self, rownum):
return self.rows[rownum].split('|')[1:-1]
@property
def table_data(self):
for i in range(len(self.rows)):
row = []
for column in self._row(i):
p = nodes.paragraph()
self.state.nested_parse(ViewList([column], source=column), 0, p)
row.append(p)
yield row
@property
def table_cols(self):
return len(self._row(0))
def setup(app):
app.add_directive('wiki-table', WikiTableDirective)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment