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?

mf67
  • 666
  • 2
    Is it guaranteed that the last part will contain a number? – egreg Dec 30 '23 at 15:47
  • Maybe a format like 2011-10-29:2-03 should be better to use. – projetmbc Dec 30 '23 at 16:10
  • 1
    @egreg: Sorry for being late. Yes, the last 2 positions are 01, 02, ..., 2-digit numbers only. – mf67 Dec 30 '23 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 Dec 30 '23 at 18:05

5 Answers5

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}

David Carlisle
  • 757,742
  • Could you please comment on the need to \relax? – lhf Jan 02 '24 at 00: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, – David Carlisle Jan 02 '24 at 00: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

egreg
  • 1,121,712
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}
matexmatics
  • 4,819
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
    The last part can be simplified with \number\theID[6], as in the answer from David Carlisle. Then it is unnecessary to define \trimzero. – matexmatics Dec 30 '23 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}
Mico
  • 506,678
  • 1
    It doesn't work if the page number is greater than 9. Neither does the OP's attempt, but… – egreg Dec 30 '23 at 16:04
  • @egreg For example \Convert{2011-10-29--2-10} and \Convert{2011-10-29--2-023} work. – matexmatics Dec 30 '23 at 16:08
  • @matexmatics But 2011-10-29-10-10 doesn't – egreg Dec 30 '23 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? – David Carlisle Dec 30 '23 at 16:21
  • @egreg and DavidCarlisle: I've updated the code to incorporate your points. – Mico Dec 30 '23 at 16:32