各位大佬,使用CJKfilltwosides环境排版多行文字分散对齐时,发现一个问题,该环境外面的文字与多行环境没有居中对齐,应该如何修正?
\documentclass{ctexart}
\usepackage{xeCJKfntef}
\begin{document}
{\Large
2021年\quad\begin{CJKfilltwosides*}{0pt}
哈尔滨师大附中\\
东北师大附中\\
辽宁省实验中学
\end{CJKfilltwosides*}
\quad 高三第一次联考
}
{\Large
2022年\,\begin{CJKfilltwosides*}{0pt}
金华市\\
衢州市
\end{CJKfilltwosides*}
\,初三第一次联考
}
\end{document}
加个 \parbox
之类的盒子
\parbox[c]{3cm}{东北师大附中}
{%
\begin{CJKfilltwosides*}{0pt}
哈尔滨师大附中\\
东北师大附中\\
辽宁省实验中学
\end{CJKfilltwosides*}
\quad 高三第一次联考
}
这个东西本来很简单,
\Large
2021年\begin{tabular}[b]{c}
哈尔滨师大附中\\
\begin{tabular}[t]{@{}c@{}}
辽宁省实验中学\\
东北师大附中
\end{tabular}
\end{tabular}高三第一次联考
这样就完事,间距还想宽一点就把里面的@{}c@{}
换成c
。
写成一个环境也行,用\alignhere
标记对齐位置。
\makeatletter
\def\parse@align#1#2#3\alignhere{%
\def\@helper##1{\begin{tabular}[b]{#1}
#3
\begin{tabular}[t]{##1}}%
\expandafter\@helper\expandafter{#2}}
\newenvironment{centertable}[2][]{%
\ifx\\#1\\%
\def\inner@preamble{#2}%
\else
\def\inner@preamble{#1}%
\fi
\parse@align{#2}\inner@preamble
}
{\end{tabular}\end{tabular}}
\makeatother
\fbox{\Large
2021年\begin{centertable}[@{}c@{}]{c}% [...]是内部表格的导言,默认跟外层相同
哈尔滨师大附中\\
\alignhere 辽宁省实验中学\\
东北师大附中
\end{centertable}高三第一次联考
}
如果非要像正常一样书写,可以用tikz标记位置,代价是编译速度会慢很多。
\documentclass{ctexart}
\usepackage{tabularray}
\usepackage{tikz}
\usetikzlibrary{tikzmark} % \subnode
\SetTblrInner{rowsep=0pt} % 设置多行文字的行间距
\makeatletter
\ExplSyntaxOn
\int_new:N \g_centertblr_num_int % 编号避免标记名字重复
\tl_new:N \l_centertblr_current_label_tl
\bool_new:N \g_centertblr_odd_row_count_bool
\NewDocumentEnvironment { centertblr } { O{c} m +b }
{
\tl_set:Nx \l_centertblr_current_label_tl { centertblr-mark-\int_use:N \g_centertblr_num_int }
\begin { tikzpicture }
[
baseline = ( \l_centertblr_current_label_tl.base ), % 1
remember~picture
]
\node
[
anchor = base,
baseline = ( \l_centertblr_current_label_tl.base ), % 2 对齐设置两次
inner~sep = 0,
]
{
\begin { tblr } [#1] {#2}
\SetRows% 最中间的行处标记
{
preto = {
\bool_if:NTF \g_centertblr_odd_row_count_bool
{
\int_compare:nNnT { \c@rownum * 2 - 1} = { \c@rowcount }
{ \subnode { \l_centertblr_current_label_tl } {} }
}
{
\int_compare:nNnT { \c@rownum * 2 } = { \c@rowcount }
{ \subnode { \l_centertblr_current_label_tl-up } {} }
\int_compare:nNnT { \c@rownum * 2 - 2} = { \c@rowcount }
{ \subnode { \l_centertblr_current_label_tl-down } {} }
}
}
}
\bool_gset:Nn \g_centertblr_odd_row_count_bool % node 里面不能写\path,保存以在外面用
{ \int_if_odd_p:n { \int_use:N \c@rowcount } }
#3
\end { tblr }
};
\bool_if:NF \g_centertblr_odd_row_count_bool
{
\path (\l_centertblr_current_label_tl-up) -- (\l_centertblr_current_label_tl-down)
coordinate[midway] (\l_centertblr_current_label_tl);% 标记中间两行anchor的中点
}
\end { tikzpicture }
}
{ \int_gincr:N \g_centertblr_num_int }
\ExplSyntaxOff
\makeatother
\begin{document}
\fbox{\Large
2021年\begin{centertblr}{Q[c,leftsep=0pt,rightsep=0pt]} % leftsep, rightsep 用来设置多行环境的左右间距
哈尔滨师大附中\\
辽宁省实验中学\\
东北师大附中
\end{centertblr}高三第一次联考
}
\fbox{\Large
2022年\begin{centertblr}{Q[c,leftsep=0pt,rightsep=0pt]}
金华市\\
衢州市
\end{centertblr}初三第一次联考
}
\fbox{\Large
2021年\begin{centertblr}{Q[c,leftsep=0pt,rightsep=0pt]}
哈尔滨师大\rule[-2cm]{1pt}{2cm}附中\\
东北师大附中\\
辽宁省实验中学
\end{centertblr}高三第一次联考
}
\fbox{\Large
2021年\begin{centertblr}{Q[c,leftsep=0pt,rightsep=0pt]}
哈尔滨师大\rule[-2cm]{1pt}{2cm}附中\\
东北师大附中\\
\end{centertblr}高三第一次联考
}
\end{document}
我也来凑个热闹,参照用LaTeX3排版分散和居中对齐文字用LaTeX3实现这一需求:
\documentclass{ctexart}
\usepackage{expl3}
\usepackage{xparse}
\ExplSyntaxOn
% 获取文本长度函数,#1用于保存长度,#2是被检测的文字
\cs_new:Npn \l_get_text_width:Nn #1#2
{
% 将文字内容存入变量
\hbox_set:Nn \l_tmpa_box {\l_font_tl #2}
% 用\box_wd:N函数获取盒子宽度,并存入长度变量
\dim_set:Nn #1 { \box_wd:N \l_tmpa_box }
}
% 文本长度函数变体
\cs_generate_variant:Nn \l_get_text_width:Nn { NV }
% 获取clist中各个成员长度是大值,
% #1用于保存长度变量,#2是被检测clist变量
\cs_new:Npn \l_get_max_text_width:NN #1#2
{
\group_begin:
% 将长度设置为小值
\dim_set:Nn #1 {-999pt}
\clist_set_eq:NN \l_tmpa_clist #2
% 循环检测每个tl的长度,并更新是大值
\bool_until_do:nn { \clist_if_empty_p:N \l_tmpa_clist }
{
\clist_pop:NN \l_tmpa_clist \l_tmpa_tl
\l_get_text_width:NV \l_tmpa_dim \l_tmpa_tl
\dim_gset:Nn #1 { \dim_max:nn {#1} { \l_tmpa_dim } }
}
\group_end:
}
% 分散对齐盒子,
% #1是盒子长度变量,#2是需要排版的文字
\cs_new_protected:Npn \l_spread_box:nn #1#2
{
\mode_leave_vertical:
\hbox_to_wd:nn {#1}
{ \tl_map_inline:xn {#2} { ##1 \hfil } \unskip }
}
% 分散对齐盒子函数变体
\cs_generate_variant:Nn \l_spread_box:nn { Vn }
\cs_generate_variant:Nn \l_spread_box:nn { nV }
% 居中对齐盒子,
% #1是盒子长度变量,#2是需要排版的文字
\cs_new_protected:Npn \l_center_box:nn #1#2
{
\mode_leave_vertical:
\dim_set:Nn \l_tmpa_dim {#1}
\dim_add:Nn \l_tmpa_dim {0.6em}
\makebox[0cm][l]{\rule[-0.5ex]{\l_tmpa_dim}{0.4 pt}}
{\hbox_to_wd:nn {\l_tmpa_dim} { \hfil #2 \hfil }}
}
% 居中对齐盒子函数变体
\cs_generate_variant:Nn \l_center_box:nn { Vn }
% 为文字添加下划线
\cs_new:Npn \l_text_uline:n #1
{
\l_get_text_width:Nn \l_tmpa_dim {#1}
\dim_add:Nn \l_tmpa_dim {0.6em}
% 将标尺盒子放到宽度为0的左右盒子中实现下划线
\makebox[0pc][l]{\rule[-0.5ex]{\l_tmpa_dim}{0.4 pt}}
% 用高度为0的标尺盒子在文字两端添加空白
\rule{.3em}{0cm}#1\rule{.3em}{0cm}
}
\clist_new:N \l_schools_clist
\dim_new:N \l_h_sep_dim
\dim_new:N \l_v_sep_dim
\coffin_new:N \l_output_coffin
\coffin_new:N \l_school_coffin
\tl_new:N \l_font_tl
\keys_define:nn { examinfo }
{
hsep .dim_set:N = \l_h_sep_dim,
hsep .initial:n = 5pt,
vsep .dim_set:N = \l_v_sep_dim,
vsep .initial:n = 5pt,
font .tl_set:N = \l_font_tl,
font .initial:n = \normalsize,
unknown .code:n = { \__examinfo_error:n { unknown-option } }
}
\msg_new:nnn { examinfo } { unknown-option }
{ package~ option~ "\l_keys_key_tl"~ is~ unknown. }
\NewDocumentCommand \examinfoset { m }
{ \keys_set:nn { examinfo } {#1} }
% 居中对齐盒子函数
\cs_new_protected:Npn \__examinfo_cover:nnn #1#2#3
{
\clist_set:Nn \l_schools_clist{#2}
% 设置年度容器
\hcoffin_set:Nn \l_tmpa_coffin {\l_font_tl #1}
\hcoffin_set:Nn \l_tmpb_coffin {\l_font_tl #3}
% 计算校名最大长度
\l_get_max_text_width:NN \l_tmpa_dim \l_schools_clist
% 排版第一个校名
\clist_if_empty:NF \l_schools_clist
{
% 从左端弹出一个校名
\clist_pop:NN \l_schools_clist \l_tmpa_tl
% 设置输出结果容器内容
\hcoffin_set:Nn \l_output_coffin
{
% 排版分散对齐盒子
\tl_use:N \l_font_tl
\l_spread_box:Vn \l_tmpa_dim { \l_tmpa_tl }
}
}
% 排版其它校名
\bool_until_do:nn { \clist_if_empty_p:N \l_schools_clist }
{
% 从左端弹出一个校名
\clist_pop:NN \l_schools_clist \l_tmpa_tl
% 设置校名容器内容
\hcoffin_set:Nn \l_school_coffin
{
% 排版分散对齐盒子
\tl_use:N \l_font_tl
\l_spread_box:Vn \l_tmpa_dim { \l_tmpa_tl }
}
% 将校名容器拼接到输出结果窗口(按\l_v_sep_dim为间隔拼接)
\coffin_join:NnnNnnnn \l_output_coffin { hc } { b }
\l_school_coffin { hc } { t } { 0pt } { -\l_v_sep_dim }
}
% 将年度容器拼接到输出结果容器(按\l_h_sep_dim为间隔拼接)
\coffin_join:NnnNnnnn \l_output_coffin { vc } { l }
\l_tmpa_coffin { vc } { r } { -\l_h_sep_dim } { 0pt }
% 将试卷名称容器拼接到输出结果容器(按\l_h_sep_dim为间隔拼接)
\coffin_join:NnnNnnnn \l_output_coffin { vc } { r }
\l_tmpb_coffin { vc } { l } { \l_h_sep_dim } { 0pt }
% 输出结果容器
\coffin_typeset:Nnnnn \l_output_coffin { vc } { l } { 0pt } { 0pt }
}
% 定义用户接口
\NewDocumentCommand{\examinfo}{O{} m m m}
{
\group_begin:
\keys_set:nn { examinfo } {#1}
\__examinfo_cover:nnn {#2}{#3}{#4}
\group_end:
}
\ExplSyntaxOff
\begin{document}
\section{默认参数}
% 注意校名间用英文逗号分隔
\examinfo{2021年}{哈尔滨师大附中, 东北师大附中, 辽宁省实验中学}{高三第一次联考}
\bigskip
\section{指定间距}
% 可以用hsep指定年度、校名、考试名称间的水平距离
% 可以用vsep指定校名间的垂直距离\bfseries
\examinfo[hsep=1cm, vsep=15pt]{2022年}{金华市, 衢州市}{初三第一次联考}
\bigskip
\section{指定字体}
% 也可以用font设置字体参数
\examinfo[font=\Large\heiti\bfseries]{2022年}{金华市, 衢州市}{初三第一次联考}
\end{document}
仔细看,确实没有居中对齐