6

I have strings such as

2011-10-29--2-03

but I want to display them as

2011-10-29, p. 2, fig. 3

I tried

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{xstring}

\begin{document}

\def\ConvertID#1{%
\StrMid{#1}{1}{10}, 
p.~\StrMid{#1}{13}{13}, 
fig.~\StrMid{#1}{15}{16}
}

See \ConvertID{2011-10-29--2-03}.

\end{document}

and then tried various methods (from ideas at Remove leading zeroes from an integer) to handle the last 2 characters, e.g.

\num[minimum-integer-digits=1]{\StrMid{#1}{15}{16}}

from siunitx, but it did not work.

How can this be done?

4
  • 2
    Is it guaranteed that the last part will contain a number?
    – egreg
    Commented Dec 30, 2023 at 15:47
  • Maybe a format like 2011-10-29:2-03 should be better to use.
    – projetmbc
    Commented Dec 30, 2023 at 16:10
  • 1
    @egreg: Sorry for being late. Yes, the last 2 positions are 01, 02, ..., 2-digit numbers only.
    – mf67
    Commented Dec 30, 2023 at 18:02
  • 2
    @projetmbc: I had to use the ID as the file name too, and on PC this is not accepted by the OS, so I thought I'd use ‘--’. ‘_’ could have been an option too, but ‘here I am’ with a ‘legacy decision’…
    – mf67
    Commented Dec 30, 2023 at 18:05

5 Answers 5

10

enter image description here

\documentclass{article}

\def\foo#1{\xfoo#1\relax}
\def\xfoo#1--#2-#3\relax{#1, p.\ \number#2, fig.\ \number#3\relax}
\begin{document}

\foo{2011-10-29--2-03}

\end{document}
2
  • Could you please comment on the need to \relax?
    – lhf
    Commented Jan 2 at 0:09
  • 1
    @lhf it stops the \number otherwise \\foo{2011-10-29--2-03}4 would do \number034 so produce 34 which is probably OK in this use but bad style to let primitive tex number parsing leak out like that, Commented Jan 2 at 0:15
5

The following code is similar to David's, but it doesn't assume that page or figure numbers only consist of digits. For this to work we need to eat up leading zeros.

\documentclass{article}

\ExplSyntaxOn
\NewExpandableDocumentCommand{\ConvertID}{m}
 {
  \mflxvii_convert:n { #1 }
 }

\cs_new:Nn \mflxvii_convert:n
 {
  \__mflxvii_convert:w #1 \q_stop
 }

\cs_new:Npn \__mflxvii_convert:w #1--#2-#3 \q_stop
 {% #1 is a date in ISO format, #2 is a page number, #3 is a figure number
  #1,~
  p.\ \__mflxvii_convert_eat:N #2 \q_nil ,~
  f.\ \__mflxvii_convert_eat:N #3 \q_nil
 }

\cs_new:Nn \__mflxvii_convert_eat:N
 {
  \quark_if_nil:NF #1
   {
    \str_if_eq:nnTF { #1 } { 0 }
     {% a zero, restart
      \__mflxvii_convert_eat:N
     }
     {% not a zero, finish up
      #1 \__mflxvii_convert_deliver:w
     }
   }
 }

\cs_new:Npn \__mflxvii_convert_deliver:w #1 \q_nil { #1 }

\ExplSyntaxOff

\begin{document}

\ConvertID{2011-10-29--22-03}

\ConvertID{2011-10-29--022-3}

\ConvertID{2011-10-29--22-a2}

\edef\test{\ConvertID{2011-10-29--22-a2}}
\texttt{\meaning\test}

\end{document}

enter image description here

If expandability is not of a concern, here's a variant of matexmatics' answer

\documentclass{article}

\ExplSyntaxOn
\NewDocumentCommand{\ConvertID}{m}
 {
  \mflxvii_convert:n { #1 }
 }

\seq_new:N \l__mflxvii_convert_seq
\tl_new:N \l__mflxvii_convert_tl

\cs_new_protected:Nn \mflxvii_convert:n
 {
  \seq_set_split:Nnn \l__mflxvii_convert_seq { - } { #1 }
  \seq_item:Nn \l__mflxvii_convert_seq { 1 } -
  \seq_item:Nn \l__mflxvii_convert_seq { 2 } -
  \seq_item:Nn \l__mflxvii_convert_seq { 3 } ,~
  p.\nobreakspace \__mflxvii_convert_eat:e { \seq_item:Nn \l__mflxvii_convert_seq { 5 } },~
  f.\nobreakspace \__mflxvii_convert_eat:e { \seq_item:Nn \l__mflxvii_convert_seq { 6 } }
 }

\cs_new_protected:Nn \__mflxvii_convert_eat:n
 {
  \tl_set:Nn \l__mflxvii_convert_tl { #1 }
  \regex_replace_once:nnN { \A 0* } { } \l__mflxvii_convert_tl
  \tl_use:N \l__mflxvii_convert_tl
 }
\cs_generate_variant:Nn \__mflxvii_convert_eat:n { e }

\ExplSyntaxOff

\begin{document}

\ConvertID{2011-10-29--22-03}

\ConvertID{2011-10-29--022-3}

\ConvertID{2011-10-29--22-a2}

\end{document}

enter image description here

3
  • note if my answer needed to be ammended to not assume digits I would just change \number#3 to \number0#3 Commented Dec 30, 2023 at 19:21
  • How - with your first variant - to handle the unlikely and edge case of p. and/or f. being 0? ;-) Commented Jan 1 at 15:45
  • @UlrichDiez One can add a layer checking whether the item is just 0 before calling \__mflxvii_convert_eat:N
    – egreg
    Commented Jan 1 at 21:12
4

The answer below uses \seq_set_split:Nnn to split the argument of \FormatDatePageFig. It applies \int_to_arabic:n to the last item of this sequence.

enter image description here

\documentclass[border=6pt]{standalone}
\ExplSyntaxOn
\seq_new:N \l__mf_format_seq
\NewDocumentCommand { \FormatDatePageFig } { m }
  {
    \seq_set_split:Nnn \l__mf_format_seq { - } {#1}
    \seq_item:Nn \l__mf_format_seq { 1 } -
    \seq_item:Nn \l__mf_format_seq { 2 } -
    \seq_item:Nn \l__mf_format_seq { 3 } , ~ p. ~
    \seq_item:Nn \l__mf_format_seq { 5 } , ~ fig. ~
    \int_to_arabic:n { \seq_item:Nn \l__mf_format_seq { 6 } }
  }
\ExplSyntaxOff
\begin{document}
\FormatDatePageFig{2011-10-29--2-03}
\end{document}
2
\documentclass{article}
\usepackage{listofitems}
\setsepchar{-}
\newcommand\convertID[1]{%
  \readlist*\theID{#1}%
  \theID[1]-\theID[2]-\theID[3], p.\ \theID[5], fig.\ \number\theID[6]%
}
\begin{document}
\convertID{2011-10-29--2-3}
\end{document}

enter image description here

1
  • 1
    The last part can be simplified with \number\theID[6], as in the answer from David Carlisle. Then it is unnecessary to define \trimzero. Commented Dec 30, 2023 at 16:45
1

The following solution employs LuaLaTeX and works with any utf8-encoded string, not just ASCII-encoded strings. It doesn't assume that the page or figure numbers consist of exactly 1 or 2 digits, respectively.

enter image description here

\documentclass{article}
\usepackage{luacode} % for 'luacode' environment
\begin{luacode}
  function Convert ( s )
    s1=unicode.utf8.sub( s , 1 , 10 )
    
    s2=unicode.utf8.match ( unicode.utf8.sub(s,13) , "^.-%-" )
    s2=tonumber(unicode.utf8.sub(s2,1,-2))
    
    s3=unicode.utf8.match( s , "-%d*$" )
    s3=tonumber(unicode.utf8.sub ( s3, 2 ))
    
    return ( s1 .. ", p.\\ " .. s2 .. ", fig.\\ " .. s3)
  end
\end{luacode}
\newcommand\Convert[1]{\directlua{tex.sprint(Convert("#1"))}}

\begin{document}
\Convert{2011-10-29--2-03}

\Convert{2023-12-30--0123-01234}
\end{document}
5
  • 1
    It doesn't work if the page number is greater than 9. Neither does the OP's attempt, but…
    – egreg
    Commented Dec 30, 2023 at 16:04
  • @egreg For example \Convert{2011-10-29--2-10} and \Convert{2011-10-29--2-023} work. Commented Dec 30, 2023 at 16:08
  • @matexmatics But 2011-10-29-10-10 doesn't
    – egreg
    Commented Dec 30, 2023 at 16:09
  • page number always one digit seems unlikely, but also it isn't clear what you mean by your comment about utf-8 v ascii, since the conversion only works for input that is a sequence of - or digits, there is no difference between the two encodings, is there? Commented Dec 30, 2023 at 16:21
  • @egreg and DavidCarlisle: I've updated the code to incorporate your points.
    – Mico
    Commented Dec 30, 2023 at 16:32

You must log in to answer this question.

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