use anyhow::Result;
use clap::Parser;
use std::path::PathBuf;
mod app;
use app::{scan_markdown_files, serve_markdown, DiagramOpts};
#[derive(Parser)]
#[command(name = "mdrvserve")]
#[command(about = "A simple HTTP server for markdown preview")]
#[command(version)]
struct Args {
path: PathBuf,
#[arg(short = 'H', long, default_value = "127.0.0.1")]
hostname: String,
#[arg(short, long, default_value = "3000")]
port: u16,
#[arg(short, long)]
open: bool,
#[arg(short, long)]
recursive: bool,
#[arg(long = "with-mermaid")]
with_mermaid: bool,
#[arg(long = "with-d2")]
with_d2: bool,
#[arg(long = "with-latex")]
with_latex: bool,
#[arg(long = "with-typst")]
with_typst: bool,
#[arg(long = "include-html")]
include_html: bool,
#[arg(long = "include-typst")]
include_typst: bool,
}
#[tokio::main]
async fn main() -> Result<()> {
let args = Args::parse();
let absolute_path = args.path.canonicalize().unwrap_or(args.path);
let (base_dir, tracked_files, is_directory_mode) = if absolute_path.is_file() {
let base_dir = absolute_path
.parent()
.unwrap_or_else(|| std::path::Path::new("."))
.to_path_buf();
let tracked_files = vec![absolute_path];
(base_dir, tracked_files, false)
} else if absolute_path.is_dir() {
let tracked_files = scan_markdown_files(&absolute_path, args.recursive, args.include_html, args.include_typst)?;
if tracked_files.is_empty() {
anyhow::bail!("No markdown files found in directory");
}
(absolute_path, tracked_files, true)
} else {
anyhow::bail!("Path must be a file or directory");
};
serve_markdown(
base_dir,
tracked_files,
is_directory_mode,
args.recursive,
args.hostname,
args.port,
args.open,
DiagramOpts {
mermaid: args.with_mermaid,
d2: args.with_d2,
latex: args.with_latex,
typst: args.with_typst,
},
args.include_html,
args.include_typst,
)
.await?;
Ok(())
}