Skip to content

Commit 1f6d982

Browse files
committed
update image loader
1 parent beaba6a commit 1f6d982

File tree

3 files changed

+72
-25
lines changed

3 files changed

+72
-25
lines changed

src/assets/publications/yao2024deft/deft.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
<div align="center">
3-
<img src="./deft.jpeg" width="200"
3+
<img src="./deft.jpeg" style="width: 10%;"
44
/>
55
</div>
66

src/components/PublicationDetails.jsx

+53-24
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,26 @@ import ReactMarkdown from "react-markdown";
1717
import remarkGfm from "remark-gfm";
1818
import rehypeRaw from "rehype-raw";
1919
import rehypeSanitize from "rehype-sanitize";
20+
import { defaultSchema } from "rehype-sanitize";
2021
import remarkBreaks from "remark-breaks";
2122
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
2223
import { coy as codeStyle } from "react-syntax-highlighter/dist/esm/styles/prism";
2324

2425
import { publications } from "../config/Publications";
2526

27+
import { getImage } from "../utils/ImageLoader";
28+
2629
import "@react-pdf-viewer/core/lib/styles/index.css";
2730
import "@react-pdf-viewer/default-layout/lib/styles/index.css";
2831

32+
const customSchema = {
33+
...defaultSchema,
34+
attributes: {
35+
...defaultSchema.attributes,
36+
img: [...(defaultSchema.attributes.img || []), ["style"]],
37+
},
38+
};
39+
2940
const PublicationDetails = React.forwardRef((props, ref) => {
3041
const { publicationName } = useParams();
3142
const publication = publications.find((pub) => pub.key === publicationName);
@@ -78,34 +89,50 @@ const PublicationDetails = React.forwardRef((props, ref) => {
7889
importBibFile();
7990
}, [publication.files.bib, publication.files.markdown]);
8091

81-
const imageContext = require.context(
82-
"../assets/publications/yu2024researchtown/",
83-
false,
84-
/\.(png|jpe?g|gif|svg|pdf)$/
85-
);
92+
const parseTitleAttributes = (title = "") => {
93+
const attrs = {};
94+
const parts = title.split(/\s+/);
95+
parts.forEach((pair) => {
96+
const [key, value] = pair.split("=");
97+
if (key && value) {
98+
attrs[key] = isNaN(value) ? value : Number(value);
99+
}
100+
});
101+
return attrs;
102+
};
86103

87-
const ImageRendererWithContext = ({ src, alt, title }) => {
88-
try {
89-
const localImageSrc = imageContext(`${src}`);
104+
const ImageRenderer = ({ src = "", alt = "", title = "", pub }) => {
105+
const imageSrc = getImage(pub, src);
106+
const styleAttrs = parseTitleAttributes(title);
107+
108+
if (!imageSrc) {
90109
return (
91110
<Figure className="text-center">
92-
<img
93-
src={localImageSrc}
94-
alt={alt}
95-
className="markdown-image"
96-
style={{ maxWidth: "100%", height: "auto" }}
97-
/>
98-
{title && (
99-
<Figure.Caption>
100-
<i>{title}</i>
101-
</Figure.Caption>
102-
)}
111+
<div style={{ padding: "1em", color: "red" }}>
112+
Image Not Found
113+
<code>
114+
{pub}/{src}
115+
</code>
116+
</div>
103117
</Figure>
104118
);
105-
} catch (err) {
106-
console.error(`Error loading image with context: ${src}`, err);
107-
return <span>Image not found: {src}</span>;
108119
}
120+
121+
return (
122+
<Figure className="text-center">
123+
<img
124+
src={imageSrc}
125+
alt={alt}
126+
className="markdown-image"
127+
style={{ maxWidth: "100%", height: "auto", ...styleAttrs }}
128+
/>
129+
{title && (
130+
<Figure.Caption>
131+
<i>{title}</i>
132+
</Figure.Caption>
133+
)}
134+
</Figure>
135+
);
109136
};
110137

111138
const TableRenderer = ({ children }) => (
@@ -326,10 +353,12 @@ const PublicationDetails = React.forwardRef((props, ref) => {
326353
]}
327354
rehypePlugins={[
328355
rehypeRaw, // Allows HTML in markdown
329-
rehypeSanitize, // Sanitizes HTML to prevent XSS
356+
[rehypeSanitize, customSchema], // Sanitizes HTML to prevent XSS
330357
]}
331358
components={{
332-
img: ImageRendererWithContext,
359+
img: (props) => (
360+
<ImageRenderer {...props} pub={publication.key} />
361+
),
333362
table: TableRenderer,
334363
code: CodeRenderer,
335364
}}

src/utils/ImageLoader.jsx

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
const ctx = require.context(
2+
"../assets/publications",
3+
true,
4+
/\.(png|jpe?g|gif|svg)$/
5+
);
6+
7+
const imageMap = {};
8+
9+
ctx.keys().forEach((key) => {
10+
const cleaned = key.replace(/^.\//, "");
11+
imageMap[cleaned] = ctx(key);
12+
});
13+
14+
export const getImage = (pub, src) => {
15+
const normalizedSrc = src.replace(/^\.?\//, "");
16+
const key = `${pub}/${normalizedSrc}`;
17+
return imageMap[key] || null;
18+
};

0 commit comments

Comments
 (0)