diff options
author | Karl Berry <karl@freefriends.org> | 2023-04-13 20:25:26 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2023-04-13 20:25:26 +0000 |
commit | 420c1f47d0310e6ddd588722438974466fd6ccb7 (patch) | |
tree | ccf51ee48ed7922ec1803921ad164a268aa445aa /Master/texmf-dist/tex/latex/citation-style-language | |
parent | 5c1dc3fcaff20eac79b374c15b1b89ee3c0a2721 (diff) |
citation-style-language (13apr23)
git-svn-id: svn://tug.org/texlive/trunk@66838 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/citation-style-language')
6 files changed, 1683 insertions, 1443 deletions
diff --git a/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-bib.sty b/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-bib.sty new file mode 100644 index 00000000000..ee8f33d5046 --- /dev/null +++ b/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-bib.sty @@ -0,0 +1,714 @@ +% +% Copyright (c) 2021-2023 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__bib_list_index_int +\tl_new:N \g__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__bib_list_index_int + \tl_gset:Nx \g__bib_list_index_tl { \int_use:N \g__bib_list_index_int } + \__csl_set_categories: + % Bibliography filter + \group_begin: + \seq_clear:N \l__csl_bib_filter_seq + \seq_put_right:Nx \l__csl_bib_filter_seq + { index = \g__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.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__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 } { bibliography / empty } } + \group_end: + } + +\msg_new:nnn { citation-style-language } { bibliography / empty } + { The~ bibliography~ is~ empty. } + +\DeclareDocumentCommand \bibliography { m } + { + \__csl_write_aux_bibdata:n {#1} + \printbibliography + } + + +\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 , + } + + +% Used for debugging and testing +\clist_new:N \g__csl_bib_items_clist + + +\cs_new:Npn \__csl_write_aux_bibliography:n #1 + { + \if@filesw + \iow_now:Nn \@auxout { \csl@aux@bibliography {#1} } + \fi + } + +\cs_new:Npn \csl@aux@bibliography #1 { } + + +\tl_new:N \l__csl_bib_index_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_new:N \l__csl_bib_wides_label_tl + +\keys_define:nn { csl / bib-options } + { + index .tl_set:N = \l__csl_bib_index_tl , + 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_wides_label_tl , + } + +\keys_set:nn { csl / bib-options } + { + index = 1 , + 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} + \dim_zero:N \parindent + \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_wides_label_tl } + \__csl_set_bib_item_sep: + } + \sloppy + \__csl_set_bib_page_break: + \frenchspacing + \__csl_bib_url_setup: + \clist_gclear:N \g__csl_bib_items_clist + } + { + \tl_set:Nn \@noitemerr + { \msg_warning:nn { citation-style-language } { bibliography / empty } } + \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 } + } + { + \settowidth \labelwidth { \@biblabel {#1} } + \dim_set_eq:NN \leftmargin \labelwidth + \dim_add:Nn \leftmargin { \labelsep } + } + } + +% 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 + { + \clist_gput_right:Nn \g__csl_bib_items_clist {#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_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 + { + \clist_gput_right:Nn \g__csl_bib_items_clist {#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 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 } { bib-heading-undefined } + {#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 } { bib-heading-undefined } + { 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:NTF \chapter + { + % `book` or `report` + \defbibheading { bibliography } [ \bibname ] + { + \chapter* {#1} + \@mkboth { \MakeUppercase {#1} } { \MakeUppercase {#1} } + } + \defbibheading { biblist } [ \biblistname ] + { + \chapter* {#1} + \@mkboth { \MakeMarkcase {#1} } { \MakeMarkcase {#1} } + } + \defbibheading { bibintoc } [ \bibname ] + { + \chapter* {#1} + \addcontentsline { toc } { chapter } {#1} + \@mkboth { \MakeMarkcase {#1} } { \MakeMarkcase {#1} } + } + \defbibheading { biblistintoc } [ \biblistname ] + { + \chapter* {#1} + \addcontentsline { toc } { chapter } {#1} + \@mkboth { \MakeMarkcase {#1} } { \MakeMarkcase {#1} } + } + \defbibheading { bibnumbered } [ \bibname ] + { \chapter {#1} } + \defbibheading { biblistnumbered } [ \biblistname ] + { \chapter {#1} } + \defbibheading { subbibliography } [ \refname ] + { + \section* {#1} + \if@twoside + \markright { \MakeMarkcase {#1} } + \fi + } + \defbibheading { subbibintoc } [ \refname ] + { + \section* {#1} + \addcontentsline { toc } { section } {#1} + \if@twoside + \markright { \MakeMarkcase {#1} } + \fi + } + \defbibheading { subbibnumbered } [ \refname ] + { \section {#1} } + } + { + % `article` + \defbibheading { bibliography } [ \refname ] + { + \section* {#1} + \@mkboth { \MakeUppercase {#1} } { \MakeUppercase {#1} } + } + \defbibheading { biblist } [ \biblistname ] + { + \section* {#1} + \@mkboth { \MakeMarkcase {#1} } { \MakeMarkcase {#1} } + } + \defbibheading { bibintoc } [ \refname ] + { + \section* {#1} + \addcontentsline { toc } { section } {#1} + \@mkboth { \MakeMarkcase {#1} } { \MakeMarkcase {#1} } + } + \defbibheading { biblistintoc } [ \biblistname ] + { + \section* {#1} + \addcontentsline { toc } { section } {#1} + \@mkboth { \MakeMarkcase {#1} } { \MakeMarkcase {#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 } { bib-note-undefined } + {#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 } { bib-note-undefined } + { 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.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 + } + } + } + +\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 + } diff --git a/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-cite.sty b/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-cite.sty new file mode 100644 index 00000000000..5c4b229bffd --- /dev/null +++ b/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-cite.sty @@ -0,0 +1,524 @@ +% +% Copyright (c) 2021-2023 Zeping Lee +% Released under the MIT License. +% Repository: https://github.com/zepinglee/citeproc-lua +% + +% ## Citation commands + +\DeclareDocumentCommand \cite { o o m } + { \__csl_cite:nnn {#1} {#2} {#3} } + +\NewDocumentCommand \parencite { o o m } + { \__csl_cite:nnn {#1} {#2} {#3} } + +\NewDocumentCommand \citep { o o m } + { \__csl_cite:nnn {#1} {#2} {#3} } + +\NewDocumentCommand \textcite { o o m } + { \__csl_text_cite:nnn {#1} {#2} {#3} } + +\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 { } + { \__csl_cites: } + +\NewDocumentCommand \citeauthor { o o m } + { \__csl_cite_author:nnn {#1} {#2} {#3} } + + +\seq_new:N \l__csl_cite_keys_seq +\seq_new:N \l__csl_citation_items_seq +\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 + { + \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 + } + } + + +\cs_new:Npn \__csl_text_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 + \prop_put:Nnn \l__csl_citation_properties_prop { noteIndex } { 0 } + \prop_put:Nnn \l__csl_citation_properties_prop { mode } { composite } + % \bool_set_false:N \l__csl_note_bool + \__csl_make_citation:N \l__csl_citation_info_prop + } + + +\cs_new:Npn \__csl_cites: + { + \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_next_cites:nnn + } + +\NewDocumentCommand \__csl_next_cites:nnn { o o g } + { + \tl_if_novalue:nTF {#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 + } + { + \__csl_process_cite_input:nnn {#1} {#2} {#3} + \__csl_next_cites:nnn + } + } + + +\cs_new:Npn \__csl_cite_author: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 + \prop_put:Nnn \l__csl_citation_properties_prop { noteIndex } { 0 } + \prop_put:Nnn \l__csl_citation_properties_prop { mode } { author-only } + \bool_set_false:N \l__csl_note_bool + \__csl_make_citation:N \l__csl_citation_info_prop + } + + +% Appends the cite key into \l__csl_cite_keys_seq and cite-items into +% \l__csl_citation_items_seq +% #1, #2: prenote/postnote +% #3: keys +\cs_new:Npn \__csl_process_cite_input:nnn #1#2#3 + { + \tl_if_novalue:nTF {#2} + { + \tl_if_novalue:nTF {#1} + { \__csl_process_cite_input_aux:nnn { } { } {#3} } + { \__csl_process_cite_input_aux:nnn { } {#1} {#3} } + } + { \__csl_process_cite_input_aux:nnn {#1} {#2} {#3} } + } + +\cs_new:Npn \__csl_process_cite_input_aux:nnn #1#2#3 + % #1: prenote, #2: postnote, #3: keys + % Return: "{id={ITEM-1},{locator=6},...}, {id={ITEM-2},...}, ..." + { + \int_zero:N \l_tmpa_int + \clist_map_inline:nn {#3} + { + \int_incr:N \l_tmpa_int + \seq_put_right:Nn \l__csl_cite_keys_seq {##1} + \int_compare:nNnTF { \l_tmpa_int } = { 1 } + { \__csl_process_cite_item:nnn {#1} {#2} {##1} } + { \__csl_process_cite_item:nnn { } { } {##1} } + } + } + + +\prop_new:N \l__csl_cite_item_prop +\tl_new:N \l__csl_prefix_tl +\tl_new:N \l__csl_suffix_tl + +\cs_new:Npn \__csl_process_cite_item:nnn #1#2#3 + % #1: prenote, #2: postnote, #3: key + % Save "{id={ITEM},locator={42},label={page}}" into \l__csl_citation_items_seq + { + \prop_clear:N \l__csl_cite_item_prop + \prop_put:Nnn \l__csl_cite_item_prop { id } {#3} + % \bool_if:T \l__csl_suppress_author_bool + % { \prop_put:Nnn \l__csl_cite_item_prop { suppress-author } { true } } + % \bool_if:T \l__csl_author_only_bool + % { \prop_put:Nnn \l__csl_cite_item_prop { author-only } { true } } + \tl_if_empty:nF {#1} + { + \tl_set:Nn \l__csl_prefix_tl {#1} + \tl_put_right:NV \l__csl_prefix_tl \l__csl_prefix_separator_tl + \prop_put:NnV \l__csl_cite_item_prop { prefix } \l__csl_prefix_tl + } + \tl_if_empty:nF {#2} + { + \tl_if_in:nnTF {#2} { = } + { \keys_set:nn { csl / cite-item } {#2} } + { + \regex_match:nnTF { \d+ } {#2} + { \__csl_set_locator:nn { page } {#2} } + { + \tl_set:Nn \l__csl_suffix_tl {#2} + \tl_put_left:NV \l__csl_suffix_tl \l__csl_suffix_separator_tl + \prop_put:NnV \l__csl_cite_item_prop { suffix } \l__csl_suffix_tl + } + } + } + \__csl_serialize_prop:NN \l__csl_cite_item_prop \l_tmpa_tl + \tl_put_left:NV \l_tmpa_tl { \c_left_brace_str } + \tl_put_right:NV \l_tmpa_tl { \c_right_brace_str } + \seq_put_right:NV \l__csl_citation_items_seq \l_tmpa_tl + } + +\cs_new:Npn \__csl_set_locator:nn #1#2 + { + \prop_put:Nnn \l__csl_cite_item_prop { label } {#1} + \prop_put:Nnn \l__csl_cite_item_prop { locator } {#2} + } + +\keys_define:nn { csl / cite-item } + { + prefix .prop_put:N = \l__csl_cite_item_prop, + suffix .prop_put:N = \l__csl_cite_item_prop, + locator .prop_put:N = \l__csl_cite_item_prop, + label .prop_put:N = \l__csl_cite_item_prop, + suppress-author .prop_put:N = \l__csl_cite_item_prop, + author-only .prop_put:N = \l__csl_cite_item_prop, + uris .prop_put:N = \l__csl_cite_item_prop, + % Locators. + act .code:n = { \__csl_set_locator:nn { act } {#1} } , + appendix .code:n = { \__csl_set_locator:nn { appendix } {#1} } , + article .code:n = { \__csl_set_locator:nn { article-locator } {#1} } , + book .code:n = { \__csl_set_locator:nn { book } {#1} } , + canon .code:n = { \__csl_set_locator:nn { canon } {#1} } , + chapter .code:n = { \__csl_set_locator:nn { chapter } {#1} } , + column .code:n = { \__csl_set_locator:nn { column } {#1} } , + elocation .code:n = { \__csl_set_locator:nn { elocation } {#1} } , + equation .code:n = { \__csl_set_locator:nn { equation } {#1} } , + figure .code:n = { \__csl_set_locator:nn { figure } {#1} } , + folio .code:n = { \__csl_set_locator:nn { folio } {#1} } , + issue .code:n = { \__csl_set_locator:nn { issue } {#1} } , + line .code:n = { \__csl_set_locator:nn { line } {#1} } , + note .code:n = { \__csl_set_locator:nn { note } {#1} } , + opus .code:n = { \__csl_set_locator:nn { opus } {#1} } , + page .code:n = { \__csl_set_locator:nn { page } {#1} } , + paragraph .code:n = { \__csl_set_locator:nn { paragraph } {#1} } , + part .code:n = { \__csl_set_locator:nn { part } {#1} } , + rule .code:n = { \__csl_set_locator:nn { rule } {#1} } , + scene .code:n = { \__csl_set_locator:nn { scene } {#1} } , + section .code:n = { \__csl_set_locator:nn { section } {#1} } , + sub-verbo .code:n = { \__csl_set_locator:nn { sub-verbo } {#1} } , + supplement .code:n = { \__csl_set_locator:nn { supplement } {#1} } , + table .code:n = { \__csl_set_locator:nn { table } {#1} } , + timestamp .code:n = { \__csl_set_locator:nn { timestamp } {#1} } , + title .code:n = { \__csl_set_locator:nn { title-locator } {#1} } , + verse .code:n = { \__csl_set_locator:nn { verse } {#1} } , + version .code:n = { \__csl_set_locator:nn { version } {#1} } , + volume .code:n = { \__csl_set_locator:nn { volume } {#1} } , + % Citation properties + infix .prop_put:N = \l__csl_citation_properties_prop, + } + + +\tl_new:N \l__csl_citation_id_tl +\tl_new:N \l__csl_cite_items_tl +\tl_new:N \l__csl_note_index_tl + +% Load the cite keys and prepare: +% - \l__csl_citation_id_tl +% - \l__csl_citation_properties_prop +% +% #1: \l__csl_cite_keys_seq +% #2: \l__csl_citation_items_seq +\cs_new:Npn \__csl_process_citation_info:NN #1#2 + { + \__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 + } + } + } + + +\tl_new:N \l__csl_citation_info_tl +\tl_new:N \l__csl_citation_tl +\prop_new:N \g__csl_citations_prop + +\tl_new:N \l__csl_citation_properties_tl + +% Write citation info to aux and print the citation contents. +% #1: \l__csl_citation_info_prop +\cs_new:Npn \__csl_make_citation:N #1 + { + \prop_clear:N \l__csl_citation_info_prop + % citationID + \prop_put:NnV \l__csl_citation_info_prop { citationID } \l__csl_citation_id_tl + % citationItems + \__csl_serialize_seq:NN \l__csl_citation_items_seq \l__csl_cite_items_tl + \prop_put:NnV \l__csl_citation_info_prop { citationItems } \l__csl_cite_items_tl + % properties + \__csl_serialize_prop:NN \l__csl_citation_properties_prop \l__csl_citation_properties_tl + \prop_put:NnV \l__csl_citation_info_prop { properties } \l__csl_citation_properties_tl + \__csl_serialize_prop:NN \l__csl_citation_info_prop \l__csl_citation_info_tl + % Write to .aux file + % \tl_show:N \l__csl_citation_info_tl + \exp_args:NV \__csl_write_aux_citation:n \l__csl_citation_info_tl + \bool_if:NT \l__csl_regression_test_bool + { \tl_show:N \l__csl_citation_info_tl } + % Print the citation string + \prop_get:NVNTF \g__csl_citations_prop \l__csl_citation_id_tl + \l__csl_citation_tl + { \__csl_print_citation:N \l__csl_citation_tl } + { + \bool_if:NTF \l__csl_engine_initialized_bool + { + % \tl_show:N \l__csl_citation_info_tl + % \tl_set:Nf \l__csl_citation_tl + % { \exp_args:NV \__csl_cite_aux:n \l__csl_citation_info_tl } + \group_begin: + \char_set_catcode_other:N \% + \char_set_catcode_other:N \# + \exp_args:NV \__csl_cite_aux:n \l__csl_citation_info_tl + \__csl_print_citation:N \l__csl_citation_tl + \group_end: + } + { + \exp_args:Nx \__csl_print_undefined_citation:n + { \seq_use:Nn \l__csl_cite_keys_seq { ,~ } } + } + } + } + +\cs_new:Npn \__csl_cite_aux:n #1 + { \lua_now:e { csl.cite("\lua_escape:n {#1}") } } + +% #1: seq +% #2: tl +\cs_new:Npn \__csl_serialize_seq:NN #1#2 + { + \tl_clear:N #2 + \seq_map_inline:Nn #1 + { + \tl_if_empty:NF #2 + { \tl_put_right:Nn #2 { , } } + \tl_put_right:Nn #2 { ##1 } + } + } + +% #1: prop +% #2: tl +\cs_new:Npn \__csl_serialize_prop:NN #1#2 + { + \tl_clear:N #2 + \prop_map_inline:Nn #1 + { + \tl_if_empty:NF #2 + { \tl_put_right:Nn #2 { , } } + \tl_put_right:Nn #2 { ##1 = { ##2 } } + } + } + +\tl_new:N \l__csl_cite_keys_tl +\tl_new:N \l__csl_citation_count_tl +\int_new:N \l__csl_citation_count_int +\prop_new:N \g__csl_citations_count_prop + +\cs_new:Npn \__csl_process_citation_id:NN #1#2 + % #1: \l__csl_citation_id_tl + % #2: \l__csl_cite_keys_seq + % Set \l__csl_citation_id_tl = "ITEM-1,ITEM-2@4". + { + \tl_set:Nx \l__csl_cite_keys_tl + { \seq_use:Nn #2 { , } } + % \prop_show:N \g__csl_citations_count_prop + % \tl_show:N \l__csl_cite_keys_tl + \prop_get:NVNTF \g__csl_citations_count_prop \l__csl_cite_keys_tl + \l__csl_citation_count_tl + { + \int_set:Nn \l__csl_citation_count_int { \l__csl_citation_count_tl } + \int_incr:N \l__csl_citation_count_int + } + { \int_set_eq:NN \l__csl_citation_count_int \c_one_int } + \prop_gput:NVV \g__csl_citations_count_prop \l__csl_cite_keys_tl + \l__csl_citation_count_int + \tl_set:Nx #1 + { \l__csl_cite_keys_tl @ \int_use:N \l__csl_citation_count_int } + } + + +\int_new:N \g__csl_pseudo_note_index_int +\int_gset:Nn \g__csl_pseudo_note_index_int { 0 } + +% Save the note number to \l__csl_note_index_tl +% TODO: multiple citations in a note +\cs_new:Npn \__csl_get_note_index:N #1 + % #1: \l__csl_note_index_tl + { + \bool_if:NTF \l__csl_note_bool + { + \int_set_eq:Nc \l_tmpa_int { c@ \@mpfn } + \int_incr:N \l_tmpa_int + \tl_set:Nx #1 { \int_use:N \l_tmpa_int } + } + { + \tl_if_empty:NTF \l__csl_class_tl + { + % The style class (in-text/note) is undetermined. + \int_set_eq:Nc \l_tmpa_int { c@ \@mpfn } + \int_gincr:N \g__csl_pseudo_note_index_int + \int_add:Nn \l_tmpa_int { \g__csl_pseudo_note_index_int } + \tl_set:Nx #1 { \int_use:N \l_tmpa_int } + } + { \tl_set:Nx #1 { 0 } } + } + } + + +\cs_new:Npn \__csl_write_aux_citation:n #1 + % #1: citation info "{<citationID>}{{id=ITEM-1},{id=ITEM-2}}{<noteIndex>}" + { + \if@filesw + \iow_now:Nn \@auxout { \csl@aux@cite {#1} } + \fi + } + + +% #1: \l__csl_citation_tl +\cs_new:Npn \__csl_print_citation:N #1 + { + \bool_if:NT \l__csl_regression_test_bool + { \tl_show:N #1 } + \bool_if:NTF \l__csl_note_bool + { \footnote {#1} } + {#1} + } + + +\cs_new:Npn \__csl_print_undefined_citation:n #1 + % #1: keys + { + \G@refundefinedtrue + \msg_warning:nnn { citation-style-language } { citation / undefined } {#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 \l__csl_citation_tl + \group_end: + } + +\msg_new:nnn { citation-style-language } { citation / undefined } + { Citation~ `#1'~ on~ page~ \thepage \space undefined~ \msg_line_context: . } + + +\DeclareDocumentCommand \nocite { m } + { \__csl_no_cite:n {#1} } + + +\cs_new:Npn \__csl_no_cite:n #1 + { + \seq_clear:N \l__csl_cite_keys_seq + \seq_clear:N \l__csl_citation_items_seq + \__csl_process_cite_input:nnn { } { } {#1} + \tl_set:Nx \l__csl_cite_items_tl + { \seq_use:Nn \l__csl_citation_items_seq { , } } + \tl_set:Nx \l__csl_citation_info_tl + { + citationID = { @nocite } , + citationItems = { \l__csl_cite_items_tl } , + properties = { noteIndex = { 0 } } + } + \bool_if:NT \l__csl_regression_test_bool + { \tl_show:N \l__csl_citation_info_tl } + \exp_args:NV \__csl_no_cite_write_aux:n \l__csl_citation_info_tl + \sys_if_engine_luatex:T + { \lua_now:n { csl.nocite("#1") } } + \tl_clear:N \l__csl_citation_tl + \bool_if:NT \l__csl_regression_test_bool + { \tl_show:N \l__csl_citation_tl } +} + + +\cs_new:Npn \__csl_no_cite_write_aux:n #1 + { + \__csl_if_preamble:TF + { + \AtBeginDocument + { \exp_args:Nx \__csl_write_aux_citation:n { #1 } } + } + { \exp_args:Nx \__csl_write_aux_citation:n { #1 } } + } + + +\prg_new_conditional:Nnn \__csl_if_preamble: { T , F , TF } + { + \if_meaning:w \@begindocumenthook \@undefined + \prg_return_false: + \else + \prg_return_true: + \fi + } + + +% Used in aux files to register cite items. +% #1: a citation object +\cs_set:Npn \csl@aux@cite #1 + { + \sys_if_engine_luatex:T + { \lua_now:e { csl.register_citation_info("\lua_escape:n {#1}") } } + } + + +\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} diff --git a/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-compatible.sty b/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-compatible.sty new file mode 100644 index 00000000000..db70f54c1ce --- /dev/null +++ b/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-compatible.sty @@ -0,0 +1,102 @@ +% +% Copyright (c) 2021-2023 Zeping Lee +% Released under the MIT License. +% Repository: https://github.com/zepinglee/citeproc-lua +% + +% ## Compatibilities with other packages + +% ### `babel` + +% This should be disabled. +\AtEndOfPackageFile* { babel } + { + \RenewDocumentCommand \nocite { m } + { + % \@safe@activestrue\org@nocite{#1}\@safe@activesfalse + \@safe@activestrue + \__csl_no_cite:n {#1} + \@safe@activesfalse + } + \cs_set_eq:NN \bbl@cite@choice \relax + \cs_set_eq:NN \@lbibitem \__csl_lbibitem_plain:nn + \cs_set_eq:NN \@bibitem \__csl_bibitem_plain:n + } + + +% ### `biblatex` +% The following doesn't really make `csl` compatible with `biblatex`. +% It just provides commands to make it accepting `biblatex`'s database. + +\ProvideDocumentCommand { \hyphen } { } + { + \nobreak - \nobreak + \hskip \z@skip + } + + +% ### `csquotes` + +\AtEndOfPackageFile* { csquotes } + { + \BlockquoteDisable + { + \cs_set_eq:NN \__csl_process_citation_info:NN \use_none:nn + \cs_set_eq:NN \__csl_make_citation:N \use_none:n + } + } + + +% ### `hyperref` + +% 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 } + { + \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 + } diff --git a/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-data.sty b/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-data.sty new file mode 100644 index 00000000000..f3fc7f13b18 --- /dev/null +++ b/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-data.sty @@ -0,0 +1,10 @@ +% +% Copyright (c) 2021-2023 Zeping Lee +% Released under the MIT License. +% Repository: https://github.com/zepinglee/citeproc-lua +% + +% ## Bibliography commands + +\NewDocumentCommand \addbibresource { o m } + { \clist_put_right:Nn \l__csl_bib_resources_clist {#2} } diff --git a/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-init.sty b/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-init.sty new file mode 100644 index 00000000000..53aea6d4f5e --- /dev/null +++ b/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language-init.sty @@ -0,0 +1,306 @@ +% +% Copyright (c) 2021-2023 Zeping Lee +% Released under the MIT License. +% Repository: https://github.com/zepinglee/citeproc-lua +% + +% ## Initialization at `\begin{document}` + +\AtBeginDocument { \__csl_at_begin_document_hook: } + + +\cs_new:Npn \__csl_at_begin_document_hook: + { + \__csl_write_aux_info: + \sys_if_engine_luatex:TF + { \__csl_initialize_lua_module: } + { \__csl_load_bbl: } + } + + +\clist_new:N \g__csl_aux_bib_files_clist + +\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 + \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 } + { + \exp_args:Nx \__csl_write_aux_bibdata:n + { \clist_use:Nn \l__csl_bib_resources_clist { , } } + } + \__csl_write_aux_csl_options: + } + +\cs_new:Npn \__csl_write_aux_bibstyle:n #1 + { + \if@filesw + \iow_now:Nx \@auxout { \token_to_str:N \csl@aux@style {#1} } + \fi + } + +\cs_new:Npn \__csl_write_aux_bibdata:n #1 + { + \if@filesw + % Full expansion for files like \jobname.bib + \iow_now:Nx \@auxout { \token_to_str:N \csl@aux@data {#1} } + \fi + } + +% In earlier time, \bibdata{xxx.json} was used but this causes latexmk unable +% to find xxx.json.bib and it refuses to run the $bibtex procedure. +% John Collins suggests using a different command than \bibdata. +\cs_new:Npn \csl@aux@data #1 + { \clist_gput_right:Nn \g__csl_aux_bib_files_clist {#1} } + + + +\cs_new:Npn \__csl_initialize_lua_module: + { + \lua_now:e + { + csl.init( + "\l__csl_style_tl", + "\l__csl_bib_resources_clist", + "\l__csl_locale_tl" + ) + } + \str_if_eq:eeT { \lua_now:n { tex.print(csl.initialized) } } { true } + { \bool_set_true:N \l__csl_engine_initialized_bool } + \__csl_get_style_class: + \@ifpackageloaded { hyperref } + { \lua_now:n { csl.enable_linking() } } + { } + } + + +% \str_new:N \l__csl_style_class_str +% In-text (including numeric or author-date) or note style +% \bool_new:N \l__csl_note_style_bool + +\cs_new:Npn \__csl_get_style_class: { + \bool_if:NT \l__csl_engine_initialized_bool + { + \tl_set:Nx \l__csl_class_tl { \lua_now:n { csl.get_style_class() } } + \tl_if_eq:NnT \l__csl_class_tl { note } + { \bool_set_true:N \l__csl_note_bool } + } +} + + +\clist_new:N \l__csl_options_clist + +\bool_new:N \l__csl_engine_initialized_bool + +\prop_set_from_keyval:Nn \l__csl_language_code_map_prop + { + acadian = fr-CA, + american = en-US, + australian = en-AU, + afrikaans = af-ZA, + albanian = sq-AL, + amharic = am-ET, + arabic = ar, + armenian = hy-AM, + asturian = ast-ES, + austrian = de-AT, + bahasa = id-ID, + bahasai = id-ID, + bahasam = id-ID, + basque = eu-ES, + bengali = bn-BD, + bgreek = el-GR, + brazil = pt-BR, + brazilian = pt-BR, + breton = br-FR, + british = en-GB, + bulgarian = bg-BG, + canadian = en-CA, + canadien = fr-CA, + catalan = ca-AD, + coptic = cop, + croatian = hr-HR, + czech = cs-CZ, + danish = da-DK, + divehi = dv-MV, + dutch = nl-NL, + english = en-US, + esperanto = eo-001, + estonian = et-EE, + ethiopia = am-ET, + farsi = fa-IR, + finnish = fi-FI, + francais = fr-FR, + french = fr-FR, + frenchle = fr-FR, + friulan = fur-IT, + galician = gl-ES, + german = de-DE, + germanb = de-DE, + greek = el-GR, + hebrew = he-IL, + hindi = hi-IN, + ibygreek = el-CY, + icelandic = is-IS, + indon = id-ID, + indonesia = id-ID, + interlingua = ia-FR, + irish = ga-IE, + italian = it-IT, + japanese = ja-JP, + kannada = kn-IN, + lao = lo-LA, + latin = la-Latn, + latvian = lv-LV, + lithuanian = lt-LT, + lowersorbian = dsb-DE, + lsorbian = dsb-DE, + magyar = hu-HU, + malay = id-ID, + malayalam = ml-IN, + marathi = mr-IN, + meyalu = id-ID, + mongolian = mn-Cyrl, + naustrian = de-AT, + newzealand = en-NZ, + ngerman = de-DE, + nko = ha-NG, + norsk = nb-NO, + norwegian = nn-NO, + nynorsk = nn-NO, + occitan = oc-FR, + piedmontese = pms-IT, + pinyin = pny, + polish = pl-PL, + polutonikogreek = el-GR, + portuges = pt-PT, + portuguese = pt-PT, + romanian = ro-RO, + romansh = rm-CH, + russian = ru-RU, + samin = se-NO, + sanskrit = sa-IN, + scottish = gd-GB, + serbian = sr-Latn, + serbianc = sr-Cyrl, + slovak = sk-SK, + slovene = sl-SI, + slovenian = sl-SI, + spanish = es-ES, + swedish = sv-SE, + swiss = de-CH, + swissgerman = de-CH, + nswissgerman = de-CH, + syriac = syc, + tamil = ta-IN, + telugu = te-IN, + thai = th-TH, + thaicjk = th-TH, + tibetan = bo-CN, + turkish = tr-TR, + turkmen = tk-TM, + ukrainian = uk-UA, + urdu = ur-IN, + UKenglish = en-UK, + uppersorbian = hsb-DE, + USenglish = en-US, + usorbian = hsb-DE, + vietnamese = vi-VN, + welsh = cy-GB, + } + + +\cs_new:Npn \__csl_write_aux_csl_options: + { + \clist_clear:N \l__csl_options_clist + % locale + \tl_if_empty:NT \l__csl_locale_tl + { + \tl_if_exist:NT \bbl@main@language + { + \prop_get:NVN \l__csl_language_code_map_prop \bbl@main@language + \l__csl_locale_tl + } + } + \tl_if_empty:NF \l__csl_locale_tl + { + \clist_put_right:Nx \l__csl_options_clist + { locale = \l__csl_locale_tl } + } + % linking + \@ifpackageloaded { hyperref } + { \clist_put_right:Nn \l__csl_options_clist { linking = true } } + { } + % write to aux file + \prop_if_empty:NF \l__csl_options_clist + { + \exp_args:Nx \__csl_write_aux_options:n + { \clist_use:Nn \l__csl_options_clist { , } } + } + } + +\cs_new:Npn \__csl_write_aux_options:n #1 + { + \if@filesw + \iow_now:Nn \@auxout { \csl@aux@options {#1} } + \fi + } + +\cs_new:Npn \csl@aux@options #1 { } + + +\tl_new:N \g__csl_bibliography_setup_tl + +% Load .bbl at the beginning of document to save one pass of latex. +% In this procedure, the \cslcitation command is processed and the contents +% of `thebibliography` is stored into \g__csl_bibliographies_prop. +\cs_new:Npn \__csl_load_bbl: + { + % The \@input@ prints "No file ....bbl" in the .log file from which + % the latexmk decides to run $bibtex or not. + \__csl_collect_bibliography:n { \@input@ { \jobname .bbl } } + % Execute the \cslsetup part to set the style class. + % \tl_show:N \g__csl_bibliography_setup_tl + \tl_use:N \g__csl_bibliography_setup_tl + % \bool_show:N \l__csl_note_bool + } + + +% A document may have multiple bibliographies or biblists and they are stored +% in `\g__csl_bibliographies_prop` by their index. +\prop_new:N \g__csl_bibliographies_prop + + +% Collection the bibliography into \g__csl_bibliographies_prop +\cs_new:Npn \__csl_collect_bibliography:n #1 + { + \group_begin: + % URLs may contain "%" and "#" characters. + \char_set_catcode_other:N \% + \char_set_catcode_other:N \# + \RenewDocumentCommand \cslsetup { m } + { \tl_gset:Nn \g__csl_bibliography_setup_tl { \cslsetup { ##1 } } } + \RenewDocumentEnvironment { thebibliography } { m +b } + { + \tl_set:Nn \l__csl_bib_index_tl { 1 } + \keys_set:nn { csl / bib-options } {##1} + \prop_gput:NVn \g__csl_bibliographies_prop \l__csl_bib_index_tl + { + \begin { thebibliography } {##1} + ##2 + \end { thebibliography } + } + } + { } + % Perform the execution + #1 + \group_end: + } + +% \msg_new:nnn { citation-style-language } { file / non-exist } +% { No~ file~ #1. } diff --git a/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language.sty b/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language.sty index 5566737b49b..0e97c76dd5d 100644 --- a/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language.sty +++ b/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language.sty @@ -9,13 +9,14 @@ \RequirePackage{expl3} \RequirePackage{xparse} -\ProvidesExplPackage {citation-style-language} {2023-04-02} {v0.4.0} +\ProvidesExplPackage {citation-style-language} {2023-04-12} {v0.4.1} {Citation Style Language for LaTeX} \RequirePackage { l3keys2e } \RequirePackage { filehook } \RequirePackage { url } + % Check incompatible packages \msg_new:nnn { citation-style-language } { incompatible-package } { The~ `#1'~ package~ is~ incompatible~ with~ `citation-style-language'. } @@ -32,651 +33,18 @@ } -% Check l3build regression-test -\bool_new:N \l__csl_regression_test_bool -% \if_meaning:w \ASSERT \@undefined -% \else -% \bool_set_true:N \l__csl_regression_test_bool -% \fi - - +% Load Lua module in LuaTeX \sys_if_engine_luatex:T { \lua_now:n { csl = require("citeproc-latex") } } +% Global options + \NewDocumentCommand \cslsetup { m } { \keys_set:nn { csl } {#1} } -\cs_new:Npn \csl@aux@options #1 { } - - -\DeclareDocumentCommand \cite { o o m } - { \__csl_cite:nnn {#1} {#2} {#3} } - -\NewDocumentCommand \parencite { o o m } - { \__csl_cite:nnn {#1} {#2} {#3} } - -\NewDocumentCommand \citep { o o m } - { \__csl_cite:nnn {#1} {#2} {#3} } - -\NewDocumentCommand \textcite { o o m } - { \__csl_text_cite:nnn {#1} {#2} {#3} } - -\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 { } - { \__csl_cites: } - -\NewDocumentCommand \citeauthor { o o m } - { \__csl_cite_author:nnn {#1} {#2} {#3} } - - -\seq_new:N \l__csl_cite_keys_seq -\seq_new:N \l__csl_citation_items_seq -\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 - { - \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 - } - } - - -\cs_new:Npn \__csl_text_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 - \prop_put:Nnn \l__csl_citation_properties_prop { noteIndex } { 0 } - \prop_put:Nnn \l__csl_citation_properties_prop { mode } { composite } - % \bool_set_false:N \l__csl_note_bool - \__csl_make_citation:N \l__csl_citation_info_prop - } - - -\cs_new:Npn \__csl_cites: - { - \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_next_cites:nnn - } - -\NewDocumentCommand \__csl_next_cites:nnn { o o g } - { - \tl_if_novalue:nTF {#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 - } - { - \__csl_process_cite_input:nnn {#1} {#2} {#3} - \__csl_next_cites:nnn - } - } - - -\cs_new:Npn \__csl_cite_author: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 - \prop_put:Nnn \l__csl_citation_properties_prop { noteIndex } { 0 } - \prop_put:Nnn \l__csl_citation_properties_prop { mode } { author-only } - \bool_set_false:N \l__csl_note_bool - \__csl_make_citation:N \l__csl_citation_info_prop - } - - -% Appends the cite key into \l__csl_cite_keys_seq and cite-items into -% \l__csl_citation_items_seq -% #1, #2: prenote/postnote -% #3: keys -\cs_new:Npn \__csl_process_cite_input:nnn #1#2#3 - { - \tl_if_novalue:nTF {#2} - { - \tl_if_novalue:nTF {#1} - { \__csl_process_cite_input_aux:nnn { } { } {#3} } - { \__csl_process_cite_input_aux:nnn { } {#1} {#3} } - } - { \__csl_process_cite_input_aux:nnn {#1} {#2} {#3} } - } - -\cs_new:Npn \__csl_process_cite_input_aux:nnn #1#2#3 - % #1: prenote, #2: postnote, #3: keys - % Return: "{id={ITEM-1},{locator=6},...}, {id={ITEM-2},...}, ..." - { - \int_zero:N \l_tmpa_int - \clist_map_inline:nn {#3} - { - \int_incr:N \l_tmpa_int - \seq_put_right:Nn \l__csl_cite_keys_seq {##1} - \int_compare:nNnTF { \l_tmpa_int } = { 1 } - { \__csl_process_cite_item:nnn {#1} {#2} {##1} } - { \__csl_process_cite_item:nnn { } { } {##1} } - } - } - - -\prop_new:N \l__csl_cite_item_prop -\tl_new:N \l__csl_prefix_tl -\tl_new:N \l__csl_suffix_tl - -\cs_new:Npn \__csl_process_cite_item:nnn #1#2#3 - % #1: prenote, #2: postnote, #3: key - % Save "{id={ITEM},locator={42},label={page}}" into \l__csl_citation_items_seq - { - \prop_clear:N \l__csl_cite_item_prop - \prop_put:Nnn \l__csl_cite_item_prop { id } {#3} - % \bool_if:T \l__csl_suppress_author_bool - % { \prop_put:Nnn \l__csl_cite_item_prop { suppress-author } { true } } - % \bool_if:T \l__csl_author_only_bool - % { \prop_put:Nnn \l__csl_cite_item_prop { author-only } { true } } - \tl_if_empty:nF {#1} - { - \tl_set:Nn \l__csl_prefix_tl {#1} - \tl_put_right:NV \l__csl_prefix_tl \l__csl_prefix_separator_tl - \prop_put:NnV \l__csl_cite_item_prop { prefix } \l__csl_prefix_tl - } - \tl_if_empty:nF {#2} - { - \tl_if_in:nnTF {#2} { = } - { \keys_set:nn { csl / cite-item } {#2} } - { - \regex_match:nnTF { \d+ } {#2} - { \__csl_set_locator:nn { page } {#2} } - { - \tl_set:Nn \l__csl_suffix_tl {#2} - \tl_put_left:NV \l__csl_suffix_tl \l__csl_suffix_separator_tl - \prop_put:NnV \l__csl_cite_item_prop { suffix } \l__csl_suffix_tl - } - } - } - \__csl_serialize_prop:NN \l__csl_cite_item_prop \l_tmpa_tl - \tl_put_left:NV \l_tmpa_tl { \c_left_brace_str } - \tl_put_right:NV \l_tmpa_tl { \c_right_brace_str } - \seq_put_right:NV \l__csl_citation_items_seq \l_tmpa_tl - } - -\cs_new:Npn \__csl_set_locator:nn #1#2 - { - \prop_put:Nnn \l__csl_cite_item_prop { label } {#1} - \prop_put:Nnn \l__csl_cite_item_prop { locator } {#2} - } - -\keys_define:nn { csl / cite-item } - { - prefix .prop_put:N = \l__csl_cite_item_prop, - suffix .prop_put:N = \l__csl_cite_item_prop, - locator .prop_put:N = \l__csl_cite_item_prop, - label .prop_put:N = \l__csl_cite_item_prop, - suppress-author .prop_put:N = \l__csl_cite_item_prop, - author-only .prop_put:N = \l__csl_cite_item_prop, - uris .prop_put:N = \l__csl_cite_item_prop, - % Locators. - act .code:n = { \__csl_set_locator:nn { act } {#1} } , - appendix .code:n = { \__csl_set_locator:nn { appendix } {#1} } , - article .code:n = { \__csl_set_locator:nn { article-locator } {#1} } , - book .code:n = { \__csl_set_locator:nn { book } {#1} } , - canon .code:n = { \__csl_set_locator:nn { canon } {#1} } , - chapter .code:n = { \__csl_set_locator:nn { chapter } {#1} } , - column .code:n = { \__csl_set_locator:nn { column } {#1} } , - elocation .code:n = { \__csl_set_locator:nn { elocation } {#1} } , - equation .code:n = { \__csl_set_locator:nn { equation } {#1} } , - figure .code:n = { \__csl_set_locator:nn { figure } {#1} } , - folio .code:n = { \__csl_set_locator:nn { folio } {#1} } , - issue .code:n = { \__csl_set_locator:nn { issue } {#1} } , - line .code:n = { \__csl_set_locator:nn { line } {#1} } , - note .code:n = { \__csl_set_locator:nn { note } {#1} } , - opus .code:n = { \__csl_set_locator:nn { opus } {#1} } , - page .code:n = { \__csl_set_locator:nn { page } {#1} } , - paragraph .code:n = { \__csl_set_locator:nn { paragraph } {#1} } , - part .code:n = { \__csl_set_locator:nn { part } {#1} } , - rule .code:n = { \__csl_set_locator:nn { rule } {#1} } , - scene .code:n = { \__csl_set_locator:nn { scene } {#1} } , - section .code:n = { \__csl_set_locator:nn { section } {#1} } , - sub-verbo .code:n = { \__csl_set_locator:nn { sub-verbo } {#1} } , - supplement .code:n = { \__csl_set_locator:nn { supplement } {#1} } , - table .code:n = { \__csl_set_locator:nn { table } {#1} } , - timestamp .code:n = { \__csl_set_locator:nn { timestamp } {#1} } , - title .code:n = { \__csl_set_locator:nn { title-locator } {#1} } , - verse .code:n = { \__csl_set_locator:nn { verse } {#1} } , - version .code:n = { \__csl_set_locator:nn { version } {#1} } , - volume .code:n = { \__csl_set_locator:nn { volume } {#1} } , - % Citation properties - infix .prop_put:N = \l__csl_citation_properties_prop, - } - - -\tl_new:N \l__csl_citation_id_tl -\tl_new:N \l__csl_cite_items_tl -\tl_new:N \l__csl_note_index_tl - -% Load the cite keys and prepare: -% - \l__csl_citation_id_tl -% - \l__csl_citation_properties_prop -% -% #1: \l__csl_cite_keys_seq -% #2: \l__csl_citation_items_seq -\cs_new:Npn \__csl_process_citation_info:NN #1#2 - { - \__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 - } - } - } - - -\tl_new:N \l__csl_citation_info_tl -\tl_new:N \l__csl_citation_tl -\prop_new:N \g__csl_citations_prop - -\tl_new:N \l__csl_citation_properties_tl - -% Write citation info to aux and print the citation contents. -% #1: \l__csl_citation_info_prop -\cs_new:Npn \__csl_make_citation:N #1 - { - \prop_clear:N \l__csl_citation_info_prop - % citationID - \prop_put:NnV \l__csl_citation_info_prop { citationID } \l__csl_citation_id_tl - % citationItems - \__csl_serialize_seq:NN \l__csl_citation_items_seq \l__csl_cite_items_tl - \prop_put:NnV \l__csl_citation_info_prop { citationItems } \l__csl_cite_items_tl - % properties - \__csl_serialize_prop:NN \l__csl_citation_properties_prop \l__csl_citation_properties_tl - \prop_put:NnV \l__csl_citation_info_prop { properties } \l__csl_citation_properties_tl - \__csl_serialize_prop:NN \l__csl_citation_info_prop \l__csl_citation_info_tl - % Write to .aux file - % \tl_show:N \l__csl_citation_info_tl - \exp_args:NV \__csl_write_aux_citation:n \l__csl_citation_info_tl - \bool_if:NT \l__csl_regression_test_bool - { \tl_show:N \l__csl_citation_info_tl } - % Print the citation string - \prop_get:NVNTF \g__csl_citations_prop \l__csl_citation_id_tl - \l__csl_citation_tl - { \__csl_print_citation:N \l__csl_citation_tl } - { - \bool_if:NTF \l__csl_engine_initialized_bool - { - % \tl_show:N \l__csl_citation_info_tl - % \tl_set:Nf \l__csl_citation_tl - % { \exp_args:NV \__csl_cite_aux:n \l__csl_citation_info_tl } - \group_begin: - \char_set_catcode_other:N \% - \char_set_catcode_other:N \# - \exp_args:NV \__csl_cite_aux:n \l__csl_citation_info_tl - \__csl_print_citation:N \l__csl_citation_tl - \group_end: - } - { - \exp_args:Nx \__csl_print_undefined_citation:n - { \seq_use:Nn \l__csl_cite_keys_seq { ,~ } } - } - } - } - -\cs_new:Npn \__csl_cite_aux:n #1 - { \lua_now:e { csl.cite("\lua_escape:n {#1}") } } - -% #1: seq -% #2: tl -\cs_new:Npn \__csl_serialize_seq:NN #1#2 - { - \tl_clear:N #2 - \seq_map_inline:Nn #1 - { - \tl_if_empty:NF #2 - { \tl_put_right:Nn #2 { , } } - \tl_put_right:Nn #2 { ##1 } - } - } - -% #1: prop -% #2: tl -\cs_new:Npn \__csl_serialize_prop:NN #1#2 - { - \tl_clear:N #2 - \prop_map_inline:Nn #1 - { - \tl_if_empty:NF #2 - { \tl_put_right:Nn #2 { , } } - \tl_put_right:Nn #2 { ##1 = { ##2 } } - } - } - -\tl_new:N \l__csl_cite_keys_tl -\tl_new:N \l__csl_citation_count_tl -\int_new:N \l__csl_citation_count_int -\prop_new:N \g__csl_citations_count_prop - -\cs_new:Npn \__csl_process_citation_id:NN #1#2 - % #1: \l__csl_citation_id_tl - % #2: \l__csl_cite_keys_seq - % Set \l__csl_citation_id_tl = "ITEM-1,ITEM-2@4". - { - \tl_set:Nx \l__csl_cite_keys_tl - { \seq_use:Nn #2 { , } } - % \prop_show:N \g__csl_citations_count_prop - % \tl_show:N \l__csl_cite_keys_tl - \prop_get:NVNTF \g__csl_citations_count_prop \l__csl_cite_keys_tl - \l__csl_citation_count_tl - { - \int_set:Nn \l__csl_citation_count_int { \l__csl_citation_count_tl } - \int_incr:N \l__csl_citation_count_int - } - { \int_set_eq:NN \l__csl_citation_count_int \c_one_int } - \prop_gput:NVV \g__csl_citations_count_prop \l__csl_cite_keys_tl - \l__csl_citation_count_int - \tl_set:Nx #1 - { \l__csl_cite_keys_tl @ \int_use:N \l__csl_citation_count_int } - } - - -\int_new:N \g__csl_pseudo_note_index_int -\int_gset:Nn \g__csl_pseudo_note_index_int { 0 } - -% Save the note number to \l__csl_note_index_tl -% TODO: multiple citations in a note -\cs_new:Npn \__csl_get_note_index:N #1 - % #1: \l__csl_note_index_tl - { - \bool_if:NTF \l__csl_note_bool - { - \int_set_eq:Nc \l_tmpa_int { c@ \@mpfn } - \int_incr:N \l_tmpa_int - \tl_set:Nx #1 { \int_use:N \l_tmpa_int } - } - { - \tl_if_empty:NTF \l__csl_class_tl - { - % The style class (in-text/note) is undetermined. - \int_set_eq:Nc \l_tmpa_int { c@ \@mpfn } - \int_gincr:N \g__csl_pseudo_note_index_int - \int_add:Nn \l_tmpa_int { \g__csl_pseudo_note_index_int } - \tl_set:Nx #1 { \int_use:N \l_tmpa_int } - } - { \tl_set:Nx #1 { 0 } } - } - } - - -\cs_new:Npn \__csl_write_aux_citation:n #1 - % #1: citation info "{<citationID>}{{id=ITEM-1},{id=ITEM-2}}{<noteIndex>}" - { - \if@filesw - \iow_now:Nn \@auxout { \csl@aux@cite {#1} } - \fi - } - - -% #1: \l__csl_citation_tl -\cs_new:Npn \__csl_print_citation:N #1 - { - \bool_if:NT \l__csl_regression_test_bool - { \tl_show:N #1 } - \bool_if:NTF \l__csl_note_bool - { \footnote {#1} } - {#1} - } - - -\cs_new:Npn \__csl_print_undefined_citation:n #1 - % #1: keys - { - \G@refundefinedtrue - \msg_warning:nnn { citation-style-language } { citation / undefined } {#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 \l__csl_citation_tl - \group_end: - } - -\msg_new:nnn { citation-style-language } { citation / undefined } - { Citation~ `#1'~ on~ page~ \thepage \space undefined~ \msg_line_context: . } - - -\DeclareDocumentCommand \nocite { m } - { \__csl_no_cite:n {#1} } - - -\cs_new:Npn \__csl_no_cite:n #1 - { - \seq_clear:N \l__csl_cite_keys_seq - \seq_clear:N \l__csl_citation_items_seq - \__csl_process_cite_input:nnn { } { } {#1} - \tl_set:Nx \l__csl_cite_items_tl - { \seq_use:Nn \l__csl_citation_items_seq { , } } - \tl_set:Nx \l__csl_citation_info_tl - { - citationID = { @nocite } , - citationItems = { \l__csl_cite_items_tl } , - properties = { noteIndex = { 0 } } - } - \bool_if:NT \l__csl_regression_test_bool - { \tl_show:N \l__csl_citation_info_tl } - \exp_args:NV \__csl_no_cite_write_aux:n \l__csl_citation_info_tl - \sys_if_engine_luatex:T - { \lua_now:n { csl.nocite("#1") } } - \tl_clear:N \l__csl_citation_tl - \bool_if:NT \l__csl_regression_test_bool - { \tl_show:N \l__csl_citation_tl } -} - - -\cs_new:Npn \__csl_no_cite_write_aux:n #1 - { - \__csl_if_preamble:TF - { - \AtBeginDocument - { \exp_args:Nx \__csl_write_aux_citation:n { #1 } } - } - { \exp_args:Nx \__csl_write_aux_citation:n { #1 } } - } - - -\prg_new_conditional:Nnn \__csl_if_preamble: { T , F , TF } - { - \if_meaning:w \@begindocumenthook \@undefined - \prg_return_false: - \else - \prg_return_true: - \fi - } - - -% Used in aux files to register cite items. -% #1: a citation object -\cs_set:Npn \csl@aux@cite #1 - { - \sys_if_engine_luatex:T - { \lua_now:e { csl.register_citation_info("\lua_escape:n {#1}") } } - } - - -\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 } - { - 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_add_filter_condition:nn #1#2 - { - \seq_put_right:Nn \l__bibliography_filter_conditions_seq - { - { - field = #1 , - value = #2 - } - } - } - -\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: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 } } - { - \bool_if:NT \l__csl_regression_test_bool - { - \seq_set_split:NnV \l__csl_bibliography_seq { \par } \g__csl_bibliography_tl - \seq_show:N \l__csl_bibliography_seq - } - \tl_use:N \g__csl_bibliography_tl - } - } - -\msg_new:nnn { citation-style-language } { bibliography / empty } - { The~ bibliography~ is~ empty. } - +\bool_new:N \l__csl_regression_test_bool \tl_new:N \l__csl_style_tl \newcommand \csl@style {} % For latex2e interface \tl_new:N \l__csl_class_tl @@ -694,11 +62,6 @@ \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 } @@ -728,451 +91,6 @@ 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 , - line-spacing .tl_set:N = \l__csl_line_spacing_tl , - entry-spacing .tl_set:N = \l__csl_entry_spacing_tl , - } - -\keys_set:nn { csl } - { - 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 - -\prop_set_from_keyval:Nn \l__csl_language_code_map_prop - { - acadian = fr-CA, - american = en-US, - australian = en-AU, - afrikaans = af-ZA, - albanian = sq-AL, - amharic = am-ET, - arabic = ar, - armenian = hy-AM, - asturian = ast-ES, - austrian = de-AT, - bahasa = id-ID, - bahasai = id-ID, - bahasam = id-ID, - basque = eu-ES, - bengali = bn-BD, - bgreek = el-GR, - brazil = pt-BR, - brazilian = pt-BR, - breton = br-FR, - british = en-GB, - bulgarian = bg-BG, - canadian = en-CA, - canadien = fr-CA, - catalan = ca-AD, - coptic = cop, - croatian = hr-HR, - czech = cs-CZ, - danish = da-DK, - divehi = dv-MV, - dutch = nl-NL, - english = en-US, - esperanto = eo-001, - estonian = et-EE, - ethiopia = am-ET, - farsi = fa-IR, - finnish = fi-FI, - francais = fr-FR, - french = fr-FR, - frenchle = fr-FR, - friulan = fur-IT, - galician = gl-ES, - german = de-DE, - germanb = de-DE, - greek = el-GR, - hebrew = he-IL, - hindi = hi-IN, - ibygreek = el-CY, - icelandic = is-IS, - indon = id-ID, - indonesia = id-ID, - interlingua = ia-FR, - irish = ga-IE, - italian = it-IT, - japanese = ja-JP, - kannada = kn-IN, - lao = lo-LA, - latin = la-Latn, - latvian = lv-LV, - lithuanian = lt-LT, - lowersorbian = dsb-DE, - lsorbian = dsb-DE, - magyar = hu-HU, - malay = id-ID, - malayalam = ml-IN, - marathi = mr-IN, - meyalu = id-ID, - mongolian = mn-Cyrl, - naustrian = de-AT, - newzealand = en-NZ, - ngerman = de-DE, - nko = ha-NG, - norsk = nb-NO, - norwegian = nn-NO, - nynorsk = nn-NO, - occitan = oc-FR, - piedmontese = pms-IT, - pinyin = pny, - polish = pl-PL, - polutonikogreek = el-GR, - portuges = pt-PT, - portuguese = pt-PT, - romanian = ro-RO, - romansh = rm-CH, - russian = ru-RU, - samin = se-NO, - sanskrit = sa-IN, - scottish = gd-GB, - serbian = sr-Latn, - serbianc = sr-Cyrl, - slovak = sk-SK, - slovene = sl-SI, - slovenian = sl-SI, - spanish = es-ES, - swedish = sv-SE, - swiss = de-CH, - swissgerman = de-CH, - nswissgerman = de-CH, - syriac = syc, - tamil = ta-IN, - telugu = te-IN, - thai = th-TH, - thaicjk = th-TH, - tibetan = bo-CN, - turkish = tr-TR, - turkmen = tk-TM, - ukrainian = uk-UA, - urdu = ur-IN, - UKenglish = en-UK, - uppersorbian = hsb-DE, - USenglish = en-US, - usorbian = hsb-DE, - vietnamese = vi-VN, - welsh = cy-GB, - } - -\tl_new:N \g__csl_bibliography_tl -\tl_new:N \g__csl_bibliography_setup_tl -\seq_new:N \l__csl_bibliography_seq - - -\AtBeginDocument { \__csl_at_begin_document_hook: } - - -\cs_new:Npn \__csl_at_begin_document_hook: - { - \__csl_write_aux_info: - \sys_if_engine_luatex:TF - { \__csl_initialize_lua_module: } - { \__csl_load_bbl: } - } - - -\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 - \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 } - { - \exp_args:Nx \__csl_write_aux_bibdata:n - { \clist_use:Nn \l__csl_bib_resources_clist { , } } - } - \__csl_write_aux_csl_options: - } - -\cs_new:Npn \__csl_write_aux_bibstyle:n #1 - { - \if@filesw - \iow_now:Nx \@auxout { \token_to_str:N \csl@aux@style {#1} } - \fi - } - - -\cs_new:Npn \__csl_initialize_lua_module: - { - \lua_now:e - { - csl.init( - "\l__csl_style_tl", - "\l__csl_bib_resources_clist", - "\l__csl_locale_tl" - ) - } - \str_if_eq:eeT { \lua_now:n { tex.print(csl.initialized) } } { true } - { \bool_set_true:N \l__csl_engine_initialized_bool } - \__csl_get_style_class: - \@ifpackageloaded { hyperref } - { \lua_now:n { csl.enable_linking() } } - { } - } - - -% \str_new:N \l__csl_style_class_str -% In-text (including numeric or author-date) or note style -% \bool_new:N \l__csl_note_style_bool - -\cs_new:Npn \__csl_get_style_class: { - \bool_if:NT \l__csl_engine_initialized_bool - { - \tl_set:Nx \l__csl_class_tl { \lua_now:n { csl.get_style_class() } } - \tl_if_eq:NnT \l__csl_class_tl { note } - { \bool_set_true:N \l__csl_note_bool } - } -} - - -\clist_new:N \l__csl_options_clist - -\cs_new:Npn \__csl_write_aux_csl_options: - { - \clist_clear:N \l__csl_options_clist - % locale - \tl_if_empty:NT \l__csl_locale_tl - { - \tl_if_exist:NT \bbl@main@language - { - \prop_get:NVN \l__csl_language_code_map_prop \bbl@main@language - \l__csl_locale_tl - } - } - \tl_if_empty:NF \l__csl_locale_tl - { - \clist_put_right:Nx \l__csl_options_clist - { locale = \l__csl_locale_tl } - } - % linking - \@ifpackageloaded { hyperref } - { \clist_put_right:Nn \l__csl_options_clist { linking = true } } - { } - % write to aux file - \prop_if_empty:NF \l__csl_options_clist - { - \exp_args:Nx \__csl_write_aux_options:n - { \clist_use:Nn \l__csl_options_clist { , } } - } - } - -\cs_new:Npn \__csl_write_aux_options:n #1 - { - \if@filesw - \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 \cslcitation command is processed and the contents -% of `thebibliography` is stored into \g__csl_bibliography_tl. -\cs_new:Npn \__csl_load_bbl: - { - % The \@input@ prints "No file ....bbl" in the .log file from which - % the latexmk decides to run $bibtex or not. - \__csl_collect_bibliography:n { \@input@ { \jobname .bbl } } - % Execute the \cslsetup part to set the style class. - % \tl_show:N \g__csl_bibliography_setup_tl - \tl_use:N \g__csl_bibliography_setup_tl - % \bool_show:N \l__csl_note_bool - } - -% Collection the bibliography (as well as \cslsetup) into \g__csl_bibliography_setup_tl -\cs_new:Npn \__csl_collect_bibliography:n #1 - { - \group_begin: - % URLs may contain "%" and "#" characters. - \char_set_catcode_other:N \% - \char_set_catcode_other:N \# - \RenewDocumentCommand \cslsetup { m } - { \tl_gset:Nn \g__csl_bibliography_setup_tl { \cslsetup { ##1 } } } - \RenewDocumentEnvironment { thebibliography } { m +b } - { - \tl_gset:Nn \g__csl_bibliography_tl - { - \begin { thebibliography } {##1} - ##2 - \end { thebibliography } - } - } - { } - % Perform the execution - #1 - \tl_if_empty:NF \g__csl_bibliography_setup_tl - { - \tl_gput_left:Nn \g__csl_bibliography_tl { \par } - \tl_gput_left:NV \g__csl_bibliography_tl \g__csl_bibliography_setup_tl - } - \group_end: - } - -% \msg_new:nnn { citation-style-language } { file / non-exist } -% { No~ file~ #1. } - - -\DeclareDocumentCommand \bibliographystyle { m } - { - \__csl_if_preamble:F - { \__csl_write_aux_bibstyle:n {#1} } - \tl_set:Nn \l__csl_style_tl {#1} - } - -\tl_new:N \g__csl_aux_bibstyle_tl -\cs_set:Npn \csl@aux@style #1 - { \tl_gset:Nn \g__csl_aux_bibstyle_tl {#1} } - - -\NewDocumentCommand \addbibresource { o m } - { \clist_put_right:Nn \l__csl_bib_resources_clist {#2} } - - -% In earlier time, \bibdata{xxx.json} was used but this causes latexmk unable -% 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@aux@data #1 - { \clist_gput_right:Nn \g__csl_aux_bib_files_clist {#1} } - - -\DeclareDocumentCommand \bibliography { m } - { - \__csl_write_aux_bibdata:n {#1} - \printbibliography - } - -\cs_new:Npn \__csl_write_aux_bibdata:n #1 - { - \if@filesw - % Full expansion for files like \jobname.bib - \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_plain:nn [#1]#2 - { - \clist_gput_right:Nn \g__csl_bib_items_clist {#2} - \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: - - -% 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 - { - \clist_gput_right:Nn \g__csl_bib_items_clist {#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 } \cs_new:Npn \__csl_set_back_ref:n #1 @@ -1189,372 +107,38 @@ } } - -% CSL outputs the whole label thus the brackets are removed from \@biblabel -% \def\@biblabel#1{[#1]} -\cs_set:Npn \@biblabel #1 {#1} - - -% Bibliography heading -\cs_if_exist:cTF { chapter } - { - \tl_set:Nn \bibsection - { - \chapter* - { - \bibname - \@mkboth - { \MakeUppercase { \bibname } } - { \MakeUppercase { \bibname } } - } - } - } - { - \tl_set:Nn \bibsection - { - \section* - { - \refname - \@mkboth - { \MakeUppercase { \refname } } - { \MakeUppercase { \refname } } - } - } - } - -\tl_new:N \l__csl_bib_preamble_tl - -\tl_new:N \l__csl_bib_postamble_tl - -\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 } - } - { - \settowidth \labelwidth { \@biblabel {#1} } - \dim_set_eq:NN \leftmargin \labelwidth - \dim_add:Nn \leftmargin { \labelsep } - } - } - -% 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 } } - } - - -% See <https://github.com/plk/biblatex/blob/e16f4aaa5d9857c7b844bbcbe246f0535fd334e9/tex/latex/biblatex/biblatex.def#L219-L258> - -\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 - } - -\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 - -\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 - } - -% The above 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. - - -% It will be used for multi-bibliography. -\cs_new:Npn \__csl_reset_bib_format: - { - \keys_set:nn { csl } { - hanging-indent = false , - line-spacing = 1 , - entry-spacing = 1 , - } - } - -% \newenvironment{thebibliography}[1] -\RenewDocumentEnvironment { thebibliography } { m } - { - \bibsection - \dim_zero:N \parindent - \l__csl_bib_preamble_tl - \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 {#1} - \__csl_set_bib_item_sep: - } - \sloppy - \__csl_set_bib_page_break: - \frenchspacing - \__csl_bib_url_setup: - \clist_gclear:N \g__csl_bib_items_clist - } - { - \l__csl_bib_postamble_tl - \tl_set:Nn \@noitemerr - { \msg_warning:nn { citation-style-language } { bibliography / empty } } - \endlist - \__csl_reset_bib_format: - } - - -% 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 - -% This should be disabled. -\AtEndOfPackageFile* { babel } +% Default settings +\keys_set:nn { csl } { - \RenewDocumentCommand \nocite { m } - { - % \@safe@activestrue\org@nocite{#1}\@safe@activesfalse - \@safe@activestrue - \__csl_no_cite:n {#1} - \@safe@activesfalse - } - \cs_set_eq:NN \bbl@cite@choice \relax - \cs_set_eq:NN \@lbibitem \__csl_lbibitem_plain:nn - \cs_set_eq:NN \@bibitem \__csl_bibitem_plain:n + backref = false , + prefix-separator = { ~ } , + suffix-separator = { , ~ } , + bib-entry-page-break = true , + bib-hang = { 1 em } , } -% csquotes - -\AtEndOfPackageFile* { csquotes } - { - \BlockquoteDisable - { - \cs_set_eq:NN \__csl_process_citation_info:NN \use_none:nn - \cs_set_eq:NN \__csl_make_citation:N \use_none:n - } - } - +\ProcessKeysPackageOptions { csl } -% hyperref -% 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 } +\DeclareDocumentCommand \bibliographystyle { m } { - \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 + \__csl_if_preamble:F + { \__csl_write_aux_bibstyle:n {#1} } + \tl_set:Nn \l__csl_style_tl {#1} } -\cs_set:Npn \__csl_hyperref_cite_item:nn #1#2 - { \hyper@@link [ cite ] { } { cite. #1 \@extra@b@citeb } { #2 } } +\tl_new:N \g__csl_aux_bibstyle_tl +\cs_set:Npn \csl@aux@style #1 + { \tl_gset:Nn \g__csl_aux_bibstyle_tl {#1} } -\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 - } +% Load other modules +\input{citation-style-language-init.sty} +\input{citation-style-language-data.sty} +\input{citation-style-language-cite.sty} +\input{citation-style-language-bib.sty} +\input{citation-style-language-compatible.sty} \endinput |