{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# `html5tagger` 快速上手\n", "\n", "安装:\n", "\n", "```bash\n", "pip install html5tagger\n", "```\n", "\n", "`html5tagger` 提供了两个 HTML 生成的起点:`E` 用于创建空的构建器来生成 HTML 片段,或者 `Document` 用于生成带有 `DOCTYPE` 声明的完整 HTML 文档。两者都会产生 `Builder` 对象,以防你需要它进行类型注解。\n", "\n", "通过点表示法创建片段并添加标签:\n", "\n", "```python \n", "E.p(\"Powered by:\").br.a(href=\"...\")(\"html5tagger\")\n", "```\n", "\n", "生成:\n", "\n", "```html\n", "

Powered by:
html5tagger\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## `html5tagger` 简单示例" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from html5tagger import Document, E" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "创建 `document`:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "doc = Document(\n", " E.TitleText_, # 第一个参数是用于 ``,添加变量TitleText。\n", " lang=\"en\", # 关键字参数用于 `<html>` 属性。\n", " # 只需列出你需要的资源,无需记住 link/script标签。\n", " _urls=[ \"style.css\", \"favicon.png\", \"manifest.json\" ]\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "大写名称是模板变量。你可以在之后修改它们:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "<!DOCTYPE html><html lang=en><meta charset=\"utf-8\"><title>\n" ] } ], "source": [ "print(doc.Head_)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "进入 `

` 并同时更新 ``。" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "<!DOCTYPE html><html lang=en><meta charset=\"utf-8\"><title>Demo

Demo

\n" ] } ], "source": [ "print(doc.h1.TitleText_(\"Demo\") )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "这一直是 DOM 和其他此类生成器的难题:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "Demo

Demo

A paragraph with a link and formatting" ], "text/plain": [ "《Document Builder》\n", "《TitleText:Demo》《Head》

《TitleText:Demo》

A paragraph with a link and formatting" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "doc.p(\"A paragraph with \").a(\"a link\", href=\"/files\")(\" and \").em(\"formatting\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "对于复杂的嵌套(通常不需要)使用 {data}`with`。" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "with doc.table(id=\"data\"):\n", " doc.tr.th(\"First\").th(\"Second\").th(\"Third\")\n", " doc.TableRows_" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "在模板变量中添加一些东西:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "print(doc.Head._script(\"console.log(' escaping is weird')\"))" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "table = doc.TableRows\n", "for row in range(10):\n", " table.tr\n", " for col in range(3):\n", " table.td(row * col)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "Demo

Demo

A paragraph with a link and formatting
FirstSecondThird
000
012
024
036
048
0510
0612
0714
0816
0918
" ], "text/plain": [ "《Document Builder》\n", "《TitleText:Demo》《Head:

《TitleText:Demo》

A paragraph with a link and formatting
FirstSecondThird《TableRows:
000< ···》
" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "doc" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "或者删除我们刚刚添加的表格数据:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "doc.TableRows = None" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "Demo

Demo

A paragraph with a link and formatting
FirstSecondThird
" ], "text/plain": [ "《Document Builder》\n", "《TitleText:Demo》《Head:

《TitleText:Demo》

A paragraph with a link and formatting
FirstSecondThird《TableRows》
" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "doc" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "你可以使用 `str(doc)` 来获取 HTML 代码,直接使用 `doc` 通常也能达到预期效果(例如提供 HTML 响应)。Jupyter Notebooks 将其渲染为 HTML。对于调试,使用 `repr(doc)`,其中模板变量是可见的:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Demo

Demo

A paragraph with a link and formatting
FirstSecondThird
'" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "print(doc)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "实际的 HTML 输出是类似的。文档中没有添加任何空白,除非内容包含换行符,否则都在同一行。您可能会注意到,`body` 和其他熟悉的标签都不见了,转义也很少。这就是HTML5:文档符合标准,且少了很多冗余。\n", "\n", "## `html5tagger` 模板\n", "\n", "使用模板变量构建一次文档,在渲染时只更新动态部分,以获得更快的性能。通过 `doc.TitleText` 访问模板变量,并在标签名后的括号中添加内容。标签名末尾的下划线表示该标签被添加到文档中,并且可以在括号中有内容,但同一行上任何进一步的标签都会进入原始文档,而不是模板。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## `html5tagger` 嵌套\n", "\n", "在 HTML5 中,像 `

` 这样的元素不需要任何闭合标签,因此我们可以不断添加内容而不必担心何时应该关闭。对于可选或禁止使用闭合标签的元素,此模块不使用闭合标签。\n", "\n", "当您向一个元素添加内容或添加另一个标签时,该元素会自动闭合。仅仅设置属性并不会关闭一个元素。如果后续的任何内容都不应该在它内部,则可以使用(`None`)来关闭空元素,例如 `doc.script(None, src=\"...\")`。\n", "\n", "对于像 `` 和 `