diff --git a/citeproc-s.el b/citeproc-s.el index bfb6208..3795de7 100644 --- a/citeproc-s.el +++ b/citeproc-s.el @@ -151,27 +151,33 @@ first word is not in lowercase then return S." (buffer-string)) s)) -(defun citeproc-s-sentence-case-title (s omit-nocase) +(defun citeproc-s-sentence-case-title (s &optional omit-nocase) "Return a sentence-cased version of title string S. If optional OMIT-NOCASE is non-nil then omit the nocase tags from the output." (if (s-blank-p s) s (let ((sliced (citeproc-s-slice-by-matches - s "\\(\\|\\|: +\\w\\)")) + s "\\(\\|\\|: +[\"'“‘]*[[:alpha:]]\\)")) (protect-level 0) (first t) result) + (message "SLICE: %s" sliced) (dolist (slice sliced) (push (pcase slice ("" (cl-incf protect-level) (if omit-nocase nil slice)) ("" (cl-decf protect-level) (if omit-nocase nil slice)) - ;; Don't touch the first letter after a colon since it is probably a subtitle. - ((pred (string-match-p "^:")) slice) + ;; Don't touch the first letter after a colon since it probably + ;; starts a subtitle. + ((pred (string-match-p "^: +[\"'“‘]*[[:alpha:]]")) (setq first nil) slice) (_ (cond ((< 0 protect-level) (setq first nil) slice) ((not first) (downcase slice)) (t (setq first nil) - (concat (upcase (substring slice 0 1)) - (downcase (substring slice 1))))))) + ;; We upcase the first letter and downcase the rest. + (let ((pos (string-match "[[:alpha:]]" slice))) + (if pos (concat (substring slice 0 pos) + (upcase (substring slice pos (1+ pos))) + (downcase (substring slice (1+ pos)))) + slice)))))) result)) (apply #'concat (nreverse result)))))