diff options
Diffstat (limited to 'Master/texmf-dist/tex/latex/joinbox/joinbox.sty')
-rw-r--r-- | Master/texmf-dist/tex/latex/joinbox/joinbox.sty | 318 |
1 files changed, 244 insertions, 74 deletions
diff --git a/Master/texmf-dist/tex/latex/joinbox/joinbox.sty b/Master/texmf-dist/tex/latex/joinbox/joinbox.sty index 8cf2cfcb54f..a3117aa5ac8 100644 --- a/Master/texmf-dist/tex/latex/joinbox/joinbox.sty +++ b/Master/texmf-dist/tex/latex/joinbox/joinbox.sty @@ -7,7 +7,7 @@ \NeedsTeXFormat{LaTeX2e} \RequirePackage{expl3} -\ProvidesExplPackage{joinbox}{2023-08-11}{v1.0.0} +\ProvidesExplPackage{joinbox}{2023-08-13}{v1.0.1} {Join figures to same height or width with LaTeX3} \RequirePackage{xparse} @@ -37,12 +37,23 @@ \cs_set_eq:NN \seq_map_indexed_function:NN \seq_indexed_map_function:NN } +\cs_new:Npn \__joinbox_error:n { \msg_error:nn { joinbox } } + +% 函数变体 +\cs_generate_variant:Nn \hcoffin_set:Nn { Nx } + + % 定义变量 \bool_new:N \l__joinbox_vertical_bool \bool_new:N \l__joinbox_out_scale_bool +\bool_new:N \l__joinbox_only_first_bool +\bool_new:N \l__joinbox_only_second_bool + \int_new:N \l__joinbox_baseline_int -\clist_const:Nn \c__joinbox_baseline_clist { t, vc, H, b } + \clist_new:N \l__joinbox_name_clist +\clist_new:N \l__joinbox_contents_clist + \coffin_new:N \l__joinbox_out_coffin \coffin_new:N \l__joinbox_tmpa_coffin \coffin_new:N \l__joinbox_tmpb_coffin @@ -52,6 +63,12 @@ \dim_new:N \l__joinbox_min_width_dim \dim_new:N \l__joinbox_min_height_dim +\dim_new:N \l__joinbox_tmpa_dim +\dim_new:N \l__joinbox_tmpb_dim + +\bool_set_false:N \l__joinbox_only_first_bool +\bool_set_false:N \l__joinbox_only_second_bool + %% 选项设计 \keys_define:nn { joinbox } { @@ -66,16 +83,16 @@ baseline .initial:n = b, % 输出尺寸(垂直拼接:宽度,水平拼接:高度) - outlen .code:n = { \dim_compare:nNnTF { #1 } < { 0pt } + outlen .code:n = { \dim_compare:nNnTF { \dim_eval:n{ #1 } } < \c_zero_dim { \bool_set_false:N \l__joinbox_out_scale_bool }{ - \dim_compare:nNnTF { #1 } = { 0pt } + \dim_compare:nNnTF { \dim_eval:n{ #1 } } = \c_zero_dim { \bool_set_false:N \l__joinbox_out_scale_bool }{ \bool_set_true:N \l__joinbox_out_scale_bool - \dim_set:Nn \l__joinbox_out_length_dim { #1 } + \dim_set:Nn \l__joinbox_out_length_dim { \dim_eval:n{ #1 } } } } }, @@ -87,42 +104,42 @@ sep .default:n = 0pt, sep .initial:n = 0pt, - unknown .code:n = { \__joinbox_error:n { unknown-option } } - % unknown .code:n = \__joinbox_unknown_key:V \l_keys_key_str, + % unknown .code:n = { \__joinbox_error:n { unknown-option } } + unknown .code:n = \__joinbox_unknown_key:V \l_keys_key_str, + } + +\cs_new_protected:Npn \__joinbox_unknown_key:n #1 + { + \str_case:nnF { #1 } + { + { t } { \int_set:Nn \l__joinbox_baseline_int { 1 } } + { vc } { \int_set:Nn \l__joinbox_baseline_int { 2 } } + { H } { \int_set:Nn \l__joinbox_baseline_int { 3 } } + { b } { \int_set:Nn \l__joinbox_baseline_int { 4 } } + } + { + % 转换为token + \tl_set_rescan:Nnn \l_tmpa_tl {} {#1} + % 计算尺寸 + \dim_set:Nn \l_tmpa_dim { \dim_eval:n { \l_tmpa_tl } } + \dim_compare:nNnTF \l_tmpa_dim < \c_zero_dim + { + \bool_set_false:N \l__joinbox_out_scale_bool + }{ + \dim_compare:nNnTF \l_tmpa_dim = \c_zero_dim + { + \bool_set_false:N \l__joinbox_out_scale_bool + }{ + \bool_set_true:N \l__joinbox_out_scale_bool + \dim_set_eq:NN \l__joinbox_out_length_dim \l_tmpa_dim + } + } + } } +\cs_generate_variant:Nn \__joinbox_unknown_key:n { V } -% \cs_new_protected:Npn \__joinbox_unknown_key:n #1 -% { -% \clist_if_in:NnTF \c__joinbox_baseline_clist { #1 } -% { -% \int_zero:N \l_tmpa_int -% \clist_map_inline:Nn \c__joinbox_baseline_clist -% { -% \int_incr:N \l_tmpa_int -% \str_if_eq:nnT { ##1 } { #1 } -% { \clist_map_break: } -% } -% \int_gset_eq:NN \l__joinbox_baseline_int \l_tmpa_int -% } -% { -% \dim_compare:nNnTF { #1 } < { 0pt } -% { -% \bool_gset_false:N \l__joinbox_out_scale_bool -% }{ -% \dim_compare:nNnTF { #1 } = { 0pt } -% { -% \bool_gset_false:N \l__joinbox_out_scale_bool -% }{ -% \bool_gset_true:N \l__joinbox_out_scale_bool -% \dim_gset:Nn \l__joinbox_out_length_dim { #1 } -% } -% } -% } -% } -% \cs_generate_variant:Nn \__joinbox_unknown_key:n { V } - -\msg_new:nnn { joinbox } { unknown-option } - { package~ option~ "\l_keys_key_tl"~ is~ unknown. } +% \msg_new:nnn { joinbox } { unknown-option } +% { package~ option~ "\l_keys_key_tl"~ is~ unknown. } %% 参数设置用户接口 \NewDocumentCommand \joinset { m } @@ -147,6 +164,10 @@ % (最小宽度和最小宽度不一定属于同一个盒子) \cs_new:Npn \__joinbox_calc_min_size:nn #1#2 { + % 最小值清0 + \dim_zero:N \l__joinbox_min_width_dim + \dim_zero:N \l__joinbox_min_height_dim + % 取得第1个盒子的宽度和高度 \hbox_set:Nn \l_tmpa_box { @@ -157,13 +178,13 @@ { \box_wd:N \l_tmpa_box } - \dim_gset_eq:NN \l__joinbox_min_width_dim \l_tmpa_dim + \dim_set_eq:NN \l__joinbox_min_width_dim \l_tmpa_dim \dim_set:Nn \l_tmpb_dim { \box_ht_plus_dp:N \l_tmpa_box } - \dim_gset_eq:NN \l__joinbox_min_height_dim \l_tmpb_dim + \dim_set_eq:NN \l__joinbox_min_height_dim \l_tmpb_dim % 取得第2个盒子的宽度和高度,并与第1个盒子比较 \hbox_set:Nn \l_tmpa_box @@ -175,21 +196,27 @@ { \box_wd:N \l_tmpa_box } - % 比较并记录最小宽度 - \dim_compare:nNnT \l__joinbox_min_width_dim > \l_tmpa_dim - { - \dim_gset_eq:NN \l__joinbox_min_width_dim \l_tmpa_dim - } \dim_set:Nn \l_tmpb_dim { \box_ht_plus_dp:N \l_tmpa_box } - % 比较并记录最小总高度(高度+深度) - \dim_compare:nNnT \l__joinbox_min_height_dim > \l_tmpb_dim + \bool_if:NT \l__joinbox_only_second_bool { - \dim_gset_eq:NN \l__joinbox_min_height_dim \l_tmpb_dim + \dim_set_eq:NN \l__joinbox_min_width_dim \l_tmpa_dim + \dim_set_eq:NN \l__joinbox_min_height_dim \l_tmpb_dim + } + + \bool_if:nT { !(\l__joinbox_only_first_bool) && !(\l__joinbox_only_second_bool) } + { + % 比较并记录最小宽度 + \dim_set:Nn \l__joinbox_min_width_dim + { \dim_min:nn { \l__joinbox_min_width_dim }{ \l_tmpa_dim } } + + % 比较并记录最小总高度(高度+深度) + \dim_set:Nn \l__joinbox_min_height_dim + { \dim_min:nn { \l__joinbox_min_height_dim }{ \l_tmpb_dim } } } } @@ -218,52 +245,66 @@ } } -% 盒子拼接内部函数 -% 将指定文件名列表中的图像拼接成一个盒子并将基线调整为中心线输出 +% 两个盒子拼接内部函数 +% 将指定文件名列表中的图像拼接成一个盒子 % #1---第1个盒子的内容 % #2---第2个盒子的内容 \cs_new:Npn \__joinbox_handle:nn #1#2 { \group_begin: - \coffin_clear:N \l__joinbox_out_coffin % 设置第1个盒子 + \coffin_clear:N \l__joinbox_out_coffin \hcoffin_set:Nn \l__joinbox_out_coffin { #1 } + % 设置第2个盒子 + \coffin_clear:N \l__joinbox_tmpa_coffin + \hcoffin_set:Nn \l__joinbox_tmpa_coffin + { + #2 + } + \bool_if:NTF \l__joinbox_vertical_bool { % 按最小宽度缩放第1个盒子 - \coffin_scale:Nnn \l__joinbox_out_coffin + \bool_if:NF \l__joinbox_only_second_bool { - \dim_ratio:nn { \l__joinbox_min_width_dim }{ \coffin_wd:N \l__joinbox_out_coffin } - } - { - \dim_ratio:nn { \l__joinbox_min_width_dim }{ \coffin_wd:N \l__joinbox_out_coffin } + \coffin_scale:Nnn \l__joinbox_out_coffin + { + \dim_ratio:nn { \l__joinbox_min_width_dim }{ \coffin_wd:N \l__joinbox_out_coffin } + } + { + \dim_ratio:nn { \l__joinbox_min_width_dim }{ \coffin_wd:N \l__joinbox_out_coffin } + } } - % 处理第2个盒子 - \hcoffin_set:Nn \l__joinbox_tmpa_coffin + % 按最小宽度缩放第2个盒子 + \bool_if:NF \l__joinbox_only_first_bool { - #2 + \coffin_scale:Nnn \l__joinbox_tmpa_coffin + { + \dim_ratio:nn { \l__joinbox_min_width_dim }{ \coffin_wd:N \l__joinbox_tmpa_coffin } + } + { + \dim_ratio:nn { \l__joinbox_min_width_dim }{ \coffin_wd:N \l__joinbox_tmpa_coffin } + } } - % 按最小宽度缩放第2个盒子 - \coffin_scale:Nnn \l__joinbox_tmpa_coffin + \bool_if:NT \l__joinbox_only_second_bool { - \dim_ratio:nn { \l__joinbox_min_width_dim }{ \coffin_wd:N \l__joinbox_tmpa_coffin } + \coffin_set_eq:NN \l__joinbox_out_coffin \l__joinbox_tmpa_coffin } + + \bool_if:nT { !(\l__joinbox_only_first_bool) && !(\l__joinbox_only_second_bool) } { - \dim_ratio:nn { \l__joinbox_min_width_dim }{ \coffin_wd:N \l__joinbox_tmpa_coffin } + % 将第2个盒子拼接到第一个盒子 + \coffin_join:NnnNnnnn \l__joinbox_out_coffin + { hc } { b } \l__joinbox_tmpa_coffin { hc } { t } { 0pt } { -\l__joinbox_sep_dim } } - % \dim_show:N \l__joinbox_sep_dim - % 将第2个盒子拼接到第一个盒子 - \coffin_join:NnnNnnnn \l__joinbox_out_coffin - { hc } { b } \l__joinbox_tmpa_coffin { hc } { t } { 0pt } { -\l__joinbox_sep_dim } - % 按指定输出宽度缩放输出盒子 \bool_if:NT \l__joinbox_out_scale_bool { @@ -276,6 +317,12 @@ } } + \hcoffin_set:Nn \l__joinbox_out_coffin + { + \coffin_typeset:Nnnnn \l__joinbox_out_coffin + { l }{ b }{ 0pt }{ 0pt } + }\hcoffin_set_end: + % 输出拼接后的盒子 \__joinbox_typeout_coffin:N \l__joinbox_out_coffin }{ @@ -319,17 +366,64 @@ } } + \hcoffin_set:Nn \l__joinbox_out_coffin + { + \coffin_typeset:Nnnnn \l__joinbox_out_coffin + { l }{ b }{ 0pt }{ 0pt } + }\hcoffin_set_end: + % 输出拼接后的盒子 \__joinbox_typeout_coffin:N \l__joinbox_out_coffin } \group_end: } +% 多个盒子拼接内部函数 +\cs_new:Npn \__joinbox_boxes: + { + % 设置第1个盒子内容 + \clist_pop:NN \l__joinbox_contents_clist \l_tmpa_tl + \hcoffin_set:Nn \l__joinbox_tmpa_coffin + { + \l_tmpa_tl + } + + % 循环处理其它盒子内容 + \clist_map_inline:Nn \l__joinbox_contents_clist + { + \hcoffin_set:Nn \l__joinbox_tmpb_coffin + { + ##1 + } + + \__joinbox_calc_min_size:nn + { + \__joinbox_typeout_coffin:N \l__joinbox_tmpa_coffin + } + { + \__joinbox_typeout_coffin:N \l__joinbox_tmpb_coffin + } + + \hcoffin_set:Nn \l__joinbox_tmpa_coffin + { + \__joinbox_handle:nn + { + \coffin_typeset:Nnnnn \l__joinbox_tmpa_coffin + { l } { b } { 0pt } { 0pt } + } + { + \coffin_typeset:Nnnnn \l__joinbox_tmpb_coffin + { l } { b } { 0pt } { 0pt } + } + } + } + \__joinbox_typeout_coffin:N \l__joinbox_tmpa_coffin + } + \cs_new:Npn \__joinbox_figs: { % 设置第1个图像 \clist_pop:NN \l__joinbox_name_clist \l_tmpa_tl - \coffin_clear:N \l__joinbox_tmpa_coffin \hcoffin_set:Nn \l__joinbox_tmpa_coffin { \includegraphics{ \l_tmpa_tl } @@ -338,7 +432,6 @@ % 循环处理其它图像 \clist_map_inline:Nn \l__joinbox_name_clist { - \coffin_clear:N \l__joinbox_tmpb_coffin \hcoffin_set:Nn \l__joinbox_tmpb_coffin { \includegraphics{ ##1 } @@ -356,10 +449,12 @@ { \__joinbox_handle:nn { - \__joinbox_typeout_coffin:N \l__joinbox_tmpa_coffin + \coffin_typeset:Nnnnn \l__joinbox_tmpa_coffin + { l } { b } { 0pt } { 0pt } } { - \__joinbox_typeout_coffin:N \l__joinbox_tmpb_coffin + \coffin_typeset:Nnnnn \l__joinbox_tmpb_coffin + { l } { b } { 0pt } { 0pt } } } } @@ -381,9 +476,28 @@ \bool_set_true:N \l__joinbox_vertical_bool } + \group_begin: % 设置拼接参数 \keys_set:nn { joinbox } { #2 } + + % 判断第1个拼接对象是否为空 + \tl_set:Nn \l_tmpa_tl { #3 } + \tl_if_empty:VT \l_tmpa_tl + { + \bool_set_true:N \l__joinbox_only_second_bool + } + % 判断第2个拼接对象是否为空 + \tl_set:Nn \l_tmpa_tl { #4 } + \tl_if_empty:VT \l_tmpa_tl + { + \bool_set_true:N \l__joinbox_only_first_bool + } + % 两个拼接对象同时为空,无需拼接 + \bool_if:nT { \l__joinbox_only_first_bool && \l__joinbox_only_second_bool } + { + \__joinbox_error:n { empty-objs } + } % 计算最小宽度和高度 \__joinbox_calc_min_size:nn { #3 } { #4 } % 拼接输出 @@ -391,8 +505,50 @@ \group_end: } +% 两个以上盒子拼接用户接口 +% 将逗号分隔的内容构成的各个盒子拼接成一个盒子 +% #1---是否为*命令,如有*则采用水平拼接,无*则采用垂直拼接 +% #2---可选参数,用key-value选项指定拼接参数 +% #3---必选参数,用逗号分隔的,需要拼接内容(各个内容应该置于大括号内) +\NewDocumentCommand{\joinboxes}{ s O{} m} + { + \IfBooleanTF{#1} + { + \bool_set_false:N \l__joinbox_vertical_bool + }{ + \bool_set_true:N \l__joinbox_vertical_bool + } + + \group_begin: + % 设置拼接参数 + \keys_set:nn { joinbox } { #2 } + % 设置内容列表 + \clist_set:Nn \l__joinbox_contents_clist { #3 } + % 判断是否为空 + \clist_if_empty:NT \l__joinbox_contents_clist + { + \__joinbox_error:n { empty-contents } + } + % 判断是否只有1个图像名称 + \int_compare:nNnT { \clist_count:N \l__joinbox_contents_clist } = { 1 } + { + \bool_set_true:N \l__joinbox_only_first_bool + } + % 拼接盒子 + \__joinbox_boxes: + \group_end: + } + +% 空图像文件名列表出错信息 +\msg_new:nnn { joinbox } { empty-contents } + { The~contents~list~is~empty. } + +% 被拼接对象同时为空,无需拼接 +\msg_new:nnn { joinbox } { empty-objs } + { The~two~objects~which~was~joined~are~empty. } + % 图像拼接用户接口 -% 将指定文件名列表中的图像拼接成一个盒子并将基线调整为中心线输出 +% 将指定文件名列表中的图像拼接成一个盒子 % #1---是否为*命令,如有*则采用水平拼接,无*则采用垂直拼接 % #2---可选参数,用key-value选项指定拼接参数 % #3---必选参数,用逗号分隔的,需要拼接的图像文件名称(可以带有路径) @@ -410,9 +566,23 @@ \keys_set:nn { joinbox } { #2 } % 设置文件名列表 \clist_set:Nn \l__joinbox_name_clist { #3 } + % 判断是否为空 + \clist_if_empty:NT \l__joinbox_name_clist + { + \__joinbox_error:n { empty-fignames } + } + % 判断是否只有1个图像名称 + \int_compare:nNnT { \clist_count:N \l__joinbox_name_clist } = { 1 } + { + \bool_set_true:N \l__joinbox_only_first_bool + } % 拼接图像 \__joinbox_figs: \group_end: } +% 空图像文件名列表出错信息 +\msg_new:nnn { joinbox } { empty-fignames } + { The~figure~namelist~is~empty. } + \endinput |