HTML++用C++模板编写HTML

2020-06-29 11:59:31

使用C++模板编写HTML。HTML文档表示为单个深度嵌套类型,编译器使用有关HTML元素如何允许嵌套的某些规则进行类型检查(例如,任何内容都不能是<;br>;标记的子级)。

如果编译成功,您将拥有一个在运行时将正确缩进的HTML文档打印到标准输出的程序。

<;html>;<;Head>;<;Title>;帮助我。<;/title>;<;/head>;<;body>;h1>;The Horror!<;/h1>;<;p>;以前可能有人这样做过,但我明白为什么它没有流行起来。<;/p&>;<;a href=";https://github.com/csb6/html-plus-plus";>;对于科学<;/a>;<;/Body>;<;/html>;

#include<;iostream>;#include";html++.h";int main(){html<;head<;title<;";帮助我。恐怖!&34;>;>;,Body<;H1<;&34;the Horror!&34;>;,p<;&34;以前可能有人这么做过,但我明白为什么它没有流行起来。";>;,a<;";href=https://github.com/csb6/html-plus-plus&34;,";>;>;>;页;std::cout<;<;页。内容;返回0;}。

此库需要C++20。它可以与启用了-std=c++2a的GCC 9.2.0一起使用。它不能与Apple Clang11.0一起使用,但可以在其他编译器上使用。IFC++20是在给定的编译器上完全实现的,它应该能够编译。

我正在编写一些HTML,我意识到HTML标记的结构和语法与C++模板的结构/语法非常相似。两者都使您能够将标识符嵌套到树结构中。

由于可变模板是添加到C++中的,因此一个模板可以容纳参数包中的任意数量的其他类型,从而使父节点能够容纳任意数量的子节点。这是用C++类型正确表示HTML元素所必需的。

从C++20开始,现在可以使用字符串文字作为非类型模板参数(例如,h1<;";这是一个标题";>;),这使得C++模板能够更接近地模仿HTML标记的外观。

我想我应该看看那会有多可怕,而且,正如我所预料的,这是非常可笑的。

整个库基本上是连接字符串的一种奇妙方式,每个标记都定义为自己的模板结构(例如Template<;.>;struct H1{.};)。每个标记接受0个或多个类型/非类型模板参数。模板参数可以是HTML属性(例如";img<;src=';pic.png&39;";,";alt=';A Picture&39;&34;>;)或任意长度的其他元素类型列表,这些元素类型本身可以将其他类型保存为子节点(例如html<;head<;title<;.>;body<;.>;

类型安全可以通过只定义对标记有意义的模板参数来实现(例如,<;img>;是一个自动关闭的标记,因此接受子节点的模板参数包是没有意义的)。通过使用继承和static_assert以及幻影类型(例如,img继承自名为body_element_tag的空结构),可以确保标记作为给定节点的子节点具有语义意义。通过这种方式,可以对HTML进行一定程度的类型检查。

输出文本是通过预先排序遍历类型树,递归调用每个类型构造函数来组装的。每个元素将其开始标记(例如<;html>;)添加到字符串中,然后通过引用每个子元素递归传递该字符串。一旦所有的子节点都添加了它们的开始标记,每个节点就会添加它的结束标记(例如<;/html>;),并从其构造函数返回。该字符串存储在顶级节点(HTML)的成员中,并且可以像正常字符串一样在运行时打印和/或使用。字符串是在运行时汇编的;但是,文档的结构是在编译时定义的。

大概不会吧。但是,我认为类型检查方面可能很有用。我还没有添加所有的HTML标记,但是从理论上讲,这个库可以以这样一种方式进行扩展,即您可以使用某种强类型来编写HTML,这对于确保HTML标准的一致性可能很有用。