
ドキュメント内で変数を定義し、後でその値を取得する推奨される方法は何ですか?
私はいくつかの異なる解決策を Google で検索しましたが、通常は約 10 行の長さです。次のようなことをもっと短く実行する方法があるはずだと思いました (疑似コード):
\setvalue(VARIABLE1){foo foo bar}
そして、文書の後半では
$\getvalue(VARIABLE1)$.
新しいコマンドを定義するという解決策も見たことがありますが、そのコマンドがすでに別のパッケージ内で使用されている場合はどうなるでしょうか? これは独立した解決策とは思えません。
答え1
まあ、それがあなたの望むものではないことはわかっていますが、標準的な方法は または のいずれかですdef
。newcommand
あなたが触れた問題は、グローバル名前空間です。newcommand
これを使用すると、コマンドがすでに設定されているかどうかがわかり (コンパイル時にエラーとして表示され、問題のある試行の名前が示されるnewcommand
)、これらの問題から保護されます。
% Set your new variable. In this case it will be
% called "\MyNewVariable" and the value will be "hello".
\newcommand{\MyNewVariable}{hello}
% Use to get the variable.
\MyNewVariable
これらすべてに自分の名前または他のニーモニックを先頭に付けることができれば、衝突が発生する可能性は低くなります。このニーモニックは、独自の (一種の) 名前空間として動作します。
変数の最初のインスタンスがnewcommand
エラーを発生させずに で設定されていると仮定すると、 をrenewcommand
後で使用してその変数を変更できます。
答え2
キーバリューシステムをお探しのようですね。提案してもいいでしょうかpgfkeys
? 各変数にプロパティを使用するという Yiannis のアイデアを含めて、次のようにします:
\documentclass{article}
\usepackage{pgfkeys}
\newcommand{\setvalue}[1]{\pgfkeys{/variables/#1}}
\newcommand{\getvalue}[1]{\pgfkeysvalueof{/variables/#1}}
\newcommand{\declare}[1]{%
\pgfkeys{
/variables/#1.is family,
/variables/#1.unknown/.style = {\pgfkeyscurrentpath/\pgfkeyscurrentname/.initial = ##1}
}%
}
\declare{}
\begin{document}
\setvalue{VARIABLE1 = foo foo bar}
\getvalue{VARIABLE1}
\declare{test/}
\setvalue{test/property = 12}
\getvalue{test/property}
\end{document}
括弧だけのものも含めて10行未満です。操作は非常に単純です。変数を「ディレクトリ」内の「ファイル」として保存します。あなたのものはディレクトリpgfkeys
内に保存することにしました。/variables
ないグローバル名前空間内にあります。(ちなみに、pgfkeys
キーは通常のマクロ名と競合することはないので、その「グローバル名前空間」はマクロ名前空間とは異なります。)
マクロ\setvalue
はディレクトリを適切に変更し、割り当てを呼び出します。\getvalue
マクロは正しいディレクトリから変数を取得します。
唯一のコツは、 ではpgfkeys
、キーが割り当てられる前にそれが「既知」である必要があることです。そうでなければ、 として呼び出す必要がありますkey/.initial = value
。これを強制的に記述したくないので、このコードをバックグラウンドで追加するだけの、未知の変数用の「ハンドラー」を作成しました。
を使ってプロパティを持つ変数を宣言し\declare{variable/}
、 をvariable/property
変数名として使用することができます\setvalue
( をvariable/
デフォルトディレクトリとして使用することもできますので、次のように記述します)。
\setvalue{variable, property 1 = value 1, property 2 = value 2}
これは便利です)。\declare
マクロは「ディレクトリ」の不明なハンドラを設定するだけです/variables/variable/
(つまり、\declare{}
先頭の不可解な行は/variables/
ディレクトリ自体を設定します)。
答え3
私はむしろ、Lisp のような方法、またはオブジェクト指向の方法を使用してそれらを定義したいと思います。
以下の最小限のものでは、以下を使用します。
\setproperty{test}{aproperty}{12}
\getproperty{test}{aproperty}
これらを を表すものと考えてくださいtest.aproperty
(実際には として定義しますtest@paproperty
)。この方法では、独自のコマンド以外の既存のコマンドと競合する可能性は非常に低くなります。
最小限:
\documentclass{article}
\makeatletter
% Properties a la Lisp.
\def\ece#1#2{\expandafter#1\csname#2\endcsname}%
% \setproperty{ATOM}{PROPNAME}{VALUE} defines the property PROPNAME on the
% ``atom'' ATOM to have VALUE.
%
\def\setproperty#1#2#3{\ece\protected@edef{#1@p#2}{#3}}%
\def\setpropertyglobal#1#2#3{\ece\protected@xdef{#1@p#2}{#3}}%
%
%
% \getproperty{ATOM}{PROPNAME} expands to the value of the property
% PROPNAME on ATOM, or to nothing (i.e., \empty), if the property isn't
% present.
%
\def\getproperty#1#2{%
\expandafter\ifx\csname#1@p#2\endcsname\relax
% then \empty
\else \csname#1@p#2\endcsname
\fi
}%
%
\makeatother
\begin{document}
\setproperty{test}{aproperty}{12}
\getproperty{test}{aproperty}
\end{document}
答え4
あなたのコードはほぼ有効なConTeXtです。変数を次のように定義します。
\setvalue{variable1}{value}
そしてその値を取得するには
\getvalue{variable1}
(これらはLaTeX の\@namedef
およびに似ています\@nameuse
)。キー値駆動型変数が必要な場合は、次を使用できます。
\definenamespace
[VAR]
[
name=VAR,
setup=list,
command=list,
parent=VAR,
]
\setupVAR
[a={default A},
b={default B}]
\defineVAR
[set1]
[a={set1 A},
c={set1 C}]
\defineVAR
[set2]
[b={set2 B},
c={set2 C}]
\starttext
\startlines
\namedVARparameter{set1}{a} % gives set1 A
\namedVARparameter{set1}{b} % gives default B
\namedVARparameter{set1}{c} % gives set1 C
\stoplines
\stoptext