Skip to content

Commit a8ffa58

Browse files
authored
🎞 [src] image URLs in /posts (#52)
* 🎞 [src] image URLs in /posts * fixes for code review
1 parent 707ef9b commit a8ffa58

File tree

2 files changed

+145
-5
lines changed

2 files changed

+145
-5
lines changed

β€Žsrc/main.rsβ€Ž

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,32 @@ fn process_file(file_name: &str, dest_dir: &str) {
101101
// Note: html5ever may report parsing errors, but they typically don't affect extraction
102102

103103
let post_data = extract_post_data(&dom.document);
104-
let markdown_content = generate_markdown(&post_data);
105104

106-
// Generate output filename
105+
// Generate output filename and extract date prefix
107106
let input_filename = file_path
108107
.file_stem()
109108
.unwrap_or_else(|| panic!("Failed to extract filename stem from: {}", file_name))
110109
.to_str()
111110
.unwrap_or_else(|| panic!("Filename contains invalid UTF-8: {}", file_name));
112-
let output_filename = format!("{}.md", format_filename_date(input_filename));
111+
let formatted_name = format_filename_date(input_filename);
112+
let output_filename = format!("{}.md", formatted_name);
113+
114+
// Extract date prefix (YYYY-MM-DD) from formatted filename
115+
// Check if it matches the expected format: YYYY-MM-DD
116+
let date_prefix = if formatted_name.len() >= 10
117+
&& formatted_name.as_bytes().get(4) == Some(&b'-')
118+
&& formatted_name.as_bytes().get(7) == Some(&b'-')
119+
{
120+
&formatted_name[..10]
121+
} else {
122+
eprintln!(
123+
"Warning: Could not extract date prefix from filename '{}' - images will use empty date prefix",
124+
formatted_name
125+
);
126+
""
127+
};
128+
129+
let markdown_content = generate_markdown(&post_data, date_prefix);
113130
let output_path = Path::new(dest_dir).join(output_filename);
114131

115132
// Write markdown file

β€Žsrc/markdown.rsβ€Ž

Lines changed: 125 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,32 @@
22
33
use crate::models::PostData;
44
use crate::utils::{clean_title, escape_toml_string};
5+
use std::path::Path;
6+
7+
/// Transform an image path to /posts/YYYY-MM-DD-filename.ext format
8+
///
9+
/// # Arguments
10+
/// * `image_path` - The original image path from the HTML
11+
/// * `date_prefix` - The date prefix (YYYY-MM-DD) from the post filename
12+
///
13+
/// # Returns
14+
/// The transformed path in the format /posts/YYYY-MM-DD-filename.ext
15+
fn transform_image_path(image_path: &str, date_prefix: &str) -> String {
16+
// Extract just the filename from the path
17+
let filename = Path::new(image_path)
18+
.file_name()
19+
.and_then(|name| name.to_str())
20+
.unwrap_or(image_path);
21+
22+
format!("/posts/{}-{}", date_prefix, filename)
23+
}
524

625
/// Generate markdown from post data
7-
pub fn generate_markdown(post_data: &PostData) -> String {
26+
///
27+
/// # Arguments
28+
/// * `post_data` - The post data to generate markdown from
29+
/// * `date_prefix` - The date prefix (YYYY-MM-DD) for image paths
30+
pub fn generate_markdown(post_data: &PostData, date_prefix: &str) -> String {
831
let mut markdown = String::new();
932

1033
// Generate TOML front matter
@@ -101,7 +124,8 @@ pub fn generate_markdown(post_data: &PostData) -> String {
101124
if !post_data.images.is_empty() {
102125
markdown.push_str("## Images\n\n");
103126
for image_url in &post_data.images {
104-
markdown.push_str(&format!("![Image]({})\n\n", image_url));
127+
let transformed_path = transform_image_path(image_url, date_prefix);
128+
markdown.push_str(&format!("![Image]({})\n\n", transformed_path));
105129
}
106130
}
107131

@@ -147,3 +171,102 @@ pub fn generate_markdown(post_data: &PostData) -> String {
147171

148172
format!("{}\n", markdown.trim_end())
149173
}
174+
175+
#[cfg(test)]
176+
mod tests {
177+
use super::*;
178+
179+
#[test]
180+
fn test_transform_image_path_standard() {
181+
assert_eq!(
182+
transform_image_path("../Photos/Photos from posts/pretty/image.jpg", "2011-11-04"),
183+
"/posts/2011-11-04-image.jpg"
184+
);
185+
}
186+
187+
#[test]
188+
fn test_transform_image_path_complex_path() {
189+
assert_eq!(
190+
transform_image_path(
191+
"../Photos/Photos%20from%20posts/Vasquez%20Rocks/183zw3ui6c0yq.jpg",
192+
"2012-11-01"
193+
),
194+
"/posts/2012-11-01-183zw3ui6c0yq.jpg"
195+
);
196+
}
197+
198+
#[test]
199+
fn test_transform_image_path_simple_filename() {
200+
assert_eq!(
201+
transform_image_path("image.jpg", "2013-07-13"),
202+
"/posts/2013-07-13-image.jpg"
203+
);
204+
}
205+
206+
#[test]
207+
fn test_transform_image_path_empty_date() {
208+
assert_eq!(transform_image_path("image.jpg", ""), "/posts/-image.jpg");
209+
}
210+
211+
#[test]
212+
fn test_transform_image_path_url() {
213+
assert_eq!(
214+
transform_image_path("http://example.com/path/image.png", "2013-07-13"),
215+
"/posts/2013-07-13-image.png"
216+
);
217+
}
218+
219+
#[test]
220+
fn test_transform_image_path_windows_path() {
221+
// On non-Windows systems, Path won't recognize Windows separators
222+
// and will treat the entire string as a filename
223+
#[cfg(windows)]
224+
{
225+
assert_eq!(
226+
transform_image_path("C:\\Photos\\image.jpg", "2015-01-01"),
227+
"/posts/2015-01-01-image.jpg"
228+
);
229+
}
230+
#[cfg(not(windows))]
231+
{
232+
// On Unix systems, backslashes are valid filename characters, not separators
233+
assert_eq!(
234+
transform_image_path("C:\\Photos\\image.jpg", "2015-01-01"),
235+
"/posts/2015-01-01-C:\\Photos\\image.jpg"
236+
);
237+
}
238+
}
239+
240+
#[test]
241+
fn test_transform_image_path_absolute_path() {
242+
assert_eq!(
243+
transform_image_path("/var/data/photos/image.jpg", "2016-06-15"),
244+
"/posts/2016-06-15-image.jpg"
245+
);
246+
}
247+
248+
#[test]
249+
fn test_transform_image_path_special_chars() {
250+
assert_eq!(
251+
transform_image_path("../Photos/my photo (1).jpg", "2017-03-20"),
252+
"/posts/2017-03-20-my photo (1).jpg"
253+
);
254+
}
255+
256+
#[test]
257+
fn test_transform_image_path_no_extension() {
258+
assert_eq!(
259+
transform_image_path("../Photos/image", "2018-12-25"),
260+
"/posts/2018-12-25-image"
261+
);
262+
}
263+
264+
#[test]
265+
fn test_transform_image_path_fallback_when_no_filename() {
266+
// Edge case: if Path can't extract a filename, use original
267+
assert_eq!(
268+
transform_image_path("..", "2019-01-01"),
269+
"/posts/2019-01-01-.."
270+
);
271+
}
272+
}

0 commit comments

Comments
Β (0)