9

I want to mix several language in my document, and the output language can be chosen according to corresponding variable

I want to define this kind of command \mulan[en,fr,ru]{arg1}{arg2}{arg3}

to return

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

The following is my basic frame, but I don't know how I can proceed.

\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}


Big thanks to Steven. Perfectly solved my question.

Can I requrie more than this?

To make the command \mulan[en,ru,fr,...]{s1}{s2}{s3} more practical, another seperating args \mysep is wanted.

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

For example, concerning the following commands

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

will output

 s1 \mysep s2 \mysep s3     

(note: at the end of the s3, there is no \mysep)

When one of the languages is turned off, the corresponding seperator does not occur either.

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

will output

 s1 \mysep s3     

and if the commands

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

will give output

s1 \mysep s2

2015/02/10

Thanks a lot, .Steven.

I think the command you defined, \mulan should have the following full format:

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

For more convience in practical use, I want to define several simplified version for the \mulan

For example,

  1. if the language sequence is not given, the command \mulan will use default language sequence given by a global variable, such as \mulanseq

    \mulanseq{jp,cn,en}
    \mulan{+++}{MyJapanese}{MyChinese}{MyEnglish}
    
  2. I want to define an alias command \mulanp for \mulan, which will give some paragrah sepeprated for different language contents. Just like:

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

So that I can input less duplicate contents in my main text. Also, if the language sequence is not specified in \mulanp, the default sequence will be used.

Though I am learning programing in LaTeX and I am trying to read and modify your program for dedicated uses, it is far for me to understand thoroughly your program soon.

Would you like to give me more help?

Note: for the above question 2, I have realized by the following

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

It looks o.k. but the first question needs your genius yet.

sRavioli
  • 136

2 Answers2

6

It took some time to figure out how to do it without knowing the number of arguments in advance. The key was to have \mulan insert a dummy argument, in this case relax, at the end of the list, which got transformed by \langcmd to \relax, and was used to shut down the process.

And, as it turned out, I didn't need any packages. EDITED to add default language sequence.

\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}

enter image description here


FOLLOW UP:

Here I hit the points of the OP's follow up with this modified solution:

  1. I take an additional mandatory 1st argument which is the separator between answers (but not before the first nor after the last).

  2. I have EDITED to handle if-conditionals to turn off languages;

  3. Much later REEDIT to allow the default sequence to placed in a \def, rather than be explicitly specified. It required the addition of \expandafter before the invocation of \commaparse in the definition of \mulan.

Here is the revised 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}

enter image description here

  • 2
    You are really a talent! I appreciate you so much. You help me a lot. I hope one day I can become so strong as you. – Jilong Yin Feb 04 '15 at 14:18
  • 1
    @JilongYin Thank you for the kind words. Best wishes to you and your family, proudly displayed in your icon. – Steven B. Segletes Feb 04 '15 at 15:03
  • I want to make your \mulang command more practical by adding another \mysep argument for it. Could you please take a look at the end of my original question? Thanks a lot. – Jilong Yin Feb 05 '15 at 01:01
  • @JilongYin I have updated my answer to provide the separator; However, I have not addressed the if-conditions you mention. – Steven B. Segletes Feb 05 '15 at 01:29
  • @JilongYin I have edited my update to provide both a separator s well as the if conditionals to turn off languages. – Steven B. Segletes Feb 05 '15 at 01:53
  • I try to add the if-conditions in your program(showed in the end of my original question, but it looks like the output is not exactly I want. Could you kindly please check it for me? Sorry to take you so much time. – Jilong Yin Feb 05 '15 at 01:55
  • @JilongYin I moved the \ifnum checks out of \langcmd macro and placed it in \callsep, which is called after the \ifru style conditions. This avoids having the separator print when the condition is false. See my update. – Steven B. Segletes Feb 05 '15 at 02:03
  • Sorry, I missed your coment after you add if-condtions. It looks like it works exactly correct. Pls admit me to use your program in my document. – Jilong Yin Feb 05 '15 at 02:03
  • @JilongYin with my blessing. – Steven B. Segletes Feb 05 '15 at 02:04
  • Would you like to strengthen your \mulan command by permitting a default language sequence like \mulanseq{en,jp,cn} \mlan{---}{arg1}{arg2}{arg3} . Even a new command name is also OK. In this way, the input in main text can be simplified a lot. Thanks in advance. – Jilong Yin Feb 10 '15 at 06:06
  • @JilongYin It is already set up for the default language sequence [en,jp,cn], which you can see as the default argument to my implementation of \mulan. – Steven B. Segletes Feb 10 '15 at 10:54
  • Thank you. Steven. I have noticed that. Actually, I want to put your \mulan command into a seperate .sty file. I don't want to edit that each time. Also, in my big document, in some paragraphs, e.g., they are mainly in English,Japanese, Chinese. But in some other paragrahs, they are mainly in Other languages. I want to a command to modify the language sequence conviently. – Jilong Yin Feb 12 '15 at 02:55
  • @JilongYin That is easy. Just \def\defaultsequence{en,jp,cn} in the preamble and define \newcommand\mulan[2][\defaultsequence]{...}. Then, when you wish, you can redefine \defaultsequence, for example, \def\defaultsequence{ru,jp,cn}. – Steven B. Segletes Feb 12 '15 at 10:54
  • It seems that it does not work well when the seperator is \ (or new paragrah). Could you check it. – Jilong Yin Feb 24 '15 at 09:13
  • @JilongYin I'm sorry, but it seems to work for me. You will ntice the last example in my MWE has \\ as the separator and that works. If I replace the \\ with \par, it also works. – Steven B. Segletes Feb 24 '15 at 10:56
  • I mean if you define \defaultsequence in preamble and replace the [en,jp,cn] with it in the \mulan defintion . It can not work fine when the seperator is \. – Jilong Yin Feb 24 '15 at 23:51
  • @JilongYin You can do what you suggest if you change the \commaparse#1,\relax% line in the \mulan definition to \expandafter\commaparse#1,\relax%. – Steven B. Segletes Feb 25 '15 at 01:05
  • @JilongYin Please see FOLLOW UP in revised answer. I have made this part of the revised code. – Steven B. Segletes Feb 25 '15 at 01:12
4

I'd try with a different syntax, where the arguments are tied to the language keys:

\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}

The phrases are printed (if the language is enabled) in the order they're specified in the argument. If a fixed language order is preferred, the macros can be (quite easily) modified to accomplish it.

You just need to provide sensible definitions for the \mulan<lang> macros. How to add language tags should be self-explaining.

egreg
  • 1,121,712
  • Also thanks for your solution. It really works. But when the sentence given in different language becomes very long, the key-value assignment seems a little unclear in document. Maybe your solution is very good for simple single sentence. – Jilong Yin Feb 24 '15 at 08:55