diff options
Diffstat (limited to 'macros/latex/contrib/easybook/easybook.dtx')
-rw-r--r-- | macros/latex/contrib/easybook/easybook.dtx | 965 |
1 files changed, 583 insertions, 382 deletions
diff --git a/macros/latex/contrib/easybook/easybook.dtx b/macros/latex/contrib/easybook/easybook.dtx index 30f7860795..93f570b482 100644 --- a/macros/latex/contrib/easybook/easybook.dtx +++ b/macros/latex/contrib/easybook/easybook.dtx @@ -1,5 +1,5 @@ % -% Copyright (C) 2021-2024 by Qu Yi <toquyi@163.com> +% Copyright (C) 2021-2025 by Qu Yi <toquyi@163.com> % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either @@ -14,7 +14,7 @@ % This work has the LPPL maintenance status `maintained'. %<class|package>\NeedsTeXFormat{LaTeX2e}[2021/11/15] %<*class> -\ProvidesExplClass{easybook}{2024/08/14}{2024dj} +\ProvidesExplClass{easybook}{2025/02/16}{2025q} {Easily typesetting Chinese theses or books} \bool_new:N \l__eb_compile_draft_bool @@ -35,16 +35,23 @@ { \tl_set:Nn \l__eb_font_value_tl {#1} }, font .value_required:n = true, font .initial:n = auto, - cjkfont .code:n = \eb_put_ctexbook:n { fontset = #1 }, + cjkfont .code:n = \eb_put_ctexbook:n { fontset = {#1} }, mathfont .tl_set:N = \l__eb_mathfont_value_tl, mathfont .initial:n = times, configs .clist_gset:N = \g__eb_configs_file_clist, - paper .code:n = { }, - class.code:n = { }, - floatpage.code:n = { }, - theorem .code:n = { }, unknown .code:n = \clist_gput_right:NV \g__eb_doc_options_clist \CurrentOption } +\IfFormatAtLeastTF{2024/06/20}{} + { + \keys_define:nn { easybook } + { + paper .code:n = { }, + class .code:n = { }, + floatpage .code:n = { }, + theorem .code:n = { }, + chem .code:n = { } + } + } \cs_if_exist:NTF \ProcessKeyOptions { \ProcessKeyOptions[easybook] } @@ -301,19 +308,15 @@ %</class> %<*package> \RequirePackage{etoolbox} -\ProvidesExplPackage{easybase}{2024/08/14}{2024dj} +\ProvidesExplPackage{easybase}{2025/02/16}{2025q} {Easily typesetting Chinese theses or books} \cs_generate_variant:Nn \dim_set:Nn { NV } \cs_generate_variant:Nn \dim_sign:n { V } \cs_generate_variant:Nn \int_to_arabic:n { v } \cs_generate_variant:Nn \msg_warning:nnn { nnV } -\cs_generate_variant:Nn \prop_set_from_keyval:Nn { NV } \cs_generate_variant:Nn \skip_set:Nn { NV } -\cs_generate_variant:Nn \seq_set_from_clist:Nn { No } \cs_generate_variant:Nn \ctex_define:nn { nx } -\cs_generate_variant:Nn \eb_set_hyperref:n { x } -\cs_generate_variant:Nn \eb_at_begin_environment:nn { o } \cs_generate_variant:Nn \tl_if_novalue:nF { V } \cs_set_protected:Npn \ctex_define:nn #1 @@ -327,11 +330,6 @@ { \AddToHook{cmd/#1/before}{#2} } \cs_new_protected:Npn \eb_appto_cmd:nn #1#2 { \AddToHook{cmd/#1/after}{#2} } -\cs_new_protected:Npn \eb_at_begin_environment:nn #1#2 - { - \clist_map_inline:nn {#1} - { \AtBeginEnvironment{##1}{#2} } - } \cs_set_protected:Npn \ctex_before_end_preamble:n { \BeforeBeginEnvironment{document} } \cs_new_protected:Npn \eb_if_package_loaded:nnF #1#2#3 @@ -394,6 +392,7 @@ \clist_new:N \g__eb_ctex_options_clist \cs_new_protected:Npn \eb_put_geometry:n #1 { \PassOptionsToPackage{#1}{geometry} } +\providebool{@openright} \keys_define:nn { easybase } { @@ -405,9 +404,18 @@ floatpage .bool_set:N = \l__eb_float_page_bool, floatpage .default:n = true, floatpage .initial:n = false, - theorem .bool_set:N = \l__eb_theorem_support_bool, - theorem .default:n = true, - theorem .initial:n = true, + theorem .choices:nn = + { thmtools,keytheorems,false } + { \tl_set:Nn \l__eb_theorem_support_tl {#1} }, + theorem/true .meta:n = { theorem = thmtools }, + theorem .default:n = thmtools, + theorem .initial:n = thmtools, + chem .choices:nn = + { chemformula,mhchem,false } + { \tl_set:Nn \l__eb_chem_support_tl {#1} }, + chem/true .meta:n = { chem = chemformula }, + chem .default:n = chemformula, + chem .initial:n = chemformula, paper .code:n = \eb_put_geometry:n {#1}, paper .initial:n = a4paper, class .choice:, @@ -416,15 +424,24 @@ { \bool_set_true:N \l__eb_class_mode_book_bool \eb_put_geometry:n { twoside } + \booltrue{@titlepage} + \booltrue{@openright} }, class/article .code:n = { \bool_set_false:N \l__eb_class_mode_book_bool \eb_put_geometry:n { twoside = false } + \boolfalse{@titlepage} }, - class .initial:n = book, + class .initial:x = \cs_if_exist:NTF \chapter { book } { article }, book .meta:n = { class = book }, article .meta:n = { class = article }, + twoside .code:n = \eb_put_geometry:n { twoside }, + oneside .code:n = \eb_put_geometry:n { twoside = false }, + titlepage .code:n = \booltrue{@titlepage}, + notitlepage .code:n = \boolfalse{@titlepage}, + openright .code:n = \booltrue{@openright}, + openany .code:n = \boolfalse{@openright}, unknown .code:n = \clist_gput_right:NV \g__eb_ctex_options_clist \CurrentOption } @@ -510,11 +527,10 @@ { [text]{spbmark}, [{shortlabels,inline}]{enumitem}, - chemformula,siunitx,pifont, - geometry,marginnote, - pdfpages,multicol, + siunitx,pifont, + geometry,marginnote,multicol, fancyhdr,titletoc,caption, - tabularray, + tabularray,graphicx,xcolor, listings } \cs_new_protected:Npn \eb_package_date_check:nn #1#2 @@ -530,50 +546,8 @@ Please~update~your~macro~package~from~CTAN. } -\NewDocumentCommand{\eb_assign_tagform:n} - {>{\SplitArgument{1}{,}}m} - {\eb_assign_tagform_pos:nn #1} -\cs_new_protected:Npn \eb_assign_tagform_pos:nn #1#2 - { - \tl_set:Nn \eb@tag@brackets@left {#1} - \tl_set:Nn \eb@tag@brackets@right {#2} - } -\cs_gset:Npn \tagform@ #1 - { - \maketag@@@ - { - \color{ctex@emph} - \ignorespaces - \eb@tag@brackets@left{#1} - \unskip\@@italiccorr - \eb@tag@brackets@right - } - } -\ctex_define:nn { tools } - { - multoc .int_set:N = \l__eb_toc_columns_int, - multoc .default:n = 2, - withpart .bool_set:N = \l__eb_chap_counter_withpart_bool, - withpart .default:n = true, - withpart .initial:n = false, - uppercase .tl_set:N = \l__eb_mark_uppercase_value_tl, - uppercase .default:n = all, - uppercase .initial:n = all, - tagform .code:n = \eb_assign_tagform:n {#1}, - tagform .initial:n = { (,) }, - brackets .meta:n = { tagform = {#1} }, - figurepath .code:n = - { - \tl_if_blank:nF {#1} - { - \regex_match:nnTF { \cB. } {#1} - { \graphicspath{#1} } - { \graphicspath{{#1}} } - } - } - } - -\includepdfset{fitpaper = true} +\ctex_at_end_package:nn { pdfpages } + { \includepdfset{fitpaper = true} } \geometry { vmargin = 2.54cm, @@ -627,14 +601,16 @@ \pagenumbering{arabic} } \NewDocumentCommand{\markrule} - {O{\textwidth}D(){ctex@frame}m>{\SplitArgument{1}{|}}O{}} - {\eb_draw_markrule:nnnnn {#1} {#2} {#3} #4} -\cs_new_protected:Npn \eb_draw_markrule:nnnnn #1#2#3#4#5 + {O{\textwidth}D(){ctex@frame}mO{0pt}} { \group_begin: - \tl_if_blank:nF {#4} { \vspace*{#4} } - \color{#2}\hrule\@width #1\@height #3 - \tl_if_novalue:nF {#5} { \vspace*{#5} } + \color{#2} + \exp_last_unbraced:Nx \hrule + { + \@width \dim_eval:n {#1} + \@height \dim_eval:n {#3} + \@depth \dim_eval:n {#4} + } \group_end: } \cs_new:Npn \eb_mark_uppercase_case_init:n @@ -648,10 +624,10 @@ } \cs_new_protected:Npn \eb@register@hdr@mark #1 { - \exp_args:Nc \NewDocumentCommand { eb@mark@#1@label@layout } + \exp_args:Nc \DeclareDocumentCommand { eb@mark@#1@label@layout } {O{\use:c { CTEXthe#1 }}m} {\tl_set:cn { eb@mark@#1@label } {##1##2}} - \cs_new_protected:cpn { eb_mark_#1_name_parse:n } ##1 + \cs_set_protected:cpn { eb_mark_#1_name_parse:n } ##1 { \regex_match:nnTF { ^\[.*\] } {##1} { \use:c { eb@mark@#1@label@layout }##1 } @@ -666,6 +642,7 @@ \eb_mark_uppercase_case_init:n {##1} }, #1-label .code:n = \use:c { eb_mark_#1_name_parse:n } {##1}, + #1-label .initial:n = \hspace{0.5em} } } \cs_new_protected:Npn \RegisterHdrMark #1 @@ -674,13 +651,7 @@ \eb@register@hdr@mark } \RegisterHdrMark{chapter,section,subsection} - -\ctex_set:nn { hdr } - { - chapter-label = \hspace{1em}, - section-label = \hspace{0.5em}, - subsection-label = \hspace{0.5em} - } +\ctex_set:nn { hdr } { chapter-label = \hspace{1em} } \ctex_define:nn { hdr } { chap-mark .meta:n = { chapter-mark = {#1} }, @@ -698,22 +669,26 @@ footrule .tl_gset:N = \footrule, footrule .initial:n = { }, footnoterule .tl_gset:N = \footnoterule, - footnoterule .initial:n = \markrule[0.35\textwidth]{\eb@footnote@rule@wd}[|3pt] + footnoterule .initial:n = + { + \markrule[0.35\textwidth]{\eb@footnote@rule@wd} + \vspace*{3pt} + } } \cs_set:Npn \markdouble #1 { \markboth{#1}{\ifbool{@twoside}{#1}{}} } -\cs_new:Npn \eb@level@markdouble #1#2 +\cs_new_protected:Npn \eb@level@markdouble #1#2 { \markdouble{\use:c { eb@mark@#1@whole }{#2}} } -\cs_new:Npn \eb@level@markright #1#2 +\cs_new_protected:Npn \eb@level@markright #1#2 { \markright{\use:c { eb@mark@#1@whole }{#2}} } \cs_gset:Npn \chaptermark #1 { \eb@level@markdouble{chapter}{#1} } -\cs_gset:Npn \sectionmark #1 +\cs_gset:Npx \sectionmark #1 { \bool_if:NTF \l__eb_class_mode_book_bool { \eb@level@markright{section}{#1} } { \eb@level@markdouble{section}{#1} } } -\cs_gset:Npn \subsectionmark #1 +\cs_gset:Npx \subsectionmark #1 { \bool_if:NF \l__eb_class_mode_book_bool { \eb@level@markright{subsection}{#1} } @@ -761,13 +736,13 @@ { \tl_clear:N \l__eb_fntext_after_tl } { \tl_set:Nn \l__eb_fntext_after_tl {#2} } } -\cs_new_protected:Npn \eb_fnmarktext_counter_pifont:N #1 +\cs_new_protected:Npn \eb_fnnormal_counter_pifont:N #1 { \ding{\int_eval:n { 171 + #1 }} } -\cs_new_protected:Npn \eb_fnmarktext_counter_pifont_neg:N #1 +\cs_new_protected:Npn \eb_fnnormal_counter_pifont_neg:N #1 { \ding{\int_eval:n { 181 + #1 }} } -\cs_new_protected:Npn \eb_fnmarktext_counter_pisans:N #1 +\cs_new_protected:Npn \eb_fnnormal_counter_pisans:N #1 { \ding{\int_eval:n { 191 + #1 }} } -\cs_new_protected:Npn \eb_fnmarktext_counter_pisans_neg:N #1 +\cs_new_protected:Npn \eb_fnnormal_counter_pisans_neg:N #1 { \ding{\int_eval:n { 201 + #1 }} } \cs_new:Npn \eb_fnt_map_symbols_list:n #1 { @@ -779,7 +754,7 @@ { \quark_if_recursion_tail_stop:n {#1} \quark_if_recursion_tail_stop:n {#2} - { #1 + \int_use:N \c@footnote } {#2} + { #1 + \int_use:N \c@footnote } { \exp_not:n {#2} } \eb_fnt_map_symbols_list:nn } \cs_new_protected:Npn \SetFntSymbsList #1#2#3 @@ -802,57 +777,74 @@ \msg_new:nnn { easybase } { undefined-fntsymbol } { The~list~of~footnote~symbols~'#1'~isn't~defined. } \SetFntSymbsList{empty}{1}{} +\SetFntSymbsList{fnsymbol}{10} + { + { 1 } { $*$ } + { 2 } { $\dagger$ } + { 3 } { $\ddagger$ } + { 4 } { $\mathsection$ } + { 5 } { $\mathparagraph$ } + { 6 } { $\|$ } + { 7 } { $**$ } + { 8 } { $\dagger\dagger$ } + { 9 } { $\ddagger\ddagger$ } + { 10 } { \@ctrerr } + } \UseFntSymbsList{empty} \cs_set_eq:NN \DefineFntSymbols \SetFntSymbsList \cs_set_eq:NN \setfntsymbol \UseFntSymbsList -\cs_new:Npn \eb_int_type_trans:NN #1 - { - \str_case:nn {#1} - { - { A } { \int_to_Alph:n } - { a } { \int_to_alph:n } - { 1 } { \int_to_arabic:n } - { I } { \int_to_Roman:n } - { i } { \int_to_roman:n } - { c } { \exp_args:NV \zhnumber } - { s } { \eb_int_to_symbols:n } - } - } -\cs_new_protected:Npn \eb_fnmarktext_normal_label_set:Nn #1#2 +\tl_new:N \l__eb_fnnormal_tmpa_tl +\tl_new:N \l__eb_fnnormal_tmpb_tl +\cs_new_protected:Npn \eb_fnnormal_normal_label_set:Nn #1#2 { - \tl_set:Nn \l__eb_fnmarktext_number_type_tl {#2} + \tl_set:Nn \l__eb_fnnormal_tmpa_tl {#2} \cs_set:Npx #1 { - \str_case:VnT \l__eb_fnmarktext_number_type_tl + \str_case:VnT \l__eb_fnnormal_tmpa_tl { { plain } { \exp_not:N \int_use:N } { pifont } - { \eb_fnmarktext_counter_pifont:N } + { \eb_fnnormal_counter_pifont:N } { pifont* } - { \eb_fnmarktext_counter_pifont_neg:N } + { \eb_fnnormal_counter_pifont_neg:N } { pisans } - { \eb_fnmarktext_counter_pisans:N } + { \eb_fnnormal_counter_pisans:N } { pisans* } - { \eb_fnmarktext_counter_pisans_neg:N } + { \eb_fnnormal_counter_pisans_neg:N } } { \exp_not:N \c@footnote } } \cs_set_eq:NN \thedownfootnote \thefootnote } \cs_generate_variant:Nn \msg_warning:nnnn { nnnV } -\cs_new_protected:Npn \eb_fnmarktext_short_label_set:Nn #1#2 +\cs_new:Npn \eb_footnote_int_trans:n #1 + { + \prop_item:Nn \l__eb_int_trans_cmds_prop {#1} + \exp_not:N \c@footnote + } +\prop_set_from_keyval:Nn \l__eb_int_trans_cmds_prop + { + A = \int_to_Alph:n, + a = \int_to_alph:n, + 1 = \int_to_arabic:n, + I = \int_to_Roman:n, + i = \int_to_roman:n, + c = \exp_args:NV \zhnumber, + s = \eb_int_to_symbols:n + } +\cs_new_protected:Npn \eb_fnnormal_short_label_set:Nn #1#2 { - \tl_set:Nn \l__eb_fnmarktext_short_tokens_tl {#2} + \tl_set:Nn \l__eb_fnnormal_tmpb_tl {#2} \clist_map_inline:nn { A,a,1,I,i,c,s } { \regex_match:nnTF {##1} {#2} { \regex_replace_once:nnN {##1} - { \c{eb_int_type_trans:NN} ##1 \c{c@footnote} } - \l__eb_fnmarktext_short_tokens_tl - \cs_set_eq:NN #1 \l__eb_fnmarktext_short_tokens_tl + { \c{eb_footnote_int_trans:n}\0 } + \l__eb_fnnormal_tmpb_tl + \cs_set:Npx #1 { \l__eb_fnnormal_tmpb_tl } \clist_map_break: } { @@ -891,7 +883,7 @@ { \tl_set:Nn \l__eb_footnote_value_tl {#1} } } } -\cs_new_protected:Npn \eb_fnmarktext_move_set:nnn #1#2#3 +\cs_new_protected:Npn \eb_fnnormal_move_set:nnn #1#2#3 { \str_if_eq:nnTF {#1} { match } { @@ -910,7 +902,7 @@ } } -\tl_new:N \l__eb_fnmarktext_format_tl +\tl_new:N \l__eb_fnnormal_format_tl \tl_new:N \l__eb_fncustom_format_tl \clist_new:N \l__eb_footnote_value_clist \ctex_define:nn { hdr } @@ -927,33 +919,35 @@ fntext-pos .initial:n = super, fntext-code .code:n = \eb_assign_fntext_code:n {#1}, fntext-code .initial:n = { ,\tl_if_eq:NnF \l__eb_fntext_position_tl { super } { ~ } }, - fnmarktext-format .code:n = \eb_fnboth_format_set:nn {#1} { marktext }, + fnnormal-format .code:n = \eb_fnboth_format_set:nn {#1} { normal }, fncustom-format .code:n = \eb_fnboth_format_set:nn {#1} { custom }, - fnboth-format .meta:n = { fnmarktext-format = {#1},fncustom-format = {#1} }, + fnmarktext-format .meta:n = { fnnormal-format = {#1} }, + fnboth-format .meta:n = { fnnormal-format = {#1},fncustom-format = {#1} }, footnotetype .multichoices:nn = { plain,hang,bottom,para,flush } { \eb_footnote_value_handle:n {#1} }, footnotetype .value_required:n = true, footnotetype/default .meta:n = { footnotetype = plain }, footnotetype .initial:n = hang, - fnmark-vmove .code:n = \eb_fnmarktext_move_set:nnn {#1} { mark } { v }, - fnmark-hmove .code:n = \eb_fnmarktext_move_set:nnn {#1} { mark } { h }, - fntext-vmove .code:n = \eb_fnmarktext_move_set:nnn {#1} { text } { v }, + fnmark-vmove .code:n = \eb_fnnormal_move_set:nnn {#1} { mark } { v }, + fnmark-hmove .code:n = \eb_fnnormal_move_set:nnn {#1} { mark } { h }, + fntext-vmove .code:n = \eb_fnnormal_move_set:nnn {#1} { text } { v }, fnmark-vmove .initial:n = 0pt, fnmark-hmove .initial:n = 0pt, fntext-vmove .initial:n = 0pt, fnmark-num .choices:nn = { plain,pifont,pifont*,pifont-sans,pifont-sans* } - { \eb_fnmarktext_normal_label_set:Nn \theupfootnote {#1} }, + { \eb_fnnormal_normal_label_set:Nn \theupfootnote {#1} }, fnmark-num .value_required:n = true, - fnmark-num/unknown .code:n = \eb_fnmarktext_short_label_set:Nn \theupfootnote {#1}, + fnmark-num/unknown .code:n = \eb_fnnormal_short_label_set:Nn \theupfootnote {#1}, fntext-num .choices:nn = { plain,pifont,pifont*,pifont-sans,pifont-sans* } - { \eb_fnmarktext_normal_label_set:Nn \thefootnote {#1} }, + { \eb_fnnormal_normal_label_set:Nn \thefootnote {#1} }, fntext-num .value_required:n = true, - fntext-num/unknown .code:n = \eb_fnmarktext_short_label_set:Nn \thefootnote {#1}, - fnmarktext-num .meta:n = { fntext-num = {#1},fnmark-num = {#1} }, - fnmarktext-num .initial:n = plain, + fntext-num/unknown .code:n = \eb_fnnormal_short_label_set:Nn \thefootnote {#1}, + fnnormal-num .meta:n = { fntext-num = {#1},fnmark-num = {#1} }, + fnnormal-num .initial:n = plain, + fnmarktext-num .meta:n = { fnnormal-num = {#1} }, unknown .code:n = \eb_msg_deprecated_option:n { hdr } } @@ -964,7 +958,11 @@ \str_case:VnT \l__eb_fnt_parent_counter_tl { { part } { \counterwithin*{footnote}{part} } - { page } { \counterwithin*{footnote}{page} } + { page } + { + \RequirePackage{zref-perpage} + \zmakeperpage{footnote} + } } { \counterwithout*{footnote}{chapter} } } @@ -998,17 +996,17 @@ } } \def\@outputbox@attachfloats{\@combinefloats} -\NewHook{makecol/footins/before} -\NewHook{makecol/footins/begin} +\NewHook{eb/footins/before} +\NewHook{eb/footins/begin} \def\@outputbox@appendfootnotes { \@if@footnotes@TF { - \UseHook{makecol/footins/before} + \UseHook{eb/footins/before} \@outputbox@append { \vskip\skip\footins - \UseHook{makecol/footins/begin} + \UseHook{eb/footins/begin} \color@begingroup \normalcolor \footnoterule @@ -1107,13 +1105,12 @@ \l__eb_fnpara_format_tl{#1} \tl_if_eq:NnT \l__eb_footnote_value_tl { hang } { \par } } -\cs_new_protected:Npn \setspread #1 { \linespread{#1}\selectfont } \clist_map_inline:nn { \@footnotetext,\@mpfootnotetext } { \eb_patch_cmd:Nnn #1 { \reset@font } { - \setspread{\eb@spread@footnote} + \usestretch{\eb@spread@footnote} \eb@font@footnote } } @@ -1151,6 +1148,7 @@ \cs_set_protected:Npn \footref #1 { \group_begin: + \unrestored@protected@xdef\@thefnmark{\ref{#1}} \unrestored@protected@xdef\@the@up@fnmark{\ref{#1}} \group_end: \H@@footnotemark @@ -1192,6 +1190,7 @@ { \@xfootnotemark } { \stepcounter{footnote} + \protected@xdef\@thefnmark{\thefootnote} \protected@xdef\@the@up@fnmark{\theupfootnote} \@footnotemark } @@ -1201,7 +1200,8 @@ \cs_set:Npn \@xfootnotemark [#1] { \group_begin: - \setcounter{footnote}{#1} + \int_set:Nn \c@footnote {#1} + \protected@xdef\@thefnmark{\thefootnote} \unrestored@protected@xdef\@the@up@fnmark{\theupfootnote} \group_end: \H@@footnotemark @@ -1210,31 +1210,33 @@ \ProvideDocumentCommand{\super}{mo}{\textsuperscript{#1}} \providecommand{\spbset}{\use_none:n} -\NewDocumentCommand{\eb@fnmarktext@super}{sm} +\NewDocumentCommand{\eb@fnnormal@super}{sm} { \IfBooleanTF{#1} {\super{#2}[vmove = \l__eb_fntext_vmove_tl,nohmove]} { - \super{\l__eb_fnmarktext_format_tl{#2}}[ + \super{\l__eb_fnnormal_format_tl{#2}}[ vmove = \l__eb_fnmark_vmove_tl, hmove = \l__eb_fnmark_hmove_tl ] } } \bool_set_true:N \l__eb_normal_footnote_bool -\bool_new:N \l__eb_fnmarktext_format_match_bool +\bool_new:N \l__eb_fnnormal_format_match_bool \bool_new:N \l__eb_fncustom_format_match_bool -\cs_new:Npn \eb_fnmarktext_format_clear:n #1 +\cs_new_protected:Npn \ifnormalfnt #1#2 + { \bool_if:NTF \l__eb_normal_footnote_bool {#1} {#2} } +\cs_new:Npn \eb_fnnormal_format_clear:n #1 { \bool_if:cTF { l__eb_fn#1_format_match_bool } - { \tl_clear:N \l__eb_fnmarktext_format_tl } + { \tl_clear:N \l__eb_fnnormal_format_tl } { \spbset{spcmd = { }} } } -\cs_new_protected:Npn \eb_fnmarktext_format_initial: +\cs_new_protected:Npn \eb_fnnormal_format_initial: { \bool_if:NTF \l__eb_normal_footnote_bool - { \eb_fnmarktext_format_clear:n { marktext } } - { \eb_fnmarktext_format_clear:n { custom } } + { \eb_fnnormal_format_clear:n { normal } } + { \eb_fnnormal_format_clear:n { custom } } \eb@font@footnote } \cs_new_protected:Npn \defupfntmark #1 @@ -1245,18 +1247,18 @@ { \tl_if_eq:NnTF \@mpfn { footnote } } \defupfntmark { - \eb_fnmarktext_format_initial: - \eb@fnmarktext@super{\notminipage{\@the@up@fnmark}{\@thefnmark}} + \eb_fnnormal_format_initial: + \eb@fnnormal@super{\notminipage{\@the@up@fnmark}{\@thefnmark}} } \defdownfntmark { - \eb_fnmarktext_format_initial: + \eb_fnnormal_format_initial: \tl_if_eq:NnTF \l__eb_fntext_position_tl { super } - { \eb@fnmarktext@super* } + { \eb@fnnormal@super* } { \use:n } { \tl_use:N \l__eb_fntext_before_tl - { \l__eb_fnmarktext_format_tl{\@thefnmark} } + { \l__eb_fnnormal_format_tl{\@thefnmark} } } \tl_use:N \l__eb_fntext_after_tl } @@ -1268,8 +1270,8 @@ \tl_if_empty:oF {#2} { \group_begin: - \unrestored@protected@xdef\@the@up@fnmark{#1} \unrestored@protected@xdef\@thefnmark{#2} + \unrestored@protected@xdef\@the@up@fnmark{#1} \group_end: } } @@ -1279,7 +1281,7 @@ \bool_if:NF \l__eb_fncustom_format_match_bool { \tl_set_eq:NN - \l__eb_fnmarktext_format_tl \l__eb_fncustom_format_tl + \l__eb_fnnormal_format_tl \l__eb_fncustom_format_tl } } \NewDocumentCommand{\Footnote}{O{#2}m+m} @@ -1331,6 +1333,31 @@ } } } +\cs_new_protected:Npn \undefinecounter #1 + { + \cs_undefine:c { c@#1 } + \cs_undefine:c { the#1 } + \group_begin: + \exp_args:Nc \providecommand { c@@ckpt }{} + \@removefromreset{#1}{@ckpt} + \group_end: + } +\ProvideDocumentCommand{\declarecounter}{mo} + { + \undefinecounter{#1} + \IfValueTF{#2}{\newcounter{#1}[#2]}{\newcounter{#1}} + } +\ProvideDocumentCommand{\renewcounter}{mo} + { + \cs_if_exist:cTF { c@#1 } + { \IfValueTF{#2}{\declarecounter{#1}[#2]}{\declarecounter{#1}} } + { \exp_args:Nc \renewcommand { c@#1 }{} } + } +\ProvideDocumentCommand{\providecounter}{mo} + { + \cs_if_exist:cF { c@#1 } + { \IfValueTF{#2}{\newcounter{#1}[#2]}{\newcounter{#1}} } + } \cs_new:Npn \eb_section_counter_prefix:n #1 { \int_compare:nNnT { \c@chapter } > { 0 } { \use:c { the#1chapter }. } @@ -1340,12 +1367,12 @@ \cs_set:Npn \thebisection { \eb_section_counter_prefix:n { bi } } \cs_set:Npn \thebisubsection { \thebisection.\@arabic\c@bisubsection } \cs_set:Npn \thesection { \eb_section_counter_prefix:n { } } -\tl_new:N \eb@before@bitocline@hook +\NewHook{eb/addbitocline/begin} +\DeclareHookRule{eb/addbitocline/begin}{chapter}{<}{code} \NewDocumentCommand{\BeforeAddtoBitoc}{sm} { - \IfBooleanTF{#1} - {\tl_gset:Nn \eb@before@bitocline@hook {#2}} - {\tl_gput_right:Nn \eb@before@bitocline@hook {#2}} + \IfBooleanT{#1}{\RemoveFromHook{eb/addbitocline/begin}[code]} + \AddToHook{eb/addbitocline/begin}[code]{#2} } \cs_set_eq:NN \BeforeAddBitoc \BeforeAddtoBitoc \cs_new_protected:Npn \CTEX@addbitocline #1#2 @@ -1354,7 +1381,7 @@ \def\CTEX@prechapter{\CTEX@prebichapter} \def\CTEX@thechapter{\CTEX@bichapter@number} \def\CTEX@postchapter{\CTEX@postbichapter} - \eb@before@bitocline@hook + \UseHook{eb/addbitocline/begin} \tl_if_eq:NnTF \g__eb_bilist_permute_value_tl { mix } { \addcontentsline{toc}{#1} } { \addcontentsline{tec}{#1} } @@ -1363,7 +1390,8 @@ } \cs_new_protected:Npn \eb@register@bititle #1 { - \exp_args:Nc \NewDocumentCommand { bi#1 }{sO{##3}mm} + \providecounter{bi#1} + \exp_args:Nc \DeclareDocumentCommand { bi#1 }{sO{##3}mm} { \IfBooleanTF{##1} { @@ -1471,14 +1499,23 @@ } } -\cs_new_protected:Npn \SetTocOuter #1 - { \keys_set:nn { eb/tocouter } {#1} } +\NewDocumentCommand{\SetTocOuter}{om} + { + \IfNoValueTF{#1} + {\keys_set:nn { eb/tocouter } {#2}} + { + \clist_if_exist:cF { l__eb_toc_outer_kv_#1_clist } + { \clist_clear_new:c { l__eb_toc_outer_kv_#1_clist } } + \clist_put_right:cn { l__eb_toc_outer_kv_#1_clist } {#2} + } + } \tl_new:N \eb@bitoc@title \bool_new:N \l__eb_toc_notitle_bool -\newbool{bitoc} -\cs_new:Npn \ebifbitoc { \ifbool{bitoc} } +\newbool{@bitoc} +\cs_new:Npn \ebifbitoc { \ifbool{@bitoc} } \seq_new:N \l__eb_level_tmpa_seq \tl_new:N \l__eb_level_tmpa_tl +\tl_gset:Nn \g__eb_bilist_permute_value_tl { new } \cs_generate_variant:Nn \regex_extract_all:nnN { no } \cs_generate_variant:Nn \keys_define:nn { nx } \cs_generate_variant:Nn \ctex_set:nn { ox } @@ -1523,6 +1560,7 @@ multoc .int_set:N = \l__eb_toc_columns_int, multoc .default:n = 2, multoc .initial:n = 1, + columns .meta:n = { multoc = {#1} }, plan .choice:, plan .value_required:n = true, plan/cn .code:n = @@ -1541,28 +1579,31 @@ \bool_set_true:N \l__eb_toc_plan_bi_bool }, plan .initial:n = cn, - columns .meta:n = { multoc = {#1} }, title .code:n = \eb_assign_toc_title:n {#1}, bilist .code:n = { - \tl_gset:Nn \g__eb_bilist_permute_value_tl {#1} \str_if_eq:nnTF {#1} { mix } { - \AddToHook{cmd/CTEX@addtocline/before}[bitoc] - {\addtocontents{toc}{\boolfalse{bitoc}}} - \AddToHook{cmd/CTEX@addbitocline/before}[bitoc] - {\addtocontents{toc}{\booltrue{bitoc}}} + \tl_if_eq:NnF \g__eb_bilist_permute_value_tl { mix } + { + \tl_gset:Nn \g__eb_bilist_permute_value_tl {#1} + \AddToHook{cmd/CTEX@addtocline/before}[bitoc] + {\addtocontents{toc}{\boolfalse{@bitoc}}} + \AddToHook{cmd/CTEX@addbitocline/before}[bitoc] + {\addtocontents{toc}{\booltrue{@bitoc}}} + } } { - \IfHookEmptyTF{cmd/CTEX@addtocline/before}{} + \tl_if_eq:NnT \g__eb_bilist_permute_value_tl { mix } { \RemoveFromHook{cmd/CTEX@addtocline/before}[bitoc] \RemoveFromHook{cmd/CTEX@addbitocline/before}[bitoc] } + \tl_gset:Nn \g__eb_bilist_permute_value_tl {#1} } }, - name .tl_set:N = \l__eb_print_index_name_tl, - name .initial:n = \imki@jobname, + name .tl_set:N = \eb@index@name, + name .initial:n = \indtl@jobname, unknown .code:n = { \ctex_set:ox { \l__eb_level_tmpa_tl } @@ -1577,9 +1618,7 @@ \cs_new_protected:Npn \eb_toc_assign_title_judge:nn #1#2 { \tl_set:Nn \eb@toc@title {#1} - \tl_if_novalue:nTF {#2} - { \tl_clear:N \eb@bitoc@title } - { \tl_set:Nn \eb@bitoc@title {#2} } + \tl_if_novalue:nF {#2} { \tl_set:Nn \eb@bitoc@title {#2} } } \cs_new_protected:Npn \eb_toc_start_multi_column_ext:n #1 { @@ -1606,11 +1645,22 @@ { \par } } } +\cs_generate_variant:Nn \keys_set:nn { nv } +\cs_new_protected:Npn \eb_toc_outer_kv_initial:n #1 + { + \clist_if_exist:cT { l__eb_toc_outer_kv_#1_clist } + { \keys_set:nv { eb/tocouter } { l__eb_toc_outer_kv_#1_clist } } + } +\cs_new_protected:Npn \eb_toc_kv_set:nn #1#2 + { + \eb_toc_outer_kv_initial:n {#1} + \IfValueT{#2}{\keys_set:nn { eb/tocouter } {#2}} + } \cs_new_protected:Npn \eb_toc_list_struct_parse:nnnnn #1#2#3#4#5 { \group_begin: \tl_set_eq:Nc \eb@toc@title { list#4name } - \IfValueT{#3}{\keys_set:nn { eb/tocouter } {#3}} + \eb_toc_kv_set:nn {#5} {#3} \eb_toc_title_level_cmd:n {#1} \eb_toc_if_title_between_hook:nn {#1} {#4} \eb_toc_start_multi_column_ext:n {#5} @@ -1618,12 +1668,18 @@ } \cs_new:Npn \listnumberline #1 { - \protect\numberline + \capifname { - \exp_args:Nnv - \use:c { p@#1 } { the#1 } - } + \protect\numberline + { + \exp_args:Nnv + \use:c { p@#1 } { the#1 } + } + }{} } +\cs_generate_variant:Nn \tl_if_blank:nTF { f } +\cs_new:Npn \capifname #1#2 + { \tl_if_blank:fTF { \caption@labelformat{p1}{p2} } {#2} {#1} } \cs_new_protected:Npn \DeclareFloatList #1#2 { \exp_args:Nc \DeclareDocumentCommand { listof#1s }{st++o} @@ -1650,6 +1706,11 @@ } } \cs_new_protected:Npn \AssignCaptionExt #1#2 + { + \clist_map_inline:nn {#1} + { \eb@assign@caption@ext{##1}{#2} } + } +\cs_new_protected:Npn \eb@assign@caption@ext #1#2 { \tl_set:cn { ext@#1 } {#2} } \cs_set_eq:NN \AllotCaptionExt \AssignCaptionExt \ctex_define:n @@ -1671,17 +1732,18 @@ { \section* } } } - \IfValueT{#3}{\keys_set:nn { eb/tocouter } {#3}} \bool_if:NT \l__eb_toc_plan_cn_bool { + \eb_toc_kv_set:nn { toc } {#3} \IfBooleanF{#1}{\eb@toc@title@level{\eb@toc@title}{}} \eb_toc_if_title_between_hook:nn {#1} { title } - \eb_toc_start_multi_column_ext:n { toc }#4 + \eb_toc_start_multi_column_ext:n { toc } } \bool_if:NT \l__eb_toc_plan_bi_bool { \tl_if_eq:NnF \g__eb_bilist_permute_value_tl { mix } { + \eb_toc_kv_set:nn { tec } {#3}#4 \IfBooleanF{#1}{\eb@toc@title@level{\eb@bitoc@title}{}} \eb_toc_if_title_between_hook:nn {#1} { bititle } \eb_toc_start_multi_column_ext:n { tec } @@ -1690,13 +1752,29 @@ \group_end: } -\cs_set_eq:NN \eb@contentsuse@save \contentsuse \RenewDocumentCommand{\contentsuse}{O{-1000}mm} { - \eb@contentsuse@save{#2}{#3} + \clist_map_inline:nn {#2} + { \eb@contents@use{#1}{##1}{#3} } + } +\cs_new_protected:Npn \eb@contents@use #1#2#3 + { + \tl_set:cn { ttlx@#2 } {#3} \tl_set:cn { ttll@#2 } {#1} + \tl_if_exist:cF { l__eb_contents_use_#2_#3_tl } + { + \tl_put_right:Nn \ttl@finishall + { \@writefile{#3}{\contentsfinish} } + } + \tl_set:cn { l__eb_contents_use_#2_#3_tl } { used } } \contentsuse{lstlisting}{lol} +\ctex_at_end_package:nn { hyperref } + { + \cs_if_exist:NTF \Hy@toclinkstart + { \cs_set:Npn \hytoclink #1 { \Hy@toclinkstart #1\Hy@toclinkend } } + { \cs_set_eq:NN \hytoclink \use:n } + } \seq_put_left:Nn \c__ctex_headings_seq { chapter } \seq_put_right:Nn \c__ctex_headings_seq { table } \seq_put_right:Nn \c__ctex_headings_seq { figure } @@ -1713,7 +1791,7 @@ #1/tocformat* .tl_set:c = l__eb_toc_#1_entry_nolabel_tl, #1/tocindent .tl_set:c = l__eb_toc_#1_indent_tl, #1/toclabel .cs_set:cp = { eb_toc_entry_#1:nnn } ##1##2##3, - #1/tocrule .tl_set:c = l__eb_toc_#1_rule_tl, + #1/tocrule .cs_set:cp = { eb_toc_rule_#1:n } ##1, #1/tocafter .tl_set:c = l__eb_toc_#1_after_tl, #1/tocbelow .tl_set:c = l__eb_toc_#1_below_tl, #1/tocbegin .meta:n = { #1/tocbelow = {##1} }, @@ -1735,7 +1813,7 @@ {\tl_use:c { l__eb_toc_#2_format_tl }} {\use:c { eb_toc_entry_#2:nnn } { \thecontentslabel } {#2} {#1}} {\tl_use:c { l__eb_toc_#2_entry_nolabel_tl }} - {\tl_use:c { l__eb_toc_#2_rule_tl }} + {\use:c { eb_toc_rule_#2:n } { \thecontentspage }} [\tl_use:c { l__eb_toc_#2_below_tl }] } \exp_not:o { \l__eb_toc_tmpb_tl } @@ -1744,13 +1822,20 @@ { tocformat = \IfBooleanT{#1}{\contentsmargin{0pt}}, tocindent = 0pt, - tocrule = \IfBooleanTF{#1}{,~\thecontentspage}{\cdottocrule}, + tocrule = \IfBooleanTF{#1}{,~##1}{\cdottocrule}, toclabel = { \bool_if:NTF \l__eb_toc_entry_hang_bool { \IfBooleanTF{##3}{\use:n}{\contentspush} } { \use:n } - { ##1\tl_use:c { l__eb_toc_##2_after_tl } } + { + \bool_lazy_or:nnTF + { \str_if_eq_p:Vn \Hy@linktoc { 1 } } + { \str_if_eq_p:Vn \Hy@linktoc { 3 } } + { \hytoclink{##1} } + {##1} + \tl_use:c { l__eb_toc_##2_after_tl } + } }, tocafter = \hspace{1em}, tocsep = .—, @@ -1833,6 +1918,7 @@ } } \cs_set:Npn \cdottocrule { \tocrule{\textperiodcentered} } +\bool_new:N \l__eb_toc_dot_align_bool \ctex_define:nn { toc } { lolskip .skip_set:N = \eb@toc@lol@skip, @@ -1841,7 +1927,17 @@ between .initial:n = \bool_if:NT \l__eb_class_mode_book_bool { \vspace*{-1pc} }, bibetween .tl_set:N = \l__eb_toc_bititle_between_hook_tl, bibetween .initial:n = \bool_if:NT \l__eb_class_mode_book_bool { \vspace*{-1pc} }, - dotalign .bool_set:N = \l__eb_toc_dot_align_bool, + dotalign .choice:, + dotalign/true .code:n = + { + \bool_set_true:N \l__eb_toc_dot_align_bool + \contentsmargin{1.55em} + }, + dotalign/false .code:n = + { + \bool_set_false:N \l__eb_toc_dot_align_bool + \contentsmargin{0pt} + }, dotalign .default:n = true, dotalign .initial:n = true, hang .bool_set:N = \l__eb_toc_entry_hang_bool, @@ -1849,19 +1945,20 @@ hang .initial:n = true, pagenumwd .code:n = \contentsmargin{#1}, pagenumwd .initial:n = 1.55em, - fileopen .tl_set:N = \l__eb_fileopen_type_tl, - fileopen .initial:n = once, unknown .code:n = \eb_msg_deprecated_option:n { toc } } -\NewHookWithArguments{starttoc/after}{1} -\AddToHookWithArguments{starttoc/after}[aux] +\NewHookWithArguments{eb/starttoc/end}{1} +\AddToHookWithArguments{eb/starttoc/end}[aux] { - \ifbool{@filesw} + \AddToHook{enddocument/afterlastpage} { - \tl_if_exist:cF { tf@#1 } - { \iow_new:c { tf@#1 }\iow_open:cn { tf@#1 } { \jobname.#1 } } - }{} + \ifbool{@filesw} + { + \tl_if_exist:cF { tf@#1 } + { \iow_new:c { tf@#1 }\iow_open:cn { tf@#1 } { \jobname.#1 } } + }{} + } } \cs_set_eq:NN \eb@starttoc \@starttoc \cs_set:Npn \@starttoc #1 @@ -1870,22 +1967,13 @@ { \group_begin: \makeatletter - \file_if_exist_input:n { \jobname.#1 } - \UseHookWithArguments{starttoc/after}{1}{#1} + \InputIfFileExists{\jobname.#1}{}{} + \UseHookWithArguments{eb/starttoc/end}{1}{#1} \boolfalse{@nobreak} \group_end: } { \eb@starttoc{#1} } } -\AddToHook{enddocument/afterlastpage} - { - \tl_if_eq:NnTF \l__eb_fileopen_type_tl { once } - { \iow_now:Nn \@mainaux { \RemoveFromHook{starttoc/after}[*] } } - { - \IfHookEmptyTF{starttoc/after}{} - {\iow_now:Nn \@mainaux { \RemoveFromHook{starttoc/after}[aux] }} - } - } \cs_set_protected:Npn \AssignPartialExt #1#2 { \tl_if_exist:cTF { ttl@partial#1 } @@ -1904,35 +1992,62 @@ } \AssignPartialExt{lol}{pll} -\cs_new_protected:Npn \RegisterTitleIfname #1 +\cs_generate_variant:Nn \str_if_eq:nnT { x } +\NewDocumentCommand{\RegisterTitleIfname}{sO{\jobname}mm} { - \clist_map_function:nN {#1} - \eb@register@title@ifname + \clist_map_inline:nn {#3} + { \eb@register@title@ifname{#1}{#2}{##1}{#4} } } -\cs_new_protected:Npn \eb@register@title@ifname #1 +\cs_new_protected:Npn \eb_save_file_name:nnn #1#2#3 + { \str_set:Nn \@real@jobname {#2} } +\cs_new_protected:Npn \eb@register@title@ifname #1#2#3#4 { - \AddToHookWithArguments{cmd/addcontentsline/before}[title/ifname/#1] + \IfBooleanT{#1} { - \str_if_eq:nnT {##1} {#1} + \RemoveFromHook{cmd/addcontentsline/before}[title/ifname/#3] + \RemoveFromHook{file/\@real@jobname.#3/before}[title/ifname/#3] + \RemoveFromHook{file/\@real@jobname.#3/after}[title/ifname/#3] + } + \AddToHookWithArguments{cmd/addcontentsline/before}[title/ifname/#3] + { + \str_if_eq:xnT {##1} {#3} { \addtocontents{##1} - {\CTEXifname{\CTEX@ifnametrue}{\CTEX@ifnamefalse}} + {#4{\CTEX@ifnametrue}{\CTEX@ifnamefalse}} } } - \AddToHook{file/\jobname.#1/before} - {\cs_set_eq:NN \eb@title@ifname@resume \CTEXifname} - \AddToHook{file/\jobname.#1/after} - {\cs_set_eq:NN \CTEXifname \eb@title@ifname@resume} + \file_parse_full_name_apply:nN {#2} \eb_save_file_name:nnn + \AddToHook{file/\@real@jobname.#3/before}[title/ifname/#3] + {\cs_gset_eq:NN \eb@title@ifname@resume \CTEXifname} + \AddToHook{file/\@real@jobname.#3/after}[title/ifname/#3] + {\cs_gset_eq:NN \CTEXifname \eb@title@ifname@resume} } -\RegisterTitleIfname{toc} +\NewDocumentCommand{\RegisterCapIfname}{sO{\jobname}m} + { + \IfBooleanTF{#1} + {\RegisterTitleIfname*[#2]{#3}{\capifname}} + {\RegisterTitleIfname[#2]{#3}{\capifname}} + } +\RegisterTitleIfname{toc}{\CTEXifname} +\RegisterCapIfname{lot,lof,lol,loe} \cs_new_protected:Npn \SetTocStyle #1#2#3 { + \clist_map_inline:nn {#1} + { \eb@set@toc@style{##1}{#2}{#3} } + } +\cs_new_protected:Npn \eb@set@toc@style #1#2#3 + { \cs_set_protected:cpn { eb@toc@style@set@#1@#2 } { \ctex_set:nn {#1} {#3} } } \cs_new_protected:Npn \UseTocStyle #1#2#3 { + \clist_map_inline:nn {#1} + { \eb@use@toc@style{##1}{#2}{#3} } + } +\cs_new_protected:Npn \eb@use@toc@style #1#2#3 + { \cs_if_exist:cTF { eb@toc@style@set@#1@#2 } { \addtocontents{#3}{\string\csuse{eb@toc@style@set@#1@#2}} } { \msg_warning:nnnn { easybase } { undefined-toc-style } {#2} {#1} } @@ -1944,14 +2059,26 @@ { part = { - tocformat = \addvspace{1pc}\sffamily\large, + tocformat = + { + \tl_if_eq:NnTF \g__eb_bilist_permute_value_tl { mix } + { \ebifbitoc{}{\addvspace{1pc}} } + { \addvspace{1pc} } + \sffamily\large + }, tocindent = 0pt, tocrule = \tocrule{}[\bfseries], tocline = \CTEXnumberline{#1}#2 }, chapter = { - tocformat = \addvspace{1pc}\sffamily, + tocformat = + { + \tl_if_eq:NnTF \g__eb_bilist_permute_value_tl { mix } + { \ebifbitoc{}{\addvspace{1pc}} } + { \addvspace{1pc} } + \sffamily + }, tocindent = 0pt, tocrule = \cdottocrule[\bfseries], tocline = \CTEXnumberline{#1}#2 @@ -1971,20 +2098,19 @@ { tocindent = \bool_if:NTF \l__eb_class_mode_book_bool { 3.8em } { 1.5em } } } -\ctex_at_end_package:nn { imakeidx } +\ctex_at_end_package:nn { indextools } { + \booltrue{indtl@fancyhdr} \RenewDocumentCommand{\printindex}{st++o} { \group_begin: \tl_set_eq:NN \eb@toc@title \indexname - \cs_set_eq:NN \imki@indexlevel \use_none:n - \IfValueT{#3}{\keys_set:nn { eb/tocouter } {#3}} - \cs_set_protected:Npn \imki@indexheaders - { - \eb_toc_title_level_cmd:n {#1} - \cs_set_eq:NN \thispagestyle \use_none:n - } - \imki@putindex{\l__eb_print_index_name_tl} + \eb_toc_kv_set:nn { idx } {#3} + \cs_set_protected:Npn \indtl@indexlevel ##1 + { \eb_toc_title_level_cmd:n {#1} } + \@ifundefined{\csuse{eb@index@name}@idxfile} + {\indtl@error{\eb@index@name}} + {\indtl@putindex{\eb@index@name}} \group_end: } } @@ -2003,7 +2129,7 @@ \ctex_assign_heading_name:nn { biappendix } {#1} \bool_if:NTF \l__eb_class_mode_book_bool { - \eb_preto_cmd:nn { eb@before@bitocline@hook } + \AddToHook{eb/addbitocline/begin}[chapter] { \def\CTEX@prechapter{\CTEX@prebiappendix} \def\CTEX@thechapter{#2} @@ -2069,19 +2195,46 @@ } \cs_set_eq:NN \addtosubfont \ebaddtofont +\cs_new_protected:Npn \usestretch #1 + { + \edef\baselinestretch{#1} + \@currsize + } +\cs_set_eq:NN \setspread \usestretch +\cs_new_protected:Npn \restore@usespace + { + \par + \vskip\parskip + \vskip\baselineskip + \endgroup + \vskip -\parskip + \vskip -\baselineskip + } +\NewDocumentEnvironment{usespace}{m+b} + { + \par + \begingroup + \usestretch{#1}#2 + \restore@usespace + }{} +\msg_new:nnn { easybase } { invalid-spread } + { + The~line~spacing~factor~option~'#1'~is~invalid. \\ + Please~use~the~'usespace'~environment~to~set~the~line~spacing. + } +\cs_new_protected:Npn \eb_invalid_spread_warning: + { \msg_warning:nnV { easybase } { invalid-spread } \l_keys_key_str } \ctex_define:nn { space } { - linespread .code:n = \setspread{#1}, - tabspread .fp_set:N = \l__eb_spread_table_fp, - tabspread .initial:n = 1.2, - mathspread .tl_set:N = \eb@spread@math, - mathspread .initial:n = 1.2, + linespread .code:n = \usestretch{#1}, + tabspread .code:n = \eb_invalid_spread_warning:, + mathspread .code:n = \eb_invalid_spread_warning:, fntspread .code:n = { \tl_set:Nn \eb@spread@footnote {#1} \group_begin: \footnotesize - \setspread{\eb@spread@footnote} + \usestretch{\eb@spread@footnote} \exp_args:NNNo \group_end: \dim_set:Nn \footnotesep { \dim_use:N \box_ht:N \strutbox } }, @@ -2097,8 +2250,8 @@ caption-spread .initial:n = 1.2, everyspread .meta:n = { - linespread = {#1},tabspread = {#1},mathspread = {#1}, - caption-spread = {#1},fntspread = {#1} + linespread = {#1},caption-spread = {#1}, + fntspread = {#1} }, abovedisplayskip .code:n = { \AfterPreamble{\skip_set:Nn \abovedisplayskip {#1}} }, @@ -2117,14 +2270,8 @@ \tl_if_eq:NnT \l__ctex_scheme_tl { chinese } { \fp_compare:nNnTF { \l__ctex_line_spread_fp } = { 1.3 } - { - \ctex_set:nn { space } - { linespread = 1.354,tabspread = 1.354 } - } - { - \ctex_set:nn { space } - { linespread = \fp_use:N \l__ctex_line_spread_fp } - } + { \usestretch{1.354} } + { \usestretch{\fp_use:N \l__ctex_line_spread_fp} } } \AfterPreamble{\skip_set:Nn \abovedisplayshortskip { 0ex plus .1ex }} @@ -2155,7 +2302,7 @@ { \DeclareCaptionFont{eb@#1@font} { - \setspread{\fp_use:c { l__eb_spread_caption_#1_fp }} + \usestretch{\fp_use:c { l__eb_spread_caption_#1_fp }} \tl_use:c { l__eb_font_caption_#1_tl } } } @@ -2175,11 +2322,7 @@ \captionsetup[figure][bi-second]{name = Figure} \captionsetup[table][bi-second]{name = Table} } -\eb_at_begin_environment:nn - { tabular,tabularx,longtable } - { \setspread{\fp_use:N \l__eb_spread_table_fp} } \UseTblrLibrary{booktabs} - \bool_if:NF \l__eb_float_page_bool { \tl_gset:Nn \textfraction { 0.1 } @@ -2195,17 +2338,12 @@ \setcounter{topnumber}{4} \setcounter{bottomnumber}{4} \setcounter{totalnumber}{8} -\tl_set:Nn \fontsubfuzz { 0.5pt } -\dim_zero_new:N \mathindent -\allowdisplaybreaks[4] -\everymath{\displaystyle} -\DeclareGraphicsExtensions{.pdf,.png,.jpg,.eps,.tif} \dim_new:N \hangwd \cs_set_protected:Npn \hangpara #1#2 { - \dim_set:Nn \hangindent {#1} - \int_set:Nn \hangafter {#2} + \dim_gset:Nn \hangindent {#1} + \int_gset:Nn \hangafter {#2} \noindent\ignorespaces } \NewDocumentCommand{\hangfrom}{sO{\hangwd}mO{1}} @@ -2256,7 +2394,7 @@ width .dim_set:N = \l__eb_eqsymb_width_dim, width .initial:n = 10pt, delim .tl_set:N = \l__eb_eqsymb_delim_tl, - delim .initial:n = \tl_if_eq:NnTF \l__ctex_scheme_tl { chinese } { —— } { --- }, + delim .initial:n = \tl_if_eq:NnTF \l__ctex_scheme_tl { chinese } { —— } { --- }, space .dim_set:N = \l__eb_eqsymb_space_dim, space .initial:n = 0.25em, item-align .tl_set:N = \l__eb_eqsymb_item_align_tl, @@ -2328,24 +2466,39 @@ \tl_clear:N \l__eb_eqsymb_intro_tl \ignorespaces } -\bool_if:NT \l__eb_theorem_support_bool + +\cs_new:Npn \eb_tl_exist_noempty:cT #1#2 + { \tl_if_exist:cT {#1} { \tl_if_empty:cF {#1} {#2} } } +\cs_new_protected:Npn \eb_theorem_load_thmtools: { \RequirePackage{amsthm,thmtools} \cs_set_eq:NN \eb@declaretheoremstyle@save \declaretheoremstyle \cs_set_eq:NN \eb@declaretheorem@save \declaretheorem \RenewDocumentCommand{\declaretheoremstyle}{+O{}m+O{}} - {\eb@declaretheoremstyle@save[#1,#3]{#2}} + {\eb@declaretheoremstyle@save[##1,##3]{##2}} \RenewDocumentCommand{\declaretheorem}{+O{}m+O{}} { - \eb@declaretheorem@save[style = default,#1,#3]{#2} - \settheoremtocline{#2} + \cs_undefine:c {##2} + \undefinecounter{##2} + \eb_tl_exist_noempty:cT { g__eb_thmt_##2_parent_tl } { - \listnumberline{#2} + \exp_args:Nnv \@removefromreset {##2} + { g__eb_thmt_##2_parent_tl } + } + \eb@declaretheorem@save[style = default,##1,##3]{##2} + \tl_gset:cV { g__eb_thmt_##2_parent_tl } \thmt@parent + \providebool{thmt@isstarred@##2} + \ifbool{thmt@isstarred} + {\booltrue{thmt@isstarred@##2}} + {\boolfalse{thmt@isstarred@##2}} + \settheoremtocline{##2} + { + \thmtifname{\listnumberline{##2}}{} \thmtname\thmtifnote{~(\thmtnote)}{} } - \cs_gset:cpn { thmt@contentsline@#2 } + \cs_gset:cpn { thmt@contentsline@##2 } { \thmt@contentslineIfNamed } - \exp_args:Nc \providecommand { p@#2 }[1]{##1} + \exp_args:Nc \providecommand { p@##2 }[1]{####1} } \ctex_define:nn { thmt } { @@ -2363,14 +2516,13 @@ bodyfont = \normalfont, postheadspace = 1em ] - \theoremstyle{default} - \cs_undefine:N \proof \DeclareFloatList{theorem}{loe} \AssignPartialExt{loe}{ple} \eb_preto_cmd:nn { listoftheorems } { \group_begin: - \def\contentsline #1 {\use:c { thmt@contentsline@#1 }{#1}} + \let\thmt@contentsline\contentsline + \def\contentsline ##1 {\use:c { thmt@contentsline@##1 }{##1}} } \eb_appto_cmd:nn { listoftheorems } { \group_end: } \eb_preto_cmd:nn { @chapter } @@ -2379,72 +2531,130 @@ { \addtocontents{loe}{\protect\addvspace{\skip_use:N \eb@thmt@loe@skip}} } } \def\thmtlo@chaptervspacehack{} + \def\thmt@mklistcmd{\thmtlo@newentry} \def\thmtname{\thmt@thmname} \def\thmtenvname{\thmt@envname} \def\thmtnote{\thmt@shortoptarg} - \def\thmtformatoptarg #1 {#1} - \def\thmtifname #1#2 {\ifbool{thmt@isstarred}{#2}{#1}} - \def\thmtifnote #1#2 + \def\thmtformatoptarg ##1 {##1} + \def\thmtifname ##1##2 {\ifbool{thmt@isstarred@\thmt@envname}{##2}{##1}} + \def\thmtifnote ##1##2 { \tl_if_empty:NTF \thmt@shortoptarg - {#2} - { \protect\thmtformatoptarg{#1} } + {##2} + { \protect\thmtformatoptarg{##1} } + } + \cs_new_protected:Npn \eb@settheoremtocline ##1##2##3 + { + \IfBooleanT{##1}{\def\thmt@contentslineIgnore{\thmt@contentsline}} + \cs_set:cpn { ll@##2 } { \@bsphack ##3\@esphack } } \NewDocumentCommand{\settheoremtocline}{smm} { - \IfBooleanT{#1}{\def\thmt@contentslineIgnore{\thmt@contentsline}} - \cs_set:cpn { ll@#2 } { \@bsphack #3\@esphack } + \clist_map_inline:nn {##2} + { \eb@settheoremtocline{##1}{####1}{##3} } } } - -\setchemformula +\cs_new_protected:Npn \eb_theorem_load_keytheorems: + { + \RequirePackage{keytheorems} + \DeclareFloatList{theorem}{thlist} + \AssignPartialExt{thlist}{ple} + } +\str_case:VnT \l__eb_theorem_support_tl { - math-scripts = false, - charge-hshift = 0.25em, - subscript-vshift = -0.2ex + { thmtools } + { \eb_theorem_load_thmtools: } + { keytheorems } + { \eb_theorem_load_keytheorems: } } -\IfPackageAtLeastTF{siunitx}{2021/06/22} + { \cs_undefine:N \proof } +\cs_new_protected:Npn \eb_chem_load_chemformula: { - \sisetup + \RequirePackage{chemformula} + \setchemformula { - number-mode = match, - range-phrase = \ensuremath{\sim}, - range-units = single, - print-unity-mantissa = false, - table-alignment-mode = none, - group-digits = none + charge-hshift = 0pt, + subscript-vshift = -0.2ex } - }{} -\eb_at_begin_environment:nn + } +\cs_new_protected:Npn \eb_chem_load_mhchem: { - array,matrix,pmatrix,bmatrix,Bmatrix,vmatrix,Vmatrix, - matrix*,pmatrix*,bmatrix*,Bmatrix*,vmatrix*,Vmatrix*, - cases,cases*,dcases,dcases*,rcases,rcases*,drcases,drcases*, - aligned,alignedat,gathered,multlined,lgathered,rgathered + \RequirePackage[version = 4]{mhchem} + \mhchemoptions{layout = stacked} } - { \setspread{\eb@spread@math} } -\clist_map_inline:nn - { \start@gather,\start@align,\start@multline } +\str_case:VnF \l__eb_chem_support_tl { - \eb_patch_cmd:Nnn #1 - { \collect@body } - { - \setspread{\eb@spread@math} - \collect@body - } + { chemformula } + { \eb_chem_load_chemformula: } + { mhchem } + { \eb_chem_load_mhchem: } } -\eb_patch_cmd:Nnn \gather@split - { \spread@equation } + { \RequirePackage{amsmath} } +\tl_set:Nn \fontsubfuzz { 0.5pt } +\everymath{\displaystyle} +\dim_zero_new:N \mathindent +\allowdisplaybreaks[4] +\DeclareGraphicsExtensions{.pdf,.png,.jpg,.eps,.tif} +\sisetup { - \setspread{\eb@spread@math} - \spread@equation + number-mode = match, + range-phrase = \ensuremath{\sim}, + range-units = single, + print-unity-mantissa = false, + table-alignment-mode = none, + group-digits = none } \ctex_at_end_package:nn { unicode-math } { \msg_redirect_module:nnn { unicode-math } { warning } { info } } \ctex_at_end_package:nn { tcolorbox } { \file_if_exist_input:n { eb-tcolorbox.cfg } } -\bool_set_true:N \l__eb_backend_bibtex_bool +\NewDocumentCommand{\eb_assign_tagform:n} + {>{\SplitArgument{1}{,}}m} + { + \eb_assign_tagform_pos:nn #1 + \cs_gset:Npn \tagform@ ##1 + { + \maketag@@@ + { + \color{ctex@emph} + \ignorespaces + \eb@tag@brackets@left{##1} + \unskip\@@italiccorr + \eb@tag@brackets@right + } + } + } +\cs_new_protected:Npn \eb_assign_tagform_pos:nn #1#2 + { + \tl_set:Nn \eb@tag@brackets@left {#1} + \tl_set:Nn \eb@tag@brackets@right {#2} + } +\ctex_define:nn { tools } + { + multoc .int_set:N = \l__eb_toc_columns_int, + multoc .default:n = 2, + withpart .bool_set:N = \l__eb_chap_counter_withpart_bool, + withpart .default:n = true, + withpart .initial:n = false, + uppercase .tl_set:N = \l__eb_mark_uppercase_value_tl, + uppercase .default:n = all, + uppercase .initial:n = all, + tagform .code:n = \eb_assign_tagform:n {#1}, + tagform .initial:n = { (,) }, + brackets .meta:n = { tagform = {#1} }, + figurepath .code:n = + { + \tl_if_blank:nF {#1} + { + \regex_match:nnTF { \cB. } {#1} + { \graphicspath{#1} } + { \graphicspath{{#1}} } + } + } + } + +\bool_new:N \l__eb_backend_bibtex_bool \ctex_define:nn { bib } { backend .choice:, @@ -2459,7 +2669,6 @@ bititle .initial:n = Bibliography, unknown .code:n = \eb_msg_deprecated_option:n { bib } } - \cs_new_protected:Npn \eb_bibtex_natbib_set: { \RequirePackage[sort&compress]{natbib} @@ -2481,7 +2690,7 @@ { \group_begin: \tl_set_eq:NN \eb@toc@title \bibname - \IfValueT{##3}{ \keys_set:nn { eb/tocouter } {##3} } + \eb_toc_kv_set:nn { bbl } {##3} \cs_set_protected:Npn \bibsection { \eb_toc_title_level_cmd:n {##1} @@ -2571,15 +2780,9 @@ \lstset{style = lst-latex} \lstloadlanguages{C,C++,Java,Python,Matlab} -\clist_new:N \l__eb_hyperref_clist -\cs_new_protected:Npn \eb_set_hyperref:n #1 - { - \IfPackageLoadedTF{hyperref} - {\hypersetup} - {\eb_put_hyperref:n}{#1} - } -\cs_new_protected:Npn \eb_put_hyperref:n #1 - { \clist_put_right:Nn \l__eb_hyperref_clist {#1} } +\clist_new:N \l__eb_hyperref_options_clist +\providecommand{\hypersetup}[1] + {\clist_put_right:Nn \l__eb_hyperref_options_clist {#1}} \cs_new_protected:Npn \eb_define_link_color:nnn #1#2#3 { \definecolorset{HTML}{ctex@}{}{link,#1;url,#2;cite,#3} } \cs_new_protected:Npn \eb_define_theme_color:nnn #1#2#3 @@ -2588,21 +2791,21 @@ { \definecolorset{HTML}{ctex@}{}{link,#1;url,#1;cite,#1} } \cs_new_protected:Npn \eb_define_theme_color:n #1 { \definecolorset{HTML}{ctex@}{}{frame,#1;emph,#1;verb,#1} } -\cs_new_protected:Npn \DeclareLinkColor #1 - { \ctex_define:nx { ref } { \eb_link_color_set:n {#1} } } -\cs_new_protected:Npn \DeclareThemeColor #1 - { \ctex_define:nx { tools } { \eb_theme_color_set:n {#1} } } +\cs_new_protected:Npn \DeclareLinkColor #1#2 + { \ctex_define:nx { ref } { \eb_link_color_set:nn {#1} {#2} } } +\cs_new_protected:Npn \DeclareThemeColor #1#2 + { \ctex_define:nx { tools } { \eb_theme_color_set:nn {#1} {#2} } } \cs_new_protected:Npn \eb_color_assign_cmd_set:nn #1#2 { - \cs_new:cpn { eb_#2_color_set:n } ##1 + \cs_new:cpn { eb_#2_color_set:nn } ##1##2 { - #1/\clist_item:nn {##1} { 1 } .code:n = + #1/##1 .code:n = { \use:c { eb_define_#2_color:nnn } - { \clist_item:nn {##1} { 2 } } - { \clist_item:nn {##1} { 3 } } - { \clist_item:nn {##1} { 4 } } - }, + { \clist_item:nn {##2} { 1 } } + { \clist_item:nn {##2} { 2 } } + { \clist_item:nn {##2} { 3 } } + } } } \clist_map_inline:nn @@ -2611,51 +2814,46 @@ { color } { theme } } { \eb_color_assign_cmd_set:nn #1 } -\ctex_define:nx { ref } +\clist_map_inline:nn + { + { fresh } { 62d71f,0000b2,005752 }, + { cutepink } { ea4492,ad3ccc,57b5e5 }, + { navyblue } { 000080,4ec9ea,eb6877 }, + { crimson } { dc143c,00c1c9,afcd20 } + } + { \DeclareLinkColor #1 } +\ctex_define:nn { ref } { linkcolor .choice:, linkcolor .value_required:n = true, - \clist_map_function:nN - { - { fresh, 62d71f,0000b2,005752 }, - { cutepink, ea4492,ad3ccc,57b5e5 }, - { navyblue, 000080,4ec9ea,eb6877 }, - { crimson, dc143c,00c1c9,afcd20 } - } - \eb_link_color_set:n - linkcolor .initial:n = navyblue, - linkcolor-every .code:n = \eb_define_link_color:n { \exp_not:n {#1} } + linkcolor .initial:n = navyblue, + linkcolor-every .code:n = \eb_define_link_color:n {#1} + } +\clist_map_inline:nn + { + { none } { 000000,000000,000000 }, + { seaside } { 333fb2,9932cc,09cc00 }, + { energy } { f39800,00a0e9,893895 }, + { cyberpunk } { 601986,eb6877,a4005b } } -\ctex_define:nx { tools } + { \DeclareThemeColor #1 } +\ctex_define:nn { tools } { color .choice:, color .value_required:n = true, - \clist_map_function:nN - { - { none, 000000,000000,000000 }, - { seaside, 333fb2,9932cc,09cc00 }, - { energy, f39800,00a0e9,893895 }, - { cyberpunk, 601986,eb6877,a4005b } - } - \eb_theme_color_set:n color .initial:n = none, - color-every .code:n = \eb_define_theme_color:n { \exp_not:n {#1} } + color-every .code:n = \eb_define_theme_color:n {#1} } \cs_new_protected:Npn \eb_link_border_set:n #1 { - \ctex_at_end_package:nn { hyperref } - { - \def\@pdfborder{#1} - \def\Hy@colorlink ##1 {\begingroup} - \def\Hy@endcolorlink{\endgroup} - } - \eb_set_hyperref:n { colorlinks = false } + \hypersetup{colorlinks = false} + \def\@pdfborder{#1} } \cs_new_protected:Npn \eb_link_colors_set: - { \eb_set_hyperref:n { colorlinks } } -\cs_new_protected:Npn \eb_link_toc_put:n #1 - { \eb_set_hyperref:n { linktoc = #1 } } + { \hypersetup{colorlinks} } +\cs_new_protected:Npn \eb_link_toc_set:n #1 + { \hypersetup{linktoc = #1} } \ctex_define:nn { ref } { linktype .choice:, @@ -2667,9 +2865,9 @@ linktype .initial:n = edge, linktoc .choice:, linktoc .value_required:n = true, - linktoc/unknown .code:n = \eb_link_toc_put:n {#1}, + linktoc/unknown .code:n = \eb_link_toc_set:n {#1}, linktoc .initial:n = all, - unknown .code:n = \eb_set_hyperref:x { \eb_unknown_kv_handle: }, + unknown .code:n = \exp_args:Nx \hypersetup { \eb_unknown_kv_handle: }, unknown .default:V = \c_novalue_tl } @@ -2692,14 +2890,14 @@ \RequirePackage{hyperref} \urlstyle{same} \eb_allow_url_break: - \eb_put_hyperref:n + \hypersetup { linkcolor = ctex@link,linkbordercolor = ctex@link, urlcolor = ctex@url,urlbordercolor = ctex@url, - citecolor = ctex@cite,citebordercolor = ctex@cite + citecolor = ctex@cite,citebordercolor = ctex@cite, + bookmarksnumbered = true } - \hypersetup{bookmarksnumbered = true} - \exp_args:NV \hypersetup \l__eb_hyperref_clist + \exp_args:NV \hypersetup \l__eb_hyperref_options_clist } \cs_set_eq:NN \eb@labelformat@save \labelformat @@ -2727,7 +2925,7 @@ } \ctex_define:n { - lstlistlistingname .tl_set:N = \listlstlistingname, + listlstlistingname .tl_set:N = \listlstlistingname, lstlistingname .tl_set:N = \lstlistingname, listtheoremname .tl_set:N = \listtheoremname } @@ -2738,15 +2936,17 @@ contentsname = 目\hspace{1em}录, listfigurename = 插图清单, listtablename = 附表清单, - lstlistlistingname = 代码清单, + listlstlistingname = 代码清单, lstlistingname = 代码, listtheoremname = 定理清单 } + \ctex_at_end_package:nn { keytheorems } + { \keytheoremlistset{title = 定理清单} } } { \keys_set_known:nn { ctex } { - lstlistlistingname = List~of~Codes, + listlstlistingname = List~of~Codes, lstlistingname = Code } } @@ -2794,15 +2994,18 @@ { \renewcommand{\theupfootnote}{\@fnsymbol\c@footnote} \renewcommand{\thefootnote}{\@fnsymbol\c@footnote} + \let\footnote\thanks } {} - \LARGE\@title\par\vskip 3em - \large + \bgroup\LARGE\@title\par\egroup + \notbool{@titlepage}{\vskip 1.5em}{\vskip 3em} + \bgroup\large \begin{tabular}[t]{c} \@author - \end{tabular}\par\vskip 1.5em - \@date - \notbool{@titlepage}{\par\vskip 1.5em}{} + \end{tabular}\par\egroup + \notbool{@titlepage}{\vskip 0.75em}{\vskip 1.5em} + \bgroup\large\@date\par\egroup + \notbool{@titlepage}{\vskip 1.5em}{} \@thanks }, beforecode = @@ -2843,15 +3046,13 @@ } %</package> %<*tcolorbox> -\ProvidesExplFile{eb-tcolorbox.cfg}{2024/08/14}{2024dj} +\ProvidesExplFile{eb-tcolorbox.cfg}{2025/02/16}{2025q} {Customization of tcolorbox for easybook} \cs_set_protected:Npn \addtotcbstyle #1#2 { \tcbset{#1/.append~style = {#2}} } \cs_set_protected:Npn \deftcbstyle #1#2 { \tcbset{#1/.style = {#2}} } -\cs_new_protected:Npn \tcbappstyle - { \@ifstar{\deftcbstyle}{\addtotcbstyle} } \deftcbstyle{tc-easyboxi} { |