3

I am preparing cloze ("fill in the gaps") worksheets for my students. They contain texts with gaps that have to be filled in using words from a list below the text (either with or without duplicates). For obvious reasons the list should not be in the order of appearance in the text, so I would like to have it in alphabetical order.

I have copy-pasted (and slightly modified) some code found on this forum. I am really a very basic LaTeX user and don't understand that code in the slightest, but it seems to be working perfectly for me ... except for the order, which is chronological not alphabetical. Before using this code, which is based on /addmark and /printmarks, I had tried using index and glossary, but didn't manage to get them working the way I wanted to.

I don't know if this is likely to make any difference, but I use XeLaTeX and Japanese characters.

\documentclass{article}
\usepackage{xcolor}
\usepackage{framed}
\usepackage[parfill]{parskip}
\usepackage{xeCJK}
\usepackage{expl3}
\usepackage{xparse}

\definecolor{shadecolor}{RGB}{210,210,210}

\ExplSyntaxOn
\seq_new:N \g_khaurum_wordlist_seq

\NewDocumentCommand{ \addmark }{ m }{
   \seq_gput_right:Nn \g_khaurum_wordlist_seq { #1 }
   #1
}

\NewDocumentCommand{ \printmarks }{s}{
%    \seq_gremove_duplicates:N \g_khaurum_wordlist_seq          % removes duplicates
    \seq_use:Nnnn \g_khaurum_wordlist_seq { ~  --  ~ } { ~  --  ~ } { ~  --  ~ }
    \IfBooleanT { #1 } {
        \seq_gclear:N \g_khaurum_wordlist_seq
    }
}

\ExplSyntaxOff

%\newcommand\gap[1]{{\colorbox{white}{\textcolor{white}{#1}}}}      %this makes a gap
\newcommand\gap[1]{{\colorbox{white}{\textcolor{red}{#1}}}}         %this makes red letters

\begin{document}

\begin{snugshade*}
\begin{framed}
\begingroup\ttfamily

The marked \gap{\addmark{words}} should appear in \gap{\addmark{alphabetical}} order, not in the order they occur in.

\endgroup
\end{framed} 
\end{snugshade*}

\printmarks

\end{document}
3

You can use \__str_if_eq:nn to sort your sequence to obtain:

enter image description here

This only requires a minor modification to your code:

\documentclass{article}
\usepackage{xcolor}
\usepackage{framed}
\usepackage[parfill]{parskip}
\usepackage{xeCJK}
\usepackage{expl3}
\usepackage{xparse}

\definecolor{shadecolor}{RGB}{210,210,210}

\ExplSyntaxOn
\seq_new:N \g_khaurum_wordlist_seq

\NewDocumentCommand{ \addmark }{ m }{
   \seq_gput_right:Nn \g_khaurum_wordlist_seq { #1 }
   #1
}

\NewDocumentCommand{ \printmarks }{s}{
%    \seq_gremove_duplicates:N \g_khaurum_wordlist_seq          % removes duplicates
   \seq_gsort:Nn \g_khaurum_wordlist_seq {
      \int_compare:nTF { \__str_if_eq:nn { ##1 } { ##2 } < 0 }
                     {\sort_return_same:}
                     {\sort_return_swapped:}
   }
     \seq_use:Nnnn \g_khaurum_wordlist_seq { ~  --  ~ } { ~  --  ~ } { ~  --  ~ }
    \IfBooleanT { #1 } {
        \seq_gclear:N \g_khaurum_wordlist_seq
    }
}

\ExplSyntaxOff

%\newcommand\gap[1]{{\colorbox{white}{\textcolor{white}{#1}}}}      %this makes a gap
\newcommand\gap[1]{{\colorbox{white}{\textcolor{red}{#1}}}}         %this makes red letters

\begin{document}

\begin{snugshade*}
\begin{framed}
\begingroup\ttfamily

The marked \gap{\addmark{words}} should appear in \gap{\addmark{alphabetical}} order, not in the order they occur in.

\endgroup
\end{framed}
\end{snugshade*}

\printmarks

\end{document}
  • 2
    \pdftex_strcmp:D will be removed from the expl3 kernel by the end of this year (along with all \pdftex_...:D and \luatex_...:D and...). Use \tex_strcmp:D instead. Perhaps better would be \__str_if_eq:nn instead of a :D function. – Phelype Oleinik Oct 21 '19 at 12:39
  • Thank you, @Andrew, this worked perfectly. I've followed @Phelype's suggestion (Thank you, too!) and replaced \pdftex_strcmp:D with \tex_strcmp:D. (I didn't use the \__str_if_eq:nn because I wouldn't have known where to put it). Thank you again. – gail Oct 21 '19 at 13:09
  • @gail You just need to replace \tex_strcmp:D by \__str_if_eq:nn. The issue with using \tex_strcmp:D is that it's only defined in pdfTeX and XeTeX, so if you happen to use this code with LuaTeX it will not work. \__str_if_eq:nn will work regardless of engine. – Phelype Oleinik Oct 21 '19 at 13:19
  • @Phelype Thank you :-) – gail Oct 21 '19 at 13:25
  • 1
    @Andrew It's not :-) Functions which start with \__ are internal functions and are not supposed to be documented and neither used. But neither is \tex_strcmp:D, so in this case the \__ form is... well, less worse :-) Both of them are undocumented and subject to changes without prior notice (as \pdftex_...:D just did). There's been talk about providing documented user-level interface for \__str_if_eq:nn, though. – Phelype Oleinik Oct 21 '19 at 13:48

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.