diff options
Diffstat (limited to 'biblio/citation-style-language/citation-style-language.sty')
-rw-r--r-- | biblio/citation-style-language/citation-style-language.sty | 458 |
1 files changed, 395 insertions, 63 deletions
diff --git a/biblio/citation-style-language/citation-style-language.sty b/biblio/citation-style-language/citation-style-language.sty index 7d0daab99e..5566737b49 100644 --- a/biblio/citation-style-language/citation-style-language.sty +++ b/biblio/citation-style-language/citation-style-language.sty @@ -1,5 +1,5 @@ % -% Copyright (c) 2021-2022 Zeping Lee +% Copyright (c) 2021-2023 Zeping Lee % Released under the MIT License. % Repository: https://github.com/zepinglee/citeproc-lua % @@ -9,7 +9,7 @@ \RequirePackage{expl3} \RequirePackage{xparse} -\ProvidesExplPackage {citation-style-language} {2022-12-25} {v0.3.0} +\ProvidesExplPackage {citation-style-language} {2023-04-02} {v0.4.0} {Citation Style Language for LaTeX} \RequirePackage { l3keys2e } @@ -18,21 +18,18 @@ % Check incompatible packages \msg_new:nnn { citation-style-language } { incompatible-package } - { The~ `#1'~ package~ is~ incompatible~ with~ `citeproc'. } + { The~ `#1'~ package~ is~ incompatible~ with~ `citation-style-language'. } -\cs_new_protected:Npn \__csl_load_check:n #1 - { - \AtBeginOfPackageFile* {#1} - { \msg_error:nnn { citation-style-language } { incompatible-package } {#1} } - } - -\clist_map_function:nN +\clist_map_inline:nn { babelbib , backref , biblatex , bibtopic , bibunits , chapterbib , cite , citeref , inlinebib , jurabib , mcite , mciteplus , multibib , natbib , splitbib } - \__csl_load_check:n + { + \AtBeginOfPackageFile* {#1} + { \msg_error:nnn { citation-style-language } { incompatible-package } {#1} } + } % Check l3build regression-test @@ -50,7 +47,7 @@ \NewDocumentCommand \cslsetup { m } { \keys_set:nn { csl } {#1} } -\cs_new:Npn \csloptions #1 { } +\cs_new:Npn \csl@aux@options #1 { } \DeclareDocumentCommand \cite { o o m } @@ -68,6 +65,9 @@ \NewDocumentCommand \citet { o o m } { \__csl_text_cite:nnn {#1} {#2} {#3} } +\NewDocumentCommand \footcite { o o m } + { \__csl_cite:nnn {#1} {#2} {#3} } + % \cites[⟨prenote⟩][⟨postnote⟩]{⟨key⟩}...[⟨prenote⟩][⟨postnote⟩]{⟨key⟩} \NewDocumentCommand \cites { } @@ -82,14 +82,19 @@ \prop_new:N \l__csl_citation_properties_prop \prop_new:N \l__csl_citation_info_prop +% \__csl_cite:nnn #1#2#3 \cs_new:Npn \__csl_cite:nnn #1#2#3 { - \seq_clear:N \l__csl_cite_keys_seq - \seq_clear:N \l__csl_citation_items_seq - \prop_clear:N \l__csl_citation_properties_prop - \__csl_process_cite_input:nnn {#1} {#2} {#3} - \__csl_process_citation_info:NN \l__csl_cite_keys_seq \l__csl_citation_items_seq - \__csl_make_citation:N \l__csl_citation_info_prop + \tl_if_blank:nTF {#3} + { \__csl_print_undefined_citation:n {#3} } + { + \seq_clear:N \l__csl_cite_keys_seq + \seq_clear:N \l__csl_citation_items_seq + \prop_clear:N \l__csl_citation_properties_prop + \__csl_process_cite_input:nnn {#1} {#2} {#3} + \__csl_process_citation_info:NN \l__csl_cite_keys_seq \l__csl_citation_items_seq + \__csl_make_citation:N \l__csl_citation_info_prop + } } @@ -279,6 +284,46 @@ \__csl_process_citation_id:NN \l__csl_citation_id_tl #1 \__csl_get_note_index:N \l__csl_note_index_tl \prop_put:NnV \l__csl_citation_properties_prop { noteIndex } \l__csl_note_index_tl + \__csl_add_back_ref_info: + } + + +\tl_new:N \l__csl_back_ref_tl +\prop_new:N \g__csl_back_ref_info_prop +\prop_new:N \l__csl_back_ref_section_pop + +% Provide empty \@currentHref when hyperref is not loaded. +\cs_new:Npn \@currentHref {} + +% TODO: write backref info to .brf file or .aux file +\cs_new:Npn \__csl_add_back_ref_info: + { + % Same as the second argument of backref's \backcite + % \thepage: the page number + % \@currentlabel: the current label of the citation + % \@currentHref: the current anchor name + \tl_if_empty:NTF \@currentlabel + { + \tl_set:Nx \l__csl_back_ref_tl + { { \thepage } { (document) } { Doc-Start } } + } + { + \tl_set:Nx \l__csl_back_ref_tl + { { \thepage } { \@currentlabel } { \@currentHref } } + } + \seq_map_inline:Nn \l__csl_cite_keys_seq + { + \prop_get:NnNTF \g__csl_back_ref_info_prop {##1} \l_tmpa_tl + { + \tl_put_right:Nn \l_tmpa_tl { , } + \tl_put_right:NV \l_tmpa_tl \l__csl_back_ref_tl + \prop_gput:NnV \g__csl_back_ref_info_prop {##1} \l_tmpa_tl + } + { + \prop_gput:NnV \g__csl_back_ref_info_prop {##1} + \l__csl_back_ref_tl + } + } } @@ -420,7 +465,7 @@ % #1: citation info "{<citationID>}{{id=ITEM-1},{id=ITEM-2}}{<noteIndex>}" { \if@filesw - \iow_now:Nn \@auxout { \citation {#1} } + \iow_now:Nn \@auxout { \csl@aux@cite {#1} } \fi } @@ -441,11 +486,13 @@ { \G@refundefinedtrue \msg_warning:nnn { citation-style-language } { citation / undefined } {#1} - \tl_set:Nn \l__csl_citation_tl { [ \textbf {#1} ] } + \tl_if_blank:nTF {#1} + { \tl_set:Nn \l__csl_citation_tl { [ \textbf { ? } ] } } + { \tl_set:Nn \l__csl_citation_tl { [ \textbf {#1} ] } } \bool_if:NT \l__csl_regression_test_bool { \tl_show:N \l__csl_citation_tl } \group_begin: - \reset@font [ \textbf {#1} ] + \reset@font \l__csl_citation_tl \group_end: } @@ -504,37 +551,116 @@ % Used in aux files to register cite items. % #1: a citation object -\cs_set:Npn \citation #1 +\cs_set:Npn \csl@aux@cite #1 { \sys_if_engine_luatex:T - { \lua_now:n { csl.register_citation_info("#1") } } + { \lua_now:e { csl.register_citation_info("\lua_escape:n {#1}") } } } -\cs_new:Npn \cslcite #1#2 +\cs_new:Npn \cslcitation #1#2 + { \prop_gput:Nnn \g__csl_citations_prop {#1} {#2} } + + +% This command is for use with hyperref. +% #1: cite id +% #2: cite contents +\cs_new:Npn \cslcite #1#2 {#2} + + +\keys_define:nn { csl / bibliography } { - % \if@filesw - % \iow_now:Nn \@auxout { \bibcite {#1} {#2} } - % \fi - \bibcite {#1} {#2} + type .code:n = \__csl_add_filter_condition:nn { type } {#1} , + nottype .code:n = \__csl_add_filter_condition_negative:nn { type } {#1} , % subtype .code:n = \__csl_add_filter_condition:nn { subtype } {#1} , + % notsubtype .code:n = \__csl_add_filter_condition_negative:nn { subtype } {#1} , + keyword .code:n = \__csl_add_filter_condition:nn { keyword } {#1} , + notkeyword .code:n = \__csl_add_filter_condition_negative:nn { keyword } {#1} , + category .code:n = \__csl_add_filter_condition:nn { categories } {#1} , + notcategory .code:n = \__csl_add_filter_condition_negative:nn { categories } {#1} , + % filter .tl_set:N = \l__csl_bibliography_nottype_tl , } +\seq_new:N \l__bibliography_filter_conditions_seq +\tl_new:N \l__bibliography_filter_conditions_tl -\cs_new:Npn \__csl_bibcite:nn #1#2 - { \prop_gput:Nnn \g__csl_citations_prop {#1} {#2} } +\cs_new:Npn \__csl_add_filter_condition:nn #1#2 + { + \seq_put_right:Nn \l__bibliography_filter_conditions_seq + { + { + field = #1 , + value = #2 + } + } + } -\cs_set_eq:NN \bibcite \__csl_bibcite:nn +\cs_new:Npn \__csl_add_filter_condition_negative:nn #1#2 + { + \seq_put_right:Nn \l__bibliography_filter_conditions_seq + { + { + field = #1, + value = #2, + negative = true + } + } + } \NewDocumentCommand \printbibliography { O { } } { + % Set categories + \prop_if_empty:NF \l__csl_categories_prop + { + \tl_clear:N \l_tmpa_tl + \prop_map_inline:Nn \l__csl_categories_prop + { + \tl_if_empty:NF \l_tmpa_tl + { \tl_put_right:Nn \l_tmpa_tl { , } } + \tl_put_right:Nn \l_tmpa_tl { ##1 = {##2} } + } + \sys_if_engine_luatex:T + { \lua_now:e { csl.set_categories("\l_tmpa_tl") } } + { + \tl_put_left:Nx \l_tmpa_tl { categories = \c_left_brace_str } + \tl_put_right:NV \l_tmpa_tl \c_right_brace_str + \exp_args:NV \__csl_write_aux_options:n \l_tmpa_tl + } + } + % Bibliography filter + \seq_clear:N \l__bibliography_filter_conditions_seq + \keys_set:nn { csl / bibliography } {#1} + \tl_clear:N \l__bibliography_filter_conditions_tl + \seq_if_empty:NF \l__bibliography_filter_conditions_seq + { + \tl_set:Nx \l__bibliography_filter_conditions_tl + { select = \c_left_brace_str } + \tl_put_right:Nx \l__bibliography_filter_conditions_tl + { \seq_use:Nn \l__bibliography_filter_conditions_seq { , } } + \tl_put_right:NV \l__bibliography_filter_conditions_tl + { \c_right_brace_str } + % Write to aux file + \sys_if_engine_luatex:F + { + \tl_set:Nx \l_tmpa_tl { bib-filter = \c_left_brace_str } + \tl_put_right:NV \l_tmpa_tl { \l__bibliography_filter_conditions_tl } + \tl_put_right:NV \l_tmpa_tl { \c_right_brace_str } + \exp_args:NV \__csl_write_aux_options:n \l_tmpa_tl + } + } + % Collect the bibliography to token list \sys_if_engine_luatex:T { \bool_if:NT \l__csl_engine_initialized_bool { - \__csl_collect_bibliography:n { \lua_now:n { csl.bibliography() } } + \__csl_collect_bibliography:n + { + \lua_now:e + { csl.bibliography("\l__bibliography_filter_conditions_tl") } + } } } + % Print the bibliography \tl_if_empty:NTF \g__csl_bibliography_tl { \msg_warning:nn { citation-style-language } { bibliography / empty } } { @@ -552,34 +678,54 @@ \tl_new:N \l__csl_style_tl +\newcommand \csl@style {} % For latex2e interface \tl_new:N \l__csl_class_tl \bool_new:N \l__csl_note_bool \clist_new:N \l__csl_bib_resources_clist +\tl_new:N \l__csl_locale_tl +\bool_new:N \l__csl_back_ref_bool +\str_new:N \l__csl_back_ref_type_str +% Citation formatting \tl_new:N \l__csl_prefix_separator_tl \tl_new:N \l__csl_suffix_separator_tl -\tl_new:N \l__csl_locale_tl +% Bibliography formatting +\tl_new:N \bibsection \tl_new:N \l__csl_bib_font_tl +\bool_new:N \l__csl_bib_entry_page_break_bool \tl_new:N \l__csl_bib_item_sep_tl \tl_new:N \l__csl_bib_hang_tl \bool_new:N \l__csl_hanging_indent_bool \tl_new:N \l__csl_line_spacing_tl \tl_new:N \l__csl_entry_spacing_tl +\tl_set:Nn \l__csl_back_ref_type_str { page } + \keys_define:nn { csl } { regression-test .bool_set:N = \l__csl_regression_test_bool , - style .tl_set:N = \l__csl_style_tl , + style .code:n = + { + \tl_set:Nn \l__csl_style_tl {#1} + \renewcommand \csl@style {#1} + } , class .code:n = { \tl_set:Nn \l__csl_class_tl {#1} \tl_if_eq:NnT \l__csl_class_tl { note } { \bool_set_true:N \l__csl_note_bool } } , + locale .tl_set:N = \l__csl_locale_tl , + backref .choices:nn = + { true, page, section, false } + { \exp_args:NV \__csl_set_back_ref:n \l_keys_choice_tl } , + % Citation formatting prefix-separator .tl_set:N = \l__csl_prefix_separator_tl , suffix-separator .tl_set:N = \l__csl_suffix_separator_tl , - locale .tl_set:N = \l__csl_locale_tl , + % Bibliography formatting + bib-section .tl_set:N = \bibsection , bib-font .tl_set:N = \l__csl_bib_font_tl , + bib-entry-page-break .bool_set:N = \l__csl_bib_entry_page_break_bool , bib-item-sep .tl_set:N = \l__csl_bib_item_sep_tl , bib-hang .tl_set:N = \l__csl_bib_hang_tl , hanging-indent .bool_set:N = \l__csl_hanging_indent_bool , @@ -591,11 +737,13 @@ { prefix-separator = { ~ } , suffix-separator = { , ~ } , + bib-entry-page-break = true , bib-hang = { 1 em } , line-spacing = { 1 } , entry-spacing = { 1 } , } + \ProcessKeysPackageOptions { csl } \bool_new:N \l__csl_engine_initialized_bool @@ -737,7 +885,10 @@ \cs_new:Npn \__csl_write_aux_info: { \tl_if_empty:NTF \l__csl_style_tl - { \tl_set_eq:NN \l__csl_style_tl \g__csl_aux_bibstyle_tl } + { + \tl_set_eq:NN \l__csl_style_tl \g__csl_aux_bibstyle_tl + \edef \csl@style { \g__csl_aux_bibstyle_tl } + } { \exp_args:Nx \__csl_write_aux_bibstyle:n { \l__csl_style_tl } } \clist_if_empty:NTF \l__csl_bib_resources_clist { \clist_set_eq:NN \l__csl_bib_resources_clist \g__csl_aux_bib_files_clist } @@ -751,7 +902,7 @@ \cs_new:Npn \__csl_write_aux_bibstyle:n #1 { \if@filesw - \iow_now:Nx \@auxout { \token_to_str:N \bibstyle {#1} } + \iow_now:Nx \@auxout { \token_to_str:N \csl@aux@style {#1} } \fi } @@ -823,13 +974,13 @@ \cs_new:Npn \__csl_write_aux_options:n #1 { \if@filesw - \iow_now:Nn \@auxout { \csloptions {#1} } + \iow_now:Nn \@auxout { \csl@aux@options {#1} } \fi } % Load .bbl at the beginning of document to save one pass of latex. -% In this procedure, the \cslcite command is processed and the contents +% In this procedure, the \cslcitation command is processed and the contents % of `thebibliography` is stored into \g__csl_bibliography_tl. \cs_new:Npn \__csl_load_bbl: { @@ -883,7 +1034,7 @@ } \tl_new:N \g__csl_aux_bibstyle_tl -\cs_set:Npn \bibstyle #1 +\cs_set:Npn \csl@aux@style #1 { \tl_gset:Nn \g__csl_aux_bibstyle_tl {#1} } @@ -895,7 +1046,7 @@ % to find xxx.json.bib and it refuses to run the $bibtex procedure. % John Collins suggests using a different command than \bibdata. \clist_new:N \g__csl_aux_bib_files_clist -\cs_new:Npn \csl@data #1 +\cs_new:Npn \csl@aux@data #1 { \clist_gput_right:Nn \g__csl_aux_bib_files_clist {#1} } @@ -909,35 +1060,134 @@ { \if@filesw % Full expansion for files like \jobname.bib - \iow_now:Nx \@auxout { \token_to_str:N \csl@data {#1} } + \iow_now:Nx \@auxout { \token_to_str:N \csl@aux@data {#1} } \fi } % Used for debugging and testing \clist_new:N \g__csl_bib_items_clist +% Backref +\bool_set_false:N \l__csl_back_ref_bool % For numeric or label-style bibliography % \def\@lbibitem[#1]#2{\item[\@biblabel{#1}\hfill]\if@filesw % {\let\protect\noexpand % \immediate % \write\@auxout{\string\bibcite{#2}{#1}}}\fi\ignorespaces} -\cs_new:Npn \__csl_lbibitem:nn [#1]#2 +\cs_new:Npn \__csl_lbibitem_plain:nn [#1]#2 { \clist_gput_right:Nn \g__csl_bib_items_clist {#2} - \item [ \@biblabel {#1} \hfill ] \ignorespaces + \item [ \@biblabel {#1} \hfill ] + \ignorespaces + } + +\cs_new:Npn \__csl_lbibitem_back_ref:nnn [#1]#2#3\par + { + \__csl_lbibitem_plain:nn [#1] {#2} + #3 + \prop_get:NnNT \g__csl_back_ref_info_prop {#2} \l_tmpa_tl + { + \c_space_tl + \exp_args:NV \__csl_print_back_refs:n \l_tmpa_tl + } + \par + } + +\cs_new:Npn \__csl_print_back_refs:n #1 + % #1: list of {<page>}{<label>}{anchor} + { + \clist_set:Nn \l_tmpa_clist {#1} + % To remove duplicates + \prop_clear:N \l_tmpa_prop + % Output seq + \seq_clear:N \l_tmpa_seq + \clist_map_inline:Nn \l_tmpa_clist { \__csl_print_back_ref_aux:nnn ##1 } + \backref { \seq_use:Nn \l_tmpa_seq { ,~ } } + } + +\cs_new:Npn \__csl_print_back_ref_aux:nnn #1#2#3 + { + \str_if_eq:VnTF \l__csl_back_ref_type_str { page } + { + \prop_if_in:NnF \l_tmpa_prop {#1} + { + \bool_if:NTF \l__csl_hyperref_loaded_bool + { \seq_put_right:Nn \l_tmpa_seq { \hyperlink { page. #1 } {#1} } } + { \seq_put_right:Nn \l_tmpa_seq {#1} } + \prop_put:Nnn \l_tmpa_prop {#1} {#1} + } + } + { + % section + \prop_if_in:NnF \l_tmpa_prop {#2} + { + \bool_if:NTF \l__csl_hyperref_loaded_bool + { \seq_put_right:Nn \l_tmpa_seq { \hyperlink {#3} {#2} } } + { \seq_put_right:Nn \l_tmpa_seq {#2} } + \prop_put:Nnn \l_tmpa_prop {#2} {#2} + } + } + } + +% Hook +\cs_new:Npn \backref #1 {#1} + +\cs_new:Npn \__csl_lbibitem: + { + \bool_if:NTF \l__csl_back_ref_bool + { \__csl_lbibitem_back_ref:nnn } + { \__csl_lbibitem_plain:nn } } -\cs_set_eq:NN \@lbibitem \__csl_lbibitem:nn + +\cs_set_eq:NN \@lbibitem \__csl_lbibitem: + % For author-date bibliography % \def\@bibitem#1{\item\if@filesw \immediate\write\@auxout % {\string\bibcite{#1}{\the\value{\@listctr}}}\fi\ignorespaces} -\cs_new:Npn \__csl_bibitem:n #1 +\cs_new:Npn \__csl_bibitem: + { + \bool_if:NTF \l__csl_back_ref_bool + { \__csl_bibitem_back_ref:nn } + { \__csl_bibitem_plain:n } + } + +\cs_set_eq:NN \@bibitem \__csl_bibitem: + +\cs_new:Npn \__csl_bibitem_plain:n #1 { \clist_gput_right:Nn \g__csl_bib_items_clist {#1} - \item [ ] \ignorespaces + \item + \ignorespaces + } + +\cs_new:Npn \__csl_bibitem_back_ref:nn #1#2\par + { + \__csl_bibitem_plain:n {#1} + #2 + % \prop_show:N \g__csl_back_ref_info_prop + \prop_get:NnNT \g__csl_back_ref_info_prop {#1} \l_tmpa_tl + { + \c_space_tl + \exp_args:NV \__csl_print_back_refs:n \l_tmpa_tl + } + \par + } + +\cs_new:Npn \__csl_set_back_ref:n #1 + { + \str_if_eq:nnTF {#1} {false} + { + \bool_set_false:N \l__csl_back_ref_bool + } + { + \bool_set_true:N \l__csl_back_ref_bool + \str_if_eq:nnTF {#1} {true} + { \str_set:Nn \l__csl_back_ref_type_str { page } } + { \str_set:Nn \l__csl_back_ref_type_str {#1} } + } } -\cs_set_eq:NN \@bibitem \__csl_bibitem:n % CSL outputs the whole label thus the brackets are removed from \@biblabel @@ -945,9 +1195,10 @@ \cs_set:Npn \@biblabel #1 {#1} +% Bibliography heading \cs_if_exist:cTF { chapter } { - \cs_set:Nn \__csl_bib_section: + \tl_set:Nn \bibsection { \chapter* { @@ -959,7 +1210,7 @@ } } { - \cs_set:Nn \__csl_bib_section: + \tl_set:Nn \bibsection { \section* { @@ -976,7 +1227,6 @@ \tl_new:N \l__csl_bib_postamble_tl \dim_new:N \l__csl_bib_hang_dim -\skip_new:N \l__csl_bib_item_sep_skip \cs_new:Npn \__csl_set_bib_label_spacing:n #1 { @@ -993,20 +1243,26 @@ } } +% In standard LaTeX classes (10pt), the vertical sep of bibliographic item is +% \itemsep (4\p@ \@plus2\p@ \@minus\p@) + \parsep (4\p@ \@plus2\p@ \@minus\p@) +% = 8pt plus 4pt minus 2pt \cs_new:Npn \__csl_set_bib_item_sep: { \skip_zero:N \parsep \tl_if_empty:NTF \l__csl_bib_item_sep_tl { - \skip_set:Nn \l__csl_bib_item_sep_skip + \skip_set:Nn \itemsep { 8 pt plus 4 pt minus 2 pt * \dim_ratio:nn { 1 em } { 8 pt } * \l__csl_entry_spacing_tl } } - { \skip_set:Nn \l__csl_bib_item_sep_skip { \l__csl_bib_item_sep_tl } } + { \skip_set:Nn \itemsep { \l__csl_bib_item_sep_tl } } } + +% See <https://github.com/plk/biblatex/blob/e16f4aaa5d9857c7b844bbcbe246f0535fd334e9/tex/latex/biblatex/biblatex.def#L219-L258> + \cs_new:Npn \__csl_set_bib_allow_break: { \sloppy @@ -1017,8 +1273,6 @@ \frenchspacing } -\cs_new_eq:NN \__csl_set_bib_page_break: \__csl_set_bib_allow_break: - \cs_new:Npn \__csl_set_bib_no_break: { \sloppy @@ -1030,6 +1284,13 @@ \frenchspacing } +\cs_new:Npn \__csl_set_bib_page_break: + { + \bool_if:NTF \l__csl_bib_entry_page_break_bool + { \__csl_set_bib_allow_break: } + { \__csl_set_bib_no_break: } + } + % Taken from `biblatex`'s \biburlsetup % https://github.com/plk/biblatex/blob/dev/tex/latex/biblatex/biblatex.def @@ -1152,7 +1413,7 @@ % \newenvironment{thebibliography}[1] \RenewDocumentEnvironment { thebibliography } { m } { - \__csl_bib_section: + \bibsection \dim_zero:N \parindent \l__csl_bib_preamble_tl \tl_if_eq:NnF \l__csl_line_spacing_tl { 1 } @@ -1178,12 +1439,41 @@ } +% Bibliography Categories + +\prop_new:N \l__csl_categories_prop + +% \DeclareBibliographyCategory{⟨category⟩} +\NewDocumentCommand \DeclareBibliographyCategory { m } + { + \prop_put:Nnn \l__csl_categories_prop { #1 } { } + } + +% \addtocategory{⟨category⟩}{⟨keys⟩} +\NewDocumentCommand \addtocategory { m m } + { + \prop_get:NnNTF \l__csl_categories_prop {#1} \l_tmpa_tl + { + \tl_if_empty:NF \l_tmpa_tl + { \tl_put_right:Nn \l_tmpa_tl { , } } + \tl_put_right:Nn \l_tmpa_tl {#2} + \prop_put:NnV \l__csl_categories_prop {#1} \l_tmpa_tl + } + { + \msg_error:nnn { citation-style-language } { category-not-declared } + {#1} + } + } + + +\msg_new:nnn { citation-style-language } { category-not-declared } + { Category~ '#1'~ not~ declared. } + % Compatibilities with other packages % babel -% The `babel` package redefines \bibcite in the \@begindocumenthook. % This should be disabled. \AtEndOfPackageFile* { babel } { @@ -1194,9 +1484,9 @@ \__csl_no_cite:n {#1} \@safe@activesfalse } - \cs_set_eq:NN \bibcite \__csl_bibcite:nn \cs_set_eq:NN \bbl@cite@choice \relax - \cs_set_eq:NN \@bibitem \__csl_bibitem:n + \cs_set_eq:NN \@lbibitem \__csl_lbibitem_plain:nn + \cs_set_eq:NN \@bibitem \__csl_bibitem_plain:n } @@ -1216,12 +1506,54 @@ % The hyperref package also patches \bibcite but it cannot provide hyperlinks % when used with csl. +\bool_new:N \l__csl_hyperref_loaded_bool \AtEndOfPackageFile* { hyperref } { - \cs_set_eq:NN \bibcite \__csl_bibcite:nn - \cs_set_eq:NN \Hy@bibcite \bibcite - \cs_gset_eq:NN \@lbibitem \__csl_lbibitem:nn - \cs_gset_eq:NN \@bibitem \__csl_bibitem:n + \bool_set_true:N \l__csl_hyperref_loaded_bool + % Pakcage "hyperref" redefines \@lbibitem and \bibitem and we need to + % recover them. + \cs_gset_eq:NN \@lbibitem \__csl_lbibitem: + \cs_gset_eq:NN \@bibitem \__csl_bibitem: + \cs_gset_eq:NN \__csl_lbibitem_plain:nn \__csl_hyperref_lbibitem:nn + \cs_gset_eq:NN \__csl_bibitem_plain:n \__csl_hyperref_bibitem:n + \cs_gset_eq:NN \cslcite \__csl_hyperref_cite_item:nn + } + +\cs_set:Npn \__csl_hyperref_cite_item:nn #1#2 + { \hyper@@link [ cite ] { } { cite. #1 \@extra@b@citeb } { #2 } } + +\cs_new:Npn \__csl_hyperref_lbibitem:nn [#1]#2 + { + \clist_gput_right:Nn \g__csl_bib_items_clist {#2} + \@skiphyperreftrue + \H@item[% + \ifx\Hy@raisedlink\@empty + \hyper@anchorstart{cite.#2\@extra@b@citeb}% + \@BIBLABEL{#1}% + \hyper@anchorend + \else + \Hy@raisedlink{% + \hyper@anchorstart{cite.#2\@extra@b@citeb}\hyper@anchorend + }% + \@BIBLABEL{#1}% + \fi + \hfill + ]% + \@skiphyperreffalse + \ignorespaces + } + +\cs_new:Npn \__csl_hyperref_bibitem:n #1 + { + \clist_gput_right:Nn \g__csl_bib_items_clist {#1} + \@skiphyperreftrue \H@item \@skiphyperreffalse + \Hy@raisedlink + { + \hyper@anchorstart + { cite. #1 \@extra@b@citeb } \relax + \hyper@anchorend + } + \ignorespaces } |