В нестандартном анализе часто используется нестандартный оператор расширения *. Однако его набор не является простым, поскольку размещение * зависит от следующего символа. Например, нестандартное расширение вещественных чисел записывается
^*{\mathbb{R}}
тогда как нестандартное расширение действительной функции X обычно набирается
^*\!{X}
Если отрицательный пробел \!
не включен, то * и X будут расположены слишком далеко друг от друга.
Я хотел бы отделить стиль от содержимого в моем LaTeX, но не ясно, как я определю макрос, который будет расширяться соответствующим образом с учетом контекста. Похоже, мне понадобятся два макроса — один, когда мне нужно отрицательное пространство, и другой, когда оно мне не нужно. Но это, кажется, не намного лучше, чем добавление \!
в код. Я видел посты, предлагающие tensor
пакет, но пространство неправильное.
EDIT: Я принял ответ, который позволяет указать подходящий интервал для определенных букв. Версия 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
ПЕРЕСМОТРЕННЫЙ ПОДХОД
Комментарии OP показали, что мое первоначальное решение, хотя, возможно, и приятное на вид, основывалось на изменении шрифта math на ptmx, что было неприемлемо. Так что проблема, похоже, была в том, что математический кернинг шрифта ptmx был в порядке, но ComputerModern (CM) был неадекватен для текущей задачи.
Имея это в виду, я решил объявить математический алфавит ptmx отдельно, ииспользуйте его только для позиционирования глифов CM. ОТРЕДАКТИРОВАНО для объявления нового математического алфавита. Затем, когда я складываю over *
/before заданный аргумент, я использую \mathptmx
версию аргумента (которую я только что объявил) для управления смещением от правой руки.
Чтобы учесть аргументы, которые не являются чистыми алфавитными глифами, я начинаю с теста catcode. В этом MWE ниже вы видите мой подход в верхней строке, по сравнению с сырой конструкцией ComputerModern во $^*<letter>$
второй строке.
ОТРЕДАКТИРОВАНО (8/2016) для работы в стиле подстрочной математики по запросу читателя по электронной почте. Для этого я использую функцию \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, корректирующую расстояние между звездочкой и последующей буквой, причем величина корректировки зависит от формы буквы.
Код определяет макрос LaTeX с именем \nsx
(сокращение от «нестандартное расширение»), который добавляет звездочку к аргументу макроса — обычно заглавную букву; корректировка интервала по умолчанию между звездочкой и буквой — -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}