@@ -76,7 +76,7 @@ export function orcidLoader(options: { orcid: string }): Loader {
7676 authors : z . string ( ) ,
7777 firstAuthor : z . string ( ) ,
7878 date : z . string ( ) ,
79- year : z . number ( ) ,
79+ year : z . number ( ) . optional ( ) ,
8080 journal : z . string ( ) ,
8181 europePmc : z . string ( ) . optional ( ) ,
8282 isPreprint : z . boolean ( ) ,
@@ -148,16 +148,45 @@ export function orcidLoader(options: { orcid: string }): Loader {
148148 }
149149
150150 const journalMatch = workXml . match ( / < w o r k : j o u r n a l - t i t l e > ( .* ?) < \/ w o r k : j o u r n a l - t i t l e > / ) ;
151- const journal = journalMatch ?. [ 1 ] || 'Unknown Journal' ;
151+ let journal = journalMatch ?. [ 1 ] || 'Unknown Journal' ;
152152
153153 const yearMatch = workXml . match ( / < c o m m o n : y e a r > ( .* ?) < \/ c o m m o n : y e a r > / ) ;
154154 const monthMatch = workXml . match ( / < c o m m o n : m o n t h > ( .* ?) < \/ c o m m o n : m o n t h > / ) ;
155155 const dayMatch = workXml . match ( / < c o m m o n : d a y > ( .* ?) < \/ c o m m o n : d a y > / ) ;
156156
157- const year = yearMatch ?. [ 1 ] ? parseInt ( yearMatch [ 1 ] ) : new Date ( ) . getFullYear ( ) ;
157+ // Fallback: try to extract year from citation if structured date is missing
158+ let year = yearMatch ?. [ 1 ] ? parseInt ( yearMatch [ 1 ] ) : null ;
159+
160+ if ( ! year ) {
161+ const citationMatch = workXml . match ( / < w o r k : c i t a t i o n - v a l u e > ( .* ?) < \/ w o r k : c i t a t i o n - v a l u e > / s) ;
162+ if ( citationMatch ?. [ 1 ] ) {
163+ const citation = citationMatch [ 1 ] ;
164+ // Try to extract 4-digit year from citation (look for years like 2012, 1999, etc.)
165+ const citationYearMatch = citation . match ( / \b ( 1 9 | 2 0 ) \d { 2 } \b / ) ;
166+ if ( citationYearMatch ?. [ 0 ] ) {
167+ year = parseInt ( citationYearMatch [ 0 ] ) ;
168+ logger . info ( `Extracted year ${ year } from citation for: ${ title } ` ) ;
169+
170+ // Also try to extract journal from citation if not found
171+ if ( journal === 'Unknown Journal' ) {
172+ // Look for text within <i>...</i> or <i>...</i>
173+ const journalFromCitationMatch = citation . match ( / (?: < i > | & l t ; i & g t ; ) ( .* ?) (?: < \/ i > | & l t ; \/ i & g t ; ) / ) ;
174+ if ( journalFromCitationMatch ?. [ 1 ] ) {
175+ journal = journalFromCitationMatch [ 1 ] ;
176+ }
177+ }
178+ }
179+ }
180+ }
181+
182+ // If no year found, log warning but continue
183+ if ( ! year ) {
184+ logger . warn ( `No year found for publication: "${ title } "` ) ;
185+ }
186+
158187 const month = monthMatch ?. [ 1 ] ?. padStart ( 2 , '0' ) || '01' ;
159188 const day = dayMatch ?. [ 1 ] ?. padStart ( 2 , '0' ) || '01' ;
160- const dateString = `${ year } -${ month } -${ day } ` ;
189+ const dateString = year ? `${ year } -${ month } -${ day } ` : '' ;
161190
162191 const doiMatch = workXml . match ( / < c o m m o n : e x t e r n a l - i d - t y p e > d o i < \/ c o m m o n : e x t e r n a l - i d - t y p e > [ \s \S ] * ?< c o m m o n : e x t e r n a l - i d - v a l u e > ( .* ?) < \/ c o m m o n : e x t e r n a l - i d - v a l u e > / ) ;
163192 const pmidMatch = workXml . match ( / < c o m m o n : e x t e r n a l - i d - t y p e > p m i d < \/ c o m m o n : e x t e r n a l - i d - t y p e > [ \s \S ] * ?< c o m m o n : e x t e r n a l - i d - v a l u e > ( .* ?) < \/ c o m m o n : e x t e r n a l - i d - v a l u e > / ) ;
@@ -213,8 +242,17 @@ export function orcidLoader(options: { orcid: string }): Loader {
213242 logger . info ( `Successfully processed ${ allPublications . length } publications from ORCID` ) ;
214243
215244 allPublications . sort ( ( a , b ) => {
216- if ( a . year !== b . year ) {
217- return b . year - a . year ;
245+ // Publications without year go to the end
246+ if ( ! a . year && ! b . year ) {
247+ return b . date . localeCompare ( a . date ) ;
248+ }
249+ if ( ! a . year ) return 1 ;
250+ if ( ! b . year ) return - 1 ;
251+
252+ // Both years are defined at this point
253+ const yearDiff = b . year - a . year ;
254+ if ( yearDiff !== 0 ) {
255+ return yearDiff ;
218256 }
219257 return b . date . localeCompare ( a . date ) ;
220258 } ) ;
0 commit comments