Нестандартный анализ: набор `^*` в зависимости от контекста

Нестандартный анализ: набор `^*` в зависимости от контекста

В нестандартном анализе часто используется нестандартный оператор расширения *. Однако его набор не является простым, поскольку размещение * зависит от следующего символа. Например, нестандартное расширение вещественных чисел записывается

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

введите описание изображения здесь

Связанный контент