각 문자에 대한 Newcommand

Sep 26 2020

사용자 지정 명령을 사용하여 다음과 같은 LaTeX 방정식을 작성하고 읽을 수 있습니다.

\newcommand{\bbA}{\mathbb{A}}
\newcommand{\bbB}{\mathbb{B}}
\newcommand{\bbC}{\mathbb{C}}
% etc...
\newcommand{\mcA}{\mathcal{A}}
\newcommand{\mcB}{\mathcal{B}}
\newcommand{\mcC}{\mathcal{C}}
% etc...
\newcommand{\msA}{\mathscr{A}}
\newcommand{\msB}{\mathscr{B}}
\newcommand{\msC}{\mathscr{C}}
% etc...
\newcommand{\mfA}{\mathfrak{A}}
\newcommand{\mfB}{\mathfrak{B}}
\newcommand{\mfC}{\mathfrak{C}}
% etc...
\newcommand{\mfa}{\mathfrak{a}}
\newcommand{\mfb}{\mathfrak{b}}
\newcommand{\mfc}{\mathfrak{c}}
% etc...

그러나 이것은 파일 헤더에서 130 줄의 코드를 차지합니다 (다행히도 손으로 작성하지 않았고 그렇게하는 프로그램을 만들었 기 때문에 문제에 대한 해결책이 있다고 확신합니다). ..

TeXStudio 날 사이에 묶어야 할 수 있도록 %BEGIN_FOLD하고 %END_FOLD이 모든 혼란을 축소 할 날 수 있도록 의견. 그러나 두 가지 우려 사항이 있습니다.

  1. %BEGIN_FOLD과 %END_FOLD기본적으로 붕괴하지 않는 것, 그것은 파일을 재-열 때 다시 확장됩니다. 또한 이것이 TeXStudio 전용 기능이 아닌지 확실하지 않습니다.

  2. 컴파일 시간에 영향을 미칩니 까? 컴파일러가 \newcommands를 처리하는 방법을 모르겠지만 매번 다시 정의하고 다시 컴파일해야한다면 개선의 여지가있을 것입니다.

따라서 다음을 요청합니다.

26 명령의 각 블록을 단일 명령으로 압축하는 방법이 있습니까?

벌금 , 나는 같은 것을 할 필요하지 싶습니다 \bb{A}, \ms{A}, 등 , 즉, 난 그냥이 명령에 대한 별칭을하지 않으려합니다. 내가 달성하고자하는 것은 두 가지 이유로 이러한 중괄호를 제거하는 것입니다.

  1. 이 명령을 몇 년 동안 사용해 왔기 때문에 근육 기억이 문제가 될 것입니다.

  2. 타이핑 Alt Gr+ 4, Alt Gr+ +, 가고 Left, 문자를 입력하고가는 Right다시하는 것은 꽤 많은 시간이 소요 : 이것이 내가 원래 이러한 명령을 만든 이유입니다.

저는 이미 저를 도와 주신 몇몇 분들처럼 LaTeX 전문가가 아닙니다. 아마도 제 "무력한 힘"130 줄이 아닌 다른 접근 방식을 찾으려고 할 때 뭔가를 놓쳤을 것입니다 ... 친절한 답변에 감사드립니다!

답변

3 egreg Sep 26 2020 at 03:16

130 줄 미만의 코드.

아이디어는 주어진 범위에서 루프를 수행하는 것입니다. 저는 알파벳 상수를 사용하므로 예를 들어 A63에 해당하지만 알 필요는 없습니다. 루프 인덱스는로 표시되며 ##1문자의 ASCII 번호를 차례로 사용합니다. 도움으로 \char_generate:nn해당 캐릭터를 생성 할 수 있습니다. 정의는 "확장"되어 있으므로 명령을 확장 할 필요가 없습니다 \exp_not:N.

\documentclass{article}
\usepackage{amsmath,amssymb}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\definealphabet}{mmmm}
 {% #1 = prefix, #2 = command, #3 = start, #4 = end
  \int_step_inline:nnn { `#3 } { `#4 }
   {
    \cs_new_protected:cpx { #1 \char_generate:nn { ##1 }{ 11 } }
     {
      \exp_not:N #2 { \char_generate:nn { ##1 } { 11 } }
     }
   }
 }

\ExplSyntaxOff

\definealphabet{bb}{\mathbb}{A}{Z}
\definealphabet{mc}{\mathcal}{A}{Z}
\definealphabet{mf}{\mathfrak}{A}{Z}
\definealphabet{mf}{\mathfrak}{a}{z}

\begin{document}

$\bbA+\mcB+\mfS+\mfz$

\end{document}

3 UlrichDiez Sep 26 2020 at 03:16

이 명령 \DEFINEbbANDmcANDmsANDmfLOOP은 정확히 하나의 토큰으로 구성된 무제한 인수를 처리하기위한 것입니다. 인수의 첫 번째 토큰의 의미가 \relax-primitive 의 의미와 같은지 확인합니다 .
그렇다면를 통해 다음 작업을 삼킨다 \@gobble.
그렇지 않은 경우 인수가 ⟨letter⟩ 를 나타내는 단일 문자 토큰이라고 가정 하고 다음을 통해 다음 작업을 수행합니다 \@firstofone.

  • 확장 할 매크로 정의\bb⟨letter⟩\bb\mathbb{⟨letter⟩}
  • 확장 할 매크로 정의\mc⟨letter⟩\bb\mathcal{⟨letter⟩}
  • 확장 할 매크로 정의\ms⟨letter⟩\bb\mathscr{⟨letter⟩}
  • 확장 할 매크로 정의\mf⟨letter⟩\bb\mathfrakr{⟨letter⟩}
  • 다시 전화하십시오.

동일한 동작을 다른 인수에 적용하기 위해 자신을 다시 호출하는 매크로 개념을 꼬리 재귀라고합니다.

(매크로 정의를 위해 \CmdName다음과 같이 작동 하는 작은 도우미 매크로 를 구현했습니다 .

\CmdName⟨stuff without braces⟩{macroname}→ ⟨stuff without braces⟩\macroname.

예 :

\CmdName\newcommand*{foobar}...→ \newcommand*\foobar....

내가 사용하는 \CmdName내가 기분이 타이핑에 아닙니다 때 \expandafter와 \csname..\endcsname너무 자주. ;-))

\documentclass{article}

\makeatletter
\@ifdefinable\CmdName{\long\def\CmdName#1#{\romannumeral0\innerCmdName{#1}}}%
\newcommand\innerCmdName[2]{\expandafter\exchange\expandafter{\csname #2\endcsname}{ #1}}%
\newcommand\exchange[2]{#2#1}%
\newcommand\DEFINEbbANDmcANDmsANDmfLOOP[1]{%
  \ifx\relax#1\expandafter\@gobble\else\expandafter\@firstofone\fi
  {%
    \CmdName\newcommand*{bb#1}{\mathbb{#1}}%
    \CmdName\newcommand*{mc#1}{\mathcal{#1}}%
    \CmdName\newcommand*{ms#1}{\mathscr{#1}}%
    \CmdName\newcommand*{mf#1}{\mathfrak{#1}}%
    \DEFINEbbANDmcANDmsANDmfLOOP
  }%
}%
\makeatother

% Now for each of the letters define \bb<letter>, \mc<letter>, \ms<letter> and \mf<letter>:

\DEFINEbbANDmcANDmsANDmfLOOP abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\relax

\begin{document}

\show\bba
\show\mca
\show\msa
\show\mfa

\show\bbb
\show\mcb
\show\msb
\show\mfb

%  . 
%  .
%  .
%  .

\show\bbY
\show\mcY
\show\msY
\show\mfY

\show\bbZ
\show\mcZ
\show\msZ
\show\mfZ

\end{document}

원하는 경우 매크로를 사용하여 꼬리 재귀를 적용 할 수 있습니다 \Definealphabet.

\documentclass{article}

\makeatletter
\newcommand\DEFINEALPHABETLOOP[3]{%
  \ifx\relax#3\expandafter\@gobble\else\expandafter\@firstofone\fi
  {\expandafter\newcommand\expandafter*\csname#1#3\endcsname{#2{#3}}%
   \DEFINEALPHABETLOOP{#1}{#2}}%
}%
\newcommand\Definealphabet[2]{%
  \DEFINEALPHABETLOOP{#1}{#2}abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\relax
}%
\makeatother


\Definealphabet{bb}{\mathbb}
\Definealphabet{mc}{\mathcal}
\Definealphabet{ms}{\mathscr}
\Definealphabet{mf}{\mathfrak}


\begin{document}

\show\bba
% ...
\show\bbz


\show\mca
% ...
\show\mcz


\show\msa
% ...
\show\msz


\show\mfa
% ...
\show\mfz


\end{document}