
Добрый день!
Я прогуглил весь stackechange, но не смог найти ответ. Я совсем новичок в Latex, поэтому мой подход неверный. Я пытаюсь определить макрос, который должен форматировать греческую букву каквертикальный жирный. Я знаю, что есть несколько способов сделать это, я бы хотел избежать использования isomath и придерживатьсявосточныйупаковка.
Я хочу уметь писать
\gb{\alpha}
\gb{\Alpha}
и в обоих случаях получить вертикальные жирные символы. Итак, вот мой код внутри:
\newcommand{\gb}[1]{ % Imagine #1=\Psi
\StrGobbleLeft{\detokenize{#1}}{1}[\chrcodet] % variable "\Psi"
\StrGobbleRight{\chrcodet}{1}[\chrcode] % variable "Psi"
\StrLeft{\chrcode}{1}[\chrfirst] % first character "P"
\IfSubStr{ABCDEFGHIJKLMNOPQRSTUVWXYZ}{\chrfirst} % Is it capital?
{\boldsymbol{#1}} % Yes - no modification
{\boldsymbol{\csname up\chrcode\endcsname}} % No - glue \up+Psi (that what happens!)
}
Я пытаюсь получить первый символ управляющей последовательности, и если это заглавная буква, я вызываю просто \boldsymbol
без изменений, в противном случае я хочу изменить управляющую последовательность, поместив ее \up
в начало. Итак, когда я это делаю, возникает следующая ошибка
! Undefined control sequence.
\bm@command ->\upPsi
Похоже, что условие «if» всегда дает false, т.е. «P» не распознается как заглавная буква, поэтому следующий MWE будет дважды записан «строчной»:
\documentclass{article}
\usepackage{bm,upgreek}
\usepackage{etoolbox}
\usepackage{xstring}
\newcommand{\gb}[1]{
\StrGobbleLeft{\detokenize{#1}}{1}[\chrcodet]
\StrGobbleRight{\chrcodet}{1}[\chrcode]
\StrLeft{\chrcode}{1}[\chrfirst]
#1 - \IfSubStr{ABCDEFGHIJKLMNOPQRSTUVWXYZ}{\chrfirst}{uppercase}{lowercase}
}
\begin{document}
\begin{equation}
\psi,\Psi,\gb{\psi},\gb{\Psi}
\end{equation}
\end{document}
Может ли кто-нибудь дать мне идею, почему это не работает так, как ожидалось?
решение1
Не bm
делает ли он просто то, что вы хотите, без каких-либо дополнительных переопределений?
\documentclass{article}
\usepackage{bm,upgreek}
\begin{document}
\begin{equation}
\psi, \uppsi, \Psi,\bm{\psi},\bm{\uppsi},\bm{\Psi}
\end{equation}
\end{document}
решение2
Огромное спасибо Дэвиду Карлайлу!
Это была совершенно правильная идея о catcodes. Из-за отсутствия опыта я понятия не имел о catcodes. Делая свои попытки, я также был сбит с толку, когда я пыталсяetoolboxфункция \ifstrequal
для сравнения обычного P
(catcode 11) и детокенизированного P
(catcode 12) и это сработало! После того, как я решил заглянуть в исходный код панели инструментов, я обнаружил, что там \detokenize
применяется к обоим операндам. Поэтому я изменил свой макрос похожим образом, поэтому теперь он работает так, как и ожидалось.
Макрос:
\documentclass{article}
\usepackage{bm,upgreek}
\usepackage{etoolbox}
\usepackage{xstring}
\newcommand{\gb}[1]{
\StrGobbleLeft{\detokenize{#1}}{1}[\chrcode]
\StrGobbleRight{\chrcode}{1}[\chrcode]
\StrLeft{\chrcode}{1}[\chrfirst]
\edef\tempa{\detokenize{ABCDEFGHIJKLMNOPQRSTUVWXYZ}}
#1 - no\;detokenize: \IfSubStr{ABCDEFGHIJKLMNOPQRSTUVWXYZ}{\chrfirst}{upper}{lower}, \,
detokenize\;both: \IfSubStr{\tempa}{\chrfirst}{upper}{lower}, \,
etoolbox: \expandafter\ifstrequal\expandafter{\chrfirst}{P}{upper}{lower}
}
\begin{document}
\begin{equation}
\gb{\psi}
\end{equation}
\begin{equation}
\gb{\Psi}
\end{equation}
\end{document}
Результат:
Возможно, это не лучшее решение и я не считаю его эффективным для поставленной задачи, но это был полезный опыт!