
さまざまな言語でテキストを作成するためのマクロをいくつか定義したいと思います。コマンドは、\newlang
特定の言語のテキストを格納するための非表示のマクロまたは変数と、この変数を設定するためのセッターを作成します。
たとえば、テキストを保存するために\newlang{ar}
を作成し、を設定します。\@artxt
\setartext{text}
\@artxt
これらの変数の内容を表示したい場合 ( \newlang
3 回呼び出したと仮定)、\csname
最後の 1 つだけを使用してその内容を表示します。コードは次のとおりです。
\documentclass{article}
\makeatletter
\newcommand\newlang[1]{ %
\ifdefined\@langs %
\expandafter\def\expandafter\@langs\expandafter{\@langs{},#1} %
\else %
\def\@langs{#1} %
\fi
\@namedef{@#1txt}{}%
%
\expandafter\newcommand\csname set#1text\endcsname[1]{ %
%
\expandafter\def\csname @#1txt\endcsname{##1} %
} %
}
\newcommand{\@processTexts}[1]{ %
-----#1----\\
\ifcsname @#1txt\endcsname
\csname @#1txt\endcsname
\else
No #1 csname here
\fi\\
******\\
\@artxt \\
\@frtxt \\
}
\newcommand\@splitcomma[1]{\@for\tmp:=#1\do{\@processTexts{\tmp}}}
\newcommand{\print}{ %
\ifdefined\@langs %
\@splitcomma{\@langs}%
\fi %
}
\makeatother
\begin{document}
\newlang{ar}
\newlang{fr}
\newlang{en}
\setartext{arabic}
\setfrtext{french}
\setentext{english}
\setartext{arabic2}
\print{}
Another text
\end{document}
次のように印刷されます:
—–ar—-
arabic2
*****
arabic2
french
—–fr—-
french
*****
arabic2
french
—–en—-
english
*****
arabic2
french
Another text
しかし、代わりに次のように出力されます:
—–ar—-
No ar csname here
*****
arabic2
french
—–fr—-
No fr csname here
*****
arabic2
french
—–en—-
english
*****
arabic2
french
Another text
答え1
エラーは、各エントリの言語リストに\@langs{}
明示的なトークン と を追加し、期待される などではなく と を残すことです。{}
ar{}
ar
この方法では\ifcsname ....
テストは失敗します。つまり、が定義されていないため、false ブランチが返されます@ar{}text
。
\documentclass{article}
\makeatletter
\newcommand\newlang[1]{%
\ifdefined\@langs%
\expandafter\def\expandafter\@langs\expandafter{\@langs,#1} %
\else %
\def\@langs{#1} %
\fi
\global\expandafter\newcommand\csname @#1txt\endcsname{foo}%
\expandafter\newcommand\csname set#1text\endcsname[1]{ %
%
\expandafter\gdef\csname @#1txt\endcsname{##1} %
}%
}
\newcommand{\@processTexts}[1]{ %
-----#1----\\
\@ifundefined{@#1txt}{%
No #1 csname here -- sorry%
}{%
\csname @#1txt\endcsname%
}
\\
******\\
}
\newcommand\@splitcomma[1]{\@for\tmp:=#1\do{\@processTexts{\tmp}}}
\newcommand{\print}{ %
\ifdefined\@langs %
\@splitcomma{\@langs}%
\fi %
}
\makeatother
\begin{document}
\newlang{ar}
\newlang{fr}
\newlang{en}
\setartext{arabic}
\setfrtext{french}
\setentext{english}
\setartext{arabic2}
\print{}
Another text
\end{document}
答え2
エラーは次の場所にあります:
\expandafter\def\expandafter\@langs\expandafter{\@langs{},#1} %
を呼び出すと\@splitcomma
、リストは
ar{},fr{},en
となり\tmp
、ar{}
と\csname @ar{}txt\endcsname
は大きく異なります\csname @artxt\endcsname
。
%
行末を修正した改良版:
\documentclass{article}
\makeatletter
\newcommand\newlang[1]{%
\ifdefined\@langs
\expandafter\def\expandafter\@langs\expandafter{\@langs,#1}%
\else
\def\@langs{#1}%
\fi
\@namedef{@#1txt}{}%
\expandafter\newcommand\csname set#1text\endcsname[1]{%
\expandafter\def\csname @#1txt\endcsname{##1}%
}%
}
\newcommand{\@processTexts}[1]{%
-----#1----\\
\ifcsname @#1txt\endcsname
\csname @#1txt\endcsname
\else
No #1 csname here%
\fi
\\
******\\
\@artxt \\
\@frtxt \\
}
\newcommand\@splitcomma[1]{\@for\tmp:=#1\do{\@processTexts{\tmp}}}
\newcommand{\print}{%
\ifdefined\@langs
\@splitcomma{\@langs}%
\fi
}
\makeatother
\begin{document}
\newlang{ar}
\newlang{fr}
\newlang{en}
\setartext{arabic}
\setfrtext{french}
\setentext{english}
\setartext{arabic2}
\noindent\print{}
Another text
\end{document}
を使用した別の実装expl3
:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
% User level commands
\NewDocumentCommand{\newlang}{m}
{
\karim_lang_newlang:n { #1 }
}
\DeclareExpandableDocumentCommand{\gettext}{m}
{
\karim_lang_gettext:n { #1 }
}
\NewDocumentCommand{\print}{}
{
\karim_lang_print:
}
% Variables
\seq_new:N \g_karim_lang_langs_seq
\prop_new:N \g_karim_lang_texts_prop
% Internal functions
\cs_new_protected:Nn \karim_lang_newlang:n
{
\seq_gput_right:Nn \g_karim_lang_langs_seq { #1 }
\cs_new:cpn { set#1text } ##1
{
\prop_gput:Nnn \g_karim_lang_texts_prop { #1 } { ##1 }
}
}
\cs_new:Nn \karim_lang_gettext:n
{
\prop_if_in:NnTF \g_karim_lang_texts_prop { #1 }
{
\prop_item:Nn \g_karim_lang_texts_prop { #1 }
}
{
No~text~for~#1~here
}
}
\cs_new_protected:Nn \karim_lang_print:
{
\seq_map_inline:Nn \g_karim_lang_langs_seq
{
\noindent
---##1---\\
\karim_lang_gettext:n { ##1 } \\
*****\par
}
}
\ExplSyntaxOff
\begin{document}
\newlang{ar}
\newlang{fr}
\newlang{en}
\setartext{arabic}
\setfrtext{french}
\setentext{english}
\setartext{arabic2}
\print
This is the text for French: \gettext{fr}
\end{document}
マクロのよりシンプルなバージョン:
\documentclass{article}
\makeatletter
\let\karim@langs\@gobble
\newcommand\newlang[1]{%
\expandafter\def\expandafter\karim@langs\expandafter{\karim@langs,#1}%
\expandafter\newcommand\csname set#1text\endcsname[1]{%
\@namedef{karim@#1@text}{##1}%
}%
}
\newcommand{\gettext}[1]{%
\ifcsname karim@#1@text\endcsname
\@nameuse{karim@#1@text}%
\else
No text for #1!%
\fi
}
\newcommand{\print}{%
\ifx\karim@langs\@gobble
\else
\@for\next:=\karim@langs\do{%
\noindent
---\next---\\
\gettext{\next}\\
******\par
}%
\fi
}
\makeatother
\begin{document}
\newlang{ar}
\newlang{fr}
\newlang{en}
\setartext{arabic}
\setfrtext{french}
\setentext{english}
\setartext{arabic2}
\print
\end{document}
答え3
次のコードは、少し見やすくなっています。
\documentclass{article}
\usepackage{etoolbox}
\makeatletter
\newcommand{\@langs}{}
\newcommand\newlang[1]{%
\xdef\@langs{\@langs,#1}%
\@namedef{set#1text}##1{\@namedef{@#1txt}{##1}}%
}
\newcommand{\printlangs}{%
\renewcommand{\do}[1]{%
\if$##1$\else
\par\noindent
\begin{tabular}{c}
\hline
-- ##1 -- \\
\hline
\ifcsname @##1txt\endcsname
\@nameuse{@##1txt}%
\else
No text specified%
\fi
\\
\hline
\end{tabular}
\par\bigskip
\fi
}
\expandafter\docsvlist\expandafter{\@langs}
}
\makeatother
\begin{document}
\newlang{ar}
\newlang{fr}
\newlang{en}
\setartext{arabic}
\setfrtext{french}
\setartext{arabic2}
\printlangs
Another text
\end{document}
言語はリストに保存され、etoolbox
(見るカンマ区切りのリストを反復処理するにはどうすればいいですか?詳細については)。