diff options
author | Jan-Erik Rediger <janerik@fnordig.de> | 2020-04-25 15:56:25 +0200 |
---|---|---|
committer | Jan-Erik Rediger <janerik@fnordig.de> | 2020-04-25 17:27:07 +0200 |
commit | 19a991472068d899c25440ab0c1073b3dbe84cf8 (patch) | |
tree | c418ce1ad198d37b0707dbff1789b1296eaeb158 | |
parent | 28780f06e2d7ab780fc1ec7da5ac3c53a9109b1d (diff) |
Add a hook to install required files and configuration
Closes #5
-rw-r--r-- | Cargo.lock | 52 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/bin/assets/mermaid-init.js (renamed from assets/mermaid-init.js) | 0 | ||||
-rw-r--r-- | src/bin/assets/mermaid.css (renamed from assets/mermaid.css) | 0 | ||||
-rw-r--r-- | src/bin/assets/mermaid.min.js (renamed from assets/mermaid.min.js) | 0 | ||||
-rw-r--r-- | src/bin/mdbook-mermaid.rs | 154 |
6 files changed, 205 insertions, 2 deletions
@@ -31,6 +31,11 @@ dependencies = [ ] [[package]] +name = "ascii" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -165,6 +170,18 @@ dependencies = [ ] [[package]] +name = "combine" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ascii 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "darling" version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -567,6 +584,11 @@ version = "0.2.68" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "linked-hash-map" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "log" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -668,6 +690,7 @@ dependencies = [ "pulldown-cmark 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark-to-cmark 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", + "toml_edit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1466,6 +1489,16 @@ dependencies = [ ] [[package]] +name = "toml_edit" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "traitobject" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1546,6 +1579,14 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "unsafe-any" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1594,6 +1635,11 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "walkdir" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1686,6 +1732,7 @@ dependencies = [ "checksum aho-corasick 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" "checksum ammonia 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "89eac85170f4b3fb3dc5e442c1cfb036cb8eecf9dbbd431a161ffad15d90ea3b" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum ascii 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" "checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" @@ -1703,6 +1750,7 @@ dependencies = [ "checksum chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" "checksum darling 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9158d690bc62a3a57c3e45b85e4d50de2008b39345592c64efd79345c7e24be0" "checksum darling_core 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d2a368589465391e127e10c9e3a08efc8df66fd49b87dc8524c764bbe7f2ef82" "checksum darling_macro 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "244e8987bd4e174385240cde20a3657f607fb0797563c28255c353b5819a07b1" @@ -1750,6 +1798,7 @@ dependencies = [ "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" "checksum libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)" = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0" +"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" "checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" @@ -1851,6 +1900,7 @@ dependencies = [ "checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" "checksum toml-query 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "654d5afba116c445bb5fb6812e7c3177d90d143427af73f12956f33e18a1cedb" "checksum toml-query_derive 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "528baacc7fbc5e12b3fc32f483bea1b1cf531afa71cfaae54838d7095a6add9b" +"checksum toml_edit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87f53b1aca7d5fe2e17498a38cac0e1f5a33234d5b980fb36b9402bb93b98ae4" "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" "checksum typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "653be63c80a3296da5551e1bfd2cca35227e13cdd08c6668903ae2f4f77aa1f6" @@ -1864,6 +1914,7 @@ dependencies = [ "checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum unsafe-any 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" @@ -1871,6 +1922,7 @@ dependencies = [ "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" "checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" @@ -16,3 +16,4 @@ env_logger = "0.7.1" log = "0.4" clap = "2.33" serde_json = "1.0" +toml_edit = "0.1.5" diff --git a/assets/mermaid-init.js b/src/bin/assets/mermaid-init.js index 313a6e8..313a6e8 100644 --- a/assets/mermaid-init.js +++ b/src/bin/assets/mermaid-init.js diff --git a/assets/mermaid.css b/src/bin/assets/mermaid.css index 74de2c1..74de2c1 100644 --- a/assets/mermaid.css +++ b/src/bin/assets/mermaid.css diff --git a/assets/mermaid.min.js b/src/bin/assets/mermaid.min.js index 0a72f33..0a72f33 100644 --- a/assets/mermaid.min.js +++ b/src/bin/assets/mermaid.min.js diff --git a/src/bin/mdbook-mermaid.rs b/src/bin/mdbook-mermaid.rs index 166cc80..960ba52 100644 --- a/src/bin/mdbook-mermaid.rs +++ b/src/bin/mdbook-mermaid.rs @@ -2,9 +2,23 @@ use clap::{crate_version, App, Arg, ArgMatches, SubCommand}; use mdbook::errors::Error; use mdbook::preprocess::{CmdPreprocessor, Preprocessor}; use mdbook_mermaid::Mermaid; +use toml_edit::{Array, Document, Item, Table, Value}; -use std::io; -use std::process; +use std::{ + fs::{self, File}, + io::{self, Write}, + path::PathBuf, + process, +}; + +const MERMAID_JS: &[u8] = include_bytes!("assets/mermaid.min.js"); +const MERMAID_INIT_JS: &[u8] = include_bytes!("assets/mermaid-init.js"); +const MERMAID_CSS: &[u8] = include_bytes!("assets/mermaid.css"); +const MERMAID_FILES: &[(&str, &[u8])] = &[ + ("mermaid.min.js", MERMAID_JS), + ("mermaid-init.js", MERMAID_INIT_JS), + ("mermaid.css", MERMAID_CSS), +]; pub fn make_app() -> App<'static, 'static> { App::new("mdbook-mermaid") @@ -15,13 +29,26 @@ pub fn make_app() -> App<'static, 'static> { .arg(Arg::with_name("renderer").required(true)) .about("Check whether a renderer is supported by this preprocessor"), ) + .subcommand( + SubCommand::with_name("install") + .arg( + Arg::with_name("dir") + .default_value(".") + .help("Root directory for the book,\nshould contain the configuration file (`book.toml`)") + ) + .about("Install the required assset files and include it in the config"), + ) } fn main() { + env_logger::init(); + let matches = make_app().get_matches(); if let Some(sub_args) = matches.subcommand_matches("supports") { handle_supports(sub_args); + } else if let Some(sub_args) = matches.subcommand_matches("install") { + handle_install(sub_args); } else { if let Err(e) = handle_preprocessing() { eprintln!("{}", e); @@ -59,3 +86,126 @@ fn handle_supports(sub_args: &ArgMatches) -> ! { process::exit(1); } } + +fn handle_install(sub_args: &ArgMatches) -> ! { + let dir = sub_args.value_of("dir").expect("Required argument"); + let proj_dir = PathBuf::from(dir); + let config = proj_dir.join("book.toml"); + + if !config.exists() { + log::error!("Configuration file '{}' missing", config.display()); + process::exit(1); + } + + log::info!("Reading configuration file {}", config.display()); + let toml = fs::read_to_string(&config).expect("can't read configuration file"); + let mut doc = toml + .parse::<Document>() + .expect("configuration is not valid TOML"); + + log::info!("Adding additional files to configuration (if necessary)"); + if add_additional_files(&mut doc) { + log::info!("Saving changed configuration to {}", config.display()); + let toml = doc.to_string_in_original_order(); + let mut file = File::create(config).expect("can't open configuration file for writing."); + file.write_all(toml.as_bytes()).expect("can't write configuration"); + } + + log::info!("Writing additional files to project directory at {}", proj_dir.display()); + for (name, content) in MERMAID_FILES { + let filepath = proj_dir.join(name); + if filepath.exists() { + log::debug!("'{}' already exists (Path: {}). Skipping.", name, filepath.display()); + } else { + log::debug!("Writing content for '{}' into {}", name, filepath.display()); + let mut file = File::create(filepath).expect("can't open file for writing"); + file.write_all(content).expect("can't write content to file"); + } + + } + + log::info!("mermaid is active. You can start using it in your book."); + + process::exit(0); +} + +fn add_additional_files(doc: &mut Document) -> bool { + let mut changed = false; + + let file = "mermaid.css"; + let additional_css = additional(doc, "css"); + if has_file(&additional_css, file) { + log::debug!("'{}' already in 'additional-css'. Skipping", file) + } else { + log::debug!("Adding '{}' to 'additional-css'", file); + insert_additional(doc, "css", file); + changed = true; + } + + let file = "mermaid.min.js"; + let additional_js = additional(doc, "js"); + if has_file(&additional_js, file) { + log::debug!("'{}' already in 'additional-js'. Skipping", file) + } else { + log::debug!("Adding '{}' to 'additional-js'", file); + insert_additional(doc, "js", file); + changed = true; + } + + let file = "mermaid-init.js"; + let additional_js = additional(doc, "js"); + if has_file(&additional_js, file) { + log::debug!("'{}' already in 'additional-js'. Skipping", file) + } else { + log::debug!("Adding '{}' to 'additional-js'", file); + insert_additional(doc, "js", file); + changed = true; + } + + changed +} + +fn additional<'a>(doc: &'a mut Document, additional_type: &str) -> Option<&'a mut Array> { + let doc = doc.as_table_mut(); + + let item = doc.entry("output"); + let item = item.as_table_mut()?.entry("html"); + let item = item + .as_table_mut()? + .entry(&format!("additional-{}", additional_type)); + item.as_array_mut() +} + +fn has_file(elem: &Option<&mut Array>, file: &str) -> bool { + match elem { + Some(elem) => elem.iter().any(|elem| match elem.as_str() { + None => true, + Some(s) => s.ends_with(file), + }), + None => false, + } +} + +fn insert_additional(doc: &mut Document, additional_type: &str, file: &str) { + let doc = doc.as_table_mut(); + + let empty_table = Item::Table(Table::default()); + let empty_array = Item::Value(Value::Array(Array::default())); + let item = doc.entry("output").or_insert(empty_table.clone()); + let item = item + .as_table_mut() + .unwrap() + .entry("html") + .or_insert(empty_table.clone()); + let array = item + .as_table_mut() + .unwrap() + .entry(&format!("additional-{}", additional_type)) + .or_insert(empty_array); + array + .as_value_mut() + .unwrap() + .as_array_mut() + .unwrap() + .push(file); +} |