私の具体的な例:

私の具体的な例:

予測可能な方法で、単一のコマンド (基本的にはカスタム ヘッダー) に基づいてさまざまなコマンドを作成しようとしています。TeX/LaTeX でこれを行う方法はありますか?

私の具体的な例:

私はモジュール仕様を書いています。各サブ見出しは\modulespec{description}{the description}または\modulespec{learning outcomes}{the learning outcomes}などで表されます。TeXが および のようなコマンドを生成できることを期待しています\mdescription{the description}\mlearningoutcomes{the learning outcomes}

私は、Bashのような拡張とTeXを組み合わせて次のように書くだろうと知っている。

for i in 'description' 'learning outcomes'
do
    \def\csname m\getRidOfSpaces{$i} \endcsname{\modulespec{$i}{#1}}
done

(言語の組み合わせをお許しいただければ)が に\getRidOfSpaces変更されます。これは TeX/LaTeX で可能/実行可能でしょうか?learning outcomeslearningoutcomes

M(not)WE:

\documentclass{article}
\usepackage{blindtext}

% In the real thing, this definition is much more complicated
\newcommand{\modulespec}[2]{\section{#1} #2}

% The code I want in pure TeX/LaTeX
for i in 'description' 'learning outcomes'
do
    \def\csname m\getRidOfSpaces{$i} \endcsname{\modulespec{$i}{#1}}
done
% end of non TeX code


\begin{document}

% Both work
\modulespec{description}{\blindtext}
\modulespec{learning outcomes}{\blindtext}

% These two commands should produce the same output as the previous two
\mdescription{\blindtext}
\mlearningoutcomes{\blindtext}

\end{document}

答え1

以下は LaTeX3 の実装です。

\documentclass{article}
\usepackage[margin=1cm]{geometry} % to fit in one page
\usepackage{blindtext}
\usepackage{xparse}

\newcommand{\modulespec}[2]{\section{#1} #2}

\ExplSyntaxOn

\NewDocumentCommand{\definemodules}{m}
 {
  \farley_definemodules:n { #1 }
 }

\tl_new:N \l_farley_temp_tl
\cs_new_protected:Npn \farley_definemodules:n #1
 {
  \clist_map_inline:nn { #1 }
   {
    \tl_set:Nn \l_farley_temp_tl { ##1 }
    \tl_replace_all:Nnn \l_farley_temp_tl { ~ } { }
    \cs_new_protected:cpn { m \l_farley_temp_tl } { \modulespec { ##1 } }
   }
 }

\ExplSyntaxOff

\definemodules{
  description,
  learning outcomes
}

\begin{document}

\modulespec{description}{\blindtext}
\modulespec{learning outcomes}{\blindtext}

% These two commands should produce the same output as the previous two
\mdescription{\blindtext}
\mlearningoutcomes{\blindtext}

\end{document}

ここに画像の説明を入力してください

コードに関するいくつかのコメント。

すべてのモジュールを一度に定義するためのユーザー レベル マクロを定義します。これは、\definemodulesプログラマー レベルの関数に制御を渡すだけです\farley_definemodules:n(これは、LaTeX3 プログラミング ガイドラインに従ったベスト プラクティスです)。

ここで、関数は\farley_definemodules:n引数をコンマで分割し、項目に対してループを実行します。現在の項目は として使用できますが、定義内にあるため が#1必要です。##1

各サイクルでは、スクラッチ トークン リスト変数にアイテムが格納され、それに\l_farley_temp_tl適用できるようになります\tl_replace_all:Nnn。置換は「スペースはすべて何もないものに置き換えられます」。プログラミング環境ではスペースは無視されるため、「実際のスペース」は で示されます~

ここで、\cs_new_protected:cpn古いスタイルに類似した関数を使用します\@namedef。最初の引数は、\csname...\endcsname(トークン リストはここで TeX ルールによって拡張されます) を使用して制御シーケンス名に変換されます。

答え2

'for each' ループを実行したいようです。LaTeX カーネルには、\@forコンマ区切りリストの各要素に対してこれを実行するマクロがあります。また、\zap@spaceスペースを削除するには、 または に類似したものも必要です。例:

\newcommand{\modulespec}[2]{\section{#1} #2}
\makeatletter
\@for\@tempa:=description,learning outcomes\do{%
  \edef\@tempa
    {\expandafter\expandafter\expandafter\zap@space
      \expandafter\@tempa\space\@empty}%
  \expandafter\edef\csname m\@tempa\endcsname
    {\noexpand\modulespec{\@tempa}}%
}
\makeatother

\mdescriptionは必要に応じてと を定義します\mlearningoutcomes。 を適切な場所で使用して、変数の拡張を強制しました。 (内では「テキスト」が「安全」である必要があるため、ここで を\edef適用しても意味がありません。)\protected@edef\csname

答え3

\xintForおよび LaTeX2e カーネル ユーティリティ (@名前に が含まれる)の使用:

\documentclass{article}
\usepackage[english]{babel}
\usepackage{blindtext}
\usepackage{xinttools}
% In the real thing, this definition is much more complicated
\newcommand{\modulespec}[2]{\section{#1} #2}

% % The code I want in pure TeX/LaTeX
% for i in 'description' 'learning outcomes'
% do
%     \def\csname m\getRidOfSpaces{$i} \endcsname{\modulespec{$i}{#1}}
% done
% % end of non TeX code

% Nota bene: in the above you probably meant \long\def, not \def
\makeatletter
\xintFor #1 in {description, learning outcomes}\do
{\long\@namedef{m\zap@space #1 \@empty}##1{\modulespec{#1}{##1}}}
\makeatother

\begin{document}

% Both work
\modulespec{description}{\blindtext}
\modulespec{learning outcomes}{\blindtext}

% These two commands should produce the same output as the previous two
\mdescription{\blindtext}
\mlearningoutcomes{\blindtext}

\end{document}

ループの定義

関連情報