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"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
|
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]]
|
[[package]]
|
||||||
name = "alloc-no-stdlib"
|
name = "alloc-no-stdlib"
|
||||||
version = "2.0.4"
|
version = "2.0.4"
|
||||||
@@ -851,6 +860,35 @@ dependencies = [
|
|||||||
"bitflags",
|
"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]]
|
[[package]]
|
||||||
name = "rikidown"
|
name = "rikidown"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -859,6 +897,7 @@ dependencies = [
|
|||||||
"git2",
|
"git2",
|
||||||
"markdown",
|
"markdown",
|
||||||
"minijinja",
|
"minijinja",
|
||||||
|
"regex",
|
||||||
"rouille",
|
"rouille",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -10,3 +10,4 @@ markdown = "1.0.0"
|
|||||||
rouille = "3.6.2"
|
rouille = "3.6.2"
|
||||||
minijinja = { version = "2.1.0", features = ["loader"] }
|
minijinja = { version = "2.1.0", features = ["loader"] }
|
||||||
serde = { version = "1.0.203", features = ["derive"] }
|
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
|
- --git-repo the URL of the git repo to load
|
||||||
- --listen address to listen on, in the form of 0.0.0.0:8080
|
- --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
|
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.
|
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 clap::Parser;
|
||||||
use git2::Repository;
|
use git2::Repository;
|
||||||
use minijinja::Environment;
|
use minijinja::Environment;
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
use rouille::Response;
|
use rouille::Response;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
@@ -19,12 +20,21 @@ struct Args {
|
|||||||
/// Address to listen on, in the form of 0.0.0.0:8080
|
/// Address to listen on, in the form of 0.0.0.0:8080
|
||||||
#[arg(long, default_value = "0.0.0.0:8080")]
|
#[arg(long, default_value = "0.0.0.0:8080")]
|
||||||
listen: String,
|
listen: String,
|
||||||
|
|
||||||
|
/// pre-processes markdown files to make them more standard compliant
|
||||||
|
#[arg(long)]
|
||||||
|
obsidian_mode: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct Context {}
|
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) {
|
let md = match fs::read_to_string(path) {
|
||||||
Ok(md) => md,
|
Ok(md) => md,
|
||||||
Err(e) => {
|
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 body_html = markdown::to_html(&md);
|
||||||
let template_path = repo_path.join("template.html");
|
let template_path = repo_path.join("template.html");
|
||||||
|
|
||||||
@@ -95,6 +111,7 @@ fn main() {
|
|||||||
|
|
||||||
println!("Listening on: {}", args.listen);
|
println!("Listening on: {}", args.listen);
|
||||||
|
|
||||||
|
let obsidian_mode = args.obsidian_mode;
|
||||||
rouille::start_server(args.listen, move |request| {
|
rouille::start_server(args.listen, move |request| {
|
||||||
let url = request.url();
|
let url = request.url();
|
||||||
let requested_path = repo_path.join(url.trim_start_matches('/'));
|
let requested_path = repo_path.join(url.trim_start_matches('/'));
|
||||||
@@ -103,18 +120,18 @@ fn main() {
|
|||||||
if requested_path.is_dir() {
|
if requested_path.is_dir() {
|
||||||
let index_path = requested_path.join("index.md");
|
let index_path = requested_path.join("index.md");
|
||||||
if index_path.is_file() {
|
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");
|
let readme_path = requested_path.join("README.md");
|
||||||
if readme_path.is_file() {
|
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
|
// Check if the path as-is is a file. e.g. /README.md
|
||||||
if requested_path.is_file() {
|
if requested_path.is_file() {
|
||||||
if requested_path.extension().and_then(std::ffi::OsStr::to_str) == Some("md") {
|
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.
|
// For now, 404 on other file types. A real implementation might serve static files.
|
||||||
return Response::empty_404();
|
return Response::empty_404();
|
||||||
@@ -124,7 +141,7 @@ fn main() {
|
|||||||
let mut md_path = requested_path;
|
let mut md_path = requested_path;
|
||||||
md_path.set_extension("md");
|
md_path.set_extension("md");
|
||||||
if md_path.is_file() {
|
if md_path.is_file() {
|
||||||
return render_page(&repo_path, &md_path);
|
return render_page(&repo_path, &md_path, obsidian_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Response::empty_404()
|
Response::empty_404()
|
||||||
|
|||||||
Reference in New Issue
Block a user