@@ -17,15 +17,26 @@ import ReactMarkdown from "react-markdown";
17
17
import remarkGfm from "remark-gfm" ;
18
18
import rehypeRaw from "rehype-raw" ;
19
19
import rehypeSanitize from "rehype-sanitize" ;
20
+ import { defaultSchema } from "rehype-sanitize" ;
20
21
import remarkBreaks from "remark-breaks" ;
21
22
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter" ;
22
23
import { coy as codeStyle } from "react-syntax-highlighter/dist/esm/styles/prism" ;
23
24
24
25
import { publications } from "../config/Publications" ;
25
26
27
+ import { getImage } from "../utils/ImageLoader" ;
28
+
26
29
import "@react-pdf-viewer/core/lib/styles/index.css" ;
27
30
import "@react-pdf-viewer/default-layout/lib/styles/index.css" ;
28
31
32
+ const customSchema = {
33
+ ...defaultSchema ,
34
+ attributes : {
35
+ ...defaultSchema . attributes ,
36
+ img : [ ...( defaultSchema . attributes . img || [ ] ) , [ "style" ] ] ,
37
+ } ,
38
+ } ;
39
+
29
40
const PublicationDetails = React . forwardRef ( ( props , ref ) => {
30
41
const { publicationName } = useParams ( ) ;
31
42
const publication = publications . find ( ( pub ) => pub . key === publicationName ) ;
@@ -78,34 +89,50 @@ const PublicationDetails = React.forwardRef((props, ref) => {
78
89
importBibFile ( ) ;
79
90
} , [ publication . files . bib , publication . files . markdown ] ) ;
80
91
81
- const imageContext = require . context (
82
- "../assets/publications/yu2024researchtown/" ,
83
- false ,
84
- / \. ( p n g | j p e ? g | g i f | s v g | p d f ) $ /
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
+ } ;
86
103
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 ) {
90
109
return (
91
110
< 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 >
103
117
</ Figure >
104
118
) ;
105
- } catch ( err ) {
106
- console . error ( `Error loading image with context: ${ src } ` , err ) ;
107
- return < span > Image not found: { src } </ span > ;
108
119
}
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
+ ) ;
109
136
} ;
110
137
111
138
const TableRenderer = ( { children } ) => (
@@ -326,10 +353,12 @@ const PublicationDetails = React.forwardRef((props, ref) => {
326
353
] }
327
354
rehypePlugins = { [
328
355
rehypeRaw , // Allows HTML in markdown
329
- rehypeSanitize , // Sanitizes HTML to prevent XSS
356
+ [ rehypeSanitize , customSchema ] , // Sanitizes HTML to prevent XSS
330
357
] }
331
358
components = { {
332
- img : ImageRendererWithContext ,
359
+ img : ( props ) => (
360
+ < ImageRenderer { ...props } pub = { publication . key } />
361
+ ) ,
333
362
table : TableRenderer ,
334
363
code : CodeRenderer ,
335
364
} }
0 commit comments