(git:374b731)
Loading...
Searching...
No Matches
reference_manager.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief provides a uniform framework to add references to CP2K
10!> cite and output these
11!> \note
12!> references need to be input using the ISI citation format, because it is
13!> uniform, easy to parse, and can be exported for example from web of science
14!> furthermore, it can be easily converted to and from using the bibutils tools
15!> a collection of easy to use conversion programs that can be found at
16!> http://www.scripps.edu/~cdputnam/software/bibutils/
17!> by Chris Putnam
18!>
19!> see thebibliography.F on how to add references easily
20!> \par History
21!> 08.2007 [Joost VandeVondele]
22!> \author Joost VandeVondele
23! **************************************************************************************************
28 USE util, ONLY: sort
29#include "../base/base_uses.f90"
30
31 IMPLICIT NONE
32
35
36 INTEGER, PUBLIC, PARAMETER :: print_format_isi = 101, &
39
40 PRIVATE
41
42 CHARACTER(len=*), PARAMETER, PRIVATE :: modulen = 'reference_manager'
43
44 ! maximum number of reference that can be added
45 INTEGER, PARAMETER :: max_reference = 1024
46
47 ! storage of a reference
48 INTEGER, PARAMETER :: doi_length = 128
49 INTEGER, PARAMETER :: isi_length = 128
50
51 ! the way we store a reference, should remain fully private
52! **************************************************************************************************
53 TYPE reference_type
54 PRIVATE
55 ! the reference in a format as returned by the web of science
56 CHARACTER(LEN=ISI_length), DIMENSION(:), POINTER :: isi_record => null()
57 ! the doi only, i.e. without "https://doi.org/"
58 CHARACTER(LEN=doi_length) :: doi = ""
59 ! has this reference been cited in the program run
60 LOGICAL :: is_cited = .false.
61 ! this is a citation key for output in the reference lists
62 CHARACTER(LEN=ISI_length) :: citation_key = ""
63 END TYPE reference_type
64
65 ! useful to build arrays
66! **************************************************************************************************
67 TYPE reference_p_type
68 TYPE(reference_type), POINTER :: ref => null()
69 END TYPE
70
71 ! thebibliography
72 INTEGER, SAVE :: nbib = 0
73 TYPE(reference_p_type), DIMENSION(max_reference) :: thebib
74
75 PUBLIC :: add_reference, & ! use this one only in bibliography.F
76 remove_all_references, & ! use only in f77_interface.F
77 get_citation_key ! a string key describing the reference (e.g. Kohn1965b)
78
79CONTAINS
80
81! **************************************************************************************************
82!> \brief marks a given reference as cited.
83!> \param key citation key as returned from add_reference
84!> \par History
85!> XX.2007 created [ ]
86! **************************************************************************************************
87 SUBROUTINE cite_reference(key)
88 INTEGER, INTENT(IN) :: key
89
90 IF (key < 1 .OR. key > max_reference) cpabort("citation key out of range")
91
92 ! set as cited
93 thebib(key)%ref%is_cited = .true.
94
95 END SUBROUTINE
96
97! **************************************************************************************************
98!> \brief Checks for each reference if any mpi-rank has marked it for citation.
99!> \param para_env ...
100!> \par History
101!> 12.2013 created [Ole Schuett]
102! **************************************************************************************************
103 SUBROUTINE collect_citations_from_ranks(para_env)
104 TYPE(mp_para_env_type), INTENT(IN) :: para_env
105
106 INTEGER :: i, t
107
108 DO i = 1, nbib
109 t = 0
110 IF (thebib(i)%ref%is_cited) t = 1
111 CALL para_env%max(t)
112 thebib(i)%ref%is_cited = (t == 1)
113 END DO
114
115 END SUBROUTINE collect_citations_from_ranks
116
117! **************************************************************************************************
118!> \brief add a reference to the bibliography
119!> \param key output, this handle is needed to cite this reference later
120!> \param ISI_record ...
121!> \param DOI ...
122!> \par History
123!> 08.2007 created [Joost VandeVondele]
124!> \note
125!> - see bibliography.F for it use.
126!> - the ISI record is space sensitive, in particular the first three characters need to be blank
127!> or contain a key indicating the record type. See the header of this file for tools
128!> that can convert e.g. bibtex or endnote files to the ISI format
129!> - DOI: provide the DOI without a link. The link will be automatically created as needed.
130! **************************************************************************************************
131 SUBROUTINE add_reference(key, ISI_record, DOI)
132 INTEGER, INTENT(OUT) :: key
133 CHARACTER(LEN=*), DIMENSION(:), INTENT(IN) :: isi_record
134 CHARACTER(LEN=*), INTENT(IN) :: doi
135
136 CHARACTER :: tmp
137 CHARACTER(LEN=ISI_length) :: author, citation_key, key_a, key_b, year
138 INTEGER :: commaloc, i, ires, line, match, mylen, &
139 nlines
140
141 IF (nbib + 1 > max_reference) cpabort("increase max_reference")
142 nbib = nbib + 1
143 key = nbib
144
145 ! initialize reference to zero
146 ALLOCATE (thebib(key)%ref)
147 NULLIFY (thebib(key)%ref%ISI_record)
148 thebib(key)%ref%DOI = ""
149 thebib(key)%ref%is_cited = .false.
150
151 ! Assign DOI
152 thebib(key)%ref%DOI = doi
153
154 ! Assign ISI_record
155 nlines = SIZE(isi_record, 1)
156 ALLOCATE (thebib(key)%ref%ISI_record(nlines))
157 thebib(key)%ref%ISI_record = isi_record
158
159 ! construct a citation_key
160 line = 1
161 author = get_next_author(thebib(key)%ref%ISI_record, line)
162 commaloc = index(author, ',')
163 IF (commaloc .GT. 0) author = author(1:commaloc - 1)
164 cpassert(len_trim(author) > 0)
165 year = get_year(thebib(key)%ref%ISI_record)
166 cpassert(len_trim(year) == 4)
167 citation_key = trim(author)//trim(year)
168
169 ! avoid special characters in names, just remove them
170 mylen = len_trim(citation_key)
171 ires = 0
172 DO i = 1, mylen
173 IF (index("0123456789thequickbrownfoxjumpsoverthelazydogTHEQUICKBROWNFOXJUMPSOVERTHELAZYDOG", citation_key(i:i)) .NE. 0) THEN
174 ires = ires + 1
175 tmp = citation_key(i:i)
176 citation_key(ires:ires) = tmp
177 END IF
178 END DO
179 citation_key(ires + 1:) = ""
180 cpassert(len_trim(citation_key) > 4) ! At least one character of the author should be left.
181
182 ! avoid duplicates, search through the list for matches (case-insensitive)
183 mylen = len_trim(citation_key)
184 key_a = citation_key(1:mylen)
185 CALL uppercase(key_a)
186 match = 0
187 DO i = 1, nbib - 1
188 key_b = thebib(i)%ref%citation_key(1:mylen)
189 CALL uppercase(key_b)
190 IF (key_a == key_b) match = match + 1
191 END DO
192 IF (match > 0) citation_key = citation_key(1:mylen)//char(ichar('a') + match)
193
194 ! finally store it
195 thebib(key)%ref%citation_key = citation_key
196
197 END SUBROUTINE add_reference
198
199! **************************************************************************************************
200!> \brief deallocate the bibliography
201!> \par History
202!> 08.2007 Joost VandeVondele [ ]
203! **************************************************************************************************
205 INTEGER :: i
206
207 DO i = 1, nbib
208 IF (ASSOCIATED(thebib(i)%ref%ISI_record)) DEALLOCATE (thebib(i)%ref%ISI_record)
209 thebib(i)%ref%DOI = ""
210
211 DEALLOCATE (thebib(i)%ref)
212 END DO
213 END SUBROUTINE remove_all_references
214!****f* reference_manager/print_all_references *
215
216! **************************************************************************************************
217!> \brief printout of all references in a specific format
218!> optionally printing only those that are actually cited
219!> during program execution
220!> \param cited_only print only those marked as cited
221!> \param sorted sort entries most recent first according to the date,
222!> otherways sort with respect to key
223!> \param FORMAT see module parameters print_format_XXXXXXXXX
224!> \param unit ...
225!> \param list optionally, output a sub-list only
226!> \par History
227!> 08.2007 Joost VandeVondele [ ]
228! **************************************************************************************************
229 SUBROUTINE print_all_references(cited_only, sorted, FORMAT, unit, list)
230 LOGICAL, INTENT(IN) :: cited_only, sorted
231 INTEGER, INTENT(IN) :: format, unit
232 INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: list
233
234 INTEGER :: i, irecord, nref
235 INTEGER, ALLOCATABLE, DIMENSION(:) :: indx, irank, ival
236
237! we'll sort the references wrt to the publication year
238! the most recent first, publications without a year get last
239
240 IF (PRESENT(list)) THEN
241 nref = SIZE(list)
242 ELSE
243 nref = nbib
244 END IF
245
246 ALLOCATE (ival(nref))
247 ALLOCATE (irank(nref))
248 ALLOCATE (indx(nref))
249
250 IF (PRESENT(list)) THEN
251 indx(:) = list
252 ELSE
253 DO i = 1, nref
254 indx(i) = i
255 END DO
256 END IF
257
258 DO i = 1, nref
259 irank(i) = i
260 END DO
261
262 IF (sorted) THEN
263 DO i = 1, nref
264 ival(i) = -get_epoch(thebib(indx(i))%ref%ISI_record)
265 END DO
266 ELSE
267 DO i = 1, nref
268 ival(i) = indx(i)
269 END DO
270 END IF
271 CALL sort(ival, nref, irank)
272
273 SELECT CASE (format)
274 CASE (print_format_isi)
276 WRITE (unit, '(A)') ""
277 CASE (print_format_html)
278 WRITE (unit, '(A)') '<TABLE border="1">'
279 CASE DEFAULT
280 cpabort("print_reference: wrong format")
281 END SELECT
282
283 DO i = 1, nref
284 irecord = indx(irank(i))
285 IF (.NOT. cited_only .OR. thebib(irecord)%ref%is_cited) THEN
286 SELECT CASE (format)
287 CASE (print_format_isi)
289 CASE (print_format_html)
290 WRITE (unit, '(A)') "<TR><TD>"//'['//trim(thebib(irecord)%ref%citation_key)//']'//"</TD><TD>"
291 CASE DEFAULT
292 cpabort("print_reference: wrong format")
293 END SELECT
294
295 CALL print_reference(irecord, FORMAT, unit)
296
297 SELECT CASE (format)
298 CASE (print_format_isi)
300 WRITE (unit, '(A)') ""
301 CASE (print_format_html)
302 WRITE (unit, '(A)') '</TD></TR>'
303 CASE DEFAULT
304 cpabort("print_reference: wrong format")
305 END SELECT
306 END IF
307 END DO
308 IF (FORMAT .EQ. print_format_html) THEN
309 WRITE (unit, '(A)') "</TABLE>"
310 END IF
311
312 END SUBROUTINE print_all_references
313!****f* reference_manager/print_reference *
314
315! **************************************************************************************************
316!> \brief printout of a specified reference to a given unit in a selectable format
317!> \param key as returned from add_reference
318!> \param FORMAT see module parameters print_format_XXXXXXXXX
319!> \param unit ...
320!> \par History
321!> 08.2007 Joost VandeVondele [ ]
322! **************************************************************************************************
323 SUBROUTINE print_reference(key, FORMAT, unit)
324 INTEGER, INTENT(IN) :: key, format, unit
325
326 INTEGER :: i
327
328 IF (key < 1 .OR. key > max_reference) cpabort("citation key out of range")
329
330 SELECT CASE (format)
331 CASE (print_format_isi)
332 DO i = 1, SIZE(thebib(key)%ref%ISI_record)
333 WRITE (unit, '(T2,A)') trim(thebib(key)%ref%ISI_record(i))
334 END DO
336 CALL print_reference_journal(key, unit)
337 CASE (print_format_html)
338 CALL print_reference_html(key, unit)
339 CASE DEFAULT
340 cpabort("print_reference: wrong format")
341 END SELECT
342 END SUBROUTINE print_reference
343
344! **************************************************************************************************
345!> \brief prints a reference in a journal style citation format,
346!> adding also a DOI link, which is convenient
347!> \param key ...
348!> \param unit ...
349!> \par History
350!> 08.2007 created [Joost VandeVondele]
351! **************************************************************************************************
352 SUBROUTINE print_reference_journal(key, unit)
353 INTEGER, INTENT(IN) :: key, unit
354
355 CHARACTER(LEN=4*ISI_length) :: journal
356 CHARACTER(LEN=ISI_length) :: author, title
357 INTEGER :: iauthor, ipos_line, ititle, line
358
359! write the author list
360
361 WRITE (unit, '(T2,A)', advance="NO") ""
362 line = 1; iauthor = 0; ipos_line = 2
363 author = get_next_author(thebib(key)%ref%ISI_record, line)
364 DO WHILE (author .NE. "")
365 iauthor = iauthor + 1
366 IF (ipos_line + len_trim(author) > 71) THEN
367 WRITE (unit, '(A)') ";"
368 WRITE (unit, '(T2,A)', advance="NO") ""
369 ipos_line = 2
370 ELSE
371 IF (iauthor .NE. 1) WRITE (unit, '(A)', advance="NO") "; "
372 ipos_line = ipos_line + 2
373 END IF
374 WRITE (unit, '(A)', advance="NO") trim(author)
375 ipos_line = ipos_line + len_trim(author)
376 author = get_next_author(thebib(key)%ref%ISI_record, line)
377 END DO
378 IF (iauthor > 0) THEN
379 WRITE (unit, '(A)', advance="NO") ". "
380 ipos_line = ipos_line + 2
381 END IF
382
383 ! Journal, volume (issue), pages (year).
384 journal = trim(get_source(thebib(key)%ref%ISI_record))
385 IF (get_volume(thebib(key)%ref%ISI_record) .NE. "") THEN
386 journal = trim(journal)//", "//get_volume(thebib(key)%ref%ISI_record)
387 IF (get_issue(thebib(key)%ref%ISI_record) .NE. "") THEN
388 journal = trim(journal)//" ("//trim(get_issue(thebib(key)%ref%ISI_record))//")"
389 END IF
390 END IF
391 journal = trim(journal)//", "//get_pages(thebib(key)%ref%ISI_record)
392 IF (get_year(thebib(key)%ref%ISI_record) .NE. "") THEN
393 journal = trim(journal)//" ("//trim(get_year(thebib(key)%ref%ISI_record))//")."
394 END IF
395 IF (ipos_line + len_trim(journal) > 71) THEN
396 WRITE (unit, '(A)') ""
397 WRITE (unit, '(T2,A)', advance="NO") ""
398 ipos_line = 2
399 END IF
400 IF (ipos_line + len_trim(journal) > 71) THEN
401 WRITE (unit, '(A)') trim(journal(1:69))
402 WRITE (unit, '(A)', advance="NO") trim(journal(69:))
403 ELSE
404 WRITE (unit, '(A)', advance="NO") trim(journal)
405 END IF
406
407 WRITE (unit, '(T2,A)') ""
408 ! Title
409 line = 1; ititle = 0
410 title = get_next_title(thebib(key)%ref%ISI_record, line)
411 DO WHILE (title .NE. "")
412 ititle = ititle + 1
413 IF (ititle .NE. 1) WRITE (unit, '(A)') ""
414 WRITE (unit, '(T2,A)', advance="NO") trim(title)
415 title = get_next_title(thebib(key)%ref%ISI_record, line)
416 END DO
417 IF (ititle > 0) WRITE (unit, '(A)') "."
418
419 ! DOI
420 IF (thebib(key)%ref%DOI .NE. "") THEN
421 WRITE (unit, '(T2,A)') "https://doi.org/"//trim(thebib(key)%ref%DOI)
422 END IF
423
424 END SUBROUTINE print_reference_journal
425
426! **************************************************************************************************
427!> \brief prints a reference in a journal style citation format,
428!> adding 'beautifying' html tags, and a link to the journal
429!> using the DOI
430!> \param key ...
431!> \param unit ...
432!> \par History
433!> 08.2007 created [Joost VandeVondele]
434! **************************************************************************************************
435 SUBROUTINE print_reference_html(key, unit)
436 INTEGER, INTENT(IN) :: key, unit
437
438 CHARACTER(LEN=ISI_length) :: author, title
439 CHARACTER(LEN=ISI_length*4) :: journal
440 INTEGER :: iauthor, ititle, line
441
442! write the author list
443
444 WRITE (unit, '(T2,A,I0,A)', advance="NO") '<A NAME="reference_', key, '">'
445 line = 1; iauthor = 0
446 author = get_next_author(thebib(key)%ref%ISI_record, line)
447 DO WHILE (author .NE. "")
448 iauthor = iauthor + 1
449 IF (iauthor .NE. 1) WRITE (unit, '(A)', advance="NO") "; "
450 WRITE (unit, '(A)', advance="NO") trim(author)
451 author = get_next_author(thebib(key)%ref%ISI_record, line)
452 END DO
453 IF (iauthor > 0) WRITE (unit, '(A)') ".<br>"
454
455 ! DOI
456 IF (thebib(key)%ref%DOI .NE. "") THEN
457 WRITE (unit, '(T2,A)', advance="NO") '<A HREF="https://doi.org/'//trim(thebib(key)%ref%DOI)//'">'
458 END IF
459 ! Journal, volume (issue), pages (year).
460 journal = trim(get_source(thebib(key)%ref%ISI_record))
461 IF (get_volume(thebib(key)%ref%ISI_record) .NE. "") THEN
462 journal = trim(journal)//", "//get_volume(thebib(key)%ref%ISI_record)
463 IF (get_issue(thebib(key)%ref%ISI_record) .NE. "") THEN
464 journal = trim(journal)//" ("//trim(get_issue(thebib(key)%ref%ISI_record))//")"
465 END IF
466 END IF
467 journal = trim(journal)//", "//get_pages(thebib(key)%ref%ISI_record)
468 IF (get_year(thebib(key)%ref%ISI_record) .NE. "") THEN
469 journal = trim(journal)//" ("//trim(get_year(thebib(key)%ref%ISI_record))//")."
470 END IF
471 WRITE (unit, '(A)', advance="NO") trim(journal)
472 IF (thebib(key)%ref%DOI .NE. "") THEN
473 WRITE (unit, '(A)', advance="NO") '</A>'
474 END IF
475 WRITE (unit, '(A)') "</A><br>"
476
477 ! Title
478 line = 1; ititle = 0
479 title = get_next_title(thebib(key)%ref%ISI_record, line)
480 DO WHILE (title .NE. "")
481 ititle = ititle + 1
482 IF (ititle .NE. 1) WRITE (unit, '(A)') ""
483 WRITE (unit, '(T2,A)', advance="NO") trim(title)
484 title = get_next_title(thebib(key)%ref%ISI_record, line)
485 END DO
486 IF (ititle > 0) WRITE (unit, '(A)') "."
487
488 END SUBROUTINE print_reference_html
489
490! **************************************************************************************************
491!> \brief returns the corresponding fields from an ISI record.
492!> returns an empty string if the field can not be found
493!> iline_start should be initialized to 1 to obtain the first matching entry
494!> on return it is updated, so that successive calls give successive fields
495!> \param ISI_record ...
496!> \param iline_start ...
497!> \return ...
498!> \par History
499!> 08.2007 created [Joost VandeVondele]
500! **************************************************************************************************
501 FUNCTION get_next_author(ISI_record, iline_start) RESULT(res)
502 CHARACTER(LEN=ISI_length), DIMENSION(:), &
503 INTENT(IN) :: isi_record
504 INTEGER, INTENT(INOUT) :: iline_start
505 CHARACTER(LEN=ISI_length) :: res
506
507 INTEGER :: i, n
508 LOGICAL :: in_au_section
509
510 res = ""
511 in_au_section = .false.
512 n = SIZE(isi_record, 1)
513 IF (iline_start > n) RETURN
514 line_loop: DO i = 1, n
515 IF (isi_record(i) (1:3) == "AU ") in_au_section = .true.
516 IF (in_au_section .AND. (isi_record(i) (1:3) /= "AU " .AND. isi_record(i) (1:3) /= " ")) in_au_section = .false.
517 IF (in_au_section) THEN
518 IF (i >= iline_start) THEN
519 iline_start = i + 1
520 res = isi_record(i) (4:)
521 EXIT line_loop
522 END IF
523 END IF
524 END DO line_loop
525
526 ! We might want to fixup the initials, adding a dot after each of them
527
528 END FUNCTION get_next_author
529
530! **************************************************************************************************
531!> \brief ...
532!> \param ISI_record ...
533!> \param iline_start ...
534!> \return ...
535! **************************************************************************************************
536 FUNCTION get_next_title(ISI_record, iline_start) RESULT(res)
537 CHARACTER(LEN=ISI_length), DIMENSION(:), &
538 INTENT(IN) :: isi_record
539 INTEGER, INTENT(INOUT) :: iline_start
540 CHARACTER(LEN=ISI_length) :: res
541
542 INTEGER :: i, n
543 LOGICAL :: in_ti_section
544
545 res = ""
546
547 in_ti_section = .false.
548 n = SIZE(isi_record, 1)
549 IF (iline_start > n) RETURN
550 line_loop: DO i = 1, n
551 IF (isi_record(i) (1:3) == "TI ") in_ti_section = .true.
552 IF (in_ti_section .AND. (isi_record(i) (1:3) /= "TI " .AND. isi_record(i) (1:3) /= " ")) in_ti_section = .false.
553 IF (in_ti_section) THEN
554 IF (i >= iline_start) THEN
555 iline_start = i + 1
556 res = isi_record(i) (4:)
557 EXIT line_loop
558 END IF
559 END IF
560 END DO line_loop
561
562 END FUNCTION get_next_title
563
564! **************************************************************************************************
565!> \brief ...
566!> \param ISI_record ...
567!> \return ...
568! **************************************************************************************************
569 PURE FUNCTION get_source(ISI_record) RESULT(res)
570 CHARACTER(LEN=ISI_length), DIMENSION(:), &
571 INTENT(IN) :: isi_record
572 CHARACTER(LEN=4*ISI_length) :: res
573
574 INTEGER :: i, j, n
575
576 n = SIZE(isi_record, 1)
577 res = ""
578 DO i = 1, n
579 IF (isi_record(i) (1:3) == "SO ") THEN
580 res = isi_record(i) (4:)
581 DO j = i + 1, n
582 IF (isi_record(j) (1:3) == " ") THEN
583 res = trim(res)//" "//isi_record(j) (4:)
584 ELSE
585 EXIT
586 END IF
587 END DO
588 EXIT
589 END IF
590 END DO
591 END FUNCTION get_source
592
593! **************************************************************************************************
594!> \brief ...
595!> \param ISI_record ...
596!> \return ...
597! **************************************************************************************************
598 PURE FUNCTION get_year(ISI_record) RESULT(res)
599 CHARACTER(LEN=ISI_length), DIMENSION(:), &
600 INTENT(IN) :: isi_record
601 CHARACTER(LEN=ISI_length) :: res
602
603 INTEGER :: i, n
604
605 n = SIZE(isi_record, 1)
606 res = ""
607 DO i = 1, n
608 IF (isi_record(i) (1:3) == "PY ") res = isi_record(i) (4:)
609 END DO
610 END FUNCTION get_year
611
612! **************************************************************************************************
613!> \brief ...
614!> \param ISI_record ...
615!> \return ...
616! **************************************************************************************************
617 PURE FUNCTION get_month(ISI_record) RESULT(res)
618 CHARACTER(LEN=ISI_length), DIMENSION(:), &
619 INTENT(IN) :: isi_record
620 CHARACTER(LEN=ISI_length) :: res
621
622 INTEGER :: i, n
623
624 n = SIZE(isi_record, 1)
625 res = ""
626 DO i = 1, n
627 IF (isi_record(i) (1:3) == "PD ") res = isi_record(i) (4:6)
628 END DO
629 END FUNCTION get_month
630
631! **************************************************************************************************
632!> \brief ...
633!> \param ISI_record ...
634!> \return ...
635! **************************************************************************************************
636 PURE FUNCTION get_day(ISI_record) RESULT(res)
637 CHARACTER(LEN=ISI_length), DIMENSION(:), &
638 INTENT(IN) :: isi_record
639 CHARACTER(LEN=ISI_length) :: res
640
641 INTEGER :: d, i, n
642
643 n = SIZE(isi_record, 1)
644 res = ""
645 DO i = 1, n
646 IF (isi_record(i) (1:3) == "PD ") res = isi_record(i) (7:)
647 END DO
648 ! PD can be e.g. OCT-NOV or OCT or OCT 27
649 ! if res can't be read as an integer, it is not a day, and we bail out
650 READ (res, *, err=998, END=998) d
651 ! if the day is not in the expected range, we assume it is a parse error
652 IF (d < 0 .OR. d > 31) res = ""
653 RETURN
654998 CONTINUE
655 res = ""
656 END FUNCTION get_day
657
658! **************************************************************************************************
659!> \brief ...
660!> \param ISI_record ...
661!> \return ...
662! **************************************************************************************************
663 PURE FUNCTION get_volume(ISI_record) RESULT(res)
664 CHARACTER(LEN=ISI_length), DIMENSION(:), &
665 INTENT(IN) :: isi_record
666 CHARACTER(LEN=ISI_length) :: res
667
668 INTEGER :: i, n
669
670 n = SIZE(isi_record, 1)
671 res = ""
672 DO i = 1, n
673 IF (isi_record(i) (1:3) == "VL ") res = isi_record(i) (4:)
674 END DO
675 END FUNCTION get_volume
676
677! **************************************************************************************************
678!> \brief ...
679!> \param ISI_record ...
680!> \return ...
681! **************************************************************************************************
682 PURE FUNCTION get_issue(ISI_record) RESULT(res)
683 CHARACTER(LEN=ISI_length), DIMENSION(:), &
684 INTENT(IN) :: isi_record
685 CHARACTER(LEN=ISI_length) :: res
686
687 INTEGER :: i, n
688
689 n = SIZE(isi_record, 1)
690 res = ""
691 DO i = 1, n
692 IF (isi_record(i) (1:3) == "IS ") res = isi_record(i) (4:)
693 END DO
694 END FUNCTION get_issue
695
696! **************************************************************************************************
697!> \brief ...
698!> \param ISI_record ...
699!> \return ...
700! **************************************************************************************************
701 PURE FUNCTION get_pages(ISI_record) RESULT(res)
702 CHARACTER(LEN=ISI_length), DIMENSION(:), &
703 INTENT(IN) :: isi_record
704 CHARACTER(LEN=ISI_length) :: res
705
706 CHARACTER(LEN=ISI_length) :: ar, bp, ep
707 INTEGER :: i, n
708
709 n = SIZE(isi_record, 1)
710 res = ""
711 bp = ""
712 ep = ""
713 ar = ""
714
715 DO i = 1, n
716 IF (isi_record(i) (1:3) == "BP ") bp = isi_record(i) (4:)
717 IF (isi_record(i) (1:3) == "EP ") ep = isi_record(i) (4:)
718 IF (isi_record(i) (1:3) == "AR ") ar = isi_record(i) (4:)
719 END DO
720 IF (bp .NE. "") THEN
721 res = bp
722 IF (ep .NE. "") res = trim(res)//"-"//ep
723 END IF
724 IF (res .EQ. "" .AND. ar .NE. "") res = ar
725 END FUNCTION get_pages
726
727! **************************************************************************************************
728!> \brief ...
729!> \param key ...
730!> \return ...
731! **************************************************************************************************
732 PURE FUNCTION get_citation_key(key) RESULT(res)
733 INTEGER, INTENT(IN) :: key
734 CHARACTER(LEN=default_string_length) :: res
735
736 res = thebib(key)%ref%citation_key
737 END FUNCTION get_citation_key
738
739!
740! This returns something epoch like, but can only be used to order the records
741! missing years, months, days are implied zero(1900)
742!
743! **************************************************************************************************
744!> \brief ...
745!> \param ISI_record ...
746!> \return ...
747! **************************************************************************************************
748 PURE FUNCTION get_epoch(ISI_record) RESULT(res)
749 CHARACTER(LEN=ISI_length), DIMENSION(:), &
750 INTENT(IN) :: isi_record
751 INTEGER :: res
752
753 CHARACTER(LEN=ISI_length) :: tmp
754 INTEGER :: day, istat, month, year
755
756! read year
757
758 tmp = get_year(isi_record)
759 READ (tmp, *, iostat=istat) year
760 IF (istat .NE. 0) year = 1900
761
762 ! read day
763 tmp = get_day(isi_record)
764 READ (tmp, *, iostat=istat) day
765 IF (istat .NE. 0) day = 0
766
767 ! read month
768 tmp = get_month(isi_record)
769 SELECT CASE (tmp)
770 CASE ("JAN")
771 month = 1
772 CASE ("FEB")
773 month = 2
774 CASE ("MAR")
775 month = 3
776 CASE ("APR")
777 month = 4
778 CASE ("MAY")
779 month = 5
780 CASE ("JUN")
781 month = 6
782 CASE ("JUL")
783 month = 7
784 CASE ("AUG")
785 month = 8
786 CASE ("SEP")
787 month = 9
788 CASE ("OCT")
789 month = 10
790 CASE ("NOV")
791 month = 11
792 CASE ("DEC")
793 month = 12
794 CASE DEFAULT
795 month = 0
796 END SELECT
797
798 res = day + 31*month + 12*31*(year - 1900)
799
800 END FUNCTION get_epoch
801
802END MODULE reference_manager
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public default_string_length
Definition kinds.F:57
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
Definition list.F:24
Interface to the message passing library MPI.
provides a uniform framework to add references to CP2K cite and output these
subroutine, public print_all_references(cited_only, sorted, format, unit, list)
printout of all references in a specific format optionally printing only those that are actually cite...
pure character(len=default_string_length) function, public get_citation_key(key)
...
subroutine, public add_reference(key, isi_record, doi)
add a reference to the bibliography
subroutine, public remove_all_references()
deallocate the bibliography
subroutine, public collect_citations_from_ranks(para_env)
Checks for each reference if any mpi-rank has marked it for citation.
subroutine, public cite_reference(key)
marks a given reference as cited.
integer, parameter, public print_format_journal
subroutine, public print_reference(key, format, unit)
printout of a specified reference to a given unit in a selectable format
integer, parameter, public print_format_html
integer, parameter, public print_format_isi
Utilities for string manipulations.
elemental subroutine, public uppercase(string)
Convert all lower case characters in a string to upper case.
All kind of helpful little routines.
Definition util.F:14
stores all the informations relevant to an mpi environment