A static site generator written in Rust
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. extern crate clap;
  2. extern crate comrak;
  3. #[macro_use]
  4. extern crate lazy_static;
  5. extern crate regex;
  6. extern crate uuid;
  7. use std::env;
  8. use std::fs;
  9. use std::path;
  10. use clap::{App, Arg};
  11. use post::parse_post;
  12. use write::{write_post, write_post_listing};
  13. mod post;
  14. mod render;
  15. mod write;
  16. fn read_posts_dir(cwd: &path::PathBuf) -> fs::ReadDir {
  17. match fs::read_dir(cwd) {
  18. Ok(posts) => posts,
  19. Err(err) => panic!(err),
  20. }
  21. }
  22. fn build() {
  23. let cwd = env::current_dir().expect("Couldn't read current directory");
  24. match fs::create_dir(cwd.join("public")) {
  25. Ok(_) => {}
  26. Err(err) => match err.kind() {
  27. std::io::ErrorKind::AlreadyExists => {}
  28. _ => panic!(err),
  29. },
  30. }
  31. let layout_template = fs::read_to_string(&cwd.join("templates").join("layout.html"))
  32. .expect("Couldn't find layout template");
  33. let post_template = fs::read_to_string(cwd.join("templates").join("post.html"))
  34. .expect("Couldn't find post template");
  35. let post_listing_template = fs::read_to_string(cwd.join("templates").join("post_listing.html"))
  36. .expect("Couldn't find post listing item template");
  37. let post_item_template =
  38. fs::read_to_string(cwd.join("templates").join("post_listing_item.html"))
  39. .expect("Couldn't find post listing item template");
  40. let post_paths = read_posts_dir(&cwd.join("posts"));
  41. let posts = post_paths
  42. .into_iter()
  43. .map(|path| match path {
  44. Ok(p) => {
  45. let post = parse_post(p.path());
  46. write_post(&cwd, &layout_template, &post_template, &post);
  47. post
  48. }
  49. Err(err) => panic!(err),
  50. }).collect();
  51. write_post_listing(
  52. &cwd,
  53. &layout_template,
  54. &post_listing_template,
  55. &post_item_template,
  56. &posts,
  57. );
  58. }
  59. fn new(name: &str) {
  60. let cwd = env::current_dir().expect("Couldn't read current directory");
  61. let project_path = cwd.join(name);
  62. fs::create_dir(&project_path).expect(&format!("Couldn't create directory '{}'", &name));
  63. for dir in &["posts", "public", "templates"] {
  64. fs::create_dir(&project_path.join(&dir))
  65. .expect(&format!("Couldn't create {} directory", &dir));
  66. }
  67. for file in &["layout", "post_listing", "post", "post_listing_item"] {
  68. fs::write(
  69. &project_path
  70. .join("templates")
  71. .join(format!("{}.html", file)),
  72. "",
  73. ).expect(&format!("Couldn't write templates/{}.html", file));
  74. }
  75. }
  76. fn main() {
  77. let matches = App::new("tlon")
  78. .version("0.1.0")
  79. .author("Dylan Baker")
  80. .about("Highly opinionated static site generator")
  81. .arg(
  82. Arg::with_name("command")
  83. .required(true)
  84. .possible_values(&["build", "new"])
  85. .index(1),
  86. ).arg(
  87. Arg::with_name("name")
  88. .required_if("command", "new")
  89. .index(2),
  90. ).get_matches();
  91. let command = matches.value_of("command").unwrap();
  92. if command == "build" {
  93. build();
  94. } else if command == "new" {
  95. new(&matches.value_of("name").unwrap());
  96. }
  97. }