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

注册于 4年前

回答
234
文章
2
关注者
24

这类问题总是可以通过把必要的信息写入到辅助文件中解决。

\documentclass{article}
\usepackage[many]{tcolorbox}
\newcounter{problem}
\newcounter{solution}

\makeatletter
\protected\def\solutionwriteaux{\immediate\write\@auxout{%
  \global\string\@namedef
  {solution@count@of-\number\value{problem}}{\number\value{solution}}}}
\def\solutionmaxcount{\@ifundefined{solution@count@of-\number\value{problem}}
  {1}{\@nameuse{solution@count@of-\number\value{problem}}}}
\def\thesolutionornone#1{\ifnum\number\solutionmaxcount>\@ne #1\thesolution\fi} % #1: sep
\makeatletter

\newcommand*{\Problem}[1]{%
    \setcounter{solution}{0}
    \refstepcounter{problem}%
    \begin{tcolorbox}[enhanced,title={\bfseries Problem~\theproblem},colframe=magenta!80!white,colback=magenta!20!white]
        #1
    \end{tcolorbox}    
}
\newcommand*{\Solution}[1]{%
    \refstepcounter{solution}%
    \solutionwriteaux        % <- 这里写入辅助文件
    \begin{tcolorbox}[enhanced,
      title={\bfseries Solution~\theproblem \thesolutionornone{-}}, % <- 检查是否多于一个
      colframe=cyan!80!white,colback=cyan!20!white]
        #1
    \end{tcolorbox}    
}
\begin{document}
    \Problem{This is the problem statement.}
    
    \Solution{This is the first solution of the problem}
xi
    \Problem{This is another problem but two solution multiple line.}

    \Solution{This is the second solution.}
    
    \Solution{This is the second solution.}

    \Problem{This is another problem balabalabala}

    \Solution{This is the only solution}

    \Problem{This is another problem balabalabala}
\end{document}

这同时需要 PDF 文件具有某些特殊标记(即 “Tagged”),以及特定的阅读器的支持才能实现。

在 LaTeX 端,由 tagpdf 宏包提供支持,可参考它的文档了解用法,不过它目前还处于实验性的阶段,而且对 XeTeX 的支持不太好。近些年的 LaTeX 大版本更新都提到了 “LaTeX Tagged PDF” 这个项目,就是用来干这个事情的。

经过我的测试,目前(在 Windows 平台)只有 Adobe Acrobat DC(Adobe 的其它阅读器也可能支持)、Drawboard PDF(据我所知,它使用 PDFKit 库,所以,任何使用这个库的阅读器应该也支持,没有测试)支持这个功能,包括 SumatraPDF、福昕 PDF 阅读器等在内的都不支持。可以用某个阅读器打开前面提到的 tagpdf.pdf 这个文件,然后随意复制一段文字用来测试是否支持这个功能。

默认情况下,LaTeX 的目录由 l@<title> 输出,<title> 就是 chapter section 这些,其中 part chapter section 都定义了自己的 l@..,而 subsection 及其子标题都使用 \@dottedtocline,区别是设置不同的参数。查看 mcmthesis 2024/01/22 v6.3.3 源码发现,它并没有修改这一行为。

因此只需在导言区加上

\makeatletter
\@namedef{@level1@space}{10pt} % section
\@namedef{@level2@space}{10pt} % subsection
\@namedef{@level3@space}{0pt} % subsubsection
\long\def\sectionvspace#1{\addvspace{\@nameuse{@level1@space}}}
\patchcmd\l@section{\addvspace}{\sectionvspace}{}{\ERR}     % section
\long\def\dottedvspace#1#2#{\nointerlineskip \vskip-\parskip \vskip\@nameuse{@level#1@space}\relax}
\patchcmd\@dottedtocline{\vskip}{\dottedvspace{#1}}{}{\ERR} % subsection
\makeatother

浮动体的位置直到 output routine 时才会确定,(浮动的)浮动环境只是把它的内容保存到盒子里,此时,LaTeX 默认的实现是不会保存当前设置的各种间距的,这些间距直到 output routine 时才会使用,因此,局部设置地设置这些间距一般都无效。既然说了是 LaTeX 的默认实现,那自然可以自定义,不过,麻烦、工作量大、与其它宏包兼容性不好(比如涉及到 output routine 的 longtable multicol paracol lineno,还有和浮动体有关的宏包 caption float placeins newfloat,等等),而且 LaTeX 也没有提供方便的方法修改 output routine 以及排布浮动体的算法。

很多时候并不需要让内容浮动,只需要一个 center 环境、一个和浮动体共享计数器的命令(直接 \let\c@myfigure\c@figure,就能够让 myfigurefigure 共享计数器了,不过这样并不共享格式),以及 caption 宏包的 type 键。

同样是在这个链接的评论里提到,

为了使得 robust cmd 达到应有的效果,必须使用这几个 \protected@ 开头的命令,而 protected 宏则没有这个要求。

因为 \label@optarg 在第一次展开 \thepage 时用的是 \edef,而不是 \protected@edef,只有后者才能保护 \protect 宏。问题就在于此。

由于 LaTeX 内核用 begindocument 钩子 patch 了 cleveref 的几个命令,\label@optarg 恰好在其中,所以自己 patch 也必须使用这个钩子才行。可查看 latex2e-first-aid-for-external-files.pdf 这个文件了解 patch 了哪些命令。

默认情况下,每页底部的文字都是对齐的,但不可能恰好每页文字的长度都一样,所以那些可以伸缩的空白就会根据需要而伸长或缩短。

你的这种情况可以设置章节标题前后的间距为固定长度,而不是弹性长度,或者不设置每页底部文字对齐。
前者可以通过 ctex 文档类或 titlesec 等提供的接口修改,后者只需在 \begin{document} 之前加上 \raggedbottom

不是没起作用,而是 env/../beforeenv/../after 钩子的内容是在当前组中执行的,这里的 \bfseries 对整篇文档都生效,而不是只对 quote 环境生效。环境开始时会添加 \begingroupbefore 钩子在这个 \begingroup 之前执行,begin 钩子在这个 \begingroup 之后执行。因此 env/../beginenv/../end 钩子才是和环境的内容在同一个组。这些在文档 lthooks-doc 的 3.1.1 节有描述。

报错里看到 \test.. 展开为了 inner sep=2 不代表 \node 读取键时看到了 \test.. 展开后的结果,读取键时可能展开,也可能不展开,完全取决于实现。比如 \keys_set:nn 就不会展开键,\keys_set:ne 就会先展开第二个参数,再读取键。实际使用时不应当依赖于这一行为,如果没有特殊说明,总是应当认为既可能展开,又可能不展开,这样才能减少出错的概率。

先保存到盒子里就好了。

\newbox\mynotebox
\newenvironment{mynote}
{%
    \begin{center} % 开始居中环境
        \begin{lrbox}{\mynotebox} %% <- 这里
        \begin{minipage}{0.9\textwidth} % 设置内容宽度为页面的 90%
            \small\itshape % 设置内容为小字号和斜体
            
}
{
        \end{minipage} % 关闭 minipage
        \end{lrbox}%
        \fbox{\box\mynotebox}
    \end{center} % 
}

XeTeX 支持 ttf、ttc、otf、otc 这四个 opentype 字体,应该不支持 TTE 字体。

𬬺(U+2CB3A)在扩展 E 区,SimSun-ExtB 支持这个字形,不过可能有版权问题。开源方案有:宋体字形,比如文津宋体 https://github.com/takushun-wu/ 。黑体字形,比如 Plangothic https://github.com/Fitzgerald-Porthmouth-Koenigsegg/Plangothic_Project 。支持的字符都比较全。还有中华书局宋体、TH-Tshyn 等字体,不过也可能有版权问题。

可以在字统网上查找字形 https://zi.tools/?secondary=ids
image.png
可以查到已经在 Unicode 里的字符,不在 Unicode 里的,也会给出组字的结果。如果不满意的话可以到 https://zhs.glyphwiki.org/wiki/GlyphWiki 里进一步编辑,保存 png 或者 svg 都可以。

我在 ubuntu 20.04 上编译没有问题。

执行 kpsewhich cmunrm.otf 看结果是什么,如果没有就是字体没装。
如果有,执行 sudo fc-cache -fsv 刷新字体缓存试试。

改成这样:

\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 已经被展开了,它的值已经固定。

发布
问题