{"id":20236078,"url":"https://github.com/chingc/pyhtml","last_synced_at":"2025-10-09T18:38:24.157Z","repository":{"id":5397378,"uuid":"6586663","full_name":"chingc/pyhtml","owner":"chingc","description":"Write and format HTML manually with Python!","archived":false,"fork":false,"pushed_at":"2018-11-03T05:18:52.000Z","size":101,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-03T14:25:17.987Z","etag":null,"topics":["html","html-generator"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chingc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-11-07T21:30:47.000Z","updated_at":"2018-11-03T05:18:53.000Z","dependencies_parsed_at":"2022-07-06T15:03:43.529Z","dependency_job_id":null,"html_url":"https://github.com/chingc/pyhtml","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/chingc/pyhtml","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chingc%2Fpyhtml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chingc%2Fpyhtml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chingc%2Fpyhtml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chingc%2Fpyhtml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chingc","download_url":"https://codeload.github.com/chingc/pyhtml/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chingc%2Fpyhtml/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279001895,"owners_count":26083226,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["html","html-generator"],"created_at":"2024-11-14T08:19:02.600Z","updated_at":"2025-10-09T18:38:24.140Z","avatar_url":"https://github.com/chingc.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pyhtml\n\n[![CircleCI](https://circleci.com/gh/chingc/pyhtml.svg?style=shield)](https://circleci.com/gh/chingc/workflows/pyhtml) [![codecov](https://codecov.io/gh/chingc/pyhtml/branch/master/graph/badge.svg)](https://codecov.io/gh/chingc/pyhtml) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)\n\nFor those who love Python and, for reasons unknown, still like to write and format HTML manually.\n\n## Installation\n\n1. Add `pyhtml.py` to your project\n1. `import pyhtml`\n\n## Reference\n\n### new\n\nThis is the first thing to call and will return a new instance of PyHTML.\n\n```python\n\u003e\u003e\u003e pyhtml.new()\n```\n\nIt can take the following arguments:\n\n- `doctype: str` - doctype declaration (default: \"\")\n  - valid doctypes: html5, html4.01s, html4.01t, html4.01f, xhtml1.1, xhtml1.0s, xhtml1.0t, xhtml1.0f\n- `spaces: int` - number of spaces used for indentation (default: 4)\n\nFor html4.01 and xhtml1.0: s, t, and f stands for strict, transitional, and frameset, respectively.\n\n### attr\n\nStrings and tuples are stringified into HTML attribute form.\n\n```python\n\u003e\u003e\u003e pyhtml.attr((\"src\", \"simpsons.webm\"), \"autoplay\", (\"width\", 800), (\"height\", 600))\n'src=\"simpsons.webm\" autoplay width=\"800\" height=\"600\"'\n```\n\nStrings are treated as boolean attributes and 2-tuples are treated as value attributes.  Tuples can take the form (str, str) or (str, int).  Multiple comma separated strings and tuples can be specified.\n\n### append\n\n- `string: str` -- add arbitrary text to the HTML\n\n### indent\n\nAdd indentation.  Indentation is handled automatically by default.  This is useful during manual spacing.\n\n### newline\n\nAdd a newline.  Newlines are handled automatically by default.  This is useful during manual spacing or when additional newlines are desired.\n\n### vwrap\n\nAdd a void element.  These are elements that do not have a closing tag.\n\n- `elem: str` -- an HTML void element\n- `attrs: str` -- element attributes (default: \"\")\n\n```python\n\u003e\u003e\u003e html = pyhtml.new()\n\u003e\u003e\u003e html.vwrap(\"img\", pyhtml.attr((\"src\", \"kwikemart.png\"), (\"width\", 358), (\"height\", 278)))\n\u003e\u003e\u003e print(html)\n\u003cimg src=\"kwikemart.png\" width=\"358\" height=\"278\"\u003e\n```\n\n### wrap\n\nAdd an element.  The closing tag will be inserted automatically.\n\n- `elem: str` -- an HTML element\n- `attrs: str` -- element attributes (default: \"\")\n\n```python\n\u003e\u003e\u003e html = pyhtml.new()\n\u003e\u003e\u003e with html.wrap(\"div\", pyhtml.attr((\"class\", \"big\"))):\n...     html.append(\"Embiggened!\")\n...\n\u003e\u003e\u003e print(html)\n\u003cdiv class=\"big\"\u003e\n    Embiggened!\n\u003c/div\u003e\n```\n\n### manual_spacing\n\nDisable automatic indentation and newlines.  Statements within the block will not have automatic indentation or newlines.\n\n```python\n\u003e\u003e\u003e html = pyhtml.new()\n\u003e\u003e\u003e with html.manual_spacing():\n...     with html.wrap(\"em\"):\n...         html.append(\"Itchy\")\n...     html.append(\" \u0026 \")\n...     with html.wrap(\"em\"):\n...         html.append(\"Scratchy\")\n...\n\u003e\u003e\u003e print(html)\n\u003cem\u003eItchy\u003c/em\u003e \u0026 \u003cem\u003eScratchy\u003c/em\u003e\n```\n\n## Examples\n\n```python\n\u003e\u003e\u003e import pyhtml\n\u003e\u003e\u003e html = pyhtml.new()\n\u003e\u003e\u003e with html.wrap(\"html\"):\n...     with html.wrap(\"head\"):\n...         with html.wrap(\"title\"):\n...             html.append(\"Dr. Nick\")\n...     with html.wrap(\"body\"):\n...         with html.wrap(\"p\"):\n...             html.append(\"Hi, everybody!\")\n...\n\u003e\u003e\u003e print(html)\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003ctitle\u003e\n            Dr. Nick\n        \u003c/title\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n        \u003cp\u003e\n            Hi, everybody!\n        \u003c/p\u003e\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n\n```python\n# Disable auto-spacing when you want to have\n# a wrapped element on a single line.\n\n\u003e\u003e\u003e import pyhtml\n\u003e\u003e\u003e html = pyhtml.new()\n\u003e\u003e\u003e with html.wrap(\"html\"):\n...     with html.wrap(\"head\"):\n...         with html.manual_spacing():\n...             html.indent()\n...             with html.wrap(\"title\"):\n...                 html.append(\"Ned Flanders\")\n...             html.newline()\n...     with html.wrap(\"body\"):\n...         with html.manual_spacing():\n...             html.indent()\n...             with html.wrap(\"p\"):\n...                 html.append(\"Hi diddly ho!\")\n...             html.newline()\n...\n\u003e\u003e\u003e print(html)\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003ctitle\u003eNed Flanders\u003c/title\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n        \u003cp\u003eHi diddly ho!\u003c/p\u003e\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n\n```python\n# Tip: Context managers can be nested.\n\n\u003e\u003e\u003e import pyhtml\n\u003e\u003e\u003e html = pyhtml.new()\n\u003e\u003e\u003e family = [\"homer\", \"marge\", \"bart\", \"lisa\", \"maggie\"]\n\u003e\u003e\u003e with html.wrap(\"ul\"), html.manual_spacing():\n...     for member in family:\n...         html.indent()\n...         with html.wrap(\"li\"):\n...             html.append(member)\n...         html.newline()\n...\n\u003e\u003e\u003e print(html)\n\u003cul\u003e\n    \u003cli\u003ehomer\u003c/li\u003e\n    \u003cli\u003emarge\u003c/li\u003e\n    \u003cli\u003ebart\u003c/li\u003e\n    \u003cli\u003elisa\u003c/li\u003e\n    \u003cli\u003emaggie\u003c/li\u003e\n\u003c/ul\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchingc%2Fpyhtml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchingc%2Fpyhtml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchingc%2Fpyhtml/lists"}