雾月
雾月
这家伙很懒,什么也没写!

注册于 3年前

回答
184
文章
2
关注者
19

如果只是想得到 title、author 等信息,可以

\def\recordinfo#1{\gdef\recordedinfo{#1}#1}

然后使用

\recordinfo{%
\title{...}%
\author{...}%
\date{...}%
}

这样就把它们保存到了 \recordedinfo 之中,\maketitle 同样可用。

实际上,标准类文档中 title 等信息被保存到了 \@title\@author\@date 之中,在 \maketitle 之前可以使用它们,如果你用的文档类没有重定义 \title 等命令的话。

第一个例子中,\@title 就是

The Triangulation of Titling Data in Non-Linear Gaussian Fashion via $\rho$ Series\thanks{No procrastination}

当然也可以使用 regexpatch 宏包的 \xpretocmd 将信息保存到自己的命令中

% \usepackage{regexpatch} % 或者\usepackage{xpatch}
\xpretocmd\title{\gdef\titlesaved{#1}}{}{}

\titlesaved 中也会保存相同的标题信息。

至于它们的显示与否和显示顺序,这是由 \maketitle 或类似的命令来完成的。
可以使用 \meaning\maketitle (或者 \show\maketitle)查看其定义,在标准类文档中是由 \@maketitle 完成的,它决定了标题信息的输出顺序。

这些标题信息在每个文档类中都不一样,而且有些文档类不只有 title、author、date 信息,要设计一个通用的命令几乎是不可能的,只能靠人工查找,当然这还不如直接排版出来,再记住它们的顺序。

可能是使用了 fancyvrb 宏包的 \DefineShortVerb 命令将 | 定义为了 verb 命令。
我使用这种方式复现了类似的错误。

这样的话可以将 | 的类代码改为 12:

\catcode`\|=12
... 公式 ...

另外你可以使用

\the\catcode`\|

查看 | 的类代码,如果其值是 13 则应该可以通过上述方式修复。

如果还不能解决,请提供 MWE。

看看这个 https://www.zhihu.com/question/501741864/answer/2244093701
原理是相同的,只要把它的 sidenote 计数器改为你的计数器即可。

使用 \phantomsection\addcontentsline

\documentclass{book}

\usepackage[colorlinks]{hyperref}
\usepackage{bookmark}
\usepackage{lipsum}

\begin{document}

% \hypersetup{pdfview=Fit}
\phantomsection
\addcontentsline{toc}{chapter}{Page One}
\begin{center}
\begin{minipage}{.7\textwidth}
{\hfill\bfseries\large Abstract\hfill}
\medskip

\parindent=2em
\small
\lipsum[11-12]
\end{minipage}
\end{center}


\cleardoublepage
% \hypersetup{pdfview=XYZ}
\phantomsection
\addcontentsline{toc}{chapter}{Contents}
\tableofcontents


\chapter{Chapter One}

\lipsum[1-3]

\section{Section One.One}

\lipsum[4-9]

\section{Section One.Two}

\chapter{Chapter Two}

\lipsum[10-13]

\end{document}

image.png
image.png

cmap是pdftex特有的功能,其它编译器不可用。

你之前那个问题是pdftex下,使用cjk支持中文出现的错误,不是标准行为。

\the\dimexpr 1em\relax = 10.0pt

\the\dimexpr 1em\relax                     = 10.0pt
\ExplSyntaxOn
\dim_to_decimal:n { 1em }                  = 10
\dim_to_decimal_in_bp:n { 1em }            = 9.96265
\dim_to_decimal_in_sp:n { 1em }            = 655360
\dim_to_decimal_in_unit:nn { 1em } { 1mm } = 3.51462
\ExplSyntaxOff

使用 enumitem 宏包。

这种情况推荐使用 description 环境。

\documentclass{ctexart}
\usepackage{enumitem}
\usepackage{zhlipsum}

\begin{document}

\zhlipsum[9][name=zhufu]

%% 全局设置使用 \setlist[description]{...}
\begin{description}[nosep,labelindent=2em,leftmargin=6.5em,font=\normalfont]
\item[参数a:] 啦啦啦
\item[参数b:] 啦啦啦
\item[参数c:] 欸\zhlipsum[14][name=zhufu]
\end{description}


\noindent\hrulefill

\zhlipsum[9][name=zhufu]

\begin{itemize}[nosep,left=5em]
\item[参数a:] 啦啦啦
\item[参数b:] 啦啦啦
\item[参数c:] 欸\zhlipsum[14][name=zhufu]
\end{itemize}

\begin{itemize}[left=5em]
\item[参数a:] 啦啦啦
\item[参数b:] 啦啦啦
\item[参数c:] 欸\zhlipsum[14][name=zhufu]
\end{itemize}

\end{document}

image.png

实际上,页眉处的“第一章 研究进展”等文字是由 \<section>mark 来进行记录的,这里的 <section> 就是 chaptersectionsubsection 等。
使用 ctex 文档类或使用 ctexheading 宏包,或在 ctex 宏包中启用 heading=true 选项时,ctex 将自动地修改这些 \<section>mark 命令,类似于

\renewcommand{\sectionmark}[1]{\markright{\CTEXthesection #1}}
\renewcommand{\chaptermark}[1]{\markboth{\CTEXthechapter #1}{}}

这里的 \CTEXthesection\CTEXthechapter 就是在页眉处输出 “第一节”、“第一章” 的。
这里的变量 #1 就是 \<section> 中给出的标题,如“研究进展”。
因此只要重定义这些 mark,去掉诸如 \CTEXthesection 之类的命令,就可以实现你的需求了。ctex 宏包文档 6.3 节给出了两个例子。

这里再给一个例子:

\documentclass{ctexbook}
\usepackage{fancyhdr}
\usepackage{zhlipsum}

% \pagestyle{...} 放前面
\def\chaptermark#1{\markboth{#1}{}}
\def\sectionmark#1{\markright{#1}}

\begin{document}

\chapter{章一第}

\zhlipsum[1]

\section{节二第}

\zhlipsum[2-5]

\section{节三第}

\zhlipsum[6-10]

\end{document}

简单来说,当 label 不存在时,强行展开 \pageref 就会出现该错误。
第一次运行时,label 还没有写入 aux,这时,由于 \write 会自动展开它的参数,于是就出错了。

知道这之后,就容易解决了。

% \usepackage{expl3}% 在较新的 LaTeX2e 中是不必要的
\makeatletter
\ExplSyntaxOn
\cs_if_free:NT \use_ii:nnnnn
  { \cs_new:Npn \use_ii:nnnnn #1#2#3#4#5 { #2 } }
% 使用 hyperref,`\newlabel` 会写入 5 个参数,不使用 hyperref,则会写入 2 个参数,需要分别处理
% 第二个参数就是 page
\@ifpackageloaded{hyperref}
  {
    \cs_set_nopar:Npn \getrefpage #1
      { % 判断 label 是否存在,LaTeX 使用 "r@<label>" 保存 label
        \cs_if_exist:cTF { r@#1 } 
          { \exp_last_unbraced:Nv \use_ii:nnnnn { r@#1 } } % 获得5个中的第2个
          { 0 } % 若不存在则使用 0
      }  
  }
  {
    \cs_set_nopar:Npn \getrefpage #1
      { % 同上
        \cs_if_exist:cTF { r@#1 } 
          { \exp_last_unbraced:Nv \use_ii:nn { r@#1 } } 
          { 0 }
      }
  }
\ExplSyntaxOff
\makeatother

这样我们就可以使用 \getrefpage{<label>} 来获取 \label 定义的 label 的页码

\immediate\write\myoutfile{\getrefpage{nohere:a}}
\label{nohere:a} % label 需要在 \write 外部,才能创造一个label

由于 \label 是不可扩展的,若要在 \write 中写入,则需要使用 \noexpand\string

\immediate\write\myoutfile{\getrefpage{nohere:a}\noexpand\label{nohere:a}}
\label{nohere:a}

另外,\label 中的 page 实际上是 \thepage 而不是绝对页码,也不一定是数字,例如修改了 page 计数器,或者使用了 \pagenumbering

此时,要想获得绝对页面,可以使用 zref-abspage 宏包,相应的,可以定义一个 \getzrefabspage\getzrefpage 来获得绝对页码和相对页码。

% \usepackage{zref-abspage}
\makeatletter
\def\getzrefabspage#1{\zref@extract{#1}{abspage}}
\def\getzrefpage#1{\zref@ifrefundefined{#1}{0}{\zref@extract{#1}{page}}} % 同样需要检查是否存在
\makeatother
% \usepackage{zref-user,zref-abspage}
\zlabel{here:a}% 使用 \zlabel 而不是 \label
\immediate\write\myoutfile{\getzrefpage{here:a}\noexpand\zlabel{here:a}}
\immediate\write\myoutfile{\getzrefabspage{here:a}\noexpand\zlabel{here:a}}

当修改了 page 计数器,或者使用了 \pagenumbering 时,这二者是不同的。

一个完整的例子:

\documentclass{article}
% \usepackage{expl3}
\usepackage{zref-user,zref-abspage,lipsum}

\newwrite\myoutfile
\immediate\openout\myoutfile=\jobname-myoutfile.txt

\makeatletter
\def\getzrefabspage#1{\zref@extract{#1}{abspage}}
\def\getzrefpage#1{\zref@ifrefundefined{#1}{0}{\zref@extract{#1}{page}}}
\ExplSyntaxOn
\cs_if_free:NT \use_ii:nnnnn
  { \cs_new:Npn \use_ii:nnnnn #1#2#3#4#5 { #2 } }
\@ifpackageloaded{hyperref}
  {
    \cs_set_nopar:Npn \getrefpage #1
      {
        \cs_if_exist:cTF { r@#1 } 
          { \exp_last_unbraced:Nv \use_ii:nnnnn { r@#1 } } 
          { 0 }
      }  
  }
  {
    \cs_set_nopar:Npn \getrefpage #1
      {
        \cs_if_exist:cTF { r@#1 } 
          { \exp_last_unbraced:Nv \use_ii:nn { r@#1 } } 
          { 0 }
      }
  }
\ExplSyntaxOff
\makeatother

\begin{document}

\immediate\write\myoutfile{\getzrefpage{here:a}\noexpand\zlabel{here:a}}
\immediate\write\myoutfile{\getzrefabspage{here:a}\noexpand\zlabel{here:a}}
\zlabel{here:a}

\immediate\write\myoutfile{\getrefpage{nohere:a}\noexpand\label{nohere:a}}
\label{nohere:a}


\lipsum[1-10]


\pagenumbering{alph}


\zlabel{here:b}.
\immediate\write\myoutfile{\getzrefpage{here:b}\noexpand\zlabel{here:b}}
\immediate\write\myoutfile{\getzrefabspage{here:b}\noexpand\zlabel{here:b}}


\label{nohere:b}.
\immediate\write\myoutfile{\getrefpage{nohere:b}\noexpand\label{nohere:b}}

\lipsum[10-12]

\end{document}

在较新的 LaTeX2e 发行版中,原生提供了 \ReadonlyShipoutCountertotalpages 计数器来记录绝对页码。

使用 fancyhdr 宏包,重定义 \headrule 命令。

% \usepackage{fancyhdr}
% 定义三个长度
\newdimen\doublelineskip % 两横线间的距离
\setlength\doublelineskip{2pt}
\newdimen\headrulewidthA % 第一条线的宽度
\setlength\headrulewidthA{.8pt}
\newdimen\headrulewidthB % 第二条线的宽度
\setlength\headrulewidthB{.4pt}

% 定义(修改) headings 样式,如果你使用了自定义样式则不必进行该步骤 
\fancypagestyle{headings}{
  \renewcommand\headrulewidth{0.4pt}
}
% 基于 headings 样式定义一个 doubleline 样式,用于插入页眉“文武线”线,原来的 headings 仍然可用
% 如果使用了自己的样式,把 headings 修改为自己的样式名字
\fancypagestyle{doubleline}[headings]{
  \renewcommand\headrule{%
    \hrule height\headrulewidthA width\headwidth% 第一根线
    \vskip \doublelineskip%
    \hrule height\headrulewidthB width\headwidth}% 第二根线
}

完整的例子:

\documentclass{article}
\usepackage{fancyhdr}
\usepackage{lipsum}
\usepackage[paperheight=10cm,textheight=6cm]{geometry}

\newdimen\doublelineskip % 两横线间的距离
\setlength\doublelineskip{2pt}
\newdimen\headrulewidthA % 第一条线的宽度
\setlength\headrulewidthA{.8pt}
\newdimen\headrulewidthB % 第二条线的宽度
\setlength\headrulewidthB{.4pt}

\setlength\headheight{21pt}

\fancypagestyle{headings}{
  \renewcommand\headrulewidth{0.4pt}
}
\fancypagestyle{doubleline}[headings]{
  \renewcommand\headrule{%
    \hrule height\headrulewidthA width\headwidth%
    \vskip \doublelineskip%
    \hrule height\headrulewidthB width\headwidth}
}

%\pagestyle{headings}
\pagestyle{doubleline}

\begin{document}

\section{SE1}
\lipsum[1-6]

\section{SE2}
\lipsum[7-15]

\end{document}

image.png

若使用 titleps 宏包,则重定义 \makeheadrule

% \usepackage{titleps}
% \newdimen 3 个,同 fancyhdr
\newpagestyle{doubleline}{
  \renewcommand\makeheadrule{%
    \makebox[0pt][l]{\rule[\doublelineskip]{\linewidth}{\headrulewidthA}}%
    \rule{\linewidth}{\headrulewidthB}}%
}

可以使用 cleveref 宏包。

主要的配置命令如下:

% \usepackage{hyperref}
% \usepackage{cleveref} % 注意顺序
% 修改 autorefname,也方便在后面使用
\def\figureautorefname{Fig.}
\def\figureautorefnames{Figs.}
\crefformat{figure}{#2\figureautorefname~#1#3}
\crefmultiformat{figure}
  {#2\figureautorefnames~#1#3}
  { and~#2#1#3}
  {, #2#1#3}
  { and~#2#1#3}
\crefrangeformat{figure}{#3\figureautorefnames~#1#4 to~#5#2#6}

详细用法见说明文档。

完整的例子:

\documentclass{article}
\usepackage[colorlinks]{hyperref}
\usepackage{cleveref}

\def\figureautorefname{Fig.}
\def\figureautorefnames{Figs.}
\crefformat{figure}{#2\figureautorefname~#1#3}
\crefmultiformat{figure}
  {#2\figureautorefnames~#1#3}
  { and~#2#1#3}
  {, #2#1#3}
  { and~#2#1#3}
\crefrangeformat{figure}{#3\figureautorefnames~#1#4 to~#5#2#6}

\begin{document}

Hello, \LaTeXe.

\begin{figure}[h]
\caption{FIGURE ONE}\label{fig:1}
\centering\fbox{FIGURE ONE}
\end{figure}

\begin{figure}[h]
\caption{FIGURE TWO}\label{fig:2}
\centering\fbox{FIGURE TWO}
\end{figure}

\begin{figure}[h]
\caption{FIGURE THREE}\label{fig:3}
\centering\fbox{FIGURE THREE}
\end{figure}

reference: \ref{fig:1} \& \ref{fig:2} \& \ref{fig:3}

autoref: \autoref{fig:1} \& \autoref{fig:2} \& \autoref{fig:3}

cleveref: \cref{fig:1} \& \cref{fig:2} \& \cref{fig:3}

multi cref: \cref{fig:1,fig:2} \& \cref{fig:1,fig:2,fig:3} \& \cref{fig:1,,fig:2,,fig:3}

---------------------------

\crefmultiformat{figure}
  {\figureautorefnames~#2#1#3}
  { and~#2#1#3}
  {, #2#1#3}
  { and~#2#1#3}
\crefrangeformat{figure}{\figureautorefnames~#3#1#4 to~#5#2#6}

multi cref: \cref{fig:1,fig:2} \& \cref{fig:1,fig:2,fig:3} \& \cref{fig:1,,fig:2,,fig:3}

\end{document}

image.png

编译不成功的原因是

  1. \newtcbtheorem 不会展开其参数;
  2. \setkeys 以及几乎所有的键设置命令(\keys_set:nn\pgfkeys)都是不可扩展的。(也有一部分命令是可扩展的,如 \keyval_parse:nnnexpkv 宏包的部分命令。)

首先要说明的是,LaTeX3 不依赖任何其它宏包,甚至都不需要是 LaTeX。以及 l3keys 也不依赖 l3prop,这二者是独立的。键值设置一般使用 l3keysl3prop 使用得较少。

要想成功编译,首先必须解析传入的键值,然后将其传给 \newtcbtheorem
可用的方法有很多,但是既然使用了 tcolorbox,就使用 pgfkeys 来实现吧。

首先定义几个辅助命令与句柄(handler):

\makeatletter

\ExplSyntaxOn
\cs_new_nopar:Npn \zt@appto@clist #1#2 { \clist_put_right:Nn #2 {#1} }
\cs_new_nopar:Npn \zt@preto@clist #1#2 { \clist_put_left:Nn #2 {#1} }
\ExplSyntaxOff

\pgfkeys{
  % {<prefix list>} {<clist>},把 <prefix list> 放到 <clist> 之前,<clist> 是一个 list 宏
  /handlers/.prefix to clist/.code 2 args=%
    \pgfkeysdef{\pgfkeyscurrentpath}{\zt@preto@clist{#1}{#2}},
  % {<append list>} {<clist>}
  /handlers/.append to clist/.code 2 args=%
    \pgfkeysdef{\pgfkeyscurrentpath}{\zt@appto@clist{#1}{#2}},
}

\tcbset{
  zljTheoStyle/.style={}, % 你自己的代码
}
% 这个命令类似于 \tikzset、\tcbset,它的形式是 \ztpgfset{<module>}{<key-val>}
\def\ztpgfset#1{\pgfqkeys{zt/#1}}
\NewDocumentCommand\ztset{O{}}
  {
    \def\zt@tmplist{}% 这个命令用于保存解析的键值
    \ztpgfset{tcb}{#1} % 这个命令用于解析传入的键值参数,使用 tcb 模块
    \def\zt@tmp{\newtcbtheorem{zljtest}{name}}
    \expandafter\zt@tmp\expandafter{\zt@tmplist,zljTheoStyle,}{zljtest} % 必须展开解析得到的键值
  }

现在就可以定义自己的键了,把它们放到 tcb 模块:

\ztpgfset{tcb}{
  color/.append to clist={colbacktitle={#1}}{\zt@tmplist},% 把 "colbacktitle={#1}" 放到 \zt@tmplist 之后,效果和 "color/.code=\zt@appto@clist{#1}{\zt@tmplist}" 一样
  color/.default=red,% 默认值为 red
  cf/.append to clist={colframe=#1}{\zt@tmplist},% 把 "colframe=#1" 放到 \zt@tmplist 之后
  cf/.default=yellow!80!black,
}
\makeatother

一个完整的例子:

\documentclass{ctexart}
\usepackage[most]{tcolorbox}

\makeatletter
\ExplSyntaxOn
\cs_new_nopar:Npn \zt@appto@clist #1#2 { \clist_put_right:Nn #2 {#1} }
\cs_new_nopar:Npn \zt@preto@clist #1#2 { \clist_put_left:Nn #2 {#1} }
\ExplSyntaxOff

\pgfkeys{
  /handlers/.prefix to clist/.code 2 args=%
    \pgfkeysdef{\pgfkeyscurrentpath}{\zt@preto@clist{#1}{#2}},
  /handlers/.append to clist/.code 2 args=%
    \pgfkeysdef{\pgfkeyscurrentpath}{\zt@appto@clist{#1}{#2}},
}

\tcbset{
  zljTheoStyle/.style={}, % 你自己的代码
}
\def\ztpgfset#1{\pgfqkeys{zt/#1}}
\NewDocumentCommand\ztset{O{}}
  {
    \def\zt@tmplist{}% 这个命令用于保存解析的键值
    \ztpgfset{tcb}{#1} % 这个命令用于解析传入的键值参数,使用 tcb 模块
    \def\zt@tmp{\newtcbtheorem{zljtest}{name}}
    \expandafter\zt@tmp\expandafter{\zt@tmplist,zljTheoStyle,}{zljtest}
  }
\ztpgfset{tcb}{
  color/.append to clist={colbacktitle={#1}}{\zt@tmplist},% 把 "colbacktitle={#1}" 放到 \zt@tmplist 之后
  color/.default=red,% 默认值为 red
  cf/.append to clist={colframe=#1}{\zt@tmplist},% 把 "colframe=#1" 放到 \zt@tmplist 之后
  cf/.default=yellow!80!black,
}
\makeatother

\begin{document}

\ztset[color=blue,cf]

\begin{zljtest}{}{}
    测试基
\end{zljtest}

\end{document}

image.png

发布
问题