{"id":15047743,"url":"https://github.com/csb6/html-plus-plus","last_synced_at":"2025-04-07T09:18:57.457Z","repository":{"id":44413668,"uuid":"275442543","full_name":"csb6/html-plus-plus","owner":"csb6","description":"Write HTML using C++ templates","archived":false,"fork":false,"pushed_at":"2020-06-27T21:12:19.000Z","size":25,"stargazers_count":431,"open_issues_count":0,"forks_count":31,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-03-31T07:08:46.503Z","etag":null,"topics":["c-plus-plus","cpp20","html","template-metaprogramming"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/csb6.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":"2020-06-27T19:46:46.000Z","updated_at":"2025-03-22T10:34:41.000Z","dependencies_parsed_at":"2022-09-09T12:50:24.329Z","dependency_job_id":null,"html_url":"https://github.com/csb6/html-plus-plus","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csb6%2Fhtml-plus-plus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csb6%2Fhtml-plus-plus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csb6%2Fhtml-plus-plus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csb6%2Fhtml-plus-plus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/csb6","download_url":"https://codeload.github.com/csb6/html-plus-plus/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247622983,"owners_count":20968575,"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","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":["c-plus-plus","cpp20","html","template-metaprogramming"],"created_at":"2024-09-24T21:04:08.864Z","updated_at":"2025-04-07T09:18:57.429Z","avatar_url":"https://github.com/csb6.png","language":"C++","readme":"# HTML++\n\nWrite HTML using C++ templates. The HTML document is represented as a single,\ndeeply-nested type which is type-checked by the compiler using certain rules about how\nHTML elements are allowed to be nested (e.g. nothing can be a child of a `\u003cbr\u003e` tag).\n\nIf compilation succeeds, you will have a program that prints a properly-indented\nHTML document to the standard output when run.\n\n## Example\n\nSay you want to write the following HTML page:\n\n```html\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003ctitle\u003eHelp Me.\u003c/title\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003ch1\u003eThe horror!\u003c/h1\u003e\n    \u003cp\u003e\n      Someone has probably done this before, but I can see why it didn't catch on.\n    \u003c/p\u003e\n    \u003ca href=\"https://github.com/csb6/html-plus-plus\"\u003eFor science\u003c/a\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\nHere is a C++ program that can be used to generate that page:\n\n```cpp\n#include \u003ciostream\u003e\n#include \"html++.h\"\n\nint main()\n{\n  html\u003c\n    head\u003c\n      title\u003c\"Help Me.\"\u003e\n    \u003e,\n    body\u003c\n      h1\u003c\"The horror!\"\u003e,\n      p\u003c\"Someone has probably done this before, but I can see why it didn't catch on.\"\u003e,\n      a\u003c\"href=https://github.com/csb6/html-plus-plus\", \"For science\"\u003e\n    \u003e\n  \u003e page;\n\n\n  std::cout \u003c\u003c page.content;\n\n  return 0;\n}\n```\n\n## Installation\n\nThis library requires C++20. It works with GCC 9.2.0 with `-std=c++2a` enabled.\nIt doesn't work with Apple Clang 11.0, but it might work on other compilers. If\nC++20 is fully implemented on a given compiler, it should be able to compile.\n\nSimply `#include html++.h`. It is the only file you need.\n\n## Questions\n\n### Why\n\nI was writing some HTML, and I realized that the structure and syntax of\nHTML tags was quite a bit like the structure/syntax of C++ templates. Both\nenable you to nest identifiers into a tree structure.\n\nSince variadic templates were added to C++, a template can hold any\nnumber of other types in a parameter pack, enabling parent nodes to hold any\nnumber of child nodes. This is necessary in order for HTML elements to be\nproperly represented by C++ types.\n\nSince C++20, it is now possible to use string literals as non-type template\nparameters (e.g. `h1\u003c\"This is a title\"\u003e`), making C++ templates capable of\nimitating the appearance of HTML tags even more closely.\n\nI thought I'd see how horrible it would be, and, as expected, it is pretty\nridiculous.\n\n### How\n\nThe entire library is basically a fancy way of concatenating strings.\nEach tag is defined as its own template struct\n(e.g. `template\u003c...\u003e struct h1 { ... };`). Each tag takes 0 or more type/\nnon-type template parameters. Template parameters can be HTML attributes\n(e.g. `\"img\u003csrc='pic.png'\", \"alt='A picture'\"\u003e`) or an arbitrarily long list of\nother element types, which can themselves hold other types as child nodes\n(e.g. `html\u003chead\u003ctitle\u003c...\u003e\u003e, body\u003c...\u003e\u003e`).\n\nType safety can be achieved by defining only template parameters that make sense for\na tag (e.g. `\u003cimg\u003e` is a self-closing tag, so it would not make sense for it to accept a\ntemplate parameter pack of child nodes). Using inheritance and\n`static_assert`, along with \"phantom\" types (e.g. `img` inherits from an empty struct\nnamed `body_element_tag`), ensures that the tags make semantic sense as children\nof a given node. In this way, HTML can be given a degree of type-checking.\n\nThe output text is assembled by pre-order traversing the tree of types, calling each type's\nconstructor recursively. Each element adds its opening tag (e.g. `\u003chtml\u003e`) to a string\nthat is then passed by reference to each child element recursively. Once all children have\nadded their opening tags, each node adds its closing tag (e.g. `\u003c/html\u003e`) and returns from its\nconstructor. The string is stored in a member of the top-level node (`html`) and can be\nprinted and/or used like a normal string at runtime. The string is assembled at runtime;\nhowever, the structure of the document is defined at compile-time.\n\n### Should I use it\n\nProbably not. However, I think the type-checking aspect could be useful. I haven't added all HTML tags,\nbut in theory this library could be extended in such a way that you could write HTML\nwith somewhat strong typing, which might be useful for ensuring HTML standards conformance.\n\nHope this project is interesting (and concerning) to you!\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcsb6%2Fhtml-plus-plus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcsb6%2Fhtml-plus-plus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcsb6%2Fhtml-plus-plus/lists"}