I have already implemented table support, but I'm am not sure how well it works across different setups. Feedback would be much appreciated.
I am keeping track of where I am in the table to hopefully make it easy to add support for nested tables in the future. Keeping track of where you are is a simple pop/push operation. Push (append) the current node to the node type array when the node is entered, and pop it off the node type array when the node is departed.
def visit_table(self, node):
self.tables.append(node)
def depart_table(self, node):
self.tables.pop()
Notice that I'm doing this with other nodes besides the table node. For example, I do this with thead
, tbody
and row
.
def visit_row(self, node):
if not len(self.theads) and not len(self.tbodys):
raise nodes.SkipNode
self.rows.append(node)
def depart_row(self, node):
self.add('|\n')
if not len(self.theads):
self.row_entries = []
self.rows.pop()
Keeping track of where you are in the table (basically reference counting) simplifies the code. Instead of using integer counters, I am using arrays of nodes. This allows referencing the nodes from other visit methods. This can come in handy quite often. For example, I use the "reference counting node arrays" to generate padding in the table entries making the tables look much prettier.
Basically, I am finding the largest string in a column and using it to calculate the padding. This would be very challenging if I did not have access to nodes outside of the current node.
@property
def rows(self):
rows = []
if not len(self.tables):
return rows
for node in self.tables[len(self.tables) - 1].children:
if isinstance(node, nodes.row):
rows.append(node)
else:
for node in node.children:
if isinstance(node, nodes.row):
rows.append(node)
return rows
def depart_entry(self, node):
length = 0
i = len(self.row_entries) - 1
for row in self.rows:
if len(row.children) > i:
entry_length = len(row.children[i].astext())
if entry_length > length:
length = entry_length
padding = ''.join(_.map(range(length - len(node.astext())), lambda: ' '))
self.add(padding + ' ')
https://github.com/codejamninja/sphinx-markdown-builder/blob/master/sphinx_markdown_builder/markdown_writer.py#L320-L329
I am thinking about possibly implementing this reference counting across all of the nodes. It could simplify the design of some of the more complex transpiling.
Please discuss the reference counting more at the issue below.
#8