Cómo pasar días al calendario tikz usando macros

Cómo pasar días al calendario tikz usando macros

Me gustaría pasar al calendario algunos nombres de días usando un comando personal, para que el usuario pueda cambiar los días fácilmente y crear un calendario personal.

Definí el comando \mydayscon un argumento, que se pasa a la lista \mydayslist.

¿Cómo utilizar esta lista dentro del calendario?

MWE

\documentclass{report}
\usepackage[margin=1cm,landscape]{geometry}
\usepackage{tikz}
\usetikzlibrary{calendar}

\newcommand*{\mydays}[1]{%
 \def\mydayslist{#1}%
}
\mydays{Monday,Friday}

\begin{document}

I want to pass the days \mydayslist\ to the calendar.

\noindent\centering
\begin{tikzpicture}
[every day/.style={anchor=mid},every node/.style={inner sep=2pt,rectangle,thick}]
\calendar (cal) [dates=2014-02-01 to 2014-07-last, month list, month label left,%
month text=\textcolor{black}{\%mt}, month yshift=1.7em, black!20]
%
if (Tuesday) [black] 
% if (\mydayslist) [black] %% <-- insert \mydayslist
;
\end{tikzpicture}

\end{document}

Respuesta1

Puedes usar elif teclas para definir un estilo para probar.unodía ( myifen mi ejemplo). Luego puede usar un .expand oncecontrolador (o .expandedcontrolador) para expandir su macro y un .listcontrolador para aplicar su lista.

\documentclass{report}
\usepackage[margin=1cm,landscape]{geometry}
\usepackage{tikz}
\usetikzlibrary{calendar}

\newcommand*{\mydays}[1]{%
 \def\mydayslist{#1}%
}
\mydays{Monday,Friday}

\begin{document}

I want to pass the days \mydayslist\ to the calendar.

\noindent\centering
\begin{tikzpicture}
[every day/.style={anchor=mid},every node/.style={inner sep=2pt,rectangle,thick}]

\calendar (cal) [dates=2014-02-01 to 2014-07-last,month list,month label left,
month text=\textcolor{black}{\%mt},month yshift=1.7em, black!20,
myif/.style={if=(#1)[black]},
myif/.list/.expand once={\mydayslist},
];
\end{tikzpicture}

\end{document}

Primera edición

Un ejemplo conand condición deCalendario TikZ y pruebas condicionales..

\documentclass{report}
\usepackage[margin=1cm,landscape]{geometry}
\usepackage{tikz}
\usetikzlibrary{calendar}
% code from https://tex.stackexchange.com/a/141027/14500
\makeatletter
\def\pgfcalendar@matchesfalse{\global\let\ifpgfcalendar@matches\iffalse}
\def\pgfcalendar@matchestrue{\global\let\ifpgfcalendar@matches\iftrue}
\pgfcalendar@matchesfalse
\pgfqkeys{/pgf/calendar}{and/.code 2 args={%
    \begingroup
      \ifdate{#1}{\ifdate{#2}{\pgfcalendar@matchestrue}{}}{}%
    \endgroup
    \ifpgfcalendar@matches\pgfcalendarmatchestrue\pgfcalendar@matchesfalse\fi}}
\makeatother
%------
\newcommand*{\mydays}[1]{%
 \def\mydayslist{#1}%
}
\mydays{Monday,Friday}

\begin{document}

I want to pass the days \mydayslist\ to the calendar.

\noindent\centering
\begin{tikzpicture}
[every day/.style={anchor=mid},every node/.style={inner sep=2pt,rectangle,thick}]

\calendar (cal) [
dates=2014-02-01 to 2014-07-last,
month list,month label left,
month text=\textcolor{black}{\%mt},
month yshift=1.7em, black!20,
myif2/.style={if={(and={between=2014-04-01 and 2014-05-32}{#1})[red]}},
myif2/.list/.expanded={\mydayslist},
];
\end{tikzpicture}

\end{document}

Segunda edición

Aquí está la mezcla de soluciones.La respuesta de Guhoy solución previa. Definí una nueva clave daypara probar una lista de días:

\pgfkeys{
  /pgf/calendar/@day/.style={#1},
  /pgf/calendar/day/.style={@day/.list/.expanded=#1},
}

Con estas claves, siempre podrá utilizar la sintaxis de especificación (p. 524 de pgfmanual).

Ejemplo conand condición deCalendario TikZ y pruebas condicionales..

ingrese la descripción de la imagen aquí

\documentclass{report}
\usepackage[margin=1cm,landscape]{geometry}
\usepackage{tikz}
\usetikzlibrary{calendar}
% code from https://tex.stackexchange.com/a/141027/14500
\makeatletter
\def\pgfcalendar@matchesfalse{\global\let\ifpgfcalendar@matches\iffalse}
\def\pgfcalendar@matchestrue{\global\let\ifpgfcalendar@matches\iftrue}
\pgfcalendar@matchesfalse
\pgfqkeys{/pgf/calendar}{and/.code 2 args={%
    \begingroup
      \ifdate{#1}{\ifdate{#2}{\pgfcalendar@matchestrue}{}}{}%
    \endgroup
    \ifpgfcalendar@matches\pgfcalendarmatchestrue\pgfcalendar@matchesfalse\fi}}
\makeatother
%------
\pgfkeys{
  /pgf/calendar/@day/.style={#1},
  /pgf/calendar/day/.style={@day/.list/.expanded=#1},
}
\newcommand*{\mydays}[1]{%
 \def\mydayslist{#1}%
}
\mydays{Monday,Friday}

\begin{document}

I want to pass the days \mydayslist\ to the calendar.

\noindent\centering
\begin{tikzpicture}
[every day/.style={anchor=mid},every node/.style={inner sep=2pt,rectangle,thick}]

\calendar (cal) [
dates=2014-02-01 to 2014-07-last,
month list,month label left,
month text=\textcolor{black}{\%mt},
month yshift=1.7em, black!20,
]
if (day=Sunday) [black,font=\itshape]
if (day=\mydayslist) [green]
if (and={between=2014-04-01 and 2014-05-32}{day=\mydayslist}) [red]
;
\end{tikzpicture}

\end{document}

Tercera edición

Mi tercera solución define la macro \calkeys(para administrar pares clave-valor como \pgfkeyso \tikzsetpero con /pgf/calendar/prefijo). Con esta macro, puedes definir cualquier selector de calendario como un estilo con nombre:

\def\calkeys#1{\pgfkeys{/pgf/calendar/.cd,#1}}
\calkeys{
  my day list/.style={Friday,Saturday},
  april/.style={between=2014-04-01 and 2014-04-30},
  my day list in april/.style={and={april}{my day list}},
}

Ejemplo:

\documentclass[margin=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calendar}
% code from https://tex.stackexchange.com/a/141027/14500
\makeatletter
\def\pgfcalendar@matchesfalse{\global\let\ifpgfcalendar@matches\iffalse}
\def\pgfcalendar@matchestrue{\global\let\ifpgfcalendar@matches\iftrue}
\pgfcalendar@matchesfalse
\pgfqkeys{/pgf/calendar}{and/.code 2 args={%
    \begingroup
      \ifdate{#1}{\ifdate{#2}{\pgfcalendar@matchestrue}{}}{}%
    \endgroup
    \ifpgfcalendar@matches\pgfcalendarmatchestrue\pgfcalendar@matchesfalse\fi}}
\makeatother
% -----
\def\calkeys#1{\pgfkeys{/pgf/calendar/.cd,#1}}
\calkeys{
  my day list/.style={Friday,Saturday},
  april 2014/.style={between=2014-04-01 and 2014-04-30},
  my day list in april 2014/.style={and={april 2014}{my day list}},
}

\begin{document}
\begin{tikzpicture}
[every day/.style={anchor=mid},every node/.style={inner sep=2pt,rectangle,thick}]
\calendar (cal) [dates=2014-02-01 to 2014-07-last,month list,month label left,
month text=\textcolor{black}{\%mt},month yshift=1.7em, black!20]
if (my day list) [red]
if (my day list in april 2014) [green]
;
\end{tikzpicture}
\end{document}

Respuesta2

Aquí hay una versión con un comando contenedor para el tikzcódigo, que expande previamente el argumento (aquí \mydayslist). El problema habitual con las interfaces de valores clave es la falta de expansión de los valores clave, ¡como es el caso aquí!

\documentclass{report}
\usepackage[margin=1cm,landscape]{geometry}
\usepackage{tikz}

\usetikzlibrary{calendar}


\def\mydayslist{}
\newcommand*{\mydays}[1]{%
 \def\mydayslist{#1}%
}

\mydays{Monday,Tuesday,Friday}

\newcommand{\sigurslittlehelper}[1]{%
  if (#1) [black]
  ;
}


\newcommand{\tikzdo}[1]{% Expand the list first, then use the tikz code
  \expandafter\sigurslittlehelper\expandafter{#1}%
}



\begin{document}

I want to pass the days \mydayslist\ to the calendar.

\noindent\centering
\begin{tikzpicture}
[every day/.style={anchor=mid},every node/.style={inner sep=2pt,rectangle,thick}]
\calendar (cal) [dates=2014-02-01 to 2014-07-last, month list, month label left,%
month text=\textcolor{black}{\%mt}, month yshift=1.7em, black!20]
\tikzdo{\mydayslist}
\end{tikzpicture}

\end{document}

ingrese la descripción de la imagen aquí

Respuesta3

Esto parece funcionar. Define una clave para ampliar la secuencia de control antes de pasarla al interno \ifdate. Derivado deesta respuesta.

\documentclass{report}
\usepackage[margin=1cm,landscape]{geometry}
\usepackage{tikz}
\usetikzlibrary{calendar}

\newcommand*{\mydays}[1]{%
 \def\mydayslist{#1}%
}
\mydays{Monday,Friday}
\pgfqkeys{/pgf/calendar}{fromcs/.code={\expandafter\ifdate\expandafter{#1}{}{}}}%<=====added
\begin{document}

I want to pass the days \mydayslist\ to the calendar.

\noindent\centering
\begin{tikzpicture}
[every day/.style={anchor=mid},every node/.style={inner sep=2pt,rectangle,thick}]
\calendar (cal) [dates=2014-02-01 to 2014-07-last, month list, month label left,%
month text=\textcolor{black}{\%mt}, month yshift=1.7em, black!20]
%
if (Tuesday) [black] 
if (fromcs={\mydayslist}) [black] %% <-- insert \mydayslist
;
\end{tikzpicture}

\end{document}

calendario resultante

información relacionada