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

注册于 5年前

回答
252
文章
2
关注者
25

\documentclass[tikz,border=5pt]{standalone}
\usepackage{tkz-euclide}

\ExplSyntaxOn\makeatletter
\pgfmathdeclarefunction{pointveclen}{3}{
  \begingroup
  \tikz@scan@one@point\pgfutil@firstofone(#1)\relax
    \pgf@xx\pgf@x \pgf@xy\pgf@y
  \tikz@scan@one@point\pgfutil@firstofone(#2)\relax
    \pgf@yx\pgf@x \pgf@yy\pgf@y
  \pgfmathparse{veclen(\the\pgf@xx+#3\the\pgf@yx,\the\pgf@xy+#3\the\pgf@yy)}
  \pgfmath@smuggleone\pgfmathresult
  \endgroup
}
\NewDocumentCommand\tkzAutoLabelPolygons{O{} r()} {
  \group_begin:
  \seq_gclear:N \g_tmpa_seq
  \foreach \x in {#2} { \seq_gput_right:Ne \g_tmpa_seq { \x } }
  \seq_get_left:NN \g_tmpa_seq \l_tmpa_tl
  \seq_get_right:NN \g_tmpa_seq \l_tmpb_tl
  \seq_gput_left:NV \g_tmpa_seq \l_tmpb_tl
  \seq_gput_right:NV \g_tmpa_seq \l_tmpa_tl
  \int_step_inline:nnn { 2 } { \seq_count:N \g_tmpa_seq - 1 }
    {
      \seq_gpop_left:NN \g_tmpa_seq \l_tmpa_tl
      \tl_set:Ne \l_tmpb_tl { \seq_item:Nn \g_tmpa_seq { 1 } }
      \tl_set:Ne \l_tmpc_tl { \seq_item:Nn \g_tmpa_seq { 2 } }
      \pgfinterruptboundingbox
      \coordinate (tempa) at ($1cm/pointveclen("\l_tmpa_tl","\l_tmpb_tl","-")
        *($(\l_tmpa_tl)-(\l_tmpb_tl)$)$);
      \coordinate (tempb) at ($1cm/pointveclen("\l_tmpc_tl","\l_tmpb_tl","-")
        *($(\l_tmpc_tl)-(\l_tmpb_tl)$)$);
      \coordinate (tempc) at ($0.3*1cm/pointveclen("tempa","tempb","+")
        *($(tempa)+(tempb)$)$);
      \endpgfinterruptboundingbox
      \path (\l_tmpb_tl) -- ($(\l_tmpb_tl)-(tempc)$)
        node[label~style,anchor=center,#1] {$\l_tmpb_tl$};
    }
  \group_end:
}
\ExplSyntaxOff\makeatother

\begin{document}

\begin{tikzpicture}
  \tkzDefPoints{-1/-1/A, 1/-2/B, 3/0/C, 2/4/D, 0/5/E,-3/2/F}  
  \tkzDrawPolygons[thick](A,...,F)
  \tkzAutoLabelPolygons(A,...,F)
\end{tikzpicture}

\begin{tikzpicture}
  \tkzDefPoints{-1/-1/A, 1/-2/B, 0.5/0/C, 2/4/D, 0/5/E,-3/2/F}
  \tkzDrawPolygons[thick](A,...,F)
  \tkzAutoLabelPolygons(A,...,F)
\end{tikzpicture}

\end{document}

image.png

见 The TeXBook 第 258 页(2021 年版),The LaTeX Companion 第三版 5.3.4、5.3.5 节。

TeX 遇到某些内容和输出这些内容所在的页码并不一定相同,比如,TeX 在准备第 5 页所需的内容时遇到太多文字,直到第 5 页输出完成后才能知道哪些文字是多余的,然而它们是在第 5 页中发现的,却并不是在第 5 页输出的,这就存在某些问题,比如假如这些多出来的文字中获取了 page 计数器的值,由于它在第 5 页中执行,得到的结果是 5,而不是 6。TeX 为了解决这个问题提供了几个方案,一个是把要获取的这些值延迟到页面输出完成之后再获取,另一个就是 mark 机制。

firstmark 就是输出的那一页最开始遇到的 mark,botmark 就是最后遇到的 mark,topmark 就是上一页的 botmark。最开始的 TeX 只有一个 mark 类,e-TeX 扩展为了 32767 个。

如果你用 LaTeX 2022-06-01 及之后的版本,那么 LaTeX 提供了 \FirstMark \LastMark \TopMark,并且不但能获得当前页的,还能获得上一页、当前栏、上一栏的。建议使用这些命令。如果用的是 2025-06-01 的版本,还能获得 multicols 每一栏的 marks。

不过,如果 marks 出现在其它盒子中,那么 TeX 无法正确更新,可以用我写的 updatemarks 宏包。

\changetext 的修改是局部的,而 shipout 钩子总是放在一个组中执行,必须要全局修改。

\AddToHookNext{shipout}{\global\advance\textheight2cm\relax}

不过,如果修改 \textheight 正好发生在 paracol 环境中间,是无效的,原因未知。

设置 TEXINPUTS 环境变量,.tex .sty 这类文件都在 $TEXMF/tex// 目录里查找,而 TeX 文档的位置在 $TEXDOCS$TEXMF/doc//) 这个变量里(texmf.cnf 的变量,不是环境变量)。

cmd:
set TEXINPUTS=;$TEXDOCS

powershell:
$env:TEXINPUTS=';$TEXDOCS'

不过最好不要设置 $TEXDOCS 来编译文档,因为这里的目录包含许多配置文件(比如 hyperref.cfg,你设置上面的环境变量再用 xelatex 编译就会发现报错),会出现什么完全不能预测。
可以先修改 TEXINPUTS 然后用 kpsewhich 找到所需的文件,只用特定目录一般问题不大:

set TEXINPUTS=;$TEXDOCS
kpsewhich lshort-zh-cn-style.sty
% 注意要先清除
set TEXINPUTS=
set TEXINPUTS=;$TEXMFDIST/doc/latex/lshort-chinese//
xelatex main.tex

可以查看 texdoc kpathsea 文档了解更多内容。

xecjk 会在 cjk 文字之间插入 \CJKglue,这个值一般为 \hskip 0pt plus 0.08\baselineskip,这个 stretch 比较小,一般小于 1em,在宽度为 3em 时,两个汉字间需要插入的空白大于 cjkglue 的伸长部分,所以会报 warning。

英文空格会变成一个 glue,根据需要会使用 \spaceskip\xspaceskip;xecjk 的中文与西文之间会插入 \CJKecglue,都可以用于控制所插入的空白的 stretch 和 shrink。

CJKfilltwosides 就调整了 \CJKglue,使得空白可以无限伸长。

X-Y problem?
你想要的是在两个字符中间插入任何东西,只要这些字符连同它中间的东西一共是三个字符的宽度就行?还是要保证不论输入几个字符,总宽度固定就行?还是不论输为何,其最终结果是两个汉字,然后在两个汉字中间插入 \quad?还是就是给定两汉字,中间插入 \quad

这几个问题难度不同,解决办法可以说是完全不同。最简单就是第四个,这种你可以直接写 \newcommand\mycmd[2]{#1\quad#2}\mycmd 余华。对于第一个问题还可以还可以看 xecjk 的文档,它有分散对齐汉字的环境。

无需任何宏包:

\documentclass{article}

\makeatletter
\def\@zheng@i{\vrule height2ex depth-1.8ex width2ex\relax} % U+1D372
\def\@zheng@ii{\@zheng@i\kern-2ex\hbox to2ex
  {\hfil\vrule height2ex depth-.2ex width.2ex\hfil}} % U+1D373
\def\@zheng@iii{\@zheng@ii\kern-1ex\hbox to1ex
  {\vrule height1.1ex depth-0.9ex width0.8ex\hfil}} % U+1D374
\def\@zheng@iv{\@zheng@iii\kern-2ex\hbox to2ex
  {\hskip 0.3ex\vrule height1.3ex depth-0.2ex width0.2ex\hfill}} % U+1D375
\def\@zheng@v{\@zheng@iv\kern-2ex\vrule height0.2ex width2ex\relax} % U+1D376
\protected\def\@zheng#1{%
  \edef\x{\ifcase#1 \or\noexpand\@zheng@i\or\noexpand\@zheng@ii\or\noexpand\@zheng@iii
    \or\noexpand\@zheng@iv\or\unexpanded{\@zheng@format{\@zheng@v}}%
    \else\unexpanded{\@zheng@format{\@zheng@v}\zheng{#1-5}}\fi}\x}
\protected\def\zheng#1{\leavevmode\expandafter\@zheng\expandafter{\the\numexpr#1}}
\long\def\@zheng@format#1{\mbox{#1}\ }
\protected\long\def\zhengformat#1{\long\def\@zheng@format##1{#1}}
\makeatother

\begin{document}

12345 \zheng{1} \zheng{2} \zheng{3} \zheng{4} \zheng{5}

12345 \zheng{1}\zheng{2}\zheng{3}\zheng{4}\zheng{5}

6 \zheng{6}

horizontal 42:
\zhengformat{\mbox{#1}\ }
\zheng{42}

vertical 42:
\zhengformat{\mbox{#1}\\}
\begin{tabular}[t]{c}
\zheng{42}
\end{tabular}

\end{document}

image.png

有的字体比如 Noto Unicode、霞骛文楷、Plangothic P1 等有这些字形,下载这些字体后直接用 \fontspec{..} \symbol{"1D372} 即可。

\documentclass[UTF8]{ctexart}%pdflatex编译
\usepackage[showframe,margin=1in]{geometry}
\usepackage{enumitem}
    \setlist[enumerate]{nosep,labelsep=0pt,leftmargin=2em}
\usepackage{multicol}
    \setlength{\columnseprule}{.4pt}
    \setlength{\columnsep}{1cm}

\makeatletter
\newcommand\brule[3][\z@]{\leavevmode
  {\setlength\@tempdima{#2}\setlength\@tempdimb{#1}\setlength\@tempdimc{#3}%
   \@tempcnta=\fpeval{ceil(\@tempdima/5pt)}
   \kern\z@
   \loop\ifnum\@tempcnta>\z@
     \vrule \@width 5pt \@height \@tempdimc \@depth -\@tempdimb \hskip\z@skip
     \advance\@tempcnta\m@ne
   \repeat \unskip
}}
\makeatother
\begin{document}

\noindent\textbf{16. }补写出下列句子中的空缺部分。(6分)

\begin{multicols}{2}

\begin{enumerate}[label=(\arabic{enumi})]
    \item 
    王湾《次北固山下》的名句“\brule{9em}{.4pt},\brule{9em}{.4pt}”,描写时序交替中的景物,暗示着时光流逝,蕴含着自然理趣。
    \item 
    小慧为朋友家的农家乐餐厅写宣传横幅,直接使用了陆游《游山西村》里的“\brule{9em}{.4pt},\brule{9em}{.4pt}”两句诗,朋友看了觉得很贴切。
    \item 
    行至群山深处,见到一挂瀑布飞泻而下,水石激荡,轰鸣作响,于老师回头对学生们说:“这不就是古诗中写的‘\brule{9em}{.4pt},\brule{9em}{.4pt}’嘛!”
\end{enumerate}

\end{multicols}

\noindent\textbf{参考答案:}

\begin{enumerate}[label=(\arabic{enumi})]
    \item 
    海日生残夜\quad 江春入旧年
    \item 
    山重水复疑无路\quad 柳暗花明又一村
    \item 
    飞流直下三千尺\quad 疑是银河落九天(飞湍瀑流争喧豗\quad 砯崖转石万壑雷)
\end{enumerate}

\end{document}

image.png

略微改进版:

\newcommand\brule[3][\z@]{\leavevmode
  {\setlength\@tempdima{#2}\setlength\@tempdimb{#1}\setlength\@tempdimc{#3}%
   \@tempcnta=\fpeval{ceil(\@tempdima/5pt)} \@tempdima=\dimexpr5pt/\@tempcnta\relax\relax
   \ifnum\@tempcnta>\z@
     \loop\ifnum\@tempcnta>\z@
       \vrule \@width 5pt\@height\@tempdimc \@depth-\@tempdimb \hskip\z@\@minus\@tempdima\relax
       \advance\@tempcnta\m@ne
     \repeat
   \unskip\fi
}}

  1. 这是手动创建命令钩子,如果命令钩子不存在,在向此钩子添加代码时,会执行自动修补。所以,为了不让它执行自动修补,必须创建钩子。我贴的图片没有加上创建钩子的代码,需要补充。
  2. 随便在哪用都行。
  3. 见 1。

image.png

使用尾递归即可,这是比较常见的处理方式,\tl_map_.. 也是用尾递归实现的。

\documentclass{article}
\ExplSyntaxOn
\cs_new:Npn \__MyCMD_deal:n #1
  {
    output: #1 \par %伪应用
  }

\quark_new:N \q__MyCMD_stop
\NewDocumentCommand{\__MyCMD_deal_newversion:nw}{+m+O{}}
  {
    \tl_if_eq:nnF {#1} { \q__MyCMD_stop }
      {
        output: #1 ~ option: #2 \par %伪应用
        
        \__MyCMD_deal_newversion:nw
      }
  }
\NewDocumentCommand{\MyCMD}{+m}
  {
    \__MyCMD_deal_newversion:nw #1 \q__MyCMD_stop []
  }
\ExplSyntaxOff

\begin{document}
\MyCMD{{par 1}{par 2}{par 3}}

\MyCMD{{par 1}{par 2}}

\MyCMD{{par 1}[opt 1]{par 2}[opt 2]{par 3}[opt 3]}

\MyCMD{{par 1}[opt 1]{par 2}{par 3}[opt 3]}

\MyCMD{{par 1}[opt 1]{par 2}[opt 2]}

\MyCMD{{par 1}{par 2}[opt 2]{par 3}}
\end{document}

由于不需要可展的实现,可以用 \tl_if_eq:nn 比较,无需可展的 \quark_if_..,这样更快。

这三个命令在文档中说的是可以用在处理键的代码中,在其它地方使用显然是未定义行为。包括那些 undocumented 命令,都由使用者自己负责。

首先,context 没有你给的那些命令行参数。
其次,TeXLive 2025 的 ConTeXt 默认用的是 LuaMetaTeX,它不带 kpathsea 库,所有的第三方模块都必须手动安装(包括 tikz、pgfplots 等),否则就会找不到相关文件,用 LuaTeX 的版本才行。因为我没有 TeX Studio,不知道你是如何成功编译的。不过你可以查看输出的 PDF 文件,看看究竟是哪个版本。
最后,LaTeX Workshop 需要找到主文件(即 root file,见 https://github.com/James-Yu/LaTeX-Workshop/wiki/Compile#the-root-file),主要是找到 \documentclass 这个命令,这在 ConTeXt 中是没有的。

只要解决上面这三个问题就行了。
修改 setting.json

{
    "latex-workshop.latex.tools": [
        {
            "name": "context-luatex",
            "command": "context",
            "args": [
                "--synctex",
                "--nonstopmode",
                "--luatex",
                "%DOC%"
            ],
            "env": {}
        },
    ],
    "latex-workshop.latex.recipes": [
        {
            "name": "context (luatex)",
            "tools": [
                "context-luatex"
            ]
        },
    ]
}

然后用 magic comment 设置主文件(注意第一行):

% !TEX root = main.tex
%命令行编译: context --luatex main
\usemodule[tikz]
\startTEXpage[offset=2pt]
\def\mygrid#1{
    \fill [gray!60]     (0,0) rectangle (#1,#1);
    \draw [white,thick] (0,0) grid      (#1,#1);
    \foreach \x in {1,...,#1}
    {
        \node at (0,\x) [left]       {$\x$};
        \node at (\x,0) [below]      {$\x$};
    }
        \node at (0,0)  [below left] {$0$};
}
\starttikzpicture[every node/.append style={scale=.5}]
\mygrid{3}
\stoptikzpicture

\CONTEXT{} -- \LUATEX

\stopTEXpage

然后点击 context (luatex) 即可。
image.png

可能是 xetex 的驱动文件有问题。asymptote 支持输出为 PDF,用 PDF 文件就好了。

case 1 是可以正常输出的,需要指定 \usepackage[encoding=gbk]{zhlipsum}

%%% 文件编码为 GBK!
\documentclass[GBK]{ctexart}
\usepackage{lipsum}
\usepackage[encoding=gbk]{zhlipsum}
\begin{document}

现代社会以海德格尔的一句“一切实践传统都已经瓦解完了”为嚆矢。滥觞于家庭与社会传统的期望正失去它们的借鉴意义。
但面对看似无垠的未来天空,我想循卡尔维诺“树上的男爵”的生活好过过早地振翮。我们怀揣热忱的灵魂天然被赋予对超越性的追求,不屑于古旧坐标的约束,钟情于在别处的芬芳。

\lipsum[1]

\zhlipsum[1]

\end{document}

case 2、3、4 都是同一个问题,TeX 不能正确解码 GBK 编码或 UTF8 编码的 bytes 为 Unicode Scalar Value。
可分别观察如下 python 代码的结果:

>>> b'\xd2\xbb'.decode('utf8')
'һ'   ### 看看 case 3 的错误日志
>>> b'\xd2\xbb'.decode('gbk')
'一'
>>> '\ufffd\ufffd'.encode('utf8')
b'\xef\xbf\xbd\xef\xbf\xbd'
>>> '\ufffd\ufffd'.encode('utf8').decode('gbk')
'锟斤拷'

同一段 bytes 以不同的方式解码得到的是不同的 Unicode Scalar Value。如果一段 bytes 可以以 GBK 解码但不能以 UTF8 解码,就会得到错误,反之亦然。如果可以以两种方式解码,那看到的 Unicode Scalar Value 也大概率不是一样的,ASCII 除外。
TeX 看到的总是 bytes,人看到的是 Unicode Scalar Value,如果字体里没有某些 Unicode Scalar Value 的字形,就不能在 PDF 中显示。

对于 case 2,由于 zhlipsum 分别制作了 gbk 和 utf8 两个文件用来保存假文,所以,在这些文件中,文件的编码和 bytes 是匹配的,并且在 case 2 中,总是使用 utf8 这个文件,TeX 也总以 utf8 解码,所以不论 main 文件编码为何,TeX 总能读出假文正确的 Unicode Scalar Value。而 main 文件由于文件编码和解码方式不同,TeX 不能正确读取(解码)。

现在如果有 GBK 编码的 TeX 文件,最好的办法应该是统一转为 UTF8 编码,然后使用 CTeX-kit 默认的编码方式。

发布
问题