\xbar
我使用以下命令在字母下方放置任意数量的特殊粗条( )。
\documentclass[prb,preprint]{revtex4-1}
\usepackage{stackengine}
\stackMath
\newcommand*\xbar[1]{% this command creates a specialized, thick bar
\hbox{%
\vbox{%
\hrule height 0.7pt %
\kern0.5ex%
\hbox{%
\kern-0.3em%
\ensuremath{#1}%
\kern-0.3em%
}%
}%
}%
}
\newcommand\xbarsbelow[2][1]{% draws n \xbar's below the given symbol
\def\useanchorwidth{T}
\ifnum#1>1
\stackunder[-5pt]{\xbarsbelow[\numexpr#1-1\relax]{#2}}{\xbar{\,\,\quad}}
\else
\stackunder[2pt]{#2}{\xbar{\,\,\quad}}
\fi
}
\newcommand\simplebars[2][1]{% same as \xbarsbelow, but uses the \bar symbol
\def\useanchorwidth{T}
\ifnum#1>1
\stackunder[-5pt]{\simplebars[\numexpr#1-1\relax]{#2}}{\bar{}}
\else
\stackunder[2pt]{#2}{\bar{}}
\fi
}
\begin{document}
$\xbarsbelow[5]{A}$, $\simplebars[5]{A}$
\end{document}
命令\xbarsbelow
和\simplebars
相同,只是前者使用\xbar
,而后者使用\bar
。
然而,当我使用时\xbarsbelow[5]{A}
,它只在字母 A 下方绘制 2 条, 而\simplebars[5]{A}
会绘制全部 5 条。
答案1
你的问题很简单。\bar
(6.77774pt) 和\xbar
(3.28333pt) 的垂直高度不同。因此,当你\stackunder
使用它们时,实现你的外观所需的间隙大小需要不同。因此,只需更改定义[-5pt]
中的间隙\xbarsbelow
即可[-1.65pt]
修复结果。
用作[-5pt]
堆叠间隙\bar
挤出了 6.77774pt 带来的一些多余垂直空间\bar
。但是,\xbar
占用的垂直空间较少,实际上不到 5pt。因此,使用[-5pt]
垂直间隙进行连续填充\xbarsbelow
会占用过多的垂直空间。 本质上,你是将每一个连续的元素放置\xbarbelow
在前一个元素的上方。
\documentclass[prb,preprint]{revtex4-1}
\usepackage{stackengine}
\stackMath
\newcommand*\xbar[1]{% this command creates a specialized, thick bar
\hbox{%
\vbox{%
\hrule height 0.7pt %
\kern0.5ex%
\hbox{%
\kern-0.3em%
\ensuremath{#1}%
\kern-0.3em%
}%
}%
}%
}
\newcommand\xbarsbelow[2][1]{% draws n \xbar's below the given symbol
\def\useanchorwidth{T}
\ifnum#1>1
\stackunder[-1.65pt]{\xbarsbelow[\numexpr#1-1\relax]{#2}}{\xbar{\,\,\quad}}
\else
\stackunder[2pt]{#2}{\xbar{\,\,\quad}}
\fi
}
\newcommand\simplebars[2][1]{% same as \xbarsbelow, but uses the \bar symbol
\def\useanchorwidth{T}
\ifnum#1>1
\stackunder[-5pt]{\simplebars[\numexpr#1-1\relax]{#2}}{\bar{}}
\else
\stackunder[2pt]{#2}{\bar{}}
\fi
}
\begin{document}
$\xbarsbelow[5]{A}$, $\simplebars[5]{A}$
\end{document}
答案2
无堆栈的实现。可选参数用于对条形宽度进行微调。
\documentclass{article}
\usepackage{amsmath}
\usepackage{expl3} % for \prg_replicate:nn
\makeatletter
\newcommand{\xbarsbelow}[3][1]{%
% #1 = kerning
% #2 = repetitions
% #3 = symbol to underbar
\sbox\z@{$\m@th\mkern-#1mu #3\mkern-#1mu$}%
\mkern#1mu
\vtop{\box\z@\replicate{#2}{\kern0.7pt\hrule height 0.7pt\relax}}
\mkern#1mu
}
\makeatother
\ExplSyntaxOn
\cs_new_eq:NN \replicate \prg_replicate:nn
\ExplSyntaxOff
\begin{document}
\begin{gather*}
A+\mathrm{A} \\
\xbarsbelow{5}{A}+\xbarsbelow[0]{3}{\mathrm{A}}
\end{gather*}
\end{document}
答案3
我不能完全确定您的\xbarsbelow
宏为什么不起作用,因为它几乎与 完全相同\simplebars
,而 确实可以工作。我怀疑问题出在您使用的方式上,\numexpr
因为正如我将在下面展示的那样,所有内容的扩展都很晚。
解决正在发生的问题的一种方法是添加以下命令:
\typeout{xbarsbelow: 1=#1, 2=#2.}
添加到宏中。在这种情况下,你会看到类似
xbarsbelow: 1=\numexpr \numexpr \numexpr 5-1\relax -1\relax -1\relax, 2=A.
在您的日志文件中(或在命令行中),这可能不是您想要的。使用\the\numexpr#1-1\relax
会产生更好的输出结果, \typeout{...}
但不能解决问题。
相反,我建议使用它\stackunder
来控制你的递归:
\newcommand\xbarsbelow[2][1]{% draws n \xbar's below the given symbol
\def\useanchorwidth{T}% not sure what this does?
\ifnum#1>1%
\rlap{\stackunder[\the\dimexpr2pt*#1\relax]{\phantom{#2}}{\xbar{\,\,\quad}}}%
\xbarsbelow[\the\numexpr#1-1\relax]{#2}
\else%
\stackunder[2pt]{#2}{\xbar{\,\,\quad}}%
\fi%
}
这样就产生了所需的输出。诀窍是使用\rlap{...}
它,粗略地说,打印一些内容“而不移动光标”。事实上,如果你采用这种方法,你甚至不需要使用stackengine
,而只需使用它\rule
来绘制线条:
\newcommand\xbarsbelow[2][1]{% draws n \xbar's below the given symbol
\ifnum#1>0%
\rlap{\rule[\the\dimexpr-2pt*#1\relax]{1em}{0.8pt}}%
\xbarsbelow[\the\numexpr#1-1\relax]{#2}% recursion
\else%
\rlap{\hbox to 1em{\hfil$#2$\hfil}}%
\hspace*{1em}%
\fi%
}
另一个选项是使用tikz
,这是我\newbars
下面代码中的宏所做的。此命令采用第二个可选参数来指定条形的宽度。不过,\xbarsbelow
基于的版本\rule
更简单,因此可能更可取——您可以以完全相同的方式向其添加可选的宽度命令。
在此处您可以生产:
使用 MWE:
\documentclass[prb,preprint]{revtex4-1}
\usepackage{stackengine}
\stackMath
\newcommand*\xbar[1]{% this command creates a specialized, thick bar
\hbox{%
\vbox{%
\hrule height 0.7pt %
\kern0.5ex%
\hbox{%
\kern-0.3em%
\ensuremath{#1}%
\kern-0.3em%
}%
}%
}%
}
\usepackage{xparse}
\usepackage{etoolbox}
\usepackage{tikz}
% usage: \newbar{A} or \newbar[3]{A} or \newbar[3](2em){A} or \newbar(2em){A}
\NewDocumentCommand\newbar{ O{1} D(){1.0em} m }{%
\tikz[baseline=(text.base)]{\node (text) at (0,0){#3};
\foreach \li [evaluate=\li as \y using (-0.1-0.08*\li)] in {1,...,#1}{
\draw[thick](-#2/2,\y)--++(#2,0);
}
}%
}
\newcommand\xbarsbelow[2][1]{% draws n \xbar's below the given symbol
\ifnum#1>0%
\rlap{\rule[\the\dimexpr-2pt*#1\relax]{1em}{0.8pt}}%
\xbarsbelow[\the\numexpr#1-1\relax]{#2}% recursion
\else%
\rlap{\hbox to 1em{\hfil$#2$\hfil}}%
\hspace*{1em}%
\fi%
}
\newcommand\simplebars[2][1]{% same as \xbarsbelow, but uses the \bar symbol
\def\useanchorwidth{T}%
\ifnum#1>1%
\stackunder[-5pt]{\simplebars[\the\numexpr#1-1\relax]{#2}}{\bar{}}%
\else%
\stackunder[2pt]{#2}{\bar{}}%
\fi%
}
\begin{document}
$\xbarsbelow[5]{A}$, $\simplebars[5]{A}$
$\newbar[5]{A}$
$\newbar[5](2em){A}$
\end{document}
顺便说一句,我不确定\def\useanchorwidth{T}
在宏中添加有什么作用,也许它有某种魔力?在宏的每一行末尾stackengine
添加也是一个好主意,因为这有助于防止不必要的空间蔓延。%
事实上,与其硬性规定线条的宽度,不如使用文本自动设置它们更好:
\documentclass[prb,preprint]{revtex4-1}
\usepackage{xparse}
\newlength\barlength
\newcommand\xbarsbelowrecursion[1]{%
\ifnum#1>0%
\rlap{\rule[\the\dimexpr-2pt*#1\relax]{\barlength}{0.7pt}}
\xbarsbelowrecursion{\the\numexpr#1-1\relax}
\fi%
}
\NewDocumentCommand\xbarsbelow{O{1} d() m}{% draws n \xbar's below the given symbol
\IfNoValueTF{#2}{\settowidth\barlength{\,#3}}{\setlength\barlength{#2}}%
\xbarsbelowrecursion{#1}%
\rlap{\hbox to \barlength{\hfil$#3$\hfil}}%
\hspace*{\barlength}%
}
\begin{document}
$\xbarsbelow[5]{A}$
$\xbarsbelow[3]{Hello}$
$\xbarsbelow[3](4em){Hello}$
\end{document}
同样,有一个可选的()
-delimited 参数用于覆盖长度。以下是输出: