Any automatic solution will have a hard time beating a human well-versed in the Chicago Manual of Style's headline-style capitalization rules. So you're probably better off formatting titles in your source file manually. Whenever the document language or bibliography format calls for sentence-style capitalization, it is relatively easy to apply with biblatex's \MakeSentenceCase
macro.
That said you could write a new macro, say \MakeHeadlineCase
, and apply it in the title formatting directives. Another approach is to use biber's sourcemap
option. It supports regular expressions and modifies fields before biblatex even sees them, which means the solution is entirely style-independent.
A rough approximation to headline-style capitalization is implemented in the following source mapping. It uses the XML syntax of the biber configuration file biber.conf
. You can also specify source mappings in the document preamble with biblatex's \DeclareSourcemap
command.
<?xml version="1.0" encoding="UTF-8"?>
<config>
<sourcemap>
<maps datatype="bibtex" map_overwrite="1">
<map>
<map_step map_field_source="TITLE"
map_match="(^|\s)(\w+\S*w*)" map_replace="$1\u\L$2"/>
<map_step map_field_source="TITLE"
map_match="\-(\w+)" map_replace="\-\u\L$1"/>
<map_step map_field_source="TITLE"
map_match="(\s+|\-)(A(|n|nd|s|t)|F(or|rom)|I(n|s)|O(f|n|r)|T(he|o)|With)\b"
map_replace="$1\L$2"/>
<map_step map_field_source="TITLE"
map_match="([:;]\s+)([a-z])" map_replace="$1\u$2"/>
</map>
</maps>
</sourcemap>
</config>
The first two steps capitalize words at the beginning of the string (^
), after whitespace (\s
) or following a hyphen (\-
). The third map down-cases selected words after whitespace or a hyphen. The last map capitalizes words following a colon or semi-colon ([:;]
).
Here's a self-contained example.
\documentclass{article}
\usepackage[backend=biber]{biblatex}
\usepackage{filecontents}
\begin{filecontents*}{biber.conf}
<?xml version="1.0" encoding="UTF-8"?>
<config>
<sourcemap>
<maps datatype="bibtex" map_overwrite="1">
<map>
<map_step map_field_source="TITLE"
map_match="(^|\s)(\w+\S*w*)" map_replace="$1\u\L$2"/>
<map_step map_field_source="TITLE"
map_match="\-(\w+)" map_replace="\-\u\L$1"/>
<map_step map_field_source="TITLE"
map_match="(\s+|\-)(A(|n|nd|s|t)|B(ut|y)|F(or|rom)|I(n|s)|O(f|n|r)|T(he|o)|With)\b"
map_replace="$1\L$2"/>
<map_step map_field_source="TITLE"
map_match="([:;]\s+)([a-z])" map_replace="$1\u$2"/>
</map>
</maps>
</sourcemap>
</config>
\end{filecontents*}
\begin{filecontents*}{\jobname.bib}
@BOOK{Smith2003,
title = {This is an off-the-hook book title, but it doesn't have a subtitle},
publisher = {Penguin},
year = {2003},
author = {Smith, James},
address = {London}}
@ARTICLE{Doe1970,
author = {H{\"a}user, {\O}rnulf},
title = {{\O}rnulf H{\"a}user's letter to the editor: an $\alpha$-to-$\omega$
summary of $\epsilon$--improvement},
journal = {Great Journal},
year = {1970},
volume = {40},
pages = {207-234}}
\end{filecontents*}
\addbibresource{\jobname.bib}
\begin{document}
\nocite{*}
\printbibliography
\end{document}
.bib
file: capitalization rules are different depending on the language (e.g., imagine a collection of essays written in different languages: essay titles in, say, English, French, and Italian, but the booktitle in German!). Now that there is no forced down-casing,title = {<Whatever>},
can be entered as it should without be according to that language's conventions.