diff --git a/legalmd/latex_renderer.py b/legalmd/latex_renderer.py index b9b19df..a41e94f 100644 --- a/legalmd/latex_renderer.py +++ b/legalmd/latex_renderer.py @@ -148,9 +148,7 @@ class LaTeXRenderer(mistletoe.latex_renderer.LaTeXRenderer): align = ['X' for col in token.column_align] if hasattr(token, 'header'): for i, col in enumerate(token.header.children): - if '[' in col.children[0].content.split(' ')[0]: - param = col.children[0].content[col.children[0].content.index('['):col.children[0].content.index(']')+1] - align[i] += param + align[i] += '[{}]'.format(col.weight) result = [ format('{\\footnotesize\\begin{longtabu} to \\dimexpr\\columnwidth-\\relax [r] {'), @@ -170,24 +168,22 @@ class LaTeXRenderer(mistletoe.latex_renderer.LaTeXRenderer): return ''.join(result) def render_table_header(self, token): - cells1 = ['{\\bfseries Column ' + self.render_inner(child).split(' ')[0].split('[')[0] + '}' for child in token.children] - cells2 = ['{\\bfseries ' + ' '.join(self.render_inner(child).split(' ')[1:]) + '}' for child in token.children] + cells1 = ['{\\bfseries Column ' + child.label + '}' for child in token.children] + cells2 = ['{\\bfseries ' + self.render_inner(child) + '}' for child in token.children] return ' & '.join(cells1) + ' \\\\\\midrule\n' + ' & '.join(cells2) + ' \\\\' def render_table_row(self, token): - cells = [self.render_table_cell(child, colnum) for colnum, child in enumerate(token.children)] + cells = [self.render_table_cell(child) for child in token.children] return ' & '.join(cells) + ' \\\\' - def render_table_cell(self, token, colnum): - inner = self.render_inner(token) - - if colnum == 0: + def render_table_cell(self, token): + if token.colnum == 0 and token.label: return format(r'\makebox[2.2em][l]{.}', - rownum=inner.split(' ')[0], - content=' '.join(inner.split(' ')[1:]) + rownum=token.label, + content=self.render_inner(token) ) else: - return inner + return self.render_inner(token) def render_document(self, token): template = r''' diff --git a/legalmd/legal_token.py b/legalmd/legal_token.py index ea5b914..ce0be4c 100644 --- a/legalmd/legal_token.py +++ b/legalmd/legal_token.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +from itertools import zip_longest import re import mistletoe @@ -155,3 +156,60 @@ mistletoe.block_token.add_token(Definition) def convert_leading_tabs(string): return string mistletoe.block_token.Quote.convert_leading_tabs = convert_leading_tabs + +class Table(mistletoe.block_token.BlockToken): + def __init__(self, lines): + if '---' in lines[1]: + self.column_align = [mistletoe.block_token.Table.parse_align(column) + for column in mistletoe.block_token.Table.split_delimiter(lines[1])] + self.header = TableRow(lines[0], 0, self.column_align) + self.children = [TableRow(line, rownum + 1, self.column_align) for rownum, line in enumerate(lines[2:])] + else: + self.column_align = [None] + self.children = [TableRow(line, rownum) for rownum, line in enumerate(lines)] + + @staticmethod + def start(line): + return '|' in line + + @staticmethod + def read(lines): + lines.anchor() + line_buffer = [next(lines)] + while lines.peek() is not None and '|' in lines.peek(): + line_buffer.append(next(lines)) + if len(line_buffer) < 2 or '---' not in line_buffer[1]: + lines.reset() + return None + return line_buffer + +class TableRow(mistletoe.block_token.BlockToken): + def __init__(self, line, rownum, row_align=None): + self.rownum = rownum + self.row_align = row_align or [None] + cells = filter(None, line.strip().split('|')) + self.children = [TableCell(x[0].strip() if x[0] else '', self, colnum, x[1]) + for colnum, x in enumerate(zip_longest(cells, self.row_align))] + self.label = self.children[0].label + +class TableCell(mistletoe.block_token.BlockToken): + pattern1 = re.compile(r'\s*([0-9A-Za-z]+\s+)?(\[[0-9]+\])?(.*)') + + def __init__(self, inner, row, colnum, align=None): + self.row = row + self.colnum = colnum + self.align = align + + if self.colnum == 0 or self.row.rownum == 0: + label, weight, content = self.pattern1.match(inner).group(1, 2, 3) + + self.label = label.strip() if label else None + self.weight = int(weight[1:-1]) if weight else 1 + self.children = mistletoe.span_token.tokenize_inner(content) + else: + self.label = None + self.weight = None + self.children = mistletoe.span_token.tokenize_inner(inner) + +mistletoe.block_token.remove_token(mistletoe.block_token.Table) +mistletoe.block_token.add_token(Table) diff --git a/legalmd/rtf_renderer.py b/legalmd/rtf_renderer.py index b04d8d5..d1cfb4d 100644 --- a/legalmd/rtf_renderer.py +++ b/legalmd/rtf_renderer.py @@ -155,13 +155,8 @@ class RTFRenderer(mistletoe.base_renderer.BaseRenderer): result = [format(r'{\sa0\trowd\trgaph120\trleft')] # Get column weights - weights = [] if hasattr(token, 'header'): - for col in token.header.children: - if '[' in col.children[0].content.split(' ')[0]: - weights.append(int(col.children[0].content[col.children[0].content.index('[')+1:col.children[0].content.index(']')])) - else: - weights.append(1) + weights = [col.weight for col in token.header.children] else: weights = [1 for col in token.column_align] @@ -184,24 +179,22 @@ class RTFRenderer(mistletoe.base_renderer.BaseRenderer): return ''.join(result) def render_table_header(self, token): - cells1 = ['{\\b Column ' + self.render_inner(child).split(' ')[0].split('[')[0] + '\\intbl\\cell}' for child in token.children] - cells2 = ['{\\b ' + ' '.join(self.render_inner(child).split(' ')[1:]) + '\\intbl\\cell}' for child in token.children] + cells1 = ['{\\b Column ' + child.label + '\\intbl\\cell}' for child in token.children] + cells2 = ['{\\b ' + self.render_inner(child) + '\\intbl\\cell}' for child in token.children] return ''.join(cells1) + '\\row' + ''.join(cells2) + '\\row ' def render_table_row(self, token): - return ''.join([self.render_table_cell(cell, i) for i, cell in enumerate(token.children)]) + '\\row ' + return ''.join([self.render_table_cell(cell) for cell in token.children]) + '\\row ' - def render_table_cell(self, token, colnum): - inner = self.render_inner(token) - - if colnum == 0: + def render_table_cell(self, token): + if token.colnum == 0 and token.label: return format(r'{. \intbl\cell}', - rownum=inner.split(' ')[0], - content=' '.join(inner.split(' ')[1:]) + rownum=token.label, + content=self.render_inner(token) ) else: return format(r'{\intbl\cell}', - content=inner + content=self.render_inner(token) ) def render_thematic_break(self, token):