Macro argument expansion and edef
Perhaps \expanded
is what you are looking for. Then you don't need the \edef
approach at all.
\documentclass{article}
\makeatletter
\def\cal@ymd#1:#2:#3:{#1-#2-#3}
\def\cal@md#1:#2:#3:{\cal@Year-#1-#2}
\def\cal@datesplit#1-#2-#3-#4#5#6{#5#1:#2:#3:}
\def\cal@Xdateexpand#1{\expandafter\cal@datesplit
\expanded{#1}--\cal@ymd\cal@md\empty}
\def\cal@Ydateexpand#1{\edef\cal@arg{#1}\expandafter\cal@datesplit
\cal@arg--\cal@ymd\cal@md\empty}
\def\cal@Year{2020}
\begin{document}
\def\dateMD{03-01} $\backslash$dateMD :: (\dateMD)
\def\dateYMD{2021-03-01} $\backslash$dateYMD :: (\dateYMD)
\def\dateY{2020} $\backslash$dateY :: (\dateY)
%% Using the \cal@X macro
A.1 (X) 03-01 :: (\cal@Xdateexpand{03-01})
A.2 (X) 2020-03-01 :: (\cal@Xdateexpand{2020-03-01})
A.3 (X) $\backslash$dateMD :: (\cal@Xdateexpand{\dateMD})
A.4 (X) 2020-$\backslash$dateMD :: (\cal@Xdateexpand{2020-\dateMD}) -- fails%% it fails in this case
A.5 (X) $\backslash$dateYMD :: (\cal@Xdateexpand{\dateYMD})
A.6 (X) $\backslash$dateY-$\backslash$dateMD :: (\cal@Xdateexpand{\dateY-\dateMD}) -- fails %% it fails in this case
%%
A.7 (X) edef 2020-03-01 :: \edef\SOME{\cal@Xdateexpand{2020-03-01}} (\SOME)
A.8 (X) edef 2020-$\backslash$dateMD :: \edef\SOME{\cal@Xdateexpand{2020-\dateMD}} (\SOME) -- fails but compile%% it still fails, but compiles
%% Using the \cal@Y macro
B.1 (Y) 03-01 :: (\cal@Ydateexpand{03-01})
B.2 (Y) 2020-03-01 :: (\cal@Ydateexpand{2020-03-01})
B.3 (Y) macro dateMD :: (\cal@Ydateexpand{\dateMD})
B.4 (Y) 2020-macro dateMD :: (\cal@Ydateexpand{2020-\dateMD}) -- desired behaviour % This is the intended behaviour
B.5 (Y) macro dateYMD :: (\cal@Ydateexpand{\dateYMD})
B.6 (Y) macros dateY-dateMD :: (\cal@Ydateexpand{\dateY-\dateMD}) -- desired behaviour
%% the two edef below fails to compile, with a "missing control sequence inserted"
%B.7 (X) edef 2020-03-01 :: \edef\SOME{\cal@Ydateexpand{2020-03-01}} (\SOME) -- fails to compile
%B.8 (X) edef 2020-macro dateMD :: \edef\SOME{\cal@Ydateexpand{2020-\dateMD}} (\SOME) -- fails to compile
\end{document}
You can use expl3
, much more direct.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\calendardate}{m}
{
\alceu_calendar_date:e { #1 }
}
\cs_new:Nn \alceu_calendar_date:n
{
\__alceu_calendar_date:w #1 - - \q_stop
}
\cs_generate_variant:Nn \alceu_calendar_date:n { e }
\cs_new:Npn \__alceu_calendar_date:w #1 - #2 - #3 - #4 \q_stop
{
\tl_if_empty:nT { #3 } { \calYear - }
#1 - #2
\tl_if_empty:nF { #3 } { - #3 }
}
\ExplSyntaxOff
\def\calYear{2020}
\begin{document}
\def\dateMD{03-01} \verb|\dateMD| :: (\dateMD)
\def\dateYMD{2021-03-01} \verb|\dateYMD| :: (\dateYMD)
\def\dateY{2020} \verb|\dateY| :: (\dateY)
A.1 (X) 03-01 :: (\calendardate{03-01})
A.2 (X) 2020-03-01 :: (\calendardate{2020-03-01})
A.3 (X) \verb|\dateMD| :: (\calendardate{\dateMD})
A.4 (X) 2020-\verb|\dateMD| :: (\calendardate{2020-\dateMD})
A.5 (X) \verb|\dateYMD| :: (\calendardate{\dateYMD})
A.6 (X) \verb|\dateY|-\verb|\dateMD| :: (\calendardate{\dateY-\dateMD})
A.7 (X) edef 2020-03-01 :: \edef\SOME{\calendardate{2020-03-01}} (\SOME)
A.8 (X) edef 2020-\verb|\dateMD| :: \edef\SOME{\calendardate{2020-\dateMD}} (\SOME)
\end{document}
A small change to ensure that months and days are printed as two digits independently of input.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\calendardate}{m}
{
\alceu_calendar_date:e { #1 }
}
\cs_new:Nn \alceu_calendar_date:n
{
\__alceu_calendar_date:w #1 - - \q_stop
}
\cs_generate_variant:Nn \alceu_calendar_date:n { e }
\cs_new:Npn \__alceu_calendar_date:w #1 - #2 - #3 - #4 \q_stop
{
\tl_if_empty:nT { #3 } { \calYear - }
\alceu_calendar_two:n { #1 } - \alceu_calendar_two:n { #2 }
\tl_if_empty:nF { #3 } { - #3 }
}
\cs_new:Nn \alceu_calendar_two:n
{
\int_compare:nT { \tl_count:n { #1 } < 2 } { 0 } #1
}
\ExplSyntaxOff
\def\calYear{2020}
\begin{document}
\def\dateMD{3-1} \verb|\dateMD| :: (\dateMD)
\def\dateYMD{2021-3-01} \verb|\dateYMD| :: (\dateYMD)
\def\dateY{2020} \verb|\dateY| :: (\dateY)
A.1 (X) 03-01 :: (\calendardate{03-01})
A.2 (X) 2020-03-01 :: (\calendardate{2020-03-01})
A.3 (X) \verb|\dateMD| :: (\calendardate{\dateMD})
A.4 (X) 2020-\verb|\dateMD| :: (\calendardate{2020-\dateMD})
A.5 (X) \verb|\dateYMD| :: (\calendardate{\dateYMD})
A.6 (X) \verb|\dateY|-\verb|\dateMD| :: (\calendardate{\dateY-\dateMD})
A.7 (X) edef 2020-03-01 :: \edef\SOME{\calendardate{2020-03-01}} (\SOME)
A.8 (X) edef 2020-\verb|\dateMD| :: \edef\SOME{\calendardate{2020-\dateMD}} (\SOME)
\end{document}