import re import border import font import html_util from html_util import E # A purely numeric cell value (either decimal-mark style, optional sign). number_rgx = re.compile(r"[-+]?[\d.,]+$") class Cell: def __init__(self, text, font, hpos, top, right, bottom, left, left_all, right_all, rowspan, colspan, first_column=False, hpos_forced=False): self.text = text self.font = font self.hpos = hpos # An :hpos override on an ordinary cell must reach the tex target # through a \multicolumn{1} (the column spec sets the default). self.hpos_forced = hpos_forced self.border = border.Border(top, right, bottom, left, left_all, right_all) self.rowspan = rowspan self.colspan = colspan self.first_column = first_column #print("Cell:", text, hpos) def __str__(self): b = str(self.border) b = f"[{b}]" if b else "" rs = f"[r{self.rowspan}]" if self.rowspan else "" cs = f"[r{self.colspan}]" if self.colspan else "" #return f'' return f'' def __repr__(self): return self.__str__() def html(self): result = self.text result = E("td").body(font.html_fontify(result, self.font, 1.0)) if self.rowspan > 1: result.attr("rowspan", self.rowspan) if self.colspan > 1: result.attr("colspan", self.colspan) for pred, cls_name in zip(self.border.has(), "Bt Br Bb Bl".split()): if pred: result.cls(cls_name) result.cls(f"H{self.hpos}") return result.str() def tex(self, debug=False): # , left_line, right_line): result = self.text # A number must not line-break (LaTeX breaks after a minus sign # read as a hyphen in narrow fit-width columns). if number_rgx.match(result.strip()): result = f"\\mbox{{{result.strip()}}}" if self.font != "r": result = font.tex_fontify(result, self.font, 1.0) if self.rowspan > 1: result = f"\\multirow{{{self.rowspan}}}{{*}}{{{result}}}" if self.colspan > 1: # \multicolumn carries the merged cell's own column spec. A # left bar may only be given when the span starts at the # table's first column: elsewhere the bar to the left belongs # to the preceding column's preamble entry, and adding one # here draws a doubled line. pos = self.hpos if self.border.left and self.first_column: pos = "|" + pos if self.border.right: pos = pos + "|" return f"\\multicolumn{{{self.colspan}}}{{{pos}}}{{{result}}}" remove_left = self.border.left_all and not self.border.left remove_right = self.border.right_all and not self.border.right if debug: left_marker = "xL" if remove_left else "L" if self.border.left_all else "" right_marker = "Rx" if remove_right else "R" if self.border.right_all else "" result = f"{left_marker} {result} {right_marker}" if remove_left or remove_right or self.hpos_forced: pos = self.hpos if self.border.left_all and self.border.left: pos = "|" + pos if self.border.right_all and self.border.right: pos = pos + "|" result = f"\\multicolumn{{1}}{{{pos}}}{{{result}}}" return result if __name__ == "__main__": print(Cell("dog", "r", "c", True, False, True, False))