lore_for_collections | 在最简实现的基础上构建 [*.html] 格式导出模块

19 阅读1分钟

这是一个实例导出。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Test</title>
  <link rel="stylesheet" href="https://fleetinglore.github.io/collection/collection.css">
</head>
<body>
<p style="margin-left: 0px"><strong>+ root</strong></p><p style="margin-left: 20px"><strong>+ test domain</strong></p><p style="margin-left: 40px"><a href="https://www.example.com" target="_blank">test link</a></p><p style="margin-left: 20px">amid line
</p><p style="margin-left: 20px"><strong>+ collections</strong></p><p style="margin-left: 40px"><a href="https://www.bilibili.com" target="_blank">bilibili</a></p><p style="margin-left: 40px"><a href="https://www.zhihu.com" target="_blank">zhihu</a></p><p style="margin-left: 20px">element
</p>
</body>
</html>

效果如此。

image.png

新模块的代码分为两部分,第一个函数生成并保存文件目标,第二个函数生成每一行。

// src/output.rs
use std::fs;
use std::path::Path;
use crate::line::{Content, Line};

pub fn output_html(title: &str, lines: Vec<Line>, path: &Path) {
    let mut html = String::new();

    html.push_str(
        format!(
            r#"<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>{}</title>
  <link rel="stylesheet" href="https://fleetinglore.github.io/collection/collection.css">
</head>
<body>
"#,
            title,
    )
            .as_str()
    );

    for line in lines {
        html.push_str(line_to_html(&line).as_str());
    }

    html.push_str(
        r#"
</body>
</html>"#
    );

    fs::write(path, html).unwrap();
}

fn line_to_html(line: &Line) -> String {
    let margin_left = line.indent * 20;

    match &line.content {
        Content::Atom(atom) => {
            format!(
                r#"<p style="margin-left: {}px">{}</p>"#,
                margin_left,
                atom
            )
        },
        Content::Link(key, value) => {
            format!(
                r#"<p style="margin-left: {}px"><a href="{}" target="_blank">{}</a></p>"#,
                margin_left,
                value,
                key
            )
        },
        Content::Domain(domain) => {
            format!(
                r#"<p style="margin-left: {}px"><strong>+ {}</strong></p>"#,
                margin_left,
                domain
            )
        }
    }
}

此时入口文件如此,改动不大。

use std::path::Path;
use crate::input_lore::input_lore_file;
use crate::input_lore::parse;
use crate::output::output_html;

mod line;
mod parser;
mod input_lore;
mod output;

fn main() {
    let content: String = input_lore_file(Path::new("..\test\basic.lore"));
    let target = parse(content);
    
    for line in &target {
        println!("{}", line);
    }
    
    output_html("Test", target, Path::new("..\test\test.html"));
    
}