采用 Moleskine/Leuchtturm 每周格式的 LaTeX 日历布局

采用 Moleskine/Leuchtturm 每周格式的 LaTeX 日历布局

我正在尝试创建自己的 A5 页面,其周历格式类似于标准 Moleskine 或 Leuchtturm 周历(参见附图左侧部分),以便为我的 A5 Atoma 笔记本制作自己的日历,但可以自动添加朋友的生日。

系统:Windows,MiKTeX

看来,使用 TikZ 应该可以实现(http://www.texample.net/tikz/examples/feature/calendar-library/),但是,我找不到符合我想要的风格的例子。

您对于如何开始有什么提示、技巧或建议吗?

提前致谢,迈克尔

想要日历布局

答案1

免责声明:这还不是一个功能齐全的解决方案。它计划进行更新。

以下是一个答案,它生成一个 PDF,每页显示一周,为期一年,从包含 1 月 1 日的那一周开始。但是,它尚未实现自动添加亲属生日的功能。它也不支持闰年。

工作准则
每周生成一个单独的tikzpicture。文档主体只是一个循环,根据tikzpicture需要多次调用创建该 的宏。(请注意,tikz给出的选项会\documentclass{standalone}为每张图片创建一个新页面。)

作为代码的输入,您手动设置:

  • 您要生成日历的年份,
  • 一月一日(星期一、星期二等)
  • 今年有多少周,
  • 是什么ISO 周日期一月一日。

然后就是关于计数器的全部内容,如下面的代码所示。

代码

\documentclass[tikz]{standalone}% Does not support leap years.

%% Load needed packages
\usepackage{lmodern}
\usepackage{tikz}
    \usetikzlibrary{positioning}
\usepackage{ifthen}

%% Create needed conters  
    \newcounter{ThisYear}
    \newcounter{NewYearsDay}
    \newcounter{NewYearsWeek}
    \newcounter{NumberOfWeeksThisYear}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% SET VARIABLES HERE                                         %

% Year number you want to generate the calendar for:
    \setcounter{ThisYear}{2017}             

% Which day is the January, 1st? (1 for Monday, 2 for Tuesday, etc.)
    \setcounter{NewYearsDay}{7}

% Which week does January, 1st belongs to?
    % Choose 52 (sometimes 53) or 1. Week 1 is not necessary the week of Jan, 1st; but *it is the week of Jan, 4th.*)
    \setcounter{NewYearsWeek}{52}

% How many weeks this year? (Choose 52 or 53, appropriately)
    \setcounter{NumberOfWeeksThisYear}{52}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Let's begin with messy stuff

    % If Jan, 1st is not on Week #1...
    \ifthenelse{\value{NewYearsWeek}>51}{
        \addtocounter{ThisYear}{-1}         % start calendar with the last week of the previous year
        \stepcounter{NumberOfWeeksThisYear} % increase amount of weeks to generate
    }{}

    % Following counter is the backbone of the calendar generation.
    \newcounter{NDOYnumber}             %% Nth Day Of the Year: 1 for Jan, 1st; 2 for Jan, 2nd; etc.
        % Set the first day of the calendar (i.e. Monday of the first generated week)
        \ifthenelse{\value{NewYearsDay}=1}{
            % Monday = Jan, 1st
            \setcounter{NDOYnumber}{1}
        }{
            % Monday belongs to previous year
            \setcounter{NDOYnumber}{367}
            \addtocounter{NDOYnumber}{-\value{NewYearsDay}}
        }

    % Store day's quantieme (1 for Jan, 1st & Feb, 1st, etc.; 17 for Jan, 17th, Feb, 17th, etc.)
    \newcounter{NDOYquantieme}

    % Store day's month number (1 for Jan, 2 for Feb, etc.)
    \newcounter{NDOYmonthnumber}

    % Internal counter
    \newcounter{tempNDOY}

    % Based on `NDOYnumber` value, compute month number and quantieme
    \newcommand{\NDOYtomonthnumber}{%
        \setcounter{tempNDOY}{\value{NDOYnumber}}%
        \setcounter{NDOYmonthnumber}{1}%
        \ifthenelse{\value{tempNDOY}<32}{%              %% JANUARY
            \setcounter{NDOYquantieme}{\value{tempNDOY}}%% Set January quantieme
        }{%
            \addtocounter{tempNDOY}{-31}%
            \stepcounter{NDOYmonthnumber}%                  %% FEBRUARY
            \ifthenelse{\value{tempNDOY}<29}{%
                \setcounter{NDOYquantieme}{\value{tempNDOY}}%
            }{%
                \addtocounter{tempNDOY}{-28}%
                \stepcounter{NDOYmonthnumber}%                  %% MARCH
                \ifthenelse{\value{tempNDOY}<32}{%
                    \setcounter{NDOYquantieme}{\value{tempNDOY}}%
                }{%
                    \addtocounter{tempNDOY}{-31}%
                    \stepcounter{NDOYmonthnumber}%                  %% APRIL
                    \ifthenelse{\value{tempNDOY}<31}{%
                        \setcounter{NDOYquantieme}{\value{tempNDOY}}%
                    }{%
                        \addtocounter{tempNDOY}{-30}%
                        \stepcounter{NDOYmonthnumber}%                  %% MAY
                        \ifthenelse{\value{tempNDOY}<32}{%
                            \setcounter{NDOYquantieme}{\value{tempNDOY}}%
                        }{%
                            \addtocounter{tempNDOY}{-31}%
                            \stepcounter{NDOYmonthnumber}%                  %% JUNE
                            \ifthenelse{\value{tempNDOY}<31}{%
                                \setcounter{NDOYquantieme}{\value{tempNDOY}}%
                            }{%
                                \addtocounter{tempNDOY}{-30}%
                                \stepcounter{NDOYmonthnumber}%                  %% JULY
                                \ifthenelse{\value{tempNDOY}<32}{%
                                    \setcounter{NDOYquantieme}{\value{tempNDOY}}%
                                }{%
                                    \addtocounter{tempNDOY}{-31}%
                                    \stepcounter{NDOYmonthnumber}%                  %% AUGUST
                                    \ifthenelse{\value{tempNDOY}<32}{%
                                        \setcounter{NDOYquantieme}{\value{tempNDOY}}%
                                    }{%
                                        \addtocounter{tempNDOY}{-31}%
                                        \stepcounter{NDOYmonthnumber}%                  %% SEPTEMBER
                                        \ifthenelse{\value{tempNDOY}<31}{%
                                            \setcounter{NDOYquantieme}{\value{tempNDOY}}%
                                        }{%
                                            \addtocounter{tempNDOY}{-30}%
                                            \stepcounter{NDOYmonthnumber}%                  %% OCTOBER
                                            \ifthenelse{\value{tempNDOY}<32}{%
                                                \setcounter{NDOYquantieme}{\value{tempNDOY}}%
                                            }{%
                                                \addtocounter{tempNDOY}{-31}%
                                                \stepcounter{NDOYmonthnumber}%                  %% NOVEMBER
                                                \ifthenelse{\value{tempNDOY}<31}{%
                                                    \setcounter{NDOYquantieme}{\value{tempNDOY}}%
                                                }{%
                                                    \addtocounter{tempNDOY}{-30}%
                                                    \stepcounter{NDOYmonthnumber}%                  %% DECEMBER
                                                    \setcounter{NDOYquantieme}{\value{tempNDOY}}%
        }}}}}}}}}}}%
    }

    % Based on previously computed `NDOYmonthnumber` value, return month name
    \newcommand{\NDOYtomonth}{%
        \foreach \monthnumber/\monthname in {1/Januar, 2/Februar, 3/März, 4/April, 5/Mai, 6/Juni, 7/Juli, 8/August, 9/September, 10/Oktober, 11/November, 12/Dezember}{%
            \ifthenelse{\value{NDOYmonthnumber}=\monthnumber}{\monthname}{}%
        }
    }

    % 'Smartly' increase `NDOYnumber` value (i.e. reset to 1 after December, 31st)
    \newcommand{\stepNDOY}{%
        \ifthenelse{\value{NDOYnumber}=365}{%
            \setcounter{NDOYnumber}{1}%
            \stepcounter{ThisYear}
        }{%
            \stepcounter{NDOYnumber}%
        }%
    }

    % Defines the `tikzpicture` used to print a week (i.e. calendar page)
    \newcommand{\printweek}[1]{% argument = \value{NDOYnumber}, i.e. Monday's day-of-the-year number
        \begin{tikzpicture}[%
            inner sep=3 pt,
            dayname/.style={%
                node font=\footnotesize,
            },
            daynumber/.style={%
                anchor=north east,
                node font=\normalsize\bfseries, 
            },
            xscale = 3,
            yscale=-1.5,% CAUTION: axis direction reversed!
        ]
        \NDOYtomonthnumber%(see below)
        \node (year_number) at (0,1) [anchor = south east, minimum height = 2em] {\theThisYear};    %prints year number
        \node [base right = 1em of year_number, anchor=base west, node font=\large] {\NDOYtomonth}; %prints month name

        %% Monday
        \NDOYtomonthnumber                                                              % compute and store which month and quantieme is this day, based on `NDOYnumber` value
        \node (monday_number) at (0,1) [daynumber] {\theNDOYquantieme};                 % prints quantieme
        \node [base right = 1em of monday_number, anchor=base west] [dayname] {Montag}; % prints day name
        \stepNDOY                                                                       % 'smartly' increases `NDOYnumber` value

        %% Tuesday
        \NDOYtomonthnumber  
        \node (tuesday_number) at (0,2) [daynumber] {\theNDOYquantieme};
        \node [base right = 1em of tuesday_number, anchor=base west] [dayname] {Dienstag};
        \stepNDOY

        %% Wednesday
        \NDOYtomonthnumber
        \node (wednesday_number) at (0,3) [daynumber] {\theNDOYquantieme};
        \node [base right = 1em of wednesday_number, anchor=base west] [dayname] {Mittwoch};
        \stepNDOY

        %% Thursday
        \NDOYtomonthnumber
        \node (thursday_number) at (0,4) [daynumber] {\theNDOYquantieme};
        \node [base right = 1em of thursday_number, anchor=base west] [dayname] {Donnerstag};
        \stepNDOY

        %% Friday
        \NDOYtomonthnumber
        \node (friday_number) at (0,5) [daynumber] {\theNDOYquantieme};
        \node [base right = 1em of friday_number, anchor=base west] [dayname] {Freitag};
        \stepNDOY

        %% Saturday
        \NDOYtomonthnumber
        \node (saturday_number) at (0,6) [daynumber] {\theNDOYquantieme};
        \node [base right = 1em of saturday_number, anchor=base west] [dayname] {Samstag};
        \stepNDOY

        %% Sunday
        \NDOYtomonthnumber
        \node (sunday_number) at (1,6) [daynumber] {\theNDOYquantieme};
        \node [base right = 1em of sunday_number, anchor=base west] [dayname] {Sonntag};
        \stepNDOY

        %% Draw lines
        \foreach \i in {1, 1.2, ..., 7}{%
            \draw [gray, thin] (2,\i) -- (4,\i);
        }

        \path (-0.35,0.25) -- (4,0.25);
        \foreach \i in {1,...,7} {%
            \draw (-0.35,\i) -- (4,\i);
        }
        \draw (2,1) -- (2,7);

        \end{tikzpicture}%
    }

\begin{document}
    \foreach \n in {1,...,\value{NumberOfWeeksThisYear}}{%
        \printweek{\value{NDOYnumber}}
    }
\end{document}

我的代码比较臃肿,欢迎大家提出精简建议!

预览

在此处输入图片描述


第一个(初步)答案

这是目前一周的粗略 TikZ 结构。

请注意,由于yscale=-1,图片的原点位于左上角(因此,y坐标的增加意味着一周中某一天的“增加” - 在我看来,这更直观。)

\documentclass{standalone}

\usepackage{lmodern}
\usepackage{tikz}
    \usetikzlibrary{positioning}

\begin{document}
    \begin{tikzpicture}[%
        inner sep=3 pt,
        dayname/.style={%
            node font=\footnotesize, 
        },
        daynumber/.style={%
            anchor=north east,
            node font=\normalsize\bfseries, 
        },
        xscale = 4,
        yscale=-1,
    ]

    \node (saturday_number) at (0,6) [daynumber] {14};
    \node [base right = 1em of saturday_number, anchor=base west] [dayname] {Samstag};

        \node (sunday_number) at (1,6) [daynumber] {15};
        \node [base right = 1em of sunday_number, anchor=base west] [dayname] {Sonntag};

    \node (friday_number) at (0,5) [daynumber] {13};
    \node [base right = 1em of friday_number, anchor=base west] [dayname] {Freitag};

    \node (thursday_number) at (0,4) [daynumber] {12};
    \node [base right = 1em of thursday_number, anchor=base west] [dayname] {Donnerstag};

    \node (wednesday_number) at (0,3) [daynumber] {11};
    \node [base right = 1em of wednesday_number, anchor=base west] [dayname] {Mittwoch};

    \node (tuesday_number) at (0,2) [daynumber] {10};
    \node [base right = 1em of tuesday_number, anchor=base west] [dayname] {Dienstag};

    \node (monday_number) at (0,1) [daynumber] {9};
    \node [base right = 1em of monday_number, anchor=base west] [dayname] {Montag};

    \node (year_number) at (0,1) [anchor = south east, minimum height = 2em] {2017};
    \node [base right = 1em of year_number, anchor=base west, node font=\large] {Januar};

    \foreach \i in {0,1,...,6} {%
        \draw (-0.25,\i) -- (2,\i);
    }

    \node (SW-corner) at (0,7) {};
    \end{tikzpicture}
\end{document}

在此处输入图片描述

下一步:

  • 添加好友生日。

相关内容