% % Copyright (c) 2021-2025 Zeping Lee % Released under the MIT License. % Repository: https://github.com/zepinglee/citeproc-lua % % ## Bibliography commands % The options like `notcategory` can be used multiple times and thus we save % them into a seq instead of a prop. \seq_new:N \l__csl_bib_filter_seq \int_new:N \g__csl_bib_list_index_int \tl_new:N \g__csl_bib_list_index_tl \tl_new:N \l__csl_bibliography_tl \seq_new:N \l__csl_bibliography_seq \NewDocumentCommand \printbibliography { O { } } { \int_gincr:N \g__csl_bib_list_index_int \tl_gset:Ne \g__csl_bib_list_index_tl { \int_use:N \g__csl_bib_list_index_int } \__csl_set_categories: % Bibliography filter \group_begin: \seq_clear:N \l__csl_bib_filter_seq \seq_put_right:Ne \l__csl_bib_filter_seq { index = \g__csl_bib_list_index_tl } \keys_set:nn { csl / bibliography } {#1} \__csl_serialize_seq:NN \l__csl_bib_filter_seq \l__csl_bib_filter_tl % Collect the bibliography to token list \sys_if_engine_luatex:TF { \bool_if:NT \l__csl_engine_initialized_bool { \__csl_collect_bibliography:n { \lua_now:e { csl_citation_manager:bibliography("\l__csl_bib_filter_tl") } } } } { % Write to aux file \exp_args:NV \__csl_write_aux_bibliography:n \l__csl_bib_filter_tl } % Print the bibliography \prop_get:NVNTF \g__csl_bibliographies_prop \g__csl_bib_list_index_tl \l__csl_bibliography_tl { \bool_if:NT \l__csl_regression_test_bool { \seq_set_split:NnV \l__csl_bibliography_seq { \par } \l__csl_bibliography_tl \seq_show:N \l__csl_bibliography_seq } \tl_use:N \l__csl_bibliography_tl } { \msg_warning:nn { citation-style-language } { empty-bibliography } } \group_end: } \msg_new:nnn { citation-style-language } { empty-bibliography } { The~ bibliography~ is~ empty. } \DeclareDocumentCommand \bibliography { m } { \clist_map_inline:nn {#1} { \exp_args:Ne \__csl_write_aux_bibdata:nn {##1} {} } \printbibliography \relax } \tl_new:N \l__csl_bib_env_tl \tl_new:N \l__csl_bib_head_name_tl \tl_new:N \l__csl_bib_head_title_tl \tl_new:N \l__csl_bib_head_label_tl \tl_new:N \l__csl_bib_pre_note_tl \tl_new:N \l__csl_bib_post_note_tl \tl_new:N \l__csl_bib_filter_tl \tl_set:Nn \l__csl_bib_env_tl { bibliography } \tl_set:Nn \l__csl_bib_head_name_tl { bibliography } \keys_define:nn { csl / bibliography } { % env .tl_set:N = \l__csl_bib_env_name_tl , heading .tl_set:N = \l__csl_bib_head_name_tl , title .tl_set:N = \l__csl_bib_head_title_tl , label .tl_set:N = \l__csl_bib_head_label_tl , % block prenote .tl_set:N = \l__csl_bib_pre_note_tl , postnote .tl_set:N = \l__csl_bib_post_note_tl , % section % segment type .code:n = { \seq_put_right:Nn \l__csl_bib_filter_seq { type = {#1} } } , nottype .code:n = { \seq_put_right:Nn \l__csl_bib_filter_seq { nottype = {#1} } } , % subtype .code:n = { \seq_put_right:Nn \l__csl_bib_filter_seq { subtype = {#1} } } , % notsubtype .code:n = { \seq_put_right:Nn \l__csl_bib_filter_seq { notsubtype = {#1} } } , keyword .code:n = { \seq_put_right:Nn \l__csl_bib_filter_seq { keyword = {#1} } } , notkeyword .code:n = { \seq_put_right:Nn \l__csl_bib_filter_seq { notkeyword = {#1} } } , category .code:n = { \seq_put_right:Nn \l__csl_bib_filter_seq { category = {#1} } } , notcategory .code:n = { \seq_put_right:Nn \l__csl_bib_filter_seq { notcategory = {#1} } } , % filter .tl_set:N = \l__csl_bibliography_nottype_tl , } \cs_new:Npn \__csl_write_aux_bibliography:n #1 { \if@filesw \iow_now:Ne \@auxout { \token_to_str:N \csl@aux@bibliography { \int_use:N \g__csl_ref_section_index_int } {#1} } \fi } \cs_new:Npn \csl@aux@bibliography #1#2 { } \tl_new:N \l__csl_bib_index_tl \bool_new:N \l__csl_hanging_indent_bool \bool_new:N \l__csl_second_field_align_flush_bool \bool_new:N \l__csl_second_field_align_margin_bool \tl_new:N \l__csl_line_spacing_tl \tl_new:N \l__csl_entry_spacing_tl \tl_new:N \l__csl_bib_widest_label_tl \keys_define:nn { csl / bib-options } { index .tl_set:N = \l__csl_bib_index_tl , second-field-align .choice:, second-field-align / flush .code:n = { \bool_set_true:N \l__csl_second_field_align_flush_bool \bool_set_false:N \l__csl_second_field_align_margin_bool } , second-field-align / margin .code:n = { \bool_set_false:N \l__csl_second_field_align_flush_bool \bool_set_true:N \l__csl_second_field_align_margin_bool } , second-field-align / false .code:n = { \bool_set_false:N \l__csl_second_field_align_flush_bool \bool_set_false:N \l__csl_second_field_align_margin_bool } , hanging-indent .bool_set:N = \l__csl_hanging_indent_bool , line-spacing .tl_set:N = \l__csl_line_spacing_tl , entry-spacing .tl_set:N = \l__csl_entry_spacing_tl , widest-label .tl_set:N = \l__csl_bib_widest_label_tl , } \keys_set:nn { csl / bib-options } { index = 1 , second-field-align = false , hanging-indent = false , line-spacing = 1 , entry-spacing = 1 , widest-label = { } , } \RenewDocumentEnvironment { thebibliography } { m } { \exp_args:NVV \__csl_make_bib_heading:nn \l__csl_bib_head_name_tl \l__csl_bib_head_title_tl \exp_args:NV \__csl_print_bib_note:n \l__csl_bib_pre_note_tl \group_begin: \tl_set:Nn \l__csl_bib_index_tl { 1 } \keys_set:nn { csl / bib-options } {#1} \tl_if_eq:NnF \l__csl_line_spacing_tl { 1 } { \linespread { \l__csl_line_spacing_tl } \selectfont } \l__csl_bib_font_tl \list { } { \__csl_set_bib_label_spacing:n { \l__csl_bib_widest_label_tl } \__csl_set_bib_item_sep: } \sloppy \__csl_set_bib_page_break: \frenchspacing \__csl_bib_url_setup: } { \tl_set:Nn \@noitemerr { \msg_warning:nn { citation-style-language } { empty-bibliography } } \endlist \group_end: \exp_args:NV \__csl_print_bib_note:n \l__csl_bib_post_note_tl } % ### Bibliography spacing \dim_new:N \l__csl_bib_hang_dim \cs_new:Npn \__csl_set_bib_label_spacing:n #1 { \bool_if:NTF \l__csl_hanging_indent_bool { \dim_set:Nn \l__csl_bib_hang_dim { \l__csl_bib_hang_tl } \dim_set_eq:NN \leftmargin \l__csl_bib_hang_dim \dim_set:Nn \itemindent { - \leftmargin } } { \bool_if:NTF \l__csl_second_field_align_flush_bool { \settowidth \labelwidth { \@biblabel {#1} } \dim_set_eq:NN \leftmargin \labelwidth \dim_add:Nn \leftmargin { \labelsep } } { \bool_if:NTF \l__csl_second_field_align_margin_bool { \dim_zero:N \leftmargin \settowidth \labelwidth { \@biblabel {#1} } \dim_add:Nn \leftmargin { \labelsep } } { \dim_zero:N \leftmargin \dim_set:Nn \itemindent { \l__csl_bib_par_indent_tl } } } } } % 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 \itemsep { 8 pt plus 4 pt minus 2 pt * \dim_ratio:nn { 1 em } { 8 pt } * \l__csl_entry_spacing_tl } } { \skip_set:Nn \itemsep { \l__csl_bib_item_sep_tl } } } % ### Bibliography label % CSL outputs the whole label thus the brackets are removed from \@biblabel % \def\@biblabel#1{[#1]} \cs_set:Npn \@biblabel #1 {#1} % For numeric or label-style bibliography: \bibitem[{[17]}]{entrykey} % \@lbibitem is redefined in `babel` and `hyperref` and we need to override it % in the patching code. Thus we define \__csl_lbibitem: here and reassign it to % \@lbibitem in compatability code \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: \cs_new:Npn \__csl_lbibitem_plain:nn [#1]#2 { \item [ \@biblabel {#1} \hfill ] \ignorespaces } % This is the version for use with backref feature. \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_if_free:NT \backref { \cs_new:Npn \backref #1 {#1} } % 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: { \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 { \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 } % ### Bibliography sections and segments \int_new:N \g__csl_ref_section_index_int \int_new:N \g__csl_max_ref_section_index_int \int_gset:Nn \g__csl_ref_section_index_int { 0 } \int_gset:Nn \g__csl_max_ref_section_index_int { 0 } \keys_define:nn { csl / ref-section } { style .code:n = { \tl_set:Nn \l__csl_style_tl {#1} \renewcommand \csl@style {#1} } , bib-resource .code:n = { \clist_clear:N \l__csl_bib_resources_clist \clist_map_inline:nn {#1} { \clist_put_right:Ne \l__csl_bib_resources_clist {##1} } } , locale .tl_set:N = \l__csl_locale_tl , } \NewDocumentCommand \refsection { O { } } { \int_gincr:N \g__csl_max_ref_section_index_int \int_gset_eq:NN \g__csl_ref_section_index_int \g__csl_max_ref_section_index_int \tl_clear:N \l__csl_style_tl \clist_clear:N \l__csl_bib_resources_clist \tl_clear:N \l__csl_locale_tl \keys_set:nn { csl / ref-section } { #1 } \tl_if_empty:NTF \l__csl_style_tl { \tl_set_eq:NN \l__csl_style_tl \g__csl_global_style_tl \tl_set_eq:NN \csl@style \l__csl_style_tl } { \tl_set_eq:NN \csl@style \l__csl_style_tl \exp_args:NV \__csl_write_aux_bibstyle:n \l__csl_style_tl } \clist_if_empty:NF \l__csl_bib_resources_clist { \clist_map_inline:Nn \l__csl_bib_resources_clist { \exp_args:Ne \__csl_write_aux_bibdata:nn {##1} { } } } \tl_if_empty:NTF \l__csl_locale_tl { \tl_set_eq:NN \l__csl_locale_tl \g__csl_global_locale_tl } { \exp_args:Ne \__csl_write_aux_options:n { locale = \l__csl_locale_tl } } \sys_if_engine_luatex:TF { \lua_now:e { csl_citation_manager:begin_ref_section( "\l__csl_style_tl", "\clist_use:Nn \l__csl_bib_resources_clist { , }", "\l__csl_locale_tl" ) } \str_if_eq:eeTF { \lua_now:n { tex.print(tostring( csl_citation_manager.ref_section.initialized )) } } { true } { \bool_set_true:N \l__csl_engine_initialized_bool } { \bool_set_false:N \l__csl_engine_initialized_bool } \__csl_get_style_class_luatex: } { \__csl_get_style_class: } \__csl_read_entry_ids: } \NewCommandCopy \newrefsection \refsection \cs_new:Npn \endrefsection { \int_compare:nNnT { \g__csl_ref_section_index_int } > { 0 } { \int_gzero:N \g__csl_ref_section_index_int \sys_if_engine_luatex:T { \lua_now:n { csl_citation_manager:end_ref_section() } } \__csl_read_entry_ids: } } % ### Bibliography Headings and Environments \prop_new:N \l__csl_bib_env_begin_prop \prop_new:N \l__csl_bib_env_end_prop \prop_new:N \l__csl_bib_item_prop % \defbibenvironment{⟨name⟩}{⟨begin code⟩}{⟨end code⟩}{⟨item code⟩} \NewDocumentCommand { \defbibenvironment } { m m m m } { \prop_put:Nnn \l__csl_bib_env_begin_prop {#1} {#2} \prop_put:Nnn \l__csl_bib_env_end_prop {#1} {#3} \prop_put:Nnn \l__csl_bib_item_prop {#1} {#4} } % \defbibenvironment { bibliography } % { } % #1: bib heading name % #2: bib heading title \cs_new:Npn \__csl_make_bib_heading:nn #1#2 { \tl_if_empty:NTF \bibsection { \cs_if_exist:cF { __csl_head_ #1 :n } { \msg_error:nnn { citation-style-language } { undefined-bib-heading } {#1} } \tl_if_blank:nTF {#2} { \use:c { __csl_head_ #1 :n } } { \use:c { __csl_head_ #1 :n } [#2] } } { \bibsection } \tl_if_empty:NF \l__csl_bib_head_label_tl { \exp_args:NV \label \l__csl_bib_head_label_tl } } \msg_new:nnn { citation-style-language } { undefined-bib-heading } { Bibliography~ heading~ '#1'~ undefined. } \keys_define:nn { csl / bib-heading } { heading .tl_set:N = \l__csl_bib_head_name_tl , title .tl_set:N = \l__csl_bib_head_title_tl , % label } \cs_new:Npn \__csl_reset_heading_options: { \tl_set:Nn \l__csl_bib_head_name_tl { bibliography } \tl_set:Nn \l__csl_bib_head_title_tl { } } \NewDocumentCommand { \printbibheading } { O { } } { % We can't use a group here. % See <https://github.com/plk/biblatex/issues/1278>. \__csl_reset_heading_options: \keys_set:nn { csl / bib-heading } {#1} \exp_args:NVV \__csl_make_bib_heading:nn \l__csl_bib_head_name_tl \l__csl_bib_head_title_tl \__csl_reset_heading_options: } % \defbibheading { ⟨name⟩}[⟨title⟩]{⟨code⟩} \NewDocumentCommand { \defbibheading } { m O { \bibname } } { \expandafter \newcommand \csname __csl_head_ #1 :n \endcsname [1] [ {#2} ] } \cs_if_exist:NF \refname { \cs_set:Npn \refname { References } } \cs_if_exist:NTF \chapter { % `book` or `report` \defbibheading { bibliography } [ \bibname ] { \chapter* {#1} \@mkboth { \MakeUppercase {#1} } { \MakeUppercase {#1} } } \defbibheading { biblist } [ \biblistname ] { \chapter* {#1} \@mkboth { \MakeUppercase {#1} } { \MakeUppercase {#1} } } \defbibheading { bibintoc } [ \bibname ] { \chapter* {#1} \addcontentsline { toc } { chapter } {#1} \@mkboth { \MakeUppercase {#1} } { \MakeUppercase {#1} } } \defbibheading { biblistintoc } [ \biblistname ] { \chapter* {#1} \addcontentsline { toc } { chapter } {#1} \@mkboth { \MakeUppercase {#1} } { \MakeUppercase {#1} } } \defbibheading { bibnumbered } [ \bibname ] { \chapter {#1} } \defbibheading { biblistnumbered } [ \biblistname ] { \chapter {#1} } \defbibheading { subbibliography } [ \refname ] { \section* {#1} \if@twoside \markright { \MakeUppercase {#1} } \fi } \defbibheading { subbibintoc } [ \refname ] { \section* {#1} \addcontentsline { toc } { section } {#1} \if@twoside \markright { \MakeUppercase {#1} } \fi } \defbibheading { subbibnumbered } [ \refname ] { \section {#1} } } { % `article` \defbibheading { bibliography } [ \refname ] { \section* {#1} \@mkboth { \MakeUppercase {#1} } { \MakeUppercase {#1} } } \defbibheading { biblist } [ \biblistname ] { \section* {#1} \@mkboth { \MakeUppercase {#1} } { \MakeUppercase {#1} } } \defbibheading { bibintoc } [ \refname ] { \section* {#1} \addcontentsline { toc } { section } {#1} \@mkboth { \MakeUppercase {#1} } { \MakeUppercase {#1} } } \defbibheading { biblistintoc } [ \biblistname ] { \section* {#1} \addcontentsline { toc } { section } {#1} \@mkboth { \MakeUppercase {#1} } { \MakeUppercase {#1} } } \defbibheading { bibnumbered } [ \refname ] { \section {#1} } \defbibheading { biblistnumbered } [ \biblistname ] { \section {#1} } \defbibheading { subbibliography } [ \refname ] { \subsection* {#1} } \defbibheading { subbibintoc } [ \refname ] { \subsection* {#1} \addcontentsline { toc } { subsection } {#1} } \defbibheading { subbibnumbered } [ \refname ] { \subsection {#1} } } \defbibheading { none } { } % Bibliography notes \prop_new:N \l__csl_bib_notes_prop % #1: name % #2: text \NewDocumentCommand { \defbibnote } { m m } { \prop_put:Nnn \l__csl_bib_notes_prop {#1} {#2} } % #1: note name \cs_new:Npn \__csl_print_bib_note:n #1 { \tl_if_empty:nF {#1} { \prop_get:NnNF \l__csl_bib_notes_prop {#1} \l_tmpa_tl { \msg_error:nnn { citation-style-language } { undefined-bib-note } {#1} } \tl_if_empty:NF \l_tmp_tl { \group_begin: % \cs_set_eq:NN \newrefsection \relax % \cs_set_eq:NN \newrefsegment \relax \noindent \tl_use:N \l_tmpa_tl \par \nobreak \group_end: } } } \msg_new:nnn { citation-style-language } { undefined-bib-note } { Bibliography~ note~ '#1'~ undefined. } % ### 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} } } % Set categories in Lua module or write to aux file. % This procesure is at `\printbibligoraphy` to allow \addtocategory in main text. \cs_new:Npn \__csl_set_categories: { % 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_citation_manager:set_categories("\l_tmpa_tl") } } { \tl_put_left:Ne \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 } } } \msg_new:nnn { citation-style-language } { category-not-declared } { Category~ '#1'~ not~ declared. } % ### Page break in bibliography % See <https://github.com/plk/biblatex/blob/e16f4aaa5d9857c7b844bbcbe246f0535fd334e9/tex/latex/biblatex/biblatex.def#L219-L258> \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: } } % The following code allows linebreaks before numbers and letters. % This is often the only way to break DOIs. It also allows breaks % after hyphens and adjusts \Urlmuskip to add some stretchability % to URLs. \cs_new:Npn \__csl_set_bib_allow_break: { \sloppy \int_set:Nn \clubpenalty { 4000 } \int_set_eq:NN \@clubpenalty \clubpenalty \int_set:Nn \widowpenalty { 4000 } % \sfcode`\.\@m \frenchspacing } \cs_new:Npn \__csl_set_bib_no_break: { \sloppy \int_set:Nn \interlinepenalty { 5000 } \int_set:Nn \widowpenalty { 10000 } \int_set:Nn \clubpenalty { 10000 } \int_set_eq:NN \@clubpenalty \clubpenalty \raggedbottom \frenchspacing } % ### Urls in bibliography % Taken from `biblatex`'s \biburlsetup % https://github.com/plk/biblatex/blob/dev/tex/latex/biblatex/biblatex.def \int_new:N \l__csl_url_big_break_penalty_int \int_new:N \l__csl_url_break_penalty_int \int_new:N \l__csl_url_num_penalty_int \int_new:N \l__csl_url_uc_penalty_int \int_new:N \l__csl_url_lc_penalty_int \int_set:Nn \l__csl_url_big_break_penalty_int { 100 } \int_set:Nn \l__csl_url_break_penalty_int { 200 } % Allow linebreaks before numbers and letters. % Taken from `xurl.sty`. \int_set:Nn \l__csl_url_num_penalty_int { 9000 } \int_set:Nn \l__csl_url_uc_penalty_int { 9000 } \int_set:Nn \l__csl_url_lc_penalty_int { 8000 } \muskip_new:N \l__csl_url_big_muskip \muskip_new:N \l__csl_url_num_muskip \muskip_new:N \l__csl_url_uc_muskip \muskip_new:N \l__csl_url_lc_muskip \muskip_set:Nn \l__csl_url_big_muskip { 0mu plus 3mu } \muskip_set:Nn \l__csl_url_num_muskip { 0mu } \muskip_set:Nn \l__csl_url_uc_muskip { 0mu } \muskip_set:Nn \l__csl_url_lc_muskip { 0mu } \cs_new:Npn \__csl_bib_url_setup: { \urlstyle { same } \muskip_set_eq:NN \Urlmuskip \l__csl_url_big_muskip \mathchardef \UrlBigBreakPenalty = \l__csl_url_big_break_penalty_int \mathchardef \UrlBreakPenalty = \l__csl_url_break_penalty_int % \int_set_eq:NN doesn't work here % \int_set_eq:NN \UrlBigBreakPenalty \l__csl_url_big_break_penalty_int % \int_set_eq:NN \UrlBreakPenalty \l__csl_url_break_penalty_int \tl_set:Nn \UrlBigBreaks { \do \: \do \- } \tl_set:Nn \UrlBreaks { \do \. \do \@ \do \/ \do \\ \do \! \do \_ \do \| \do \; \do \> \do \] \do \) \do \} \do \, \do \? \do \' \do \+ \do \= \do \# \do \$ \do \& \do \* \do \^ \do \" } \int_compare:nNnT { \l__csl_url_num_penalty_int } > { 0 } { \clist_map_inline:nn { \1 , \2 , \3 , \4 , \5 , \6 , \7 , \8 , \9 , \0 } { \tl_put_right:Nn \UrlSpecials { \do ##1 { \mathchar`##1 \mskip \l__csl_url_num_muskip \penalty \l__csl_url_num_penalty_int } } } } \int_compare:nNnT { \l__csl_url_uc_penalty_int } > { 0 } { \clist_map_inline:nn { \A , \B , \C , \D , \E , \F , \G , \H , \I , \J , \K , \L , \M , \N , \O , \P , \Q , \R , \S , \T , \U , \V , \W , \X , \Y , \Z } { \tl_put_right:Nn \UrlSpecials { \do ##1 { \mathchar`##1 \mskip \l__csl_url_uc_muskip \penalty \l__csl_url_uc_penalty_int } } } } \int_compare:nNnT { \l__csl_url_lc_penalty_int } > { 0 } { \clist_map_inline:nn { \a , \b , \c , \d , \e , \f , \g , \h , \i , \j , \k , \l , \m , \n , \o , \p , \q , \r , \s , \t , \u , \v , \w , \x , \y , \z } { \tl_put_right:Nn \UrlSpecials { \do ##1 { \mathchar`##1 \mskip \l__csl_url_lc_muskip \penalty \l__csl_url_lc_penalty_int } } } } \cs_set_eq:NN \do \exp_not:N }