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

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

  • 1
    A simple and exactly what I want solution! Thank you! – lyl Feb 17 at 4:44
  • @lyl You're welcome! – marmot Feb 17 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 Feb 17 at 5:58
  • @lyl What do you mean by "spread align"? Something like justify? (BTW, will go hibernate now.) – marmot Feb 17 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 Feb 17 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}
2

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

  • Oh, many thanks for your continuous support!! – lyl Feb 17 at 11:14
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}
  • This is also a fine idea. Thank you. Yet I'm afraid I can't take the first string out of my list. – lyl Feb 17 at 5:49
  • I don't understand the use of `\before[!\n]'. why "[ ]" and what the meaning of "!n"? – lyl Feb 17 at 10:52
  • I use a array as described on page 999 of the tikz 3.1 manual – AndréC Feb 17 at 11:43
  • Thank you for your reply. I'll go through it. – lyl Feb 17 at 13:09

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.