Discussion:
Frage zu führenden Tagen tikzlibrary calendar mit Versuch eines Minimalbeispiels
(zu alt für eine Antwort)
Heiner Richter
2023-10-09 10:59:23 UTC
Permalink
Liebe Fachleute,

hat es jemand schon mal mit der tikzlibrary calendar geschafft, die paar
Tage des Vor- und folgenden Monats automatisch (zB in blasser Schrift,
die kein Problem wäre) den einzelnen Monaten jeweils hinzuzufügen?

Also etwa

November 2023
Montag Dienstag Mittwoch Donnerstag Freitag Samstag Sonntag
29blass 30blass 1 2 3 4 5

...
...

27 28 29 30 1blass 2blass 3blass

Dezember 2023
Montag Dienstag Mittwoch Donnerstag Freitag Samstag Sonntag
27blass 28blass 29blass 30blass 1 2 3

...
...

Falls ja, wäre ich für Code-Schnipsel oder ein komplettes Jahr dankbar.

Mit der Bitte um Nachsicht, wenn mein Versuch eines Mini-Bsp. zu viele
Zeilen gekürzt hätte, denn das Riesen-Dokument hatte ich (ohne zu
wissen, was ich mache) aus diversen internet-Quellen zusammengeklaubt.

Heiner

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Bsp.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\documentclass[landscape,fontsize=20pt]{scrartcl}
\pagestyle{empty}
\usepackage{tikz}
\usetikzlibrary{calendar}

\makeatletter
\tikzstyle{month label above centered}=[%
execute before day scope={%
\ifdate{day of month=1}{%
{
\pgfmathsetlength{\***@xa}{\***@lib@***@xshift}%
\***@xb=\***@lib@***@width\***@xa%
\advance\***@xb by-\***@xa%
\***@xb=.5\***@xb%
\pgftransformxshift{\***@xb}%
\pgftransformxshift{-\cellwidth/2}%
\pgfmathsetlength{\***@y}{\***@lib@***@yshift}%
\pgftransformyshift{0.333\***@y}
\tikzmonthcode%
}
}{}},
every month/.append style={anchor=base}
]

\tikzoption{day headings}{\tikzstyle{day heading}=[#1]}
\tikzstyle{day heading}=[]
\tikzstyle{day letter headings}=[
execute before day scope={ \ifdate{day of month=1}{%
\pgfmathsetlength{\***@ya}{\***@lib@***@yshift}%
\pgfmathsetlength\***@xa{\***@lib@***@xshift}%
\pgftransformyshift{-\***@ya}
\foreach \d/\l in {0/Mo,1/Di,2/Mi,3/Do,4/Fr,5/Sa,6/So} {
\***@xa=\d\***@xa%
\pgftransformxshift{\***@xa-\cellwidth/2}%
\pgftransformyshift{\***@ya}%
\node[every day,day heading]{\l};%
}
}{}%
}%
]
\makeatother



\pgfkeys{/tikz/inner sep = 0pt}

\pgfkeys{/tikz/day xshift=\cellwidth+2mm+2mm}

\pgfkeys{/tikz/day yshift=\cellheight+2mm+2mm}

\newlength{\cellheight}
\setlength{\cellheight}{.13\textheight}
\newlength{\cellwidth}
\setlength{\cellwidth}{.13\textwidth}



\newcommand*{\Kalenderblatt}[1]{%
\begin{tikzpicture}[thick]
\calendar[dates=#1,
week list,
month label above centered,
month text=\textsc{\%mt \%y0},
day headings={font=\footnotesize},
day letter headings]
;
\end{tikzpicture}
}

\begin{document}
\Kalenderblatt{\year-11-01 to \year-11-last}
\Kalenderblatt{\year-12-01 to \year-12-last}

\end{document}
Ulrich D i e z
2023-10-11 09:18:23 UTC
Permalink
Am 09.10.23 um 12:59 schrieb Heiner Richter:

[...]
Post by Heiner Richter
\Kalenderblatt{\year-11-01 to \year-11-last}
[...]

Du möchtest also im Argument eines Befehls \Kalenderblatt eine
Zeitspanne anhand eines frühesten Tag und eines spätesten Tag angeben
und dann sollen für diese Zeitspanne Monatskalender mit vollen Wochen
ausgegeben werden, bei denen die zum Vormonat gehörenden Tage der ersten
Woche des Monats und die zum Nachfolgemonat der letzten Woche des Monats
gehörenden Tage in anderer Einfärbung als die übrigen Tage erscheinen.

Wie soll \Kalenderblatt sich verhalten, wenn der früheste Tag nicht in
der ersten Monatswoche liegt, sondern in einer späteren Woche des Monats?

Wie soll \Kalenderblatt sich verhalten, wenn der späteste Tag nicht in
der letzten Monatswoche liegt, sondern in einer früheren Woche des
Monats?

Wie sollen dann die nicht zur Zeitspanne gehörenden Wochentage
erscheinen?

Mit freundlichem Gruß

Ulrich
Holger Schieferdecker
2023-10-11 15:02:24 UTC
Permalink
Post by Ulrich D i e z
[...]
Post by Heiner Richter
\Kalenderblatt{\year-11-01 to \year-11-last}
[...]
Du möchtest also im Argument eines Befehls \Kalenderblatt eine
Zeitspanne anhand eines frühesten Tag und eines spätesten Tag angeben
und dann sollen für diese Zeitspanne Monatskalender mit vollen Wochen
ausgegeben werden, bei denen die zum Vormonat gehörenden Tage der ersten
Woche des Monats und die zum Nachfolgemonat der letzten Woche des Monats
gehörenden Tage in anderer Einfärbung als die übrigen Tage erscheinen.
Wie soll \Kalenderblatt sich verhalten, wenn der früheste Tag nicht in
der ersten Monatswoche liegt, sondern in einer späteren Woche des Monats?
Wie soll \Kalenderblatt sich verhalten, wenn der späteste Tag nicht in
der letzten Monatswoche liegt, sondern in einer früheren Woche des
Monats?
Wie sollen dann die nicht zur Zeitspanne gehörenden Wochentage
erscheinen?
Ich bin nicht der OP, aber die Grundfrage finde ich auch interessant.

Zu Deinen Nachfragen, wenn der Kalender immer von einem Montag bis zu
einem Sonntag gehen soll, ist das wichtig, in welcher Woche des Monats
die früheren bzw. späteren Tage außerhalb des angegebenen Bereichs
liegen? Ich habe das so verstanden, daß die im angegebenen Bereich
normal und die außerhalb blaß gefärbt werden sollen. Wobei der OP glaube
ich nur an ganzen Monaten interessiert ist.

Holger
Heiner Richter
2023-10-12 05:52:00 UTC
Permalink
Post by Ulrich D i e z
[...]
Post by Heiner Richter
\Kalenderblatt{\year-11-01 to \year-11-last}
[...]
Du möchtest also im Argument eines Befehls \Kalenderblatt eine
Zeitspanne anhand eines frühesten Tag und eines spätesten Tag angeben
und dann sollen für diese Zeitspanne Monatskalender mit vollen Wochen
ausgegeben werden, bei denen die zum Vormonat gehörenden Tage der ersten
Woche des Monats und die zum Nachfolgemonat der letzten Woche des Monats
gehörenden Tage in anderer Einfärbung als die übrigen Tage erscheinen.
Wie soll \Kalenderblatt sich verhalten, wenn der früheste Tag nicht in
der ersten Monatswoche liegt, sondern in einer späteren Woche des Monats?
Wie soll \Kalenderblatt sich verhalten, wenn der späteste Tag nicht in
der letzten Monatswoche liegt, sondern in einer früheren Woche des
Monats?
Wie sollen dann die nicht zur Zeitspanne gehörenden Wochentage
erscheinen?
Mit freundlichem Gruß
Ulrich
Weil ich Deine Nachfragen nicht verstehe (und ich vermute, dass ich
meine Frage unklar/falsch gestellt habe), nochmals mein Wunsch: Ein
Kalenderblatt (im ganzen Jahr dann 12 Kalenderblätter), das immer mit
Montag beginnt und auf dem bspw. der Monat Oktober 2023 wie folgt erscheint

25blass 26blass 27blass 28blass 29blass 30blass 1
2 3 4 5 6 7 7
... (hier 8 bis 22 gekürzt)
23 24 25 26 27 28 29
30 31 1blass 2blass 3blass 4blass 5blass



Der früheste Tag ist hier, und darum geht es mir, automatisch berechnet
Montag, 25.9., und der späteste Sonntag, 5.11.

Im Netz
https://www.dickimaw-books.com/latex/admin/html/displaycalendar.shtml
habe ich in einem Kalender diese Frage angesprochen und gelöst gefunden,
und zwar die Zeilen ab
% is this the first day of the month?

%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}

\newcount\rowcount
\rowcount=1\relax
\newcount\julianday

\fbox{%
\let\%\pgfcalendarshorthand
\begin{tikzpicture}[x=1.5cm,y=1.75cm]
\begin{scope}[every node/.style={rectangle,fill=green!5,minimum
width=1.4cm}]
\foreach \x in {0,...,6}
{\path (\x,0) node {\pgfcalendarweekdayshortname{\x}};}
\end{scope}
\pgfcalendar{cal}{2014-05-01}{2014-05-31}{%
% is this the first day of the month?
\ifnum\pgfcalendarcurrentday=1\relax
% Fill in days from previous month if this isn't a Monday
\ifdate{Monday}{}%
{%
% Get last day of previous month
\julianday = \pgfcalendarcurrentjulian\relax
\advance\julianday by -\pgfcalendarcurrentweekday\relax
\foreach \x in {0,...,\numexpr\pgfcalendarcurrentweekday-1}
{
\pgfcalendarjuliantodate{\julianday}{\theyear}{\themonth}{\theday}
\path (\x,-1)
node
[
rectangle split,
rectangle split parts=2,
draw]
{\number\theday
\nodepart{two}%
\parbox[t][1cm]{1.2cm}{\mbox{}}%
};
\global\advance\julianday by 1\relax
}
}%
\fi
\def\thebackground{magenta!4}%
\ifcsdef{\pgfcalendarsuggestedname}%
{%
\def\thecontents{\csuse{\pgfcalendarsuggestedname}}%
\def\thebackground{black!4}%
}%
{%
\def\thecontents{\mbox{}}%
\ifdate{weekend}{\def\thebackground{black!4}}{}%
}%
\path (\pgfcalendarcurrentweekday,-\rowcount)
node
[
rectangle split,
rectangle split parts=2,
rectangle split part fill={cyan!20,\thebackground},
draw]
{\%d-
\nodepart{two}%
\parbox[t][1cm]{1.2cm}{\small\thecontents }%
};
\ifdate{Sunday}{\global\advance\rowcount by 1}{}%
\xdef\lastjulianday{\number\pgfcalendarcurrentjulian}%
\xdef\lastweekday{\number\pgfcalendarcurrentweekday}%
}%
\ifnum\lastweekday < 6\relax
\julianday = \lastjulianday\relax
\edef\lastweekday{\number\numexpr\lastweekday+1}%
\foreach \x in {\lastweekday,...,6}
{
\global\advance\julianday by 1\relax
\pgfcalendarjuliantodate{\julianday}{\theyear}{\themonth}{\theday}
\path (\x,-\rowcount)
node
[
rectangle split,
rectangle split parts=2,
draw]
{\number\theday
\nodepart{two}%
\parbox[t][1cm]{1.2cm}{\mbox{}}%
};
}
\fi
\end{tikzpicture}%
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%




aber das passt natürlich nur für diesen anders definierten Kalender als
den, den ich im Minimalbsp. gekürzt vorgestellt hatte.
Heiner Richter
2023-10-12 06:02:50 UTC
Permalink
... Korrektur, das im Netz gefundene Bsp lautete komplett

% This is an example document accompanying "LaTeX for Administrative Work"
% See www.dickimaw-books.com/latex/admin/ for the book details,
% including licence.
%
% arara: pdflatex
\documentclass{article}

\usepackage{etoolbox}
\usepackage{tikz}
\usepackage{pgfcalendar}

\usetikzlibrary{shapes.multipart}

\begin{document}

\newcount\rowcount
\rowcount=1\relax
\newcount\julianday

\csdef{cal-2014-05-05}{Early May BH}
\csdef{cal-2014-05-26}{Spring BH}

\fbox{%
\let\%\pgfcalendarshorthand
\begin{tikzpicture}[x=1.5cm,y=1.75cm]
\begin{scope}[every node/.style={rectangle,fill=green!5,minimum
width=1.4cm}]
\foreach \x in {0,...,6}
{\path (\x,0) node {\pgfcalendarweekdayshortname{\x}};}
\end{scope}
\pgfcalendar{cal}{2014-05-01}{2014-05-31}{%
% is this the first day of the month?
\ifnum\pgfcalendarcurrentday=1\relax
% Fill in days from previous month if this isn't a Monday
\ifdate{Monday}{}%
{%
% Get last day of previous month
\julianday = \pgfcalendarcurrentjulian\relax
\advance\julianday by -\pgfcalendarcurrentweekday\relax
\foreach \x in {0,...,\numexpr\pgfcalendarcurrentweekday-1}
{
\pgfcalendarjuliantodate{\julianday}{\theyear}{\themonth}{\theday}
\path (\x,-1)
node
[
rectangle split,
rectangle split parts=2,
draw]
{\number\theday
\nodepart{two}%
\parbox[t][1cm]{1.2cm}{\mbox{}}%
};
\global\advance\julianday by 1\relax
}
}%
\fi
\def\thebackground{magenta!4}%
\ifcsdef{\pgfcalendarsuggestedname}%
{%
\def\thecontents{\csuse{\pgfcalendarsuggestedname}}%
\def\thebackground{black!4}%
}%
{%
\def\thecontents{\mbox{}}%
\ifdate{weekend}{\def\thebackground{black!4}}{}%
}%
\path (\pgfcalendarcurrentweekday,-\rowcount)
node
[
rectangle split,
rectangle split parts=2,
rectangle split part fill={cyan!20,\thebackground},
draw]
{\%d-
\nodepart{two}%
\parbox[t][1cm]{1.2cm}{\small\thecontents }%
};
\ifdate{Sunday}{\global\advance\rowcount by 1}{}%
\xdef\lastjulianday{\number\pgfcalendarcurrentjulian}%
\xdef\lastweekday{\number\pgfcalendarcurrentweekday}%
}%
\ifnum\lastweekday < 6\relax
\julianday = \lastjulianday\relax
\edef\lastweekday{\number\numexpr\lastweekday+1}%
\foreach \x in {\lastweekday,...,6}
{
\global\advance\julianday by 1\relax
\pgfcalendarjuliantodate{\julianday}{\theyear}{\themonth}{\theday}
\path (\x,-\rowcount)
node
[
rectangle split,
rectangle split parts=2,
draw]
{\number\theday
\nodepart{two}%
\parbox[t][1cm]{1.2cm}{\mbox{}}%
};
}
\fi
\end{tikzpicture}%
}

\end{document}
Heiner Richter
2023-10-12 06:06:16 UTC
Permalink
... verflixt, so selbstverständlich

25blass 26blass 27blass 28blass 29blass 30blass 1
2 3 4 5 6 7 8
... (hier 9 bis 22 gekürzt)
23 24 25 26 27 28 29
30 31 1blass 2blass 3blass 4blass 5blass
Nico Hoffmann
2023-10-12 17:24:15 UTC
Permalink
Post by Heiner Richter
Post by Ulrich D i e z
[...]
Post by Heiner Richter
\Kalenderblatt{\year-11-01 to \year-11-last}
[...]
Du möchtest also im Argument eines Befehls \Kalenderblatt eine
Zeitspanne anhand eines frühesten Tag und eines spätesten Tag angeben
und dann sollen für diese Zeitspanne Monatskalender mit vollen Wochen
ausgegeben werden, bei denen die zum Vormonat gehörenden Tage der ersten
Woche des Monats und die zum Nachfolgemonat der letzten Woche des Monats
gehörenden Tage in anderer Einfärbung als die übrigen Tage erscheinen.
Wie soll \Kalenderblatt sich verhalten, wenn der früheste Tag nicht in
der ersten Monatswoche liegt, sondern in einer späteren Woche des Monats?
Wie soll \Kalenderblatt sich verhalten, wenn der späteste Tag nicht in
der letzten Monatswoche liegt, sondern in einer früheren Woche des
Monats?
Wie sollen dann die nicht zur Zeitspanne gehörenden Wochentage
erscheinen?
Mit freundlichem Gruß
Ulrich
Weil ich Deine Nachfragen nicht verstehe (und ich vermute, dass ich
meine Frage unklar/falsch gestellt habe), nochmals mein Wunsch: Ein
Kalenderblatt (im ganzen Jahr dann 12 Kalenderblätter), das immer mit
Montag beginnt und auf dem bspw. der Monat Oktober 2023 wie folgt erscheint
Es soll vermutlich so ähnlich aussehen:

https://lewonze.de/tmp/cal-2023-10.pdf

und die Tage, die bei mir grau sind, eben 'blass'.

N., ja , das ist auch mit tikz und nach Lektüre von
https://www.dickimaw-books.com/ entstanden, aber mit brutal viel
umständlicher Handarbeit... Ich wäre an einer Lösung dieses Problems
auch interessiert.
--
Netzfahrkarte - 1 Person - alle Tarifzonen - abgestempelt: 17.12.1999
Ulrich D i e z
2023-10-14 16:49:14 UTC
Permalink
Post by Heiner Richter
Liebe Fachleute,
hat es jemand schon mal mit der tikzlibrary calendar geschafft, die paar Tage des Vor- und folgenden Monats automatisch (zB in blasser Schrift, die kein Problem wäre) den einzelnen Monaten jeweils hinzuzufügen?
Ich frage mich, ob man unbedingt TikZ und die calendar-Library braucht,
um einen Kalender zu setzen.

Vielleicht braucht man weniger Masochismus, wenn man die von
pgfcalendar.sty zur Verfügung gestellte Schleife verwendet und
selbst etwas bastelt, was einem Tabellen-Umgebungen produziert.

Aber sei es drum.

Ich denke, ein Problem könnte darin bestehen, einen Algorithmus zu
formulieren, der es erlaubt, zwischen Tagen, die zum Monat gehören
und zwischen Tagen, die nicht zum Monat gehören, zu unterscheiden,
und, wenn beim Monatswechsel Wochentage wiederholt werden, die
jeweiligen Zähler richtig zurück zu setzen.

Ich habe jetzt spaßeshalber eine geschlagene Dreiviertelstunde damit
zugebracht, etwas zusammenzufrickeln, was man als Grundidee
auffassen könnte.

Ich habe es mir aber geschenkt, noch länger herumzufrickeln, um eine
wirklich perfekte Platzierung der Elemente auf dem Blatt zu erreichen -
mein Masochismus hat nicht ausgereicht, anhand von Quellcode
herauszufinden, was TikZ in Sachen Positionierung genau veranstaltet.

Zur Grundidee:

Wenn die zu einer bestimmten Zeitspanne gehörenden Tage in einer Schleife
in einen Monatskalender bzw. Wochentagskalender gesetzt werden sollen,
sodass zu jedem Monat eine Monatsüberschrift und eine Tabellenbeschriftung
mit Wochentagen gehört, muss man in der Schleife wohl zwischen sechs
Situationen unterscheiden.

Dazu braucht es eine Variable "Laufender Monat", die zwölf verschiedene
Werte annehmen kann und die Nummer desjenigen Monats angibt, für den
gerade der Kalender gebastelt wird.

Dazu braucht es außerdem eine Variable "Situation", die sechs verschiedene
Werte annehmen kann, von denen jeder für eine bestimmte Situation steht.

Am Anfang einer Iteration gibt diese Variable an, welche Situation in
der vorherigen Iteration bzw. zu Beginn der Schleife vorlag.

Anhand dieser Information und sonstigen Umständen kann gschlossen werden,
welche Situation in dieser Iteration vorliegt und der Wert der Variablen
"Situation" entsprechend geändert werden.

Dann kann, bevor die Tageszahl gesetzt wird, Code ausgeführt werden, je
nachdem, welche Situation in dieser Iteration gegeben ist.
Solcher Code kann z.B. Anweisungen zum Ändern der Textfarbe, etwa
durch Anhängen von key=value-Paaren an die entsprechenden Styles,
enthalten.

Die sechs Situationen sind:

- Situation "just initialized".
Diese Situation liegt nur vor, bevor die Schleife begonnen wird.
Sie liegt nie vor, wenn eine Tageszahl gesetzt wird.

- Situation "before the date range".
(Man bedenke, dass immer ganze Kalenderwochen ausgegeben werden.)
Diese Situation liegt vor, wenn ein Tag gesetzt wird, der in der
selben Woche wie das erste Datum des Datumsbereichs, aber früher als
das erste Datum des Datumsbereichs liegt.

- Situation "before the month".
Diese Situation liegt vor, wenn ein Tag gesetzt wird, der im
Datumsbereich früher als der erste des Monats, aber nicht früher als
das erste Datum des Datumsbereichs liegt.

- Situation "in the month".
Diese Situation liegt vor, wenn ein Tag gesetzt wird, der im
Datumsbereich und im betreffenden Monat liegt.

- Situation "after the month".
Diese Situation liegt vor, wenn ein Tag gesetzt wird, der im
Datumsbereich später als der letzte des Monats, aber nicht später als
das letzte Datum des Datumsbereichs liegt.

- Situation "after the date range".
(Man bedenke, dass immer ganze Kalenderwochen ausgegeben werden.)
Diese Situation liegt vor, wenn ein Tag gesetzt wird, der in der
selben Woche wie das letzte Datum des Datumsbereichs, aber später als
das letzte Datum des Datumsbereichs liegt.

Je nachdem, welche Situation in der vorigen Iteration gegeben war, muss
man in der laufenden Iteration prüfen, um festzustellen, welche
Situation diesmal gegeben ist, und den Wert der Variablen "Situation"
entsprechend ändern:

- Wenn in der vorherigen Iteration die Situation
"just initialized"
gegeben war:
----------------------------------------------
* "Monatsüberschriftsroutine" ausführen.

- Wenn in der vorherigen Iteration die Situation
"before the date range"
gegeben war:
----------------------------------------------
* Wenn das Datum nicht früher als das Startdatum liegt, dann
- wenn der Monat des Datums ungleich dem "Laufenden Monat" ist,
setze Situation := "before the month".
- wenn der Monat des Datums gleich dem "Laufenden Monat" ist,
setze Situation := "in the month".

- Wenn in der vorherigen Iteration die Situation
"before the month"
gegeben war:
----------------------------------------------
- Wenn das Datum der Erste des (Folge)Monats ist, dann setze
Situation := "in the month".

- Wenn in der vorherigen Iteration die Situation
"in the month"
gegeben war:
----------------------------------------------
* Wenn das Datum später ist als das Enddatum, setze
Situation:="after the date range".
* Wenn das Datum nicht später ist als das Enddatum und das Datum
der Monatserste ist und
- es Montag ist, führe die "Monatsüberschriftsroutine" aus.
- es nicht Montag ist, setze Situation:="after the month".

- Wenn in der vorherigen Iteration die Situation
"after the month"
gegeben war:
----------------------------------------------
* Wenn das Datum später ist als das Enddatum, setze
Situation:="after the date range".
* Wenn das Datum nicht später ist als das Enddatum und wenn
- es Montag ist, führe die "Monatsüberschriftsroutine" aus.

- Wenn in der vorherigen Iteration die Situation
"after the date range"
gegeben war:
----------------------------------------------
[Situation nicht verändern]

Während die Situation in der laufenden Iteration bestimmt wird, kann es
dazu kommen, dass eine "Monatsüberschriftsroutine" ausgeführt wird,
die die Monatsüberschrift und die Wochentagstabellenbeschriftung setzt
und ggfs zwecks Wiederholung der Tage, die zur ersten Woche des
Monates gehören, aber nicht im Monat liegen, den Datumszähler auf den
nicht später gelegenen Montag zurücksetzt, insgesamt also folgendes tut:

1. Monatsüberschrift und Wochentagstabellenbeschriftung setzen.
2. Die Nummer des Monats, für den jetzt der Monatskalender gesetzt werden soll,
in der Variablen "Laufender Monat" abspeichern.
3. "Situation anpassen":
Wenn nicht "just initialized": Datum auf den Monatsersten zurücksetzen.
Datum auf Montag zurücksetzen.
Wenn das Datum vor dem Startdatum liegt, setze Situation:="before the date range".
Wenn das Datum nicht vor dem Startdatum und im laufenden Monat liegt,
setze Situation:="in the month".
Wenn das Datum nicht vor dem Startdatum und nicht im laufenden Monat liegt,
setze Situation:="before the month".

Man muss also, bevor die Schleife gestartet wird,
- Situation = "just initialized" setzen,
- Start- und Enddatum als julianische Datumsnummern speichern und
- danach das Enddatum auf den nächsten Sonntag legen, der nicht früher
als das Enddatum liegt.

In der Schleife, immer bevor ein Kalendertag geschrieben wird, also über
execute before day scope={...}, musss abgefragt werden, welche der sechs
Situationen beim Ausgeben der Tagesnummer in der vorigen Iteration
gegeben war und die entsprechende Aktion ausgeführt werden, um ggfs. die
Situation anzupassen.
Nach dem Anpassen der Situation ist eine der Situationen
"before the date range", "before the month", "in the month",
"after the month", "after the date range" gegeben.

Danach kann in dem local scope, den TeX eröffnet, um den Kalendertag
zu schreiben, also über execute at begin day scope={...} , bevor die
Tagesnummer gesetzt wird, Code ausgeführt werden, je nachdem, welche
Situation in dieser Iteration gegeben ist.
Solcher Code kann z.B. Anweisungen zum Ändern der Textfarbe, etwa
durch Anhängen von key=value-Paaren an die entsprechenden Styles,
enthalten.

Sowohl beim Anpassen der Situation als auch beim Setzen der Tageszahl
muss verzweigt werden, je nachdem, welche der sechs Situationen
vorliegt.

Im untenstehenden Beispiel
- haben alle Makros, die ich selbst geschrieben habe, das Namenspräfix
"MYSTUFF".
- dient das Makro \MYSTUFFCurrentMonth als Variable "Laufender Monat",
für den gerade der Kalender gebastelt wird.
- dient das Makro \MYSTUFFSaveCurrentMonth dazu, die Variable
"Laufender Monat" anhand des Datums, für das in der laufenden
Iteration der Kalendertag geschrieben werden soll, zu aktualisieren.
- dient das Makro \MYSTUFFSituation als Variable "Situation".
- dient das Makro \MYSTUFFSetSituation{<Situation>};
Situation = just initialized | before the date range | before the month |
in the month | after the month | after the date range
dazu, den Wert der Variablen "Situation" global zu ändern.
- dient das Makro
\Situationfork{<tokens wenn Situation = just initialized>}%
{<tokens wenn Situation = before the date range>}%
{<tokens wenn Situation = before the month>}%
{<tokens wenn Situation = in the month>}%
{<tokens wenn Situation = after the month>}%
{<tokens wenn Situation = after the date range>}%
dazu, zu verzweigen, je nachdem, welche Situation gegeben ist.
- hat das Makro \Kalenderblatt ein optionales Argument, in dem man
für jede der Situationen "before the date range", "before the month",
"in the month", "after the month", "after the date range"
mittels key=value-Interface angeben kann, welcher Code direkt vor
dem Setzen der Tagesnummer ausgeführt werden soll, wenn diese
Situation gegeben ist. Hier kann man z.B. Direktiven zur Farbänderung
angeben. Die Keys heißen natürlich "before the date range",
"before the month", "in the month", "after the month",
"after the date range" und gehören zum pgfkeys-Pfad
/MYSTUFF/Kalenderblatt/.
- wird die "Monatsüberschriftsroutine" durch das Makro
"\MYStuffKalenderblattUeberschrift" initiiert.
- Ist die julianische Datumsnummer des Startdatums in \MYSTUFFStartdate
gespeichert.
- Ist die julianische Datumsnummer des Endatums in \MYSTUFFEnddate
gespeichert.

Mit freundlichem Gruß

Ulrich



%\errorcontextlines=10000
\documentclass{scrartcl}
\usepackage[ngerman]{babel}
\usepackage[ngerman]{translator}
\usepackage{tikz}
\usetikzlibrary{calendar}
%\usetikzlibrary{babel}

\makeatletter
% ======================================================
% Infrastruktur fürs Verwalten der Variable "Situation":
% ======================================================
\newcommand\MYSTUFFSituation{just initialized}%
\newcommand\MYSTUFFSetSituation[1]{%
\xdef\MYSTUFFSituation{\unexpanded{#1}}%
}%
\newcommand\MYSTUFFSituationfork{%
\expandafter\***@Situationfork\expandafter{\MYSTUFFSituation}%
}%
\newcommand\***@Situationfork[7]{%
\MYSTUFF@@Situationfork
!#1!before the date range!before the month!in the month!after the month!after the date range!{#2}%
!just initialized!#1!before the month!in the month!after the month!after the date range!{#3}%
!just initialized!before the date range!#1!in the month!after the month!after the date range!{#4}%
!just initialized!before the date range!before the month!#1!after the month!after the date range!{#5}%
!just initialized!before the date range!before the month!in the month!#1!after the date range!{#6}%
!just initialized!before the date range!before the month!in the month!after the month!#1!{#7}!!!!%
}%
\@ifdefinable\MYSTUFF@@Situationfork{%
\long\def\MYSTUFF@@Situationfork
#1!just initialized!before the date range!before the month!in the month!after the month!after the date range!#2#3!!!!{#2}%
}%
\newcommand*\MYSTUFFSpace{ }%
\newcommand\MYSTUFFCurrentMonth{}%
\newcommand\MYSTUFFSaveCurrentMonth{%
\xdef\MYSTUFFCurrentMonth{\the\numexpr(\pgfcalendarcurrentmonth)\relax}%
}%
% =============================================================
% Key=Value-Interface, um für jede der Situationen
% "before the date range", "before the month", "in the month",
% "after the month", "after the date range"
% anzugeben, welcher Code direkt vor dem Setzen der Tagesnummer
% ausgeführt werden soll, wenn diese Situation gegeben ist:
% =============================================================
\pgfkeys{%
/MYSTUFF/Kalenderblatt/.cd,
before the date range/.initial = {},
before the date range/.default = {},
before the month/.initial = {},
before the month/.default = {},
in the month/.initial = {},
in the month/.default = {},
after the month/.initial = {},
after the month/.default = {},
after the date range/.initial = {},
after the date range/.default = {},
day heading/.initial = {},
day heading/.default = {},
month heading/.initial = {},
month heading/.default = {},
}%
% =============================================================
% \Kalenderblatt[
% before the date range=...,
% before the month=...,
% in the month=...,
% after the month=...,
% after the date range=...,
% ]{YYYY-MM-DD to YYYY-MM-DD}
% =============================================================
\newcommand\Kalenderblatt[2][]{%
\begingroup
\pgfkeys{%
% /tikz/inner sep = 0pt,
/tikz/day xshift=\the\dimexpr.166666667\textwidth \relax,
/tikz/day yshift=\the\dimexpr\textheight / 21 \relax,
/MYSTUFF/Kalenderblatt/.cd, #1%
}%
\MYSTUFFSetSituation{just initialized}%
\begingroup
% Speichere Start- und Stopdatum im ISO-Format in Makros \***@lib@***@start / \***@lib@***@end:
\***@lib@***@parse#2\relax
% Konvertiere Start in julianische Datumsnummer und speichere als \MYSTUFFStartdate:
\pgfcalendardatetojulian{\***@lib@***@start}{\pgfcalendarcurrentjulian}%
\xdef\MYSTUFFStartdate{\the\pgfcalendarcurrentjulian}%
% Konvertiere Stopdatum in julianische Datumsnummer und speichere als \MYSTUFFEnddate::
\pgfcalendardatetojulian{\***@lib@***@end}{\pgfcalendarcurrentjulian}%
\xdef\MYSTUFFEnddate{\the\pgfcalendarcurrentjulian}%
% Berechne den Wochentag des Stopdatums in den Zähler \***@tempcntb :
\pgfcalendarjuliantoweekday{\pgfcalendarcurrentjulian}{\***@tempcntb}%
% Zähle das Stopdatum bis zum nächsten Sonntag hoch:
\pgfcalendarcurrentjulian=\the\numexpr(\pgfcalendarcurrentjulian+6-\***@tempcntb)\relax
% Konvertiere hochgezähltes Stopdatum in Iso-Datumskomponenten:
\pgfcalendarjuliantodate{\pgfcalendarcurrentjulian}{\myyear}{\mymonth}{\myday}%
\expanded{\unexpanded{\endgroup
\begin{tikzpicture}[thick]%
\calendar[%
dates=}\***@lib@***@start\space to\space\myyear-\mymonth-\myday},
week list,
month yshift=0cm,
month xshift=0cm,
month text=\%mt \%y0,
every month/.append style={anchor=base},
every day/.append style={anchor=base},
execute before day scope={%
% Situation anpassen:
\MYSTUFFSituationfork{%
% <tokens wenn Situation = just initialized>%
% * führe die "Monatsüberschriftsroutine" aus.
\MYStuffKalenderblattUeberschrift
}{%
% <tokens wenn Situation = before the date range>%
% * Wenn das Datum nicht früher als das Startdatum liegt, dann
% - wenn der Monat des Datums ungleich dem "Laufenden Monat" ist,
% setze Situation := "before the month".
% - wenn der Monat des Datums gleich dem "Laufenden Monat" ist,
% setze Situation := "in the month".
\ifnum\pgfcalendarcurrentjulian<\MYSTUFFStartdate\MYSTUFFSpace\else
\ifnum\pgfcalendarcurrentmonth=\MYSTUFFCurrentMonth\MYSTUFFSpace
\MYSTUFFSetSituation{in the month}%
\else
\MYSTUFFSetSituation{before the month}%
\fi
\fi
}{%
% <tokens wenn Situation = before the month>%
% * Wenn das Datum der Erste des (Folge)Monats ist, dann setze
% Situation := "in the month".
\ifdate{day of month=1}{\MYSTUFFSetSituation{in the month}}{}%
}{%
% <tokens wenn Situation = in the month>%
% * Wenn das Datum später ist als das Enddatum, setze
% Situation:="after the date range".
% * Wenn das Datum nicht später ist als das Enddatum und das Datum
% der Monatserste ist und
% - es Montag ist, führe die "Monatsüberschriftsroutine" aus.
% - es nicht Montag ist, setze Situation:="after the month".
\ifnum\pgfcalendarcurrentjulian>\MYSTUFFEnddate\MYSTUFFSpace
\MYSTUFFSetSituation{after the date range}%
\else
\ifdate{day of month=1}{%
\ifdate{Monday}{\MYStuffKalenderblattUeberschrift}{\MYSTUFFSetSituation{after the month}}%
}{}%
\fi
}{%
% <tokens wenn Situation = after the month>%
% * Wenn das Datum später ist als das Enddatum, setze
% Situation:="after the date range".
% * Wenn das Datum nicht später ist als das Enddatum und wenn
% - es Montag ist, führe die "Monatsüberschriftsroutine" aus.
\ifnum\pgfcalendarcurrentjulian>\MYSTUFFEnddate\MYSTUFFSpace
\MYSTUFFSetSituation{after the date range}%
\else
\ifdate{Monday}{\MYStuffKalenderblattUeberschrift}{}%
\fi
}{%
% <tokens wenn Situation = after the date range>%
}%
},
execute at begin day scope={%
% Anweisungen gemäß Situation:
\MYSTUFFSituationfork
{}% <- Die Situation "just initialized" sollte jetzt nicht mehr gegeben sein.
{\pgfkeysvalueof{/MYSTUFF/Kalenderblatt/before the date range}}%
{\pgfkeysvalueof{/MYSTUFF/Kalenderblatt/before the month}}%
{\pgfkeysvalueof{/MYSTUFF/Kalenderblatt/in the month}}%
{\pgfkeysvalueof{/MYSTUFF/Kalenderblatt/after the month}}%
{\pgfkeysvalueof{/MYSTUFF/Kalenderblatt/after the date range}}%
},
];
\end{tikzpicture}
\endgroup
}%
\newcommand\MYStuffKalenderblattUeberschrift{%
% ------------------------------------------------------------
% Monatsüberschrift und Wochentagstabellenbeschriftung setzen:
% ------------------------------------------------------------
{%
% Mittels \pgftransformxshift die x-Koordinate horizontal in die
% horizontale Bildmitte verschieben:
% Der Kalender hat eine Geaamtbreite von sechs Kalenderspaltenabständen.
% Der Kalenderspaltenabstand ist (\***@lib@***@xshift).
% Der Kalender hat also eine Gesamtbreite von 6 * (\***@lib@***@xshift),
% bzw. der Kalender hat eine Gesamtbreite von
% ((\***@lib@***@width)-1)*(\***@lib@***@xshift).
% Davon die Hälfte:
\pgftransformxshift{(((\***@lib@***@width)-1)*(\***@lib@***@xshift))/2}%
\pgftransformyshift{(\***@lib@***@yshift)/3}%
\pgfkeysvalueof{/MYSTUFF/Kalenderblatt/month heading}%
\tikzmonthcode
}%
% ------------------------------------------------
% Wochentagstabellenbeschriftung setzen:
% ------------------------------------------------
\pgftransformyshift{-(\***@lib@***@yshift)}%
\foreach \d/\l in {0/Mo,1/Di,2/Mi,3/Do,4/Fr,5/Sa,6/So} {
\pgftransformxshift{(\d)*(\***@lib@***@xshift)}%
\pgftransformyshift{(\***@lib@***@yshift)}%
\pgfkeysvalueof{/MYSTUFF/Kalenderblatt/day heading}%
\node[every day, anchor=base]{\l};%
}%
% ------------------------------------------------
% Laufenden Monat abspeichern:
% ------------------------------------------------
\MYSTUFFSaveCurrentMonth
% ------------------------------------------------
% Gggfs Datum zurücksetzen und Situation anpassen:
% ------------------------------------------------
\MYSTUFFSituationfork{\@firstoftwo}{\@secondoftwo}{\@secondoftwo}{\@secondoftwo}{\@secondoftwo}{\@secondoftwo}%
{}{%
\pgfcalendarcurrentjulian=\the\numexpr\pgfcalendarcurrentjulian-\pgfcalendarcurrentday+1\relax
\pgfcalendarjuliantodate{\pgfcalendarcurrentjulian}{\pgfcalendarcurrentyear}{\pgfcalendarcurrentmonth}{\pgfcalendarcurrentday}%
\pgfcalendarjuliantoweekday{\pgfcalendarcurrentjulian}{\***@tempcntb}%
\edef\pgfcalendarcurrentweekday{\the\***@tempcntb}%
}%
\pgfcalendarcurrentjulian=\the\numexpr\pgfcalendarcurrentjulian-\pgfcalendarcurrentweekday\relax
\pgfcalendarjuliantodate{\pgfcalendarcurrentjulian}{\pgfcalendarcurrentyear}{\pgfcalendarcurrentmonth}{\pgfcalendarcurrentday}%
\pgfcalendarjuliantoweekday{\pgfcalendarcurrentjulian}{\***@tempcntb}%
\edef\pgfcalendarcurrentweekday{\the\***@tempcntb}%
\ifnum\pgfcalendarcurrentjulian<\MYSTUFFStartdate\MYSTUFFSpace
\MYSTUFFSetSituation{before the date range}%
\else
\ifnum\pgfcalendarcurrentmonth=\MYSTUFFCurrentMonth\MYSTUFFSpace
\MYSTUFFSetSituation{in the month}%
\else
\MYSTUFFSetSituation{before the month}%
\fi
\fi
}%
\makeatother

\pagestyle{empty}

\begin{document}

\enlargethispage{2cm}

\hrule height 0pt \kern -2cm

\section{Datumsbereich: 2023-10-31 to 2023-12-26}

\begin{itemize}
\item Jedes Datum des Datumsbereichs muss in genau einem Monatskalender normal
in schwarz erscheinen.
\item Der 30. Oktober 2023 liegt in der ersten Woche des Datumsbereiches, gehört
aber nicht zum Datumsbereich und ist deshalb sowohl im Monatskalender für
Oktober als auch im Monatsalender für November grau hinterlegt.
\item Der 1. und 2. und 3. und 4. und 5. November liegen in der letzten
Oktoberwoche, aber nicht im Oktober und sind deshalb im Monatskalender
für Oktober grau.
\item Der 31. Oktober liegt in der ersten Novemberwoche, aber nicht
im November und ist deshalb im Monatskalender für November grau.
\item Der 1. und 2. und 3. Dezember liegen in der letzten Novemberwoche, aber
nicht im November und sind deshalb im Monatskalender für November grau.
\item Der 27. und 28. und 29. und 30. November liegen in der ersten
Dezemberwoche, aber nicht im Dezember und sind deshalb im Monatskalender
für Dezember grau.
\item Der 27. und 28. und 29. und 30. und 31. Dezember liegen in der letzten
Woche des Datumsbereicht, aber nicht im Datumsbereich und sind deshalb
grau hinterlegt.
\end{itemize}

\vfill
\noindent
\Kalenderblatt[%
% In den Werten der Keys "before the date range=..." etc. kann man mit \ifdate weiter
% verzweigen und z.B. bestimmte Tage der Woche anders einfärben.
before the date range=\pgfkeys{/tikz/every day/.append style={preaction={fill=black!20}, rectangle, draw, white}},
before the month=\pgfkeys{/tikz/every day/.append style={black!20}},
in the month=\pgfkeys{/tikz/every day/.append style={black}},
after the month=\pgfkeys{/tikz/every day/.append style={black!20}},
after the date range=\pgfkeys{/tikz/every day/.append style={preaction={fill=black!20}, rectangle, draw, white}},
day heading=\pgfkeys{/tikz/every day/.append style={font=\footnotesize\scshape}},
month heading=\pgfkeys{/tikz/every month/.append style={font=\Large\scshape}},
]{2023-10-31 to 2023-12-26}

\section{Datumsbereich: 2023-12-01 to 2023-12-last}
\noindent
\Kalenderblatt{2023-12-01 to 2023-12-last}

\end{document}
Heiner Richter
2023-10-14 19:20:09 UTC
Permalink
Li...
Uiuiui, und ich dachte, jemand habe etwas wie \ifdate{Montag} usw. für
mich. Vielen, vielen Dank, da habe ich ja jetzt einiges zum Grübeln,
Kopieren und Verstehen(?) in den kommenden Tagen, ach was Wochen und
Monaten.
Heiner Richter
2023-11-02 10:21:17 UTC
Permalink
Post by Heiner Richter
Li...
Uiuiui, und ich dachte, jemand habe etwas wie \ifdate{Montag} usw. für
mich. Vielen, vielen Dank, da habe ich ja jetzt einiges zum Grübeln,
Kopieren und Verstehen(?) in den kommenden Tagen, ach was Wochen und
Monaten.
Ich ahnte, dass mich das lange beschäftigen wird.

In Kürze: Die von Dir, lieber Ulrich (D i e z), gezeigte Lösung
funktioniert perfekt, aber ich konnte sie nicht auf mein Mini-Beispiel
anwenden (auf mein nicht eingedampftes Bsp. schon gar nicht).

Jetzt habe ich im Netz die Antwort
https://tex.stackexchange.com/questions/576673/full-weeks-in-tikz-calendar
gefunden, so dass es mir jetzt zumindest damit schonmal gelingt, die
führenden/folgenden Tage ins Mini-Beispiel zu integrieren (auch wenn ich
wie so oft nicht verstehe, was ich da zusammenklaube), und zwar mittels

\usetikzlibrary{ext.calendar-plus}
\makeatletter
\tikzset{
add day from week before/.default=, add day from week after/.default=,
add day from week before/.code={%
\begingroup % shift whole calendar 7 days in the past
\advance\pgfcalendarcurrentjulian by -7

\pgfcalendarjuliantodate{\pgfcalendarcurrentjulian}{\pgfcalendarcurrentyear}{\pgfcalendarcurrentmonth}{\pgfcalendarcurrentday}%
\pgfcalendarjuliantoweekday{\pgfcalendarcurrentjulian}{\***@tempcntb}%
\edef\pgfcalendarcurrentweekday{\the\***@tempcntb}%

\pgfcalendarjulianyeartoweek{\pgfcalendarcurrentjulian}{\pgfcalendarcurrentyear}{\***@tempcntb}%
\edef\pgfcalendarcurrentweek{\ifnum\***@tempcntb<10
0\fi\the\***@tempcntb}%
\pgftransformyshift{\pgfkeysvalueof{/tikz/day yshift}}%
\tikzset{every day from week before/.try,#1}%
\tikzdaycode
\endgroup},
add day from week after/.code={%
\begingroup % shift whole calendar 7 days in the future
\advance\pgfcalendarcurrentjulian by +7

\pgfcalendarjuliantodate{\pgfcalendarcurrentjulian}{\pgfcalendarcurrentyear}{\pgfcalendarcurrentmonth}{\pgfcalendarcurrentday}%
\pgfcalendarjuliantoweekday{\pgfcalendarcurrentjulian}{\***@tempcntb}%
\edef\pgfcalendarcurrentweekday{\the\***@tempcntb}%

\pgfcalendarjulianyeartoweek{\pgfcalendarcurrentjulian}{\pgfcalendarcurrentyear}{\***@tempcntb}%
\edef\pgfcalendarcurrentweek{\ifnum\***@tempcntb<10
0\fi\the\***@tempcntb}%
\pgftransformyshift{-(\pgfkeysvalueof{/tikz/day yshift})}%
\tikzset{every day from week after/.try,#1}%
\tikzdaycode
\endgroup}}
\makeatother


und der If-Definition

% as early as possible
if = {(and = {week of month = 1, calendar week of month = 2}) [add day
from week before]},
if = {(and = {week of month'= 1, calendar week of month'= 2}) [add day
from week after]},
every day from week before/.style=gray,
every day from week after/.style={gray,if=(Sunday)[red!25!gray]},

Gruß

Heiner

%%%%%%%%%%%%%%%%%%%%%%lauffähges Mini-Bsp. für Nov/Dez. 2023%%%%%%%%

\documentclass[landscape,fontsize=20pt]{scrartcl}
\pagestyle{empty}
\usepackage{tikz}
\usetikzlibrary{calendar}
\usetikzlibrary{ext.calendar-plus}
\makeatletter
\tikzset{
add day from week before/.default=, add day from week after/.default=,
add day from week before/.code={%
\begingroup % shift whole calendar 7 days in the past
\advance\pgfcalendarcurrentjulian by -7

\pgfcalendarjuliantodate{\pgfcalendarcurrentjulian}{\pgfcalendarcurrentyear}{\pgfcalendarcurrentmonth}{\pgfcalendarcurrentday}%
\pgfcalendarjuliantoweekday{\pgfcalendarcurrentjulian}{\***@tempcntb}%
\edef\pgfcalendarcurrentweekday{\the\***@tempcntb}%

\pgfcalendarjulianyeartoweek{\pgfcalendarcurrentjulian}{\pgfcalendarcurrentyear}{\***@tempcntb}%
\edef\pgfcalendarcurrentweek{\ifnum\***@tempcntb<10
0\fi\the\***@tempcntb}%
\pgftransformyshift{\pgfkeysvalueof{/tikz/day yshift}}%
\tikzset{every day from week before/.try,#1}%
\tikzdaycode
\endgroup},
add day from week after/.code={%
\begingroup % shift whole calendar 7 days in the future
\advance\pgfcalendarcurrentjulian by +7

\pgfcalendarjuliantodate{\pgfcalendarcurrentjulian}{\pgfcalendarcurrentyear}{\pgfcalendarcurrentmonth}{\pgfcalendarcurrentday}%
\pgfcalendarjuliantoweekday{\pgfcalendarcurrentjulian}{\***@tempcntb}%
\edef\pgfcalendarcurrentweekday{\the\***@tempcntb}%

\pgfcalendarjulianyeartoweek{\pgfcalendarcurrentjulian}{\pgfcalendarcurrentyear}{\***@tempcntb}%
\edef\pgfcalendarcurrentweek{\ifnum\***@tempcntb<10
0\fi\the\***@tempcntb}%
\pgftransformyshift{-(\pgfkeysvalueof{/tikz/day yshift})}%
\tikzset{every day from week after/.try,#1}%
\tikzdaycode
\endgroup}}
\makeatother

\makeatletter
\tikzstyle{month label above centered}=[%
execute before day scope={%
\ifdate{day of month=1}{%
{
\pgfmathsetlength{\***@xa}{\***@lib@***@xshift}%
\***@xb=\***@lib@***@width\***@xa%
\advance\***@xb by-\***@xa%
\***@xb=.5\***@xb%
\pgftransformxshift{\***@xb}%
\pgftransformxshift{-\cellwidth/2}%
\pgfmathsetlength{\***@y}{\***@lib@***@yshift}%
\pgftransformyshift{0.333\***@y}
\tikzmonthcode%
}
}{}},
every month/.append style={anchor=base}
]

\tikzoption{day headings}{\tikzstyle{day heading}=[#1]}
\tikzstyle{day heading}=[]
\tikzstyle{day letter headings}=[
execute before day scope={ \ifdate{day of month=1}{%
\pgfmathsetlength{\***@ya}{\***@lib@***@yshift}%
\pgfmathsetlength\***@xa{\***@lib@***@xshift}%
\pgftransformyshift{-\***@ya}
\foreach \d/\l in {0/Mo,1/Di,2/Mi,3/Do,4/Fr,5/Sa,6/So} {
\***@xa=\d\***@xa%
\pgftransformxshift{\***@xa-\cellwidth/2}%
\pgftransformyshift{\***@ya}%
\node[every day,day heading]{\l};%
}
}{}%
}%
]
\makeatother



\pgfkeys{/tikz/inner sep = 0pt}

\pgfkeys{/tikz/day xshift=\cellwidth+2mm+2mm}

\pgfkeys{/tikz/day yshift=\cellheight+2mm+2mm}

\newlength{\cellheight}
\setlength{\cellheight}{.13\textheight}
\newlength{\cellwidth}
\setlength{\cellwidth}{.13\textwidth}



\newcommand*{\Kalenderblatt}[1]{%
\begin{tikzpicture}[thick]
\calendar[dates=#1,
week list,
% as early as possible
if = {(and = {week of month = 1, calendar week of month = 2}) [add day
from week before]},
if = {(and = {week of month'= 1, calendar week of month'= 2}) [add day
from week after]},
every day from week before/.style=gray,
every day from week after/.style={gray,if=(Sunday)[red!25!gray]},
month label above centered,
month text=\textsc{\%mt \%y0},
day headings={font=\footnotesize},
day letter headings]
;
\end{tikzpicture}
}

\begin{document}
\Kalenderblatt{\year-11-01 to \year-11-last}
\Kalenderblatt{\year-12-01 to \year-12-last}

\end{document}
Heiner Richter
2023-11-02 16:05:25 UTC
Permalink
Fast alles klappt auch weiter, nur die wohl für sowas wie Buß- und Bettag

if (and={between=11-16 and 11-22}{Wednesday}) [observance=Buß- und Bettag]

notwendige Definition

\makeatletter
\def\***@matchesfalse{\global\let\***@matches\iffalse}
\def\***@matchestrue{\global\let\***@matches\iftrue}
\***@matchesfalse
\pgfqkeys{/pgf/calendar}{and/.code 2 args={%
\begingroup
\ifdate{#1}{\ifdate{#2}{\***@matchestrue}{}}{}%
\endgroup

\***@matches\pgfcalendarmatchestrue\***@matchesfalse\fi}}
\makeatother

haut nicht mehr hin; hier Zeilen auskommentiert, sonst Fehler. Hat
jemand eine Idee?

%%%%%%%%%%%%%%%Ergänztes, lauffähges Mini-Bsp. für Nov/Dez. 2023%%%%%%%%

\documentclass[landscape,fontsize=20pt]{scrartcl}
\pagestyle{empty}
\usepackage{tikz}
\usetikzlibrary{calendar}
\usetikzlibrary{ext.calendar-plus}
\makeatletter
\tikzset{
add day from week before/.default=, add day from week after/.default=,
add day from week before/.code={%
\begingroup % shift whole calendar 7 days in the past
\advance\pgfcalendarcurrentjulian by -7

\pgfcalendarjuliantodate{\pgfcalendarcurrentjulian}{\pgfcalendarcurrentyear}{\pgfcalendarcurrentmonth}{\pgfcalendarcurrentday}%
\pgfcalendarjuliantoweekday{\pgfcalendarcurrentjulian}{\***@tempcntb}%
\edef\pgfcalendarcurrentweekday{\the\***@tempcntb}%

\pgfcalendarjulianyeartoweek{\pgfcalendarcurrentjulian}{\pgfcalendarcurrentyear}{\***@tempcntb}%
\edef\pgfcalendarcurrentweek{\ifnum\***@tempcntb<10
0\fi\the\***@tempcntb}%
\pgftransformyshift{\pgfkeysvalueof{/tikz/day yshift}}%
\tikzset{every day from week before/.try,#1}%
\tikzdaycode
\endgroup},
add day from week after/.code={%
\begingroup % shift whole calendar 7 days in the future
\advance\pgfcalendarcurrentjulian by +7

\pgfcalendarjuliantodate{\pgfcalendarcurrentjulian}{\pgfcalendarcurrentyear}{\pgfcalendarcurrentmonth}{\pgfcalendarcurrentday}%
\pgfcalendarjuliantoweekday{\pgfcalendarcurrentjulian}{\***@tempcntb}%
\edef\pgfcalendarcurrentweekday{\the\***@tempcntb}%

\pgfcalendarjulianyeartoweek{\pgfcalendarcurrentjulian}{\pgfcalendarcurrentyear}{\***@tempcntb}%
\edef\pgfcalendarcurrentweek{\ifnum\***@tempcntb<10
0\fi\the\***@tempcntb}%
\pgftransformyshift{-(\pgfkeysvalueof{/tikz/day yshift})}%
\tikzset{every day from week after/.try,#1}%
\tikzdaycode
\endgroup}}
\makeatother

\makeatletter
\tikzstyle{month label above centered}=[%
execute before day scope={%
\ifdate{day of month=1}{%
{
\pgfmathsetlength{\***@xa}{\***@lib@***@xshift}%
\***@xb=\***@lib@***@width\***@xa%
\advance\***@xb by-\***@xa%
\***@xb=.5\***@xb%
\pgftransformxshift{\***@xb}%
\pgftransformxshift{-\cellwidth/2}%
\pgfmathsetlength{\***@y}{\***@lib@***@yshift}%
\pgftransformyshift{0.333\***@y}
\tikzmonthcode%
}
}{}},
every month/.append style={anchor=base}
]

\tikzoption{day headings}{\tikzstyle{day heading}=[#1]}
\tikzstyle{day heading}=[]
\tikzstyle{day letter headings}=[
execute before day scope={ \ifdate{day of month=1}{%
\pgfmathsetlength{\***@ya}{\***@lib@***@yshift}%
\pgfmathsetlength\***@xa{\***@lib@***@xshift}%
\pgftransformyshift{-\***@ya}
\foreach \d/\l in {0/Mo,1/Di,2/Mi,3/Do,4/Fr,5/Sa,6/So} {
\***@xa=\d\***@xa%
\pgftransformxshift{\***@xa-\cellwidth/2}%
\pgftransformyshift{\***@ya}%
\node[every day,day heading]{\l};%
}
}{}%
}%
]
\makeatother

\pgfkeys{/tikz/observance/.code =
{
\addtext{#1}
}
}


\pgfkeys{/tikz/inner sep = 0pt}

\pgfkeys{/tikz/day xshift=\cellwidth+2mm+2mm}

\pgfkeys{/tikz/day yshift=\cellheight+2mm+2mm}

\newlength{\cellheight}
\setlength{\cellheight}{.13\textheight}
\newlength{\cellwidth}
\setlength{\cellwidth}{.13\textwidth}

%%%%%%%auskommentiert, sonst Fehler
%\makeatletter
%\def\***@matchesfalse{\global\let\***@matches\iffalse}
%\def\***@matchestrue{\global\let\***@matches\iftrue}
%\***@matchesfalse
%\pgfqkeys{/pgf/calendar}{and/.code 2 args={%
% \begingroup
% \ifdate{#1}{\ifdate{#2}{\***@matchestrue}{}}{}%
% \endgroup
%
\***@matches\pgfcalendarmatchestrue\***@matchesfalse\fi}}
%\makeatother



\newcommand*{\Kalenderblatt}[1]{%
\begin{tikzpicture}[thick]
\calendar[dates=#1,
week list,
% as early as possible
if = {(and = {week of month = 1, calendar week of month = 2}) [add day
from week before]},
if = {(and = {week of month'= 1, calendar week of month'= 2}) [add day
from week after]},
every day from week before/.style=gray,
every day from week after/.style={gray,if=(Sunday)[red!25!gray]},
month label above centered,
month text=\textsc{\%mt \%y0},
day headings={font=\footnotesize},
day letter headings]
%%%%%%auskommentiert, sonst Fehler
% if (and={between=11-16 and 11-22}{Wednesday}) [observance=Buß- und Bettag]
;
\end{tikzpicture}
}

\begin{document}
\Kalenderblatt{\year-11-01 to \year-11-last}
\Kalenderblatt{\year-12-01 to \year-12-last}




\end{document}
Heiner Richter
2023-11-02 20:17:16 UTC
Permalink
Gelöst: Buß- und Bettag ließ sich in meinem Komplettbeispiel einfacher
über minus 11 Tage vorm Advent lösen

if (Advent=-11) [observance=Buß- und Bettag]

und die Fehler aufgrund der Kollision bei der and-Definition habe ich
nunmehr eliminiert mit anders abgekupfertem Code

https://tex.stackexchange.com/questions/140948/tikz-calendar-and-conditional-tests

und statt "and" bzw. "And" halt "und" und "Und" verwendet

\makeatletter
\pgfqkeys{/pgf/calendar}{
und/.code 2 args=%
\begingroup
\let\***@cal@temp\***@empty
\***@launch@ifdate{#1}{\***@launch@ifdate{#2}{\def\***@cal@temp{\let\ifpgfcalendarmatches\iftrue}}{}}{}%
\expandafter\endgroup\***@cal@temp,
Und/.code=%
\begingroup
\let\***@cal@temp\***@empty
\ifpgfcalendarmatches\expandafter\***@firstofone\else\expandafter\***@gobble\fi
{\***@launch@ifdate{#1}{\def\***@cal@temp{\let\ifpgfcalendarmatches\iftrue}}{}}%
\expandafter\endgroup\***@cal@temp}
\makeatother

Jetzt klappt alles (nur geht's nicht mehr im Mini-Beispiel) und ich habe
einen ewigen automatischen Kalender mit allen Feiertagen und sonstigen
flexiblen Jahrestagen.

Viele Grüße und Danke

Heiner

Lesen Sie weiter auf narkive:
Loading...