File: update-readme.rs

package info (click to toggle)
rust-comrak 0.41.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,016 kB
  • sloc: sh: 5; makefile: 2
file content (93 lines) | stat: -rw-r--r-- 3,424 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Update the "comrak --help" text in Comrak's own README.

use std::error::Error;
use std::fmt::Write;
use std::str;
use toml::Table;

use comrak::nodes::NodeValue;
use comrak::{format_commonmark, parse_document, Arena, Options};

const DEPENDENCIES: &str = "[dependencies]\ncomrak = ";
const HELP: &str = "$ comrak --help\n";
const HELP_START: &str =
    "A 100% CommonMark-compatible GitHub Flavored Markdown parser and formatter\n";

fn main() -> Result<(), Box<dyn Error>> {
    let arena = Arena::new();

    let readme = std::fs::read_to_string("README.md")?;
    let doc = parse_document(&arena, &readme, &Options::default());

    let cargo_toml = std::fs::read_to_string("Cargo.toml")?.parse::<Table>()?;
    let msrv = cargo_toml["package"].as_table().unwrap()["rust-version"]
        .as_str()
        .unwrap();

    let mut in_msrv = false;
    let mut next_block_is_help_body = false;

    for node in doc.descendants() {
        match node.data.borrow_mut().value {
            NodeValue::CodeBlock(ref mut ncb) => {
                // Look for the Cargo.toml example block.
                if ncb.info == "toml" && ncb.literal.starts_with(DEPENDENCIES) {
                    let mut content = DEPENDENCIES.to_string();
                    let mut version_parts = comrak::version().split('.').collect::<Vec<&str>>();
                    version_parts.pop();
                    write!(content, "\"{}\"", version_parts.join(".")).unwrap();
                    ncb.literal = content;
                    continue;
                }

                // Look for a console code block whose contents starts with the HELP string.
                // The *next* code block contains our help, minus the starting string.
                if ncb.info == "console" && ncb.literal.starts_with(HELP) {
                    next_block_is_help_body = true;
                    continue;
                }

                if next_block_is_help_body {
                    next_block_is_help_body = false;
                    assert!(ncb.info.is_empty() && ncb.literal.starts_with(HELP_START));
                    let mut content = String::new();
                    let mut cmd = std::process::Command::new("cargo");
                    content.push_str(
                        str::from_utf8(
                            &cmd.args(["run", "--all-features", "--", "--help"])
                                .output()
                                .unwrap()
                                .stdout,
                        )
                        .unwrap(),
                    );
                    ncb.literal = content;
                    continue;
                }
            }
            NodeValue::HtmlInline(ref mut s) => {
                if s == "<span class=\"msrv\">" {
                    in_msrv = true;
                } else if in_msrv && s == "</span>" {
                    in_msrv = false;
                }
            }
            NodeValue::Text(ref mut t) => {
                if in_msrv {
                    std::mem::swap(t, &mut msrv.to_string());
                }
            }
            _ => {}
        }
    }

    let mut options = Options::default();
    options.render.prefer_fenced = true;
    options.render.experimental_minimize_commonmark = true;

    let mut out = vec![];
    format_commonmark(doc, &options, &mut out)?;
    std::fs::write("README.md", &out)?;

    Ok(())
}