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

注册于 4年前

回答
223
文章
2
关注者
23

改成这样:

\setlist[trivlist]{nosep}
\newenvironment{zhengming}
    {\setlength\partopsep{0pt}%
        \begin{adjustwidth}{40pt}{40pt}
        \begin{proof}
    }
    {
        \end{proof}
        \end{adjustwidth}
    }
\newenvironment{dingli}
    {\setlength\partopsep{0pt}%
        \begin{adjustwidth}{40pt}{40pt}
        \vspace{-\baselineskip}
        \begin{theorem}
    }
    {
        \end{theorem}
        \end{adjustwidth}
    }

坐标的表达式提前不会展开宏,而是一步步解析,并且在解析表达式时会使用 \pgfmathparse,这会修改 \pgfmathresult 的值,所以 \pgfmathresult 的值是不确定的。

而数学表达式 \pgfmath 等,会首先展开它的参数,这时 \pgfmathresult 已经被展开了,它的值已经固定。

可以下载字体放到 /use/share/fonts,然后更新 fontconfig 的配置文件。

如果只需要供 TeX Live 使用,可以直接下载到 $TEXMFROOT/texmf-local/fonts 文件夹,然后执行 (sudo) texhash && fc-cache -fsv

对于 Times New RomanTeXGyreTermesTeXGyreTermesX 可以作为它的替代,字形几乎完全一致,并且已经在 TeX Live 里面了。

问题 1,如果不用 needspace 或类似的方法,会有极少的概率不能正确判断是否已经分页,比如下面的第四个标题就有可能会判断失败。

看看这是不是你想要的:

\documentclass{ctexart}
\usepackage{zhlipsum}
%\usepackage{showframe}

\ExplSyntaxOn\makeatletter
\cs_set_eq:NN \section:nn \section
\cs_new_protected:Npn \__my_needspace_if_newpage:nTF #1
  {
    % 可以试试删掉 \begingroup 和 \endgroup 之间的内容,看看能否正确判断第四个标题
    \par \penalty-100\begingroup
    \setlength{\dimen@}{\dimexpr#1}
    \dimen@ii\pagegoal \advance\dimen@ii-\pagetotal
    \ifdim \dimen@>\dimen@ii
      \ifdim\dimen@ii>\z@ \vfil\fi
      \penalty-\@M
    \fi\endgroup
    % 上面这些是 \Needspace 的代码,可以直接用 \Needspace{\dimexpr#1} 或 \Needspace*{\dimexpr#1} 替代
    \bool_lazy_or:nnTF
      { \dim_compare_p:nNn { \pagegoal } = { \c_max_dim} }
      { \int_compare_p:nNn { \lastpenalty } < { -9999 } } % -\@M = -10000
  }

\RenewDocumentCommand{ \section }{ m } 
  {
    \__my_needspace_if_newpage:nTF { 1.5cm }
      { }
      { \hrule height0.4pt depth0pt }
    \section:nn {#1}
  }
\ExplSyntaxOff\makeatother

\begin{document}

\section{测试}
\zhlipsum[1-2]

\section{测试}
\zhlipsum[1]

\section{测试}
\zhlipsum[3-9][name=zhufu]

\section{测试}
\zhlipsum[1]

\end{document}

如果只需要 \captionof,不需要强制 abovebelowcaption 宏包就提供这个命令,必须用在一个环境内,不过最好是用 \captionsetup{type=...},这样可以正确处理超链接。

\begin{center}
\captionsetup{type=table...}
\caption{...}
...
\end{center}

如果需要强制设置 caption 的位置,而不管 \caption 是放在图片/文字前面还是后面,那 \captionaboveof 的功能不是这个(至少现在的版本不是)。如果需要类似的功能,floatrow 宏包可以全局设置 caption 的位置,也可用它的 floatrow 环境配合 \ffigbox 等。

封装一下 minipage,设置 \parindent=0pt

\documentclass{article}

\ExplSyntaxOn
\box_new:N \l__skyrmion_left_box
\box_new:N \l__skyrmion_right_box
\box_new:N \l__skyrmion_seg_box
\keys_define:nn { skyrmion }
  {
    lefthand~ratio .fp_set:N = \l__skyrmion_left_ratio_fp ,
    lefthand~width .dim_set:N = \l__skyrmion_left_dim ,
    righthand~ratio .dim_set:N = \l__skyrmion_right_ratio_fp ,
    righthand~width .dim_set:N = \l__skyrmion_right_dim ,
    sidebyside~gap .dim_set:N = \l__skyrmion_gap_dim ,
    sidebyside~gap .initial:n = 10mm ,
    before~left .tl_set:N = \l__skyrmion_before_left_tl ,
    before~right .tl_set:N = \l__skyrmion_before_right_tl ,
  }
\cs_new_protected:Npn \twopartsplit
  {
    \dim_compare:nNnTF \l__skyrmion_right_dim < { 10sp }
      {
        %% Width is too small! Abort!
      }
      {
        \__skyrmion_twopart_end_save:
        \__skyrmion_twopart_save:NN \l__skyrmion_right_box \l__skyrmion_right_dim
        \l__skyrmion_before_right_tl \ignorespaces
      }
  }
\NewDocumentEnvironment{twopart}{ O{} }
  {
    \par \keys_set:nn { skyrmion } {#1}
    \__skyrmion_calc_width: 
    \__skyrmion_twopart_save:NN \l__skyrmion_left_box \l__skyrmion_left_dim
    \l__skyrmion_before_left_tl \ignorespaces
  }
  {
    \__skyrmion_twopart_end_save:
    \__skyrmion_twopart_typeset:
  }
\cs_new:Npn \__skyrmion_calc_width:
  {
    \bool_lazy_and:nnTF
      { \dim_compare_p:nNn \l__skyrmion_left_dim = \c_zero_dim }
      { \dim_compare_p:nNn \l__skyrmion_right_dim = \c_zero_dim }
      {
        \bool_lazy_and:nnTF
          { \fp_compare_p:nNn { abs ( \l__skyrmion_left_ratio_fp ) } < { 0.0001 } }
          { \fp_compare_p:nNn { abs ( \l__skyrmion_right_ratio_fp ) } < { 0.0001 } }
          {
            \dim_set:Nn \l__skyrmion_left_dim { 0.5\linewidth - 0.5\l__skyrmion_gap_dim }
            \dim_set:Nn \l__skyrmion_right_dim { \l__skyrmion_left_dim }
          }
          {
            \fp_compare:nNnTF { abs ( \l__skyrmion_left_ratio_fp ) } < { 0.0001 }
              {
                \dim_set:Nn \l__skyrmion_right_dim 
                  { 
                    \fp_use:N \l__skyrmion_right_ratio_fp 
                    \dimexpr \linewidth - \l__skyrmion_gap_dim \relax
                  }
                \dim_set:Nn \l__skyrmion_left_dim 
                  { \linewidth - \l__skyrmion_gap_dim - \l__skyrmion_right_dim }
              }
              {
                \dim_set:Nn \l__skyrmion_left_dim 
                  { 
                    \fp_use:N \l__skyrmion_left_ratio_fp 
                    \dimexpr \linewidth - \l__skyrmion_gap_dim \relax
                  }
                \dim_set:Nn \l__skyrmion_right_dim 
                  { \linewidth - \l__skyrmion_gap_dim - \l__skyrmion_left_dim }
              }
          }
      }
      {
        \dim_compare:nNnTF \l__skyrmion_left_dim = \c_zero_dim
          {
            \dim_set:Nn \l__skyrmion_left_dim 
              { \linewidth - \l__skyrmion_gap_dim - \l__skyrmion_right_dim }
          }
          {
            \dim_set:Nn \l__skyrmion_right_dim 
              { \linewidth - \l__skyrmion_gap_dim - \l__skyrmion_left_dim }
          }
      }
  }
\cs_new:Npn \__skyrmion_twopart_save:NN #1 #2
  {
    \hbox_set:Nw #1
    \minipage {#2}
    \setlength{\parindent}{0pt}
  }
\cs_new:Npn \__skyrmion_twopart_end_save:
  {
    \endminipage
    \hbox_set_end:
  }
\cs_new:Npn \__skyrmion_seg: { } % 画线,可以用 tikz 等等
\cs_new:Npn \__skyrmion_twopart_typeset:
  {
    \hbox_to_wd:nn { \linewidth }
      {
        \hbox_set:Nn \l__skyrmion_seg_box { \__skyrmion_seg: }
        \hbox_unpack_drop:N \l__skyrmion_left_box
        \hss \clap { \box_use_drop:N \l__skyrmion_seg_box } \hss
        \hbox_unpack_drop:N \l__skyrmion_right_box
      }
  }

\ExplSyntaxOff

\usepackage{lipsum,amsthm,tcolorbox}
\NewTColorBox { textfig } { O { .64\linewidth } }
  {
    sidebyside, sidebyside gap = .02\linewidth, boxsep = 0pt,
    left = 0pt, right = 0pt, top = 3pt, bottom = 0pt,
    lefthand width = #1, standard jigsaw, opacityback = 0, frame empty
  }
\newtheorem{problem}{Problem}

\begin{document}

\begin{textfig}
  \begin{problem}
    \lipsum[2]
  \end{problem}
  \tcblower
  \centering
  \includegraphics[width = .5\linewidth]{example-image-a}
\end{textfig}

\begin{twopart}[sidebyside gap=.02\linewidth, lefthand width=.64\linewidth]
  \begin{problem}
    \lipsum[2]
  \end{problem}
\twopartsplit
  \centering
  \includegraphics[width = .5\linewidth]{example-image-a}
\end{twopart}

\end{document}

也可以用 coffin,代码是相似的。

一般情况下,如果要实现类似的需求,是交换 1、2 个参数的顺序,或者用不同类型的定界符([] () <> 等)。

也可以用一个特殊的值表示默认值,遇到这个特殊值的时候把它替换为默认值。

\ExplSyntaxOn
\cs_new_protected:Npn \__my_make_default:nnn #1#2#3
  {
    \tl_if_eq:nnTF {#3} {#1}
      { \tl_set:Nn \ProcessedArgument {#2} }
      { \tl_set:Nn \ProcessedArgument {#3} }
  }
\cs_new_eq:NN \TrueDefault \__my_make_default:nnn
\ExplSyntaxOff

\NewDocumentCommand{\cmdt}{ 
  >{\TrueDefault{?}{default1}} O{?} % 如果参数为 ? 就替换为 default1
  >{\TrueDefault{?}{default2}} O{?}
  m
}{%
    \textbf{The result of \texttt{\string\cmdt}:} \par
    optional param1: #1 \par
    optional param2: #2 \par
    mandattory param: #3 \par
}

\cmdt{Explorer}

\cmdt[anaconda][python]{Explorer}

\cmdt[anaconda]{Explorer}

\cmdt[?][python]{Explorer}

猜你想要 lttemplates(即 xtemplate),即将进入 LaTeX2e 内核(不出意外的话是 Released 2024-11-01),目前(2024.10.31)可以使用 xelatex-dev 等 dev 版。

l3keys(包括其它键值宏包)都不会每次没给出键时自动使用默认值,只会使用初始值,但 lttemplates 会。

\documentclass{article}

\ExplSyntaxOn
\quark_new:N \q__skyrmion_mark
\quark_new:N \q__skyrmion_stop
\prg_new_conditional:Npnn \skyrmion_if_item_star:n #1 { TF } % 完全可展的函数
  {
    \str_if_eq:eeTF { \skyrmion_strip_end_star:n {#1} } { \exp_not:n {#1} }
      { \prg_return_false: } % 如果移除掉结尾 * 号之后,两个相同,说明原来没有星号
      { \prg_return_true:  } % 反之,则有
  }
\cs_generate_variant:Nn \skyrmion_if_item_star:nTF { e }
\cs_new:Npn \skyrmion_strip_end_star:n #1 % 完全可展的函数,用 e 展开可得到结果
  { 
    \__skyrmion_strip_end_star:w 
      \prg_do_nothing: #1   \q__skyrmion_mark % 如果 #1 以 * 结尾,就用这个
      #1 * \q__skyrmion_mark % 自己加上 *,如果 #1 不以 * 结尾,就会用这个
      \q__skyrmion_stop 
      {#1} % <- 注意这个
  }
\cs_new:Npn \__skyrmion_strip_end_star:w #1 *\q__skyrmion_mark #2 \q__skyrmion_stop
  {
    \tl_if_empty:nTF {#2} % 如果 #2 为空,说明使用是我们自己加的 *
      { \exp_not:n } % <- 这个保护的是上面带花括号的 {#1}
      { \exp_not:o {#1} \use_none:n } % <- \use_none:n 移除上面的 {#1}
  }
\cs_generate_variant:Nn \skyrmion_strip_end_star:n { e }

\clist_new:N \l__skyrmion_tmp_clist
\NewDocumentCommand \skyrmionif { m }
  {
    \skyrmion_strip_end_star:e { \clist_item:Nn \l__skyrmion_tmp_clist {#1} }
    { ~is~ } % <- TeX 会忽略每行开头的空格,
    \skyrmion_if_item_star:eTF
      { \clist_item:Nn \l__skyrmion_tmp_clist {#1} }
      { True } { False }
  }
\clist_set:Nn \l__skyrmion_tmp_clist
  { explorer, fishrows*, eureka, admin, skyrmion }
\ExplSyntaxOff

\begin{document}

\skyrmionif{1}

\skyrmionif{2}

\ExplSyntaxOn \cs_generate_variant:Nn \tl_to_str:n { e } \ttfamily
\tl_to_str:e { \skyrmion_strip_end_star:n { fishrows* } } |
\tl_to_str:e { \skyrmion_strip_end_star:n { {}* } } |
\tl_to_str:e { \skyrmion_strip_end_star:n { {} } } |
\tl_to_str:e { \skyrmion_strip_end_star:n {   * } } |
\ExplSyntaxOff

\end{document}

如果设置了 BoldFontItalicFontxeCJK 不会再使用伪粗体。而 ctex 为预定义的字体都设置了这两个键,因此后续的修改无效。只需重新定义 xeCJKBoldFontItalicFont 这两个键即可。

必须在加载 ctex 之前就加载 xeCJK,或者用 \PassOptionsToPackage,否则设置的 xeCJK 宏包选项无效。

\documentclass{article}

\PassOptionsToPackage{AutoFakeBold=3.0}{xeCJK}
\ExplSyntaxOn
\AddToHook{package/ctex/before}{
  \AddToHook{package/xeCJK/after}{
    \keys_define:nn { xeCJK / features }
      { BoldFont .code:n = , ItalicFont .code:n = }
  }
}
\AddToHook{package/ctex/after}{
  \keys_define:nn { xeCJK / features }
    {
      BoldFont .tl_set:N = \l__xeCJK_font_name_bf_tl ,
      ItalicFont .tl_set:N = \l__xeCJK_font_name_it_tl
    }
}
\ExplSyntaxOff
\usepackage[UTF8]{ctex}
\usepackage{fontspec}

\begin{document}

我上{\bfseries 早八}

\CJKfontspec[BoldFont=FandolHei, ItalicFont=FandolKai]{FandolSong}
我上{\bfseries 早八}

\end{document}

只可用 xelatex 编译。

也可把这两个键定义为使用 AutoFakeBoldAutoFakeSlant 等。

\makeatletter\ExplSyntaxOn
\clist_new:N \g__my_packages_clist
\int_new:N \g__my_level_int
\AddToHook{package/before}{\int_gincr:N \g__my_level_int}
\AddToHook{package/after}{
  \int_gdecr:N \g__my_level_int
  \int_compare:nNnT \g__my_level_int = { 0 }
    { \clist_gput_right:Nx \g__my_packages_clist { \@currname } }
}
\AddToHook{enddocument/info}{ \tl_show:e { Packages:~ \g__my_packages_clist } }
\ExplSyntaxOff\makeatother

\documentclass{} % <- 改成你的文档类
\begin{document}
\end{document}

然后在终端中正常编译。这样可以列出使用的文档类中直接加载的宏包(不包括它们依赖的宏包,如果需要,把代码中的 level=0 改成其它值,或直接删去即可),也会包含这个文档在导言区加载的宏包(这里没有)。

如果不是用 xelatex 编译的,最后一个加载的宏包可能是 epstopdf-base,这是 LaTeX 自动加载的,直接忽略即可。

用通用命令钩子 \AddToHook{cmd/<document cmd>/before}{<write to aux>} 在需要判断是否在正文使用了的命令前加上一段代码,在辅助文件中写入一些标记,然后在 begindocument 钩子(或 \AtBeginDocument,或 begindocument/after 钩子)判断是否有此标记,然后根据需要重定义命令即可。

发布
问题