8

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. The first question needs your genius yet.

  • Generally, once an original question is adequately answered, it is preferable to ask follow ups as a new, separate question (while referring to the original question). That way, you will likely get new sets of eyes upon the new question. If a question is answered adequately, the protocol is to click the big check mark next to that answer. That generally signifies that a question is complete. – Steven B. Segletes Feb 5 '15 at 1:04
  • However, I will give thought to your follow up... – Steven B. Segletes Feb 5 '15 at 1:06
  • Thanks for your help. I have solve the 2nd question by define a new command . The first question is not solved yet. \def\mulanp{\expandafter\mulan{\par}} \mulanp{MyJapanese}{MyChinese}{MyEnglish} – Jilong Yin Feb 10 '15 at 6:16
  • Don't change your question so that it invalidates the already given answers. Please, open a new question stating precisely the specifications. – egreg Feb 10 '15 at 9:18
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

  • 1
    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 4 '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 4 '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 5 '15 at 1: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 5 '15 at 1: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 5 '15 at 1:53
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.

  • 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 8:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.