TeX - LaTeX Asked by Stefan Drückler on April 2, 2021
I am adopting this calendar (https://texample.net/tikz/examples/birthday-calendar/) to my needs, but I have a problem I cannot solve on my own.
In each single day grid, how can I get rid of the last comma in the list of birthdays (blue top line) and the list of special days (green bottom line)?
Bonus question: Is it possible that a second line of birthdays starts right of the day number?
This is my code:
% Birthday calendar
% Author: Hakon Malmedal
documentclass[fontsize=15pt]{scrartcl}
usepackage[german]{babel}
usepackage[utf8]{inputenc}
usepackage[T1]{fontenc}
usepackage{lmodern}
usepackage[paperheight=70cm,paperwidth=50cm,margin=0mm,heightrounded]{geometry}
%usepackage[margin=1cm,a4paper,landscape]{geometry}
pagestyle{empty}
usepackage{graphicx}
usepackage{tikz}
%%%<
usepackage{verbatim}
%%%>
begin{comment}
:Title: Birthday calendar
:Tags: Calendar library;Calendars
:Author: Hakon Malmedal
:Slug: birthday-calendar
end{comment}
usetikzlibrary{calendar,fit}
usepackage{expl3,xparse}
%from https://tex.stackexchange.com/questions/140948/tikz-calendar-and-conditional-tests
makeatletter
defpgfcalendar@matchesfalse{globalletifpgfcalendar@matchesiffalse}
defpgfcalendar@matchestrue{globalletifpgfcalendar@matchesiftrue}
pgfcalendar@matchesfalse
pgfqkeys{/pgf/calendar}{and/.code 2 args={%
begingroup
ifdate{#1}{ifdate{#2}{pgfcalendar@matchestrue}{}}{}%
endgroup
ifpgfcalendar@matchespgfcalendarmatchestruepgfcalendar@matchesfalsefi}}
makeatother
%% Adapted from pgf source
defpgfcalendarmonthname#1{%
translate{ifcase#1or Januaror Februaror Märzor Aprilor
Maior Junior Julior Augustor Septemberor Oktoberor
Novemberor Dezemberfi}%
}
%% Adapted from http://tex.stackexchange.com/a/10199/4771
makeatletter%
tikzoption{day headings}{tikzstyle{day heading}=[#1]}
tikzstyle{day heading}=[]
tikzstyle{day letter headings}=[
execute before day scope={ ifdate{equals=01-01}{%
pgfmathsetlength{pgf@ya}{tikz@lib@cal@yshift}%
pgfmathsetlengthpgf@xa{tikz@lib@cal@xshift}%
pgftransformyshift{-pgf@ya}
foreach d/l in {0/Montag,1/Dienstag,2/Mittwoch,3/Donnerstag,%
4/Freitag,5/Samstag,6/Sonntag} {
pgf@xa=dpgf@xa%
pgftransformxshift{pgf@xa-cellwidth/2}%
pgftransformyshift{2pgf@ya-2pt}%
node[below=0.5ex,day heading, inner sep=2.5mm,font=Large]{l};%
}
}{}%
}%
]
makeatother%
%% End
ExplSyntaxOn
%% Adapted from http://tex.stackexchange.com/a/56214/4771
%%
% first of all we define the user level commands
NewDocumentCommand{addtext}{ m }{ bdaycal_input_add_text:n { #1 } }
NewDocumentCommand{addbirthday}{ mm }{ bdaycal_input_add_birthday:nn { #1 } { #2 } }
NewDocumentCommand{addbirthdaydead}{ mm }{ bdaycal_input_add_birthday_dead:nn { #1 } { #2 } }
NewDocumentCommand{adddateofdeath}{ mm }{ bdaycal_input_add_date_of_death:nn { #1 } { #2 } }
NewDocumentCommand{addweek}{ m }{ bdaycal_input_add_week:n { #1 } }
NewDocumentCommand{showtext}{ }{ bdaycal_output_direct_text: }
NewDocumentCommand{showbirthdays}{ }{ bdaycal_output_direct_birthday: }
% allocate variable:
% a sequence for global storage of the inputs;
seq_new:N g_bdaycal_input_seq_text
seq_new:N g_bdaycal_input_seq_birthday
% store globally an input in the sequence
cs_new:Npn bdaycal_input_add_text:n #1
{
seq_gput_right:Nn g_bdaycal_input_seq_text { #1 }
}
cs_new:Npn bdaycal_input_add_birthday:nn #1 #2
{
seq_gput_right:Nn g_bdaycal_input_seq_birthday { #1 ~ int_to_arabic:n
{ pgfcalendarifdateyear - #2 }}
}
cs_new:Npn bdaycal_input_add_birthday_dead:nn #1 #2
{
seq_gput_right:Nn g_bdaycal_input_seq_birthday {( #1 ~ int_to_arabic:n
{ pgfcalendarifdateyear - #2 })}
}
cs_new:Npn bdaycal_input_add_date_of_death:nn #1 #2
{
seq_gput_right:Nn g_bdaycal_input_seq_birthday {dag #1 ~ #2}
}
% how to output in direct order; we simply do a mapping function calling
% bdaycal_print:n after incrementing the counter
cs_new_protected:Npn bdaycal_output_direct_text:
{
seq_map_inline:Nn g_bdaycal_input_seq_text
{
int_gincr:N g_tmpa_int
% int_compare:nNnT {g_tmpa_int}={1}{}%vor dem ersten Eintrag
##1
int_compare:nNnF {g_tmpa_int}={seq_count:N g_bdaycal_input_seq_text}{,~}%am Ende jedes Eintrags, außer nach dem letzten
}
seq_gclear:N g_bdaycal_input_seq_text
}
cs_new_protected:Npn bdaycal_output_direct_birthday:
{
seq_map_inline:Nn g_bdaycal_input_seq_birthday
{
int_gincr:N g_tmpa_int
% int_compare:nNnT {g_tmpa_int}={1}{}%vor dem ersten Eintrag
##1
int_compare:nNnF {g_tmpa_int}={seq_count:N g_bdaycal_input_seq_birthday}{,~}%am Ende jedes Eintrags, außer nach dem letzten
}
seq_gclear:N g_bdaycal_input_seq_birthday
}
%% End
%% Knuth's AoCP, vol 1, 2nd ed, pp 155--156
int_new:N l_easter_Y_int
int_new:N l_easter_G_int
int_new:N l_easter_C_int
int_new:N l_easter_X_int
int_new:N l_easter_Z_int
int_new:N l_easter_D_int
int_new:N l_easter_E_int
int_new:N l_easter_N_int
int_new:N l_easter_M_int
int_new:N l_easter_julian_day_int
cs_new:Nn easter_sunday:n {
int_set:Nn l_easter_Y_int { #1 }
int_set:Nn l_easter_G_int {
int_mod:nn { l_easter_Y_int } { 19 } + 1
}
int_set:Nn l_easter_C_int {
int_div_truncate:nn { l_easter_Y_int } { 100 } + 1
}
int_set:Nn l_easter_X_int {
int_div_truncate:nn { 3 * l_easter_C_int } { 4 } - 12
}
int_set:Nn l_easter_Z_int {
int_div_truncate:nn { 8 * l_easter_C_int + 5 } { 25 } - 5
}
int_set:Nn l_easter_D_int {
int_div_truncate:nn { 5 * l_easter_Y_int } { 4 } - l_easter_X_int - 10
}
int_set:Nn l_easter_E_int {
int_mod:nn { 11 * l_easter_G_int + 20 + l_easter_Z_int
- l_easter_X_int } { 30 }
}
% int_mod:nn behaves strangely.
int_compare:nNnT { l_easter_E_int } < { 0 }
{
int_add:Nn l_easter_E_int { 30 }
}
int_compare:nNnTF { l_easter_E_int } = { 25 }
{ % true
int_compare:nNnT { l_easter_G_int } > { 11 }
{ % true
int_incr:N l_easter_E_int
}
}
{ % false
int_compare:nNnT { l_easter_E_int } = { 24 }
{ % true
int_incr:N l_easter_E_int
}
}
int_set:Nn l_easter_N_int { 44 - l_easter_E_int }
int_compare:nNnT { l_easter_N_int } < { 21 }
{ % true
int_add:Nn l_easter_N_int { 30 }
}
int_add:Nn l_easter_N_int {
7 - int_mod:nn { l_easter_D_int + l_easter_N_int } { 7 }
}
int_compare:nNnTF { l_easter_N_int } > { 31 }
{ % true
int_sub:Nn l_easter_N_int { 31 }
int_set:Nn l_easter_M_int { 4 } % April
}
{ % false
int_set:Nn l_easter_M_int { 3 } % March
}
pgfcalendardatetojulian { l_easter_Y_int -
l_easter_M_int - l_easter_N_int
} { l_easter_julian_day_int }
}
pgfkeys{/pgf/calendar/Easter/.default = 0}
pgfkeys{/pgf/calendar/Easter/.code =
{
easter_sunday:n { pgfcalendarifdateyear }
int_compare:nNnT { pgfcalendarifdatejulian }
= {l_easter_julian_day_int + #1}
{ pgfcalendarmatchestrue }
}
}
int_new:N l_advent_Y_int
int_new:N l_advent_xmas_julian_day_int
int_new:N l_advent_xmas_week_day_int
int_new:N l_advent_julian_day_int
cs_new:Nn advent_sunday:n {
int_set:Nn l_advent_Y_int { #1 }
pgfcalendardatetojulian { l_advent_Y_int - 12 - 25 } {
l_advent_xmas_julian_day_int }
pgfcalendarjuliantoweekday { l_advent_xmas_julian_day_int } {
l_advent_xmas_week_day_int }
int_set:Nn l_advent_julian_day_int {
l_advent_xmas_julian_day_int - l_advent_xmas_week_day_int - 22 }
}
ExplSyntaxOff
pgfkeys{/tikz/observance/.code =
{
addtext{#1}
}
}
pgfkeys{/tikz/anniversary/.code 2 args=addbirthday{#1}{#2}}
pgfkeys{/tikz/anniversary_dead/.code 2 args=addbirthdaydead{#1}{#2}}
pgfkeys{/tikz/date_of_death/.code 2 args=adddateofdeath{#1}{#2}}
pgfkeys{/tikz/day code =
{
node (lower right) at (-1pt,1pt){};
node (upper left) at (-cellwidth +1pt,cellheight -1pt){};
node (day of month) at (-cellwidth + 3pt,0.3cellheight) [above right,font=bfseriesLarge] {tikzdaytext};
node (birthdays) at (-cellwidth +2pt,cellheight -2pt)
[below right,align=left,text width=cellwidth-3pt,
font=tinybfseries,blue] {showbirthdays};
node (name of day) at (-cellwidth +2pt,8pt)
[below right,align=left,text width=cellwidth-pgflinewidth,
font=tiny,green] {showtext};
node[draw,
fit=(lower right) (upper left),
inner sep=0mm] {};
}
}
pgfkeys{/tikz/inner sep = 0pt}
pgfkeys{/tikz/day xshift=cellwidth}
pgfkeys{/tikz/day yshift=cellheight}
pgfkeys{/tikz/month yshift=0mm}
newlength{cellheight}
setlength{cellheight}{13mm}
newlength{cellwidth}
setlength{cellwidth}{68mm}
begin{document}
centering
begin{tikzpicture}[thick]
calendar[dates=2021-01-01 to 2021-12-last,
week list,
day headings={font=footnotesize},
day letter headings
]
if (%Sunday,
% Easter=-3, % Maundy Thursday
Easter=-2, % Good Friday
Easter, % Easter Sunday
Easter=1, % Easter Monday
Easter=39, % Feast of the Ascension
Easter=49, % Pentecost
Easter=50, % Whit Monday
equals=01-01,%Neujahr
equals=03-08,%Internationaler Frauentag (nur Berlin)
equals=05-01,%Tag der Arbeit
equals=10-03,%Tag der deutschen Einheit
equals=12-25,%1. und 2. Weihnachtsfeiertag
equals=12-26) [red]
if (Easter=-48) [observance=Rosenmontag]
if (Easter=-46) [observance=Aschermittwoch]
if (Easter=-7) [observance=Palmsonntag]
if (Easter=-3) [observance=Gründonnerstag]
if (Easter=-2) [observance=Karfreitag]
if (Easter) [observance=Ostersonntag]
if (Easter=1) [observance=Ostermontag]
if (Easter=39) [observance=Christi Himmelfahrt]
if (Easter=39) [observance=Vatertag]
if (Easter=49) [observance=Pfingstsonntag]
if (Easter=50) [observance=Pfingstmontag]
if (Easter=59) [observance=Fronleichnam]
if (equals=01-01) [observance=Neujahr]
if (equals=01-06) [observance=Heilige drei Könige]
if (equals=02-14) [observance=Valentinstag]
if (equals=03-08) [observance=Internationaler Frauentag]
if (equals=05-01) [observance=Tag der Arbeit]
if (equals=05-08) [observance=Tag der Befreiung / Ende WWII 1945]
if (equals=08-15) [observance=Mariä Himmelfahrt]
if (equals=10-03) [observance=Tag der deutschen Einheit 1990]
if (equals=10-31) [observance=Reformationstag]
if (equals=10-31) [observance=Halloween]
if (equals=11-01) [observance=Allerheiligen]
if (equals=11-09) [observance=Fall der Mauer 1989]
if (equals=11-09) [observance=Novemberprogrome 1938]
if (equals=12-24) [observance=Heilig Abend]
if (equals=12-25) [observance=1. Weihnachtstag]
if (equals=12-26) [observance=2. Weihnachtstag]
if (equals=12-31) [observance=Silvester]
if (and={between=11-16 and 11-22}{Wednesday}) [observance=Buß- und Bettag]
if (and={between=11-13 and 11-19}{Sunday}) [observance=Volkstrauertag]
if (and={between=11-20 and 11-26}{Sunday}) [observance=Totensonntag]
if (and={between=11-27 and 12-03}{Sunday}) [observance=1. Advent]
if (and={between=12-04 and 12-10}{Sunday}) [observance=2. Advent]
if (and={between=12-11 and 12-17}{Sunday}) [observance=3. Advent]
if (and={between=12-18 and 12-24}{Sunday}) [observance=4. Advent]
if (and={between=03-25 and 03-31}{Sunday}) [observance=Beginn Sommerzeit]%letzter Sonntag im März
if (and={between=10-25 and 10-31}{Sunday}) [observance=Ende Sommerzeit]%letzter Sonntag im Oktober
if (and={between=05-08 and 05-14}{Sunday}) [observance=Muttertag]%2. Sonntag im Mai
if (equals=12-06) [observance=Nikolaus]
if (equals=07-17) [anniversary={John Smith}{2018}]
if (equals=12-07) [anniversary={John Smith}{1982}]
if (equals=01-04) [anniversary={John Smith}{1983}]
if (equals=01-18) [anniversary={John Smith}{1985}]
if (equals=10-23) [anniversary={John Smith}{1986}]
if (equals=08-29) [anniversary={John Smith}{1954}]
if (equals=10-14) [anniversary={John Smith}{1954}]
if (equals=03-01) [anniversary_dead={John Smith}{1923}]
if (equals=05-24) [date_of_death={John Smith}{2011}]
if (equals=12-01) [anniversary={John Smith}{1927}]
if (equals=08-29) [anniversary={John Smith}{2013}]
if (equals=08-29) [anniversary={John Smith}{1981}]
;
end{tikzpicture}
end{document}
The following code solves the problem:
int_new:N g_counter_int
cs_new_protected:Npn bdaycal_output_direct_text:
{
seq_map_inline:Nn g_bdaycal_input_seq_text
{
int_add:Nn g_counter_int { 1 }
##1
int_compare:nNnF {g_counter_int}={seq_count:N g_bdaycal_input_seq_text}{,~}
}
seq_gclear:N g_bdaycal_input_seq_text
int_set:Nn g_counter_int {0}
}
cs_new_protected:Npn bdaycal_output_direct_birthday:
{
seq_map_inline:Nn g_bdaycal_input_seq_birthday
{
int_add:Nn g_counter_int { 1 }
##1
int_compare:nNnF {g_counter_int}={seq_count:N g_bdaycal_input_seq_birthday}{,~}
}
seq_gclear:N g_bdaycal_input_seq_birthday
int_set:Nn g_counter_int {0}
}
Correct answer by Stefan Drückler on April 2, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP