pogmommy-webserver/src/lib/curl.rs
2026-02-23 00:57:01 -08:00

139 lines
4.3 KiB
Rust

use crate::markdowner::MarkdownModule;
use lipgloss::{Border, utils::width};
use mq_markdown::{ListStyle, RenderOptions, UrlSurroundStyle};
use mq_view::{RenderConfig, render_markdown_with_config};
use termimad::minimad::lines;
use warp::Reply;
fn box_content(content: &String, width: i32) -> String {
let lg_border = Border::new("", "", "", "", "", "", "", "", "", "", "", "", "");
let border_style = lipgloss::Style::new()
.border(lg_border)
.width(width)
.padding(0, 2, 0, 2)
.align_horizontal(lipgloss::position::LEFT);
border_style.render(content.as_str())
}
fn markdown_to_cli(content: &String) -> String {
let mut mq: mq_markdown::Markdown = content.parse().expect("could not parse markdown content!");
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 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();
String::from_utf8(writer).unwrap()
}
fn render_content(content: &String, width: i32) -> String {
let md = markdown_to_cli(content);
box_content(&md, width)
}
fn get_cli_header(page_contents: &Vec<MarkdownModule>, width: i32) -> String {
let header = page_contents
.iter()
.find(|m| m.path.file_name().unwrap_or_default().eq("header.md"));
match header {
Some(h) => render_content(&h.content, width),
None => "".to_string(),
}
}
fn get_cli_content(page_contents: &Vec<MarkdownModule>, width: i32) -> Vec<String> {
let content = page_contents
.iter()
.filter(|m| m.path.file_name().unwrap_or_default().ne("header.md"));
content
.map(|m| render_content(&m.content, (width / 2) - 4))
.collect()
}
fn column_layout(mut left_column: String, mut right_column: String) -> String {
let left_pad = left_column
.lines()
.map(|l| {
String::from_utf8(strip_ansi_escapes::strip(&l))
.expect("could not strip ansi from text")
.chars()
.count()
})
.max()
.unwrap_or(0);
while right_column
.lines()
.count()
.lt(&left_column.lines().count())
{
right_column = format!("{}\n", right_column);
}
while left_column
.lines()
.count()
.lt(&right_column.lines().count())
{
left_column = format!("{}\n", left_column);
}
println!(
"page: {}\nsidebar: {}",
right_column.lines().count(),
left_column.lines().count()
);
let cli_columns: Vec<String> = left_column
.lines()
.zip(right_column.lines())
.map(|(left, right)| format!("{:width$} {}", left, right, width = left_pad))
.collect();
cli_columns.join("\n")
}
pub fn curl_response(
page_contents: Vec<MarkdownModule>,
sidebar_contents: Vec<MarkdownModule>,
width: Option<i32>,
) -> Box<dyn Reply> {
let w = width.unwrap_or(100);
let shell_header = if width.is_none() {
"curl -s beta.pogmom.me/?width=$(tput cols);exit 0\n".to_string()
} else {
"".to_string()
};
let shell_footer = if width.is_none() {
box_content(
&"Did you know‽\nIf you (dangerously) pipe this output to your shell, it autosizes! more interactivity is planned in the future".to_string(),
w - 4)
} else {
"".to_string()
};
let terminal_header = get_cli_header(&page_contents, w - 4);
let terminal_sidebar = get_cli_content(&sidebar_contents, w).join("\n");
let terminal_page = get_cli_content(&page_contents, w).join("\n");
let terminal_body = if w.gt(&110) {
column_layout(terminal_sidebar, terminal_page)
} else {
format!("{}\n{}\n", terminal_sidebar, terminal_page)
};
let cli_contents = format!(
"{}{}\n{}\n{}\n",
shell_header, terminal_header, terminal_body, shell_footer
);
Box::new(warp::reply::with_status(
cli_contents,
warp::http::StatusCode::OK,
))
}