summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/biblatex/latex/blx-case-expl3.sty
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/biblatex/latex/blx-case-expl3.sty')
-rw-r--r--macros/latex/contrib/biblatex/latex/blx-case-expl3.sty289
1 files changed, 289 insertions, 0 deletions
diff --git a/macros/latex/contrib/biblatex/latex/blx-case-expl3.sty b/macros/latex/contrib/biblatex/latex/blx-case-expl3.sty
new file mode 100644
index 0000000000..e90a4a7c11
--- /dev/null
+++ b/macros/latex/contrib/biblatex/latex/blx-case-expl3.sty
@@ -0,0 +1,289 @@
+\RequirePackage{expl3}[2020/04/06]
+\RequirePackage{xparse}
+\ProvidesExplPackage {blx-case-expl3} {\abx@date} {\abx@version}
+ {expl3 case changing code for biblatex}
+
+
+% helper macros to work around babel \languagename catcode weirdness
+\cs_new:Npn \__biblatex_clist_put_detokenized_left:Nn #1 #2
+ {
+ \clist_put_left:No #1 { \detokenize{#2} }
+ }
+
+\cs_generate_variant:Nn \__biblatex_clist_put_detokenized_left:Nn { Ne }
+
+
+\prg_new_conditional:Npnn \__biblatex_clist_if_detokenized_in:Nn #1#2 { TF }
+ {
+ \clist_if_in:NoTF #1 { \detokenize{#2} }
+ {\prg_return_true:}
+ {\prg_return_false:}
+ }
+
+\prg_generate_conditional_variant:Nnn \__biblatex_clist_if_detokenized_in:Nn {Ne} {TF}
+
+
+
+% Map for babel/polyglossia names
+% to BCP-47-like l3text names.
+% We only need maps for l3text names that do something
+% as of 2020/04/06 those names are
+% az, de-alt, el, lt, nl, tr.
+% biblatex currently only supports dutch, greek and turkish
+% so we only map those.
+% de-alt is optional and still unusual, so *we* don't map it,
+% but a user could map it themselves.
+
+\prop_new:N \l__biblatex_babel_to_pseudobcp_prop
+
+\cs_generate_variant:Nn \msg_info:nnnnn { nnnxn }
+
+\cs_new_protected:Npn \biblatex_maplang_babel_to_pseudobcp:nn #1 #2
+ {
+ \prop_if_in:NnT \l__biblatex_babel_to_pseudobcp_prop {#1}
+ {
+ \msg_info:nnnxn { biblatex }
+ { overwrite-babel-to-pseudobcp-map }
+ {#1}
+ {\prop_item:Nn \l__biblatex_babel_to_pseudobcp_prop {#1}}
+ {#2}
+ }
+ \prop_put:Nnn \l__biblatex_babel_to_pseudobcp_prop {#1} {#2}
+ }
+
+\NewDocumentCommand \DeclareBabelToExplLanguageMapping {mm}
+ {
+ \biblatex_maplang_babel_to_pseudobcp:nn {#1} {#2}
+ }
+
+\cs_generate_variant:Nn \msg_info:nnnn { nnnx }
+
+\cs_new_protected:Npn \biblatex_unmaplang_babel_to_pseudobcp:n #1
+ {
+ \prop_if_in:NnT \l__biblatex_babel_to_pseudobcp_prop {#1}
+ {
+ \msg_info:nnnx { biblatex }
+ { remove-babel-to-pseudobcp-map }
+ {#1}
+ { \prop_item:Nn \l__biblatex_babel_to_pseudobcp_prop {#1} }
+ }
+ \prop_remove:Nn \l__biblatex_babel_to_pseudobcp_prop {#1}
+ }
+
+\NewDocumentCommand \UndeclareBabelToExplLanguageMapping {m}
+ {
+ \str_if_eq:nnTF {#1} {*}
+ { \prop_clear:N \l__biblatex_babel_to_pseudobcp_prop }
+ { \biblatex_unmaplang_babel_to_pseudobcp:n {#1} }
+ }
+
+% Don't put this into biblatex.sty, since
+% \DeclareBabelToExplLanguageMapping has no equivalent in the LaTeX2e
+% code.
+\DeclareBabelToExplLanguageMapping{dutch}{nl}
+\DeclareBabelToExplLanguageMapping{greek}{el}
+\DeclareBabelToExplLanguageMapping{turkish}{tr}
+
+% Our copy of \l_text_titlecase_check_letter_bool
+\bool_new:N \l_biblatex_titlecase_check_letter_bool
+% Just to be clear: unlike l3text our default is "false"
+\bool_set_false:N \l_biblatex_titlecase_check_letter_bool
+
+% Helper macro to avoid unnecessary repetition of the same structure
+% {<case [lowercase|uppercase|titlecase|titlecase_first]>}
+% {<babel language>}{<text>}
+% We use that \prop_item:Nn is empty if the item is not present
+% and that \text_...:nn becomes \text_...:n if the first argument
+% is empty.
+\cs_new_protected:Npn \__biblatex_text_makeconverter:nnn #1 #2 #3
+ {
+ \group_begin:
+ \bool_if_exist:NTF \l_text_titlecase_check_letter_bool
+ {
+ \bool_set_eq:NN \l_text_titlecase_check_letter_bool
+ \l_biblatex_titlecase_check_letter_bool
+ }
+ {
+ % should we raise an error or at least issue a warning here?
+ }
+ \use:c { text_#1:nn }
+ { \prop_item:Nn \l__biblatex_babel_to_pseudobcp_prop {#2} } {#3}
+ \group_end:
+ }
+
+
+\cs_new:Npn \biblatex_text_lowercase:nn #1 #2
+ {
+ \__biblatex_text_makeconverter:nnn {lowercase} {#1} {#2}
+ }
+
+\cs_generate_variant:Nn \biblatex_text_lowercase:nn { Vn }
+
+\cs_new:Npn \biblatex_text_lowercase:n #1
+ {
+ \biblatex_text_lowercase:Vn \blx@languagename {#1}
+ }
+
+\cs_set_eq:NN \blx@maketext@lowercase \biblatex_text_lowercase:n
+
+
+\cs_new:Npn \biblatex_text_uppercase:nn #1 #2
+ {
+ \__biblatex_text_makeconverter:nnn {uppercase} {#1} {#2}
+ }
+
+\cs_generate_variant:Nn \biblatex_text_uppercase:nn { Vn }
+
+\cs_new:Npn \biblatex_text_uppercase:n #1
+ {
+ \biblatex_text_uppercase:Vn \blx@languagename {#1}
+ }
+
+\cs_set_eq:NN \blx@maketext@uppercase \biblatex_text_uppercase:n
+
+
+\cs_new:Npn \biblatex_text_makecapital:nn #1 #2
+ {
+ \__biblatex_text_makeconverter:nnn {titlecase_first} {#1} {#2}
+ }
+
+\cs_generate_variant:Nn \biblatex_text_makecapital:nn { Vn }
+
+\cs_new:Npn \biblatex_text_makecapital:n #1
+ {
+ \biblatex_text_makecapital:Vn \blx@languagename {#1}
+ }
+
+\cs_set_eq:NN \blx@maketext@makecapital \biblatex_text_makecapital:n
+
+\NewDocumentCommand \MakeCapital {m}
+ {
+ \biblatex_text_makecapital:n {#1}
+ }
+
+
+
+% BibTeX to expl3 case protection code by Joseph Wright
+% https://github.com/plk/biblatex/issues/960#issuecomment-578435859
+% and Bruno Le Floch
+% https://github.com/moewew/biblatex/commit/c485f1b8079d56497b17343d7883b8fcd42f961a#r39225533
+\tl_put_right:Nn \l_text_expand_exclude_tl { \NoCaseChange }
+
+\tl_put_right:Nn \l_text_case_exclude_arg_tl { \NoCaseChange }
+
+\cs_new:Npn \biblatex_text_bibtex_to_expl:n #1
+ {
+ \__biblatex_text_bibtex_loop:w #1
+ { \q_recursion_tail } \q_recursion_stop
+ }
+
+\cs_new:Npn \__biblatex_text_bibtex_loop:w #1 #
+ {
+ \exp_not:n {#1}
+ \__biblatex_text_bibtex_group:n
+ }
+
+\cs_new:Npn \__biblatex_text_bibtex_group:n #1
+ {
+ \quark_if_recursion_tail_stop:n {#1}
+ {
+ \bool_lazy_and:nnTF
+ { \tl_if_head_is_N_type_p:n {#1} }
+ { \exp_after:wN \token_if_cs_p:N \tl_head:w #1 \q_stop }
+ { \exp_not:n {#1} }
+ { \exp_not:n { \NoCaseChange {#1} } }
+ }
+ \__biblatex_text_bibtex_loop:w
+ }
+
+\cs_new_eq:NN \biblatex_text_sentencecase_preprocess:n
+ \biblatex_text_bibtex_to_expl:n
+
+
+% By default we emulate BibTeX's brace case protection rules
+% but the user can turn that off for a more sane behaviour
+% that only relies on \NoCaseChange.
+\DeclareBiblatexOption{global,type,entry}[boolean]{bibtexcaseprotection}[true]{%
+ \str_case:nnF {#1}
+ {
+ { true }
+ {
+ \cs_set_eq:NN \biblatex_text_sentencecase_preprocess:n
+ \biblatex_text_bibtex_to_expl:n
+ }
+ { false }
+ {
+ \cs_set_eq:NN \biblatex_text_sentencecase_preprocess:n
+ \use:n
+ }
+ }
+ {
+ \msg_error:nnn { biblatex } { invalid-value-bibtexcaseprotection }
+ {#1}
+ }
+}
+
+
+\cs_new:Npn \biblatex_text_sentencecase:nn #1 #2
+ {
+ \__biblatex_text_makeconverter:nnn {titlecase} {#1} {#2}
+ }
+
+
+\cs_generate_variant:Nn \biblatex_text_sentencecase:nn { Vo, xo }
+
+% If \DeclareCaseLangs says we should apply sentence casing,
+% we go for it and pass the language along to the sentence casing macro.
+% Preprocess is either the BibTeX-to-expl3 brace translator
+% or \@firstofone (do nothing),
+% we need to expand once to get rid of the latter.
+\NewDocumentCommand \MakeSentenceCase {sm}
+ {
+ \IfBooleanTF {#1}
+ {
+ \__biblatex_clist_if_detokenized_in:NeTF
+ \l__biblatex_caselangs_clist { \blx@mksc@lang }
+ {
+ \biblatex_text_sentencecase:xo { \blx@mksc@lang }
+ { \biblatex_text_sentencecase_preprocess:n {#2} }
+ }
+ {#2}
+ }
+ {
+ \biblatex_text_sentencecase:Vo \blx@languagename
+ { \biblatex_text_sentencecase_preprocess:n {#2} }
+ }
+ }
+
+
+\clist_new:N \l__biblatex_caselangs_clist
+
+% {<language,language,...>}
+\NewDocumentCommand \DeclareCaseLangs {sm}
+ {
+ \IfBooleanF {#1}
+ { \clist_clear:N \l__biblatex_caselangs_clist }
+ \__biblatex_clist_put_detokenized_left:Ne
+ \l__biblatex_caselangs_clist {#2}
+ }
+
+% \DeclareCaseLangs invocation is in biblatex.sty
+
+\NewDocumentCommand \ifcaselang {O{\blx@languagename}}
+ {
+ \__biblatex_clist_if_detokenized_in:NeTF \l__biblatex_caselangs_clist {#1}
+ }
+
+
+\msg_new:nnnn { biblatex } { invalid-value-bibtexcaseprotection }
+ { Invalid~value~'#1'~for~option~'bibtexcaseprotection'. }
+ { Valid~values~for~'bibtexcaseprotection'~are~'true'~and~'false'. }
+
+\msg_new:nnn { biblatex } { remove-babel-to-pseudobcp-map }
+ { Removing~babel->l3text~language~mapping~for~'#1'~to~'#2'. }
+
+\msg_new:nnn { biblatex } { overwrite-babel-to-pseudobcp-map }
+ { Overwriting~babel->l3text~language~mapping~for~'#1'~from~
+ '#2'~to~'#3'. }
+
+\endinput