9

Consider the following example:

\documentclass{article}

\usepackage[
  a4paper,
  hmargin = 2.4cm,
  vmargin = 3cm
]{geometry}        % https://ctan.org/pkg/geometry
\usepackage{xskak} % https://ctan.org/pkg/xskak

\newcommand*\hestA[2][\svarstedA]{%
  \underline{\makebox[\ifdim\width>#1\width\else#1\fi]{#2}}}
\newcommand*\opgaverLoesningerA[1]{\hestA{\textcolor{blue}{#1}}}
\newcommand*\opgaverLoesningerEkstra[6]{%
  \def\tempA{#1}%
  \def\tempB{#2}%
  \def\tempC{#3}%
  \def\tempD{#4}%
  \def\tempE{#5}%
  \def\tempF{#6}%
  \opgaverLoesninger
}
\newcommand*\opgaverLoesninger[6]{%
\begin{figure}[!htbp]
 \centering
  \begin{minipage}{0.5\textwidth}
   \centering
    \newgame
    \fenboard{\tempB \tempA - - 0 1}%
    \scalebox{1.2}{\showboard}%
    \vspace*{2ex}

    {\LARGE Løsning: \opgaverLoesningerA{\tempC}}%
  \end{minipage}%
  \begin{minipage}{0.5\textwidth}
   \centering
    \newgame
    \fenboard{\tempE \tempD - - 0 1}%
    \scalebox{1.2}{\showboard}%
    \vspace*{2ex}

    {\LARGE Løsning: \opgaverLoesningerA{\tempF}}%
  \end{minipage}
\end{figure}
\vspace*{2ex}

\begin{figure}[!htbp]
 \centering
  \begin{minipage}{0.5\textwidth}
   \centering
    \newgame
    \fenboard{#2 #1 - - 0 1}%
    \scalebox{1.2}{\showboard}%
    \vspace*{2ex}

    {\LARGE Løsning: \opgaverLoesningerA{#3}}%
  \end{minipage}%
  \begin{minipage}{0.5\textwidth}
   \centering
    \newgame
    \fenboard{#5 #4 - - 0 1}%
    \scalebox{1.2}{\showboard}%
    \vspace*{2ex}

    {\LARGE Løsning: \opgaverLoesningerA{#6}}%
  \end{minipage}
\end{figure}}

\begin{document}

\opgaverLoesninger%
  {w}{6k1/6p1/1p5p/3r4/1P6/6P1/4B1KP/8}{Lc4}%
  {w}{1k6/pp6/2p3p1/4n1P1/8/P6P/KP1B4/8}{Lf4}%
  {w}{8/1p4kp/p5p1/B7/3n4/1P5P/2P3P1/6K1}{Lc3}%
  {w}{k7/p6p/1p4p1/3r4/1P5P/P5P1/1KB5/8}{Le4}

\end{document}

When I compile using xelatex, I get the error

! Paragraph ended before \FenBoard was complete.
<to be read again> 
                   \par 
l.73   {w}{1k6/pp6/2p3p1/4n1P1/8/P6P/KP1B4/8}{Lf4}
                                                  %

Can anyone help me fix this?

P.S. I think it is related to the fact that I try to have more than 9 arguments (here it is 12 arguments) in my macro but I am not sure.

  • 2
    Your \opgaverLoesningerEkstra is never called and o \tempB is undefined at the first \fenboard. Beside this I don't understand what you are trying to do and imho commands with more than 3 or 4 arguments are madness. – Ulrike Fischer Nov 5 '17 at 16:50
  • 6
    you can not have nore than 9 arguments but you shouldn't ever need more than 2 or 3. use a comma or \\ separated list to allow arbitrary arguments \foo{a,b,c,d,e,f,g,h,i,j,k} one argument with a list, not \foo{a}{b}{c}{d}{e}{f}{g}{h}{i}{j}{k} – David Carlisle Nov 5 '17 at 16:53
  • 1
    What I like to do is pass macros as arguments, and each of those can have up to 8 arguments. Is 64 enough? – John Kormylo Nov 5 '17 at 16:54
  • Related/duplicate: How to define a command that takes more than 9 arguments – Werner Nov 5 '17 at 17:24
  • @JohnKormylo shouldn't it be 9 times 9 so 81 arguments? – Skillmon Nov 5 '17 at 18:31
7

What about having five boards to draw? Or eight?

Here's an implementation that accepts any number of boards and outputs them in pairs in figure environments. If the number is odd, the last one is output by itself in another figure.

\documentclass{article}
\usepackage[
  a4paper,
  hmargin = 2.4cm,
  vmargin = 3cm
]{geometry}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{xcolor}
\usepackage{xparse}
\usepackage{xskak}

\setchessboard{smallboard}

\ExplSyntaxOn

\NewDocumentCommand{\opgaverLoesninger}{m}
 {
  \svend_opgaver_loesninger:n { #1 }
 }

\tl_new:N \l__svend_opgaver_final_tl
\seq_new:N \l__svend_opgaver_tables_in_seq
\seq_new:N \l__svend_opgaver_tables_out_seq

\cs_new_protected:Nn \svend_opgaver_loesninger:n
 {
  \seq_set_split:Nnn \l__svend_opgaver_tables_in_seq { \\ } { #1 }
  \seq_clear:N \l__svend_opgaver_tables_out_seq
  \seq_map_inline:Nn \l__svend_opgaver_tables_in_seq
   {
    \seq_put_right:Nx \l__svend_opgaver_tables_out_seq
     {
      \__svend_opgaver_board:nn
       { \clist_item:nn { ##1 } { 1 } } 
       { \clist_item:nn { ##1 } { 2 } } 
      \__svend_opgaver_caption:n { \clist_item:nn { ##1 } { 3 } }
     }
   }
  \__svend_opgaver_make_tables:
 }

\cs_new_protected:Nn \__svend_opgaver_board:nn
 {
  \newgame
  \fenboard{#2 ~ #1 ~ - ~ - ~ 0 ~ 1 }
 }

\cs_new_protected:Nn \__svend_opgaver_caption:n
 {
  \scalebox{1.2}{\showboard}\par
  \vspace*{2ex}
  {\LARGE Løsning: ~ \textcolor{blue}{#1}}
 }

\cs_new_protected:Nn \__svend_opgaver_make_tables:
 {
  \tl_clear:N \l__svend_opgaver_final_tl
  \int_if_odd:nT { \seq_count:N \l__svend_opgaver_tables_out_seq }
   {
    \seq_pop_right:NN \l__svend_opgaver_tables_out_seq \l__svend_opgaver_final_tl
   }
  \int_step_inline:nnnn { 1 } { 2 } { \seq_count:N \l__svend_opgaver_tables_out_seq }
   {
    \begin{figure}[!htbp]
    \begin{minipage}[b]{0.5\textwidth}
    \centering
    \seq_item:Nn \l__svend_opgaver_tables_out_seq { ##1 }
    \end{minipage}
    \begin{minipage}[b]{0.5\textwidth}
    \centering
    \seq_item:Nn \l__svend_opgaver_tables_out_seq { ##1+1 }
    \end{minipage}
    \end{figure}
   }
   \tl_if_empty:NF \l__svend_opgaver_final_tl
   {
    \begin{figure}[!htbp]
    \centering
    \tl_use:N \l__svend_opgaver_final_tl
    \end{figure}
   }
 }

\ExplSyntaxOff

\begin{document}

\opgaverLoesninger{
  w, 6k1/6p1/1p5p/3r4/1P6/6P1/4B1KP/8, Lc4 \\
  w, 1k6/pp6/2p3p1/4n1P1/8/P6P/KP1B4/8, Lf4 \\
  w, 8/1p4kp/p5p1/B7/3n4/1P5P/2P3P1/6K1, Lc3 \\
  w, k7/p6p/1p4p1/3r4/1P5P/P5P1/1KB5/8, Le4 \\
  w, k7/p6p/1p4p1/3r4/1P5P/P5P1/1KB5/8, Le4
}

\end{document}

Instead of a syntax with braces, separating boards with \\ and data in each one with commas is simpler and more readable.

enter image description here

enter image description here

With slight changes, you can also set the magnification for the boards (default 1.2) and the number of boards per row (default 2).

The magnification is changed with mag=<factor>, the number of boards per row is set with n=<number> in the optional argument to \opgaverLoesninger.

The option single (a boolean, single=true is implicit) will make a single figure environment, but you're responsible for it to fit on a page, of course. It is present in the example just by way of example. If you try \opgaverLoesninger[single]{...} (same mandatory argument for five boards), the float will be too large (not with four boards).

\documentclass{article}
\usepackage[
  a4paper,
  hmargin = 2.4cm,
  vmargin = 3cm
]{geometry}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{xcolor}
\usepackage{xparse}
\usepackage{xskak}

\setchessboard{smallboard}

\ExplSyntaxOn

\NewDocumentCommand{\opgaverLoesninger}{O{}m}
 {
  \keys_set:nn { svend/opgaver } { n=2, mag=1.2, single=false, #1 }
  \svend_opgaver_loesninger:n { #2 }
 }

\keys_define:nn { svend/opgaver }
 {
  n      .int_set:N  = \l__svend_opgaver_n_int,
  mag    .tl_set:N   = \l__svend_opgaver_mag_tl,
  single .bool_set:N = \l__svend_opgaver_single_bool,
  single .default:n  = true,
 }

\tl_new:N \l__svend_opgaver_final_tl
\seq_new:N \l__svend_opgaver_tables_in_seq
\seq_new:N \l__svend_opgaver_tables_out_seq

\cs_new_protected:Nn \svend_opgaver_loesninger:n
 {
  \seq_set_split:Nnn \l__svend_opgaver_tables_in_seq { \\ } { #1 }
  \seq_clear:N \l__svend_opgaver_tables_out_seq
  \seq_map_inline:Nn \l__svend_opgaver_tables_in_seq
   {
    \seq_put_right:Nx \l__svend_opgaver_tables_out_seq
     {
      \__svend_opgaver_board:nn
       { \clist_item:nn { ##1 } { 1 } } 
       { \clist_item:nn { ##1 } { 2 } } 
      \__svend_opgaver_caption:n { \clist_item:nn { ##1 } { 3 } }
     }
   }
  \__svend_opgaver_make_tables:
 }

\cs_new_protected:Nn \__svend_opgaver_board:nn
 {
  \newgame
  \fenboard{#2 ~ #1 ~ - ~ - ~ 0 ~ 1 }
 }

\cs_new_protected:Nn \__svend_opgaver_caption:n
 {
  \scalebox{\l__svend_opgaver_mag_tl}{\showboard}\par
  \vspace*{2ex}
  {\LARGE Løsning: ~ \textcolor{blue}{#1}}
 }

\cs_new_protected:Nn \__svend_opgaver_make_tables:
 {
  \bool_if:NT \l__svend_opgaver_single_bool { \begin{figure}[!htbp] \centering }
  \int_step_inline:nnnn
   { 1 } % start
   { \l__svend_opgaver_n_int } % step
   { \seq_count:N \l__svend_opgaver_tables_out_seq } % end
   {
    \bool_if:NF \l__svend_opgaver_single_bool { \begin{figure}[!htbp] \centering }
    \int_step_inline:nnnn { 0 } { 1 } { \l__svend_opgaver_n_int - 1 }
     {
      \tl_if_empty:xF
       { \seq_item:Nn \l__svend_opgaver_tables_out_seq { ##1+####1 } }
       {
        \begin{minipage}[b]{ \dim_eval:n { \textwidth/\l__svend_opgaver_n_int } }
        \centering
        \seq_item:Nn \l__svend_opgaver_tables_out_seq { ##1+####1 }
        \end{minipage}
       }
     }
    \bool_if:NTF \l__svend_opgaver_single_bool { \\ \bigskip } { \end{figure} }
   }
  \bool_if:NT \l__svend_opgaver_single_bool { \end{figure} }
 }
\cs_generate_variant:Nn \tl_if_empty:nF { x }

\ExplSyntaxOff

\begin{document}

\opgaverLoesninger[mag=0.5,n=4,single]{
  w, 6k1/6p1/1p5p/3r4/1P6/6P1/4B1KP/8, Lc4 \\
  w, 1k6/pp6/2p3p1/4n1P1/8/P6P/KP1B4/8, Lf4 \\
  w, 8/1p4kp/p5p1/B7/3n4/1P5P/2P3P1/6K1, Lc3 \\
  w, k7/p6p/1p4p1/3r4/1P5P/P5P1/1KB5/8, Le4 \\
  w, k7/p6p/1p4p1/3r4/1P5P/P5P1/1KB5/8, Le4
}

\end{document}

enter image description here

  • That looks really nice! Thank you very much, egreg! – Svend Tveskæg Nov 6 '17 at 8:05
  • @SvendTveskæg Isn't the extended version even more interesting? ;-) – egreg Nov 6 '17 at 8:53
  • With the magnifying/scaling options it's now very ineresting. :-) – Svend Tveskæg Nov 6 '17 at 9:25
  • @SvendTveskæg I added a single option that makes a single figure environment. Just a few changes as you can see. :-) – egreg Nov 6 '17 at 10:14
  • Really cool. Any chance that you will implement Ulrike's suggestion in her comment? – Svend Tveskæg Nov 6 '17 at 11:44
10

I think you are looking more or less for something like this (I disable the \hestA-command as the dimension \svarstedA is nowhere defined).

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[
  a4paper,
  hmargin = 2.4cm,
  vmargin = 3cm
]{geometry}
\usepackage{xskak}

\setchessboard{smallboard}

\newcommand*\hestA[2][\svarstedA]{%
  \underline{\makebox[\ifdim\width>#1\width\else#1\fi]{#2}}}

\newcommand*\opgaverLoesningerA[1]{{\textcolor{blue}{#1}}}
\newcommand*\opgaverLoesningerEkstra[6]{%
  \def\tempA{#1}%
  \def\tempB{#2}%
  \def\tempC{#3}%
  \def\tempD{#4}%
  \def\tempE{#5}%
  \def\tempF{#6}%
  \opgaverLoesninger
}

\newcommand*\opgaverLoesninger[6]{%
\begin{figure}[!htbp]
 \centering
  \begin{minipage}{0.5\textwidth}
   \centering
    \newchessgame[setfen=\tempB\space \tempA - - 0 1,print]%
    \vspace*{2ex}

    {\LARGE Løsning: \opgaverLoesningerA{\tempC}}%
  \end{minipage}%
  \begin{minipage}{0.5\textwidth}
   \centering
    \newchessgame[setfen=\tempE \space \tempD - - 0 1,print]%
    \vspace*{2ex}

    {\LARGE Løsning: \opgaverLoesningerA{\tempF}}%
  \end{minipage}
\end{figure}
\vspace*{2ex}

\begin{figure}[!htbp]
 \centering
  \begin{minipage}{0.5\textwidth}
   \centering
    \newchessgame[setfen = #2 #1 - - 0 1,print]%
    \vspace*{2ex}

    {\LARGE Løsning: \opgaverLoesningerA{#3}}%
  \end{minipage}%
  \begin{minipage}{0.5\textwidth}
   \centering
    \newchessgame[setfen= #5 #4 - - 0 1,print]%
    \vspace*{2ex}

    {\LARGE Løsning: \opgaverLoesningerA{#6}}%
  \end{minipage}
\end{figure}}

\begin{document}

\opgaverLoesningerEkstra%
  {w}{6k1/6p1/1p5p/3r4/1P6/6P1/4B1KP/8}{Lc4}%
  {w}{1k6/pp6/2p3p1/4n1P1/8/P6P/KP1B4/8}{Lf4}%
  {w}{8/1p4kp/p5p1/B7/3n4/1P5P/2P3P1/6K1}{Lc3}%
  {w}{k7/p6p/1p4p1/3r4/1P5P/P5P1/1KB5/8}{Le4}

\end{document}

enter image description here

  • This looks really nice! One small thing: How do I get rid of the small box next to the board, which indicates whether it's white or black to move? (I'll accept ypur answer as soon as this small annoyance is fixed.) – Svend Tveskæg Nov 5 '17 at 17:29
  • 1
    Add showmover=false to the \setchessboard:\setchessboard{smallboard,showmover=false}. You can find the description of this keys in the chessboard documentation. – Ulrike Fischer Nov 5 '17 at 18:01
  • HI Ulrike. Sorry, but I've accepted Enrico's answer instead since it's more flexible. (Again: Thank you for helping me!) – Svend Tveskæg Nov 6 '17 at 9:26
  • That's okay -- I didn't try to improve your code, I mostly corrected the chess related commands. But @egreg doesn't use the best command to set the board. You should better use the xskak/chessboard commands from my answer (\newchessgame[setfen = ...]), \fenboard and \showboard are from the skak package and while they work they are a bit alien and not so flexible. – Ulrike Fischer Nov 6 '17 at 9:34
  • Hmmm! I've just noticed some "unexpected" behaviour: Assume I change the first of the 12 arguments of \opgaverLoesningerEkstra in your code from w to b then the square next to board still indicates that it's white's turn. – Svend Tveskæg Nov 23 '17 at 20:35

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.