import re from jinja2 import Environment, FileSystemLoader from mistletoe import HtmlRenderer from .comment import BlockComment from .dash import Dash from .document import Document from .formula import Formula from .halfwidth_spaces import HalfwidthSpaces from .image import Image from .include import Include from .index import Index from .morse import Morse from .nonbreaking_spaces import NonbreakingSpaces, NonbreakingSpacesDots from .qso import Qso from .question import Question from .quote import Quote from .reference import Reference from .table import Table, TableBody, TableCell, TableHeader, TableRow from .tag import Tag from .underline import Underline from .unit import Unit table_alignment = {"l": "left", "c": "center", "r": "right"} class FiftyOhmHtmlRenderer(HtmlRenderer): margin_anchor_id = 0 margin_id = 0 def __init__( self, *extras, question_renderer=None, picture_handler=None, photo_handler=None, include_handler=None, edition=None, chapter=None, section=None, section_url=None, **kwargs, ): super().__init__( Dash, BlockComment, Quote, Unit, Underline, Morse, Tag, HalfwidthSpaces, NonbreakingSpaces, NonbreakingSpacesDots, Reference, Question, Image, Table, TableHeader, TableRow, TableCell, TableBody, Qso, Include, Formula, Index, *extras, **kwargs, ) self.question_renderer = question_renderer self.picture_handler = picture_handler self.photo_handler = photo_handler self.include_handler = include_handler # Figure numbering context self.edition = edition self.chapter = chapter self.section = section # Set section URL if provided, otherwise use default self.section_url = section_url if section_url is not None else "section.html" self.references: dict[str, str] = {} # Keep track of index ids already emitted in this document. self.index_anchor_ids = set() def _format_reference_label(self, marker: str): if marker in self.references: label = self.references[marker] if self.edition and self.chapter and self.section: label = f"{self.edition}-{self.chapter}.{self.section}.{label}" return label else: return None def render_dash(self, token): return " – " def render_block_comment(self, token): return None def render_quote(self, token): return f"”{self.render_inner(token)}”" def render_underline(self, token): return f"{self.render_inner(token)}" @classmethod def render_unit(cls, token: Unit): unit = token.prefix + cls.convert_unit_helper(token.unit) if token.unit == "°": # Special case with no space between value and unit. return f"{token.value}{unit}" else: # Default case is rendered with a narrow no-break space. return f"{token.value} {unit}" units = { "Ohm": "Ω", "ohm": "Ω", } @classmethod def convert_unit_helper(cls, unit: str) -> str: """Converts human-typable units to their preferred representation. :param str unit: The unit to convert """ if unit in cls.units.keys(): return cls.units[unit] else: return unit def render_thematic_break(self, token): self.margin_anchor_id += 1 return f'' @staticmethod def render_morse_helper(morse_code): result = '' for char in morse_code: result += '\n' for symbol in char: result += '\n' if symbol == 1: result += "▄" elif symbol == 2: result += "▄▄▄" elif symbol == 3: result += " " result += "\n" result += "\n" result += "" return result def render_morse(self, token): morse_code = Morse.convert_to_morse_code(token.content) return self.render_morse_helper(morse_code) @staticmethod def render_tag_helper(type, content, margin_id, margin_anchor_id): """This function is used to render the different types of tags. It is used in the HtmlRenderer class and also in the test class""" env = Environment(loader=FileSystemLoader("templates/html")) margin_template = env.get_template("margin.html") return margin_template.render( type=type, content=content, id=margin_id, margin_anchor_id=margin_anchor_id, ) def render_tag(self, token): if token.tagtype == "latexonly": return "" elif token.tagtype == "webonly": return self.render_inner(token) self.margin_id += 1 if token.tagtype == "webmargin": type = "margin" elif token.tagtype == "webtip": type = "tip" elif token.tagtype == "webindepth": type = "indepth" else: type = token.tagtype return self.render_tag_helper(type, self.render_inner(token), self.margin_id, self.margin_anchor_id) def render_qso(self, token): self.margin_id += 1 qso = "" for child in token.children: direction = "other" if child.received else "own" qso += f'