
Некоторое время назад я нашел действительно хороший фрагмент для создания календарных страниц Filofax (tm) organiser A5 -- к сожалению, я не смог найти исходный код. Впоследствии я модифицировал его и теперь с нетерпением жду возможности его использовать.
Однако мне не удалось создать больше двух последовательных страниц. Было бы очень здорово, если бы я мог добавить цикл, чтобы я мог создавать больше одной недели за раз. Может быть, месяц, год или даже произвольный промежуток времени.
\documentclass[%
a5paper,
BCOR=2cm,% Space for hole puncher
DIV=25,% Size of textbody
9pt% Fontsize
]{scrbook}
%
%%%%%%%%%% PACKAGES %%%%%%%%%%
%
\usepackage{tabularx,booktabs,multirow}
%\renewcommand*\familydefault{\sfdefault}
%\usepackage{roboto}
\renewcommand{\familydefault}{\sfdefault}
%
%%%%%%%%%% COUNTER %%%%%%%%%%
%
\newcount\counter
\newcount\startdate
\newcount\starttime
\newcount\stoptime
\newcount\sundaybegin
\newcount\week
%
%%%%%%%%%% CUSTOMISATIONS %%%%%%%%%%
%
%% Month
\renewcommand{\month}{March}
%% Date to start the week with
\startdate=13
%% Morning starttime
\starttime=8
%% Evening time
\stoptime=20
%% Starttime sunday
% Min \starttime+1
% Max \stoptime-2
\sundaybegin=14
%% Weeknumber
\week=11
%% Rule width thick
\newcommand{\rulew}{.15em}
%% Extra space
%\setlength{\extrarowheight}{1pt}
%
%%%%%%%%%% DEFINITIONS %%%%%%%%%%
%
\newcommand{\lendt}{\cmidrule[\rulew](l){1-2}\cmidrule[\rulew](l){3-4}\cmidrule[\rulew](l){5-6}}
\newcommand{\lend}{\cmidrule(l){1-2}\cmidrule(l){3-4}\cmidrule(l){5-6}}
\newcommand{\lsun}{\cmidrule(l){1-2}\cmidrule(l){3-4}}
\newcommand{\lsunt}{\cmidrule(l){1-2}\cmidrule(l){3-4}\cmidrule[\rulew](l){5-6}}
\newcommand{\printday}[2]{{\LARGE \textbf{#1}}\,\, \large \textbf{#2}}
\newcommand{\neutralline}{& & & & &}
\newcommand{\footer}{\centering\rule{5.5cm}{\cmidrulewidth} \raisebox{-0.5ex}{\textbf{Dragosh Christian OTTO}} \rule{5.5cm}{\cmidrulewidth}}
\newcommand{\printmonth}{{\LARGE \textbf{\month}}}
%
%%%%%%%%%% TABLE CONTENT LEFT SIDE %%%%%%%%%%
%
% Correction due to \global\advance
\advance\startdate-6
%
\advance\stoptime1
\long\def\addto#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}
%
\def\tabledataleft{} \counter=\the\starttime
\loop
\edef\tabline{\the\counter & & \the\counter & & \the\counter & }
\expandafter\addto\expandafter\tabledataleft\expandafter{\tabline \\\lend}
\expandafter\addto\expandafter\tabledataleft\expandafter{\neutralline \\\lend}
\expandafter\addto\expandafter\tabledataleft\expandafter{\neutralline \\\lend}
\expandafter\addto\expandafter\tabledataleft\expandafter{\neutralline \\\lend}
\advance \counter 2
\ifnum \counter<\the\stoptime
\repeat
%
%%%%%%%%%% TABLE CONTENT RIGHT SIDE %%%%%%%%%%
%
\def\tabledatarightupper{} \counter=\the\starttime
\loop
\edef\tabline{\the\counter & & \the\counter & & & }
\expandafter\addto\expandafter\tabledatarightupper\expandafter{\tabline \\\lend}
\expandafter\addto\expandafter\tabledatarightupper\expandafter{\neutralline \\\lend}
\expandafter\addto\expandafter\tabledatarightupper\expandafter{\neutralline \\\lend}
\expandafter\addto\expandafter\tabledatarightupper\expandafter{\neutralline \\\lend}
\advance \counter 2
\ifnum \counter<\the\sundaybegin
\repeat
%
\advance\sundaybegin1
\def\tabledatarightinter{} \counter=\the\sundaybegin
\newcount\sundaystop
\sundaystop=\the\sundaybegin
\advance\sundaystop1
\loop
\edef\tabline{\the\counter & & \the\counter & & & }
%\expandafter\addto\expandafter\tabledatarightinter\expandafter{\neutralline \\\lsun}
\expandafter\addto\expandafter\tabledatarightinter\expandafter{\neutralline \\\lsun}
\expandafter\addto\expandafter\tabledatarightinter\expandafter{\neutralline \\\lsun}
\advance \counter 2
\ifnum \counter<\the\sundaystop
\repeat
\advance\sundaybegin-1
\advance\sundaystop1
%
\def\tabledatarightlower{} \counter=\the\sundaystop
\loop
\advance \counter 1
\edef\tabline{\the\counter & & \the\counter & & & }
\expandafter\addto\expandafter\tabledatarightlower\expandafter{\neutralline \\\lend}
\expandafter\addto\expandafter\tabledatarightlower\expandafter{\neutralline \\\lend}
\expandafter\addto\expandafter\tabledatarightlower\expandafter{\neutralline \\\lend}
\expandafter\addto\expandafter\tabledatarightlower\expandafter{\tabline \\\lend}
\advance \counter 1
\ifnum \counter<\the\stoptime
\repeat
\advance\sundaystop-1
%
\begin{document}
%
%% Empty page to start left
\thispagestyle{empty}
\mbox{}
\clearpage
%
\pagestyle{empty}
\enlargethispage{1cm}
%
%%%%%%%%%% LEFT TABLE %%%%%%%%%%
%
\noindent
\begin{tabularx}{\linewidth}{lXlXlX}
\multicolumn{6}{l}{\printmonth \hfill Week \the\week}\\[.2em]
\midrule[\rulew]
\addlinespace[.5em]
\multicolumn{2}{l}{\printday{\the\startdate}{Monday}} \global\advance\startdate 1\relax &%
\multicolumn{2}{l}{\printday{\the\startdate}{Tuesday}} \global\advance\startdate 1\relax &%
\multicolumn{2}{l}{\printday{\the\startdate}{Wednesday}}\global\advance\startdate 1\relax \\[1cm]
& & & & & \\\lendt
\tabledataleft
& & & & & \\[1cm]
\midrule[\rulew]
\end{tabularx}
%
\vfill
%\footer
%
\clearpage
\enlargethispage{1cm}
% Correction due to \global\advance
\advance\startdate-6
%
%%%%%%%%%% RIGHT TABLE %%%%%%%%%%
%
\noindent
\begin{tabularx}{\linewidth}{lXlXlX}
\multicolumn{6}{l}{Week \the\week \hfill \printmonth}\\[.2em]\midrule[\rulew]
\addlinespace[.5em]
\multicolumn{2}{l}{\printday{\the\startdate}{Thursday}} \global\advance\startdate 1\relax &%
\multicolumn{2}{l}{\printday{\the\startdate}{Friday}} \global\advance\startdate 1\relax &%
\multicolumn{2}{l}{\printday{\the\startdate}{Saturday}} \global\advance\startdate 1\relax \\[1cm]
& & & & & \\\lendt
\tabledatarightupper
%& & & & & \\\lsunt
\addlinespace[-.15em]
\the\sundaybegin & & \the\sundaybegin & & \multicolumn{2}{l}{\multirow{4}{*}[1.5em]{\printday{\the\startdate}{Sunday}}}\\\lsun
\tabledatarightinter
& & & & & \\\lsun
\the\sundaystop & & \the\sundaystop & & & \\\lsunt
\tabledatarightlower
& & & & & \\\lend
& & & & & \\\lend
& & & & & \\\lend
& & & & & \\[1cm]
\midrule[\rulew]
\end{tabularx}
%
\vfill
%\footer
\end{document}
решение1
PGF/TikZ поставляется с «утилитой»PGFCalendar. В мой tikz-ext
пакет я добавилподдержка нумерации недель. Для этого вам фактически нужно будет загрузить пакет pgfcalendar-ext
.
Теперь у PGFCalendar есть одна основная команда:\pgfcalendar
Он перебирает все даты, указанные в диапазоне, и настраивает несколько макросов (и один счетчик TeX), которые содержат информацию о текущем дне. (И pgfcalendar-ext
расширяет ее так, чтобы был доступен также номер недели.)
Теперь нам не нужно проходить по каждой дате, а нужно рассмотреть только понедельники (левая сторона) и четверги (правая сторона).
Итак, в конце мы обманываем PGFCalendar, перемещаясь во времени в среду (левая сторона) и воскресенье (правая сторона):
\ifdate{Monday}{\advance\pgfcalendarcurrentjulian by 2}
{\advance\pgfcalendarcurrentjulian by 3}
\clearpage
На самом деле мы могли бы просто \ifodd\value{page}
определить, где мы находимся, но здесь я использую PGFCalendar, \ifdate
где понедельник указывает на левую сторону.
Поскольку заголовок и низ каждой страницы примерно одинаковы, мы набираем это прямо в цикле. Мы используем тот же тест, чтобы выяснить, нужно ли нам набирать левую или правую настройку заголовка. (Мы, вероятно, могли бы использовать для этого левую и правую метки классов Koma, но это не наша главная забота здесь.)
После того, как мы набрали три дня вверху (подробнее об этом позже), нам снова нужно подумать, на какой странице мы находимся (→ \ifdate{Monday}
).
Для левой стороны мы просто набираем все строки для всех времен. Для правой стороны мы должны разбить их на воскресенье.
Вместо ваших готовых шаблонов я использую Latex3 \int_step_function:nnnN
как простой цикл for(each). Его можно безопасно использовать внутри tabularx
. Воскресная сторона немного запутана. Я внес несколько корректировок:
Посмотрите,
\lineEndSundayTop
где я добавил межстрочный интервал, который заставит таблицу игнорировать дополнительную толщину,\ruleThick
так что сетка линий с правой стороны будет располагаться точно так же, как и с левой стороны.Заголовок воскресенья опускается (отрицательно поднимается) при
\smash
редактировании таким образом, чтобы он не подбирался к верхней строке, не увеличивая ее по вертикали.
Теперь мы не можем просто прибавить один, два или — для воскресенья — три к текущему дню, чтобы получить другие дни на странице, которые не являются понедельником или четвергом, потому что каждый из этих дней может быть в следующем месяце.
Мы могли бы немного проверить, окажемся ли мы выше 28/29/30/31 и скорректировать все соответствующим образом, но я просто позволю PGFCalendar снова сделать эту работу через \PGFCalendarPlus
.
Этот макрос запустит еще один \pgfcalendar
цикл из одного (1) дня, который идет через один, два или три дня после текущего (это либо понедельник, либо четверг). Мы выведем номер дня и день недели, и все.
Код
\documentclass[a5paper, BCOR=2cm, DIV=25, fontsize=9pt]{scrbook}
% https://tex.stackexchange.com/a/651888
\usepackage{pgfcalendar-ext} % loads pgfcalendar and has weeknumbering
\usepackage{tabularx, booktabs, multirow}
\usepackage{xfp}% for \inteval for older TeX distributions
\renewcommand*\familydefault{\sfdefault}
% horizontal lines in tabularx
\newcommand*\lineEndTop {\cmidrule[\ruleThick](l){1-2}\cmidrule[\ruleThick](l){3-4}\cmidrule[\ruleThick](l){5-6}}
\newcommand*\lineEnd {\cmidrule (l){1-2}\cmidrule (l){3-4}\cmidrule (l){5-6}}
\newcommand*\lineEndSunday {\cmidrule (l){1-2}\cmidrule (l){3-4}}
\newcommand*\lineEndSundayTop{\cmidrule (l){1-2}\cmidrule (l){3-4}\cmidrule[\ruleThick](l){5-6}%
\addlinespace[\dimexpr-\ruleThick+\lightrulewidth]}
\newcommand*\printDay {{\LARGE \textbf{\%d-}}\,\, \large \textbf{\%wt}}
\newcommand*\printDays {%
\multicolumn{2}{l} {\printDay} &
\multicolumn{2}{l}{\PGFcalendarPlus{1}{\printDay}} &
\multicolumn{2}{l}{\PGFcalendarPlus{2}{\printDay}}}
\newcommand*\printWeekLeft {{\bfseries\LARGE\%mt} \hfill Week \%n-}
\newcommand*\printWeekRight {Week \%n-\hfill {\bfseries\LARGE\%mt}}
\newcommand*\timeStart {8}
\newcommand*\timeEnd {20}
\newcommand*\timeStep {2}
\newcommand*\timeSunday{14}
\newcommand*\timeBlockX[2]{%
#1 & & #1 & & #2 \\ \lineEnd
& & & & & \\ \lineEnd \\ \lineEnd \\ \lineEnd}
\newcommand*\timeBlockLeft [1]{\timeBlockX{#1}{#1}}
\newcommand*\timeBlockRight[1]{\timeBlockX{#1}{}}
\newcommand*\blockSunday[3]{% Ugh!
\inteval{\timeSunday-\timeStep} & &
\inteval{\timeSunday-\timeStep} & & \\ \lineEnd
\\ \lineEnd \\ \lineEnd \\ \lineEndSundayTop
\timeSunday & & \timeSunday & & #1 \\ \lineEndSunday
\\ \lineEndSunday \\ \lineEndSunday}
\newcommand*\PGFcalendarPlus[2]{%
\pgfcalendar{temp}{\pgfcalendarcurrentyear-\pgfcalendarcurrentmonth-\pgfcalendarcurrentday+#1}
{\pgfcalendarcurrentyear-\pgfcalendarcurrentmonth-\pgfcalendarcurrentday+#1}{#2}}
\newcommand*\ruleThick{.15em}
\pagestyle{empty}
\setlength\parindent{0pt}% instead of \noindent
\ExplSyntaxOn \let\FOREACH\int_step_function:nnnN \ExplSyntaxOff
\let\%\pgfcalendarshorthand
%\usepackage[showframe, pass]{geometry}
\begin{document}
\null\clearpage
\pgfcalendar{cal}{2023-03-13}{2023-06-30}{%
\enlargethispage{1cm}
\begin{tabularx}{\linewidth}{lXlXlX}
\multicolumn{6}{l}{\ifdate{Monday}{\printWeekLeft}{\printWeekRight}}\\[.2em]
\midrule[\ruleThick] \addlinespace[.5em]
\printDays \\[4em]\lineEndTop
\ifdate{Monday}{% left page
\FOREACH{\timeStart}{\timeStep}{\timeEnd}\timeBlockLeft
}{%
\FOREACH{\timeStart}{\timeStep}{\inteval{\timeSunday-2*\timeStep}}\timeBlockRight
\blockSunday{\multicolumn{2}{l}{\PGFcalendarPlus{3}{\smash{\raisebox{-.3em}{\printDay}}}}}{}{}
\\\lineEndSundayTop
\FOREACH{\inteval{\timeSunday+\timeStep}}{\timeStep}{\timeEnd}\timeBlockRight
}%
\\[1cm]
\midrule[\ruleThick]
\end{tabularx}
\ifdate{Monday}{\advance\pgfcalendarcurrentjulian by 2}
{\advance\pgfcalendarcurrentjulian by 3}
\clearpage
}
\end{document}