Na análise não padronizada, o operador de extensão não padronizado * é usado com frequência. Porém, a composição não é simples, porque a colocação de * depende do símbolo a seguir. Por exemplo, a extensão não padronizada dos reais é escrita
^*{\mathbb{R}}
enquanto a extensão não padronizada de uma função real X é normalmente composta
^*\!{X}
Se o espaço negativo \!
não for incluído, * e X ficarão muito espaçados.
Gostaria de separar o estilo do conteúdo no meu LaTeX, mas não está claro como definiria uma macro que se expandisse adequadamente de acordo com o contexto. Parece que eu precisaria de duas macros – uma onde precisasse de um espaço negativo e outra quando não precisasse. Mas isso não parece muito melhor do que adicionar algo \!
ao código. Já vi posts sugerindo o tensor
pacote, mas o espaço não está correto.
EDIT: Aceitei uma resposta que permite especificar o espaçamento apropriado para letras específicas. Uma versão LuaLateX é uma versão mais flexível dessa ideia. A abordagem automática é impressionante e criativa, mas não oferece a qualidade necessária para um documento tipografado profissionalmente. Agora estou inclinado a pensar que é improvável que uma abordagem automática seja suficiente sem um conhecimento detalhado da fonte subjacente.
Responder1
Até que alguém encontre uma boa solução, uma solução de força bruta poderia ser:
\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}
Você só precisa adicionar um par dentro do \str_case:nn
segundo argumento se quiser adicionar uma nova letra e o espaço correspondente para remover.
Responder2
ABORDAGEM REVISADA
Os comentários do OP indicaram que minha solução original, embora talvez agradável de se ver, dependia da alteração da fonte matemática para ptmx, o que não era aceitável. Portanto, o problema parecia ser que o kerning matemático da fonte ptmx estava OK, mas o do ComputerModern (CM) era inadequado para a tarefa atual.
Com isso em mente, decidi declarar o alfabeto matemático ptmx separadamente, euse-o apenas para posicionamento dos glifos CM. EDITADO para declarar um novo alfabeto matemático. Então, quando estou empilhando *
acima/antes do argumento fornecido, uso a \mathptmx
versão do argumento (que acabei de declarar) para controlar o deslocamento da mão direita.
Para explicar argumentos que não são glifos alfabéticos puros, começo com um teste de catcode. Neste MWE abaixo, você vê minha abordagem na linha superior, em comparação com a construção bruta do ComputerModern $^*<letter>$
na segunda linha.
EDITADO (8/2016) para funcionar em estilos matemáticos subscritos, mediante solicitação por e-mail de um leitor. Para isso, utilizo o \ThisStyle{...\SavedStyle...}
recurso do scalerel
pacote para importar o estilo matemático para locais onde ele seria perdido. REEDITADO para \leavevmode
lidar com casos de uso em \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}
ABORDAGEM ORIGINAL (matemática ptmx)
Isso tenta alinhar * aproximadamente onde a extremidade direita de um f pode estar. A primeira linha mostra o kerning que eu estava tentando emular (o modelo); a segunda linha mostra a macro implementada; enquanto a terceira linha mostra como a macro atinge seu objetivo (o método, com *
sobreposição na extremidade direita de 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}
Responder3
Aqui está uma solução baseada em LuaLaTeX, que configura uma função Lua que ajusta o espaço entre o asterisco e a letra subsequente, onde o valor do ajuste depende do formato da letra.
O código define uma macro LaTeX chamada \nsx
(abreviação de "extensão não padrão") que prefixa um asterisco ao argumento da macro - normalmente uma letra maiúscula; o ajuste de espaçamento padrão entre o asterisco e a letra é -4mu
. (Um thinspace negativo, \!
, é igual a -3mu
.) O código a seguir configura uma função Lua que substitui o valor de ajuste padrão para letras selecionadas.
Consulte a tabela abaixo para ver os valores de ajuste que consegui calcular para as 26 letras maiúsculas do alfabeto latino, bem como para \mathbb{R}
e \Gamma
. Observe que esses valores de ajuste são otimizados para as fontes matemáticas "Computer/Latin Modern". Outras famílias de fontes provavelmente exigirão valores de ajuste diferentes.
% !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}
Responder4
Este código também reconhece alguns tipos, com base na macro \binrel@
: operações e relações binárias (embora sem operadores).
\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}