# How to do something after @ifnextchar?

In my LaTeX file, I'm using \usepackage{indentfirst}.

And there I've defined a command:

% ################################################## %
% Coding skills
% ---------- Usage example ----------
% \codingskills{Fortran}{C}{Java}{Kotlin}{Swift}
% ################################################## %
\def\codingskills#1{\faCode\space#1\@ifnextchar\bgroup{\iteratenextskill}{, etc.}}
\def\iteratenextskill#1{, #1\@ifnextchar\bgroup{\iteratenextskill}{, etc.}}



This would output the content as my expectation, just like below:

However, I'd like to align the indent for all lines. So I've tried to add \noindent\setlength{\leftskip}{1.5em} before and reset the length afterwards. The setlength in the code before works smoothly, but the reset (\setlength{\leftskip}{0em}) in the code after completely breaks everything. Because it has been taken (parsed) as part of @ifnextchar. Below is the code snippet and I've simply used {!!!!!} to demonstrate the parsing problem: I'd like to parse the {!!!!!} at the end of this command (a.k.a. do the reset length processing in the end), but not right after iterating the first argument.

\def\codingskills#1{\noindent\setlength{\leftskip}{1.5em}\faCode\space#1\@ifnextchar\bgroup{\iteratenextskill}{, etc.}{!!!!!}}
\def\iteratenextskill#1{, #1\@ifnextchar\bgroup{\iteratenextskill}{, etc.}}


Could anyone kindly help tell me where should I put the after reset length code please? Thanks in advance.

I've tried putting to the end of iteratenextskill, even worse. So did \newenvironment block, same effect like above screenshot.

• Just a friendly note: If you want to show your skills and include LaTeX, it might be a good idea to use \LaTeX instead of Latex :) – Skillmon Jun 30 '19 at 17:16
• You're right, my bad :) Actually this is a demo, I don't have proper LaTeX skill by myself :P – Jing Li Jun 30 '19 at 18:01

You have to include the \setlength instruction into the second argument of \@ifnextchar, you'll need to add a \par prior to it, though, or else your \setlength{\leftskip}{1.5em} wouldn't have an effect. So you'd use:

\def\codingskills#1{\noindent\setlength{\leftskip}{1.5em}\faCode\space#1\@ifnextchar\bgroup{\iteratenextskill}{, etc.\par\setlength{\leftskip}{0pt}}}
\def\iteratenextskill#1{, #1\@ifnextchar\bgroup{\iteratenextskill}{, etc.\par\setlength{\leftskip}{0pt}}


For some reasons I'm not quite sure about, I'd structure the macros slightly different though (one argument being no duplicate code):

\documentclass[]{article}

\def\faCode{\textless/\textgreater}

\makeatletter
\newcommand*\codingskills[1]
{%
\par\noindent\setlength{\leftskip}{1.5em}\faCode\space#1\iteratenextskill
}
\newcommand*\iteratenextskill
{%
, \@ifnextchar\bgroup{\iteratenextskill@}{\endskill}%
}
\newcommand*\iteratenextskill@[1]
{%
#1\iteratenextskill
}
\newcommand*\endskill
{%
etc.\par\setlength{\leftskip}{0pt}%
}
\makeatother

\begin{document}
\codingskills{Java}{JavaScript}{Python}{Ruby}{C}{C++}{C\#}{RESTful
\end{document}


Note however, that the interface of taking arbitrarily many braced arguments is frowned upon, so I'd instead use a comma separated list as input, you can specify additional formatting in the second argument of \clist_map_inline:nn, note that in the range of \ExplSyntaxOn spaces are ignored and ~ is a space.

\documentclass[]{article}

\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand \codingskills { m }
{
\tex_par:D
\tex_noindent:D
\dim_set:Nn \leftskip { 1.5em }
\faCode
\clist_map_inline:nn { #1 } { ~ ##1, } ~ etc.
\tex_par:D
\dim_set:Nn \leftskip { 0pt }
}
\ExplSyntaxOff

\def\faCode{\textless/\textgreater}

\begin{document}
\codingskills{Java, JavaScript, Python, Ruby, C, C++, C\#, RESTful
API, gRPC, Microservice, Latex, Fortran, Go, Erlang, Elixir, Haskell, Rust, R}
\end{document}

• Thanks a bunch @Skillmon! I don't know why you are not quite sure about it, actually your 1st solution perfectly solved my issue (tested with different cases). So the trick is just dropping a \par to start a new paragraph right before setting the length to 0? So that the parsing of new argument would not apply to it? I'm sorry that I didn't get enough time to check your 2nd enhanced solution because the 1st one is good enough and effortless to me. While I'm pretty sure your time is not wasted, it must be helpful for someone else. I'll leave it like this for now, though I prefer foreach. – Jing Li Jun 30 '19 at 16:14
• I realized that you're living in Germany, and I'm in Berlin. Please drop me a line (twitter.com/thyrlian) when you're free for a drink, I owe you a beer. Vielen Dank! – Jing Li Jun 30 '19 at 16:16
• @JingLi I'm not a social media user, so that might be problematic :) If we ever meet in person you can buy me a beer, we don't have to arrange things to make it happen. A paragraph is typeset with the \leftskip in effect at its end, that's why we have to put a \par before \setlength{\leftskip}{0pt}. – Skillmon Jun 30 '19 at 17:15