def render_cmd_sub_sup(self, children: List[MathTexAST], font_size) -> HtmlElement: elem = HtmlElement() main_item = self.render(children[0], font_size) elem.children.append(main_item) elem.width = main_item.width elem.height = main_item.height elem.baseline = main_item.baseline sub_size = (font_size + 3) / 5 if children[1] is not None: sub_item = self.render(children[1], sub_size) sub_item.x = main_item.width + sub_size * self.char_margin elem.children.append(sub_item) elem.width = sub_item.x + sub_item.width if sub_item.height > main_item.height / 2: main_item.y = sub_item.height - main_item.height / 2 elem.baseline += main_item.y elem.height += main_item.y if children[2] is not None: sup_item = self.render(children[2], sub_size) sup_item.x = main_item.width + sub_size * self.char_margin elem.children.append(sup_item) elem.width = max(elem.width, sup_item.x + sup_item.width) delta = sup_item.height - main_item.height / 2 if delta <= 0: sup_item.y = main_item.y + main_item.height / 2 - delta else: sup_item.y = main_item.y + main_item.height / 2 elem.height += delta return elem
def align_children(self, elem: HtmlElement, font_size): elem.width = 0 elem.height = 0 elem.baseline = 0 for i in range(0, len(elem.children)): if i > 0: elem.width += self.char_margin * font_size child = elem.children[i] child.x = elem.width if child.baseline > elem.baseline: elem.baseline = child.baseline elem.width += child.width for child in elem.children: child.y = elem.baseline - child.baseline if child.y + child.height > elem.height: elem.height = child.y + child.height return elem
def render_cmd_square_root(self, children: List[MathTexAST], font_size) -> HtmlElement: elem = HtmlElement() inner_item = self.render(children[0], font_size) inner_item.x = 0.4 * font_size inner_item.y = 0.1 * font_size elem.width = inner_item.x + inner_item.width + 0.2 * font_size elem.height = inner_item.y + inner_item.height elem.baseline = inner_item.y + inner_item.baseline elem.children = [inner_item] + HtmlElement.create_square_root_group( elem.width, elem.height, font_size) return elem
def render_cmd_fraction(self, children: List[MathTexAST], font_size) -> HtmlElement: elem = HtmlElement() up_item = self.render(children[0], font_size) down_item = self.render(children[1], font_size) elem.width = max(up_item.width, down_item.width) + font_size / 2 elem.height = up_item.height + down_item.height + self.line_margin * font_size elem.update_baseline(font_size, pseudo_height=up_item.height * 2 + self.line_margin * font_size) up_item.x = (elem.width - up_item.width) / 2 down_item.x = (elem.width - down_item.width) / 2 down_item.y = elem.height - down_item.height line = HtmlElement.create_horizontal_line( font_size / 8, up_item.height + self.line_margin * font_size / 2, elem.width - font_size / 4) elem.children = [up_item, down_item, line] return elem
def align_children_grid(self, elem: HtmlElement, children: Array2D[HtmlElement], font_size): rows = Array1D(children.height, lambda: RowColumnMeta()) columns = Array1D(children.width, lambda: RowColumnMeta()) def update_row_column_meta1(y, x, item: HtmlElement): if item.baseline > rows[y].baseline: rows[y].baseline = item.baseline if item.width > columns[x].width: columns[x].width = item.width def update_row_column_meta2(y, _, item: HtmlElement): y_offset = rows[y].baseline - item.baseline new_height = y_offset + item.height if new_height > rows[y].height: rows[y].height = new_height children.for_each_not_none(update_row_column_meta1) children.for_each_not_none(update_row_column_meta2) for i in range(0, children.height): if i > 0: rows[i].y = rows[i - 1].y + rows[ i - 1].height + self.line_margin * font_size elem.height = rows[i].y + rows[i].height elem.update_baseline(font_size) for j in range(0, children.width): if j > 0: columns[j].x = columns[j - 1].x + columns[ j - 1].width + self.cell_margin * font_size elem.width = columns[j].x + columns[j].width def update_cell_position(y, x, item: HtmlElement): item.x = columns[x].x item.y = rows[y].y + rows[y].baseline - item.baseline elem.children.append(item) children.for_each_not_none(update_cell_position)