With help from this group, I've written my first baby-program in Racket and
would really appreciate any feedback on how to make it more idiomatic,
efficient and well-formatted (I struggle with where to break lines). Thank you
in advance.
The purpose is to fix the irregular capitalization of entries in the "Keywords"
field of a large BibLaTeX (.bib) file. A sample entry in the input file might be
@article{Ender-2016-Review-00,
Author = {Ender, P. B.},
Keywords = {Book Review, Behaviorial sciences, ANALYSIS OF VARIANCE,
experimental design},
...}
I want non-Keyword lines passed unchanged to the output file and each keyword
entry (potentially multiword) changed to have only its first word capitalized.
Thus
@article{Ender-2016-Review-00,
Author = {Ender, P. B.},
Keywords = {Book review, Behaviorial sciences, Analysis of variance,
Experimental design},
...}
Here is what I came up with.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#lang racket
(define in (open-input-file "/Users/me/BibDeskPapers/oldBib.bib"))
(define out (open-output-file "/Users/me/BibDeskPapers/newBib.bib" #:exists
'replace))
(define keyword-prefix "\tKeywords = {")
;; Return a string with only the first word capitalized and all else in lower
case
;; Courtesy https://groups.google.com/forum/m/#!topic/racket-users/gw8Ivm5HSZQ
(provide
(contract-out
[string-upcase-first-word (-> string? string?)]))
(define (string-upcase-first-word s)
(apply
string
(for/list ([c (in-string s)]
[i (in-naturals)])
(if (= i 0)
(char-upcase c)
(char-downcase c)))))
(module+ test
(require rackunit)
(check-equal? (string-upcase-first-word "") "")
(check-equal? (string-upcase-first-word "Cat Dog") "Cat dog")
(check-equal? (string-upcase-first-word "cat dog") "Cat dog"))
;; Main program
(for ([aLine (in-lines in)])
(cond
[(string-prefix? aLine "\tKeywords = {") ; Identify Keywords lines
(define keywords-as-list (string-split (string-replace aLine "\tKeywords =
{" "") ","))
(define cleaned-keywords (map (lambda (aString)
(string-upcase-first-word
(string-trim aString)))
keywords-as-list))
(display keyword-prefix out)
(display (string-join cleaned-keywords ", ") out)
(display "," out)
(newline out)]
[else (display aLine out) (newline out)]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Thank you again.
--
You received this message because you are subscribed to the Google Groups
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.