1use crate::asset_snapshot::AssetSnapshot;
23use crate::resolve::embed_renderer::{file_stem, html_escape_attr};
24use crate::resolve::title_params::TitleParams;
25
26#[allow(unused_variables)]
41pub fn synthesize_pdf_html(
42 params: &TitleParams,
43 src: &str,
44 assets: &AssetSnapshot,
45) -> String {
46 let mut data_url = String::from(src);
49 if let Some(q) = params.get("query") {
50 data_url.push('?');
51 data_url.push_str(q);
52 }
53 if let Some(f) = params.get("fragment") {
54 data_url.push('#');
55 data_url.push_str(f);
56 }
57
58 let data_width_attr = match params.get("data-width") {
59 Some(w) => format!(r#" data-width="{}""#, html_escape_attr(w)),
60 None => String::new(),
61 };
62
63 let html_width_attr = match params.get("width") {
64 Some(w) => format!(r#" width="{}""#, html_escape_attr(w)),
65 None => String::new(),
66 };
67
68 let html_height_attr = match params.get("height") {
69 Some(h) => format!(r#" height="{}""#, html_escape_attr(h)),
70 None => String::new(),
71 };
72
73 let name = file_stem(src);
74
75 format!(
78 "<object class=\"moss-embed\" data-type=\"pdf\"{} type=\"application/pdf\" data=\"{}\"{}{}><a href=\"{}\">Download {}</a></object>",
79 data_width_attr,
80 html_escape_attr(&data_url),
81 html_width_attr,
82 html_height_attr,
83 html_escape_attr(src),
84 html_escape_attr(&name),
85 )
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91
92 fn empty_snapshot() -> AssetSnapshot {
93 AssetSnapshot::new()
94 }
95
96 fn params_with(kvs: &[(&str, &str)]) -> TitleParams {
97 let mut p = TitleParams::default();
98 for (k, v) in kvs {
99 p.insert(*k, *v);
100 }
101 p
102 }
103
104 #[test]
105 fn pdf_basic_shape() {
106 let p = params_with(&[("kind", "pdf")]);
107 let out = synthesize_pdf_html(&p, "doc.pdf", &empty_snapshot());
108 assert!(
110 out.contains(r#"<object class="moss-embed" data-type="pdf""#),
111 "got: {}",
112 out
113 );
114 assert!(
115 out.contains(r#"type="application/pdf""#),
116 "got: {}",
117 out
118 );
119 assert!(out.contains(r#"data="doc.pdf""#), "got: {}", out);
121 assert!(
123 out.contains(r#"<a href="doc.pdf">Download doc</a>"#),
124 "got: {}",
125 out
126 );
127 }
128
129 #[test]
130 fn pdf_with_height_param() {
131 let p = params_with(&[("kind", "pdf"), ("width", "400px"), ("height", "800px")]);
132 let out = synthesize_pdf_html(&p, "doc.pdf", &empty_snapshot());
133 assert!(out.contains(r#"width="400px""#), "got: {}", out);
134 assert!(out.contains(r#"height="800px""#), "got: {}", out);
135 }
136
137 #[test]
138 fn pdf_escapes_url_specials() {
139 let p = params_with(&[("kind", "pdf")]);
140 let out = synthesize_pdf_html(
141 &p,
142 r#"file with "quotes".pdf"#,
143 &empty_snapshot(),
144 );
145 assert!(
150 out.contains(r#"data="file with "quotes".pdf""#),
151 "expected escaped data= attr, got: {}",
152 out
153 );
154 assert!(
155 out.contains(r#"href="file with "quotes".pdf""#),
156 "expected escaped href= attr, got: {}",
157 out
158 );
159 assert!(
161 !out.contains(r#"data="file with ""#),
162 "raw quote leaked into data= attr, got: {}",
163 out
164 );
165 }
166
167 #[test]
168 fn pdf_query_and_fragment_appended_to_url() {
169 let p = params_with(&[("kind", "pdf"), ("fragment", "page=5")]);
171 let out = synthesize_pdf_html(&p, "report.pdf", &empty_snapshot());
172 assert!(out.contains(r#"data="report.pdf#page=5""#), "got: {}", out);
173 assert!(out.contains(r#"<a href="report.pdf">"#), "got: {}", out);
176 }
177
178 #[test]
179 fn pdf_query_before_fragment() {
180 let p = params_with(&[
181 ("kind", "pdf"),
182 ("query", "version=2"),
183 ("fragment", "page=5"),
184 ]);
185 let out = synthesize_pdf_html(&p, "report.pdf", &empty_snapshot());
186 assert!(
188 out.contains(r#"data="report.pdf?version=2#page=5""#),
189 "got: {}",
190 out
191 );
192 }
193
194 #[test]
195 fn pdf_data_width_attr_when_present() {
196 let p = params_with(&[("kind", "pdf"), ("data-width", "wide")]);
197 let out = synthesize_pdf_html(&p, "doc.pdf", &empty_snapshot());
198 assert!(out.contains(r#"data-width="wide""#), "got: {}", out);
199 }
200
201 #[test]
202 fn pdf_no_data_width_when_absent() {
203 let p = params_with(&[("kind", "pdf")]);
204 let out = synthesize_pdf_html(&p, "doc.pdf", &empty_snapshot());
205 assert!(!out.contains("data-width"), "got: {}", out);
207 }
208
209 #[test]
210 fn pdf_stem_strips_directory_and_extension() {
211 let p = params_with(&[("kind", "pdf")]);
212 let out = synthesize_pdf_html(&p, "papers/2024/big-report.pdf", &empty_snapshot());
213 assert!(out.contains("Download big-report</a>"), "got: {}", out);
215 }
216}