From d23bbe66809f97e31eb5d49d468e2ddcd2e25d9c Mon Sep 17 00:00:00 2001
From: Chris Wong <lambda.fairy@gmail.com>
Date: Sat, 23 Mar 2019 22:57:59 +1300
Subject: [PATCH] Add Makefile

---
 docs/Cargo.lock   |  7 ------
 docs/Cargo.toml   |  1 -
 docs/Makefile     | 18 ++++++++++++++
 docs/src/main.rs  | 62 +++++++++++++++++++++--------------------------
 docs/src/views.rs | 13 +++++-----
 docs/watch.sh     |  4 ++-
 6 files changed, 55 insertions(+), 50 deletions(-)
 create mode 100644 docs/Makefile

diff --git a/docs/Cargo.lock b/docs/Cargo.lock
index 165d626..0d9c35b 100644
--- a/docs/Cargo.lock
+++ b/docs/Cargo.lock
@@ -157,7 +157,6 @@ name = "docs"
 version = "0.0.0"
 dependencies = [
  "comrak 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "maud 0.20.0",
  "syntect 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -204,11 +203,6 @@ dependencies = [
  "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "indexmap"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "itoa"
 version = "0.4.3"
@@ -688,7 +682,6 @@ dependencies = [
 "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
 "checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
 "checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114"
-"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
 "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
 "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
 "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
diff --git a/docs/Cargo.toml b/docs/Cargo.toml
index 4771728..34b185b 100644
--- a/docs/Cargo.toml
+++ b/docs/Cargo.toml
@@ -12,6 +12,5 @@ edition = "2018"
 
 [dependencies]
 comrak = "*"
-indexmap = "*"
 maud = { path = "../maud" }
 syntect = "*"
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..2cf4cdc
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,18 @@
+MARKDOWN_FILES := $(wildcard content/*.md)
+HTML_FILES := $(patsubst content/%.md,site/%.html,$(MARKDOWN_FILES))
+
+.PHONY: all
+all: $(HTML_FILES) site/styles.css
+
+target/debug/docs: $(wildcard src/*)
+	cargo build
+
+site/%.html: content/%.md target/debug/docs
+	target/debug/docs build-page $< $@
+
+site/styles.css: styles.css
+	cp $^ $@
+
+.PHONY: clean
+clean:
+	rm -fr site
diff --git a/docs/src/main.rs b/docs/src/main.rs
index 7137815..c9cb9c5 100644
--- a/docs/src/main.rs
+++ b/docs/src/main.rs
@@ -3,8 +3,8 @@
 
 use comrak::{self, Arena, ComrakOptions};
 use comrak::nodes::{AstNode, NodeCodeBlock, NodeHeading, NodeHtmlBlock, NodeLink, NodeValue};
-use indexmap::IndexMap;
 use std::error::Error;
+use std::env;
 use std::fs;
 use std::io;
 use std::mem;
@@ -16,20 +16,30 @@ use syntect::html::highlighted_html_for_string;
 
 mod views;
 
-const BOOK_FILES: &[&str] = &[
-    "index",
-    "getting-started",
-    "basic-syntax",
-    "dynamic-content",
-    "partials",
-    "control-structures",
-    "traits",
-    "web-frameworks",
-    "faq",
-];
-
 fn main() -> Result<(), Box<dyn Error>> {
-    fs::create_dir_all("site")?;
+    let args = env::args().collect::<Vec<_>>();
+    if args.len() == 4 && &args[1] == "build-page" {
+        build_page(&args[2], &args[3])
+    } else {
+        Err("invalid arguments".into())
+    }
+}
+
+fn build_page(input_path: &str, output_path: &str) -> Result<(), Box<dyn Error>> {
+    // TODO make this list dynamically generated
+    const NAV: &[(&str, Option<&str>)] = &[
+        ("index", None),
+        ("getting-started", Some("Getting started")),
+        ("basic-syntax", Some("Basic syntax")),
+        ("dynamic-content", Some("Dynamic content")),
+        ("partials", Some("Partials")),
+        ("control-structures", Some("Control structures")),
+        ("traits", Some("Traits")),
+        ("web-frameworks", Some("Web frameworks")),
+        ("faq", Some("FAQ")),
+    ];
+
+    fs::create_dir_all(Path::new(output_path).parent().unwrap())?;
 
     let arena = Arena::new();
     let options = ComrakOptions {
@@ -38,26 +48,10 @@ fn main() -> Result<(), Box<dyn Error>> {
         ..ComrakOptions::default()
     };
 
-    let mut pages = IndexMap::<&str, _>::new();
+    let page = load_page(&arena, &options, input_path)?;
+    let markup = views::main(&options, input_path, page, &NAV);
 
-    for path in BOOK_FILES {
-        let mut input_path = Path::new("content").join(path);
-        input_path.set_extension("md");
-
-        let page = load_page(&arena, &options, &input_path)?;
-
-        pages.insert(path, page);
-    }
-
-    for path in pages.keys() {
-        let mut output_path = Path::new("site").join(path);
-        output_path.set_extension("html");
-        println!("{}", output_path.display());
-        let markup = views::main(&options, path, &pages);
-        fs::write(output_path, markup.into_string())?;
-    }
-
-    fs::copy("styles.css", "site/styles.css")?;
+    fs::write(output_path, markup.into_string())?;
 
     Ok(())
 }
@@ -70,7 +64,7 @@ struct Page<'a> {
 fn load_page<'a>(
     arena: &'a Arena<AstNode<'a>>,
     options: &ComrakOptions,
-    path: &Path,
+    path: impl AsRef<Path>,
 ) -> io::Result<Page<'a>> {
     let buffer = fs::read_to_string(path)?;
     let content = comrak::parse_document(arena, &buffer, options);
diff --git a/docs/src/views.rs b/docs/src/views.rs
index 8fed8f0..2c5a378 100644
--- a/docs/src/views.rs
+++ b/docs/src/views.rs
@@ -1,7 +1,6 @@
 use comrak::{self, ComrakOptions};
 use comrak::nodes::AstNode;
 use crate::Page;
-use indexmap::IndexMap;
 use maud::{DOCTYPE, Markup, Render, html};
 use std::io;
 use std::str;
@@ -41,10 +40,10 @@ impl<'a> Render for ComrakText<'a> {
 
 crate fn main<'a>(
     options: &'a ComrakOptions,
-    path: &str,
-    pages: &IndexMap<&str, Page<'a>>,
+    _path: &str,  // TODO add nav indicator
+    page: Page<'a>,
+    nav: &[(&str, Option<&str>)],
 ) -> Markup {
-    let page = &pages[path];
     html! {
         (DOCTYPE)
         meta charset="utf-8";
@@ -69,11 +68,11 @@ crate fn main<'a>(
 
         nav {
             ul {
-                @for (other_path, other_page) in pages {
-                    @if let Some(title) = other_page.title {
+                @for (other_path, other_title) in nav {
+                    @if let Some(title) = other_title {
                         li {
                             a href={ (other_path) ".html" } {
-                                (Comrak(title, options))
+                                (title)
                             }
                         }
                     }
diff --git a/docs/watch.sh b/docs/watch.sh
index b88b334..b268871 100755
--- a/docs/watch.sh
+++ b/docs/watch.sh
@@ -6,7 +6,9 @@ python3 -m http.server -d site &
 server_pid=$!
 trap 'kill $server_pid' EXIT
 
+nproc=$(nproc || echo 4)
+
 while true
 do
-    find . -name '*.rs' -o -name '*.md' -o -name '*.css' | entr -d cargo run
+    find . -name '*.rs' -o -name '*.md' -o -name '*.css' | entr -d make -j$nproc
 done