breb 0.5.0

the blog/reblog library and command-line tool
Documentation
//! **b**log/**reb**log is oriented around the [`Blog`]: a collection of [`Serve`]s with some
//! sitewide metadata. each [`Serve`] knows how to render the files in it, and the [`Blog`] maps
//! the actual incoming requests to them. the responses are in the form of [`Servable`]s, which
//! map cleanly to http responses.
//!
// //! you can create your list of [`Serve`]s however you want, but if you're familiar with the
// //! blog/reblog config file, you might want to lean on the familiar blog/reblog [`Config`], which
// //! is 1:1 with it -- it's how the CLI parses it normally. you can then [`expand`](Config::expand)
// //! it into the serve list.
// //!
// //! to serve a **preview** of your blog, a simple HTTP server is included in
// //! [`server`]. see the module docs for more info.
//!
//!   [`Serve`]: serve::Serve

#![forbid(missing_docs, clippy::empty_docs)]

mod config;
pub use config::{friendly, raw};
mod blog;
pub use blog::{Blog, Metadata, Post, Servable};
mod html;
mod mime;
pub use mime::Mime;
pub mod serve;

/// miscellaneous documentation, exposed via crate docs for offline friendliness
pub mod docs {
	macro_rules! docmod {
		($name:ident) => {
			#[doc = include_str!(concat!("docs/", stringify!($name), ".md"))]
			pub mod $name {}
		}
	}
	docmod!(tutorial);
}

mod cli;

#[cfg(feature = "server")]
mod live;
#[cfg(feature = "server")]
pub use live::LiveServer;

// we want to doctest the readme, but only when doctesting, so:
#[cfg(doctest)]
#[doc = include_str!("../README.md")]
#[doc(hidden)]
mod _readme_docs {}

/// all the imports you usually need. `use breb::quick::*` for best results.
///
/// **this module is highly subject to change!**
/// it'll be a breaking change when it happens,
/// but we're in 0.x territory, that ain't mean nothin'.
pub mod quick {
	use std::time::Instant;

	use crate::cli;

	pub use crate::{
		// useful types for building a `Blog`
		Blog,
		config::{friendly, raw},
		serve::{
			// builtin serve implementations
			AsIs,
			CssRule,
			Feed,
			FeedKind,
			HasCssRules,
			HasNav,
			// common logic for serves
			NavItem,
			Pages,
			Posts,
		},
	};

	/// a wrapper function to do the boilerplate of a basic, statically defined blog:
	/// - pull the in and out directories out of the args, including a little help message
	/// - read the blog from the input and write it to the output
	///
	/// usage is simple; build your [`raw::Config`] and pass it in.
	///
	/// the cli is, admittedly, a little more complex:
	/// - `-h`/`--help`/`help`: print some help text
	/// - `run <in> <out>`: run the blog generation once, writing it to `<out>`
	/// - `serve <in>`: serve the blog directly off disk
	pub fn run(cfg: raw::Config) {
		let start = Instant::now();

		let mut args = std::env::args();
		let cmd = args.next().unwrap_or("breb".into());

		let mode = args.next();
		match mode.as_deref() {
			None | Some("help" | "-h" | "--help") => cli::usage!(cmd),
			Some("run") => cli::run(&cmd, args, cfg, start),
			Some("serve") => cli::serve(&cmd, args, cfg, start),
			Some(cmd) => cli::usage!(cmd; "unknown command: {:?}", cmd),
		}
	}
}