Skip to content

Commit 8e172c2

Browse files
yoyo930021claude
andcommitted
refactor: merge absolutize_image_srcs into render_markdown
render_markdown now accepts base_url and handles image src absolutization internally, reducing the call-site boilerplate from two chained calls to one. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 49d4ae8 commit 8e172c2

File tree

3 files changed

+14
-16
lines changed

3 files changed

+14
-16
lines changed

src/newsletter.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@ use crate::security;
44
use crate::shorturl::ShortUrlService;
55
use crate::AppState;
66

7-
/// Convert Markdown to HTML using comrak, with inline styles on `<img>` tags
8-
/// so images display properly in both previews and email clients.
9-
pub fn render_markdown(md: &str) -> String {
7+
/// Convert Markdown to HTML using comrak, absolutize relative image srcs,
8+
/// and add inline styles on `<img>` tags so images display properly in email clients.
9+
pub fn render_markdown(md: &str, base_url: &str) -> String {
1010
use comrak::{markdown_to_html, Options};
1111
let mut options = Options::default();
1212
options.extension.strikethrough = true;
1313
options.extension.table = true;
1414
options.extension.autolink = true;
1515
options.render.unsafe_ = true;
1616
let html = markdown_to_html(md, &options);
17-
style_images_for_email(&html)
17+
let html = style_images_for_email(&html);
18+
absolutize_image_srcs(&html, base_url)
1819
}
1920

2021
/// Rewrite relative `src` attributes (e.g. `/uploads/...`) to absolute URLs
@@ -204,10 +205,9 @@ pub async fn send_newsletter(
204205
.map_err(|e| e.to_string())?,
205206
};
206207

207-
// Render markdown → HTML, sanitize, then absolutize relative image paths for email clients
208-
let content_html = render_markdown(&markdown_content);
208+
// Render markdown → HTML (includes image src absolutization), then sanitize
209+
let content_html = render_markdown(&markdown_content, &state.config.base_url);
209210
let content_html = sanitize_html(&content_html);
210-
let content_html = absolutize_image_srcs(&content_html, &state.config.base_url);
211211

212212
// Update rendered_html
213213
sqlx::query("UPDATE newsletters SET rendered_html = $1, updated_at = NOW() WHERE id = $2")
@@ -523,28 +523,28 @@ mod tests {
523523

524524
#[test]
525525
fn test_render_markdown_basic() {
526-
let html = render_markdown("# Hello\n\nWorld");
526+
let html = render_markdown("# Hello\n\nWorld", "");
527527
assert!(html.contains("<h1>Hello</h1>"));
528528
assert!(html.contains("<p>World</p>"));
529529
}
530530

531531
#[test]
532532
fn test_render_markdown_links() {
533-
let html = render_markdown("[COSCUP](https://coscup.org)");
533+
let html = render_markdown("[COSCUP](https://coscup.org)", "");
534534
assert!(html.contains("href=\"https://coscup.org\""));
535535
assert!(html.contains("COSCUP"));
536536
}
537537

538538
#[test]
539539
fn test_render_markdown_table() {
540540
let md = "| A | B |\n|---|---|\n| 1 | 2 |";
541-
let html = render_markdown(md);
541+
let html = render_markdown(md, "");
542542
assert!(html.contains("<table>"));
543543
}
544544

545545
#[test]
546546
fn test_render_markdown_strikethrough() {
547-
let html = render_markdown("~~deleted~~");
547+
let html = render_markdown("~~deleted~~", "");
548548
assert!(html.contains("<del>deleted</del>"));
549549
}
550550

src/routes/archive.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,9 @@ pub async fn view(
5757

5858
let (title, markdown_content, template_id) = row;
5959

60-
// Render markdown to HTML, then sanitize for public web display
60+
// Render markdown to HTML (includes image src absolutization), then sanitize
6161
// (strips <script>, event handlers, and other dangerous elements)
62-
let content_html = newsletter::render_markdown(&markdown_content);
63-
let content_html = newsletter::absolutize_image_srcs(&content_html, &state.config.base_url);
62+
let content_html = newsletter::render_markdown(&markdown_content, &state.config.base_url);
6463
let content_html = newsletter::replace_recipient_name(&content_html, "訂閱者");
6564
let content_html = newsletter::sanitize_html(&content_html);
6665

src/routes/newsletter.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,7 @@ pub async fn preview(
303303
}
304304
};
305305

306-
let content_html = newsletter::render_markdown(&markdown_content);
307-
let content_html = newsletter::absolutize_image_srcs(&content_html, &state.config.base_url);
306+
let content_html = newsletter::render_markdown(&markdown_content, &state.config.base_url);
308307
let content_html = newsletter::replace_recipient_name(&content_html, "王小明");
309308

310309
// Use dummy values for preview

0 commit comments

Comments
 (0)