5

As the following example showes, there are an extra line-feed which is not needed. Is there a way to eliminate?

Example:

\documentclass{article}
\usepackage{tikz}

\begin{document}
\def\mylist{str1,str2,str3}

\framebox{
  \parbox{4em}{%
    \foreach \x in \mylist {%
      \makebox[4em][s]{\x}\\%
    }%
  }
}

\end{document}

enter image description here

5 Answers 5

6

The problem is that you issue a \\ at the end of each line. You can avoid it e.g. with

\documentclass{article}
\usepackage{tikz}

\begin{document}
\def\mylist{str1,str2,str3}

\framebox{
  \parbox{4em}{%
    \foreach \X [count=\Y]in \mylist {%
      \ifnum\Y=1
        \makebox[4em][s]{\X}
      \else 
        \\ \makebox[4em][s]{\X}%
      \fi
    }%
  }
}

\end{document}

enter image description here

5
  • 1
    A simple and exactly what I want solution! Thank you!
    – lyl
    Commented Feb 17, 2019 at 4:44
  • @lyl You're welcome!
    – user121799
    Commented Feb 17, 2019 at 5:04
  • Normally, \parbox has not the ability to spread align. In this question, we just achieve it by manually add \\ to ensure spread align only for those lengh shorter than defined width. I wonder if there are solutions to spread align text in \parbox autometically?
    – lyl
    Commented Feb 17, 2019 at 5:58
  • @lyl What do you mean by "spread align"? Something like justify? (BTW, will go hibernate now.)
    – user121799
    Commented Feb 17, 2019 at 6:00
  • Yes, just like the option[s] in \makebox. Ok, I'll post another question to illustrate my meaning. Have a nice evening!
    – lyl
    Commented Feb 17, 2019 at 6:04
6

A listofitems alternative...

\documentclass{article}
\usepackage{listofitems}
\begin{document}
\readlist*\mylist{str1,str2,str3}
\framebox{%
  \parbox{4em}{%
    \foreachitem\x\in\mylist[]{%
      \makebox[4em][l]{\x}%
      \ifnum\xcnt<\mylistlen\relax\\\fi%
    }%
  }%
}
\end{document}

enter image description here

or switch the test order:

\documentclass{article}
\usepackage{listofitems}
\begin{document}
\readlist*\mylist{str1,str2,str3}
\framebox{%
  \parbox{4em}{%
    \foreachitem\x\in\mylist[]{%
      \ifnum\xcnt=1\relax\else\\\fi%
      \makebox[4em][l]{\x}%
    }%
  }%
}
\end{document}
0
2

With a conditionnal (minimum code text)

\documentclass{article}
\usepackage{tikz}

\begin{document}

\def\mylist{str1,str2,str3}
\framebox{
  \parbox{4em}{%
    \foreach \x[count=\n] in \mylist {%
      \ifnum \n >1 \\ \fi
      \makebox[4em][s]{\x}%
    }%
  }
}

\end{document}

With an array (just for the fun of it)

\documentclass{article}
\usepackage{tikz}

\begin{document}
\def\mylist{str1,str2,str3}
\def\before{{"\noexpand\\",{}}}
\framebox{
  \parbox{4em}{%
    \foreach \x[count=\n from 0] in \mylist {%
      \pgfmathparse{\before[!\n]}\pgfmathresult
      \makebox[4em][s]{\x}%
    }%
  }
}

\end{document}

Without any conditional ....

\documentclass{article}
\usepackage{tikz}

\begin{document}
\def\mylist{str2,str3}

\framebox{
  \parbox{4em}{%
   str1
    \foreach \x in \mylist {%
      \\\makebox[4em][s]{\x}%
    }%
  }
}

\end{document}
4
  • This is also a fine idea. Thank you. Yet I'm afraid I can't take the first string out of my list.
    – lyl
    Commented Feb 17, 2019 at 5:49
  • I don't understand the use of `\before[!\n]'. why "[ ]" and what the meaning of "!n"?
    – lyl
    Commented Feb 17, 2019 at 10:52
  • I use a array as described on page 999 of the tikz 3.1 manual
    – AndréC
    Commented Feb 17, 2019 at 11:43
  • Thank you for your reply. I'll go through it.
    – lyl
    Commented Feb 17, 2019 at 13:09
1

With the general purpose macro suggested in https://tex.stackexchange.com/a/475291/4427 (slightly modified):

\documentclass[12pt,a4paper]{article}

\usepackage{xparse}
\usepackage{amsmath}

\ExplSyntaxOn

% a general purpose macro for defining other macros
% \makemultiargument* will do a one step expansion of the second argument
\NewDocumentCommand{\makemultiargument}{smmmmm}
 {
  \IfBooleanTF { #1 }
   {
    \projetmbc_multiarg:nonnn { #2 } { #3 } { #4 } { #5 } { #6 }
   }
   {
    \projetmbc_multiarg:nnnnn { #2 } { #3 } { #4 } { #5 } { #6 }
   }
 }

% allocate a private variable
\seq_new:N \l__projetmbc_generic_seq

% the internal version of the general purpose macro
\cs_new_protected:Nn \projetmbc_multiarg:nnnnn
 {% #1 = separator
  % #2 = multiargument
  % #3 = code before
  % #4 = code between
  % #5 = code after

  % a group allows nesting
  \group_begin:
  % split the multiargument into parts
  \seq_set_split:Nnn \l__projetmbc_generic_seq { #1 } { #2 }
  % execute the <code before>
  #3
  % deliver the items, with the chosen material between them
  \seq_use:Nn \l__projetmbc_generic_seq { #4 }
  % execute the <code after>
  #5
  % end the group started at the beginning
  \group_end:
 }
\cs_generate_variant:Nn \projetmbc_multiarg:nnnnn { no }

\ExplSyntaxOff

% separator: ,; before: empty; between: \\, after: empty
\newcommand{\fboxstack}[2][4em]{% #1=width, #2=items
  \fbox{\parbox{#1}{%
    \makemultiargument*{,}{#2}{}{\\}{}%
  }}%
}

\begin{document}

\newcommand{\mylist}{str1,str2,str3}

\fboxstack{\mylist}\qquad\fboxstack[8em]{\mylist}

\end{document}

enter image description here

A variant suggested by your last questions How to make a macro like \parbox with a style of spread align and Automatically justify text in \parbox

\documentclass[12pt,a4paper]{article}

\usepackage{xparse}
\usepackage{amsmath}

\ExplSyntaxOn

% a general purpose macro for defining other macros
% \makemultiargument* will do a one step expansion of the second argument
\NewDocumentCommand{\makemultiargument}{smmm+mm}
 {
  \IfBooleanTF { #1 }
   {
    \projetmbc_multiarg:nonnn { #2 } { #3 } { #4 } { #5 } { #6 }
   }
   {
    \projetmbc_multiarg:nnnnn { #2 } { #3 } { #4 } { #5 } { #6 }
   }
 }

% allocate a private variable
\seq_new:N \l__projetmbc_generic_seq

% the internal version of the general purpose macro
\cs_new_protected:Nn \projetmbc_multiarg:nnnnn
 {% #1 = separator
  % #2 = multiargument
  % #3 = code before
  % #4 = code between
  % #5 = code after

  % a group allows nesting
  \group_begin:
  % split the multiargument into parts
  \seq_set_split:Nnn \l__projetmbc_generic_seq { #1 } { #2 }
  % execute the <code before>
  #3
  % deliver the items, with the chosen material between them
  \seq_use:Nn \l__projetmbc_generic_seq { #4 }
  % execute the <code after>
  #5
  % end the group started at the beginning
  \group_end:
 }
\cs_generate_variant:Nn \projetmbc_multiarg:nnnnn { no }

\ExplSyntaxOff

% separator: ,; before: empty; between: \\, after: empty
\newcommand{\fboxstack}[2][4em]{% #1=width, #2=items
  \fbox{\parbox{#1}{%
    \setlength{\parfillskip}{0pt}%
    \hbadness 10000 % no warning about underfull boxes
    \makemultiargument*{,}{#2}{}{\par}{}%
  }}%
}

\begin{document}

\newcommand{\mylist}{test ab,ab cd,de fg}

\fboxstack{\mylist}\qquad\fboxstack[8em]{\mylist}

\end{document}

enter image description here

1
  • Oh, many thanks for your continuous support!!
    – lyl
    Commented Feb 17, 2019 at 11:14
1

This is an answer to an old question, but since all the previous answers use counter-based conditionals, I propose, for the sake of completeness, a solution based on redefining macros.

\documentclass[varwidth, border=7pt]{standalone}
\usepackage{pgffor}

\begin{document}
  \def\mylist{str1,str2,str3}

  \framebox{
    \parbox{4em}{%
      \foreach[remember=\newline as \mynewline (initially \relax)] \x in \mylist {%
        \mynewline\makebox[4em][s]{\x}%
      }%
    }
  }
\end{document}

enter image description here

And the same result can be obtained with classical \def & \gdef.

\documentclass[varwidth, border=7pt]{standalone}
\usepackage{pgffor}

\begin{document}
  \def\mylist{str1,str2,str3}

  \framebox{
    \parbox{4em}{%
      \def\mynewline{}%
      \foreach \x in \mylist {%
        \mynewline\makebox[4em][s]{\x}%
        \gdef\mynewline{\newline}%
      }%
    }
  }
\end{document}

Note: the \gdef is need here because \foreach creates a group. If we want to avoid this we can use the first solution or another loop, like \xintFor.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .