29 #include "../base/base_uses.f90"
42 CHARACTER(len=*),
PARAMETER,
PRIVATE :: modulen =
'reference_manager'
45 INTEGER,
PARAMETER :: max_reference = 1024
48 INTEGER,
PARAMETER :: doi_length = 128
49 INTEGER,
PARAMETER :: isi_length = 128
56 CHARACTER(LEN=ISI_length),
DIMENSION(:),
POINTER :: isi_record => null()
58 CHARACTER(LEN=doi_length) :: doi =
""
60 LOGICAL :: is_cited = .false.
62 CHARACTER(LEN=ISI_length) :: citation_key =
""
63 END TYPE reference_type
68 TYPE(reference_type),
POINTER :: ref => null()
72 INTEGER,
SAVE :: nbib = 0
73 TYPE(reference_p_type),
DIMENSION(max_reference) :: thebib
88 INTEGER,
INTENT(IN) :: key
90 IF (key < 1 .OR. key > max_reference) cpabort(
"citation key out of range")
93 thebib(key)%ref%is_cited = .true.
104 TYPE(mp_para_env_type),
INTENT(IN) :: para_env
110 IF (thebib(i)%ref%is_cited) t = 1
112 thebib(i)%ref%is_cited = (t == 1)
132 INTEGER,
INTENT(OUT) :: key
133 CHARACTER(LEN=*),
DIMENSION(:),
INTENT(IN) :: isi_record
134 CHARACTER(LEN=*),
INTENT(IN) :: doi
137 CHARACTER(LEN=ISI_length) :: author, citation_key, key_a, key_b, year
138 INTEGER :: commaloc, i, ires, line, match, mylen, &
141 IF (nbib + 1 > max_reference) cpabort(
"increase max_reference")
146 ALLOCATE (thebib(key)%ref)
147 NULLIFY (thebib(key)%ref%ISI_record)
148 thebib(key)%ref%DOI =
""
149 thebib(key)%ref%is_cited = .false.
152 thebib(key)%ref%DOI = doi
155 nlines =
SIZE(isi_record, 1)
156 ALLOCATE (thebib(key)%ref%ISI_record(nlines))
157 thebib(key)%ref%ISI_record = isi_record
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)
170 mylen = len_trim(citation_key)
173 IF (index(
"0123456789thequickbrownfoxjumpsoverthelazydogTHEQUICKBROWNFOXJUMPSOVERTHELAZYDOG", citation_key(i:i)) .NE. 0)
THEN
175 tmp = citation_key(i:i)
176 citation_key(ires:ires) = tmp
179 citation_key(ires + 1:) =
""
180 cpassert(len_trim(citation_key) > 4)
183 mylen = len_trim(citation_key)
184 key_a = citation_key(1:mylen)
188 key_b = thebib(i)%ref%citation_key(1:mylen)
190 IF (key_a == key_b) match = match + 1
192 IF (match > 0) citation_key = citation_key(1:mylen)//char(ichar(
'a') + match)
195 thebib(key)%ref%citation_key = citation_key
208 IF (
ASSOCIATED(thebib(i)%ref%ISI_record))
DEALLOCATE (thebib(i)%ref%ISI_record)
209 thebib(i)%ref%DOI =
""
211 DEALLOCATE (thebib(i)%ref)
230 LOGICAL,
INTENT(IN) :: cited_only, sorted
231 INTEGER,
INTENT(IN) :: format, unit
232 INTEGER,
DIMENSION(:),
INTENT(IN),
OPTIONAL ::
list
234 INTEGER :: i, irecord, nref
235 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: indx, irank, ival
240 IF (
PRESENT(
list))
THEN
246 ALLOCATE (ival(nref))
247 ALLOCATE (irank(nref))
248 ALLOCATE (indx(nref))
250 IF (
PRESENT(
list))
THEN
264 ival(i) = -get_epoch(thebib(indx(i))%ref%ISI_record)
271 CALL sort(ival, nref, irank)
276 WRITE (unit,
'(A)')
""
278 WRITE (unit,
'(A)')
'<TABLE border="1">'
280 cpabort(
"print_reference: wrong format")
284 irecord = indx(irank(i))
285 IF (.NOT. cited_only .OR. thebib(irecord)%ref%is_cited)
THEN
290 WRITE (unit,
'(A)')
"<TR><TD>"//
'['//trim(thebib(irecord)%ref%citation_key)//
']'//
"</TD><TD>"
292 cpabort(
"print_reference: wrong format")
300 WRITE (unit,
'(A)')
""
302 WRITE (unit,
'(A)')
'</TD></TR>'
304 cpabort(
"print_reference: wrong format")
309 WRITE (unit,
'(A)')
"</TABLE>"
324 INTEGER,
INTENT(IN) :: key, format, unit
328 IF (key < 1 .OR. key > max_reference) cpabort(
"citation key out of range")
332 DO i = 1,
SIZE(thebib(key)%ref%ISI_record)
333 WRITE (unit,
'(T2,A)') trim(thebib(key)%ref%ISI_record(i))
336 CALL print_reference_journal(key, unit)
338 CALL print_reference_html(key, unit)
340 cpabort(
"print_reference: wrong format")
352 SUBROUTINE print_reference_journal(key, unit)
353 INTEGER,
INTENT(IN) :: key, unit
355 CHARACTER(LEN=4*ISI_length) :: journal
356 CHARACTER(LEN=ISI_length) :: author, title
357 INTEGER :: iauthor, ipos_line, ititle, line
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")
""
371 IF (iauthor .NE. 1)
WRITE (unit,
'(A)', advance=
"NO")
"; "
372 ipos_line = ipos_line + 2
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)
378 IF (iauthor > 0)
THEN
379 WRITE (unit,
'(A)', advance=
"NO")
". "
380 ipos_line = ipos_line + 2
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))//
")"
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))//
")."
395 IF (ipos_line + len_trim(journal) > 71)
THEN
396 WRITE (unit,
'(A)')
""
397 WRITE (unit,
'(T2,A)', advance=
"NO")
""
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:))
404 WRITE (unit,
'(A)', advance=
"NO") trim(journal)
407 WRITE (unit,
'(T2,A)')
""
410 title = get_next_title(thebib(key)%ref%ISI_record, line)
411 DO WHILE (title .NE.
"")
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)
417 IF (ititle > 0)
WRITE (unit,
'(A)')
"."
420 IF (thebib(key)%ref%DOI .NE.
"")
THEN
421 WRITE (unit,
'(T2,A)')
"https://doi.org/"//trim(thebib(key)%ref%DOI)
424 END SUBROUTINE print_reference_journal
435 SUBROUTINE print_reference_html(key, unit)
436 INTEGER,
INTENT(IN) :: key, unit
438 CHARACTER(LEN=ISI_length) :: author, title
439 CHARACTER(LEN=ISI_length*4) :: journal
440 INTEGER :: iauthor, ititle, line
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)
453 IF (iauthor > 0)
WRITE (unit,
'(A)')
".<br>"
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)//
'">'
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))//
")"
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))//
")."
471 WRITE (unit,
'(A)', advance=
"NO") trim(journal)
472 IF (thebib(key)%ref%DOI .NE.
"")
THEN
473 WRITE (unit,
'(A)', advance=
"NO")
'</A>'
475 WRITE (unit,
'(A)')
"</A><br>"
479 title = get_next_title(thebib(key)%ref%ISI_record, line)
480 DO WHILE (title .NE.
"")
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)
486 IF (ititle > 0)
WRITE (unit,
'(A)')
"."
488 END SUBROUTINE print_reference_html
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
508 LOGICAL :: in_au_section
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
520 res = isi_record(i) (4:)
528 END FUNCTION get_next_author
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
543 LOGICAL :: in_ti_section
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
556 res = isi_record(i) (4:)
562 END FUNCTION get_next_title
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
576 n =
SIZE(isi_record, 1)
579 IF (isi_record(i) (1:3) ==
"SO ")
THEN
580 res = isi_record(i) (4:)
582 IF (isi_record(j) (1:3) ==
" ")
THEN
583 res = trim(res)//
" "//isi_record(j) (4:)
591 END FUNCTION get_source
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
605 n =
SIZE(isi_record, 1)
608 IF (isi_record(i) (1:3) ==
"PY ") res = isi_record(i) (4:)
610 END FUNCTION get_year
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
624 n =
SIZE(isi_record, 1)
627 IF (isi_record(i) (1:3) ==
"PD ") res = isi_record(i) (4:6)
629 END FUNCTION get_month
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
643 n =
SIZE(isi_record, 1)
646 IF (isi_record(i) (1:3) ==
"PD ") res = isi_record(i) (7:)
650 READ (res, *, err=998,
END=998) d
652 IF (d < 0 .OR. d > 31) res =
""
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
670 n =
SIZE(isi_record, 1)
673 IF (isi_record(i) (1:3) ==
"VL ") res = isi_record(i) (4:)
675 END FUNCTION get_volume
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
689 n =
SIZE(isi_record, 1)
692 IF (isi_record(i) (1:3) ==
"IS ") res = isi_record(i) (4:)
694 END FUNCTION get_issue
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
706 CHARACTER(LEN=ISI_length) :: ar, bp, ep
709 n =
SIZE(isi_record, 1)
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:)
722 IF (ep .NE.
"") res = trim(res)//
"-"//ep
724 IF (res .EQ.
"" .AND. ar .NE.
"") res = ar
725 END FUNCTION get_pages
733 INTEGER,
INTENT(IN) :: key
734 CHARACTER(LEN=default_string_length) :: res
736 res = thebib(key)%ref%citation_key
748 PURE FUNCTION get_epoch(ISI_record)
RESULT(res)
749 CHARACTER(LEN=ISI_length),
DIMENSION(:), &
750 INTENT(IN) :: isi_record
753 CHARACTER(LEN=ISI_length) :: tmp
754 INTEGER :: day, istat, month, year
758 tmp = get_year(isi_record)
759 READ (tmp, *, iostat=istat) year
760 IF (istat .NE. 0) year = 1900
763 tmp = get_day(isi_record)
764 READ (tmp, *, iostat=istat) day
765 IF (istat .NE. 0) day = 0
768 tmp = get_month(isi_record)
798 res = day + 31*month + 12*31*(year - 1900)
800 END FUNCTION get_epoch
Defines the basic variable types.
integer, parameter, public default_string_length
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
Interface to the message passing library MPI.
provides a uniform framework to add references to CP2K cite and output these
pure character(len=default_string_length) function, public get_citation_key(key)
...
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...
subroutine, public remove_all_references()
deallocate the bibliography
subroutine, public add_reference(key, ISI_record, DOI)
add a reference to 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.
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_journal
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.