0

I wonder how I could test if the date of the event passed is between \calbegindate and \calenddate. These two values are set dynamically based on some options inside my code and because of that it could easily happen, that one of the events, that has not been updated, still has a date outside the calendar. This would produce a weird output as well as en error message.

So it would be nice to test if the event has a date that is on the calendar before trying to print it to the calendar which will of course fail. I included a commented out event, that is outside the calendar dates, uncomment it and add a comma to the event above to test the output.


"Minimal" Exampe

(Sorry, but I don't know how to further simplify the code, so it's not really minimal)

% %%%%%%%%
% Preamble
% %%%%%%%%

\documentclass[10pt, a4paper, landscape]{article}
\usepackage[margin = .5cm, nofoot]{geometry}

% Tikz
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{calendar}

% Logic and Tools
\usepackage{xparse}

% Fonts
\RequirePackage{lmodern}
\renewcommand*\familydefault{\sfdefault}

% Color
\definecolor{definedcolor}{HTML}{00CC00}

% Calculation
\ExplSyntaxOn
    \DeclareExpandableDocumentCommand{\eval}{m}{\int_eval:n {#1}}
\ExplSyntaxOff

% Custom appearance
\newcommand{\practicalCourse}[2]{%
    \node [text=black, anchor = north west, text width = 3.3cm ] at ($(cal-#1.north west)+(3.5em, -0.2em)$) {\scriptsize{#2}};
}

% Variables
\newcommand{\currentyear}{\the\year}
\newcommand{\nextyear}{\eval{\currentyear + 1}}

\newcommand{\calbegindate}{\currentyear-10-01}
\newcommand{\calenddate}{\nextyear-03-31}

\newcommand{\practicalCourses}{%
    {Foo}/\currentyear-10-10,%
    {Foo}/\currentyear-10-11,%
    {Foo}/\currentyear-10-12,%
    {Foo}/\currentyear-10-17,%
    {Foo}/\currentyear-10-18,%
    {Foo}/\currentyear-10-24,%
    {Foo}/\currentyear-10-25,%
    {Foo}/\currentyear-10-26,%
    {Foo}/\currentyear-11-07,%
    {Foo}/\currentyear-11-08%
    % {Bar}/\currentyear-04-11%
}

% Define searchable object (\ifdate{PracticalCourse})
% Answer by cfr on StackExchange: https://tex.stackexchange.com/a/346318/117727
\ExplSyntaxOn
    \clist_new:N \g_practical_course_clist%
    \int_new:N \l_practical_course_int%
    \foreach \i/\j in \practicalCourses {%
        \pgfcalendardatetojulian{\j}{\l_practical_course_int}%
        \clist_gput_right:Nx \g_practical_course_clist {%
            \int_to_arabic:n { \l_practical_course_int }%
        }%
    }%
    \cs_new_protected_nopar:Nn \practical_course_test:n {%
        \int_set:Nn \l_tmpa_int {#1}%
            \clist_if_in:NVT \g_practical_course_clist \l_tmpa_int {%
            \pgfcalendarmatchestrue%
        }%
    }%
    \cs_generate_variant:Nn \practical_course_test:n {x}%
    \NewDocumentCommand \testpraktikum { m } {%
        \practical_course_test:x { #1 }%
    }%
\ExplSyntaxOff

\tikzset{
    /pgf/calendar/PracticalCourse/.code={%
        \testpraktikum{\pgfcalendarifdatejulian}%
    },
}


% %%%%%%%%%%%%%%
% Begin Document
% %%%%%%%%%%%%%%

\begin{document}
    \centering
    \begin{tikzpicture}[every day/.style={anchor = north}]
        \calendar[
            dates = \calbegindate to \calenddate,
            name = cal,
            day yshift = 3em,
            day code = {
                \node[name = \pgfcalendarsuggestedname, every day, minimum height = .53cm, text width = 4.4cm, draw = gray] {\tikzdaytext};
                \draw (-1.8cm, -.1ex) node [anchor = west, font=\footnotesize] {\pgfcalendarweekdayshortname{\pgfcalendarcurrentweekday}};
            },
            execute before day scope={
                \ifdate{day of month = 1} {
                    \pgftransformxshift{4.8cm}
                    \draw (0,0) node [minimum height = .53cm, text width = 4.4cm, fill = definedcolor, text = white, draw = definedcolor, text centered] {\textbf{\pgfcalendarmonthname{\pgfcalendarcurrentmonth}\strut}};
                }{}
                \ifdate{workday} {
                    \tikzset{every day/.style = {fill = white}}
                    \ifdate{PracticalCourse}{%
                        \tikzset{every day/.style = {fill = olive!30}}%
                    }{}
                }{}
                \ifdate{Saturday} {
                    \tikzset{every day/.style = {fill = definedcolor!10}}%
                }{}
                \ifdate{Sunday} {
                    \tikzset{every day/.style = {fill = definedcolor!20}}%
                }{}
            },
            execute at begin day scope = {
                \pgftransformyshift{-.53*\pgfcalendarcurrentday cm}
            }
        ];
        \foreach \subject/\eventdate in \practicalCourses {
            \practicalCourse{\eventdate}{\subject}
        }
    \end{tikzpicture}
\end{document}
  • If any date in the calendar is in \practicalCourses you could use a \clist_if_in to test (take that as a clist and then check for {Foo}/datetotest or something). – TeXnician Oct 15 '17 at 11:55
  • @TeXnician I don't really get what you mean, could you be so nice and give an example? Thanks in advance. – Sam Oct 15 '17 at 12:02
  • Do you really need to test an arbitrary date or would it suffice to take one from the list? – TeXnician Oct 15 '17 at 12:05
  • @TeXnician As explained in the question, I want to test each date passed in the list to make sure that there is no error, even if the user has forgotten to remove an event – Sam Oct 15 '17 at 16:37
1

You can test if the node exists:

\newcommand{\practicalCourse}[2]{%
    \pgfutil@ifundefined{pgf@sh@ns@cal-#1}
     {\typeout{Warning date #1 doesn't exist}}% or some other action 
     {\node [text=black, anchor = north west, text width = 3.3cm ] at ($(cal-#1.north west)+(3.5em, -0.2em)$) {\scriptsize{#2}};}
}

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.