非标准分析:根据上下文排版 `^*`

非标准分析:根据上下文排版 `^*`

在非标准分析中,非标准扩展运算符 * 的使用频率很高。不过,排版并不简单,因为 * 的位置取决于后面的符号。例如,实数的非标准扩展写为

^*{\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}

在此处输入图片描述

相关内容