5

I am a newbie to expl3 programming and stumbled over a problem with colon (:) parsing.

For some TikZ related code I have to split #1:#2 into pieces. I found several questions and in this direction, but I could not manage to find a proper solution.

I was able to reproduce the lower case trick, but this includes the deprecated \tex_lowercase:D. Here is my current working, but deprecated code:

\documentclass{article}
\usepackage{expl3,xparse}

\ExplSyntaxOn

\cs_set_nopar:Npn \__example_point:nn #1#2
  {
    Example~with~#1~and~#2.
  }


\group_begin:
\char_set_lccode:nn { `? } { `: }
\tex_lowercase:D {
  \group_end:
  \cs_set_nopar:Npn \__example_point:w #1 ? #2 \q_stop
}{
    \__example_point:nn {#1}{#2}
  }


\cs_set_nopar:Npn \__example_point:n #1
  {
    \__example_point:w #1 \q_stop
  }


\DeclareDocumentCommand{\myexample}{ m }{ \__example_point:n {#1} }

\ExplSyntaxOff


\begin{document}

\myexample{34.2:47.9}

\end{document}

The output is

Example with 34.2 and 47.9.

I am searching for a replacement for \tex_lowercase:D and my current \__example_point:w.

I guess there is some clever way using expansions, but I was not able to find it.

2 Answers 2

4

You can exploit \use:x

\documentclass{article}
\usepackage{expl3,xparse}

\ExplSyntaxOn

\cs_new_nopar:Npn \__example_point:nn #1#2
  {
    Example~with~#1~and~#2.
  }

\use:x
  {
    \cs_new_nopar:Npn \exp_not:N \__example_point:w ##1 \c_colon_str ##2 \exp_not:N \q_stop
  }
  {
    \__example_point:nn {#1}{#2}
  }

\cs_new_nopar:Npn \__example_point:n #1
  {
    \__example_point:w #1 \q_stop
  }

\NewDocumentCommand{\myexample}{ m }{ \__example_point:n {#1} }

\ExplSyntaxOff


\begin{document}

\myexample{34.2:47.9}

\end{document}

Note \cs_new…, which is better practice than \cs_set….

This also works:

\ExplSyntaxOn

\cs_new_nopar:Npn \__example_point:nn #1#2
  {
    Example~with~#1~and~#2.
  }

\tl_set:Nx \l_tmpa_tl { ##1 \c_colon_str ##2 }
\exp_last_unbraced:NNV \cs_new_nopar:Npn \__example_point:w \l_tmpa_tl \q_stop
  {
    \__example_point:nn {#1}{#2}
  }

\cs_new_nopar:Npn \__example_point:n #1
  {
    \__example_point:w #1 \q_stop
  }

\NewDocumentCommand{\myexample}{ m }{ \__example_point:n {#1} }

\ExplSyntaxOff
4
  • Your first solution is near my own attempts but with the huge distinction that yours is working and mine not ;-) I just tested it with my real code and it works perfectly. Mar 7, 2020 at 11:18
  • Why is \cs_new... better than \cs_set...? From the description in interface3.pdf I had the impression that new is always global while set is local to TeX groups (?). Mar 7, 2020 at 11:21
  • @ThomasF.Sturm Why would you define those helper functions locally? \cs_set… is for functions with no “predetermined action” and which may locally change.
    – egreg
    Mar 7, 2020 at 11:22
  • I think from (good|bad) habit. \newcommand is local, \def is local. Over the years it cut in that using \global\def is something you do, if you really want it to be global. But, this mindset maybe wrong or outdated. Mar 7, 2020 at 11:32
5

You could use \seq_set_split:Nnn like this:

\documentclass{article}
\usepackage{expl3,xparse}

\ExplSyntaxOn


\cs_set_nopar:Npn \__example_point:nn #1#2
  {
    Example~with~#1~and~#2.
  }

\cs_generate_variant:Nn \seq_set_split:Nnn {NVn}

\cs_set_nopar:Npn \__example_point:n #1
  {
    \seq_set_split:NVn \l_tmpa_seq \c_colon_str {#1}
    \__example_point:nn {\seq_item:Nn\l_tmpa_seq {1}}{\seq_item:Nn\l_tmpa_seq {2}}
  }


\DeclareDocumentCommand{\myexample}{ m }{ \__example_point:n {#1} }

\ExplSyntaxOff


\begin{document}

\myexample{34.2:47.9}

\end{document}

enter image description here

4
  • \seq_set_split:NVn \l_tmpa_seq \c_colon_str { #1 } seems better to me
    – egreg
    Mar 7, 2020 at 11:04
  • @egreg yes, good point. I edited. Mar 7, 2020 at 11:06
  • I decided to accept @egreg' s answer because of the impression that runtime maybe faster (?). In my application, the macro may be called very often. Anyway, your answer is also very helpful to me, because I am at the very start of learning expl3 and I am sure that I will need sequence splitting soon. Mar 7, 2020 at 11:26
  • yes, @egreg's answer is certainly better for low-level code used often. Mar 7, 2020 at 11:43

You must log in to answer this question.

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