解析以逗号分隔的命令参数

解析以逗号分隔的命令参数

我想在我的文档中混合几种语言,并且可以根据相应的变量选择输出语言

我想定义这种命令 \mulan[en,fr,ru]{arg1}{arg2}{arg3}

回来

\en{arg1} / \fr{arg2} /\ru{arg3}

以下是我的基本框架,但我不知道如何进行。

\documentclass{article}

\usepackage{xifthen}


\newif\ifen % if English
\newif\iffr % if French
\newif\ifru % if Russia
\newif\ifcn % if Chinese
\newif\ifjp % if Japanese



\newcommand{\en}[1]{\ifen#1\fi}
\newcommand{\fr}[1]{\ifen#1\fi}
\newcommand{\ru}[1]{\ifru#1\fi}
\newcommand{\cn}[1]{\ifcn#1\fi}
\newcommand{\jp}[1]{\ifjp#1\fi}

%specify the multi languge sequence variable globaly
\def\mulanseq#1{\gdef\mymulanseq{#1}}
\newcommand{\mymulanseq}[2]{#1 #2}

\newcommand{\mulan}[2][]{
    \mymulan{\ifthenelse{\isempty{#1}}{\mymulanseq}{#1}}{#2}
}

\makeatletter
\newcommand{\mymulanp}[2]
{

 (#1): #2  
 
}


\begin{document}

%choose output language
\entrue
\jptrue
\cnfalse

%define default language sequence
\mulanseq{en,jp,cn}

%explain the three sententces according default language sequence
\mulan{en-sentence}{jp-sentence}{cn-sentence}

%explain the three sententces according given language sequence
\mulan[cn,jp,en]{sentence-A}{sentence-B}{sentence-C}

%deal with variable number sentence
% only 1 sentence should be explained using the first language specification
\mulan{sentence-A}

% only 1 sentence should be explained using the first language specification
\mulan{sentence-A}{sentence-B}


\end{document}

非常感谢 Steven。完美解决了我的问题。

我还能要求更多吗?

为了使命令更加实用,需要\mulan[en,ru,fr,...]{s1}{s2}{s3}另一个分隔参数。\mysep

\mulan[en,ru,fr,...]{\mysep}{s1}{s2}{s3} 

例如,关于以下命令

\mulan[en,ru,fr]{\mysep}{s1}{s2}{s3}  

将输出

 s1 \mysep s2 \mysep s3     

(注意: 末尾s3没有\mysep

当其中一种语言被关闭时,相应的分隔符也不会出现。

\entrue
\rufalse
\frtrue
\mulan[en,ru,fr]{\mysep}{s1}{s2}{s3}  

将输出

 s1 \mysep s3     

如果命令

\entrue
\rutrue
\frfalse
\mulan[en,ru,fr]{\mysep}{s1}{s2}{s3}  

将给出输出

s1 \mysep s2

2015/02/10

非常感谢,史蒂文。

我认为您定义的命令\mulan应该具有以下完整格式:

\mulan[en,jp,cn]{seperator}{Language-1}{Language-2}{Language-3}

为了在实际使用中更加方便,我想定义几个简化版本\mulan

例如,

  1. 如果没有给出语言序列,命令\mulan将使用全局变量给出的默认语言序列,例如\mulanseq

    \mulanseq{jp,cn,en}
    \mulan{+++}{MyJapanese}{MyChinese}{MyEnglish}
    
  2. 我想\mulanp为定义一个别名命令\mulan,它将为不同的语言内容提供一些单独的段落。就像:

    \newcommand\mulanp#1{\mulan{\par}{#1}}
    \newcommand\mulanr#1{\mulan{\space/\space}{#1}}
    

这样我就可以在正文中输入更少的重复内容。另外,如果未在 中指定语言顺序\mulanp,则将使用默认顺序。

虽然我正在学习使用 LaTeX 编程,并尝试阅读和修改您的程序以供专用,但我还远不能很快彻底理解您的程序。

你愿意给我更多帮助吗?

注:对于上述问题2,我通过以下方式实现

\def\mulanp{\expandafter\mulan{\par}}
\mulanp{MyJapanese}{MyChinese}{MyEnglish}

看起来还不错,但第一个问题还需要你的天赋。

答案1

在事先不知道参数数量的情况下,我花了一些时间才弄清楚如何做到这一点。关键是在列表末尾\mulan插入一个伪参数(在本例中为) ,该参数被转换为,并用于关闭进程。relax\langcmd\relax

事实证明,我不需要任何包。已编辑以添加默认语言序列。

\documentclass{article}
\newcounter{args}
\newcommand\mulan[1][en,jp,cn]{%
  \setcounter{args}{0}%
  \commaparse#1,\relax%
  \stepcounter{args}%
  \expandafter\def\csname arg\romannumeral\value{args}\endcsname{relax}
  \setcounter{args}{0}%
  \langcmd%
}
\def\commaparse#1,#2\relax{%
  \stepcounter{args}%
  \expandafter\def\csname arg\romannumeral\value{args}\endcsname{#1}%
  \if\relax#2\else\commaparse#2\relax\fi%
}
\newcommand\langcmd{%
  \stepcounter{args}%
    \csname\csname arg\romannumeral\value{args}\endcsname\endcsname%
}
\def\en#1{Run en on #1!\langcmd}
\def\fr#1{Run fr on #1!\langcmd}
\def\ru#1{Run ru on #1!\langcmd}
\def\jp#1{Run jp on #1!\langcmd}
\def\cn#1{Run cn on #1!\langcmd}
\begin{document}
\mulan[en,fr,ru]{arg1}{arg2}{arg3} Following text\par
\mulan[fr,jp]{arg1}{arg2} Next\par
\mulan[en]{arg1} and so on\par
\mulan[en,fr,ru,jp]{arg1}{arg2}{arg3}{arg4} ...\par
%explain the three sententces according default languajp sequence
\mulan{en-sentence}{jp-sentence}{cn-sentence}\par
\mulan[cn,jp,en]{sentence-A}{sentence-B}{sentence-C}
\end{document}

在此处输入图片描述


跟进:

在这里,我针对此修改后的解决方案击中了 OP 的后续要点:

  1. 我采用了额外的强制性第一个参数,它是答案之间的分隔符(但不在第一个答案之前,也不在最后一个答案之后)。

  2. 我已经编辑了处理 if 条件来关闭语言;

  3. 后来,REEDIT 允许将默认序列放在 中\def,而不是明确指定。它要求在 的定义中\expandafter在 的调用之前添加。\commaparse\mulan

这是修订后的 MWE。

\documentclass{article}
\newcounter{args}
\def\defaultsequence{en,jp,cn}
\newcommand\mulan[2][\defaultsequence]{%
  \gdef\thesep{#2}%
  \setcounter{args}{0}%
  \expandafter\commaparse#1,\relax%
  \stepcounter{args}%
  \expandafter\def\csname arg\romannumeral\value{args}\endcsname{relax}%
  \setcounter{args}{0}%
  \langcmd%
}
\def\commaparse#1,#2\relax{%
  \stepcounter{args}%
  \expandafter\def\csname arg\romannumeral\value{args}\endcsname{#1}%
  \if\relax#2\else\commaparse#2\relax\fi%
}
\newcommand\langcmd{%
  \stepcounter{args}%
  \csname\csname arg\romannumeral\value{args}\endcsname\endcsname%
}
\newcommand\callsep{\ifnum\value{args}>1\thesep\fi}

\newif\ifen \newif\iffr \newif\ifru \newif\ifjp \newif\ifcn
\def\en#1{\ifen\callsep Run \textbf{en} on ``#1''!\fi\langcmd}
\def\fr#1{\iffr\callsep Run \textbf{fr} on ``#1''!\fi\langcmd}
\def\ru#1{\ifru\callsep Run \textbf{ru} on ``#1''!\fi\langcmd}
\def\jp#1{\ifjp\callsep Run \textbf{jp} on ``#1''!\fi\langcmd}
\def\cn#1{\ifcn\callsep Run \textbf{cn} on ``#1''!\fi\langcmd}
\parskip 1em\relax
\parindent 0pt\relax
\begin{document}
\entrue\frtrue\rufalse\jptrue\cntrue
\mulan[en,fr,ru,cn]{---}{arg1}{arg2}{arg3}{arg4}\par
\rutrue
\mulan[en,fr,ru,cn]{---}{arg1}{arg2}{arg3}{arg4}\par
BEFORE \mulan{\\}{en-sentence}{jp-sentence}{cn-sentence} NEXT!
\end{document}

在此处输入图片描述

答案2

我会尝试使用不同的语法,其中参数与语言键绑定:

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\mulan}{m}
 {
  \group_begin:
  \keys_set:nn { yin/mulan } { #1 }
  \seq_use:NV \l_yin_mulan_args_seq \l_yin_mulan_sep_tl
  \group_end:
 }

\NewDocumentCommand{\enablelan}{m}
 {
  \clist_map_inline:nn { #1 }
   {
    \bool_set_true:c { l_yin_mulan_##1_bool }
   }
 }

\NewDocumentCommand{\disablelan}{m}
 {
  \clist_map_inline:nn { #1 }
   {
    \bool_set_false:c { l_yin_mulan_##1_bool }
   }
 }

\cs_generate_variant:Nn \seq_use:Nn { NV }

\seq_new:N \l_yin_mulan_args_seq
\bool_new:N \l_yin_mulan_en_bool
\bool_new:N \l_yin_mulan_fr_bool
\bool_new:N \l_yin_mulan_ru_bool
\bool_new:N \l_yin_mulan_cn_bool
\bool_new:N \l_yin_mulan_jp_bool

\keys_define:nn { yin/mulan }
 {
  sep .tl_set:N = \l_yin_mulan_sep_tl,
  sep .initial:n = { --- },
  en .code:n = \__mulan_append_lang:nn { en } { #1 },
  fr .code:n = \__mulan_append_lang:nn { fr } { #1 },
  ru .code:n = \__mulan_append_lang:nn { ru } { #1 },
  cn .code:n = \__mulan_append_lang:nn { cn } { #1 },
  jp .code:n = \__mulan_append_lang:nn { jp } { #1 },
 }

\cs_new_protected:Npn \__mulan_append_lang:nn #1 #2
 {
  \bool_if:cT { l_yin_mulan_#1_bool }
   {
    \seq_put_right:Nn \l_yin_mulan_args_seq
     {
      \use:c { mulan#1 } { #2 }
     }
   }
 }
\ExplSyntaxOff

\newcommand{\mulanen}[1]{Run \textbf{en} on ``#1''!}
\newcommand{\mulanfr}[1]{Run \textbf{fr} on ``#1''!}
\newcommand{\mulanru}[1]{Run \textbf{ru} on ``#1''!}
\newcommand{\mulanjp}[1]{Run \textbf{jp} on ``#1''!}
\newcommand{\mulancn}[1]{Run \textbf{cn} on ``#1''!}

\begin{document}

\section{A}
\enablelan{en,fr,jp,cn}

\mulan{
  en=arg1,
  fr=arg2,
  ru=arg3,
  cn=arg4,
}

\section{B}
\enablelan{ru}

\mulan{
  en=arg1,
  fr=arg2,
  ru=arg3,
  cn=arg4,
}

\section{C}
\disablelan{fr}

\mulan{
  en=arg1,
  fr=arg2,
  ru=arg3,
  cn=arg4,
}

\section{D}

BEFORE 
\mulan{
  sep=\\,
  en=en-sentence,
  jp=jp-sentence,
  cn=cn-sentence,
}
NEXT!

\end{document}

短语将按照参数中指定的顺序打印(如果启用了语言)。如果希望使用固定的语言顺序,可以(相当容易地)修改宏来实现它。

您只需要为\mulan<lang>宏提供合理的定义。如何添加语言标签应该是不言自明的。

相关内容