From 4ec5cf0f9b904476f9bb53a2556039c8d2238454 Mon Sep 17 00:00:00 2001 From: silverpill Date: Thu, 1 Dec 2022 21:42:43 +0000 Subject: [PATCH] Render instance description to HTML https://codeberg.org/silverpill/mitra-web/issues/3 --- src/mastodon_api/instance/types.rs | 4 ++ src/mastodon_api/statuses/types.rs | 4 +- src/utils/markdown.rs | 66 +++++++++++++++++++----------- 3 files changed, 49 insertions(+), 25 deletions(-) diff --git a/src/mastodon_api/instance/types.rs b/src/mastodon_api/instance/types.rs index 152ba26..c1ed8c9 100644 --- a/src/mastodon_api/instance/types.rs +++ b/src/mastodon_api/instance/types.rs @@ -4,6 +4,7 @@ use serde_json::{to_value, Value}; use crate::config::{BlockchainConfig, Config}; use crate::ethereum::contracts::ContractSet; use crate::mastodon_api::MASTODON_API_VERSION; +use crate::utils::markdown::markdown_to_html; #[derive(Serialize)] struct InstanceStats { @@ -32,7 +33,9 @@ pub struct InstanceInfo { uri: String, title: String, short_description: String, + // TODO: HTML by default description: String, + description_html: String, version: String, registrations: bool, stats: InstanceStats, @@ -106,6 +109,7 @@ impl InstanceInfo { title: config.instance_title.clone(), short_description: config.instance_short_description.clone(), description: config.instance_description.clone(), + description_html: markdown_to_html(&config.instance_description), version: get_full_api_version(&config.version), registrations: config.registrations_open, stats: InstanceStats { diff --git a/src/mastodon_api/statuses/types.rs b/src/mastodon_api/statuses/types.rs index 1a7f89e..d5041f8 100644 --- a/src/mastodon_api/statuses/types.rs +++ b/src/mastodon_api/statuses/types.rs @@ -9,7 +9,7 @@ use crate::mastodon_api::accounts::types::Account; use crate::mastodon_api::media::types::Attachment; use crate::models::posts::types::{Post, PostCreateData, Visibility}; use crate::models::profiles::types::DbActorProfile; -use crate::utils::markdown::markdown_to_html; +use crate::utils::markdown::markdown_lite_to_html; /// https://docs.joinmastodon.org/entities/mention/ #[derive(Serialize)] @@ -170,7 +170,7 @@ impl TryFrom for PostCreateData { let content = match status_data.content_type.as_str() { "text/html" => status_data.status, "text/markdown" => { - markdown_to_html(&status_data.status) + markdown_lite_to_html(&status_data.status) .map_err(|_| ValidationError("invalid markdown"))? }, _ => return Err(ValidationError("unsupported content type")), diff --git a/src/utils/markdown.rs b/src/utils/markdown.rs index dbfc09a..a2ae4d9 100644 --- a/src/utils/markdown.rs +++ b/src/utils/markdown.rs @@ -19,6 +19,21 @@ pub enum MarkdownError { Utf8Error(#[from] std::string::FromUtf8Error), } +fn build_comrak_options() -> ComrakOptions { + ComrakOptions { + extension: ComrakExtensionOptions { + autolink: true, + ..Default::default() + }, + parse: ComrakParseOptions::default(), + render: ComrakRenderOptions { + hardbreaks: true, + escape: true, + ..Default::default() + }, + } +} + fn iter_nodes<'a, F>( node: &'a AstNode<'a>, func: &F, @@ -48,19 +63,8 @@ fn node_to_markdown<'a>( /// - bold and italic /// - links and autolinks /// - inline code and code blocks -pub fn markdown_to_html(text: &str) -> Result { - let options = ComrakOptions { - extension: ComrakExtensionOptions { - autolink: true, - ..Default::default() - }, - parse: ComrakParseOptions::default(), - render: ComrakRenderOptions { - hardbreaks: true, - escape: true, - ..Default::default() - }, - }; +pub fn markdown_lite_to_html(text: &str) -> Result { + let options = build_comrak_options(); let arena = Arena::new(); let root = parse_document( &arena, @@ -180,14 +184,20 @@ pub fn markdown_to_html(text: &str) -> Result { Ok(html) } +/// Full markdown +pub fn markdown_to_html(text: &str) -> String { + let options = build_comrak_options(); + comrak::markdown_to_html(text, &options) +} + #[cfg(test)] mod tests { use super::*; #[test] - fn test_markdown_to_html() { + fn test_markdown_lite_to_html() { let text = "# heading\n\ntest **bold** test *italic* test ~~strike~~ with `code`, html and https://example.com\nnew line\n\ntwo new lines and a list:\n- item 1\n- item 2\n\n>greentext\n\n---\n\nimage: ![logo](logo.png)\n\ncode block:\n```\nlet test\ntest = 1\n```"; - let html = markdown_to_html(text).unwrap(); + let html = markdown_lite_to_html(text).unwrap(); let expected_html = concat!( r#"

# heading

test bold test italic test ~~strike~~ with code, <span>html</span> and https://example.com
new line

two new lines and a list:

- item 1
- item 2

>greentext

-----

image: ![logo](logo.png)

code block:

"#, "
let test\ntest = 1\n
", @@ -196,31 +206,41 @@ mod tests { } #[test] - fn test_markdown_to_html_ordered_list() { + fn test_markdown_lite_to_html_ordered_list() { let text = "1. item 1\n2. item 2\n"; - let html = markdown_to_html(text).unwrap(); + let html = markdown_lite_to_html(text).unwrap(); let expected_html = r#"

1. item 1
2. item 2

"#; assert_eq!(html, expected_html); } #[test] - fn test_markdown_to_html_mention() { + fn test_markdown_lite_to_html_mention() { let text = "@user@example.org test"; - let html = markdown_to_html(text).unwrap(); + let html = markdown_lite_to_html(text).unwrap(); assert_eq!(html, format!("

{}

", text)); } #[test] - fn test_markdown_to_html_hashtag() { + fn test_markdown_lite_to_html_hashtag() { let text = "#hashtag test"; - let html = markdown_to_html(text).unwrap(); + let html = markdown_lite_to_html(text).unwrap(); assert_eq!(html, format!("

{}

", text)); } #[test] - fn test_markdown_to_html_object_link() { + fn test_markdown_lite_to_html_object_link() { let text = "[[https://example.org/objects/1]] test"; - let html = markdown_to_html(text).unwrap(); + let html = markdown_lite_to_html(text).unwrap(); assert_eq!(html, format!("

{}

", text)); } + + #[test] + fn test_markdown_to_html() { + let text = "# heading\n\ntest"; + let html = markdown_to_html(text); + assert_eq!( + html, + "

heading

\n

test

\n", + ); + } }