带有数组的日历

带有数组的日历

修改后的 LaTeX 模板

% DIN-A4 doublesided year calendar
% Author: Robert Krause
% License : Creative Commons attribution license
% Submitted to TeXample.net on 13 July 2012
\documentclass[landscape,a4paper, 10pt]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage[T1]{fontenc}
\usepackage{tikz}           % Use the calendar.sty style

\usepackage{translator} % German Month and Day names
\usepackage{fancyhdr}       % header and footer
\usepackage{fix-cm}     % Large year in header

\usepackage[landscape, headheight = 2cm, margin=.5cm,
  top = 3.2cm, nofoot]{geometry}
\usetikzlibrary{calc}
\usetikzlibrary{calendar}
\renewcommand*\familydefault{\sfdefault}

% User defined
\def\year{2016}
\def\nextyear{2017}
% Names of Holidays are inserted by employing this macro
\def\termin#1#2{
  \node [anchor=north west, text width= 3.4cm] at
    ($(cal-#1.north west)+(3em, 0em)$) {\tiny{#2}};
}

%Header
\renewcommand{\headrulewidth}{0.0pt}
\setlength{\headheight}{3ex}
\chead{
  %\fontsize{60}{70}\selectfont\textbf{\year}
  \Large\textbf{Cleaning Plan}\hfill
}
%Footer
%\cfoot{\footnotesize\texttt{http://www.texample.net/}}
\pagenumbering{gobble}

% === Macro that returns a name if given a number from 0 to 29, "Error!" otherwise
\newcommand{\Person}[1]{%
\ifcase#1
Bryant Romans \or
Latricia Stoneman \or
Wilmer Lytton \or 
Tommie Lenahan \or 
Antonio Hoggard \or 
Edward Lanctot \or 
Chassidy Hyndman \or 
Marianela Wojciechowski \or 
Edna Kreitzer \or 
Harrison Cruze \or 
Marna Meloy \or 
Georgene Joly \or 
Ken Denley \or 
William Loeffler \or 
Young Spinelli \or 
Glendora Bruss \or 
Kraig Calloway \or 
Chantal Callejas \or 
Eleni Graziani \or 
Ilene Crumpler \or 
Ali Valliere \or 
Sonya Barlett \or 
Frederick Delacruz \or 
Kayce Foti \or 
Orval Kirchner \or 
Corrinne Cahoon \or 
Modesto Mulloy \or 
Alessandra Rodenberger \or 
Bernita Redman \or 
Iola Eudy \else
Error! \fi
}

\xdef\cleanerID{18}

\begin{document}
\pagestyle{fancy}
\begin{center}
\begin{tikzpicture}[every day/.style={anchor = north}]
\calendar[
  dates=\year-09-01 to \nextyear-02-28,
  name=cal,
  day yshift = 3em,
  day code=
  { %=== Define macro that holds cleaners name on cleaning days, empty otherwise
    \ifdate{Monday,Wednesday,Saturday}%
    {   \ifdate{between=\year-11-18 and \year-12-09, at least=\nextyear-01-03}
        {   \xdef\InsertName{\Person{\cleanerID}}
            \pgfmathtruncatemacro{\newCleanerID}{mod(\cleanerID+1,30)}
                \xdef\cleanerID{\newCleanerID}
            }
            {   \xdef\InsertName{}
            }
    }
    {   \xdef\InsertName{}
    } 
    \ifdate{equals=\year-11-21}
    {   \xdef\InsertName{Iola Eudy}
        \tikzset{every day/.style={fill=cyan!50!blue!50}}       
    }{}
    \ifdate{equals=\nextyear-01-06}
    {   \xdef\InsertName{Ilene Crumpler}
        \tikzset{every day/.style={fill=cyan!50!blue!50}}       
    }{}
    \node[name=\pgfcalendarsuggestedname,every day,shape=rectangle,
    minimum height= .53cm, text width = 4.4cm, draw = gray]{\tikzdaytext};
    %=== Insert the  cleaners name here
    \draw (-1.8cm, -.1ex) node[anchor = west]{\footnotesize%
      \pgfcalendarweekdayshortname{\pgfcalendarcurrentweekday} \InsertName
      };
  },
  execute before day scope=
  {
    \ifdate{day of month=1}
    {
      % Shift right
      \pgftransformxshift{4.8cm}
      % Print month name 
      \draw (0,0)node [shape=rectangle, minimum height= .53cm,
        text width = 4.4cm, fill = black, text= white, draw = black, text centered]
        {\textbf{\pgfcalendarmonthname{\pgfcalendarcurrentmonth} \pgfcalendarcurrentyear}
        };
    }{}
    \ifdate{workday}
    {
      % normal days are white
      \tikzset{every day/.style={fill=white}}
    }{}
    % Saturdays and half holidays (Christma's and New year's eve)
    \ifdate{Saturday}{\tikzset{every day/.style={fill=red!10}}}{}
    % Sundays and full holidays
    \ifdate{Sunday}{\tikzset{every day/.style={fill=red!20}}}{}
  },
 execute at begin day scope=
  {
    % each day is shifted down according to the day of month
    \pgftransformyshift{-.53*\pgfcalendarcurrentday cm}
  }
];
\end{tikzpicture}
% Repeat the whole thing for the second page
%\pagebreak

\begin{tikzpicture}[every day/.style={anchor = north}]
\calendar[dates=\nextyear-05-01 to \nextyear-10-31,
  name=cal,
  day yshift = 3em,
  day code=
  { %=== Define macro that holds cleaners name on cleaning days, empty otherwise
    \ifdate{Monday,Wednesday,Saturday}%
    {   \ifdate{at least=\nextyear-01-03}
        {   \xdef\InsertName{\Person{\cleanerID}}
            \pgfmathtruncatemacro{\newCleanerID}{mod(\cleanerID+1,30)}
                \xdef\cleanerID{\newCleanerID}
            }
            {   \xdef\InsertName{}
            }
    }
    {   \xdef\InsertName{}
    }   
    \node[name=\pgfcalendarsuggestedname,every day,shape=rectangle,
    minimum height= .53cm, text width = 4.4cm, draw = gray]{\tikzdaytext};
    %=== Insert the  cleaners name here
    \draw (-1.8cm, -.1ex) node[anchor = west]{\footnotesize%
      \pgfcalendarweekdayshortname{\pgfcalendarcurrentweekday} \InsertName
      };
  },
  execute before day scope=
  {
    \ifdate{day of month=1} {
    % Shift right
    \pgftransformxshift{4.8cm}
    % Print month name 
    \draw (0,0)node [shape=rectangle, minimum height= .53cm, 
      text width = 4.4cm, fill = black, text= white, draw = black, text centered]
    {
      \textbf{\pgfcalendarmonthname{\pgfcalendarcurrentmonth} \pgfcalendarcurrentyear}
    };
  }{}
  \ifdate{workday}
  {
    \tikzset{every day/.style={fill=white}}
  }{}
  % Saturdays and half holidays (Christma's and New year's eve)
  \ifdate{Saturday}{\tikzset{every day/.style={fill=red!10}}}{}
  % Sundays and full holidays
  \ifdate{Sunday}{\tikzset{every day/.style={fill=red!20}}}{}
  },
  execute at begin day scope=
  {
   % Each day is shifted down according to the day of month
    \pgftransformyshift{-.53*\pgfcalendarcurrentday cm}
  }
];
\end{tikzpicture}
\end{center}
\end{document}

已更改

我已更改以下几行:

% User defined
\def\year{2015}
\def\nextyear{2016}

dates=\year-11-01 to \nextyear-04-30,

问题

我是飞行助理。以下我不知道如何更改:

  • 我的团队有 15 个人。总是周一和周四。飞行助理(13 号)根本不需要清洁厕所 --- 所以我需要像 [... 11、12、14、15、1 ...] 这样的计数。厕所清洁从 9 月 5 日开始。

  • 假期:12 月 21 日至 1 月 23 日以及 5 月 26 日至 9 月 1 日。日历应该从那里开始。

解决问题

更改号码

\pgfmathtruncatemacro{\newCleanerID}{mod(\cleanerID+1,30)}

我会将其更改为以下内容:

\pgfmathtruncatemacro{\newCleanerID}{mod(\cleanerID+1,15)}

我希望你能帮助我:-)

注意!是否可以在顶部定义日历/清洁的开始/停止?是否可以在顶部定义假期?这样就不用深入研究代码了?

答案1

我认为在顶部定义事物是错误的。这意味着文档主体包含静态配置的多个副本,而序言包含一组自定义设置,主体在第一个日历之后为每个日历包含一组附加设置。

重复静态代码使得定制和维护变得更加困难。

我建议将静态代码放入序言中并定义一个简单的命令来生成每个日历。

\rgcalendar[<tikz keys to customise>]

接受单个可选参数并生成日历。提供附加键以方便自定义。

  • rg start date=<YYYY>-<MM>-<DD>开始日期
  • rg end date=<YYYY>-<MM>-<DD>结束日期
  • rg cleaning dates=<specification using the calendar syntax>清洁期间
  • rg cal colour=<colour>用于周末使用的突出显示颜色,不与白色混合
  • rg cal draw=<colour>用于绘制日期周围框的颜色
  • rg cal fill=<colour>用于填充非周末的颜色

我还对代码进行了简化,以便编译时间不会太长。我删除或重命名了覆盖现有宏的宏,并尽可能使用 LaTeX 宏进行宏定义。

我使用计数器而不是宏来跟踪清洁工的数量,并使用另一个计数器为日历赋予唯一的名称。

默认值设置为生成问题中描述的第一个日历,因此\rgcalendar无需可选参数即可运行。后续日历显然需要进行适当调整。

这一切的结果是

\rgcalendar
\rgcalendar[%
  rg start date=2017-03-01,
  rg end date=2017-08-31,
  rg cleaning dates={between=\rgcalyear-01-23 and \rgcalyear-05-26},
  rg cal colour=blue,
]
\rgcalendar[%
  rg start date=2017-09-01,
  rg end date=2018-02-28,
  rg cleaning dates={between=\rgcalyear-09-01 and \rgcalyear-12-21, at least=\rgnextcalyear-01-23},
  rg cal colour=violet,
]

生产

3 个日历

% DIN-A4 doublesided year calendar
% Author: Robert Krause
% License : Creative Commons attribution license
% Submitted to TeXample.net on 13 July 2012

% Modifications by cfr 4 September 2016

\documentclass[landscape, a4paper, american, 10pt]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage[T1]{fontenc}
\usepackage{tikz}           % Use the calendar.sty style
\usepackage{fancyhdr}       % header and footer
\usepackage[sf={lining,proportional},tt={lining,monowidth},rm={lining,oldstyle}]{cfr-lm}
\usepackage[landscape, headheight = 2cm, margin=.5cm, top = 3.2cm, nofoot, headheight=3ex]{geometry}% don't set layout dimensions manually if using geometry - it won't know about them when it calculates everything!
\usetikzlibrary{calc,calendar}
\renewcommand*\familydefault{\sfdefault}
%Header
\renewcommand{\headrulewidth}{0pt}
\fancyhf{}
\lhead{%
  \Large\textbf{Cleaning Plan}%
}
% === Macro that returns a name if given a number from 0 to 15, "Error!" otherwise
\newcommand*{\Person}[1]{%
  \ifcase#1
  person 1 \or
  person 2 \or
  person 3 \or
  person 4 \or
  person 5 \or
  person 6 \or
  person 7 \or
  person 8 \or
  person 9 \or
  person 10 \or
  person 11 \or
  person 12 \or
  person 13 \or
  person 14 \or
  person 15 \else
  Error! \fi
}
\newcounter{cleanerID}
\setcounter{cleanerID}{0}
\newcounter{rgcal}
\setcounter{rgcal}{0}
\newcommand*\InsertName{}
\pagestyle{fancy}
\tikzset{%
  rg cal/.code={%
    \stepcounter{rgcal}%
    \tikzset{%
      every day/.style={anchor=center, minimum height=.53cm, text width=4.4cm, fill=rgcalfill, draw=rgcaldraw},
      every month/.style={minimum height=.53cm, text width=4.4cm, fill=black, text=white, draw=black, text centered, font=\bfseries},
      name=rgcal\thergcal,
      execute before day scope={%
        \ifdate{day of month=1}
        {% Shift right
          \pgftransformxshift{4.8cm}%
          % Print month name
          \node [every month] {\pgfcalendarmonthname{\pgfcalendarcurrentmonth} \pgfcalendarcurrentyear};
        }{}%
      },
      execute at begin day scope=
      {% each day is shifted down according to the day of month
        \pgftransformyshift{-.53*\pgfcalendarcurrentday cm}%
        \ifdate{Sunday}{%
          \tikzset{rg cal fill=rgcalcol!30}%
        }{%
          \ifdate{Saturday}{%
            \tikzset{rg cal fill=rgcalcol!20}%
          }{}%
        }%
      },
      dates=\rgstartdate{} to \rgenddate,
      #1,
    }%
  },
  rg cal fill/.code={%
    \colorlet{rgcalfill}{#1}%
  },
  rg cal draw/.code={%
    \colorlet{rgcaldraw}{#1}%
  },
  rg cal colour/.code={%
    \colorlet{rgcalcol}{#1}%
  },
  rg cleaning dates/.style={%
    day code={%=== Define macro that holds cleaners name on cleaning days, empty otherwise
      \ifdate{Monday,Thursday}%
      {%
        \ifdate{#1}%between=\calyear-09-05 and \calyear-12-21, at least=\calnextyear-01-23}
        {%
          \ifnum\thecleanerID=12\stepcounter{cleanerID}\fi
          \edef\InsertName{\Person{\thecleanerID}}%
          \stepcounter{cleanerID}%
          \ifnum\thecleanerID=15\setcounter{cleanerID}{0}\fi
        }{}%
      }{}%
      \path node [name=\pgfcalendarsuggestedname, every day] {\tikzdaytext};
      %=== Insert the  cleaners name here
      \node at ([xshift=6mm]\pgfcalendarsuggestedname.base west) [anchor=base west, font=\footnotesize]{\pgfcalendarweekdayshortname{\pgfcalendarcurrentweekday} \InsertName};
    },
  },
  rg start date/.store in=\rgstartdate,
  rg end date/.store in=\rgenddate,
  rg cal year/.store in=\rgcalyear,
  rg next cal year/.store in=\rgnextcalyear,
  rg year/.style args={#1-#2-#3}{%
    /tikz/rg cal year=#1,
  },
  rg next year/.style args={#1-#2-#3}{%
    /tikz/rg next cal year=#1,
  },
  rg start date/.forward to=/tikz/rg year,
  rg end date/.forward to=/tikz/rg next year,
  rg cal draw=gray,
  rg cal colour=red,
  rg cal fill=white,
  rg cleaning dates={between=\rgcalyear-09-05 and \rgcalyear-12-21, at least=\rgnextcalyear-01-23},
  rg start date=2016-09-01,
  rg end date=2017-02-28,
}
\newcommand*\rgcalendar[1][]{%
  \clearpage
  \tikzset{#1}%
  \tikz{\calendar [rg cal];}%
  \clearpage
}

\begin{document}
\centering
\rgcalendar
\rgcalendar[%
  rg start date=2017-03-01,
  rg end date=2017-08-31,
  rg cleaning dates={between=\rgcalyear-01-23 and \rgcalyear-05-26},
  rg cal colour=blue,
]
\rgcalendar[%
  rg start date=2017-09-01,
  rg end date=2018-02-28,
  rg cleaning dates={between=\rgcalyear-09-01 and \rgcalyear-12-21, at least=\rgnextcalyear-01-23},
  rg cal colour=violet,
]
\end{document}

相关内容