summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/citation-style-language/citation-style-language.sty
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/latex/citation-style-language/citation-style-language.sty')
-rw-r--r--Master/texmf-dist/tex/latex/citation-style-language/citation-style-language.sty729
1 files changed, 455 insertions, 274 deletions
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 117e9c844ab..546ac13eeca 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
@@ -1,46 +1,40 @@
%
-% Copyright (C) 2021 Zeping Lee
+% Copyright (c) 2021-2022 Zeping Lee
+% Released under the MIT License.
+% Repository: https://github.com/zepinglee/citeproc-lua
%
\NeedsTeXFormat{LaTeX2e}
+
\RequirePackage{expl3}
\RequirePackage{xparse}
+
\ProvidesExplPackage {citation-style-language} {2022-01-22} {v0.1.0}
{Citation Style Language for LaTeX}
-% \msg_new:nnn { citation-style-language } { require-luatex }
-% { LuaTeX~ is~ required~ for~ `citation-style-language'~ package. }
-% \sys_if_engine_luatex:F { \msg_fatal:nn { citation-style-language } { require-luatex } }
-
-\sys_if_engine_luatex:T
- { \lua_now:n { csl = require("csl") } }
-
\RequirePackage { filehook }
\RequirePackage { url }
-\cs_new:Npn \csl_incompatible_package:n #1
- {
- \AtBeginOfPackageFile* { #1 }
- { \msg_error:nnn { citation-style-language } { incompatible-package } { #1 } }
- }
+% Check incompatible packages
\msg_new:nnn { citation-style-language } { incompatible-package }
{ The~ `#1'~ package~ is~ incompatible~ with~ `citeproc'. }
-\csl_incompatible_package:n { babelbib }
-\csl_incompatible_package:n { backref }
-\csl_incompatible_package:n { biblatex }
-\csl_incompatible_package:n { bibtopic }
-\csl_incompatible_package:n { bibunits }
-\csl_incompatible_package:n { chapterbib }
-\csl_incompatible_package:n { cite }
-\csl_incompatible_package:n { citeref }
-\csl_incompatible_package:n { inlinebib }
-\csl_incompatible_package:n { jurabib }
-\csl_incompatible_package:n { mcite }
-\csl_incompatible_package:n { mciteplus }
-\csl_incompatible_package:n { multibib }
-\csl_incompatible_package:n { natbib }
-\csl_incompatible_package:n { splitbib }
+\cs_new_protected:Npn \__csl_load_check:n #1
+ {
+ \AtBeginOfPackageFile* {#1}
+ { \msg_error:nnn { citation-style-language } { incompatible-package } {#1} }
+ }
+
+\clist_map_function:nN
+ {
+ babelbib , backref , biblatex , bibtopic , bibunits , chapterbib ,
+ cite , citeref , inlinebib , jurabib , mcite , mciteplus ,
+ multibib , natbib , splitbib
+ }
+ \__csl_load_check:n
+
+\sys_if_engine_luatex:T
+ { \lua_now:n { csl = require("csl") } }
\NewDocumentCommand \cslsetup { m }
@@ -50,243 +44,237 @@
\DeclareDocumentCommand \cite { o o m }
- {
- \IfValueTF { #2 }
- { \csl_cite:nnn { #1 } { #2 } { #3 } }
- {
- \IfValueTF { #1 }
- { \csl_cite:nnn { } { #1 } { #3 } }
- { \csl_cite:nnn { } { } { #3 } }
- }
- }
+ { \__csl_cite:nnn {#1} {#2} {#3} }
-% % multicite command
-% \DeclareDocumentCommand \cites { o o m }
+% \cites[⟨prenote⟩][⟨postnote⟩]{⟨key⟩}...[⟨prenote⟩][⟨postnote⟩]{⟨key⟩}
+\NewDocumentCommand \cites { }
+ { \__csl_cites: }
-\DeclareDocumentCommand \nocite { m }
- {
- \ifx \@begindocumenthook \@undefined \else
- \exp_after:wN \AtBeginDocument
- \fi
- {
- \if@filesw
- \iow_now:Nn \@auxout
- { \citation { { nocite } { #1 } { } } }
- \fi
- }
- \sys_if_engine_luatex:T
- { \lua_now:n { csl.nocite("#1") } }
-}
-
-
-\tl_new:N \l__csl_citation_tl
-\tl_new:N \l__csl_citation_id_tl
-\tl_new:N \l__csl_cite_items_tl
-\tl_new:N \l__csl_note_index_tl
-\tl_new:N \l__csl_citation_info_tl
+\seq_new:N \l__csl_cite_keys_seq
+\seq_new:N \l__csl_cite_items_seq
-\cs_new:Npn \csl_cite:nnn #1#2#3
+\cs_new:Npn \__csl_cite:nnn #1#2#3
{
- \csl_process_citation_id:n { #3 }
- \csl_process_cite_items:nnn { #1 } { #2 } { #3 }
- \exp_args:NV \csl_process_note_index:n \l__csl_citation_id_tl
- \tl_set:Nx \l__csl_citation_info_tl
- {
- { \l__csl_citation_id_tl }
- { \l__csl_cite_items_tl }
- { \l__csl_note_index_tl }
- }
- \if@filesw
- {
- \iow_now:Nx \@auxout
- { \exp_not:N \citation { \l__csl_citation_info_tl } }
- }
- \fi
- \tl_clear:N \l__csl_citation_tl
- \tl_if_exist:cTF { g__csl_citation_ \l__csl_citation_id_tl _tl }
- {
- \exp_args:Nv \csl_print_defined_citation:n
- { g__csl_citation_ \l__csl_citation_id_tl _tl }
- }
- {
- \bool_if:NTF \l__csl_engine_initialized_bool
- {
- \tl_set:Nx \l__csl_citation_tl
- { \lua_now:e { csl.cite("\l__csl_citation_info_tl") } }
- }
- {
- \exp_args:Nx \csl_print_undefined_citation:n
- { \clist_use:Nn \l__csl_keys_clist { ,~ } }
- }
- }
- }
-
-\cs_new:Npn \csl_print_undefined_citation:n #1
- {
- \tl_set:Nn \l__csl_citation_tl { [ \textbf { #1 } ] }
- \G@refundefinedtrue
- \exp_args:Nnnx \msg_warning:nnn { citation-style-language } { citation / undefined } { #1 }
- \group_begin:
- \reset@font [ \textbf { #1 } ]
- \group_end:
+ \seq_clear:N \l__csl_cite_keys_seq
+ \seq_clear:N \l__csl_cite_items_seq
+ \__csl_process_cite_items:nnn {#1} {#2} {#3}
+ \__csl_make_citation:NN \l__csl_cite_keys_seq \l__csl_cite_items_seq
}
-\cs_new:Npn \csl_print_defined_citation:n #1
- {
- \csl_print_defined_citation_aux:nn #1
- }
-\cs_new:Npn \csl_print_defined_citation_aux:nn #1#2
+\cs_new:Npn \__csl_cites:
{
- \tl_set:Nn \l__csl_citation_tl { #2 }
- \tl_if_eq:nnTF { #1 } { note }
- { \footnote { #2 } }
- { #2 }
+ \seq_clear:N \l__csl_cite_keys_seq
+ \seq_clear:N \l__csl_cite_items_seq
+ \__csl_next_cites:nnn
}
-
-\msg_new:nnn { citation-style-language } { citation / undefined }
+\NewDocumentCommand \__csl_next_cites:nnn { o o g }
{
- Citation~ `#1'~ on~ page~ \thepage \space undefined~ \msg_line_context: .
+ \tl_if_novalue:nTF {#3}
+ { \__csl_make_citation:NN \l__csl_cite_keys_seq \l__csl_cite_items_seq }
+ {
+ \__csl_process_cite_items:nnn {#1} {#2} {#3}
+ \__csl_next_cites:nnn
+ }
}
-\clist_new:N \l__csl_keys_clist
-\tl_new:N \l__csl_normalized_keys_tl
-
-% \csl_process_citation_id:n { <cite item ids> }
-% It sets the `\l__csl_citation_id_tl` `ITEM-1,ITEM-2@4`.
-\cs_new:Npn \csl_process_citation_id:n #1
+\cs_new:Npn \__csl_process_cite_items:nnn #1#2#3
+ % #1,#2: prenote/postnote, #3: keys
{
- \clist_set:Nn \l__csl_keys_clist { #1 }
- \tl_set:Nx \l__csl_normalized_keys_tl
- { \clist_use:Nn \l__csl_keys_clist { , } }
- \int_if_exist:cF { g__csl_citation_count_ \l__csl_normalized_keys_tl _int }
+ \tl_if_novalue:nTF {#2}
{
- \int_gzero_new:c
- { g__csl_citation_count_ \l__csl_normalized_keys_tl _int }
- }
- \int_gincr:c { g__csl_citation_count_ \l__csl_normalized_keys_tl _int }
- \tl_set:Nx \l__csl_citation_id_tl
- {
- \l__csl_normalized_keys_tl @
- \int_use:c { g__csl_citation_count_ \l__csl_normalized_keys_tl _int }
+ \tl_if_novalue:nTF {#1}
+ { \__csl_process_cite_items_aux:nnn { } { } {#3} }
+ { \__csl_process_cite_items_aux:nnn { } {#1} {#3} }
}
+ { \__csl_process_cite_items_aux:nnn {#1} {#2} {#3} }
}
-
-\tl_new:N \l__csl_cite_item_tl
-
-% `{citationID}{{id={id1},{}},{}}{<noteIndex>}`
-\cs_new:Npn \csl_process_cite_items:nnn #1#2#3
+\cs_new:Npn \__csl_process_cite_items_aux:nnn #1#2#3
+ % #1: prenote, #2: postnote, #3: keys
+ % Return: "{id={ITEM-1},{locator=6},...}, {id={ITEM-2},...}, ..."
{
- \tl_clear:N \l__csl_cite_items_tl
- \clist_map_inline:nn { #3 }
+ \int_zero:N \l_tmpa_int
+ \clist_map_inline:nn {#3}
{
- \tl_if_empty:NTF \l__csl_cite_items_tl
- {
- \csl_process_cite_item:nnn { #1 } { #2 } { ##1 }
- \tl_put_right:Nx \l__csl_cite_items_tl { { \l__csl_cite_item_tl } }
- }
- {
- \csl_process_cite_item:nnn { } { } { ##1 }
- \tl_put_right:Nx \l__csl_cite_items_tl { , { \l__csl_cite_item_tl } }
- }
+ \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
-
-\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,
- book .code:n = { \csl_set_locator:nn { book } { #1 } } ,
- chapter .code:n = { \csl_set_locator:nn { chapter } { #1 } } ,
- column .code:n = { \csl_set_locator:nn { column } { #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 } } ,
- section .code:n = { \csl_set_locator:nn { section } { #1 } } ,
- sub-verbo .code:n = { \csl_set_locator:nn { sub-verbo } { #1 } } ,
- verse .code:n = { \csl_set_locator:nn { verse } { #1 } } ,
- volume .code:n = { \csl_set_locator:nn { volume } { #1 } } ,
- }
-
-\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 }
- }
-
\tl_new:N \l__csl_prefix_tl
\tl_new:N \l__csl_suffix_tl
-% \csl_process_cite_item:nnn { <prenote> } { <postnote> } { <item ID> }
-% return: `id={ITEM},locator={42},label={page}`
-\cs_new:Npn \csl_process_cite_item:nnn #1#2#3
+\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_cite_items_seq
{
\prop_clear:N \l__csl_cite_item_prop
- \prop_put:Nnn \l__csl_cite_item_prop { id } { #3 }
- \tl_if_empty:nF { #1 }
+ \prop_put:Nnn \l__csl_cite_item_prop { id } {#3}
+ \tl_if_empty:nF {#1}
{
- \tl_set:Nn \l__csl_prefix_tl { #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_in:nnTF { #2 } { = }
+ \tl_if_in:nnTF {#2} { = }
{
- \keys_set:nn { csl / cite-item } { #2 }
+ \keys_set:nn { csl / cite-item } {#2}
}
{
- \tl_if_empty:nF { #2 }
+ \tl_if_empty:nF {#2}
{
- \regex_match:nnTF { \d+ } { #2 }
- { \csl_set_locator:nn { page } { #2 } }
+ \regex_match:nnTF { \d+ } {#2}
+ { \__csl_set_locator:nn { page } {#2} }
{
- \tl_set:Nn \l__csl_suffix_tl { #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 }
}
}
}
- \tl_clear:N \l__csl_cite_item_tl
+ \seq_clear:N \l_tmpa_seq
\prop_map_inline:Nn \l__csl_cite_item_prop
+ { \seq_put_right:Nn \l_tmpa_seq { ##1 = {##2} } }
+ \seq_put_right:Nx \l__csl_cite_items_seq
+ { { \seq_use:Nn \l_tmpa_seq { , } } }
+ }
+
+\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,
+ act .code:n = { \__csl_set_locator:nn { act } {#1} } ,
+ appendix .code:n = { \__csl_set_locator:nn { appendix } {#1} } ,
+ article-locator .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-locator .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} } ,
+ }
+
+
+\tl_new:N \l__csl_citation_id_tl
+\tl_new:N \l__csl_cite_items_tl
+\tl_new:N \l__csl_note_index_tl
+\tl_new:N \l__csl_citation_info_tl
+\tl_new:N \l__csl_citation_tl
+\prop_new:N \g__csl_citations_prop
+
+\cs_new:Npn \__csl_make_citation:NN #1#2
+ % #1: \l__csl_cite_keys_seq
+ % #2: \l__csl_cite_items_seq
+ {
+ \__csl_process_citation_id:NN \l__csl_citation_id_tl #1
+ \tl_set:Nx \l__csl_cite_items_tl
+ { \seq_use:Nn #2 { , } }
+ \exp_args:NNV \__csl_process_note_index:Nn \l__csl_note_index_tl \l__csl_citation_id_tl
+ \tl_set:Nx \l__csl_citation_info_tl
+ {
+ { \l__csl_citation_id_tl }
+ { \l__csl_cite_items_tl }
+ { \l__csl_note_index_tl }
+ }
+ \exp_args:NV \__csl_write_aux_citation:n \l__csl_citation_info_tl
+ \prop_get:NVNTF \g__csl_citations_prop \l__csl_citation_id_tl
+ \l__csl_citation_tl
+ { \exp_args:NV \__csl_print_citation:n \l__csl_citation_tl }
+ {
+ \bool_if:NTF \l__csl_engine_initialized_bool
+ {
+ \tl_set:Nx \l__csl_citation_tl
+ { \lua_now:e { csl.cite("\l__csl_citation_info_tl") } }
+ }
+ {
+ \exp_args:Nx \__csl_print_undefined_citation:n
+ { \seq_use:Nn \l__csl_cite_keys_seq { ,~ } }
+ }
+ }
+ }
+
+
+\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_get:NVNTF \g__csl_citations_count_prop \l__csl_cite_keys_tl
+ \l__csl_citation_count_tl
{
- \tl_if_empty:NF \l__csl_cite_item_tl
- { \tl_put_right:Nn \l__csl_cite_item_tl { , } }
- \tl_put_right:Nn \l__csl_cite_item_tl { ##1 = { ##2 } }
+ \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 \l__csl_note_index_int
\int_gzero_new:N \g__csl_last_note_index_int
\int_gzero_new:N \g__csl_citation_note_count_int
-% \csl_process_note_index:nnn { <citation ID> }
-\cs_new:Npn \csl_process_note_index:n #1
+\cs_new:Npn \__csl_process_note_index:Nn #1#2
+ % #1 \l__csl_note_index_tl
+ % #2: citationID
{
\int_set_eq:Nc \l__csl_note_index_int { c@ \@mpfn }
- \tl_if_exist:cTF { g__csl_citation_ #1 _tl }
+ \prop_if_in:NnTF \g__csl_citations_prop {#2}
{ \int_incr:N \l__csl_note_index_int }
{ \int_gincr:N \g__csl_citation_note_count_int }
\int_add:Nn \l__csl_note_index_int { \g__csl_citation_note_count_int }
- \tl_set:Nx \l__csl_note_index_tl
- { \int_use:N \l__csl_note_index_int }
+ \tl_set:Nx #1 { \int_use:N \l__csl_note_index_int }
\int_gset_eq:NN \g__csl_last_note_index_int \l__csl_note_index_int
\int_compare:nT { \l__csl_note_index_int < \g__csl_last_note_index_int }
{
@@ -296,6 +284,73 @@
}
+\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
+ { \citation { #1 } }
+ \fi
+ }
+
+
+\cs_new:Npn \__csl_print_citation:n #1
+ % #1: "{<type>}{<citation text>}"
+ { \__csl_print_citation_aux:nn #1 }
+
+\cs_new:Npn \__csl_print_citation_aux:nn #1#2
+ % #1: citation type, "in-text" or "note"
+ % #2: citation text
+ {
+ \tl_set:Nn \l__csl_citation_tl {#2}
+ \tl_if_eq:nnTF {#1} { note }
+ { \footnote {#2} }
+ {#2}
+ }
+
+
+\cs_new:Npn \__csl_print_undefined_citation:n #1
+ % #1: keys
+ {
+ \tl_set:Nn \l__csl_citation_tl { [ \textbf {#1} ] }
+ \G@refundefinedtrue
+ \msg_warning:nnn { citation-style-language } { citation / undefined } {#1}
+ \group_begin:
+ \reset@font [ \textbf {#1} ]
+ \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
+ {
+ \__csl_if_preamble:TF
+ {
+ \AtBeginDocument
+ { \__csl_write_aux_citation:n { { nocite } {#1} { } } }
+ }
+ { \__csl_write_aux_citation:n { { nocite } {#1} { } } }
+ \sys_if_engine_luatex:T
+ { \lua_now:n { csl.nocite("#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.
\cs_set:Npn \citation #1
{
@@ -306,34 +361,20 @@
\cs_new:Npn \cslcite #1#2
{
- \bibcite { #1 } { #2 }
+ \bibcite {#1} {#2}
\if@filesw
- \iow_now:Nn \@auxout { \bibcite { #1 } { #2 } }
+ \iow_now:Nn \@auxout { \bibcite {#1} {#2} }
\fi
}
-\cs_set:Npn \bibcite #1#2
- {
- \tl_gset:cn { g__csl_citation_ #1 _tl } { #2 }
- }
+\cs_new:Npn \__csl_bibcite:nn #1#2
+ { \prop_gput:Nnn \g__csl_citations_prop {#1} {#2} }
-% The `babel` package redefines \bibcite in the \@begindocumenthook.
-% This should be disabled.
-\AtEndOfPackageFile* { babel }
- {
- \cs_set_eq:NN \bbl@cite@choice \relax
- }
+\cs_set_eq:NN \bibcite \__csl_bibcite:nn
-\AtEndOfPackageFile* { hyperref }
- {
- \cs_set:Npn \bibcite #1#2
- {
- \tl_gset:cn { g__csl_citation_ #1 _tl } { #2 }
- }
- }
-\NewDocumentCommand \printbibliography { }
+\NewDocumentCommand \printbibliography { O { } }
{
\sys_if_engine_luatex:TF
{
@@ -349,11 +390,11 @@
\msg_warning:nnx { citation-style-language } { file / non-exist} { \jobname .bbl }
}
}
- { \exp_args:NV \csl_print_bibiliography_tl \l__csl_bibliography_tl }
+ { \exp_args:NV \__csl_print_bibliography:n \l__csl_bibliography_tl }
}
}
-\cs_new:Npn \csl_print_bibliography_tl #1
+\cs_new:Npn \__csl_print_bibliography:n #1
{
\begin { thebibliography }
#1
@@ -529,14 +570,14 @@
{
\tl_if_empty:NTF \l__csl_style_tl
{ \tl_set_eq:NN \l__csl_style_tl \g__csl_aux_bibstyle_tl }
- { \exp_args:Nx \csl_write_aux_bibstyle:n { \l__csl_style_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
+ \exp_args:Nx \__csl_write_aux_bibdata:n
{ \clist_use:Nn \l__csl_bib_resources_clist { , } }
}
- \csl_write_aux_csl_options:
+ \__csl_write_aux_csl_options:
\sys_if_engine_luatex:T
{
\lua_now:e
@@ -558,24 +599,24 @@
% of `thebibliography` is stored into \l__csl_bibliography_tl.
\group_begin:
\RenewDocumentCommand \cslsetup { m }
- { \tl_set:Nn \l__csl_bibliography_setup_tl { #1 } }
+ { \tl_set:Nn \l__csl_bibliography_setup_tl {#1} }
\RenewDocumentEnvironment { thebibliography } { m +b }
- { \tl_set:Nn \l__csl_bibliography_tl { { #1 } #2 } }
+ { \tl_set:Nn \l__csl_bibliography_tl { {#1} #2 } }
{ }
\file_if_exist_input:n { \jobname .bbl }
\group_end:
}
-\cs_new:Npn \csl_write_aux_bibstyle:n #1
+\cs_new:Npn \__csl_write_aux_bibstyle:n #1
{
\if@filesw
- \iow_now:Nn \@auxout { \bibstyle { #1 } }
+ \iow_now:Nn \@auxout { \bibstyle {#1} }
\fi
}
\clist_new:N \l__csl_options_clist
-\cs_new:Nn \csl_write_aux_csl_options:
+\cs_new:Npn \__csl_write_aux_csl_options:
{
\clist_clear:N \l__csl_options_clist
% locale
@@ -612,40 +653,40 @@
\DeclareDocumentCommand \bibliographystyle { m }
{
- \ifx \@begindocumenthook \@undefined
- \csl_write_aux_bibstyle:n { #1 }
- \fi
- \tl_set:Nn \l__csl_style_tl { #1 }
+ \__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 \bibstyle #1
- { \tl_gset:Nn \g__csl_aux_bibstyle_tl { #1 } }
+ { \tl_gset:Nn \g__csl_aux_bibstyle_tl {#1} }
\NewDocumentCommand \addbibresource { o m }
- { \clist_put_right:Nn \l__csl_bib_resources_clist { #2 } }
+ { \clist_put_right:Nn \l__csl_bib_resources_clist {#2} }
\clist_new:N \g__csl_aux_bib_files_clist
\cs_set:Npn \bibdata #1
- { \clist_gput_right:Nn \g__csl_aux_bib_files_clist { #1 } }
+ { \clist_gput_right:Nn \g__csl_aux_bib_files_clist {#1} }
\DeclareDocumentCommand \bibliography { m }
{
- \csl_write_aux_bibdata:n { #1 }
+ \__csl_write_aux_bibdata:n {#1}
\printbibliography
}
-\cs_new:Npn \csl_write_aux_bibdata:n #1
+\cs_new:Npn \__csl_write_aux_bibdata:n #1
{
\if@filesw
- \iow_now:Nn \@auxout { \bibdata { #1 } }
+ \iow_now:Nn \@auxout { \bibdata {#1} }
\fi
}
+% Used for debugging and testing
\clist_new:N \g__csl_bib_items_clist
% For numeric or label-style bibliography
@@ -653,39 +694,34 @@
% {\let\protect\noexpand
% \immediate
% \write\@auxout{\string\bibcite{#2}{#1}}}\fi\ignorespaces}
-\cs_new:Npn \csl_lbibitem:nn [#1]#2
+\cs_new:Npn \__csl_lbibitem:nn [#1]#2
{
- \clist_gput_right:Nn \g__csl_bib_items_clist { #2 }
- \item [ \@biblabel { #1 } \hfill ] \ignorespaces
+ \clist_gput_right:Nn \g__csl_bib_items_clist {#2}
+ \item [ \@biblabel {#1} \hfill ] \ignorespaces
}
-\cs_set_eq:NN \@lbibitem \csl_lbibitem:nn
+\cs_set_eq:NN \@lbibitem \__csl_lbibitem:nn
% For author-date bibliography
% \def\@bibitem#1{\item\if@filesw \immediate\write\@auxout
% {\string\bibcite{#1}{\the\value{\@listctr}}}\fi\ignorespaces}
-\cs_new:Npn \csl_bibitem:n #1
+\cs_new:Npn \__csl_bibitem:n #1
{
- \clist_gput_right:Nn \g__csl_bib_items_clist { #1 }
+ \clist_gput_right:Nn \g__csl_bib_items_clist {#1}
\item [ ] \ignorespaces
}
-\cs_set_eq:NN \@bibitem \csl_bibitem:n
+\cs_set_eq:NN \@bibitem \__csl_bibitem:n
-\AtEndOfPackageFile* { hyperref }
- {
- \cs_gset_eq:NN \@lbibitem \csl_lbibitem:nn
- \cs_gset_eq:NN \@bibitem \csl_bibitem:n
- }
% CSL outputs the whole label thus the brackets are removed from \@biblabel
% \def\@biblabel#1{[#1]}
-\cs_set:Npn \@biblabel #1 { #1 }
+\cs_set:Npn \@biblabel #1 {#1}
\cs_if_exist:cTF { chapter }
{
- \cs_set:Nn \csl_bib_section:
+ \cs_set:Nn \__csl_bib_section:
{
- \chapter *
+ \chapter*
{
\bibname
\@mkboth
@@ -695,9 +731,9 @@
}
}
{
- \cs_set:Nn \csl_bib_section:
+ \cs_set:Nn \__csl_bib_section:
{
- \section *
+ \section*
{
\refname
\@mkboth
@@ -714,7 +750,7 @@
\dim_new:N \l__csl_bib_hang_dim
\skip_new:N \l__csl_bib_item_sep_skip
-\cs_new:Npn \csl_set_bib_label_spacing:n #1
+\cs_new:Npn \__csl_set_bib_label_spacing:n #1
{
\bool_if:NTF \l__csl_hanging_indent_bool
{
@@ -723,13 +759,13 @@
\dim_set:Nn \itemindent { - \leftmargin }
}
{
- \settowidth \labelwidth { \@biblabel { #1 } }
+ \settowidth \labelwidth { \@biblabel {#1} }
\dim_set_eq:NN \leftmargin \labelwidth
\dim_add:Nn \leftmargin { \labelsep }
}
}
-\cs_new:Nn \csl_set_bib_item_sep:
+\cs_new:Npn \__csl_set_bib_item_sep:
{
\skip_zero:N \parsep
\tl_if_empty:NTF \l__csl_bib_item_sep_tl
@@ -743,7 +779,7 @@
{ \skip_set:Nn \l__csl_bib_item_sep_skip { \l__csl_bib_item_sep_tl } }
}
-\cs_new:Nn \csl_set_bib_allow_break:
+\cs_new:Npn \__csl_set_bib_allow_break:
{
\sloppy
\int_set:Nn \clubpenalty { 4000 }
@@ -752,11 +788,10 @@
% \sfcode`\.\@m
\frenchspacing
}
-% TODO: \biburlsetup
-\cs_new_eq:NN \csl_set_bib_page_break: \csl_set_bib_allow_break:
+\cs_new_eq:NN \__csl_set_bib_page_break: \__csl_set_bib_allow_break:
-\cs_new:Nn \csl_set_bib_no_break:
+\cs_new:Npn \__csl_set_bib_no_break:
{
\sloppy
\int_set:Nn \interlinepenalty { 5000 }
@@ -767,8 +802,117 @@
\frenchspacing
}
+
+% 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:Nn \csl_reset_bib_format:
+\cs_new:Npn \__csl_reset_bib_format:
{
\keys_set:nn { csl } {
hanging-indent = false ,
@@ -780,7 +924,7 @@
% \newenvironment{thebibliography}[1]
\RenewDocumentEnvironment { thebibliography } { m }
{
- \csl_bib_section:
+ \__csl_bib_section:
\dim_zero:N \parindent
\l__csl_bib_preamble_tl
\tl_if_eq:NnF \l__csl_line_spacing_tl { 1 }
@@ -788,12 +932,13 @@
\l__csl_bib_font_tl
\list { }
{
- \csl_set_bib_label_spacing:n { #1 }
- \csl_set_bib_item_sep:
+ \__csl_set_bib_label_spacing:n {#1}
+ \__csl_set_bib_item_sep:
}
\sloppy
- \csl_set_bib_page_break:
+ \__csl_set_bib_page_break:
\frenchspacing
+ \__csl_bib_url_setup:
\clist_gclear:N \g__csl_bib_items_clist
}
{
@@ -801,7 +946,43 @@
\tl_set:Nn \@noitemerr
{ \msg_warning:nnn { citation-style-language } { bibliography / empty } }
\endlist
- \csl_reset_bib_format:
+ \__csl_reset_bib_format:
+ }
+
+
+
+% Compatibilities with other packages
+
+% babel
+
+% The `babel` package redefines \bibcite in the \@begindocumenthook.
+% 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 \bibcite \__csl_bibcite:nn
+ \cs_set_eq:NN \bbl@cite@choice \relax
+ \cs_set_eq:NN \@bibitem \__csl_bibitem:n
}
+
+% hyperref
+
+% The hyperref package also patches \bibcite but it cannot provide hyperlinks
+% when used with csl.
+\AtEndOfPackageFile* { hyperref }
+ {
+ \cs_set_eq:NN \bibcite \__csl_bibcite:nn
+ \cs_set_eq:NN \Hy@bibcite \bibcite
+ \cs_gset_eq:NN \@lbibitem \__csl_lbibitem:nn
+ \cs_gset_eq:NN \@bibitem \__csl_bibitem:n
+ }
+
+
\endinput