diff --git a/.gitignore b/.gitignore
index 9f97022..8647666 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
-target/
\ No newline at end of file
+target/
+build/
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
index 938d9ae..946f93a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -180,9 +180,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
-version = "0.2.138"
+version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
+checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]]
name = "log"
@@ -208,13 +208,15 @@ dependencies = [
"lazy_static",
"serde",
"serde_json",
+ "toml",
+ "walkdir",
]
[[package]]
name = "pest"
-version = "2.5.1"
+version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc8bed3549e0f9b0a2a78bf7c0018237a2cdf085eecbbc048e52612438e4e9d0"
+checksum = "0f6e86fb9e7026527a0d46bc308b841d73170ef8f443e1807f6ef88526a816d4"
dependencies = [
"thiserror",
"ucd-trie",
@@ -222,9 +224,9 @@ dependencies = [
[[package]]
name = "pest_derive"
-version = "2.5.1"
+version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdc078600d06ff90d4ed238f0119d84ab5d43dbaad278b0e33a8820293b32344"
+checksum = "96504449aa860c8dcde14f9fba5c58dc6658688ca1fe363589d6327b8662c603"
dependencies = [
"pest",
"pest_generator",
@@ -232,9 +234,9 @@ dependencies = [
[[package]]
name = "pest_generator"
-version = "2.5.1"
+version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28a1af60b1c4148bb269006a750cff8e2ea36aff34d2d96cf7be0b14d1bed23c"
+checksum = "798e0220d1111ae63d66cb66a5dcb3fc2d986d520b98e49e1852bfdb11d7c5e7"
dependencies = [
"pest",
"pest_meta",
@@ -245,9 +247,9 @@ dependencies = [
[[package]]
name = "pest_meta"
-version = "2.5.1"
+version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fec8605d59fc2ae0c6c1aefc0c7c7a9769732017c0ce07f7a9cfffa7b4404f20"
+checksum = "984298b75898e30a843e278a9f2452c31e349a073a0ce6fd950a12a74464e065"
dependencies = [
"once_cell",
"pest",
@@ -287,6 +289,15 @@ version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
[[package]]
name = "semver"
version = "0.9.0"
@@ -381,6 +392,15 @@ dependencies = [
"syn",
]
+[[package]]
+name = "toml"
+version = "0.5.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f"
+dependencies = [
+ "serde",
+]
+
[[package]]
name = "typenum"
version = "1.16.0"
@@ -404,3 +424,45 @@ name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "walkdir"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
+dependencies = [
+ "same-file",
+ "winapi",
+ "winapi-util",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/Cargo.toml b/Cargo.toml
index d296d53..809ecb5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,22 +3,18 @@ name = "org-static"
version = "0.1.0"
edition = "2021"
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-
[lib]
crate-type = ["cdylib"]
[dependencies]
-
lazy_static = "1.4"
emacs = "0.18.0"
+
serde = { version = "1.0.151", features = ["derive"] }
handlebars = "4.3.6"
serde_json = "1.0.91"
-
-[dev-dependencies]
-#emacs-rs-module = { version = "0.13.0" }
+walkdir = "2.3.2"
+toml = "0.5.10"
diff --git a/examples/basic.rs b/examples/basic.rs
new file mode 100644
index 0000000..46418cd
--- /dev/null
+++ b/examples/basic.rs
@@ -0,0 +1,8 @@
+use org_static::publish;
+
+fn main() {
+ match publish("examples/basic".into()) {
+ Ok(()) => println!("Complete"),
+ Err(e) => println!("Error: {}", e),
+ }
+}
diff --git a/examples/basic/articles/a-test-pos.org b/examples/basic/articles/a-test-pos.org
new file mode 100644
index 0000000..527a4c7
--- /dev/null
+++ b/examples/basic/articles/a-test-pos.org
@@ -0,0 +1,13 @@
+#+title: A test Post
+#+filetags: :test:
+
+
+* Article Heading
+
+Heading
+
+
+#+begin_src emacs-lisp
+(org-static-publish-current-project)
+(org-static-publish "/media/joe/extradrive1/Projects/fivesigma/org-static/examples/basic/articles/")
+#+end_src
diff --git a/examples/basic/orgstatic.toml b/examples/basic/orgstatic.toml
new file mode 100644
index 0000000..dd6587f
--- /dev/null
+++ b/examples/basic/orgstatic.toml
@@ -0,0 +1,2 @@
+[site]
+title = "Basic Example Site"
\ No newline at end of file
diff --git a/examples/basic/theme/articles.html b/examples/basic/theme/articles.html
new file mode 100644
index 0000000..016fcc9
--- /dev/null
+++ b/examples/basic/theme/articles.html
@@ -0,0 +1,5 @@
+
+title: {{ article.title }}
+
+ {{{content}}}
+
diff --git a/readme.org b/readme.org
new file mode 100644
index 0000000..e20682c
--- /dev/null
+++ b/readme.org
@@ -0,0 +1,10 @@
+
+
+#+begin_src emacs-lisp
+(progn
+ (add-to-list 'load-path "/media/joe/extradrive1/Projects/fivesigma/org-static/target/debug")
+ (require 'org-static))
+#+end_src
+
+
+[[file:examples/basic/articles/a-test-pos.org]]
diff --git a/src/article.rs b/src/article.rs
index 83d438c..9c1dab9 100644
--- a/src/article.rs
+++ b/src/article.rs
@@ -1,16 +1,26 @@
-use crate::{error::Result, site::Site, template::Template};
use serde::Serialize;
-use serde_json::json;
-use std::collections::{HashMap, HashSet};
+use std::{collections::HashSet, path::PathBuf};
-#[derive(Serialize, Default)]
+use crate::config::Config;
+
+#[derive(Serialize, Default, Clone)]
pub struct Article {
- title: String,
- filename: String,
- date: String,
- author: String,
- properties: HashMap,
- tags: HashSet,
+ pub title: String,
+ pub date: String,
+ pub author: String,
+ pub slug: String,
+ pub file_path: PathBuf,
+ pub tags: HashSet,
+}
+
+impl Article {
+ pub fn get_build_path(&self, config: &Config) -> PathBuf {
+ config
+ .get_build_path()
+ .join("articles")
+ .join(&self.slug)
+ .join("index.html")
+ }
}
#[derive(Serialize, Default)]
@@ -20,91 +30,7 @@ pub struct ArticleContext {
}
impl ArticleContext {
- pub fn load(article: Article) -> Result {
- Ok(Self {
- article,
- content: String::new(),
- })
- }
-
- #[cfg(test)]
- pub fn load_string(article: Article, content: &str) -> Result {
- Ok(Self {
- article,
- content: content.to_string(),
- })
- }
-}
-
-pub fn generate_article(
- site: &Site,
- article: &ArticleContext,
- template: &Template,
-) -> Result {
- let ctx = json!({
- "site": site,
- "data": article,
- });
- let res = template.generate(&ctx)?;
- Ok(res)
-}
-
-pub fn generate_article_index(
- site: &Site,
- articles: Vec,
- template: &Template,
-) -> Result {
- let ctx = json!({
- "site": site,
- "data": articles,
- });
-
- let res = template.generate(&ctx)?;
- Ok(res)
-}
-
-#[cfg(test)]
-mod tests {
- use crate::{site::tests::fixture_site, template::Template};
-
- use super::*;
-
- pub fn fixture_article() -> Article {
- Article {
- title: "Test Article #1".to_string(),
- filename: "test.org".to_string(),
- date: "".to_string(),
- author: "Bob Bobberson".to_string(),
- properties: HashMap::new(),
- tags: vec!["article", "new", "cool"]
- .into_iter()
- .map(String::from)
- .collect(),
- }
- }
-
- #[test]
- fn test_generate_article() {
- let article_ctx =
- ArticleContext::load_string(fixture_article(), "ten animals i slam in a net")
- .expect("couldnt build article");
- let template =
- Template::new("content: {{{data.content}}}, site: {{site.title}}".to_string());
- let site = fixture_site();
- let res =
- generate_article(&site, &article_ctx, &template).expect("couldnt gnenerate template");
-
- assert_eq!(res, "content: ten animals i slam in a net, site: Test Site");
- }
-
- #[test]
- fn test_generate_article_index() {
- let articles = vec![fixture_article(), fixture_article()];
- let site = fixture_site();
- let template = Template::new("list: {{#each data}}{{title}} {{/each}}".to_string());
- let res =
- generate_article_index(&site, articles, &template).expect("couldnt generate template");
-
- assert_eq!(res, "list: Test Article #1 Test Article #1 ");
+ pub fn new(article: Article, content: String) -> Self {
+ Self { article, content }
}
}
diff --git a/src/config.rs b/src/config.rs
new file mode 100644
index 0000000..48e3a3e
--- /dev/null
+++ b/src/config.rs
@@ -0,0 +1,112 @@
+use std::path::PathBuf;
+
+use serde::{Deserialize, Serialize};
+
+use crate::{error::Error, site::Site};
+
+#[derive(Serialize, Deserialize, Debug)]
+#[serde(default)]
+pub struct Config {
+ pub project_root: PathBuf,
+ pub build_path: PathBuf,
+ pub articles_path: PathBuf,
+ pub theme_path: PathBuf,
+ pub static_path: PathBuf,
+ pub partials_path: PathBuf,
+ pub site: Site,
+}
+
+impl Default for Config {
+ fn default() -> Self {
+ Config {
+ site: Site::default(),
+ project_root: ".".into(),
+ build_path: "build".into(),
+ articles_path: "articles".into(),
+ theme_path: "theme".into(),
+ static_path: "static".into(),
+ partials_path: "partials".into(),
+ }
+ }
+}
+
+impl Config {
+ pub fn find(path: PathBuf) -> crate::error::Result {
+ if let Some(p) = find_config(path) {
+ let content = std::fs::read_to_string(&p)?;
+ let mut cfg: Config = toml::from_str(&content)?;
+ cfg.project_root = p
+ .canonicalize()?
+ .parent()
+ .ok_or_else(|| Error::new("Couldnt find project root"))?
+ .to_path_buf();
+ Ok(cfg)
+ } else {
+ Err(Error::new("Config file not found"))
+ }
+ }
+
+ pub fn get_build_path(&self) -> PathBuf {
+ if self.build_path.is_relative() {
+ PathBuf::from(&self.project_root).join(&self.build_path)
+ } else {
+ self.build_path.clone()
+ }
+ }
+
+ pub fn get_articles_path(&self) -> PathBuf {
+ if self.articles_path.is_relative() {
+ PathBuf::from(&self.project_root).join(&self.articles_path)
+ } else {
+ self.articles_path.clone()
+ }
+ }
+
+ pub fn get_theme_path(&self) -> PathBuf {
+ if self.theme_path.is_relative() {
+ PathBuf::from(&self.project_root).join(&self.theme_path)
+ } else {
+ self.theme_path.clone()
+ }
+ }
+
+ pub fn get_static_path(&self) -> PathBuf {
+ if self.static_path.is_relative() {
+ PathBuf::from(&self.project_root).join(&self.static_path)
+ } else {
+ self.static_path.clone()
+ }
+ }
+
+ pub fn get_partials_path(&self) -> PathBuf {
+ if self.partials_path.is_relative() {
+ PathBuf::from(&self.project_root).join(&self.partials_path)
+ } else {
+ self.partials_path.clone()
+ }
+ }
+}
+
+fn find_config(mut path: PathBuf) -> Option {
+ let config_path = path.join("orgstatic.toml");
+ if config_path.is_file() {
+ Some(config_path)
+ } else if path.pop() {
+ find_config(path)
+ } else {
+ None
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_find_config() {
+ let path = PathBuf::from("examples/basic/articles/")
+ .canonicalize()
+ .unwrap();
+ Config::find(path).unwrap();
+ }
+}
diff --git a/src/elisp/org-static.el b/src/elisp/org-static.el
new file mode 100644
index 0000000..97c1399
--- /dev/null
+++ b/src/elisp/org-static.el
@@ -0,0 +1,20 @@
+(require 'liborg_static)
+
+(defun org-static-file-info (filename)
+ (vector (nth 0 (cdr (nth 0 (org-collect-keywords '("title" "")))))
+ (nth 0 (cdr (nth 0 (org-collect-keywords '("author" "")))))
+ (nth 0 (cdr (nth 0 (org-collect-keywords '("date" "")))))
+ (nth 0 (cdr (nth 0 (org-collect-keywords '("slug" "")))))
+ (nth 0 (cdr (nth 0 (org-collect-keywords '("filetags" "")))))))
+
+
+(defun org-static-file-contents (filename)
+ (org-export-string-as (f-read-text filename 'utf-8) 'html t))
+
+
+(defun org-static-publish-current-project ()
+ (org-static-publish (file-name-directory (buffer-file-name))))
+
+(provide 'org-static)
+
+
diff --git a/src/error.rs b/src/error.rs
index 8359cfa..7347158 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -11,8 +11,6 @@ impl std::fmt::Display for Error {
}
}
-impl std::error::Error for Error {}
-
impl Error {
pub fn new(message: &str) -> Self {
Error {
@@ -21,18 +19,16 @@ impl Error {
}
}
-impl From for Error {
- fn from(source: handlebars::TemplateError) -> Self {
+impl From for Error {
+ fn from(source: T) -> Self {
Self {
message: source.to_string(),
}
}
}
-impl From for Error {
- fn from(source: handlebars::RenderError) -> Self {
- Self {
- message: source.to_string(),
- }
+impl From for emacs::Error {
+ fn from(source: Error) -> Self {
+ emacs::Error::msg(source)
}
}
diff --git a/src/lib.rs b/src/lib.rs
index 922f924..f5a1a4d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,25 +1,117 @@
#![allow(non_snake_case)]
mod article;
+mod config;
mod error;
mod site;
mod template;
-use emacs::{defun, Env, Result, Value};
+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 = "org-static")]
-fn init(_: &Env) -> Result<()> {
+#[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]
-fn say_hello(env: &Env, _name: String) -> Result> {
- let fname = env
- .call("buffer-file-name", [])
- .unwrap()
- .into_rust::()
- .unwrap();
- env.message(fname)
+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(())
}
diff --git a/src/site.rs b/src/site.rs
index 24198c0..ac4bf03 100644
--- a/src/site.rs
+++ b/src/site.rs
@@ -1,12 +1,13 @@
use serde::{Deserialize, Serialize};
-#[derive(Serialize, Deserialize, Default)]
+#[derive(Serialize, Deserialize, Default, Debug)]
pub struct Site {
title: String,
}
#[cfg(test)]
pub mod tests {
+
use super::*;
#[allow(dead_code)]
@@ -15,7 +16,4 @@ pub mod tests {
title: "Test Site".to_string(),
}
}
-
- #[test]
- fn test_name() {}
}
diff --git a/src/template.rs b/src/template.rs
index ce2a8e8..2ce578f 100644
--- a/src/template.rs
+++ b/src/template.rs
@@ -1,22 +1,61 @@
+use std::{collections::HashMap, path::PathBuf};
+
use handlebars::Handlebars;
use serde::Serialize;
-use crate::{error::Result, site::Site};
+use crate::error::Result;
-pub struct Template {
- pub template_string: String,
+#[derive(Debug, Default)]
+pub struct TemplateEngine {
+ partials: HashMap,
}
-impl Template {
- pub fn new(template_string: String) -> Self {
- Self { template_string }
+impl TemplateEngine {
+ pub fn new>(partial_path: T) -> Result {
+ let pp: PathBuf = partial_path.into();
+
+ let partials = if pp.exists() {
+ pp.read_dir()?
+ .filter_map(|i| i.ok())
+ .fold(HashMap::new(), |mut acc, i| {
+ if i.path().is_file() {
+ if let Some(file_name) = i.path().with_extension("").file_name() {
+ acc.insert(
+ file_name.to_str().unwrap_or_default().to_string(),
+ std::fs::read_to_string(i.path()).unwrap_or_default(),
+ );
+ }
+ }
+ acc
+ })
+ } else {
+ HashMap::new()
+ };
+
+ Ok(Self { partials })
}
- pub fn generate(&self, data: &T) -> Result {
- let reg = Handlebars::new();
+ pub fn render_string(&self, template_string: &str, data: D) -> Result {
+ let mut reg = Handlebars::new();
+ for (k, v) in self.partials.iter() {
+ reg.register_partial(k, v)?;
+ }
- let output = reg.render_template(&self.template_string, data)?;
- Ok(output)
+ let res = reg.render_template(template_string, &data)?;
+
+ Ok(res)
+ }
+
+ pub fn render_file(
+ &self,
+ template_file: PathBuf,
+ output_path: PathBuf,
+ data: D,
+ ) -> Result<()> {
+ let template_content = std::fs::read_to_string(template_file)?;
+ let res = self.render_string(&template_content, data)?;
+ std::fs::write(output_path, res)?;
+ Ok(())
}
}
@@ -45,12 +84,11 @@ mod tests {
#[test]
fn test_template() {
- let tmpl = Template::new(
- "Hello, my name is {{ name }}, I am {{ age }} years old and i like {{#each tags}}{{this}} {{/each}}"
- .to_string(),
- );
- let res = tmpl
- .generate(&TestData::default())
+ let eng = TemplateEngine::default();
+
+ let template_string = "Hello, my name is {{ name }}, I am {{ age }} years old and i like {{#each tags}}{{this}} {{/each}}";
+ let res = eng
+ .render_string(template_string, &TestData::default())
.expect("Error parsing template");
assert_eq!(
res,
@@ -65,12 +103,13 @@ mod tests {
..Default::default()
};
- let tmpl = Template::new(
- "Hello, my name is {{{ name }}}, I am {{ age }} years old and i like {{#each tags}}{{this}} {{/each}}"
- .to_string(),
- );
+ let template_string = "Hello, my name is {{{ name }}}, I am {{ age }} years old and i like {{#each tags}}{{this}} {{/each}}";
- let res = tmpl.generate(&data).expect("Error parsing template");
+ let eng = TemplateEngine::default();
+
+ let res = eng
+ .render_string(template_string, &data)
+ .expect("Error parsing template");
assert_eq!(
res,
"Hello, my name is Alice Allison, I am 21 years old and i like cats dogs rust "
diff --git a/test.html b/test.html
new file mode 100644
index 0000000..0167482
--- /dev/null
+++ b/test.html
@@ -0,0 +1,257 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
(progn
+ (add-to-list 'load-path "/media/joe/extradrive1/Projects/fivesigma/org-static/target/debug")
+ (require 'org-static)
+ (org-static-say-hello "joe"))
+
+(buffer-file-name)
+
+(org-export-to-file 'html "test.html")
+
+
+
+
+
Author: Joe Bellus
+
Created: 2022-12-21 Wed 01:30
+
+
+