diff options
-rw-r--r-- | Master/texmf-dist/doc/latex/typed-checklist/README.md | 19 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/typed-checklist/typed-checklist.pdf | bin | 401991 -> 356320 bytes | |||
-rw-r--r-- | Master/texmf-dist/source/latex/typed-checklist/typed-checklist.dtx | 1843 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/typed-checklist/typed-checklist.ins | 4 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/typed-checklist/typed-checklist.sty | 415 |
5 files changed, 1770 insertions, 511 deletions
diff --git a/Master/texmf-dist/doc/latex/typed-checklist/README.md b/Master/texmf-dist/doc/latex/typed-checklist/README.md index 326adb8cb84..bea5d768f3b 100644 --- a/Master/texmf-dist/doc/latex/typed-checklist/README.md +++ b/Master/texmf-dist/doc/latex/typed-checklist/README.md @@ -1,7 +1,7 @@ The typed-checklist package =========================== -Copyright (C) 2013-2018 Richard Grewe +Copyright (C) 2013-2019 Richard Grewe Released under the [LaTeX Project Public License](http://www.latex-project.org/lppl/) version 1.2 or later @@ -53,25 +53,12 @@ To build the documentation of the `typed-checklist` package, you additionally need the following classes and packages (including their dependencies): * ltxdoc -* idxlayout -* etoolbox -* xcolor +* rgltxdoc * soul * csquotes -* enumitem -* booktabs -* showexpl -* pbox * skull -* hypdoc -* xkeyval -* etoolbox -* xcolor * asciilist -* bbding -* marginnote -* longtable -* tabu +* keyvaltable as well as * pdflatex diff --git a/Master/texmf-dist/doc/latex/typed-checklist/typed-checklist.pdf b/Master/texmf-dist/doc/latex/typed-checklist/typed-checklist.pdf Binary files differindex 6565215e3c3..a208b62661f 100644 --- a/Master/texmf-dist/doc/latex/typed-checklist/typed-checklist.pdf +++ b/Master/texmf-dist/doc/latex/typed-checklist/typed-checklist.pdf diff --git a/Master/texmf-dist/source/latex/typed-checklist/typed-checklist.dtx b/Master/texmf-dist/source/latex/typed-checklist/typed-checklist.dtx index 28c61c6c751..44fccc37dcc 100644 --- a/Master/texmf-dist/source/latex/typed-checklist/typed-checklist.dtx +++ b/Master/texmf-dist/source/latex/typed-checklist/typed-checklist.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2013-2018 by Richard Grewe <r-g+tex@posteo.net> +% Copyright (C) 2013-2019 by Richard Grewe <r-g+tex@posteo.net> % ------------------------------------------------------- % % This file may be distributed and/or modified under the @@ -22,56 +22,27 @@ %<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01] %<package>\ProvidesPackage{typed-checklist} %<*package> - [2018/10/31 v1.5b A package for layouting checklists] + [2019/01/11 v2.0 A package for layouting checklists] %</package> % %<*driver> \documentclass{ltxdoc} -\usepackage[columns=2]{idxlayout} -\usepackage{etoolbox} -\usepackage{xcolor} +\usepackage{rgltxdoc} +% finetuning of rgltxdoc config +\lstset{overhang=0cm}% this is to still have room for deadlines in margins +% additional stuff \usepackage{soul} \usepackage{csquotes} -\usepackage{enumitem} +\usepackage{datetime2} \makeatletter \newlist{Dict}{itemize}{1} \setlist[Dict]{nosep,label={--},leftmargin=*,before*={\@minipagetrue}} \makeatother -\usepackage{longtable,tabu,booktabs} -\setlength{\tabulinesep}{0.75ex} -\newcolumntype{C}{>{\normalfont\ttfamily}l<{}}% codelike \setlist[description]{style=nextline} -\usepackage{showexpl} -\lstset{gobble=2,frame=trbl,backgroundcolor=\color{black!5!white}} -\lstset{explpreset={numbers=none,columns=flexible,basicstyle=\footnotesize\ttfamily}} -\lstset{preset={\small\sffamily},overhang=0cm,pos=r} -\usepackage{pbox} -\newcommand\NiceDescribeStuff[2]{% #1=margin text, #2=body text - \medskip\par\noindent\leavevmode% - \marginpar{\hfill\pbox[t]{\marginparwidth}{\ttfamily #1}% - \hspace*{-\marginparsep}}% - \ifstrempty{#2}{}{#2\smallskip\\}} -\newcommand\NiceDescribeEnv[2]{% #1=envname, #2=parameters - \NiceDescribeStuff{% - \textcolor{gray}{\cs{begin}}\string{#1\string}\\ - \textcolor{gray}{\cs{end}}\string{#1\string}}{#2}} -\newcommand\NiceDescribeMacro[2]{% #1=macro, #2=parameters - \NiceDescribeStuff{\hbox to 0pt{\hss\string#1}}{#2}} \usepackage{skull} \newcommand\Good{\dotfill\enspace\Checkmark\smallskip\break} \newcommand\Evil{\dotfill\enspace$\skull$\smallskip\break} \usepackage[withAsciilist=true]{typed-checklist} -\usepackage{hypdoc} -% The following macro simulates labels and references, assuming -% labels are only referenced after they have been defined. This -% is used in LTXexample environments, in which the normal label -% and ref mechanism is otherwise disabled. -\newcommand\FakeRefs{% - \def\ref##1{\csuse{fakelabel@##1}}% - \def\label##1{\global\csletcs{fakelabel@##1}{@currentlabel}}% - \let\marginpar=\origmarginpar -} -\let\origmarginpar=\marginpar \EnableCrossrefs \CodelineIndex \RecordChanges @@ -111,15 +82,15 @@ % \changes{v0.6}{2014/05/19}{Indication of closed checklist entries} % \changes{v1.0}{2014/08/22}{First documented version} % \changes{v1.1}{2014/08/23}{Added definable layouts} -% \changes{v1.3}{2015/04/01}{Support for combining checklists with \textsf{asciilist}} +% \changes{v1.3}{2015/04/01}{Support for combining checklists with \pkgname{asciilist}} % % \GetFileInfo{typed-checklist.dtx} % % \DoNotIndex{\newcommand,\newenvironment,\def,\gdef,\edef} % % -% \title{The \textsf{typed-checklist} package\thanks{This document -% corresponds to \textsf{typed-checklist}~\fileversion, dated \filedate. +% \title{The \pkgname{typed-checklist} package\thanks{This document +% corresponds to \pkgname{typed-checklist}~\fileversion, dated \filedate. % The package is available online at % \url{http://www.ctan.org/pkg/typed-checklist} and % \url{https://github.com/Ri-Ga/typed-checklist}.}} @@ -128,7 +99,7 @@ % \maketitle % % \begin{abstract} -% The main goal of the \textsf{typed-checklist} package is to provide +% The main goal of the \pkgname{typed-checklist} package is to provide % means for typesetting checklists in a way that stipulates users to % explicitly distinguish checklists for goals, for tasks, for % artifacts, and for milestones -- i.e., the \emph{type} of checklist @@ -162,7 +133,7 @@ % then only contain entries of this type. % % While the package allows one to define custom checklist types (see -% Section~\ref{sec:customizing}), it comes with four basic types: +% \cref{sec:customizing}), it comes with four basic types: % |Artifact|, |Goal|, |Milestone|, and |Task|. In this documentation, % the terms \enquote{artifact}, \enquote{goal}, \enquote{milestone}, and % \enquote{task} will be used along the lines of the following @@ -176,7 +147,7 @@ % \begin{Dict} % \item\textquote[\href{http://www.businessdictionary.com/definition/goal.html}{BusinessDictionary.com}]{An observable and measurable \hl{end result} having one or more objectives to be achieved within a more or less fixed timeframe.} % \item\textquote[\href{http://www.merriam-webster.com/dictionary/goal}{Merriam-Webster}]{the \hl{end} toward which effort is directed} -% \item\textquote[\href{http://www.oxforddictionaries.com/de/definition/englisch_usa/goal?q=Goal}{Oxford Dictionaries}]{The object of a person’s ambition or effort; an aim or desired \hl{result}} +% \item\textquote[\href{http://www.oxforddictionaries.com/de/definition/englisch_usa/goal?q=Goal}{Oxford Dictionaries}]{The object of a person's ambition or effort; an aim or desired \hl{result}} % \item\textquote[\href{https://en.wiktionary.org/wiki/goal}{Wiktionary}]{A \hl{result} that one is attempting to achieve.} % \end{Dict} % \item[milestone:] @@ -186,7 +157,7 @@ % \item[task:] % \begin{Dict} % \item\textquote[\href{http://www.merriam-webster.com/dictionary/task}{Merriam-Webster}]{a usually assigned \hl{piece of work} often to be finished within a certain time} -% \item\textquote[\href{https://en.wiktionary.org/wiki/task}{Wiktionary}]{A \hl{piece of work} done as part of one’s duties.} +% \item\textquote[\href{https://en.wiktionary.org/wiki/task}{Wiktionary}]{A \hl{piece of work} done as part of one's duties.} % \end{Dict} % \end{description} % We could connect the four terms as follows. @@ -197,12 +168,12 @@ % available at some point in time. A milestone is a group of goals whose % achievement is of importance for something bigger. % These connections suggest that nesting different types of checklists -% is reasonable -- and it is supported by the \textsf{typed-checklist} +% is reasonable -- and it is supported by the \pkgname{typed-checklist} % package. % % \section{Recommendations for Structuring Checklists} % -% The \textsf{typed-checklist} package allows checklists of different +% The \pkgname{typed-checklist} package allows checklists of different % types as well as of identical types to be nested. That is, within a % checklist, another checklist can be placed. The following list % discusses some combinations of nested checklist types and provides @@ -273,27 +244,89 @@ % task) that is decorated depending on the status (e.g., with a % check mark). The entry's description is shown next to the symbol. % +% \subsection{Checklists} +% % \NiceDescribeEnv{CheckList}{\oarg{options}\marg{type}} % Checklists are created via the |CheckList| environment. % The \meta{type} parameter determines the type of all checklist entries -% in the environment. The \textsf{typed-checklist} package comes with +% in the environment. The \pkgname{typed-checklist} package comes with % four predefined types: |Goal|, |Task|, |Artifact|, and |Milestone|. % Each of the types comes with a macro of the same name as the type. % With this macro, the entries of the checklist can be created. % % The \meta{options} can be a comma-separated list of -% \meta{key}|=|\meta{value} pairs. The following keys can be set: -% \begin{itemize} -% \item With the |layout| key, the layout of the checklist can be -% chosen. Supported layouts are |list| (a list-based layout with -% each entry being a list item), |table| (a table-based layout with -% each entry being a table row), and |hidden| (a layout that does -% not display the entries). -% \end{itemize} +% \meta{key}|=|\meta{value} pairs. \Vref{tab:CheckListOptions} shows the +% keys and possible values that can be set. +% \begin{table} +% \begin{KeyValTable}{KeyDesc} +% \Row{key =layout, +% desc ={This selects the default checklist layout. +% Allowed values are all known layout names, including the +% pre-defined `|list|', `|table|', `|hidden|'. +% In |list| layout, each entry is a list item. +% In |table| layout, each entry is a row and the checklist +% is a table (see \cref{sec:tablepkg} for how to change +% which table environment is used). +% The |hidden| layout does not display the +% checklist and its entries.}, +% default=list, +% } +% \Row{key =input-dates, +% desc ={This option specifies the format of deadlines +% that checklist entries expect. Allowed values are +% `|d.m.y|', `|m/d/y|', and `|y-m-d|' -- with the +% intuitive meaning.}, +% default=d.m.y, +% } +% \Row{key =output-dates, +% desc ={This option specifies the format in which +% deadline dates are displayed. Allowed values are: +% \begin{description}[style=standard,font=\normalfont,nosep] +% \item[`|d.m.y|', `|m/d/y|', `|y-m-d|':] +% These format dates in the indicated order of day, month, and +% year. +% \item[`|d.m.yy|', `|m/d/yy|', `|yy-m-d|':] +% These are analogous to their counterparts with a single `y', +% but use a two-digit display of the year (i.e., the century is +% stripped away). +% \item[`|d.m.|', `|m/d|', `|m-d|':] +% These format dates in the indicated order, showing only month +% and day of the month. +% \item[`|same|':] +% With |same|, deadlines are output in the same format +% in which they are specified. +% \item[`|datetime|':] +% With |datetime|, the \pkgname{datetime2} package is +% used for displaying deadlines. The package must be +% loaded manually. +% \end{description}}, +% default=same, +% } +% \Row{key =strict-dates, +% desc ={This option specifies whether deadlines must +% adhere to the input date format (as specified via +% the |input-dates| key) or can deviate. +% Allowed values are `|true|' and `|false|'.}, +% default=false, +% } +% \end{KeyValTable} +% \caption{Options for \env{CheckList} environments (and \cs{CheckListSet})} +% \label{tab:CheckListOptions} +% \end{table} +% +% Defaults for checklist options can also be specified globally, +% either through package options or through the |\CheckListSet| +% macro. +% \NiceDescribeMacro{\CheckListSet}{\marg{options-list}} +% This macro takes a comma-separated \meta{options} list +% and sets these options for all subsequent checklists. +% % A checklist can be viewed as a list of entries (even if the layout is % actually tabular). The macros for creating the entries are described % next. % +% \subsection{Checklist Entries} +% % \NiceDescribeMacro{\Goal}{\oarg{options}\marg{status}\marg{description}} % Inside a checklist of type |Goal|, the |\Goal| macro specifies a goal. % Every goal comes at least with a \meta{description} and a @@ -301,50 +334,52 @@ % that is displayable in the given checklist |layout|. However, for the % purpose of a meaningful checklist, the \meta{description} should be a % clear description of a goal in a full sentence\footnote{Incomplete -% sentences typically tend to be less clear.}. The \meta{status} +% sentences tend to be less clear.}. The \meta{status} % parameter selects the most recent known status of the goal. This % parameter can assume any of the following values\footnote{See -% Section~\ref{sec:AddingStates} to find out how custom states can be +% \cref{sec:AddingStates} to find out how custom states can be % defined}: -% \begin{longtabu}{@{}CX@{}} -% achieved & -% This value specifies that the goal has been achieved. Depending on -% how the \meta{description} was formulated, this might mean that in -% the respective situation the \meta{description} is a true -% statement.\\ -% dropped & -% This value specifies that the goal was a goal once but is no longer -% a goal that shall be pursued. This value allows one to preserve -% historical information about a checklist.\\ -% unclear & -% This value specifies that the goal somehow exists but is not yet -% clear enough to those who pursue the goal (or: who typeset the -% checklist) for actually pursuing the goal.\\ -% open & -% This value specifies the negation of all aforementioned values. That -% is, the goal is clear but neither achieved yet nor dropped.\\ -% \end{longtabu} +% \begin{KeyValTable}{ValDesc} +% \Row{val=achieved, +% desc={This value specifies that the goal has been achieved. +% Depending on how the \meta{description} was formulated, this might +% mean that in the respective situation the \meta{description} is a +% true statement.}} +% \Row{val=dropped, +% desc={This value specifies that the goal was a goal once but is no +% longer a goal that shall be pursued. This value allows one to +% preserve historical information about a checklist.}} +% \Row{val=unclear, +% desc={This value specifies that the goal somehow exists but is not yet +% clear enough to those who pursue the goal (or: who typeset the +% checklist) for actually pursuing the goal.}} +% \Row{val=open, +% desc={This value specifies the negation of all aforementioned values. That +% is, the goal is clear but neither achieved yet nor dropped.}} +% \end{KeyValTable} % The \meta{options}\label{EntryOptions} allow one to specify further % details about the goal. The \meta{options} must be a possibly empty, % comma-separated list of \meta{key}|=|\meta{value} pairs. The % \meta{key} must be one of the following values\footnote{See -% Section~\ref{sec:AddingEntryKeys} to find out how custom \meta{key}s +% \cref{sec:AddingEntryKeys} to find out how custom \meta{key}s % can be defined.}: -% \begin{longtabu}{@{}CX@{}} -% who & -% This option declares who is responsible for making sure the -% checklist entry is addressed. Remember to put the value in curly -% braces if it contains commas.\\ -% deadline & -% This option declares a deadline for the checklist entry, i.e., a date -% until which the entry must be addressed at latest. The deadline must -% be of the format ``\meta{day}.\meta{month}.\meta{year}''.\\ -% label & -% This option declares a label name for the checklist entry. This is -% analogous to the \cs{label} macro of \LaTeX. The entry's label is -% displayed next to the entry. A reference to a labeled checklist -% entry can be made using the \cs{ref} macro of \LaTeX{}.\\ -% \end{longtabu} +% \begin{KeyValTable}{ValDesc} +% \Row{val=who, +% desc={This option declares who is responsible for making sure the +% checklist entry is addressed. Remember to put the value in curly +% braces if it contains commas.}} +% \Row{val=deadline, +% desc={This option declares a deadline for the checklist entry, i.e., +% a date until which the entry must be addressed at latest. The format +% for specifying deadlines is determined by the checklist options +% |input-dates| and |strict-dates|.}} +% \Row{val=label, +% desc={This option declares a label name for the checklist entry. +% This is analogous to the \cs{label} macro of \LaTeX. The entry's +% label is displayed next to the entry. A reference to a labeled +% checklist entry can be made using the \cmd{\ref} macro of +% \LaTeX{}.}} +% \end{KeyValTable} % % \NiceDescribeMacro{\Task}{\oarg{options}\marg{status}\marg{description}} % Inside a checklist of type |Task|, the |\Task| macro specifies a task. @@ -353,33 +388,32 @@ % that is displayable in the given checklist |layout|. However, for the % purpose of a meaningful checklist, the \meta{description} should be a % clear description of a task in a full sentence, possibly in imperative -% form\footnote{For a \meta{description} in imperative form, the -% \texttt{who} option can be used to specify who is addressed by the -% \meta{description}.}. The \meta{status} parameter selects the most -% recent known status of the task. This parameter can assume any of the -% following values: -% \begin{longtabu}{@{}CX@{}} -% open & -% This value specifies that the task is still planned but has not -% yet been started.\\ -% dropped & -% This value specifies that the task was originally planned but is -% no longer part of the plan.\\ -% unclear & -% This value specifies that the task itself or its current status is -% unclear.\\ -% started & -% This value specifies that someone has started to perform the task, -% but has not finished yet.\\ -% done & -% This value specifies that someone has accomplished the task. -% Depending on the clarity and level of detail of the -% \meta{description}, whether accomplishing the task yielded a -% meaningful outcome might be more or less subjective to the person -% who accomplished the task.\\ -% \end{longtabu} +% form. % The \meta{options} parameter can be set as documented for the % |\Goal| macro on page~\pageref{EntryOptions}. +% The \meta{status} parameter selects the most +% recent known status of the task. This parameter can assume any of the +% following values: +% \begin{KeyValTable}{ValDesc} +% \Row{val=open, +% desc={This value specifies that the task is still planned but has +% not yet been started.}} +% \Row{val=dropped, +% desc={This value specifies that the task was originally planned but +% is no longer part of the plan.}} +% \Row{val=unclear, +% desc={This value specifies that the task itself or its current +% status is unclear.}} +% \Row{val=started, +% desc={This value specifies that someone has started to perform the +% task, but has not finished yet.}} +% \Row{val=done, +% desc={This value specifies that someone has accomplished the task. +% Depending on the clarity and level of detail of the +% \meta{description}, whether accomplishing the task yielded a +% meaningful outcome might be more or less subjective to the person +% who accomplished the task.}} +% \end{KeyValTable} % % \NiceDescribeMacro{\Artifact}{\oarg{options}\marg{status}\marg{description}} % Inside a checklist of type |Artifact|, the |\Artifact| macro specifies @@ -391,22 +425,22 @@ % clear identification of the artifact and its required attributes. % The \meta{status} parameter selects the most recent known status of % the artifact. This parameter can assume any of the following values: -% \begin{longtabu}{@{}CX@{}} -% missing & -% This value specifies that the artifact is missing yet.\\ -% dropped & -% This value specifies that the artifact was originally planned but -% is no longer part of the plan.\\ -% unclear & -% This value specifies that the artifact itself or its current -% status is unclear.\\ -% incomplete & -% This value specifies that some non-negligible parts of the -% artifact exist but the artifact does not yet exist in its final -% form\\ -% available & -% This value specifies that the artifact exists and available.\\ -% \end{longtabu} +% \begin{KeyValTable}{ValDesc} +% \Row{val=missing, +% desc={This value specifies that the artifact is missing yet.}} +% \Row{val=dropped, +% desc={This value specifies that the artifact was originally planned +% but is no longer part of the plan.}} +% \Row{val=unclear, +% desc={This value specifies that the artifact itself or its current +% status is unclear.}} +% \Row{val=incomplete, +% desc={This value specifies that some non-negligible parts of the +% artifact exist but the artifact does not yet exist in its final +% form.}} +% \Row{val=available, +% desc={This value specifies that the artifact exists and available.}} +% \end{KeyValTable} % % \NiceDescribeMacro{\Milestone}{\oarg{options}\marg{status}\marg{description}} % Inside a checklist of type |Milestone|, the |\Milestone| macro @@ -419,42 +453,53 @@ % fulfilled. % The \meta{status} parameter selects the most recent known status of % the milestone. This parameter can assume any of the following values: -% \begin{longtabu}{@{}CX@{}} -% open & -% This value specifies that the milestone has not yet been achieved.\\ -% achieved & -% This value specifies that the milestone has been achieved.\\ -% \end{longtabu} -% -% \subsection{Example}\label{sec:NestOptExample} -% The following example shows the use of nested checklists and the use -% of the options |layout|, |deadline|, |label|, and |who|. Note that -% deadlines are displayed in the margin of the document, which in this -% documentation is outside the example box in this documentation. -% \begin{LTXexample}[pos=t,preset=\FakeRefs] +% \begin{KeyValTable}{ValDesc} +% \Row{val=open, +% desc={This value specifies that the milestone has not yet been achieved.}} +% \Row{val=achieved, +% desc={This value specifies that the milestone has been achieved.}} +% \end{KeyValTable} +% +% \subsection{Comprehensive Example}\label{sec:NestOptExample} +% The example in \vref{lst:Comprehensive} shows the use of nested +% checklists and the use of various checklist and entry options. +% \begin{LTXexample}[float,caption={Comprehensive checklist example}, +% label=lst:Comprehensive,pos=t] +% \DTMsetregional% remember \usepackage{datetime2} +% \CheckListSet{strict-dates,input-dates=d.m.y,output-dates=same} % \begin{CheckList}{Goal} -% \Goal[deadline=31.12.999]{achieved}{No Y1K problems} -% \Goal[who=John,deadline=31.12.1999]{open}{No Y2K problems} -% \begin{CheckList}[layout=table]{Task} +% \Goal[deadline=31.12.999]{achieved}{Y1K problems are resolved.} +% \Goal[who=John,deadline=31.12.1999]{open}{Y2K problems are resolved.} +% \begin{CheckList}[layout=table,output-dates=datetime]{Task} % \Task[who=John,label=Fix1]{started}{Repair all programs} % \Task[who=Mankind,deadline=31.12.1999] % {open}{Just turn off all computers, if \ref{Fix1} fails} % \end{CheckList} -% \Goal[deadline=31.12.9999]{unclear}{No Y10K problems} +% \Goal[deadline=31.12.65535]{unclear}{Y65K problems are resolved.} +% \begin{CheckList}[strict-dates=false,output-dates=m/d/y]{Task} +% \Task[deadline=$\approx 2500AD$,label=TM] +% {open}{Build Y65K-proof time machine.} +% \Task[deadline=31.12.65535] +% {open}{Use time machine from \ref{TM} if problem persists.} +% \end{CheckList} % \end{CheckList} % \end{LTXexample} +% The example deliberately mixes different date formats for the sake +% of demonstration, but this should normally be avoided as it reduces +% legibility. % % % \section{Customized Checklists}\label{sec:customizing} % -% The \textsf{typed-checklist} package comes with a set of layouts, +% The \pkgname{typed-checklist} package comes with a set of layouts, % checklist types, checklist entry states, and checklist entry % options. These together shall provide everything needed for % typesetting even checklists with complex structures. When the % default is not enough, you can use the macros described in this % section for creating your own layouts, types, states, and options. % -% \subsection{Defining Checklist Types}\label{sec:AddingTypes} +% \subsection{Defining Checklist Types and Entry States} +% \label{sec:AddingTypes}\label{sec:AddingStates} % % \NiceDescribeMacro{\CheckListAddType}{\marg{type}\marg{symbol}} % Using this macro, you can add a new checklist type. The name of the @@ -462,13 +507,10 @@ % environment, is specified by \meta{type}. % The basic symbol of entries belonging to this checklist type will be % \meta{symbol} (e.g., an empty box or circle). All status-symbols (see -% Section~\ref{sec:AddingStates}) are drawn on top of \meta{symbol}. -% -% Note that the \textsf{typed-checklist} package uses this macro also +% \cref{sec:AddingStates}) are drawn on top of \meta{symbol}. +% Note that the \pkgname{typed-checklist} package uses this macro also % for creating each of the four default checklist types. % -% \subsection{Defining Checklist Entry States}\label{sec:AddingStates} -% % \NiceDescribeMacro{\CheckListAddStatus}{\marg{types}\marg{status}\marg{isclosed}\marg{symbol}} % Using this macro, you can add a new checklist entry status for % selected checklist types. The name of the status to define is @@ -483,24 +525,58 @@ % deadline of an entry with this status is passed. A value of |false| % for \meta{isclosed} indicates that the \meta{status} corresponds to % the entry not yet being closed. -% -% Note that the \textsf{typed-checklist} package uses this macro also +% Note that the \pkgname{typed-checklist} package uses this macro also % for creating the provided states of the four default checklist types. % +% \paragraph{Example} +% The following example shows how to define a `bug' type. +% +% \begin{LTXexample}[pos=t,morepreset={\setlist{nosep}}] +% \CheckListAddType{Bug}{\textcolor{lightgray}{\FourStar}} +% \CheckListAddStatus{Bug}{new}{false}{\textcolor{red}{\FourStar}} +% \CheckListAddStatus{Bug}{assigned}{false}{\textcolor{yellow!75!red}{\FourStar}} +% \CheckListAddStatus{Bug}{resolved}{true}{\textcolor{green}{\FourStar}} +% \CheckListAddStatus{Bug}{closed}{true}{\Checkmark} +% +% \begin{CheckList}{Bug} +% \Bug{new}{program crashes when started after 31.12.65535} +% \Bug[who=C++ Team]{assigned}{progress bar flawed when duration above 136.2 years} +% \Bug[who=Test Team]{resolved}{help screen crashes when F1 is pressed} +% \Bug{closed}{fancy splash screen missing} +% \end{CheckList} +% \end{LTXexample} +% % \subsection{Defining Checklist Layouts}\label{sec:AddingEntryKeys} +% \lstset{morekeywords={CheckListDeclareLayout,CheckListDefineFieldFormat,CheckListExtendLayout}} % \NiceDescribeMacro{\CheckListDeclareLayout}{\marg{name}\marg{fields}\marg{begin}\marg{end}} % Using this macro, you can add a new checklist layout. % The \meta{begin} and \meta{end} part is similar to a % |\newenvironment|. The \meta{fields} must be a comma-separated list -% of field names that can be the names of the checklist entry options -% (plus ``description'' and ``status'') but can assume other values. -% +% of field names. A field name can be one of the following: +% \begin{enumerate}[noitemsep] +% \item\label{enum:field-format-property} +% the name of an entry property (e.g., `status', `description', +% `deadline', or `who'), +% \item\label{enum:field-format-multiple} +% the concatenation of multiple entry properties, separated by a `+' (e.g., `deadline+status'), or +% \item\label{enum:field-format-other} +% a fresh name that does not correspond to an entry property. +% \end{enumerate} +% When one or multiple entry properties are referenced in a field name +% (cases~\ref{enum:field-format-property} +% and~\ref{enum:field-format-multiple}), then the \meta{code} +% argument to |\CheckListDefineFieldFormat| gets the properties' values +% as arguments when invoked. % \NiceDescribeMacro{\CheckListDefineFieldFormat}{\marg{layout}\marg{field}\marg{code}} % After the new type has been added, for each field in the % comma-separated \meta{fields}, this % macro must be used to define how a field is formatted. The -% \meta{code} can take one argument, through which it is passed the -% entry's option with name \meta{field}. +% \meta{code} can take one or more arguments. If the \meta{field} does +% not contain a `+', the \meta{code} can take one argument, through +% which the value of the respective entry property is passed to +% \meta{code}. If \meta{field} concatenates multiple property names with +% a `+', then the number of arguments equals the number of names in +% \meta{field} and the properties are passed in the given order. % % \NiceDescribeMacro{\CheckListExtendLayout}{\marg{name}\marg{base}\marg{fields}} % Using this macro, you can extend an existing checklist layout. @@ -510,19 +586,263 @@ % in the \meta{fields} parameter of the new layout. However, % additional fields can be defined and the format of the fields for % the new layout can be overwritten via |\CheckListDefineFieldFormat|. -% +% +% \paragraph{Auxiliary Macros} +% The following macros can be used in the definition of field formats. +% \lstset{morekeywords={CheckListStatusSymbol,CheckListSigned,CheckListDefaultLabel,CheckListDisplayDeadline}} +% +% \NiceDescribeMacro{\CheckListStatusSymbol}{\marg{status}} +% The macro expands to the defined symbol for the given \meta{status}, +% i.e., the overlay between the checklist type's base symbol and the +% entry status' symbol. +% +% \NiceDescribeMacro{\CheckListSigned}{\oarg{core}\marg{text}} +% The macro displays \meta{text} in a right-aligned fashion with a +% dotted leader to \meta{text}. This is similar to the display of page +% numbers in some table of content formats. +% The display takes place only if \meta{text} is non-empty. If +% \meta{core} is given, \meta{core} is instead used in the emptiness +% check. +% +% \NiceDescribeMacro{\CheckListDefaultLabel}{\marg{label}} +% This macro sets \meta{label} as the label for the current entry, based +% on the default checklist counter. It corresponds to a +% |\refstepcounter| on the checklist counter and a subsequent +% |\label{|\meta{label}|}|. +% +% \NiceDescribeMacro{\CheckListDisplayDeadline}{\marg{status}\marg{deadline}} +% This macro displays \meta{deadline} depending on the given entry's +% \meta{status} and the current date. Internally, for highlighting +% the deadline, the following macro is used, which can be redefined with +% |\renewcommand| to change the deadline highlighting. +% \NiceDescribeMacro{\CheckListHighlightDeadline}{\marg{closed?}\marg{passed?}\marg{deadline}} +% This macro formats \meta{deadline} depending on whether the +% corresponding checklist entry is \meta{closed?} (|true| or |false|) +% and whether \meta{deadline} has already \meta{passed?} (|true| or +% |false|). +% +% \paragraph{Example} +% The following example shows how to define an alternative list format. +% +% \begin{LTXexample}[pos=t] +% \CheckListDeclareLayout{enumlist}{label,who,status,description+deadline+status} +% {\bgroup\topsep=\medskipamount\itemsep=0pt\enumerate} +% {\endenumerate\egroup} +% \CheckListDefineFieldFormat{enumlist}{label}{\item\label{#1}} +% \CheckListDefineFieldFormat{enumlist}{who}{\ifstrempty{#1}{}{#1: }} +% \CheckListDefineFieldFormat{enumlist}{status}{\normalmarginpar\marginnote +% {\CheckListStatusSymbol{#1}}} +% \CheckListDefineFieldFormat{enumlist}{description+deadline+status} +% {#1\CheckListSigned[#2]{\CheckListDisplayDeadline{#3}{#2}}} +% +% \begin{CheckList}[layout=enumlist]{Goal} +% \Goal[deadline=31.12.999]{achieved}{Y1K problems are resolved.} +% \Goal[who=John,deadline=31.12.1999]{open}{Y2K problems are resolved.} +% \begin{CheckList}{Task} +% \Task[who=John,label=Fix1]{started}{Repair all programs} +% \Task[who=Mankind,deadline=31.12.1999] +% {open}{Just turn off all computers, if Task~\ref{Fix1} fails} +% \end{CheckList} +% \end{CheckList} +% \end{LTXexample} +% +% \subsection{Adding Entry Options} +% \lstset{morekeywords={CheckListAddEntryOption}} +% +% Checklist entries can be augmented by more than the default fields. +% Values for these additional fields can be specified as entry options. +% +% \NiceDescribeMacro{\CheckListAddEntryOption}{\marg{name}\marg{default}} +% This macro introduces a new entry option named \meta{name} and with +% the given \meta{default} value. The newly introduced option can then +% be provided to a checklist entry in the same way as the pre-defined +% options ``who'' and ``label''. +% +% When an entry option is defined, by default it is not displayed. +% Hence, when introducing a new entry option, one should consider +% defining a new checklist layout that makes use of the entry option. +% +% The following example shows how to extend a layout for incorporating a +% custom-defined priority field. +% \begin{LTXexample}[pos=t] +% \CheckListAddEntryOption{priority}{M} +% \usepackage{xcolor} +% \colorlet{priocolor-H}{red} +% \colorlet{priocolor-M}{black} +% \colorlet{priocolor-L}{lightgray} +% \CheckListExtendLayout{priolist}{list}{priority+status,label,description, +% who,deadline+status,END} +% \CheckListDefineFieldFormat{priolist}{priority+status}{% +% \item[{\normalfont\textcolor{priocolor-#1}{\CheckListStatusSymbol{#2}}}]} +% +% \begin{CheckList}[layout=priolist]{Task} +% \Task[priority=H]{done}{Important task} +% \Task{open}{Normal task} +% \Task[priority=L]{started}{Unimportant task} +% \end{CheckList} +% \end{LTXexample} +% +% +% \section{Filtering Checklists}\label{sec:filtering} +% +% Filtering out certain checklist entries based on their properties can +% help keeping the focus on the relevant entries. +% For this purpose, \pkgname{typed-checklist} allows one to specify +% filtering code. +% +% \subsection{Setting Basic Filters} +% +% \NiceDescribeMacro{\CheckListFilterClosed}{\oarg{types}} +% This macro sets up a filter that \emph{hides} all checklist entries +% whose status is closed. +% Through the optional \meta{types} argument, a comma-separated list of +% checklist types can be specified to which the filter shall be applied. +% By default, the filter is applied to all defined checklist types. +% \begin{LTXexample}[morekeywords=CheckListFilterClosed] +% \CheckListFilterClosed +% \begin{CheckList}{Task} +% \Task{open}{Open task} +% \Task{started}{Started task} +% \Task{done}{Done task} +% \Task{dropped}{Dropped task} +% \end{CheckList} +% \end{LTXexample} +% +% \NiceDescribeMacro{\CheckListFilterValue}{\oarg{types}\marg{field}\marg{value}} +% This macro sets up a filter that \emph{hides} all checklist entries +% whose \meta{field} has a value that is unequal \meta{value}. +% \begin{LTXexample}[morekeywords=CheckListFilterValue] +% \CheckListFilterValue{who}{John} +% \begin{CheckList}{Task} +% \Task[who=John]{open}{John's task} +% \Task[who=Mary]{open}{Mary's task} +% \end{CheckList} +% \end{LTXexample} +% +% \NiceDescribeMacro{\CheckListFilterDeadline}{\oarg{types}\marg{comp}\marg{date}\marg{filter-inv}} +% This macro sets up a filter that filters out checklist entries by +% their deadline. Only those entries are preserved whose deadline is +% before (if \meta{comp} equals `$<$'), equal (if \meta{comp} equals +% `$=$'), or after (if \meta{comp} equals `$>$') the given \meta{date}. +% The \meta{date} \emph{must} be in the format selected for input dates (see +% the |input-dates| option). +% If \meta{filter-inv} is |true|, then checklist entries whose deadline +% does not obey the format for input dates are filtered out. Otherwise, +% if \meta{filter-inv} is |false|, these checklist entries are not +% filtered out. +% +% \begin{LTXexample}[pos=t,morekeywords={CheckListFilterDeadline}] +% \CheckListFilterDeadline{<}{01.01.2019}{true} +% \begin{CheckList}{Task} +% \Task[who=John,deadline=09.11.1989]{open}{John's task} +% \Task[who=Mary,deadline=01.01.2019]{open}{Mary's task} +% \Task[deadline=TBD]{open}{Other task (first time)} +% +% \CheckListFilterDeadline{<}{01.01.2019}{false} +% \Task[deadline=TBD]{open}{Other task (second time)} +% \end{CheckList} +% \end{LTXexample} +% +% \subsection{Combining and Resetting Filters} +% +% When multiple filter macros are used, the filters are applied one +% after another to each checklist entry until a filter filters out the +% entry. Consequentially, all applied filters are combined +% conjunctively, i.e., only those checklist entries are displayed that +% satisfy all filters. +% +% When two filters are set up that affect the exact same fields of +% checklist entries (of the same type), then only the last of these +% filters becomes effective. The following example demonstrates this as +% well as the conjunction of filters. +% \begin{LTXexample}[width=0.414\hsize,morekeywords=CheckListFilterValue] +% \CheckListFilterValue{who}{John} +% \CheckListFilterValue[Task]{status}{done} +% \CheckListFilterValue[Goal]{status}{achieved} +% \CheckListFilterValue{who}{Mary} +% \begin{CheckList}{Goal} +% \Goal[who=Mary]{achieved}{Mary's goal} +% \begin{CheckList}{Task} +% \Task[who=John]{done}{John's task} +% \Task[who=Mary]{done}{Mary's task} +% \Task[who=Mary]{open}{Mary's open task} +% \end{CheckList} +% \end{CheckList} +% \end{LTXexample} +% +% Filters are local to the \LaTeX{} group in which they are set up. +% In particular, if a filter is set up inside an environment, then the +% filter is no longer effective after the environment. +% \begin{LTXexample}[width=0.414\hsize,morekeywords=CheckListFilterValue] +% \begin{CheckList}{Goal} +% \Goal[who=Mary]{achieved}{Mary's goal} +% \begin{CheckList}{Task} +% \CheckListFilterValue{who}{Mary} +% \Task[who=Mary]{done}{Mary's task} +% \Task[who=John]{done}{John's task} +% \end{CheckList} +% \Goal[who=John]{achieved}{John's goal} +% \end{CheckList} +% \end{LTXexample} +% +% \NiceDescribeMacro{\CheckListFilterReset}{\oarg{types}} +% This macro removes all filters. If \meta{types} are given, then only +% the filters for the checklist types in the comma-separated +% \meta{types} are removed. +% \begin{LTXexample}[width=0.414\hsize,morekeywords={CheckListFilterValue,CheckListFilterReset}] +% \CheckListFilterValue{who}{John} +% \begin{CheckList}{Task} +% \Task[who=John]{open}{John's task (1)} +% \Task[who=Mary]{open}{Mary's task (1)} +% \end{CheckList} +% \CheckListFilterReset[Task] +% \begin{CheckList}{Task} +% \Task[who=John]{open}{John's task (2)} +% \Task[who=Mary]{open}{Mary's task (2)} +% \end{CheckList} +% \begin{CheckList}{Goal} +% \Goal[who=Mary]{achieved}{Mary's goal (3)} +% \Goal[who=John]{achieved}{John's goal (3)} +% \end{CheckList} +% \end{LTXexample} +% +% +% \subsection{The Generic Filter Interface}\label{sec:filter-generic} +% +% Filters can also be set up programmatically. +% +% \NiceDescribeMacro{\CheckListSetFilter}{\oarg{types}\marg{fields}\marg{filter-code}} +% This macro sets up the \meta{filter-code} for a set of \meta{fields}. +% The \meta{fields} must be given as a `+'-separated list of field +% names, e.g., ``|status+who|''. +% The \meta{filter-code} may contain as many positional parameters +% (|#1|, \ldots) as there are fields names in \meta{fields}. When a +% checklist entry is about to be displayed, the \meta{filter-code} is +% evaluated, obtaining as arguments the entry's field values. By default +% (without any filter set up), all entries are displayed. To disable the +% display of an entry, the \meta{filter-code} can use +% |\togglefalse{display}|. +% If \meta{types} are given (as a comma-separated list), then the +% \meta{filter-code} is applied only to checklists of a type in the +% list. +% +% Examples for how to use the macro can be found in the implementation, +% e.g., of the macros |\CheckListFilterClosed| and +% |\CheckListFilterValue|. +% +% % \section{Checklists and Other Packages} % -% \subsection{asciilist} +% \subsection{asciilist}\label{sec:asciilist} % -% The \textsf{typed-checklist} package can be combined with the -% \textsf{asciilist} package in the sense that a checklist can be +% The \pkgname{typed-checklist} package can be combined with the +% \pkgname{asciilist} package in the sense that a checklist can be % defined within an |AsciiList| environment. The -% \textsf{typed-checklist} package provides a syntax for this when the +% \pkgname{typed-checklist} package provides a syntax for this when the % package is loaded with the |withAsciilist=true| option. The syntax % is illustrated with the following snippet, a transformed version of -% the example in Section~\ref{sec:NestOptExample}: -% \begin{LTXexample}[pos=t,preset=\FakeRefs] +% the example in \cref{sec:NestOptExample}: +% \begin{LTXexample}[pos=t] % \usepackage[withAsciilist=true]{typed-checklist} % \begin{AsciiList}[GoalList,TaskList]{-,*} % - achieved[deadline=31.12.999]: No Y1K problems @@ -543,41 +863,66 @@ % Note also that the |table| layout does not work within an |AsciiList| % environment. % +% \subsection{Table Packages}\label{sec:tablepkg} +% +% The |table| layout by default uses the \pkgname{tabu} package for +% layouting the tables. The default can be changed through the +% |tablepkg| package option. The following values are available: +% \begin{KeyValTable}{ValDesc} +% \Row{val=ltablex, +% desc={This option uses the \pkgname{ltablex} package. }} +% \Row{val=tabu, +% desc={This option uses the \pkgname{tabu} package, which is the +% default. That is, specifying this option does not change the +% package behavior.}} +% \Row{val=tabularx, +% desc={This option uses the \pkgname{tabularx} package from the +% \hologo{LaTeX} core. When using this table type, keep in mind +% that |tabularx| tables must fit onto a single page.}} +% \Row{val=xltabular, +% desc={This option uses the \pkgname{xltabular} package, a successor +% of \pkgname{ltablex}.}} +% \end{KeyValTable} +% +% Note: +% In the future, the default might change if the \pkgname{tabu} package +% remains unmaintained. +% % \section{Related Packages} % % The following \LaTeX{} packages provide related functionalities to -% the \textsf{typed-checklist} package. +% the \pkgname{typed-checklist} package. % % \begin{description} -% \item[\textsf{todo}:] +% \item[\pkgname{todo}:] % The package allows for typesetting ``to-dos'', i.e., tasks in some % sense, in a simple way with customizable display. The three main -% conceptual differences between \textsf{todo} and -% \textsf{typed-checklist} are: +% conceptual differences between \pkgname{todo} and +% \pkgname{typed-checklist} are: % \begin{enumerate} -% \item \textsf{todo} does not distinguish between different types +% \item \pkgname{todo} does not distinguish between different types % (such as goals and tasks); -% \item \textsf{todo} does not allow one to provide a status for a +% \item \pkgname{todo} does not allow one to provide a status for a % to-do and rather assumes that done to-dos are simply removed from % the document; -% \item \textsf{todo} aims at specifying tasks for document into which -% the to-dos are placed, while \textsf{typed-checklist} aims at +% \item \pkgname{todo} aims at specifying tasks for the document into +% which the to-dos are placed, while \pkgname{typed-checklist} aims at % typesetting checklists whose entries are for more general kinds of % projects. % \end{enumerate} -% \item[\textsf{easy-todo}:] -% The package is similar in spirit to the \textsf{tood} package and -% shares the main differences to the \textsf{typed-checklist} package. -% \item[\textsf{todonotes}:] -% The package is similar in spirit to \textsf{todo} and -% \textsf{easy-tood}, but provide more formatting options for the +% \item[\pkgname{easy-todo}:] +% The package is similar in spirit to the \pkgname{todo} package and +% shares the main differences to the \pkgname{typed-checklist} package. +% \item[\pkgname{todonotes}:] +% The package is similar in spirit to \pkgname{todo} and +% \pkgname{easy-todo}, but provides more formatting options for the % to-dos. -% \item[\textsf{pgfgantt}:] +% \item[\pkgname{pgfgantt}:] % The package allows one to create Gantt charts, i.e., graphical % displays of activities and milestones with a focus on time frames. % The package allows one to structure the activities into groups. In % that sense, there are certain similarities between the packages. The -% main conceptual difference to \textsf{typed-checklist} is the form +% main conceptual difference to \pkgname{typed-checklist} is the form % of presentation (time-centric Gantt chart vs. text-centric lists). % \end{description} % @@ -588,6 +933,9 @@ % left margin on even pages. The default layout (|list|) does not look % good then. This should be repaired. The same problem is with % checklist entry labels, which are displayed on the other side. +% \item In deadlines, the full year (including century) must be provided +% for the colored highlighting to work. Future versions could check +% for a two-digit year and automatically prepend "20" for the century. % \item The package automatically adds the pre-defined checklist types % and states, which might have two draws for some users: firstly, this % adds a dependency on symbol packages, which might not work well @@ -595,25 +943,21 @@ % definitions of the standard checklist types. % To improve the situation, the package could offer an option for % disabling the definition of the standard checklist types. Concerning -% the symbols packages, \textsf{typed-checklist} could also reduce the +% the symbols packages, \pkgname{typed-checklist} could also reduce the % set of used packages or even draw all symbols itself. -% \item The date format for deadlines currently is ``DD.MM.YYYY''. We -% could make the package more flexible in this regard by offering -% other formats as well, for instance by using the \textsf{datetime2} -% package. % \item The package displays checklist entries in the ordering in which % they are listed in the \LaTeX{} sources. Automatic sorting of % checklist entries, for instance by deadline or future fields like % priority/importance, might make the package even more useful for % bigger checklists. -% The implementation of the feature could be inspired by the following -% \textsf{stackexchange} thread: -% \url{http://tex.stackexchange.com/questions/6988/how-to-sort-an-alphanumeric-list} +% The implementation of the feature could be done for example as +% discussed on +% \href{http://tex.stackexchange.com/questions/6988/how-to-sort-an-alphanumeric-list}{stackexchange}. % \end{itemize} % % \clearpage % \section{Pre-defined Checklist Types and States} -% \begin{LTXexample} +% \begin{LTXexample}[width=0.414\hsize] % \paragraph{Goals} % \begin{CheckList}{Goal} % \Goal{open}{open goal} @@ -621,6 +965,7 @@ % \Goal{unclear}{unclear goal} % \Goal{achieved}{achieved goal} % \end{CheckList} +% % \paragraph{Tasks} % \begin{CheckList}{Task} % \Task{open}{open task} @@ -629,6 +974,7 @@ % \Task{started}{started task} % \Task{done}{done task} % \end{CheckList} +% % \paragraph{Artifacts} % \begin{CheckList}{Artifact} % \Artifact{missing}{missing artifact} @@ -637,6 +983,7 @@ % \Artifact{incomplete}{incomplete artifact} % \Artifact{available}{available artifact} % \end{CheckList} +% % \paragraph{Milestones} % \begin{CheckList}{Milestone} % \Milestone{open}{open milestone} @@ -654,23 +1001,14 @@ % % \section{Implementation} % -% \subsection{Package Options} +% \subsection{Basic Package Dependencies} % -% We use the \textsf{xkeyval} package for declaring package options as +% We use the \pkgname{xkeyval} package for declaring package options as % well as for option lists of entry types. % \begin{macrocode} \RequirePackage{xkeyval} % \end{macrocode} -% The |withAsciilist| option enables support for the -% \textsf{asciilist} package. -% \begin{macrocode} -\define@boolkey{typed-checklist.sty}[tchklst@]{withAsciilist}{} -\ProcessOptionsX -% \end{macrocode} -% -% \subsection{Basic Package Dependencies} -% -% We use the \textsf{etoolbox} package for simpler handling of lists. +% We use the \pkgname{etoolbox} package for simpler handling of lists. % \begin{macrocode} \RequirePackage{etoolbox} % \end{macrocode} @@ -678,37 +1016,40 @@ % \begin{macrocode} \RequirePackage{xcolor} % \end{macrocode} -% If the package is loaded with \textsf{asciilist} support, we load -% the package here. -% \begin{macrocode} -\iftchklst@withAsciilist -\RequirePackage{asciilist} -\fi -% \end{macrocode} % -% \subsection{Checklist and Entry Options} -% \label{sec:Impl-ChecklistOptions} -% In the following, we define the possible options for a checklist. -% \begin{macrocode} -\define@cmdkey[tchklst]{ListOption}{layout}[\tchklst@defaultlayout]{} -\presetkeys[tchklst]{ListOption}{layout}{} -% \end{macrocode} +% \subsection{Options} % -% \begin{macro}{\CheckListDefaultLayout} -% The |\CheckListDefaultLayout|\marg{layout} macro sets the default -% layout for all |CheckList| environments that do not set the |layout| -% option explicitly. -% \changes{v1.2b}{2015/04/01}{Enabled setting default checklist layouts} +% \subsubsection{Checklist Options} +% +% In the following, we define the possible options for a checklist. % \begin{macrocode} -\newcommand*\CheckListDefaultLayout[1]{% +\define@key[tchklst]{GlobalListOptions}{layout}{% \ifinlist{#1}{\tchklst@ChecklistLayouts}{}{% \PackageError{typed-checklist}{% - Checklist layout `#1' cannot be made default: - it does not exist}{}}% - \def\tchklst@defaultlayout{#1}} -\def\tchklst@defaultlayout{list} + `#1' not a known checklist layout} + {Known layouts are:\forlistloop{ }{\tchklst@@CheckListLayouts}}}% + \def\tchklst@@layout{#1}} +\define@key[tchklst]{GlobalListOptions}{input-dates}{% + \ifinlist{#1}{\tchklst@@InputDateFormats}{}{% + \PackageError{typed-checklist}{% + `#1' not a known input date format} + {Known formats are:\forlistloop{ }{\tchklst@@InputDateFormats}}}% + \letcs\tchklst@inputdate@order{tchklst@dateorder@#1}% + \letcs\tchklst@inputdate@sep{tchklst@dateformat@sep@#1}} +\define@key[tchklst]{GlobalListOptions}{output-dates}{% + \ifinlist{#1}{\tchklst@@OutputDateFormats}{}{% + \PackageError{typed-checklist}{% + `#1' not a known output date format} + {Known formats are:\forlistloop{ }{\tchklst@@OutputDateFormats}}}% + \letcs\tchklst@@dateoutput@use{tchklst@dateoutput@use@#1}} +\define@boolkey[tchklst]{GlobalListOptions}{strict-dates}[true]{% + \ifbool{tchklst@GlobalListOptions@strict-dates} + {\let\tchklst@@faileddate=\tchklst@DateFailStrict} + {\let\tchklst@@faileddate=\tchklst@DateFailLax}} % \end{macrocode} -% \end{macro} +% +% \subsubsection{Checklist Entry Options} +% \label{sec:Impl-ChecklistEntryOptions} % % \begin{macro}{\CheckListAddEntryOption} % The |\CheckListAddEntryOption|\marg{option}\marg{default} macro @@ -717,8 +1058,8 @@ % \changes{v1.2}{2015/03/20}{Added \cs{CheckListAddEntryOption} macro} % \begin{macrocode} \newcommand*\CheckListAddEntryOption[2]{% - \define@cmdkey[tchklst]{EntryOption}{#1}[#2]{}% - \presetkeys[tchklst]{EntryOption}{#1}{}} + \define@cmdkey[tchklst]{Entry}{#1}[#2]{}% + \presetkeys[tchklst]{Entry}{#1}{}} % \end{macrocode} % \end{macro} % @@ -730,6 +1071,31 @@ \CheckListAddEntryOption{label}{} % \end{macrocode} % +% \subsection{Setting Options Globally} +% +% \begin{macro}{\CheckListSet} +% The |\CheckListSet|\marg{options-list} sets global options for the +% \pkgname{typed-checklist} package. +% \changes{v2.0}{2018/11/10}{Macro added} +% \begin{macrocode} +\newcommand\CheckListSet[1]{% + \setkeys[tchklst]{GlobalListOptions}{#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\CheckListDefaultLayout} +% The |\CheckListDefaultLayout|\marg{layout} macro sets the default +% layout for all |CheckList| environments that do not set the |layout| +% option explicitly. +% This macro is obsoleted by the |\CheckListSet| macro introduced in +% v2.0 of the package. +% \changes{v1.2b}{2015/04/01}{Enabled setting default checklist layouts} +% \begin{macrocode} +\newcommand*\CheckListDefaultLayout[1]{% + \CheckListSet{layout={#1}}} +% \end{macrocode} +% \end{macro} +% % \subsection{Checklist Types} % In the following, we implement the existing types of checklists as % well as the macros for declaring new types. @@ -758,38 +1124,49 @@ % \end{macrocode} % Save the symbol of the new type. % \begin{macrocode} - \expandafter\def\csname tchklst@ChecklistTypeSym@#1\endcsname{#2}% + \csdef{tchklst@ChecklistTypeSym@#1}{#2}% % \end{macrocode} % Create an initially empty list of possible states that entries of the -% type can have. +% type can have, and an empty list of filters for the type. % \begin{macrocode} - \expandafter\def\csname tchklst@ChecklistStates@#1\endcsname{}% + \csdef{tchklst@ChecklistStates@#1}{}% + \csdef{tchklst@ChecklistFilters@#1}{}% % \end{macrocode} -% If \textsf{asciilist} support is enabled, register an environment -% for the checklist type. -% \changes{v1.3c}{2015/08/24}{Enabled use of optional arguments for -% \textsf{asciilist} environments} -% \begin{macrocode} - \iftchklst@withAsciilist - \AsciiListRegisterEnv{#1List}% - {\tchklst@aux@OargAfter{\CheckList{#1}}}% - {\endCheckList}% - {\AsciiListEndArg{\tchklst@ChkListEntry{\csname #1\endcsname}}}% - \fi -} +% Finally, invoke all hooks for new types of checklists. +% \begin{macrocode} + \def\do##1{##1{#1}}% + \dolistloop\tchklst@@addtype@hooks} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tchklst@@addtype@hooks} +% This is an \pkgname{etoolbox} list of single-argument macros for +% hooking into the registration of new checklist types. +% \begin{macrocode} +\newcommand*\tchklst@@addtype@hooks{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tchklst@IntroduceTypeHook} +% The |\tchklst@IntroduceTypeHook|\marg{cmd} macro introduces \meta{cmd} +% for all existing checklist types (first code line) as well as for all +% checklist types defined afterwards (second code line). +% \begin{macrocode} +\newcommand*\tchklst@IntroduceTypeHook[1]{% + \forlistloop{#1}{\tchklst@ChecklistTypes}% + \listgadd\tchklst@@addtype@hook{#1}} % \end{macrocode} % \end{macro} % % \begin{macro}{\tchklst@aux@OargAfter} -% The |\tchklst@aux@OargAfter|\marg{macro-use}\oarg{opt-arg} macro takes a -% \meta{macro-use} without optional arguments and subsequently an -% optional argument. If the optional argument is given, then this is -% added to the \meta{macro-use} in a way that the macro uses the -% optional argument. If no optional argument is given, then the -% \meta{macro-use} is taken as is. +% The |\tchklst@aux@OargAfter|\marg{macro-use}\oarg{opt-arg} macro +% inserts an optional argument, \meta{opt-arg}, into a \meta{macro-use}, +% where the \meta{macro-use} may have multiple mandatory +% arguments but no optional argument. The \meta{opt-arg} is optional, +% i.e., if it is not provided, then \meta{macro-use} is taken as is. % % Example use: |\tchklst@aux@OargAfter{\cite{foo}}[page 9]| would expand -% to |\tchklst@aux@OargAfter@ii{\cite}{page 9}{foo}| and, finally, to +% first to |\tchklst@aux@OargAfter@ii{page 9}\cite{foo}| and, finally, to % |\cite[page 9]{foo}|. % \begin{macrocode} \newcommand\tchklst@aux@OargAfter[1]{% @@ -835,14 +1212,15 @@ % \end{macrocode} % We loop over all the checklist \meta{types} given. % \begin{macrocode} - \forcsvlist% + \forcsvlist % \end{macrocode} % In the following line, the actual type parameter is added last by the % |\forcsvlist| macro. % \begin{macrocode} - {\tchklst@AddStatus{#2}{#3}{#4}}% - {#1}}% + {\tchklst@AddStatus{#2}{#3}{#4}}% + {#1}}% % \end{macrocode} +% \end{macro} % \begin{macro}{\tchklst@AddStatus} % The % |\tchklst@AddStatus|\marg{status}\marg{isclosed}\marg{symbol}\marg{type} @@ -870,7 +1248,6 @@ \expandafter\def\csname tchklst@sym@#4@#1\endcsname{#3}} % \end{macrocode} % \end{macro} -% \end{macro} % % \begin{macro}{\tchklst@CheckTypeStatus} % The |\tchklst@CheckTypeStatus|\marg{type}\marg{status} is a convenience @@ -886,12 +1263,12 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\tchklst@getsymbol} -% The |\tchklst@getsymbol|\marg{status} is a convenience +% \begin{macro}{\CheckListStatusSymbol} +% The |\CheckListStatusSymbol|\marg{status} is a convenience % macro for obtaining the symbol for a particular \meta{status} of the % current checklist's type. % \begin{macrocode} -\newcommand*\tchklst@getsymbol[1]{% +\newcommand*\CheckListStatusSymbol[1]{% \tchklst@symbolcombine{\csuse{tchklst@sym@\tchklst@cur@type @#1}}% {\csuse{tchklst@ChecklistTypeSym@\tchklst@cur@type}}} % \end{macrocode} @@ -900,23 +1277,26 @@ % \begin{macro}{\tchklst@symbolcombine} % The |\tchklst@symbolcombine|\marg{symbol1}\marg{symbol2} % macro combines two symbols, \meta{symbol1} and \meta{symbol2}. +% \changes{v2.0}{2018/11/17}{Switched combining order} +% \changes{v2.0}{2018/11/19}{Ignore height of first argument} % \begin{macrocode} \newcommand*\tchklst@symbolcombine[2]{{% \setbox0\hbox{#2}% - \rlap{\hbox to \wd0{\hss #1\hss}}\box0 }} + \copy0\llap{\hbox to \wd0{\hss\smash{#1}\hss}}}} % \end{macrocode} % \end{macro} % -% \begin{macro}{\tchklst@ifsymdone} +% \begin{macro}{\CheckListIfClosed} % The -% |\tchklst@ifsymdone|\marg{type}\marg{status}\marg{iftrue}\marg{iffalse} -% macro expands to \meta{iftrue}, if the \meta{status} of an entry in a -% checklist of type \meta{type} is a ``closed'' one (see the +% |\CheckListIfClosed|\marg{status}\marg{iftrue}\marg{iffalse} +% macro expands to \meta{iftrue}, if the \meta{status} of an entry in +% the current checklist is a ``closed'' one (see the % documentation for |\CheckListAddStatus| for details). Otherwise, the % macro expands to \meta{iffalse}. % \begin{macrocode} -\newcommand*\tchklst@ifsymdone[2]{% - \csname if\csname tchklst@isclosed@#1@#2\endcsname\endcsname +\newcommand*\CheckListIfClosed[1]{% + \csname if\csname tchklst@isclosed@\tchklst@cur@type @#1\endcsname + \endcsname \expandafter\@firstoftwo \else \expandafter\@secondoftwo @@ -991,21 +1371,63 @@ % \begin{macro}{\CheckListDefineFieldFormat} % The |\CheckListDefineFieldFormat|\marg{layout}\marg{field}\marg{code} % macro defines the \meta{code} to be used for displaying the given -% \meta{field} in a checklist of the given \meta{layout}. The code may -% take one argument (i.e., use \verb!#1!). +% \meta{field} (or fields) in a checklist of the given \meta{layout}. +% Multiple fields can be displayed by specifying \meta{field} in the +% form $\meta{field}_1+\ldots+\meta{field}_n$. % \begin{macrocode} \newcommand\CheckListDefineFieldFormat[3]{% - \long\csdef{tchklst@ChecklistFormat@#1@#2}##1{#3}} + \tchklst@deffieldmacro{tchklst@ChecklistFormat@#1@#2}{#2}{#3}} % \end{macrocode} % \end{macro} % -% \begin{macro}{\tchklst@FormattedField} -% The |\tchklst@FormattedField|\marg{field} macro returns the macro for -% formatting the given \meta{field} in a layout given by -% |\tchklst@cur@layout|. +% \begin{macro}{\tchklst@deffieldmacro} +% The |\tchklst@deffieldmacro|\marg{csname}\marg{fields}\marg{code} +% defines a command with name \meta{csname} whose number of arguments +% equals the number of `+'-separated elements in \meta{fields}. +% The command then expands to \meta{code}, which can refer to the +% respective number of positional parameters. +% \begin{macrocode} +\newcommand\tchklst@deffieldmacro[3]{% + \begingroup +% \end{macrocode} +% Get number of properties (`+'-separated) in \meta{field} into +% |\@tempcnta|. +% \begin{macrocode} + \@tempcnta=0\relax + \def\do##1{\advance\@tempcnta by 1\relax}% + \tchklst@dopsvlist{#2}% +% \end{macrocode} +% Next, use the above number for determining the number of arguments +% of the defined formatting macro, i.e., the number of positional +% parameters permitted in \meta{code}. The macro is first |\undef|'d +% such that |\newcommand| always succeeds. % \begin{macrocode} -\newcommand*\tchklst@FormattedField[1]{% - \csname tchklst@ChecklistFormat@\tchklst@cur@layout @#1\endcsname} + \edef\do{\endgroup + \csundef{#1}% + \noexpand\newcommand\expandonce{\csname #1\endcsname}% + [\the\@tempcnta]{\unexpanded{#3}}}% + \do} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tchklst@usefieldmacro} +% The |\tchklst@usefieldmacro|\oarg{use-cmd}\marg{csname}\marg{fields} +% macro takes the current values of the fields in the `+'-separated +% \meta{fields} and applies them in the given order to \meta{csname}. +% This application is performed directly, if \meta{use-cmd} is left at +% its default, or is otherwise provided as an argument to \meta{use-cmd}. +% \begin{macrocode} +\newcommand\tchklst@usefieldmacro[3][\@firstofone]{% + \begingroup + \expandafter\def\expandafter\tchklst@@cmd\expandafter{% + \csname #2\endcsname}% + \def\do##1{\eappto\tchklst@@cmd{% + {\csexpandonce{cmdtchklst@Entry@##1}}}}% + \tchklst@dopsvlist{#3}% + \expandafter\def\expandafter\tchklst@@cmd\expandafter{% + \expandafter{\tchklst@@cmd}}% + \preto\tchklst@@cmd{\endgroup#1}% + \tchklst@@cmd} % \end{macrocode} % \end{macro} % @@ -1023,6 +1445,115 @@ % \end{macrocode} % \end{macro} % +% \subsection{Entry Filters} +% +% \begin{macro}{\CheckListSetFilter} +% \changes{v2.0}{2018/11/27}{Added customizable filtering feature} +% \begin{macro}{\tchklst@SetFilter} +% The |\CheckListSetFilter|\oarg{types}\marg{fields}\marg{code} macro +% defines a filter for the given \meta{fields} of all types in the +% comma-separated list \meta{types}. The filtering code is \meta{code}, +% which may use positional parameters. +% \begin{macrocode} +\newcommand*\CheckListSetFilter[3][*]{% + \ifstrequal{#1}{*} + {\forlistloop{\tchklst@SetFilter{#2}{#3}}{\tchklst@ChecklistTypes}} + {\forcsvlist{\tchklst@SetFilter{#2}{#3}}{#1}}} +% \end{macrocode} +% The |\tchklst@SetFilter|\marg{fields}\marg{code}\marg{type} +% macro defines a filter for a single type. +% \begin{macrocode} +\newcommand*\tchklst@SetFilter[3]{% + \tchklst@CheckType{#3}% + \ifinlistcs{#1}{tchklst@ChecklistFilters@#3}{} + {\listcsadd{tchklst@ChecklistFilters@#3}{#1}}% + \tchklst@deffieldmacro{tchklst@CheckListFilter@#3@#1}{#1}{#2}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\CheckListFilterValue} +% The |\CheckListFilterValue|\oarg{types}\marg{field}\marg{value} macro +% filters out all checklist entries whose \meta{field} is unequal +% \meta{value}, by using an |\ifstrequal| comparison. +% \begin{macrocode} +\newcommand*\CheckListFilterValue[3][*]{% + \CheckListSetFilter[#1]{#2} + {\ifstrequal{##1}{#3}{}{\togglefalse{display}}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\CheckListFilterClosed} +% The |\CheckListFilterClosed|\oarg{types}\marg{field}\marg{value} macro +% filters out all checklist entries whose status is closed, +% by using |\CheckListIfClosed|. +% \begin{macrocode} +\newcommand*\CheckListFilterClosed[1][*]{% + \CheckListSetFilter[#1]{status} + {\CheckListIfClosed{##1}{\togglefalse{display}}{}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\CheckListFilterDeadline} +% The +% |\CheckListFilterDeadline|\oarg{types}\marg{comp}\marg{refdate}\marg{filter-inv} +% macro filters out all checklist entries whose deadline does not +% satisfy the comparison against \meta{refdate} by operator \meta{comp} +% (`$<$', `$=$', `$>$'). The argument \meta{filter-inv} must be either +% |true| or |false| and specifies whether deadlines that do not match +% the selected input deadline format are filtered out (|true|) or not +% (|false|). +% \begin{macrocode} +\newcommand*\CheckListFilterDeadline[4][*]{% +% \end{macrocode} +% First, pre-parse \meta{refdate} such that it need not be parsed for +% each checklist entry. +% \begin{macrocode} + \bgroup + \def\do##1##2##3##4{\egroup +% \end{macrocode} +% Use the internal |\tchklst@DateCompare| macro to perform the date +% comparison based on the pre-parsed date of the +% |\do|\marg{year}\marg{month}\marg{day} macro arguments. +% \begin{macrocode} + \CheckListSetFilter[#1]{deadline} + {\tchklst@DateCompare{####1}{#2}{##1}{##2}{##3} + {}{\togglefalse{display}} + {\ifbool{#4}{\togglefalse{display}}{}\@gobble}}} + \CheckListParseDate{#3}{\do} +% \end{macrocode} +% If parsing \meta{refdate} fails, we always fail like with strict input +% date parsing: Setting up a filter with an invalid date would not make +% sense. +% \begin{macrocode} + {\egroup\tchklst@DateFailStrict}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\CheckListFilterReset} +% The |\CheckListFilterReset|\oarg{types} macro resets the filters for +% all checklist types in the comma-separated list \meta{types}. If +% \meta{types} is omitted or equals `|*|', then the filters for all +% checklist types are reset. +% \begin{macrocode} +\newcommand*\CheckListFilterReset[1][*]{% + \ifstrequal{#1}{*} + {\forlistloop{\tchklst@ResetFilter}{\tchklst@ChecklistTypes}} + {\forcsvlist{\tchklst@ResetFilter}{#1}}} +% \end{macrocode} +% \begin{macro}{\tchklst@ResetFilter} +% The |\tchklst@ResetFilter|\marg{type} macro removes all filters (i.e., +% for all fields) from checklists of the given \meta{type}. +% \begin{macrocode} +\newcommand*\tchklst@ResetFilter[1]{% + \def\do##1{\csundef{tchklst@CheckListFilter@#1@##1}}% + \dolistcsloop{tchklst@ChecklistFilters@#1}% + \csdef{tchklst@ChecklistFilters@#1}{}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% % \subsection{Checklist and Entry Definition} % % \begin{environment}{CheckList} @@ -1037,14 +1568,14 @@ % \end{macrocode} % Parse and check the options. % \begin{macrocode} - \setkeys[tchklst]{ListOption}{#1}% - \tchklst@CheckLayout{\cmdtchklst@ListOption@layout}% + \setkeys[tchklst]{GlobalListOptions}{#1}% + \tchklst@CheckLayout{\tchklst@@layout}% % \end{macrocode} % We store the type, layout, and fields of the checklist for use inside % the list. % \begin{macrocode} \edef\tchklst@cur@type{#2}% - \let\tchklst@cur@layout=\cmdtchklst@ListOption@layout% + \let\tchklst@cur@layout=\tchklst@@layout% \letcs\tchklst@cur@fields {tchklst@ChecklistLayoutFields@\tchklst@cur@layout}% % \end{macrocode} @@ -1063,25 +1594,16 @@ % \end{macrocode} % \end{environment} % -% \begin{macro}{\tchklst@entry@toks} -% The |\tchklst@entry@toks| token register is used by |\tchklst@entry| to first -% collect all the fields before showing the result. This is useful in -% cases when the layout changes the \LaTeX{} grouping between the field -% display (as it is the case for a table layout). -% \begin{macrocode} -\newtoks\tchklst@entry@toks -% \end{macrocode} -% \end{macro} -% % \begin{macro}{\tchklst@entry} % The |\tchklst@entry|\oarg{options}\marg{status}\marg{description} macro % defines a checklist entry with a given \meta{status}, a given % \meta{description}, and possibly particular \meta{options} (a % comma-separated list of key-value pairs). See -% Section~\ref{sec:Impl-ChecklistOptions} for the list of available +% \cref{sec:Impl-ChecklistEntryOptions} for the list of available % options. % \begin{macrocode} \newcommand\tchklst@entry[3][]{% + \begingroup % \end{macrocode} % First check for a valid status. There is no need to check for a valid % type, because the surrounding |CheckList| environment already does this. @@ -1090,60 +1612,169 @@ % \end{macrocode} % Parse the options. % \begin{macrocode} - \setkeys[tchklst]{EntryOption}{#1}% -% \end{macrocode} -% Define the label of the entry, if the |label| option is given in -% \meta{options}. -% \begin{macrocode} - \ifx\cmdtchklst@EntryOption@label\empty\else - \refstepcounter{tchklst@entryID}% - \expandafter\label\expandafter{\cmdtchklst@EntryOption@label}% - \fi + \setkeys[tchklst]{Entry}{#1}% % \end{macrocode} % Save status and description such that they can be accessed just like % the options. % \begin{macrocode} - \def\cmdtchklst@EntryOption@status{#2}% - \def\cmdtchklst@EntryOption@description{#3}% + \def\cmdtchklst@Entry@status{#2}% + \def\cmdtchklst@Entry@description{#3}% % \end{macrocode} -% Show the fields of the entry in the order they were given. +% Now iterate through all filters for the current type until one filter +% turns the local |display| toggle to false. % \begin{macrocode} - \tchklst@entry@toks={}% + \newtoggle{display}\toggletrue{display}% \def\do##1{% - \begingroup - \edef\tchklst@doformat{\endgroup - \noexpand\tchklst@entry@toks={% - \expandonce{\the\tchklst@entry@toks}% - \noexpand\tchklst@FormattedField{##1}% - {\csexpandonce{cmdtchklst@EntryOption@##1}}}}% - \tchklst@doformat}% - \dolistloop\tchklst@cur@fields - \the\tchklst@entry@toks} + \tchklst@usefieldmacro + {tchklst@CheckListFilter@\tchklst@cur@type @##1}{##1}% + \iftoggle{display}{}{\listbreak}}% + \dolistcsloop{tchklst@ChecklistFilters@\tchklst@cur@type}% +% \end{macrocode} +% Show the fields of the entry in the order they were given. +% The whole entry is first collected in a macro (|\tchklst@@entry|), +% such that individual field display code cannot leave the +% current \LaTeX{} group (e.g., by advancing to the next table +% cell in table layout) and thereby void the entry option macros. +% \changes{v2.0}{2018/11/27}{Simplified field display through +% \cs{tchklst@usefieldmacro}} +% \begin{macrocode} + \def\tchklst@@entry{\endgroup}% + \iftoggle{display}{% + \def\do##1{% + \tchklst@usefieldmacro[\appto\tchklst@@entry] + {tchklst@ChecklistFormat@\tchklst@cur@layout @##1}{##1}}% + \dolistloop\tchklst@cur@fields}{}% + \tchklst@@entry} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tchklst@dopsvlist} +% The |\tchklst@dopsvlist|\marg{list} parses a `+'-separated list. +% \begin{macrocode} +\DeclareListParser{\tchklst@dopsvlist}{+} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\CheckListSigned} +% The |\CheckListSigned|\oarg{core}\marg{text} macro is taken from Knuth's \TeX +% book with minor spacing modifications. See also +% \url{http://tex.stackexchange.com/a/13761}. +% The added optional \meta{core} is the reference for checks whether +% \meta{text} is empty: In case of emptiness, nothing is shown by the +% macro. If \meta{core} is omitted, \meta{text} itself is used in the +% emptiness check. +% \begin{macrocode} +\newcommand\CheckListSigned{\@dblarg\tchklst@signed} +\newcommand\tchklst@signed[2][]{% + \ifstrempty{#1} + {\nobreak\hfill\null} + {\leavevmode\unskip\nobreak\hfil\penalty50\hskip0.25em + \hbox{}\nobreak\dotfill\hbox{#2}}} +% \end{macrocode} +% \end{macro} +% +% \subsection{Deadlines} +% +% The following code implements the parsing of deadlines and for +% comparing deadlines against the current date. +% +% \begin{macro}{\CheckListDisplayDeadline} +% The |\CheckListDisplayDeadline|\marg{status}\marg{deadline} formats a +% \meta{deadline} dependent on the \meta{status} and the current date. +% \begin{macrocode} +\newcommand\CheckListDisplayDeadline[2]{% +% \end{macrocode} +% Try to parse \meta{deadline} as a date. +% \changes{v2.0}{2018/11/10}{More flexibility for deadline parsing and +% deadline printing} +% \begin{macrocode} + \CheckListParseDate{#2}{\tchklst@DisplayDeadline@i} +% \begin{macrocode} + {\tchklst@firstoftwoargs\tchklst@@faileddate} +% \end{macrocode} +% To each of the two former arguments (for successful and, respectively, +% failed parsing of the deadline), apply \meta{deadline} +% as argument. +% \begin{macrocode} + {#1}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\tchklst@firstoftwoargs} +% The |\tchklst@firstoftwoargs|\marg{cmd}\marg{arg1}\marg{arg2} macro +% applies \meta{cmd} to \meta{arg1} and gobbles \meta{arg2}. +% \begin{macrocode} +\newcommand\tchklst@firstoftwoargs[3]{#1{#2}} % \end{macrocode} % \end{macro} % -% \begin{macro}{\tchklst@ifafterdots} +% \begin{macro}{\tchklst@DisplayDeadline@i} % The -% |\tchklst@ifafterdots| \meta{day}.\meta{month}.\meta{year} macro is a -% parsing macro for dates in dotted notation. The macro is a wrapper for -% |\tchklst@ifafter|. +% |\tchklst@DisplayDeadline@i|\marg{y}\marg{m}\marg{d}\marg{deadline}\marg{status} +% macro displays a given \meta{deadline} that is additionally decomposed +% into year, month, and day given a particular \meta{status} of the +% respective checklist entry. The macro uses the chosen output date +% format as well as colored highlighting. +% \begin{macrocode} +\newcommand\tchklst@DisplayDeadline@i[5]{% +% \end{macrocode} +% Check whether the entry is completed and whether the deadline +% has passed. Collect the checks' results as arguments for +% |\CheckListHighlightDeadline|. +% \begin{macrocode} + \def\tchklst@@args{}% + \CheckListIfClosed{#5}% + {\appto\tchklst@@args{{true}}}{\appto\tchklst@@args{{false}}}% + \tchklst@ifafter{#1}{#2}{#3} + {\appto\tchklst@@args{{true}}}{\appto\tchklst@@args{{false}}}% +% \end{macrocode} +% Apply the selected output format for deadlines and apply +% the highlighting to the result. +% \begin{macrocode} + \expandafter\CheckListHighlightDeadline\tchklst@@args + {\tchklst@@dateoutput@use{#1}{#2}{#3}{#4}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\CheckListHighlightDeadline} +% The |\CheckListHighlightDeadline|\marg{closed?}\marg{passed?}\meta{deadline} +% macro highlights the given \meta{deadline} based on the two +% Boolean (`true' or `false') arguments \meta{done?} (whether +% the respective checklist entry has been completed) and +% \meta{passed?} (whether the deadline has passed). +% One can |\renewcommand| this macro to change the deadline +% highlighting. +% \changes{v2.0}{2018/11/13}{Show future deadlines of completed entries also in green} +% \begin{macrocode} +\newcommand\CheckListHighlightDeadline[3]{% + \ifbool{#1} + {\textcolor{green!66!black}{#3}} + {\ifbool{#2}{\textcolor{red}{#3}} + {\textcolor{black}{#3}}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tchklst@splitapply@i} +% The following auxiliary macro just swaps the first two arguments, +% \meta{text} and \meta{sep} of |\tchklst@splitapply| such that +% the now first argument \meta{sep} can be expanded more easily. % \begin{macrocode} -\def\tchklst@ifafterdots #1.#2.#3\relax{\tchklst@ifafter{#1}{#2}{#3}} +\newcommand*\tchklst@splitapply@i[2]{\tchklst@splitapply{#2}{#1}} % \end{macrocode} % \end{macro} % % \begin{macro}{\tchklst@ifafter} % The -% |\tchklst@ifafter|\marg{day}\marg{month}\marg{year}\marg{iftrue}\marg{iffalse} +% |\tchklst@ifafter|\marg{y}\marg{m}\marg{d}\marg{iftrue}\marg{iffalse} % macro performs the check whether the current date is after the date -% specified by \meta{day}, \meta{month}, and \meta{year}. If this is the +% specified by \meta{y}, \meta{m}, and \meta{d}. If this is the % case, the macro expands to \meta{iftrue}, otherwise to \meta{iffalse}. % Credits for this code go to % \url{http://tex.stackexchange.com/questions/41404/how-to-make-time-dependent-code!}. +% \changes{v2.0}{2018/11/09}{Reversed argument list} % \begin{macrocode} \newcommand*\tchklst@ifafter[3]{% \ifnum\the\year\two@digits\month\two@digits\day% - >\numexpr#3\two@digits{#2}\two@digits{#1}\relax + >\numexpr#1\two@digits{#2}\two@digits{#3}\relax \expandafter\@firstoftwo \else \expandafter\@secondoftwo @@ -1151,41 +1782,253 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\tchklst@signed} -% The |\tchklst@signed|\marg{text} macro is taken from Knuth's \TeX book -% with minor spacing modifications. See also -% \url{http://tex.stackexchange.com/a/13761}. +% \begin{macro}{\CheckListDateCompare} +% The +% |\CheckListDateCompare|\marg{date}\marg{comp}\marg{refdate}\marg{iftrue}\marg{iffalse}\marg{iffail} +% macro compares \meta{date} against \meta{refdate} using the operator +% \meta{comp}. The latter must be one of |<|, |=|, and |>|. +% If the dates fulfill the comparison, the macro expands to +% \meta{iftrue}. If the dates do not fulfill the comparison, the macro +% expands to \meta{iffalse}. Finally, if one of \meta{date} and +% \meta{refdate} are not recognized as dates, the macro expands to +% \meta{iffail}. +% \begin{macrocode} +\newcommand\CheckListDateCompare[6]{% + \bgroup + \def\do##1##2##3##4{\egroup + \tchklst@DateCompare{#1}{#2}{##1}{##2}{##3}{#4}{#5}{#6}}% + \CheckListParseDate{#3}{\do}{\egroup#6}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tchklst@DateCompare} +% The +% |\tchklst@DateCompare|\marg{date}\marg{comp}\marg{y}\marg{m}\marg{d}\marg{iftrue}\marg{iffalse}\marg{iffail} +% macro is the internal counterpart to |\CheckListDateCompare|. +% The difference is that the former expects \meta{refdate} to already be +% parsed into \meta{y}, \meta{m}, and \meta{d}. +% \begin{macrocode} +\newcommand*\tchklst@DateCompare[8]{% + \bgroup + \def\do##1##2##3##4{\egroup +% \end{macrocode} +% The actual comparsion between the dates is done via |\ifnum|. +% Here, the auxiliary macro +% |\do|\marg{year}\marg{month}\marg{day}\marg{date} gets the +% components of \meta{date} from |\CheckListParseDate|. +% \begin{macrocode} + \ifnum##1\two@digits{##2}\two@digits{##3}% + #2% + #3\two@digits{#4}\two@digits{#5}\relax + \expandafter\@firstoftwo + \else\expandafter\@secondoftwo\fi{#6}{#7}}% + \CheckListParseDate{#1}{\do}{\egroup#8}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\CheckListParseDate} +% The |\CheckListParseDate|\marg{date}\marg{cmd}\marg{fail} macro +% parses \meta{date} according to the selected date input format. +% If the parsing succeeds, the macro expands +% to \meta{cmd}\marg{year}\marg{month}\marg{day}\marg{date} (i.e., +% \meta{cmd} must take four arguments). +% Otherwise, the macro expands to \meta{fail}\marg{date} (i.e., +% \meta{fail} must take one argument). +% \begin{macrocode} +\newcommand\CheckListParseDate[3]{% + \expandafter\tchklst@splitapply@i\expandafter{\tchklst@inputdate@sep} + {#1} +% \end{macrocode} +% Dates have three components and all must be positive numbers. +% \begin{macrocode} + {3}{\tchklst@ifPositive} +% \end{macrocode} +% Before expanding to \meta{cmd}, reorder the parsed date components +% according to the ordering of the selected date input format. +% \begin{macrocode} + {\expandafter#2\tchklst@inputdate@order} + {#3} +% \end{macrocode} +% The following argument is applied to whichever of the two previous +% arguments |\tchklst@splitapply@i| expands to. +% \begin{macrocode} + {#1}} +% \end{macrocode} +% \end{macro} +% +% The following set of macros is for registering date input and date output +% formats. +% +% \begin{macro}{\tchklst@@InputDateFormats} +% \begin{macro}{\tchklst@@OutputDateFormats} +% The |\tchklst@@InputDateFormats| and |\tchklst@@OutputDateFormats| macros +% collect the list of known input date formats +% and, respectively, output date formats. +% Both are \pkgname{etoolbox} lists. +% Initially, both lists are empty. +% \begin{macrocode} +\newcommand*\tchklst@@InputDateFormats{} +\newcommand*\tchklst@@OutputDateFormats{} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tchklst@registerdateinputfmt} +% The |\tchklst@registerdateinputfmt|\marg{name}\marg{reorder}\marg{sep} +% macro registers a date input format under the given \meta{name}. +% The format uses \meta{sep} as the separator symbol between dates' components +% and uses the \meta{reorder} code to reorder the components from given +% dates to the ordering ``\meta{year}-\meta{month}-\meta{day}''. +% \begin{macrocode} +\newcommand*\tchklst@registerdateinputfmt[3]{% + \listadd\tchklst@@InputDateFormats{#1}% + \csgdef{tchklst@dateorder@#1}##1##2##3{#2}% + \csgdef{tchklst@dateformat@sep@#1}{#3}} +% \end{macrocode} +% \end{macro} +% +% The following registers some typical date input formats. +% \begin{macrocode} +\tchklst@registerdateinputfmt{d.m.y}{{#3}{#2}{#1}}{.} +\tchklst@registerdateinputfmt{m/d/y}{{#2}{#3}{#1}}{/} +\tchklst@registerdateinputfmt{y-m-d}{{#1}{#2}{#3}}{-} +% \end{macrocode} +% +% \begin{macro}{\tchklst@registerdateoutputfmt} +% The |\tchklst@registerdateoutputfmt|\marg{name}\marg{use} +% macro registers a date output format under the given \meta{name}. +% The \meta{use} code may take four parameters: +% \meta{year}, \meta{month}, \meta{day}, and \meta{deadline}. +% Hence, \meta{use} can use the original \meta{deadline} as well as +% the decomposed form into year, month, and day. +% \begin{macrocode} +\newcommand*\tchklst@registerdateoutputfmt[2]{% + \listadd\tchklst@@OutputDateFormats{#1}% + \csgdef{tchklst@dateoutput@use@#1}##1##2##3##4{#2}} +% \end{macrocode} +% \end{macro} +% +% The following registers some typical date output formats. +% \begin{macrocode} +\tchklst@registerdateoutputfmt{same}{#4} +\tchklst@registerdateoutputfmt{datetime} + {\DTMdisplaydate{#1}{#2}{#3}{-1}} +\tchklst@registerdateoutputfmt{d.m.y}{#3.#2.#1} +\tchklst@registerdateoutputfmt{m/d/y}{#2/#3/#1} +\tchklst@registerdateoutputfmt{y-m-d}{#1-#2-#3} +\tchklst@registerdateoutputfmt{d.m.}{#3.#2.} +\tchklst@registerdateoutputfmt{m/d}{#2/#3} +\tchklst@registerdateoutputfmt{m-d}{#2-#3} +% \end{macrocode} +% The following |\numexpr|s looks a bit unfamiliar but it computes the +% modulo, given that integer division rounds the result. +% \begin{macrocode} +\tchklst@registerdateoutputfmt{d.m.yy} + {#3.#2.\the\numexpr #1-100*((#1-50)/100)\relax} +\tchklst@registerdateoutputfmt{m/d/yy} + {#2/#3/\the\numexpr #1-100*((#1-50)/100)\relax} +\tchklst@registerdateoutputfmt{yy-m-d} + {\the\numexpr #1-100*((#1-50)/100)\relax-#2-#3} +% \end{macrocode} +% +% \begin{macro}{\tchklst@DateFailLax} +% \begin{macro}{\tchklst@DateFailStrict} +% The |\tchklst@DateFailStrict|\marg{date} macro displays a failure to +% parse \meta{date} in |strict-dates| mode. +% Conversely, |\tchklst@DateFailLax|\marg{date} formats a failure to +% parse \meta{date}, in non-strict mode. +% \begin{macrocode} +\newcommand\tchklst@DateFailStrict[1]{% + \PackageError{typed-checklist} + {date `#1' not understood} + {See the options `strict-dates' and `input-dates' + in the package documentation\MessageBreak + if you intend to keep the value `#1'.}} +\newcommand\tchklst@DateFailLax[1]{\textit{#1}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% The remainder of this section defines generic auxiliary macros for deadline parsing. +% +% \begin{macro}{\tchklst@splitapply} +% The +% |\tchklst@splitapply|\marg{text}\marg{sep}\marg{n}\marg{cond}\marg{cmd}\marg{fail} +% macro is a generic macro for parsing a list-like \meta{text} of fixed length \meta{n}, +% whose components satisfy \meta{cond} (a macro with one argument) and are separated +% by \meta{sep}. +% If $c_1$ to $c_n$ are the components of \meta{text}, i.e., +% if \meta{text}=$c_1$\meta{sep}$\cdots$\meta{sep}$c_n$, +% then the macro expands to \meta{cmd}\marg{$c_1$}$\cdots$\marg{$c_n$}. +% If \meta{text} has less than \meta{n} or more than \meta{n} components, or +% if at least one of the components does not satisfy \meta{cond}, +% then the macro expands to \meta{fail}. +% \begin{macrocode} +\newcommand*\tchklst@splitapply[6]{% +% \end{macrocode} +% The |\tchklst@split@@rec|\marg{k}\marg{cmd}\marg{prefix}\meta{sep}\marg{suffix}|\relax| +% macro recursively grabs \meta{prefix}es from the remaining \meta{suffix} and +% appends them to \meta{cmd}. The latter accumulates \meta{cmd} and the already +% parsed components. +% \begin{macrocode} + \def\tchklst@split@@rec##1##2##3#2##4\relax{% +% \end{macrocode} +% Check whether \meta{cond} holds for \meta{prefix} first. +% \begin{macrocode} + #4{##3} +% \end{macrocode} +% If $\meta{k}>0$, i.e., then \meta{suffix} contains the last \meta{k} components +% of \meta{text} plus a trailing \meta{sep}. +% \begin{macrocode} + {\ifnumgreater{##1}{0}% +% \end{macrocode} +% If \meta{suffix} is empty, then \meta{text} contained too few components and, hence, +% expand to \meta{fail}. Otherwise recurse. +% \begin{macrocode} + {\ifstrempty{##4} + {#6} + {\tchklst@split@@rec{##1-1}{##2{##3}}##4\relax}}% +% \end{macrocode} +% Otherwise, if $\meta{k}=0$, and \meta{suffix} is empty, then \meta{text} indeed contains +% \meta{n} components and \meta{prefix} is appended to \meta{cmd} as the last component. +% If \meta{suffix} is nonempty, expand to \meta{fail}. +% \begin{macrocode} + {\ifstrempty{##4} + {##2{##3}} + {#6}}} +% \end{macrocode} +% If \meta{cond} does not hold, expand to \meta{fail}. % \begin{macrocode} -\def\tchklst@signed #1{{% - \leavevmode\unskip\nobreak\hfil\penalty50\hskip0.25em - \hbox{}\nobreak\dotfill\hbox{#1}}} + {#6}}% + \tchklst@split@@rec{#3-1}{#5}#1#2\relax} % \end{macrocode} % \end{macro} % -% \begin{macro}{tchklst@entryID} -% We define a counter for the labels of checklist entries. We also -% determine how counter values are displayed. +% \begin{macro}{\tchklst@ifPositive} +% The |\tchklst@ifPositive|\marg{text}\marg{iftrue}\marg{iffalse} macro +% expands to \meta{iftrue} if \meta{text} is a positive number and expands to +% \meta{iffalse} otherwise (i.e., if \meta{text} is not a number or not positive). +% The code of the macro is taken from Donald Arseneau's cite package. % \begin{macrocode} -\newcounter{tchklst@entryID} -\setcounter{tchklst@entryID}{0} -\renewcommand*\thetchklst@entryID{% - \tchklst@cur@type~\protect\textsc{\roman{tchklst@entryID}}} +\newcommand*\tchklst@ifPositive[1]{% + \ifcat _\ifnum\z@<0#1_\else A\fi + \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi} % \end{macrocode} % \end{macro} % % \subsection{Default Checklist Types and States} % % We use some packages for the default symbols in the checklist. -% \changes{v1.4}{2016/03/29}{Eliminated \textsf{MnSymbol} dependency} -% \changes{v1.4}{2016/03/29}{Robustified use of \textsf{bbding} package} +% \changes{v1.4}{2016/03/29}{Eliminated \pkgname{MnSymbol} dependency} +% \changes{v1.4}{2016/03/29}{Robustified use of \pkgname{bbding} package} % \begin{macrocode} \RequirePackage{bbding} % \end{macrocode} -% The following line makes sure that the \textsf{bbding} font is +% The following line makes sure that the \pkgname{bbding} font is % actually loaded, by simply putting a particular symbol into a box and % then forgetting the box again (via the grouping). This addresses the -% case that the \textsf{bbding} symbols are used inside an |\import*| or -% |\subimport*| of the \textsf{import} package: In this case, the font +% case that the \pkgname{bbding} symbols are used inside an |\import*| or +% |\subimport*| of the \pkgname{import} package: In this case, the font % would be attempted to be loaded only inside the `import' and could % then no longer be found (producing ``No file Uding.fd''). % \begin{macrocode} @@ -1231,7 +2074,7 @@ % % \subsubsection{list} % -% We use the \textsf{marginnote} package to display deadlines in the |list| +% We use the \pkgname{marginnote} package to display deadlines in the |list| % layout. % \begin{macrocode} \RequirePackage{marginnote} @@ -1241,27 +2084,31 @@ % slightly modified vertical and horizontal spacing. % \changes{v1.1b}{2015/03/05}{Fix for more comprehensible error messages % when end of environment is forgotten} -% \changes{v1.3b}{2015/07/26}{Removed dependency on \textsf{paralist} +% \changes{v1.3b}{2015/07/26}{Removed dependency on \pkgname{paralist} % package} % \changes{v1.5}{2018/10/29}{Improve left alignment of entry text in list layout} % \changes{v1.5b}{2018/10/31}{Fix for list layout (changed to itemize)} +% \changes{v2.0}{2018/11/26}{Allow empty list-type checklists} % \begin{macrocode} -\CheckListDeclareLayout{list}{status,label,description,who,deadline,END}% - {\bgroup\topsep=\medskipamount\itemsep=0pt\itemize}% - {\enditemize\egroup} +\CheckListDeclareLayout{list}{status,label,description, + who,deadline+status,END}% + {\bgroup\topsep=\medskipamount\itemsep=0pt\itemize\@newlistfalse}% + {\global\@newlistfalse\enditemize\egroup} % \end{macrocode} % The checklist entry starts with the status symbol, which opens up a % new list item. % \begin{macrocode} \CheckListDefineFieldFormat{list}{status}% - {\item[{\normalfont\tchklst@getsymbol{#1}}]} + {\item[{\normalfont\CheckListStatusSymbol{#1}}]} % \end{macrocode} % Show the label in the reverse margin, with some nice layout. % \changes{v1.4}{2016/03/30}{Robustified label display in inner mode} % \changes{v1.5}{2018/10/29}{Raggedright for labels in case of a narrow list} % \begin{macrocode} \CheckListDefineFieldFormat{list}{label}{% - \ifstrempty{#1}{}{\ifbool{inner}% + \ifstrempty{#1}{}{% + \CheckListDefaultLabel{#1}% + \ifbool{inner}% {\mbox{\small(\ref{#1})}% \nobreak\hskip 0pt plus50pt\allowbreak \ \hskip 0pt plus-50pt\relax}% @@ -1279,19 +2126,22 @@ % \meta{options}. % \begin{macrocode} \CheckListDefineFieldFormat{list}{who}{% - \ifstrempty{#1}{\nobreak\hfill\null}{% - \tchklst@signed{\textit{(#1)}}}} + \CheckListSigned[#1]{\textit{(#1)}}} % \end{macrocode} % Show the deadline of the entry in the margin, if the |deadline| option % is given in \meta{options}. -% \textbf{FIXME:} here, the interface of the code is not very elegant, -% because the field format code uses the internal macro -% |\cmdtchklst@EntryOption@status| for obtaining the current entry's -% status. % \begin{macrocode} -\CheckListDefineFieldFormat{list}{deadline}{% +\CheckListDefineFieldFormat{list}{deadline+status}{% \ifstrempty{#1}{}{{\normalmarginpar\marginnote{% - \tchklst@DisplayDeadline{\cmdtchklst@EntryOption@status}{#1}}}}} +% \end{macrocode} +% The following |\unskip| prevents |\marginnote| from breaking an +% overfull margin text at it's very beginning, which meant that +% the margin text would vertically be placed below the actual entry +% (see also \url{https://tex.stackexchange.com/questions/117695/}). +% \changes{v1.5c}{2018/11/05}{Fix vertical placement of deadlines in narrow margins} +% \begin{macrocode} + \unskip + \CheckListDisplayDeadline{#2}{#1}}}}} % \end{macrocode} % End the display of one checklist entry. % \meta{options}. @@ -1300,33 +2150,6 @@ \parfillskip=0pt \finalhyphendemerits=0 \endgraf}} % \end{macrocode} % -% \begin{macro}{\tchklst@DisplayDeadline} -% The |\tchklst@DisplayDeadline|\marg{status}\marg{deadline} formats a -% \meta{deadline} dependent on the \meta{status} and the current date. -% \begin{macrocode} -\newcommand\tchklst@DisplayDeadline[2]{% -% \end{macrocode} -% Check which text color to use for this item if its deadline has -% already passed. -% \begin{macrocode} - \tchklst@ifsymdone{\tchklst@cur@type}{#1}% - {\def\tchklst@deadcolor{green!66!black}}% - {\def\tchklst@deadcolor{red}}% -% \end{macrocode} -% Check whether the deadline of the entry has already passed and, if so, -% set the text color to the color determined above. -% \begin{macrocode} - \tchklst@ifafterdots#2\relax% - {\textcolor{\tchklst@deadcolor}}% - {}% -% \end{macrocode} -% Show the actual deadline. Note that this may constitute the second -% parameter of the above |\textcolor|. -% \begin{macrocode} - {#2}} -% \end{macrocode} -% \end{macro} -% % \subsubsection{hidden} % % The |hidden| layout completely hides the checklist and all its @@ -1343,39 +2166,245 @@ % checklist entry. The |NC| field just inserts the column separator. % \changes{v1.4}{2016/03/30}{Added display of labels to table layout} % \changes{v1.5}{2018/10/29}{Raggedright for labels in case of narrow table display} +% \changes{v2.0}{2018/11/26}{Made ``who'' column left-aligned in table layout} % \begin{macrocode} -\RequirePackage{longtable,tabu} \CheckListDeclareLayout{table}% - {status,NC,label,description,NC,who,NC,deadline,endline}% + {newline,status,NC,label,description,NC,who,NC,deadline+status}% {% - \tabulinesep=0.5ex - \longtabu to \linewidth {|c|X|r|r|} - \hline - \bf Status & \bf Description & \bf Who & \bf Deadline\endhead\hline} - {\endlongtabu} -\CheckListDefineFieldFormat{table}{status}{\tchklst@getsymbol{#1}} + \tchklst@@begintab\hline +% \end{macrocode} +% The |\tchklst@@newline| macro ensures that the |\\\hline| is only +% produced after the first content row. Generally, |\tchklst@@newline| +% (and the |newline| field) are used at the \emph{beginning} of each row +% is due to checklist entry filters: This way of line breaking ensures +% there is no spurious empty row at the end of tables whose last +% checklist entry was filtered out. +% \begin{macrocode} + \gdef\tchklst@@newline{\\\hline\tchklst@@endhead + \gdef\tchklst@@newline{\\\hline}}% + \textbf{Status} & \textbf{Description} & + \textbf{Who} & \textbf{Deadline}} + {\tchklst@@endtab} +\CheckListDefineFieldFormat{table}{newline}{\tchklst@@newline} +\CheckListDefineFieldFormat{table}{status}{\CheckListStatusSymbol{#1}} \CheckListDefineFieldFormat{table}{label}% - {\ifstrempty{#1}{}{\mbox{\small(\ref{#1})}% + {\ifstrempty{#1}{}{% + \leavevmode\CheckListDefaultLabel{#1}% + \mbox{\small(\ref{#1})}% \nobreak\hskip 0pt plus50pt\allowbreak \ \hskip 0pt plus-50pt\relax}} \CheckListDefineFieldFormat{table}{description}{\ignorespaces #1} -\CheckListDefineFieldFormat{table}{deadline}{#1} +\CheckListDefineFieldFormat{table}{deadline+status}{% + \ifstrempty{#1}{}{\CheckListDisplayDeadline{#2}{#1}}} \CheckListDefineFieldFormat{table}{who}{#1} \CheckListDefineFieldFormat{table}{NC}{&} -\CheckListDefineFieldFormat{table}{endline}{\\\hline} % \end{macrocode} +% The following macros define the package-specific table code. +% \begin{macro}{\tchklst@inittab@tabu} +% \begin{macro}{\tchklst@begintab@tabu} +% \begin{macro}{\tchklst@endtab@tabu} +% The following three macros specify how the \pkgname{tabu} package is +% initialized (i.e., how the package is loaded) and how table +% environments are started and, respectively, ended. +% \begin{macrocode} +\newcommand\tchklst@inittab@tabu{% + \RequirePackage{longtable,tabu}} +\newcommand\tchklst@begintab@tabu{% + \tabulinesep=0.5ex\relax + \def\tchklst@@endhead{\endhead}% + \longtabu to \linewidth {|c|X|l|r|}} +\newcommand\tchklst@endtab@tabu{\tchklst@@newline\endlongtabu} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\tchklst@inittab@xltabular} +% \begin{macro}{\tchklst@begintab@xltabular} +% \begin{macro}{\tchklst@endtab@xltabular} +% The following three macros specify how the \pkgname{xltabular} package +% is initialized (i.e., how the package is loaded) and how table +% environments are started and, respectively, ended. +% \begin{macrocode} +\newcommand\tchklst@inittab@xltabular{% + \RequirePackage{array,xltabular}} +\newcommand\tchklst@begintab@xltabular{% + \setlength{\extrarowheight}{0.5ex}% + \def\tchklst@@endhead{\endhead}% +% \end{macrocode} +% The following modifies the internal end code of \pkgname{xltabular} +% such that |\endxltabular| can be the first token as required while +% there is still the horizontal line. +% \begin{macrocode} + \preto\XLT@ii@TX@endtabularx{% + \toks@\expandafter{\the\toks@\tchklst@@newline}}% + \xltabular{\linewidth}{|c|X|l|r|}} +\newcommand\tchklst@endtab@xltabular{\endxltabular} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\tchklst@inittab@tabularx} +% \begin{macro}{\tchklst@begintab@tabularx} +% \begin{macro}{\tchklst@endtab@tabularx} +% The following three macros specify how the \pkgname{tabularx} package +% is initialized (i.e., how the package is loaded) and how table +% environments are started and, respectively, ended. +% \begin{macrocode} +\newcommand\tchklst@inittab@tabularx{% + \RequirePackage{array,tabularx}} +\newcommand\tchklst@begintab@tabularx{% + \let\tchklst@@endhead\relax% + \setlength{\extrarowheight}{0.5ex}% +% \end{macrocode} +% The following is analogous to its counterpart in |xltabular|. +% \begin{macrocode} + \preto\TX@endtabularx{\toks@\expandafter{\the\toks@\tchklst@@newline}}% + \tabularx{\linewidth}{|c|X|l|r|}} +\newcommand\tchklst@endtab@tabularx{\endtabularx} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\tchklst@inittab@ltablex} +% \begin{macro}{\tchklst@begintab@ltablex} +% \begin{macro}{\tchklst@endtab@ltablex} +% The following three macros specify how the \pkgname{ltablex} package +% is initialized (i.e., how the package is loaded) and how table +% environments are started and, respectively, ended. +% \begin{macrocode} +\newcommand\tchklst@inittab@ltablex{\RequirePackage{ltablex} +% \end{macrocode} +% The following fixes a bug in \pkgname{ltablex}, see +% \url{https://tex.stackexchange.com/a/197000/132738}. +% \begin{macrocode} + \patchcmd{\TX@endtabularx} + {\end{tabularx}} + {\endtabularx\endgroup} + {} + {\PackageError{typed-checklist}{Could not apply code patch to + ltablex' package.}{}}} +\let\tchklst@begintab@ltablex=\tchklst@begintab@tabularx +\let\tchklst@endtab@ltablex=\tchklst@endtab@tabularx +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Package Options} +% +% \subsubsection{Package-Only Options} +% +% The |withAsciilist| option enables support for the +% \pkgname{asciilist} package. +% \begin{macrocode} +\define@boolkey[tchklst]{PackageOptions}[tchklst@] + {withAsciilist}[true]{} +% \end{macrocode} +% The |tablepkg| option specifies which table package is used for +% layouting checklists in the |table| layout. +% \changes{v2.0}{2018/12/24}{Package option `tablepkg' added} +% \begin{macrocode} +\define@choicekey[tchklst]{PackageOptions}{tablepkg}[\val] + {ltablex,tabu,tabularx,xltabular}{% + \letcs\tchklst@@inittab{tchklst@inittab@\val}% + \letcs\tchklst@@begintab{tchklst@begintab@\val}% + \letcs\tchklst@@endtab{tchklst@endtab@\val}% +} +% \end{macrocode} +% +% The |onecounter| option specifies whether a single counter +% shall be used for all entry labels, no matter the entry types, +% or whether one counter per entry type shall be used. +% \begin{macrocode} +\define@boolkey[tchklst]{PackageOptions}[tchklst@] + {onecounter}[true]{} +% \end{macrocode} +% +% \subsubsection{Processing Options} +% +% Set option defaults and then load the given options. +% \begin{macrocode} +\ExecuteOptionsX[tchklst]<PackageOptions,GlobalListOptions>{% + withAsciilist=false, + tablepkg=tabu, + onecounter=true, + layout=list, + input-dates=d.m.y, + output-dates=same, + strict-dates=false, +} +\ProcessOptionsX[tchklst]<PackageOptions,GlobalListOptions>\relax +\tchklst@@inittab +% \end{macrocode} +% +% \subsubsection{Labels} +% +% \changes{v2.0}{2018/11/15}{Add package option for using per-type +% entry counters} +% \begin{macro}{\CheckListDefaultLabel} +% The |\CheckListDefaultLabel|\marg{label} macro puts the given +% \meta{label} and ensures that this \meta{label} is based on +% the right checklist entry counter. +% \begin{macrocode} +\newcommand*\CheckListDefaultLabel[1]{% + \ifstrempty{#1}{} + {\ifbool{tchklst@onecounter} + {\refstepcounter{tchklst@entryID}} + {\refstepcounter{tchklst@entryID@\tchklst@cur@type}}% + \label{#1}}} +% \end{macrocode} +% \end{macro} % -% \subsection{Compatibility with Other Packages} +% \begin{macro}{\tchklst@NewEntryCounter} +% The |\tchklst@NewEntryCounter|\oarg{at}\marg{type} +% creates a new counter for checklist entries and +% defines the format for displaying counter values. +% The counter is named |tchklst@entryID|\meta{at}\meta{type}. +% \begin{macrocode} +\newcommand*\tchklst@NewEntryCounter[2][@]{% + \newcounter{tchklst@entryID#1#2}% + \setcounter{tchklst@entryID#1#2}{0}% + \ifstrempty{#2} + {\csgdef{thetchklst@entryID#1#2}{% + \tchklst@cur@type~\protect\textsc{\roman{tchklst@entryID#1#2}}}}% + {\csgdef{thetchklst@entryID#1#2}{% + #2~\protect\textsc{\roman{tchklst@entryID#1#2}}}}} +% \end{macrocode} +% \end{macro} +% +% If the package shall use a single counter for all entries +% then define the counter and how counter values are displayed +% here. +% \begin{macrocode} +\iftchklst@onecounter + \tchklst@NewEntryCounter[]{} +\else +% \end{macrocode} +% Otherwise, register the creation of a new type-specific counter +% in the hook for new checklist types. +% \begin{macrocode} + \tchklst@IntroduceTypeHook{\tchklst@NewEntryCounter[@]} +\fi +% \end{macrocode} % % \subsubsection{asciilist} % +% If the package is loaded with \pkgname{asciilist} support\ldots +% \begin{macrocode} +\iftchklst@withAsciilist +% \end{macrocode} +% +% First, we load the package. +% \begin{macrocode} +\RequirePackage{asciilist} +% \end{macrocode} +% % \begin{macro}{\tchklst@ChkListEntry} % The |\tchklst@ChkListEntry|\marg{item-macro}\marg{content} macro can be % used as a parameter to |\AsciiListEndArg| of the -% \textsf{asciilist} package in order to allow for checklist +% \pkgname{asciilist} package in order to allow for checklist % entries in an |AsciiList|. % \begin{macrocode} -\iftchklst@withAsciilist \newcommand*\tchklst@ChkListEntry[2]{% \tchklst@ChkListEntry@i{#1}#2\@undefined} % \end{macrocode} @@ -1383,15 +2412,29 @@ % have the following signatures: % \begin{itemize} % \item -% |\tchklst@CheckListEntry@i|\marg{item-macro}\marg{status+opts}\marg{entry} -% where \meta{entry} is the goal/task/... of the checklist entry. +% |\tchklst@ChkListEntry@i|\marg{item-macro}\marg{status+opts}\marg{descr} % \item -% |\tchklst@CheckListEntry@ii|\marg{item-macro}\marg{entry}\marg{status}\marg{options}. +% |\tchklst@ChkListEntry@ii|\marg{item-macro}\marg{descr}\marg{status}\marg{opts} % \end{itemize} % \begin{macrocode} \def\tchklst@ChkListEntry@ii#1#2#3[#4]#5\@undefined{#1[#4]{#3}{#2}} \def\tchklst@ChkListEntry@i#1#2:#3\@undefined{% \tchklst@ChkListEntry@ii{#1}{#3}#2[]\@undefined} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tchklst@RegisterAsciiTypeEnv} +% The |\tchklst@RegisterAsciiTypeEnv|\marg{type} registers an \pkgname{asciilist} +% environment for the given checklist \meta{type}. +% \changes{v1.3c}{2015/08/24}{Enabled use of optional arguments for +% \pkgname{asciilist} environments} +% \begin{macrocode} +\newcommand*\tchklst@RegisterAsciiTypeEnv[1]{% + \AsciiListRegisterEnv{#1List}% + {\tchklst@aux@OargAfter{\CheckList{#1}}}% + {\endCheckList}% + {\AsciiListEndArg{\tchklst@ChkListEntry{\csname #1\endcsname}}}}% +\tchklst@IntroduceTypeHook{\tchklst@RegisterAsciiTypeEnv} \fi % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/typed-checklist/typed-checklist.ins b/Master/texmf-dist/source/latex/typed-checklist/typed-checklist.ins index e083327e0ae..42e1a032e1c 100644 --- a/Master/texmf-dist/source/latex/typed-checklist/typed-checklist.ins +++ b/Master/texmf-dist/source/latex/typed-checklist/typed-checklist.ins @@ -1,5 +1,5 @@ %% -%% Copyright (C) 2013-2018 by Richard Grewe <r-g+tex@posteo.net> +%% Copyright (C) 2013-2019 by Richard Grewe <r-g+tex@posteo.net> %% %% This file may be distributed and/or modified under the conditions of %% the LaTeX Project Public License, either version 1.2 of this license @@ -17,7 +17,7 @@ \usedir{tex/latex/typed-checklist} \preamble -Copyright (C) 2013-2018 by Richard Grewe <r-g+tex@posteo.net> +Copyright (C) 2013-2019 by Richard Grewe <r-g+tex@posteo.net> This file may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.2 of this license diff --git a/Master/texmf-dist/tex/latex/typed-checklist/typed-checklist.sty b/Master/texmf-dist/tex/latex/typed-checklist/typed-checklist.sty index 374a2b64838..a29194d2476 100644 --- a/Master/texmf-dist/tex/latex/typed-checklist/typed-checklist.sty +++ b/Master/texmf-dist/tex/latex/typed-checklist/typed-checklist.sty @@ -6,7 +6,7 @@ %% %% typed-checklist.dtx (with options: `package') %% -%% Copyright (C) 2013-2018 by Richard Grewe <r-g+tex@posteo.net> +%% Copyright (C) 2013-2019 by Richard Grewe <r-g+tex@posteo.net> %% %% This file may be distributed and/or modified under the conditions of %% the LaTeX Project Public License, either version 1.2 of this license @@ -20,45 +20,58 @@ %% \NeedsTeXFormat{LaTeX2e}[1999/12/01] \ProvidesPackage{typed-checklist} - [2018/10/31 v1.5b A package for layouting checklists] + [2019/01/11 v2.0 A package for layouting checklists] \RequirePackage{xkeyval} -\define@boolkey{typed-checklist.sty}[tchklst@]{withAsciilist}{} -\ProcessOptionsX \RequirePackage{etoolbox} \RequirePackage{xcolor} -\iftchklst@withAsciilist -\RequirePackage{asciilist} -\fi -\define@cmdkey[tchklst]{ListOption}{layout}[\tchklst@defaultlayout]{} -\presetkeys[tchklst]{ListOption}{layout}{} -\newcommand*\CheckListDefaultLayout[1]{% +\define@key[tchklst]{GlobalListOptions}{layout}{% \ifinlist{#1}{\tchklst@ChecklistLayouts}{}{% \PackageError{typed-checklist}{% - Checklist layout `#1' cannot be made default: - it does not exist}{}}% - \def\tchklst@defaultlayout{#1}} -\def\tchklst@defaultlayout{list} + `#1' not a known checklist layout} + {Known layouts are:\forlistloop{ }{\tchklst@@CheckListLayouts}}}% + \def\tchklst@@layout{#1}} +\define@key[tchklst]{GlobalListOptions}{input-dates}{% + \ifinlist{#1}{\tchklst@@InputDateFormats}{}{% + \PackageError{typed-checklist}{% + `#1' not a known input date format} + {Known formats are:\forlistloop{ }{\tchklst@@InputDateFormats}}}% + \letcs\tchklst@inputdate@order{tchklst@dateorder@#1}% + \letcs\tchklst@inputdate@sep{tchklst@dateformat@sep@#1}} +\define@key[tchklst]{GlobalListOptions}{output-dates}{% + \ifinlist{#1}{\tchklst@@OutputDateFormats}{}{% + \PackageError{typed-checklist}{% + `#1' not a known output date format} + {Known formats are:\forlistloop{ }{\tchklst@@OutputDateFormats}}}% + \letcs\tchklst@@dateoutput@use{tchklst@dateoutput@use@#1}} +\define@boolkey[tchklst]{GlobalListOptions}{strict-dates}[true]{% + \ifbool{tchklst@GlobalListOptions@strict-dates} + {\let\tchklst@@faileddate=\tchklst@DateFailStrict} + {\let\tchklst@@faileddate=\tchklst@DateFailLax}} \newcommand*\CheckListAddEntryOption[2]{% - \define@cmdkey[tchklst]{EntryOption}{#1}[#2]{}% - \presetkeys[tchklst]{EntryOption}{#1}{}} + \define@cmdkey[tchklst]{Entry}{#1}[#2]{}% + \presetkeys[tchklst]{Entry}{#1}{}} \CheckListAddEntryOption{who}{} \CheckListAddEntryOption{deadline}{} \CheckListAddEntryOption{label}{} +\newcommand\CheckListSet[1]{% + \setkeys[tchklst]{GlobalListOptions}{#1}} +\newcommand*\CheckListDefaultLayout[1]{% + \CheckListSet{layout={#1}}} \newcommand*\tchklst@ChecklistTypes{} \newcommand*\CheckListAddType[2]{% \ifinlist{#1}{\tchklst@ChecklistTypes}{% \PackageError{typed-checklist}{% Checklist type `#1' already defined}{}}{} \listadd\tchklst@ChecklistTypes{#1}% - \expandafter\def\csname tchklst@ChecklistTypeSym@#1\endcsname{#2}% - \expandafter\def\csname tchklst@ChecklistStates@#1\endcsname{}% - \iftchklst@withAsciilist - \AsciiListRegisterEnv{#1List}% - {\tchklst@aux@OargAfter{\CheckList{#1}}}% - {\endCheckList}% - {\AsciiListEndArg{\tchklst@ChkListEntry{\csname #1\endcsname}}}% - \fi -} + \csdef{tchklst@ChecklistTypeSym@#1}{#2}% + \csdef{tchklst@ChecklistStates@#1}{}% + \csdef{tchklst@ChecklistFilters@#1}{}% + \def\do##1{##1{#1}}% + \dolistloop\tchklst@@addtype@hooks} +\newcommand*\tchklst@@addtype@hooks{} +\newcommand*\tchklst@IntroduceTypeHook[1]{% + \forlistloop{#1}{\tchklst@ChecklistTypes}% + \listgadd\tchklst@@addtype@hook{#1}} \newcommand\tchklst@aux@OargAfter[1]{% \@ifnextchar[{\tchklst@aux@OargAfter@i{#1}}{#1}} \long\def\tchklst@aux@OargAfter@i#1[#2]{% @@ -71,9 +84,9 @@ {Unknown checklist type `#1'} {Known types are:\forlistloop{ }{\tchklst@ChecklistTypes}}}} \newcommand*\CheckListAddStatus[4]{% - \forcsvlist% - {\tchklst@AddStatus{#2}{#3}{#4}}% - {#1}}% + \forcsvlist + {\tchklst@AddStatus{#2}{#3}{#4}}% + {#1}}% \newcommand*\tchklst@AddStatus[4]{% \tchklst@CheckType{#4}% \ifinlistcs{#1}{tchklst@ChecklistStates@#4}{% @@ -87,14 +100,15 @@ \PackageError{typed-checklist}% {Unknown #1-checklist entry status `#2'}% {Known states are:\forlistcsloop{ }{tchklst@ChecklistStates@#1}}}} -\newcommand*\tchklst@getsymbol[1]{% +\newcommand*\CheckListStatusSymbol[1]{% \tchklst@symbolcombine{\csuse{tchklst@sym@\tchklst@cur@type @#1}}% {\csuse{tchklst@ChecklistTypeSym@\tchklst@cur@type}}} \newcommand*\tchklst@symbolcombine[2]{{% \setbox0\hbox{#2}% - \rlap{\hbox to \wd0{\hss #1\hss}}\box0 }} -\newcommand*\tchklst@ifsymdone[2]{% - \csname if\csname tchklst@isclosed@#1@#2\endcsname\endcsname + \copy0\llap{\hbox to \wd0{\hss\smash{#1}\hss}}}} +\newcommand*\CheckListIfClosed[1]{% + \csname if\csname tchklst@isclosed@\tchklst@cur@type @#1\endcsname + \endcsname \expandafter\@firstoftwo \else \expandafter\@secondoftwo @@ -120,20 +134,71 @@ \dolistcsloop{tchklst@ChecklistLayoutFields@#2}% } \newcommand\CheckListDefineFieldFormat[3]{% - \long\csdef{tchklst@ChecklistFormat@#1@#2}##1{#3}} -\newcommand*\tchklst@FormattedField[1]{% - \csname tchklst@ChecklistFormat@\tchklst@cur@layout @#1\endcsname} + \tchklst@deffieldmacro{tchklst@ChecklistFormat@#1@#2}{#2}{#3}} +\newcommand\tchklst@deffieldmacro[3]{% + \begingroup + \@tempcnta=0\relax + \def\do##1{\advance\@tempcnta by 1\relax}% + \tchklst@dopsvlist{#2}% + \edef\do{\endgroup + \csundef{#1}% + \noexpand\newcommand\expandonce{\csname #1\endcsname}% + [\the\@tempcnta]{\unexpanded{#3}}}% + \do} +\newcommand\tchklst@usefieldmacro[3][\@firstofone]{% + \begingroup + \expandafter\def\expandafter\tchklst@@cmd\expandafter{% + \csname #2\endcsname}% + \def\do##1{\eappto\tchklst@@cmd{% + {\csexpandonce{cmdtchklst@Entry@##1}}}}% + \tchklst@dopsvlist{#3}% + \expandafter\def\expandafter\tchklst@@cmd\expandafter{% + \expandafter{\tchklst@@cmd}}% + \preto\tchklst@@cmd{\endgroup#1}% + \tchklst@@cmd} \newcommand*\tchklst@CheckLayout[1]{% \xifinlist{#1}{\tchklst@ChecklistLayouts}{}{% \PackageError{typed-checklist}% {Unknown checklist layout `#1'} {Known layouts are:\forlistloop{ }{\tchklst@ChecklistLayouts}}}} +\newcommand*\CheckListSetFilter[3][*]{% + \ifstrequal{#1}{*} + {\forlistloop{\tchklst@SetFilter{#2}{#3}}{\tchklst@ChecklistTypes}} + {\forcsvlist{\tchklst@SetFilter{#2}{#3}}{#1}}} +\newcommand*\tchklst@SetFilter[3]{% + \tchklst@CheckType{#3}% + \ifinlistcs{#1}{tchklst@ChecklistFilters@#3}{} + {\listcsadd{tchklst@ChecklistFilters@#3}{#1}}% + \tchklst@deffieldmacro{tchklst@CheckListFilter@#3@#1}{#1}{#2}} +\newcommand*\CheckListFilterValue[3][*]{% + \CheckListSetFilter[#1]{#2} + {\ifstrequal{##1}{#3}{}{\togglefalse{display}}}} +\newcommand*\CheckListFilterClosed[1][*]{% + \CheckListSetFilter[#1]{status} + {\CheckListIfClosed{##1}{\togglefalse{display}}{}}} +\newcommand*\CheckListFilterDeadline[4][*]{% + \bgroup + \def\do##1##2##3##4{\egroup + \CheckListSetFilter[#1]{deadline} + {\tchklst@DateCompare{####1}{#2}{##1}{##2}{##3} + {}{\togglefalse{display}} + {\ifbool{#4}{\togglefalse{display}}{}\@gobble}}} + \CheckListParseDate{#3}{\do} + {\egroup\tchklst@DateFailStrict}} +\newcommand*\CheckListFilterReset[1][*]{% + \ifstrequal{#1}{*} + {\forlistloop{\tchklst@ResetFilter}{\tchklst@ChecklistTypes}} + {\forcsvlist{\tchklst@ResetFilter}{#1}}} +\newcommand*\tchklst@ResetFilter[1]{% + \def\do##1{\csundef{tchklst@CheckListFilter@#1@##1}}% + \dolistcsloop{tchklst@ChecklistFilters@#1}% + \csdef{tchklst@ChecklistFilters@#1}{}} \newenvironment{CheckList}[2][]{% \tchklst@CheckType{#2}% - \setkeys[tchklst]{ListOption}{#1}% - \tchklst@CheckLayout{\cmdtchklst@ListOption@layout}% + \setkeys[tchklst]{GlobalListOptions}{#1}% + \tchklst@CheckLayout{\tchklst@@layout}% \edef\tchklst@cur@type{#2}% - \let\tchklst@cur@layout=\cmdtchklst@ListOption@layout% + \let\tchklst@cur@layout=\tchklst@@layout% \letcs\tchklst@cur@fields {tchklst@ChecklistLayoutFields@\tchklst@cur@layout}% \cslet{#2}{\tchklst@entry}% @@ -141,42 +206,128 @@ }{% \csname tchklst@ChecklistLayoutEnd@\tchklst@cur@layout\endcsname } -\newtoks\tchklst@entry@toks \newcommand\tchklst@entry[3][]{% + \begingroup \tchklst@CheckTypeStatus{\tchklst@cur@type}{#2}% - \setkeys[tchklst]{EntryOption}{#1}% - \ifx\cmdtchklst@EntryOption@label\empty\else - \refstepcounter{tchklst@entryID}% - \expandafter\label\expandafter{\cmdtchklst@EntryOption@label}% - \fi - \def\cmdtchklst@EntryOption@status{#2}% - \def\cmdtchklst@EntryOption@description{#3}% - \tchklst@entry@toks={}% + \setkeys[tchklst]{Entry}{#1}% + \def\cmdtchklst@Entry@status{#2}% + \def\cmdtchklst@Entry@description{#3}% + \newtoggle{display}\toggletrue{display}% \def\do##1{% - \begingroup - \edef\tchklst@doformat{\endgroup - \noexpand\tchklst@entry@toks={% - \expandonce{\the\tchklst@entry@toks}% - \noexpand\tchklst@FormattedField{##1}% - {\csexpandonce{cmdtchklst@EntryOption@##1}}}}% - \tchklst@doformat}% - \dolistloop\tchklst@cur@fields - \the\tchklst@entry@toks} -\def\tchklst@ifafterdots #1.#2.#3\relax{\tchklst@ifafter{#1}{#2}{#3}} + \tchklst@usefieldmacro + {tchklst@CheckListFilter@\tchklst@cur@type @##1}{##1}% + \iftoggle{display}{}{\listbreak}}% + \dolistcsloop{tchklst@ChecklistFilters@\tchklst@cur@type}% + \def\tchklst@@entry{\endgroup}% + \iftoggle{display}{% + \def\do##1{% + \tchklst@usefieldmacro[\appto\tchklst@@entry] + {tchklst@ChecklistFormat@\tchklst@cur@layout @##1}{##1}}% + \dolistloop\tchklst@cur@fields}{}% + \tchklst@@entry} +\DeclareListParser{\tchklst@dopsvlist}{+} +\newcommand\CheckListSigned{\@dblarg\tchklst@signed} +\newcommand\tchklst@signed[2][]{% + \ifstrempty{#1} + {\nobreak\hfill\null} + {\leavevmode\unskip\nobreak\hfil\penalty50\hskip0.25em + \hbox{}\nobreak\dotfill\hbox{#2}}} +\newcommand\CheckListDisplayDeadline[2]{% + \CheckListParseDate{#2}{\tchklst@DisplayDeadline@i} + {\tchklst@firstoftwoargs\tchklst@@faileddate} + {#1}} +\newcommand\tchklst@firstoftwoargs[3]{#1{#2}} +\newcommand\tchklst@DisplayDeadline@i[5]{% + \def\tchklst@@args{}% + \CheckListIfClosed{#5}% + {\appto\tchklst@@args{{true}}}{\appto\tchklst@@args{{false}}}% + \tchklst@ifafter{#1}{#2}{#3} + {\appto\tchklst@@args{{true}}}{\appto\tchklst@@args{{false}}}% + \expandafter\CheckListHighlightDeadline\tchklst@@args + {\tchklst@@dateoutput@use{#1}{#2}{#3}{#4}}} +\newcommand\CheckListHighlightDeadline[3]{% + \ifbool{#1} + {\textcolor{green!66!black}{#3}} + {\ifbool{#2}{\textcolor{red}{#3}} + {\textcolor{black}{#3}}}} +\newcommand*\tchklst@splitapply@i[2]{\tchklst@splitapply{#2}{#1}} \newcommand*\tchklst@ifafter[3]{% \ifnum\the\year\two@digits\month\two@digits\day% - >\numexpr#3\two@digits{#2}\two@digits{#1}\relax + >\numexpr#1\two@digits{#2}\two@digits{#3}\relax \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi} -\def\tchklst@signed #1{{% - \leavevmode\unskip\nobreak\hfil\penalty50\hskip0.25em - \hbox{}\nobreak\dotfill\hbox{#1}}} -\newcounter{tchklst@entryID} -\setcounter{tchklst@entryID}{0} -\renewcommand*\thetchklst@entryID{% - \tchklst@cur@type~\protect\textsc{\roman{tchklst@entryID}}} +\newcommand\CheckListDateCompare[6]{% + \bgroup + \def\do##1##2##3##4{\egroup + \tchklst@DateCompare{#1}{#2}{##1}{##2}{##3}{#4}{#5}{#6}}% + \CheckListParseDate{#3}{\do}{\egroup#6}} +\newcommand*\tchklst@DateCompare[8]{% + \bgroup + \def\do##1##2##3##4{\egroup + \ifnum##1\two@digits{##2}\two@digits{##3}% + #2% + #3\two@digits{#4}\two@digits{#5}\relax + \expandafter\@firstoftwo + \else\expandafter\@secondoftwo\fi{#6}{#7}}% + \CheckListParseDate{#1}{\do}{\egroup#8}} +\newcommand\CheckListParseDate[3]{% + \expandafter\tchklst@splitapply@i\expandafter{\tchklst@inputdate@sep} + {#1} + {3}{\tchklst@ifPositive} + {\expandafter#2\tchklst@inputdate@order} + {#3} + {#1}} +\newcommand*\tchklst@@InputDateFormats{} +\newcommand*\tchklst@@OutputDateFormats{} +\newcommand*\tchklst@registerdateinputfmt[3]{% + \listadd\tchklst@@InputDateFormats{#1}% + \csgdef{tchklst@dateorder@#1}##1##2##3{#2}% + \csgdef{tchklst@dateformat@sep@#1}{#3}} +\tchklst@registerdateinputfmt{d.m.y}{{#3}{#2}{#1}}{.} +\tchklst@registerdateinputfmt{m/d/y}{{#2}{#3}{#1}}{/} +\tchklst@registerdateinputfmt{y-m-d}{{#1}{#2}{#3}}{-} +\newcommand*\tchklst@registerdateoutputfmt[2]{% + \listadd\tchklst@@OutputDateFormats{#1}% + \csgdef{tchklst@dateoutput@use@#1}##1##2##3##4{#2}} +\tchklst@registerdateoutputfmt{same}{#4} +\tchklst@registerdateoutputfmt{datetime} + {\DTMdisplaydate{#1}{#2}{#3}{-1}} +\tchklst@registerdateoutputfmt{d.m.y}{#3.#2.#1} +\tchklst@registerdateoutputfmt{m/d/y}{#2/#3/#1} +\tchklst@registerdateoutputfmt{y-m-d}{#1-#2-#3} +\tchklst@registerdateoutputfmt{d.m.}{#3.#2.} +\tchklst@registerdateoutputfmt{m/d}{#2/#3} +\tchklst@registerdateoutputfmt{m-d}{#2-#3} +\tchklst@registerdateoutputfmt{d.m.yy} + {#3.#2.\the\numexpr #1-100*((#1-50)/100)\relax} +\tchklst@registerdateoutputfmt{m/d/yy} + {#2/#3/\the\numexpr #1-100*((#1-50)/100)\relax} +\tchklst@registerdateoutputfmt{yy-m-d} + {\the\numexpr #1-100*((#1-50)/100)\relax-#2-#3} +\newcommand\tchklst@DateFailStrict[1]{% + \PackageError{typed-checklist} + {date `#1' not understood} + {See the options `strict-dates' and `input-dates' + in the package documentation\MessageBreak + if you intend to keep the value `#1'.}} +\newcommand\tchklst@DateFailLax[1]{\textit{#1}} +\newcommand*\tchklst@splitapply[6]{% + \def\tchklst@split@@rec##1##2##3#2##4\relax{% + #4{##3} + {\ifnumgreater{##1}{0}% + {\ifstrempty{##4} + {#6} + {\tchklst@split@@rec{##1-1}{##2{##3}}##4\relax}}% + {\ifstrempty{##4} + {##2{##3}} + {#6}}} + {#6}}% + \tchklst@split@@rec{#3-1}{#5}#1#2\relax} +\newcommand*\tchklst@ifPositive[1]{% + \ifcat _\ifnum\z@<0#1_\else A\fi + \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi} \RequirePackage{bbding} \AtBeginDocument{{\setbox0\hbox{\Checkmark}}} \CheckListAddType{Goal}{$\bigcirc$} @@ -205,13 +356,16 @@ \CheckListAddStatus{Artifact}{available}{true}{\kern 4pt\Checkmark} \CheckListAddStatus{Artifact}{dropped}{true}{{\small$\dagger$}} \RequirePackage{marginnote} -\CheckListDeclareLayout{list}{status,label,description,who,deadline,END}% - {\bgroup\topsep=\medskipamount\itemsep=0pt\itemize}% - {\enditemize\egroup} +\CheckListDeclareLayout{list}{status,label,description, + who,deadline+status,END}% + {\bgroup\topsep=\medskipamount\itemsep=0pt\itemize\@newlistfalse}% + {\global\@newlistfalse\enditemize\egroup} \CheckListDefineFieldFormat{list}{status}% - {\item[{\normalfont\tchklst@getsymbol{#1}}]} + {\item[{\normalfont\CheckListStatusSymbol{#1}}]} \CheckListDefineFieldFormat{list}{label}{% - \ifstrempty{#1}{}{\ifbool{inner}% + \ifstrempty{#1}{}{% + \CheckListDefaultLabel{#1}% + \ifbool{inner}% {\mbox{\small(\ref{#1})}% \nobreak\hskip 0pt plus50pt\allowbreak \ \hskip 0pt plus-50pt\relax}% @@ -221,48 +375,123 @@ \CheckListDefineFieldFormat{list}{description}{% \ignorespaces #1\relax} \CheckListDefineFieldFormat{list}{who}{% - \ifstrempty{#1}{\nobreak\hfill\null}{% - \tchklst@signed{\textit{(#1)}}}} -\CheckListDefineFieldFormat{list}{deadline}{% + \CheckListSigned[#1]{\textit{(#1)}}} +\CheckListDefineFieldFormat{list}{deadline+status}{% \ifstrempty{#1}{}{{\normalmarginpar\marginnote{% - \tchklst@DisplayDeadline{\cmdtchklst@EntryOption@status}{#1}}}}} + \unskip + \CheckListDisplayDeadline{#2}{#1}}}}} \CheckListDefineFieldFormat{list}{END}{{% \parfillskip=0pt \finalhyphendemerits=0 \endgraf}} -\newcommand\tchklst@DisplayDeadline[2]{% - \tchklst@ifsymdone{\tchklst@cur@type}{#1}% - {\def\tchklst@deadcolor{green!66!black}}% - {\def\tchklst@deadcolor{red}}% - \tchklst@ifafterdots#2\relax% - {\textcolor{\tchklst@deadcolor}}% - {}% - {#2}} \CheckListDeclareLayout{hidden}{dummy}{\ignorespaces}{\ignorespaces} \CheckListDefineFieldFormat{hidden}{dummy}{\ignorespaces} -\RequirePackage{longtable,tabu} \CheckListDeclareLayout{table}% - {status,NC,label,description,NC,who,NC,deadline,endline}% + {newline,status,NC,label,description,NC,who,NC,deadline+status}% {% - \tabulinesep=0.5ex - \longtabu to \linewidth {|c|X|r|r|} - \hline - \bf Status & \bf Description & \bf Who & \bf Deadline\endhead\hline} - {\endlongtabu} -\CheckListDefineFieldFormat{table}{status}{\tchklst@getsymbol{#1}} + \tchklst@@begintab\hline + \gdef\tchklst@@newline{\\\hline\tchklst@@endhead + \gdef\tchklst@@newline{\\\hline}}% + \textbf{Status} & \textbf{Description} & + \textbf{Who} & \textbf{Deadline}} + {\tchklst@@endtab} +\CheckListDefineFieldFormat{table}{newline}{\tchklst@@newline} +\CheckListDefineFieldFormat{table}{status}{\CheckListStatusSymbol{#1}} \CheckListDefineFieldFormat{table}{label}% - {\ifstrempty{#1}{}{\mbox{\small(\ref{#1})}% + {\ifstrempty{#1}{}{% + \leavevmode\CheckListDefaultLabel{#1}% + \mbox{\small(\ref{#1})}% \nobreak\hskip 0pt plus50pt\allowbreak \ \hskip 0pt plus-50pt\relax}} \CheckListDefineFieldFormat{table}{description}{\ignorespaces #1} -\CheckListDefineFieldFormat{table}{deadline}{#1} +\CheckListDefineFieldFormat{table}{deadline+status}{% + \ifstrempty{#1}{}{\CheckListDisplayDeadline{#2}{#1}}} \CheckListDefineFieldFormat{table}{who}{#1} \CheckListDefineFieldFormat{table}{NC}{&} -\CheckListDefineFieldFormat{table}{endline}{\\\hline} +\newcommand\tchklst@inittab@tabu{% + \RequirePackage{longtable,tabu}} +\newcommand\tchklst@begintab@tabu{% + \tabulinesep=0.5ex\relax + \def\tchklst@@endhead{\endhead}% + \longtabu to \linewidth {|c|X|l|r|}} +\newcommand\tchklst@endtab@tabu{\tchklst@@newline\endlongtabu} +\newcommand\tchklst@inittab@xltabular{% + \RequirePackage{array,xltabular}} +\newcommand\tchklst@begintab@xltabular{% + \setlength{\extrarowheight}{0.5ex}% + \def\tchklst@@endhead{\endhead}% + \preto\XLT@ii@TX@endtabularx{% + \toks@\expandafter{\the\toks@\tchklst@@newline}}% + \xltabular{\linewidth}{|c|X|l|r|}} +\newcommand\tchklst@endtab@xltabular{\endxltabular} +\newcommand\tchklst@inittab@tabularx{% + \RequirePackage{array,tabularx}} +\newcommand\tchklst@begintab@tabularx{% + \let\tchklst@@endhead\relax% + \setlength{\extrarowheight}{0.5ex}% + \preto\TX@endtabularx{\toks@\expandafter{\the\toks@\tchklst@@newline}}% + \tabularx{\linewidth}{|c|X|l|r|}} +\newcommand\tchklst@endtab@tabularx{\endtabularx} +\newcommand\tchklst@inittab@ltablex{\RequirePackage{ltablex} + \patchcmd{\TX@endtabularx} + {\end{tabularx}} + {\endtabularx\endgroup} + {} + {\PackageError{typed-checklist}{Could not apply code patch to + ltablex' package.}{}}} +\let\tchklst@begintab@ltablex=\tchklst@begintab@tabularx +\let\tchklst@endtab@ltablex=\tchklst@endtab@tabularx +\define@boolkey[tchklst]{PackageOptions}[tchklst@] + {withAsciilist}[true]{} +\define@choicekey[tchklst]{PackageOptions}{tablepkg}[\val] + {ltablex,tabu,tabularx,xltabular}{% + \letcs\tchklst@@inittab{tchklst@inittab@\val}% + \letcs\tchklst@@begintab{tchklst@begintab@\val}% + \letcs\tchklst@@endtab{tchklst@endtab@\val}% +} +\define@boolkey[tchklst]{PackageOptions}[tchklst@] + {onecounter}[true]{} +\ExecuteOptionsX[tchklst]<PackageOptions,GlobalListOptions>{% + withAsciilist=false, + tablepkg=tabu, + onecounter=true, + layout=list, + input-dates=d.m.y, + output-dates=same, + strict-dates=false, +} +\ProcessOptionsX[tchklst]<PackageOptions,GlobalListOptions>\relax +\tchklst@@inittab +\newcommand*\CheckListDefaultLabel[1]{% + \ifstrempty{#1}{} + {\ifbool{tchklst@onecounter} + {\refstepcounter{tchklst@entryID}} + {\refstepcounter{tchklst@entryID@\tchklst@cur@type}}% + \label{#1}}} +\newcommand*\tchklst@NewEntryCounter[2][@]{% + \newcounter{tchklst@entryID#1#2}% + \setcounter{tchklst@entryID#1#2}{0}% + \ifstrempty{#2} + {\csgdef{thetchklst@entryID#1#2}{% + \tchklst@cur@type~\protect\textsc{\roman{tchklst@entryID#1#2}}}}% + {\csgdef{thetchklst@entryID#1#2}{% + #2~\protect\textsc{\roman{tchklst@entryID#1#2}}}}} +\iftchklst@onecounter + \tchklst@NewEntryCounter[]{} +\else + \tchklst@IntroduceTypeHook{\tchklst@NewEntryCounter[@]} +\fi \iftchklst@withAsciilist +\RequirePackage{asciilist} \newcommand*\tchklst@ChkListEntry[2]{% \tchklst@ChkListEntry@i{#1}#2\@undefined} \def\tchklst@ChkListEntry@ii#1#2#3[#4]#5\@undefined{#1[#4]{#3}{#2}} \def\tchklst@ChkListEntry@i#1#2:#3\@undefined{% \tchklst@ChkListEntry@ii{#1}{#3}#2[]\@undefined} +\newcommand*\tchklst@RegisterAsciiTypeEnv[1]{% + \AsciiListRegisterEnv{#1List}% + {\tchklst@aux@OargAfter{\CheckList{#1}}}% + {\endCheckList}% + {\AsciiListEndArg{\tchklst@ChkListEntry{\csname #1\endcsname}}}}% +\tchklst@IntroduceTypeHook{\tchklst@RegisterAsciiTypeEnv} \fi \endinput %% |