#![allow(non_snake_case)] mod article; mod config; mod error; mod site; mod template; use article::{Article, ArticleContext}; use std::path::PathBuf; use template::TemplateEngine; use walkdir::WalkDir; use emacs::{defun, Env, IntoLisp, Result, Vector}; emacs::plugin_is_GPL_compatible!(); #[emacs::module(name = "liborg_static", defun_prefix = "org-static")] fn init(e: &Env) -> Result<()> { e.message("orgstatic loaded")?; Ok(()) } fn find_articles(env: &Env, config: &config::Config) -> Result> { let mut articles: Vec
= vec![]; for entry in WalkDir::new(&config.get_articles_path()) .into_iter() .filter_map(|e| e.ok()) .filter(|e| e.path().extension().map(|ex| ex == "org").unwrap_or(false)) { let file_path = entry.path().canonicalize()?; let article_data = Vector::from_value_unchecked( env.call( "org-static-file-info", [file_path .to_str() .unwrap_or_default() .to_string() .into_lisp(env)?], )?, 3, ); let title = article_data.get::(0)?; let author = article_data.get::(1)?; let date = article_data.get::(2)?; let slug = { let s = article_data.get::(3)?; if s.is_empty() { file_path .file_name() .unwrap_or_default() .to_str() .unwrap_or_default() .to_string() } else { s } }; let tags = article_data .get::(4)? .split(':') .filter(|i| !i.is_empty()) .map(|i| i.to_string()) .collect(); articles.push(Article { title, slug, date, author, file_path, tags, }); } Ok(articles) } fn publish_articles(env: &Env, config: &config::Config, articles: &[Article]) -> Result<()> { let eng = TemplateEngine::new(config.get_partials_path())?; for article in articles { std::fs::create_dir_all(article.get_build_path(config))?; let content = env .call( "org-static-file-contents", [article .file_path .to_str() .unwrap_or_default() .to_string() .into_lisp(env)?], )? .into_rust::()?; let ctx = ArticleContext::new(article.clone(), content); eng.render_file( config.get_theme_path().join("articles.html"), article.get_build_path(config).join("index.html"), &ctx, )?; } Ok(()) } #[defun] pub fn publish(env: &Env, starting_path: String) -> Result<()> { let cfg = config::Config::find(PathBuf::from(starting_path))?; println!("{:?}", cfg); let articles = find_articles(env, &cfg)?; env.message(format!("{} articles found", articles.len()))?; publish_articles(env, &cfg, &articles)?; Ok(()) }