add: basic obsidian mode
This commit is contained in:
39
Cargo.lock
generated
39
Cargo.lock
generated
@@ -8,6 +8,15 @@ version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "alloc-no-stdlib"
|
||||
version = "2.0.4"
|
||||
@@ -851,6 +860,35 @@ dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.12.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
|
||||
|
||||
[[package]]
|
||||
name = "rikidown"
|
||||
version = "0.1.0"
|
||||
@@ -859,6 +897,7 @@ dependencies = [
|
||||
"git2",
|
||||
"markdown",
|
||||
"minijinja",
|
||||
"regex",
|
||||
"rouille",
|
||||
"serde",
|
||||
]
|
||||
|
||||
@@ -10,3 +10,4 @@ markdown = "1.0.0"
|
||||
rouille = "3.6.2"
|
||||
minijinja = { version = "2.1.0", features = ["loader"] }
|
||||
serde = { version = "1.0.203", features = ["derive"] }
|
||||
regex = "1"
|
||||
|
||||
11
README.md
11
README.md
@@ -16,6 +16,17 @@ The arguments supported include:
|
||||
|
||||
- --git-repo the URL of the git repo to load
|
||||
- --listen address to listen on, in the form of 0.0.0.0:8080
|
||||
- --obsidian-mode pre-processes markdown files to make them more standard compliant
|
||||
|
||||
Additionally, if there is a './template.html' file in the repo, is will be used to wrap
|
||||
the generated HTML. Specifically, the 'body' block will be replaced by the markdown content.
|
||||
|
||||
## Obsidian mode
|
||||
|
||||
Intended to create compatibility with Obsidian, because it has a fancy UI.
|
||||
Specifically, this replaces `[[thing]]` with `[thing](thing.md)`
|
||||
None of the other options in https://help.obsidian.md/obsidian-flavored-markdown are included.
|
||||
|
||||
## Future work
|
||||
|
||||
Replace the Obisdian markdown with https://crates.io/crates/obsidian-export.
|
||||
|
||||
27
src/main.rs
27
src/main.rs
@@ -1,6 +1,7 @@
|
||||
use clap::Parser;
|
||||
use git2::Repository;
|
||||
use minijinja::Environment;
|
||||
use regex::Regex;
|
||||
|
||||
use rouille::Response;
|
||||
use serde::Serialize;
|
||||
@@ -19,12 +20,21 @@ struct Args {
|
||||
/// Address to listen on, in the form of 0.0.0.0:8080
|
||||
#[arg(long, default_value = "0.0.0.0:8080")]
|
||||
listen: String,
|
||||
|
||||
/// pre-processes markdown files to make them more standard compliant
|
||||
#[arg(long)]
|
||||
obsidian_mode: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Context {}
|
||||
|
||||
fn render_page(repo_path: &PathBuf, path: &Path) -> Response {
|
||||
fn preprocess_obsidian(md: &str) -> String {
|
||||
let re = Regex::new(r"\[\[(.*?)\]\]").unwrap();
|
||||
re.replace_all(md, "[$1]($1.md)").to_string()
|
||||
}
|
||||
|
||||
fn render_page(repo_path: &PathBuf, path: &Path, obsidian_mode: bool) -> Response {
|
||||
let md = match fs::read_to_string(path) {
|
||||
Ok(md) => md,
|
||||
Err(e) => {
|
||||
@@ -33,6 +43,12 @@ fn render_page(repo_path: &PathBuf, path: &Path) -> Response {
|
||||
}
|
||||
};
|
||||
|
||||
let md = if obsidian_mode {
|
||||
preprocess_obsidian(&md)
|
||||
} else {
|
||||
md
|
||||
};
|
||||
|
||||
let body_html = markdown::to_html(&md);
|
||||
let template_path = repo_path.join("template.html");
|
||||
|
||||
@@ -95,6 +111,7 @@ fn main() {
|
||||
|
||||
println!("Listening on: {}", args.listen);
|
||||
|
||||
let obsidian_mode = args.obsidian_mode;
|
||||
rouille::start_server(args.listen, move |request| {
|
||||
let url = request.url();
|
||||
let requested_path = repo_path.join(url.trim_start_matches('/'));
|
||||
@@ -103,18 +120,18 @@ fn main() {
|
||||
if requested_path.is_dir() {
|
||||
let index_path = requested_path.join("index.md");
|
||||
if index_path.is_file() {
|
||||
return render_page(&repo_path, &index_path);
|
||||
return render_page(&repo_path, &index_path, obsidian_mode);
|
||||
}
|
||||
let readme_path = requested_path.join("README.md");
|
||||
if readme_path.is_file() {
|
||||
return render_page(&repo_path, &readme_path);
|
||||
return render_page(&repo_path, &readme_path, obsidian_mode);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the path as-is is a file. e.g. /README.md
|
||||
if requested_path.is_file() {
|
||||
if requested_path.extension().and_then(std::ffi::OsStr::to_str) == Some("md") {
|
||||
return render_page(&repo_path, &requested_path);
|
||||
return render_page(&repo_path, &requested_path, obsidian_mode);
|
||||
}
|
||||
// For now, 404 on other file types. A real implementation might serve static files.
|
||||
return Response::empty_404();
|
||||
@@ -124,7 +141,7 @@ fn main() {
|
||||
let mut md_path = requested_path;
|
||||
md_path.set_extension("md");
|
||||
if md_path.is_file() {
|
||||
return render_page(&repo_path, &md_path);
|
||||
return render_page(&repo_path, &md_path, obsidian_mode);
|
||||
}
|
||||
|
||||
Response::empty_404()
|
||||
|
||||
Reference in New Issue
Block a user