在非标准分析中,非标准扩展运算符 * 的使用频率很高。不过,排版并不简单,因为 * 的位置取决于后面的符号。例如,实数的非标准扩展写为
^*{\mathbb{R}}
而实函数 X 的非标准扩展通常是排版
^*\!{X}
如果不包含负空间\!
,则 * 和 X 之间的距离太远。
我想在 LaTeX 中将样式与内容分开,但不清楚如何定义一个根据上下文适当扩展的宏。似乎我需要两个宏——一个用于需要负空间,另一个用于不需要负空间。但这似乎并不比添加\!
到代码中好多少。我见过一些帖子建议tensor
包,但空间不正确。
编辑:我接受了允许指定特定字母的适当间距的答案。LuaLateX 版本是这个想法的更灵活版本。自动方法令人印象深刻且富有创意,但无法提供专业排版文档所需的质量。我现在倾向于认为,如果不详细了解底层字体,自动方法不太可能满足要求。
答案1
除非有人想出一个好的解决方案,否则强力解决方案可能是:
\documentclass{scrartcl}
\usepackage{xparse,dsfont}
\ExplSyntaxOn
\NewDocumentCommand \nsext { m }
{
{\vphantom{#1}}
\sp
{
*
\str_case:nn {#1}
{
{ X } { \mskip-3mu }
{ A } { \mskip-6mu }
}
}
#1
}
\ExplSyntaxOff
\newcommand*{\R}{\mathds{R}}
\begin{document}
$\nsext\R \quad \nsext X \quad \nsext V \quad \nsext A$
\end{document}
\str_case:nn
如果您想添加新字母和要删除的相应空格,您只需要在第二个参数中添加一对。
答案2
修订方法
原作者的评论指出,我原来的解决方案虽然看起来不错,但依赖于将数学字体更改为 ptmx,这是不可接受的。因此,问题似乎是 ptmx 字体的数学字距调整没问题,但 ComputerModern (CM) 的数学字距调整不足以完成当前任务。
考虑到这一点,我决定单独声明 ptmx 数学字母表,并且仅用于定位 CM 字形*
。已编辑以声明新的数学字母表。然后,当我在给定参数上方/之前堆叠时,我使用\mathptmx
该参数的版本(我刚刚声明的)来控制从右侧的偏移量。
为了解释非纯字母字形的参数,我首先进行了 catcode 测试。在下面的 MWE 中,您可以看到我在第一行的方法,与$^*<letter>$
第二行的原始 ComputerModern 构造相比。
已编辑(2016 年 8 月),以便根据读者的电子邮件请求使用下标数学样式。为此,我使用包\ThisStyle{...\SavedStyle...}
的功能scalerel
将数学样式导入到否则会丢失的地方。已重新编辑以\leavevmode
处理用例\substack
。
\documentclass{article}
\usepackage{amssymb,stackengine,xcolor,scalerel,mathtools}
\stackMath
\def\nsa#1{\leavevmode\ThisStyle{%
\def\stackalignment{r}\def\stacktype{L}%
\ifcat A#1
\mkern-6.5mu\stackon[0pt]{\SavedStyle\phantom{f}#1}
{\SavedStyle^*\mkern-1.1mu\phantom{\mathptmx{#1}}}%
\else
\mkern-4mu\stackon[0pt]{\SavedStyle\phantom{f}#1}
{\SavedStyle^*\mkern-1.7mu\phantom{#1}}%
\fi
}}
\def\R{\mathbb{R}}
\DeclareMathAlphabet{\mathptmx}{OML}{ztmcm}{m}{it}
\parskip 1ex
\begin{document}
\centering
$(\nsa\R) ~ (\nsa V) ~ (\nsa X) ~ (\nsa A) ~ (\nsa M)$
vs.
$(^*\R) ~ (^*V) ~ (^*X) ~ (^*A) ~ (^*M)$
\hrulefill
Other cases requiring EDIT to \textbackslash nsa:
$(x_n)_{n\in\nsa{\mathbb N}}$.
$\bigcup_{\substack{U\subseteq X\\ \nsa U\subseteq \mathrm{Fin}(\nsa X)}}$
\end{document}
原始方法 (ptmx 数学)
这会尝试将 * 对齐到 f 的右端可能所在的位置。第一行显示我试图模仿的字距调整(模型);第二行显示已实现的宏;而第三行显示宏如何成功实现其目标(方法,覆盖*
右端f
)
\documentclass{article}
\usepackage{amssymb,mathptmx,stackengine,xcolor}
\stackMath
\def\nsa#1{\def\stackalignment{r}\def\stacktype{L}%
\mkern-1mu\stackon[0pt]{\mkern-2mu\phantom{f}#1}{^*\mkern-1.7mu\phantom{#1}}}
\def\R{\mathbb{R}}
\begin{document}
$ f\R ~fV ~fX ~fA$ The model
$\nsa\R ~ \nsa V ~ \nsa X ~ \nsa A$ The macro
\def\nsa#1{\def\stackalignment{r}\def\stacktype{L}%
\mkern-1mu\stackon[0pt]{\color{cyan}\mkern-2mu f#1}{^*\mkern-1.7mu #1}}
$\nsa\R ~ \nsa V ~ \nsa X ~ \nsa A$ The method
\end{document}
答案3
这是一个基于LuaLaTeX的解决方案,它设置了一个Lua函数来调整星号和后续字母之间的间距,其中调整量取决于字母的形状。
代码定义了名为\nsx
(“非标准扩展”的 LaTeX 宏)的前缀,该宏的参数(通常是大写字母)前面加了一个星号;星号和字母之间的默认间距调整是-4mu
。(负数细间距,\!
等于-3mu
。)代码接下来设置了一个 Lua 函数,用于覆盖所选字母的默认调整量。
请参阅下表,了解我为拉丁字母表的 26 个大写字母以及 和 得出的调整量\mathbb{R}
。\Gamma
请注意,这些调整量针对“Computer/Latin Modern”数学字体进行了优化。其他字体系列可能需要不同的调整量。
% !TEX TS-program = lualatex
\documentclass{article}
\newcommand\nsx[2][4]{{}^{*}\mkern-#1mu#2} % default neg. space: 4mu
\usepackage{amsfonts,array,booktabs} % just for this example
\usepackage{luacode,luatexbase}
\begin{luacode}
function adjust_ns ( line )
if string.find ( line, "\\nsx" ) then
line = string.gsub ( line, "\\nsx{([AJ])}", "\\nsx[6.5]{%1}" )
line = string.gsub ( line, "\\nsx{([X])}", "\\nsx[4.5]{%1}" )
line = string.gsub ( line, "\\nsx{([SZ])}", "\\nsx[3.5]{%1}" )
line = string.gsub ( line, "\\nsx{([CGOQUVW])}", "\\nsx[2.5]{%1}" )
line = string.gsub ( line, "\\nsx{([Y])}", "\\nsx[1.5]{%1}" )
line = string.gsub ( line, "\\nsx{([T])}", "\\nsx[1]{%1}" )
line = string.gsub ( line, "\\nsx{\\mathbb{R}}", "\\nsx[1.5]{\\mathbb{R}}" )
line = string.gsub ( line, "\\nsx{\\Gamma}", "\\nsx[2]{\\Gamma}" )
end
return line
end
luatexbase.add_to_callback ( "process_input_buffer", adjust_ns, "adjust_ns" )
\end{luacode}
\begin{document}
\noindent
\begin{tabular}{@{} >{$}l<{$} l @{}}
$Letter$ & Adjustment (in ``mu'')\\
\midrule
\nsx{B}\nsx{D}\nsx{E}\nsx{F}\nsx{H}\nsx{I}\nsx{K}\nsx{L}\nsx{M}\nsx{N}\nsx{P}
\nsx{R} & 4 (default)\\
\nsx{A}\nsx{J} & 6.5\\
\nsx{X} & 4.5\\
\nsx{S}\nsx{Z} & 3.5\\
\nsx{C}\nsx{G}\nsx{O}\nsx{Q}\nsx{U}\nsx{V}\nsx{W} & 2.5 \\
\nsx{Y} & 1.5 \\
\nsx{T} & 1 \\
\nsx{\mathbb{R}} & 1.5 \\
\nsx{\Gamma} & 2 \\
\end{tabular}
\end{document}
答案4
该代码还根据宏识别一些类型\binrel@
:二元运算和关系(但没有运算符)。
\documentclass{article}
\usepackage{amsmath}
\usepackage{amssymb}
\makeatletter
\DeclareRobustCommand{\nsext}[1]{%
\binrel@{#1}% compute the type
\binrel@@{%
{\vphantom{#1}}^*% the asterisk at the proper height
\kern-\scriptspace % remove the script space
\csname mkern@\detokenize{#1}\endcsname % additional kerning
{#1}% the symbol
}%
}
\newcommand{\defineextkern}[2]{%
\@namedef{mkern@\detokenize{#1}}{\mkern#2}%
}
\makeatother
% define some additional kerning
\defineextkern{X}{-3mu}
\defineextkern{\in}{-2mu}
\begin{document}
$x\nsext{\in}\nsext{\mathbb{R}}$
$\nsext{X}_{x\nsext{\in}\nsext{X}}$
\end{document}