尊咾哎哟
尊咾哎哟
¥a^2+b^2=c^2¥. . .

注册于 3年前

回答
10
文章
0
关注者
1

有点久的提问了,不懂题主是否已经解决了...这个[空白变多]疑惑之前遇到过,所以小发表一下看法。

关于patch的方法

ctexart.cls\@startsection的定义中,如下句子便是用来添加beforeskip的:

\addvspace \CTEX@headingskip

于是原MWE中将\addvspace替换为\vspace*,效果如lshort中所说,可以使所添加的垂直间距在一页的顶端不被“吞掉”。

对此,直接在\ssection命令之前\vspace*{0bp},效果基本是等价的。

ctexart类中,可以用\ctexset命令,将语句\vspace*{0bp}叠加berak键中。

beforeskip中多余的空白

我受了如下这个tse贴的启发:
https://tex.stackexchange.com/questions/7676/why-does-vspace0pt-add-vertical-space

进一步,在TeX by Topic的26.2中大致找到了答案:
image.png

image.png

可以理解为:\topskip用来保证本页第一个box的baseline能有一个最小的深度,当小于这个深度时,就会自动延伸直到\topskip值大小为止。

从实验来看,\topskip的值可能等于fontsize的大小。在文档类中设置fontsize然后在正文打印这个长度值便可发现。

Example:
image.png

于是我推测\section命令(其他各级章节标题命令类似)在真正生成标题内容(即:运行\@sect)之前,会先运行\vspace* \CTEX@headingskip。而当页面第一行为\section命令时,\vspace* \CTEX@headingskip便直接成为了本页实质上的第一个box,但这个box没有没有其他任何实质内容,于是\topskip的机制在这里多添加了除beforeskip以外的垂直间距。

在视觉上是多加了一个空行。可以验证:在\newpage之后先添加一行文本、再使用\section命令,和在\newpage之后直接使用\section命令相比,\section命令所生成标题的相对位置是(几乎)没发生改变的。

进一步的解决方案

对于消除\topskip的影响呢,刚才提到的tse贴中给了一种方法:将topskip的值设为0

原贴中还额外要加\offinterlineskip,但这有点“野蛮”,我给删掉了

在原有MWE的导言区中,用钩子封装一下即可:

\AtBeginDocument{\topskip=0pt}

但这会造成一个问题:\topskip设为0,相当于(几乎)没有了\topskip的延展,对于一些上方该有垂直间距的文本内容现在会直接“顶行”(虽然把geometry包的showfram效果去掉后看不出什么端倪)。且\topskip好像是无法分页/按条件修改的(一经设置便对所有页统一作用)。可能会就此产生一些新的问题。

特别的,上述的推测基本为启发式的,我对\vspace*\topskip机制中的根本性质依旧存疑。

@u686 的回答中所给tse贴的方法对标准book文档类确实是有效的,但:

  • ctexbook文档类对各标题命令都进行了一定程度的重定义,所以一些基于patching的方法可能会失效;
  • tse贴中的方法没能完全覆盖题主的需求。

本人的方法省流:

  1. 导入etoolbox宏包;
  2. 设置条件变量,用于判断是否属于\part命令下的第一个\chapter命令
  3. 使用\apptocmd命令,将布尔变量“植入”\part,\chapter的定义中;
  4. 使用\patchcmd命令,从底层删掉\part命令之后的换页命令;
  5. \ctexset命令下,条件设置\chapter命令之前的换页操作。
  6. 调整\part命令所生成标题的前后间距;
  7. 修改\part命令所生成标题的样式

预处理

首先删掉选项twoside。该选项对于book文档类是默认导入的:
image.png

然后导入etoolbox宏包。

标准ctexbook文档类下的初始效果

先展示不做任何处理时的效果,以做对比:
image.png

设置条件变量,用于判断是否属于\part命令下的第一个\chapter命令

其实呢,你在每个\part命令下第二个及之后的\chapter命令之前手动换页就行了...但为了严格遵守“内容与格式分离”嘛...
\newif\ifrefreshpart
\refreshpartfalse

原理为:

  • 正文开始前,将变量初始化为FALSE
  • 每次使用\part命令时,将变量设为TRUE,表示:刷新为新的一个\part命令的标题
  • 每个\part命令下第一次使用\chapter前判断变量真值,为假则取消\chapter命令之前的换页操作;反之则保留
  • 每次执行了\chapter命令之后,将变量设为FALSE

使用\apptocmd命令,将布尔变量“植入”\part,\chapter的定义中

\apptocmd{\@part}{\refreshparttrue}{}{}
\apptocmd{\@chapter}{\refreshpartfalse}{}{}

删掉\part命令之后的换页操作、条件设置\chapter命令之前的换页操作

如图,ctexbook类重定义了\part命令,但一直展开到\@endpart时,可以发现是靠\newpage命令来换页的:
image.png

因此删掉这里的\newpage即可:

\patchcmd{\@endpart}{\newpage}{}{}{}

\chapter命令之前的样式属于ctex宏集可操作的,因此在\ctexset命令下根据之前提到的原理修改:

\ctexset{
    chapter={
        break={%条件设置\chapter之前的换页
            \if@openright\cleardoublepage\else
                \ifrefreshpart
                \par
                \else
                \clearpage
                \fi
            \fi
        },
    }
}

调整\part命令所生成标题的样式、前后间距

题主所给的效果图中,\part命令所生成标题满足:

  • 编号与内容不换行
  • 顶行(,非垂直居中)

所以在\ctexset命令下修改:

\ctexset{
    part={
        aftername={\quad},
        beforeskip={0pt plus 50pt},
        afterskip={50pt},
    },
}

MWE

\documentclass[12pt,openany]{ctexbook}
\usepackage[paperwidth=168mm, paperheight=240mm, left=2.35cm, right=2.35cm, top=3cm, bottom=3cm]{geometry}

\usepackage{etoolbox}

\newif\ifrefreshpart
\refreshpartfalse

\makeatletter
\apptocmd{\@part}{\refreshparttrue}{}{}
\apptocmd{\@chapter}{\refreshpartfalse}{}{}
\patchcmd{\@endpart}{\newpage}{}{}{}
\ctexset{
    part={
        aftername={\quad},
        beforeskip={0pt plus 50pt},
        afterskip={50pt},
    },
    chapter={
        break={%条件设置\chapter之前的换页
            \if@openright\cleardoublepage\else
                \ifrefreshpart
                \par
                \else
                \clearpage
                \fi
            \fi
        },
    }
}
\makeatother

\begin{document}
    \part{层次一}
    第一部分和第一章希望在同一页上。
    \chapter{一层一}
    第一章和第二章仍然分页。
    \chapter{一层二}
    
    \part{层次二}
    \chapter{二层一}
\end{document}

效果:
image.png

省流:

  1. 修改后三列的对齐方式
  2. 因第1步修改,需单独对表头做居中对齐的处理;
  3. \adjustbox命令中valign的值改为m.

修改后三列的列对齐方式

首先,最后一列的对齐方式需要改为p型。原因未知。

然后:

在文字文本框内部的文字水平左对齐,且不缩进

既然如此,中间两列没必要再使用预设的C型(因为它用了\centering),而直接用m型即可。


需单独对表头做居中对齐处理

从效果图来看,表头内容是居中对齐的。由于改用了m型,故对表头所在行单独做居中对齐处理:

\textbf{序号} & \centering\textbf{实验内容} & \centering\textbf{按键操作} & \makebox[5.2cm][c]{\textbf{截屏显示}}

其中,最后一列在改用了p型的情况下用\centering会报错,所以改用盒子把它“撑开”。


\adjustbox命令中valign的值改为m.

我翻了adjustbox宏包的手册,发现valign键的值只有T,M,B;t,t,m,b,但用c好像也没报错...我不懂看漏了什么,但还是顺便改成m了。
image.png

另外,valign的各值的效果图:
image.png
它的参考系有点诡异,可能与所在列不能用m型对齐的情况有关,但我看了很久没弄明白,交给有缘人了...


MWE

\documentclass{ctexart}
\usepackage[margin=1in,landscape]{geometry}
\usepackage{longtable}  
\usepackage{array}
\usepackage{cellspace}
\usepackage{graphicx}
\usepackage[export]{adjustbox}
% \usepackage{tabularray}
% 全局定义表格列类型(兼容 longtable)
\newcolumntype{L}[1]{>{\raggedright\arraybackslash}m{#1}} 
% 左对齐+垂直居中(必须指定宽度)
\newcolumntype{C}[1]{>{\centering\arraybackslash}m{#1}}   
\begin{document}
    
\section{我是一个章节章节章节}

\begin{longtable}{|C{1cm}|m{4cm}|m{5cm}|p{5.2cm}|}
    \caption{画随点运动实时生成的正弦曲线} \label{tab:image_table}  \\ 
    \hline
    % 表头设置(四列)
    \textbf{序号} & \centering\textbf{实验内容} & \centering\textbf{按键操作} & \makebox[5.2cm][c]{\textbf{截屏显示}} \\
    \hline
    \endfirsthead
    % 续表头设置
    \multicolumn{4}{c}%
    {\tablename\ \thetable{} -- 续上页表格} \\
    \hline
    \textbf{序号} & \centering\textbf{实验内容} & \centering\textbf{按键操作} & \makebox[5.2cm][c]{\textbf{截屏显示}} \\
    \hline
    \endhead
    1 & 暂停动画并擦除几何跟踪痕迹&隐藏不需要展示的对象,播放动画,隐藏不需要展示的对象,播放动画,
    &\adjustbox{valign=m, margin=3pt 5pt}{\includegraphics[width=5cm,height=3.5cm]{example-image}}\\
    \hline
    2&测量点$M$ 的坐标 &隐藏不需要展示的对象,播放动画,
    得到点$M$的横、纵坐标,隐藏不需要展示的对象,播放动画,
    &\adjustbox{valign=m, margin=3pt 5pt}{\includegraphics[width=5cm,height=3.5cm]{example-image}}\\
    \hline
    3&保存点$M$ 的横坐标 &    选择点$M$ 的横坐标,依次点击命名为$x_m$  ,或者 鼠标右键
    &\adjustbox{valign=m, margin=3pt 5pt}{\includegraphics[width=5cm,height=3.5cm]{example-image}}\\
    \hline
    4 & 绘制随点 $M$变化生成的正弦曲线 &隐藏不需要展示的对象,播放动画输入相应的表达式
    &\adjustbox{valign=m, margin=3pt 5pt}{\includegraphics[width=5cm,height=3.5cm]{example-image}} \\
    \hline
\end{longtable}
    
\end{document}

效果:
image.png

详情xeCJK宏包手册的3.5 标点符号的处理

这里我有种错觉:既然您都知道PunctStyle这个key的存在,那应该能顺势从xeCJK手册后面摸排到专门处理标点符号的方法才对...

仅针对个别case的话(例如这里的,),可以使用\xeCJKsetwidth命令来修改其宽度。

MWE:

\documentclass{ctexart}

\xeCJKsetwidth{《》}{0.5em} %一次可对多个标点符号同时修改

\begin{document}

查看《手册》, 可以知道。

\end{document}

效果:
image.png

但如果是一般的全角标点宽度问题/全角标点与西文标点间距问题,可能得用到3.5.2中的命令了。

一个不skilled的方法。

核心思路是使用盒子:

\parbox[l]{<字数>\ccwd}{<第一行内容>\newline{}<第二行内容>}
% <字数>的大小对应两行中字数较大者

这边无法确定正文是否也需要想目录那样对齐,所以下面分类解决.

所有情况下MWE的结果均为:
image.png

目录中的为双行、正文中的随意

即:正文中两行之间要么用符号分隔,要么直接连成一句话.
\documentclass{ctexbook}

\ctexset{
    chapter={
        name={第,回},
        number={\chinese{chapter}}
    }
}

\usepackage[hidelinks,bookmarksnumbered=true, breaklinks=true]{hyperref}

\begin{document}

\tableofcontents

\chapter[\texorpdfstring{\parbox[l]{8\ccwd}{甄士隐梦幻识通\newline{}贾雨村风尘怀闺秀}}{甄士隐梦幻识通灵,贾雨村风尘怀闺秀}]{甄士隐梦幻识通灵,贾雨村风尘怀闺秀}

\chapter{这一回不需要双行目录}

\chapter[\texorpdfstring{\parbox[l]{8\ccwd}{甄士隐梦幻识通灵\newline{}贾雨村风尘怀闺秀}}{甄士隐梦幻识通灵贾雨村风尘怀闺秀}]{甄士隐梦幻识通灵贾雨村风尘怀闺秀}

\end{document}

正文、目录的标题样式均双行

从你给的图来看,不是所有的章标题都要双行,所以直接封装一个新的章标题命令\twolinechapter

  • 参数1:字数最多行的字数
  • 参数2:第一行的内容
  • 参数3:第二行的内容
\documentclass{ctexbook}

\ctexset{
    chapter={
        name={第,回},
        number={\chinese{chapter}}
    }
}

% ------------- 封装部分 -------------- %
\newcommand{\twolinechapter}[3]{
\chapter{\texorpdfstring{\parbox[l]{#1\ccwd}{#2\newline{}#3}}{#2,#3}} % \texorpdfstring命令是为了照顾到pdf书签中的输出内容,下同
} 
% ====================================== %

\usepackage[hidelinks,bookmarksnumbered=true, breaklinks=true]{hyperref}

\begin{document}

\tableofcontents

\twolinechapter{8}{甄士隐梦幻识通灵}{贾雨村风尘怀闺秀}

\chapter{这一回不需要双行目录}

\twolinechapter{8}{甄士隐梦幻识通}{贾雨村风尘怀闺秀}

\end{document}

正文中的按逗号分隔、目录的为双行

还是封装一个新的章标题命令\twolinechapter

\documentclass{ctexbook}

\ctexset{
    chapter={
        name={第,回},
        number={\chinese{chapter}}
    }
}

% ------------- 封装部分 -------------- %
\newcommand{\twolinechapter}[3]{
\chapter[\texorpdfstring{\parbox[l]{#1\ccwd}{#2\newline{}#3}}{#2,#3}]{#2,#3}
}
% ====================================== %

\usepackage[hidelinks,bookmarksnumbered=true, breaklinks=true]{hyperref}

\begin{document}

\tableofcontents

\twolinechapter{8}{甄士隐梦幻识通灵}{贾雨村风尘怀闺秀}

\chapter{这一回不需要双行目录}

\twolinechapter{8}{甄士隐梦幻识通}{贾雨村风尘怀闺秀}

\end{document}

小插曲

\settowidth命令对中文文本长度的获取貌似不准确,不然\twolinechapter命令的第一个参数可以省去。

不清楚这种“拿来主义”是否讲武德,侵删...

取自 tse 中某个问答的首答:
https://tex.stackexchange.com/questions/2326/vertically-center-text-on-a-page

但此处无需用 memoir 文档类,而是从 memoir.cls 中剖出 vplace 环境定义的 code。同时再加上\centering 实现行内居中。

\documentclass{article}
\usepackage{lipsum}
\newenvironment{vplace}[1][1]{%
  \par\vspace*{\stretch{#1}}%
  \centering %extra centering
}{%
  \vspace*{\stretch{1}}%
  \par}

\begin{document}

\lipsum[1-3] %contents of former pages
\clearpage

\begin{vplace}
\parbox{\textwidth}{\lipsum[1-3]}
\end{vplace}

\clearpage 
\lipsum[1-3] %contents of later pages

\end{document}

效果:
image.png

承接@u70550 的回答。

MWE的编译确实没有问题,但我猜题主想说的是无法使用超链接...在导言区(的尽可能最后一行)中导入 hyperref 宏包即可启动超链接。

请提供完整的MWE(最小工作示例),即从\documentclass\end{document}的代码部分,以便能复现你所说的问题

您所给的代码(大概率)只是放在导言区中的config,而没有正文区中的伪代码示例,因此无法看出所谓的Step x

(貌似)直接用 \SetCell命令就行:

\documentclass{article}
\usepackage{xcolor}
\usepackage[scale=0.8,papersize={10.5cm,14.85cm}]{geometry}
\usepackage{tabularray}
\pagestyle{empty}
\begin{document}
\begin{center}
    \begin{tblr}{
        hlines,vlines,
        colspec={X[c,m]X[c,m]X[c,m]X[c,m]X[c,m]X[c,m]},
        cell{3,4}{4,5}={bg=green!30},
        cell{3,4}{6}={bg=red!30},
        cell{5,6,7}{6}={bg=blue!30},
    }
    1-1&1-2&1-3&1-4&1-5&1-6\\
    2-1&2-2&2-3&2-4&2-5&2-6\\
    3-1&3-2&3-3&\SetCell[r=2,c=2]{c,m}3-4&   &\SetCell[r=2]{c,m}3-6\\
    4-1&4-2&4-3&   &   &   \\
    5-1&5-2&5-3&5-4&5-5&\SetCell[r=3]{c,m}5-6\\
    6-1&6-2&6-3&6-4&6-5&   \\
    7-1&7-2&7-3&7-4&7-5&   \\
    \end{tblr}
\end{center}
\end{document}

image.png

写在前头

  • 该代码有种拼接感,下次请提供只反映需求的MWE(最小代码示例)
  • 该代码如下部分设置的是全文的页眉页脚样式,而不只是首页:

    % 章节首页样式(无页眉和页眉横线,仅保留页码)
    \fancypagestyle{plain}{%
    %...
    }

解答

个人认为最快捷的方式,但会顺带使修改正文中章节标题也具备这个效果:
将原代码中的如下部分(第3行--第7行)

\ctexset{
    chapter/name = {第,回},
    chapter/number = \chinese{chapter},
    %    chapter/format = \Huge\bfseries\centering
}

改为

\ctexset{
    chapter/name = {第,回},
    chapter/number = \makebox[3em]{\chinese{chapter}},
    %    chapter/format = \Huge\bfseries\centering
}

即:用盒子控制长度。其中,章节序号有多少个字、就相应有多少个em

效果:
image.png
image.png

发布
问题