Compare commits

..

2 Commits

Author SHA1 Message Date
Joe Bellus 860fa79187 Sync commit 2022-12-25 01:57:01 -05:00
Joe Bellus b70bb8e542 Added article index generation 2022-12-23 01:51:56 -05:00
16 changed files with 695 additions and 131 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
target/ target/
build/

82
Cargo.lock generated
View File

@ -180,9 +180,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.138" version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]] [[package]]
name = "log" name = "log"
@ -208,13 +208,15 @@ dependencies = [
"lazy_static", "lazy_static",
"serde", "serde",
"serde_json", "serde_json",
"toml",
"walkdir",
] ]
[[package]] [[package]]
name = "pest" name = "pest"
version = "2.5.1" version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc8bed3549e0f9b0a2a78bf7c0018237a2cdf085eecbbc048e52612438e4e9d0" checksum = "0f6e86fb9e7026527a0d46bc308b841d73170ef8f443e1807f6ef88526a816d4"
dependencies = [ dependencies = [
"thiserror", "thiserror",
"ucd-trie", "ucd-trie",
@ -222,9 +224,9 @@ dependencies = [
[[package]] [[package]]
name = "pest_derive" name = "pest_derive"
version = "2.5.1" version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdc078600d06ff90d4ed238f0119d84ab5d43dbaad278b0e33a8820293b32344" checksum = "96504449aa860c8dcde14f9fba5c58dc6658688ca1fe363589d6327b8662c603"
dependencies = [ dependencies = [
"pest", "pest",
"pest_generator", "pest_generator",
@ -232,9 +234,9 @@ dependencies = [
[[package]] [[package]]
name = "pest_generator" name = "pest_generator"
version = "2.5.1" version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28a1af60b1c4148bb269006a750cff8e2ea36aff34d2d96cf7be0b14d1bed23c" checksum = "798e0220d1111ae63d66cb66a5dcb3fc2d986d520b98e49e1852bfdb11d7c5e7"
dependencies = [ dependencies = [
"pest", "pest",
"pest_meta", "pest_meta",
@ -245,9 +247,9 @@ dependencies = [
[[package]] [[package]]
name = "pest_meta" name = "pest_meta"
version = "2.5.1" version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fec8605d59fc2ae0c6c1aefc0c7c7a9769732017c0ce07f7a9cfffa7b4404f20" checksum = "984298b75898e30a843e278a9f2452c31e349a073a0ce6fd950a12a74464e065"
dependencies = [ dependencies = [
"once_cell", "once_cell",
"pest", "pest",
@ -287,6 +289,15 @@ version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" 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]] [[package]]
name = "semver" name = "semver"
version = "0.9.0" version = "0.9.0"
@ -381,6 +392,15 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "toml"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "typenum" name = "typenum"
version = "1.16.0" version = "1.16.0"
@ -404,3 +424,45 @@ name = "version_check"
version = "0.9.4" version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 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"

View File

@ -3,22 +3,18 @@ name = "org-static"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib] [lib]
crate-type = ["cdylib"] crate-type = ["cdylib"]
[dependencies] [dependencies]
lazy_static = "1.4" lazy_static = "1.4"
emacs = "0.18.0" emacs = "0.18.0"
serde = { version = "1.0.151", features = ["derive"] } serde = { version = "1.0.151", features = ["derive"] }
handlebars = "4.3.6" handlebars = "4.3.6"
serde_json = "1.0.91" serde_json = "1.0.91"
walkdir = "2.3.2"
[dev-dependencies] toml = "0.5.10"
#emacs-rs-module = { version = "0.13.0" }

8
examples/basic.rs Normal file
View File

@ -0,0 +1,8 @@
use org_static::publish;
fn main() {
match publish("examples/basic".into()) {
Ok(()) => println!("Complete"),
Err(e) => println!("Error: {}", e),
}
}

View File

@ -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

View File

@ -0,0 +1,2 @@
[site]
title = "Basic Example Site"

View File

@ -0,0 +1,5 @@
<div class="menu">Some Menu</div>
<div>title: {{ article.title }}</div>
<Article>
{{{content}}}
</Article>

10
readme.org Normal file
View File

@ -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]]

View File

@ -1,15 +1,26 @@
use crate::{error::Result, site::Site, template::Template};
use serde::Serialize; use serde::Serialize;
use serde_json::json; use std::{collections::HashSet, path::PathBuf};
use std::collections::{HashMap, HashSet};
#[derive(Serialize, Default)] use crate::config::Config;
#[derive(Serialize, Default, Clone)]
pub struct Article { pub struct Article {
filename: String, pub title: String,
date: String, pub date: String,
author: String, pub author: String,
properties: HashMap<String, String>, pub slug: String,
tags: HashSet<String>, pub file_path: PathBuf,
pub tags: HashSet<String>,
}
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)] #[derive(Serialize, Default)]
@ -19,65 +30,7 @@ pub struct ArticleContext {
} }
impl ArticleContext { impl ArticleContext {
pub fn load(article: Article) -> Result<Self> { pub fn new(article: Article, content: String) -> Self {
Ok(Self { Self { article, content }
article,
content: String::new(),
})
}
#[cfg(test)]
pub fn load_string(article: Article, content: &str) -> Result<Self> {
Ok(Self {
article,
content: content.to_string(),
})
}
}
pub fn generate_article(
site: &Site,
article: &ArticleContext,
template: &Template,
) -> Result<String> {
let ctx = json!({
"site": site,
"data": article,
});
let res = template.generate(&ctx)?;
Ok(res)
}
#[cfg(test)]
mod tests {
use crate::template::Template;
use super::*;
pub fn fixture_article() -> Article {
Article {
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() {
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 = crate::site::tests::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");
} }
} }

112
src/config.rs Normal file
View File

@ -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<Self> {
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<PathBuf> {
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();
}
}

20
src/elisp/org-static.el Normal file
View File

@ -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)

View File

@ -11,8 +11,6 @@ impl std::fmt::Display for Error {
} }
} }
impl std::error::Error for Error {}
impl Error { impl Error {
pub fn new(message: &str) -> Self { pub fn new(message: &str) -> Self {
Error { Error {
@ -21,18 +19,16 @@ impl Error {
} }
} }
impl From<handlebars::TemplateError> for Error { impl<T: std::error::Error> From<T> for Error {
fn from(source: handlebars::TemplateError) -> Self { fn from(source: T) -> Self {
Self { Self {
message: source.to_string(), message: source.to_string(),
} }
} }
} }
impl From<handlebars::RenderError> for Error { impl From<Error> for emacs::Error {
fn from(source: handlebars::RenderError) -> Self { fn from(source: Error) -> Self {
Self { emacs::Error::msg(source)
message: source.to_string(),
}
} }
} }

View File

@ -1,25 +1,117 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
mod article; mod article;
mod config;
mod error; mod error;
mod site; mod site;
mod template; 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::plugin_is_GPL_compatible!();
#[emacs::module(name = "org-static")] #[emacs::module(name = "liborg_static", defun_prefix = "org-static")]
fn init(_: &Env) -> Result<()> { fn init(e: &Env) -> Result<()> {
e.message("orgstatic loaded")?;
Ok(())
}
fn find_articles(env: &Env, config: &config::Config) -> Result<Vec<Article>> {
let mut articles: Vec<Article> = 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::<String>(0)?;
let author = article_data.get::<String>(1)?;
let date = article_data.get::<String>(2)?;
let slug = {
let s = article_data.get::<String>(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::<String>(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::<String>()?;
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(()) Ok(())
} }
#[defun] #[defun]
fn say_hello(env: &Env, _name: String) -> Result<Value<'_>> { pub fn publish(env: &Env, starting_path: String) -> Result<()> {
let fname = env let cfg = config::Config::find(PathBuf::from(starting_path))?;
.call("buffer-file-name", []) println!("{:?}", cfg);
.unwrap() let articles = find_articles(env, &cfg)?;
.into_rust::<String>() env.message(format!("{} articles found", articles.len()))?;
.unwrap(); publish_articles(env, &cfg, &articles)?;
env.message(fname) Ok(())
} }

View File

@ -1,12 +1,13 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Default)] #[derive(Serialize, Deserialize, Default, Debug)]
pub struct Site { pub struct Site {
title: String, title: String,
} }
#[cfg(test)] #[cfg(test)]
pub mod tests { pub mod tests {
use super::*; use super::*;
#[allow(dead_code)] #[allow(dead_code)]
@ -15,7 +16,4 @@ pub mod tests {
title: "Test Site".to_string(), title: "Test Site".to_string(),
} }
} }
#[test]
fn test_name() {}
} }

View File

@ -1,22 +1,61 @@
use std::{collections::HashMap, path::PathBuf};
use handlebars::Handlebars; use handlebars::Handlebars;
use serde::Serialize; use serde::Serialize;
use crate::{error::Result, site::Site}; use crate::error::Result;
pub struct Template { #[derive(Debug, Default)]
pub template_string: String, pub struct TemplateEngine {
partials: HashMap<String, String>,
} }
impl Template { impl TemplateEngine {
pub fn new(template_string: String) -> Self { pub fn new<T: Into<PathBuf>>(partial_path: T) -> Result<Self> {
Self { template_string } 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<T: Serialize>(&self, data: &T) -> Result<String> { pub fn render_string<D: Serialize>(&self, template_string: &str, data: D) -> Result<String> {
let reg = Handlebars::new(); 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)?; let res = reg.render_template(template_string, &data)?;
Ok(output)
Ok(res)
}
pub fn render_file<D: Serialize>(
&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] #[test]
fn test_template() { fn test_template() {
let tmpl = Template::new( let eng = TemplateEngine::default();
"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 = eng
let res = tmpl .render_string(template_string, &TestData::default())
.generate(&TestData::default())
.expect("Error parsing template"); .expect("Error parsing template");
assert_eq!( assert_eq!(
res, res,
@ -65,12 +103,13 @@ mod tests {
..Default::default() ..Default::default()
}; };
let tmpl = Template::new( let template_string = "Hello, my name is {{{ name }}}, I am {{ age }} years old and i like {{#each tags}}{{this}} {{/each}}";
"Hello, my name is {{{ name }}}, I am {{ age }} years old and i like {{#each tags}}{{this}} {{/each}}"
.to_string(),
);
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!( assert_eq!(
res, res,
"Hello, my name is <b>Alice</b> Allison, I am 21 years old and i like cats dogs rust " "Hello, my name is <b>Alice</b> Allison, I am 21 years old and i like cats dogs rust "

257
test.html Normal file
View File

@ -0,0 +1,257 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2022-12-21 Wed 01:30 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>&lrm;</title>
<meta name="author" content="Joe Bellus" />
<meta name="generator" content="Org Mode" />
<style type="text/css">
<!--/*--><![CDATA[/*><!--*/
html, body {
background: #181818;
font-family: sans-serif;
margin: 0;
padding: 0;
width: 100vw;
overflow-x: hidden;
}
a, a:active, a:visited {
text-decoration: none;
color: #de0192;
font-weight: bold;
}
h1.title {
display: fixed;
margin-top: 0;
top: 0;
width: 100%;
height: 60px;
line-height: 60px;
font-weight: 300;
color: #888;
padding: 0 15px;
background: #131313;
border-bottom: 1px solid #000;
}
h2 {
font-weight: 300;
color: #de0192;
}
h2:after {
content: ' ';
height: 2px;
display: block;
background: linear-gradient(90deg, #8604e2 60%, #de0192 100%);
width: 100%;
}
h2 {
text-transform: capitalize;
}
h3 {
text-transform: initial
}
.outline-text-4 p {
margin-top: 0;
padding-top: 0;
}
h4 {
text-transform: uppercase;
font-size: 14px;
margin-bottom: 3px;
}
.figure,
.outline-2 {
max-width: 800px;
padding: 0px 25px;
margin-left: 350px;
color: #fcfcfc;
}
.figure img {
box-shadow: rgba(0, 0, 0, 0.8) 0px 20px 30px -10px;
}
.outline-2, .outline-3 {
margin-top: 15px;
}
.org-ul, .org-ul li {
padding: 0;
margin: 0;
list-style: square;
}
.org-ul {
padding-left: 15px;
}
.figure img {
max-width:100%;
max-height:100%;
margin: auto auto;
border-radius: 5px;
overflow: hidden;
}
#table-of-contents {
position: absolute;
width: 300px;
top: 61px;
left: 0;
color: #f0f0f0;
padding: 15px;
border-radius: 0 0 5px 0;
background: #151515;
border-right: 1px solid #000;
border-bottom: 1px solid #000;
}
#table-of-contents h2 {
display: none;
}
#table-of-contents h2:after {
display: none;
}
#text-table-of-contents > ul {
margin: 0;
padding: 0;
margin-bottom: 15px;
}
#table-of-contents li {
list-style: none;
margin: 0;
padding: 3px 0;
}
#text-table-of-contents > ul {
font-weight: 700;
font-size: 15px;
}
#text-table-of-contents > ul ul {
font-weight: 500;
list-style: square;
margin-left: 5px;
padding: 3px 0;
font-size: 13px;
}
#table-of-contents ul ul {
padding-left: 10px;
}
#table-of-contents a,
#table-of-contents a:hover,
#table-of-contents a:active,
#table-of-contents a:visited {
text-decoration: none;
color: #ffffff;
transition: color 0.2s;
}
#table-of-contents a:hover {
text-decoration: none;
color: #de0192;
transition: color 0.2s;
}
.org-src-container {
margin-top: 5px;
margin-bottom: 10px;
width: 100%;
background: #000;
border-radius: 15px;
padding: 10px;
color: #fff;
font-weight: 600;
font-family: monospace;
}
#postamble {
margin-top: 25px;
font-weight: 300;
color: #999;
font-size: 14px;
font-weight: 700;
padding: 25px 15px;
background: #131313;
border-top: 1px solid #000;
text-align: center;
}
p {
color: #f5f5f5;
font-size: 14px;
}
@media (max-width: 1000px) {
#content > p,
h1,
.figure,
.outline-2 {
margin-left: 0;
}
#table-of-contents {
display: none;
}
.org-src-container {
width: 100%;
overflow-x: scroll;
padding: 0;
}
#content .title + .org-ul {
margin-left: 0;
margin-right: 0;
}
.title + .org-ul > li b {
flex-direction: column-reverse;
text-align: right;
}
.title + .org-ul > li b a {
text-align: left;
}
}
/*]]>*/-->
</style>
</head>
<body>
<div id="content" class="content">
<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #c792ea;">(</span><span style="color: #89DDFF;">progn</span>
<span style="color: #f78c6c;">(</span>add-to-list 'load-path <span style="color: #c3e88d;">"/media/joe/extradrive1/Projects/fivesigma/org-static/target/debug"</span><span style="color: #f78c6c;">)</span>
<span style="color: #f78c6c;">(</span><span style="color: #89DDFF;">require</span> '<span style="color: #f78c6c;">org-static</span><span style="color: #f78c6c;">)</span>
<span style="color: #f78c6c;">(</span>org-static-say-hello <span style="color: #c3e88d;">"joe"</span><span style="color: #f78c6c;">)</span><span style="color: #c792ea;">)</span>
<span style="color: #c792ea;">(</span>buffer-file-name<span style="color: #c792ea;">)</span>
<span style="color: #c792ea;">(</span>org-export-to-file 'html <span style="color: #c3e88d;">"test.html"</span><span style="color: #c792ea;">)</span>
</pre>
</div>
</div>
<div id="postamble" class="status">
<p class="author">Author: Joe Bellus</p>
<p class="date">Created: 2022-12-21 Wed 01:30</p>
</div>
</body>
</html>