def document_to_html(document: Document, theme: HtmlTheme) -> List[Tag]: logger.info('Serializing HTML5 book...') html = Tag('html') generate_head(document, html, theme) generate_body(document, html, theme) return [Tag('!DOCTYPE html'), html]
def append_component_tag(parent: Tag, component: Component, tag_name: str) -> Tag: for other_id in reversed(component.get_other_refs()): parent.append_tag('a', {'id': other_id}, text='') tag = parent.append_tag(tag_name) tag_id = component.get_main_ref() if tag_id is not None: tag['id'] = tag_id return tag
def generate_styled_text(parent: Tag, styled_text: StyledText): if styled_text.style == 'strong': tag_name = 'strong' elif styled_text.style == 'emphasized': tag_name = 'em' elif styled_text.style == 'code': tag_name = 'code' elif styled_text.style == 'deleted': tag_name = 'del' else: tag_name = None if tag_name is not None: styled_tag = append_component_tag(parent, styled_text, tag_name) generate_components(styled_tag, styled_text.contents) else: if styled_text.style == 'double-quote': parent.append_literal('“') generate_components(parent, styled_text.contents) parent.append_literal('”') elif styled_text.style == 'single-quote': parent.append_literal('‘') generate_components(parent, styled_text.contents) parent.append_literal('’') else: raise StxError(f'Not supported style: {styled_text.style}.', styled_text.location)
def generate_body(document: Document, html: Tag, theme: HtmlTheme): body = html.append_tag('body', {'data-type': 'book'}) if document.title is not None: body.append_tag('h1', text=document.title) if document.header is not None: header = body.append_tag('header') generate_component(header, document.header) if document.content is not None: generate_component(body, document.content) if document.footer is not None: footer = body.append_tag('footer') generate_component(footer, document.footer) for js in theme.body_scripts: body.append_tag('script', { 'type': 'application/javascript', }, text=js, text_literal=True)
def generate_layout(parent: Tag, layout: Layout): container = parent.append_tag('div', { 'data-type': 'layout', 'data-dir': layout.direction, }) for component in layout.components: item = container.append_tag('div', { 'data-type': 'layout-item', }) generate_component(item, component)
def generate_toc_elements(parent: Tag, elements: List[ElementReference]): if len(elements) == 0: return list_tag = parent.append_tag('ol') for element in elements: item_tag = list_tag.append_tag('li') a_tag = item_tag.append_tag('a', { 'href': f'#{element.reference}', 'data-type': 'xref', }, text=element.title) if element.number is not None: a_tag['data-number'] = element.number generate_toc_elements(item_tag, element.elements)
def generate_head(document: Document, html: Tag, theme: HtmlTheme): head = html.append_tag('head') if document.encoding: head.append_tag('meta', {'charset': document.encoding}) if document.author: head.append_tag('meta', { 'name': 'author', 'content': document.author, }) head.append_tag('meta', { 'name': 'generator', 'content': app.app_title, }) if document.title: head.append_tag('title', text=document.title) for css in theme.head_styles: head.append_tag('style', { 'type': 'text/css', }, text=css, text_literal=True) for stylesheet in document.stylesheets: head.append_tag('link', { 'rel': 'stylesheet', 'type': 'text/css', 'href': stylesheet, }) for js in theme.head_scripts: head.append_tag('script', { 'type': 'application/javascript', }, text=js, text_literal=True)
def generate_image(parent: Tag, image: Image): img_tag = parent.append_tag('img') img_tag['src'] = image.src if image.alt: img_tag['alt'] = image.alt
def generate_literal(parent: Tag, literal: Literal): parent.append_literal(literal.text)
def generate_plain_text(parent: Tag, plain_text: PlainText): for ref in plain_text.get_refs(): parent.append_tag('a', {'id': ref}, text='') parent.append_text(plain_text.content)