#html-parser #syn #jsx #html #html-macro #rsx #macro

syn-rsx

基于syn的JSX-like TokenStreams解析器

23次发布

0.9.0 2022年11月10日
0.9.0-alpha.12022年10月21日
0.8.1 2022年6月26日
0.8.0 2021年2月17日
0.6.1 2020年6月6日

471过程宏

Download history 3288/week @ 2024-04-22 1987/week @ 2024-04-29 2326/week @ 2024-05-06 2372/week @ 2024-05-13 2539/week @ 2024-05-20 2246/week @ 2024-05-27 2881/week @ 2024-06-03 2559/week @ 2024-06-10 2146/week @ 2024-06-17 1707/week @ 2024-06-24 615/week @ 2024-07-01 382/week @ 2024-07-08 811/week @ 2024-07-15 592/week @ 2024-07-22 590/week @ 2024-07-29 582/week @ 2024-08-05

2,630 每月下载量
50 个crate中(直接使用13个) 中使用

MIT 许可证

44KB
809

syn-rsx

crates.io page docs.rs page codecov build license: MIT

syn 驱动的JSX-like TokenStream解析器,称为RSX。解析结果是一个嵌套的 Node 结构,类似于浏览器DOM,节点名称和值是syn表达式,以支持构建过程宏。

use std::convert::TryFrom;

use eyre::bail;
use quote::quote;
use syn_rsx::{parse2, Node, NodeAttribute, NodeElement, NodeText};

// Create HTML `TokenStream`.
let tokens = quote! { <hello world>"hi"</hello> };

// Parse the tokens into a tree of `Node`s.
let nodes = parse2(tokens)?;

// Extract some specific nodes from the tree.
let Node::Element(element) = &nodes[0] else { bail!("element") };
let Node::Attribute(attribute) = &element.attributes[0] else { bail!("attribute") };
let Node::Text(text) = &element.children[0] else { bail!("text") };

// Work with the nodes.
assert_eq!(element.name.to_string(), "hello");
assert_eq!(attribute.key.to_string(), "world");
assert_eq!(String::try_from(&text.value)?, "hi");

您还可以查看html-to-string-macro示例

功能

  • 无偏见

    每个标签或属性名称都是有效的

    <hello world />
    
  • 文本节点

    计划支持未引用的文本

    <div>"String literal"</div>
    
  • 节点名称由短横线、冒号或双冒号分隔

    <tag-name attribute-key="value" />
    <tag:name attribute:key="value" />
    <tag::name attribute::key="value" />
    
  • 支持保留关键字作为节点名称

    <input type="submit" />
    
  • 文档类型、注释和片段

    <!DOCTYPE html>
    <!-- "comment" -->
    <></>
    
  • 花括号块被解析为任意Rust代码

    <{ let block = "in node name position"; } />
    <div>{ let block = "in node position"; }</div>
    <div { let block = "in attribute position"; } />
    <div key={ let block = "in attribute value position"; } />
    
  • 属性值可以是任何有效的syn表达式,无需花括号

    <div key=some::value() />
    
  • 内置有用的错误报告

    error: open tag has no corresponding close tag and is not self-closing
    --> examples/html-to-string-macro/tests/lib.rs:5:24
      |
    5 |     html_to_string! { <div> };
      |                        ^^^
    
  • 定制化

    有一个 ParserConfig,可以定制解析行为,因此如果您对解析有稍微不同的要求,而且它还没有定制化,请随时打开一个问题或拉取请求以扩展配置。

    关于定制化的一个亮点是 transform_block 配置,它接受一个闭包,该闭包接收原始块内容作为 ParseStream,并允许您可选地将它转换为 TokenStream。这使得在块中有自定义语法成为可能。更多详情请见 #9

依赖项

~250–700KB
~16K SLoC