150 lines
5.7 KiB
Rust
150 lines
5.7 KiB
Rust
#![warn(unused_extern_crates)]
|
|
use std::{
|
|
fs::ReadDir,
|
|
io::{BufWriter, Write, stdout},
|
|
ops::Deref,
|
|
path::{self, Path, PathBuf},
|
|
str::FromStr,
|
|
};
|
|
|
|
use ansi_align::{AlignOptions, ansi_align, ansi_align_with_options};
|
|
use borderrs::BorderFormatter;
|
|
use boxen::boxen;
|
|
use lipgloss::{Border, Position};
|
|
use mq_markdown::{ColorTheme, ListStyle, Markdown, Node, RenderOptions, UrlSurroundStyle};
|
|
use mq_view::{RenderConfig, render_markdown, render_markdown_with_config};
|
|
use serde::de::value;
|
|
use warp::{Filter, filters::path::FullPath};
|
|
|
|
fn renderer(path: FullPath, user_agent: String) -> Box<dyn warp::Reply> {
|
|
let time = chrono::Local::now().to_rfc2822();
|
|
println!("{:?} requested by {}", path, user_agent);
|
|
let path_as_buf = PathBuf::from_str(path.as_str())
|
|
.unwrap_or_default()
|
|
.strip_prefix("/")
|
|
.unwrap()
|
|
.to_owned();
|
|
let target_path = std::env::current_dir()
|
|
.expect("could not determine current directory")
|
|
.join(path_as_buf);
|
|
|
|
if target_path.exists() {
|
|
let page_contents: Vec<PathBuf> = match target_path.is_dir() {
|
|
true => std::fs::read_dir(target_path)
|
|
.unwrap()
|
|
.filter(|x| {
|
|
x.as_ref()
|
|
.unwrap()
|
|
.path()
|
|
.extension()
|
|
.unwrap_or_default()
|
|
.eq("md")
|
|
})
|
|
.map(|x| x.unwrap().path())
|
|
.collect(),
|
|
false => vec![target_path],
|
|
};
|
|
|
|
if user_agent.starts_with("curl/") {
|
|
println!("displaying curl formatting");
|
|
let page_markdowns: Vec<String> = page_contents
|
|
.iter()
|
|
.map(|x| {
|
|
let source = std::fs::read_to_string(x).unwrap();
|
|
let mut mq: mq_markdown::Markdown = source.parse().unwrap();
|
|
let render_opts = RenderOptions {
|
|
list_style: ListStyle::Dash,
|
|
link_url_style: UrlSurroundStyle::None,
|
|
link_title_style: mq_markdown::TitleSurroundStyle::Single,
|
|
};
|
|
mq.set_options(render_opts);
|
|
let theme = ColorTheme::parse_colors("heading=34:code=31");
|
|
mq.to_colored_string_with_theme(&theme);
|
|
let render_conf = RenderConfig {
|
|
header_full_width_highlight: false,
|
|
};
|
|
|
|
let styled_mq = mq_view::render_markdown_to_string(&mq).unwrap();
|
|
|
|
let mut writer: Vec<u8> = Vec::new();
|
|
|
|
render_markdown_with_config(&mq, &mut writer, &render_conf).unwrap();
|
|
|
|
let render_string = String::from_utf8(writer).unwrap();
|
|
|
|
println!("{}", render_string);
|
|
|
|
let md = mdriver::StreamingParser::new().feed(
|
|
termimad::text(std::fs::read_to_string(x).unwrap_or_default().as_str())
|
|
.to_string()
|
|
.as_str(),
|
|
);
|
|
let border_style = lipgloss::Style::new()
|
|
.border(Border::new(
|
|
"─", "─", "│", "│", "╭", "╮", "╰", "╯", "", "", "", "", "",
|
|
))
|
|
.width(80)
|
|
.padding(0, 2, 0, 2)
|
|
.align_horizontal(lipgloss::position::CENTER);
|
|
border_style.render(render_string.as_str())
|
|
})
|
|
.collect();
|
|
|
|
for c in &page_markdowns {
|
|
println!("{}\n", c);
|
|
}
|
|
let page_md_collected = format!("{}\n", page_markdowns.join("\n"));
|
|
|
|
Box::new(warp::reply::with_status(
|
|
page_md_collected,
|
|
warp::http::StatusCode::OK,
|
|
))
|
|
} else {
|
|
println!("displaying html formatting");
|
|
let page_md_packed: Vec<String> = page_contents
|
|
.iter()
|
|
.map(|x| {
|
|
format!(
|
|
"<div id='{}' class='markdown-module'>{}</div>",
|
|
x.file_stem()
|
|
.unwrap_or_default()
|
|
.to_str()
|
|
.unwrap_or_default(),
|
|
markdown::to_html_with_options(
|
|
std::fs::read_to_string(x).unwrap_or_default().as_str(),
|
|
&markdown::Options::gfm()
|
|
)
|
|
.unwrap_or_default()
|
|
)
|
|
})
|
|
.collect();
|
|
let page_md_collected = page_md_packed.join("\n");
|
|
let template_html =
|
|
std::fs::read_to_string("./assets/template.html").unwrap_or_default();
|
|
let template = text_template::Template::from(template_html.as_str());
|
|
let mut values = std::collections::HashMap::new();
|
|
values.insert("time", time.as_str());
|
|
values.insert("body", page_md_collected.as_str());
|
|
let html = template.fill_in(&values);
|
|
Box::new(warp::reply::html(html.to_string()))
|
|
}
|
|
} else {
|
|
println!("could not find path!");
|
|
Box::new(warp::reply::with_status(
|
|
"uh oh",
|
|
warp::http::StatusCode::NOT_FOUND,
|
|
))
|
|
}
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
println!("Hello, world!");
|
|
|
|
let readme = warp::any() //path::end()
|
|
.and(warp::path::full())
|
|
.and(warp::header("user-agent"))
|
|
.map(|path: FullPath, agent: String| renderer(path, agent));
|
|
|
|
warp::serve(readme).run(([127, 0, 0, 1], 3030)).await;
|
|
}
|