diff --git a/src/media.rs b/src/media.rs index eccd64f7d4..9aaf75bd1f 100644 --- a/src/media.rs +++ b/src/media.rs @@ -9,6 +9,7 @@ pub(crate) enum Media { Audio, Iframe, Image, + Markdown, Model, Pdf, Text, @@ -41,8 +42,8 @@ impl Media { ("text/html", Media::Iframe, &[]), ("text/html;charset=utf-8", Media::Iframe, &["html"]), ("text/javascript", Media::Text, &["js"]), - ("text/markdown", Media::Text, &[]), - ("text/markdown;charset=utf-8", Media::Text, &["md"]), + ("text/markdown", Media::Markdown, &[]), + ("text/markdown;charset=utf-8", Media::Markdown, &["md"]), ("text/plain", Media::Text, &[]), ("text/plain;charset=utf-8", Media::Text, &["txt"]), ("video/mp4", Media::Video, &["mp4"]), diff --git a/src/subcommand/server.rs b/src/subcommand/server.rs index 93069204dc..006c0df54f 100644 --- a/src/subcommand/server.rs +++ b/src/subcommand/server.rs @@ -9,9 +9,9 @@ use { crate::templates::{ BlockHtml, ClockSvg, HomeHtml, InputHtml, InscriptionHtml, InscriptionJson, InscriptionsBlockHtml, InscriptionsHtml, InscriptionsJson, OutputHtml, OutputJson, PageContent, - PageHtml, PreviewAudioHtml, PreviewImageHtml, PreviewModelHtml, PreviewPdfHtml, - PreviewTextHtml, PreviewUnknownHtml, PreviewVideoHtml, RangeHtml, RareTxt, SatHtml, SatJson, - TransactionHtml, + PageHtml, PreviewAudioHtml, PreviewImageHtml, PreviewMarkdownHtml, PreviewModelHtml, + PreviewPdfHtml, PreviewTextHtml, PreviewUnknownHtml, PreviewVideoHtml, RangeHtml, RareTxt, + SatHtml, SatJson, TransactionHtml, }, axum::{ body, @@ -915,6 +915,16 @@ impl Server { ) .into_response(), ), + Media::Markdown => Ok( + ( + [( + header::CONTENT_SECURITY_POLICY, + "script-src-elem 'self' https://cdn.jsdelivr.net", + )], + PreviewMarkdownHtml { inscription_id }, + ) + .into_response(), + ), Media::Model => Ok( ( [( @@ -2514,6 +2524,26 @@ mod tests { ); } + #[test] + fn markdown_preview() { + let server = TestServer::new_with_regtest(); + server.mine_blocks(1); + + let txid = server.bitcoin_rpc_server.broadcast_tx(TransactionTemplate { + inputs: &[(1, 0, 0, inscription("text/markdown", "hello").to_witness())], + ..Default::default() + }); + let inscription_id = InscriptionId { txid, index: 0 }; + + server.mine_blocks(1); + + server.assert_response_regex( + format!("/preview/{inscription_id}"), + StatusCode::OK, + format!(r".*.*"), + ); + } + #[test] fn image_preview() { let server = TestServer::new_with_regtest(); diff --git a/src/templates.rs b/src/templates.rs index 7df7f4442a..7967b7dffa 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -12,8 +12,8 @@ pub(crate) use { output::{OutputHtml, OutputJson}, page_config::PageConfig, preview::{ - PreviewAudioHtml, PreviewImageHtml, PreviewModelHtml, PreviewPdfHtml, PreviewTextHtml, - PreviewUnknownHtml, PreviewVideoHtml, + PreviewAudioHtml, PreviewImageHtml, PreviewMarkdownHtml, PreviewModelHtml, PreviewPdfHtml, + PreviewTextHtml, PreviewUnknownHtml, PreviewVideoHtml, }, range::RangeHtml, rare::RareTxt, diff --git a/src/templates/preview.rs b/src/templates/preview.rs index 74cb0261dd..bd72443708 100644 --- a/src/templates/preview.rs +++ b/src/templates/preview.rs @@ -10,6 +10,11 @@ pub(crate) struct PreviewImageHtml { pub(crate) inscription_id: InscriptionId, } +#[derive(boilerplate::Boilerplate)] +pub(crate) struct PreviewMarkdownHtml { + pub(crate) inscription_id: InscriptionId, +} + #[derive(boilerplate::Boilerplate)] pub(crate) struct PreviewModelHtml { pub(crate) inscription_id: InscriptionId, diff --git a/static/preview-markdown.css b/static/preview-markdown.css new file mode 100644 index 0000000000..f7676f18ba --- /dev/null +++ b/static/preview-markdown.css @@ -0,0 +1,7 @@ + html { + color: #98a3ad; + background-color: #131516; + max-width: 900px; + margin: 0 auto; + font-family: system-ui, sans-serif; +} diff --git a/static/preview-markdown.js b/static/preview-markdown.js new file mode 100644 index 0000000000..1c3b770cbd --- /dev/null +++ b/static/preview-markdown.js @@ -0,0 +1,6 @@ +import { marked } from 'https://cdn.jsdelivr.net/npm/marked@9/+esm' + +const inscription = document.documentElement.dataset.inscription; +const response = await fetch(`/content/${inscription}`); +const markdown = await response.text(); +document.body.innerHTML = marked.parse(markdown); diff --git a/templates/preview-markdown.html b/templates/preview-markdown.html new file mode 100644 index 0000000000..718c9ca7ed --- /dev/null +++ b/templates/preview-markdown.html @@ -0,0 +1,10 @@ + + +
+ + + + + + +