mygit

[UNMAINTAINED] A cgit/webgit alternative, written in Rust
Log | Files | Refs | README | LICENSE

commit 309802d123c2d3b431e16b03f0f5067a7a510131
parent 9bc901c485bc04b9c8d56a209181b7c4e598c9d1
Author: Johann150 <johann@qwertqwefsday.eu>
Date:   Sun, 14 Mar 2021 23:55:36 +0100

add readme formats: plaintext, HTML

Made RepoHomeTemplate::readme_text a String because for plaintext and
markdown formatting the content has to be turned into a String anyway.

Diffstat:
Msrc/main.rs | 65+++++++++++++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 51 insertions(+), 14 deletions(-)

diff --git a/src/main.rs b/src/main.rs @@ -3,7 +3,6 @@ use askama::Template; use git2::{Commit, Diff, DiffDelta, DiffFormat, Oid, Reference, Repository, Tree, TreeEntry}; use once_cell::sync::Lazy; use pico_args; -use pulldown_cmark::{html, Options, Parser}; use serde::{Deserialize, Serialize}; use std::fs; use std::path::Path; @@ -79,9 +78,9 @@ async fn index(req: Request<()>) -> tide::Result { #[derive(Template)] #[template(path = "repo.html")] // using the template in this path, relative -struct RepoHomeTemplate<'a> { - repo: &'a Repository, - readme_text: &'a str, +struct RepoHomeTemplate { + repo: Repository, + readme_text: String, } fn repo_from_request(repo_name: &str) -> Result<Repository> { @@ -92,18 +91,56 @@ fn repo_from_request(repo_name: &str) -> Result<Repository> { } async fn repo_home(req: Request<()>) -> tide::Result { + use pulldown_cmark::{escape::escape_html, html::push_html, Options, Parser}; + + enum ReadmeFormat { + Plaintext, + Html, + Markdown, + } + let repo = repo_from_request(&req.param("repo_name")?)?; - let readme = &repo.revparse_single("HEAD:README.md")?; // TODO allow more incl plaintext - let markdown_input = std::str::from_utf8(readme.as_blob().unwrap().content())?; - let mut options = Options::empty(); - let parser = Parser::new_ext(markdown_input, options); - let mut html_output = String::new(); - html::push_html(&mut html_output, parser); - let tmpl = RepoHomeTemplate { - repo: &repo, - readme_text: &html_output, + + let readme_text = { + let mut format = ReadmeFormat::Plaintext; + let readme = repo + .revparse_single("HEAD:README") + .or_else(|_| repo.revparse_single("HEAD:README.txt")) + .or_else(|_| { + format = ReadmeFormat::Markdown; + repo.revparse_single("HEAD:README.md") + }) + .or_else(|_| repo.revparse_single("HEAD:README.mdown")) + .or_else(|_| repo.revparse_single("HEAD:README.markdown")) + .or_else(|_| { + format = ReadmeFormat::Html; + repo.revparse_single("HEAD:README.html") + }) + .or_else(|_| repo.revparse_single("HEAD:README.htm"))?; + let readme_text = str::from_utf8(readme.as_blob().unwrap().content())?; + + // render the file contents to HTML + match format { + // render plaintext as preformatted text + ReadmeFormat::Plaintext => { + let mut output = "<pre>".to_string(); + escape_html(&mut output, readme_text)?; + output.push_str("</pre>"); + output + } + // already is HTML + ReadmeFormat::Html => readme_text.to_string(), + // render Markdown to HTML + ReadmeFormat::Markdown => { + let mut output = String::new(); + let parser = Parser::new_ext(readme_text, Options::empty()); + push_html(&mut output, parser); + output + } + } }; - Ok(tmpl.into()) + + Ok(RepoHomeTemplate { repo, readme_text }.into()) } #[derive(Template)]