diff options
Diffstat (limited to 'texmf-dist/source/latex/cntdwn')
-rw-r--r-- | texmf-dist/source/latex/cntdwn/cntdwn.dtx | 1306 | ||||
-rw-r--r-- | texmf-dist/source/latex/cntdwn/cntdwn.ins | 65 | ||||
-rw-r--r-- | texmf-dist/source/latex/cntdwn/examples/clock_tst.tex | 56 | ||||
-rw-r--r-- | texmf-dist/source/latex/cntdwn/examples/lngcntdwn_tst.tex | 62 | ||||
-rw-r--r-- | texmf-dist/source/latex/cntdwn/examples/shrtcntdwn_tst.tex | 79 |
5 files changed, 1568 insertions, 0 deletions
diff --git a/texmf-dist/source/latex/cntdwn/cntdwn.dtx b/texmf-dist/source/latex/cntdwn/cntdwn.dtx new file mode 100644 index 00000000..acc02bac --- /dev/null +++ b/texmf-dist/source/latex/cntdwn/cntdwn.dtx @@ -0,0 +1,1306 @@ +% \iffalse +%<*copyright> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% cntdwn package, 2010-8-2 %% +%% Copyright (C) 2010 D. P. Story %% +%% dpstory@uakron.edu %% +%% %% +%% This program can redistributed and/or modified under %% +%% the terms of the LaTeX Project Public License %% +%% Distributed from CTAN archives in directory %% +%% macros/latex/base/lppl.txt; either version 1 of the %% +%% License, or (at your option) any later version. %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%</copyright> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{cntdwn} +%<package> [2014/11/26 v.6 countdown support (dps)] +%<*driver> +\documentclass{ltxdoc} +\usepackage[colorlinks,hyperindex]{hyperref} +\pdfstringdefDisableCommands{\let\\\textbackslash} +\OnlyDescription +\EnableCrossrefs +\CodelineIndex +\begin{document} + \GetFileInfo{cntdwn.sty} + \title{cntdwn: A countdown Package} + \author{D. P. Story\\ + Email: \texttt{dpstory@uakron.edu}} + \date{processed \today} + \maketitle + \tableofcontents + \let\Email\texttt + \DocInput{cntdwn.dtx} + \PrintIndex +\end{document} +%</driver> +% \fi +% +% \MakeShortVerb{|} +% +% \DoNotIndex{\def,\edef,\gdef,\xdef,\global,\long,\let} +% \DoNotIndex{\expandafter,\string,\the,\ifx,\else,\fi} +% \DoNotIndex{\csname,\endcsname,\relax,\begingroup,\endgroup} +% \DoNotIndex{\DeclareTextCommand,\DeclareTextCompositeCommand} +% \DoNotIndex{\space,\@empty,\special} +% +% \begin{macrocode} +%<*package> +% \end{macrocode} +% This is a ``countdown'' package that features a countdown field and three events. Each event +% is fired at designated points in the talk. The length of the talk is preset, it can be started, +% paused, and stopped. There is an end of talk event as well. All these things are definable by +% the document author, or the defaults can be taken. Only the length of the talk is required. +% +% We support four scenarios: +% \begin{enumerate} +% \item short countdown: less than a day. Designed for talks +% \item short stopwatch: counting up from the start (less than a day) +% \item long countdown: a countdown to an event, the event is some future date. There is an option +% that once reached, the countdown will stop, or continue as a ``countup.'' +% \item long stopwatch: count up from the starting time/date +%\end{enumerate} +% \begin{macrocode} +\RequirePackage{xkeyval} +\def\cntdwn@defaultcode{\makeatletter + \InputIfFileExists{shrtcnt.def}{}\makeatother} +\DeclareOptionX{shortcount}{% + \def\cntdwn@shrtcnt{\cntdwn@defaultcode}% +} +\let\cntdwn@shrtcnt\@empty +\DeclareOptionX{longcount}{% + \def\cntdwn@lngcnt{\makeatletter + \InputIfFileExists{lngcnt.def}{}\makeatother}% +} +\let\cntdwn@lngcnt\@empty +\ProcessOptionsX +% \end{macrocode} +% If no options are give, we assume \texttt{shortcount} and +% input \texttt{shrtcnt.def}. +% If only \texttt{longcount} is taken, then only \texttt{lngcnt.def} is input. +% If shortcnt is taken only, we input \texttt{shrtcnt.def}, and if both options +% are taken, we input \texttt{shrtcnt.def} followed by \texttt{lngcnt.def}. +% \begin{macrocode} +\ifx\cntdwn@shrtcnt\@empty + \ifx\cntdwn@lngcnt\@empty\AtEndOfPackage{\cntdwn@defaultcode}\else + \AtEndOfPackage{\cntdwn@lngcnt}\fi +\else + \AtEndOfPackage{\cntdwn@defaultcode} + \ifx\cntdwn@lngcnt\@empty\else\AtEndOfPackage{\cntdwn@lngcnt}\fi +\fi +% \end{macrocode} +% \texttt{\_oTime} is a JovaScript object that we must not let the user +% ``overwrite'' by allowing him to name a timer with the name \texttt{Time}. +% \begin{macrocode} +\@namedef{Time@timername}{Time} +% \end{macrocode} +% \cs{cntdwnlTimers} and \cs{cntdwnaTimers} hold the JavaScript timer objects created by +% \cs{setShortCntDwn}. +% \begin{macrocode} +\def\cntdwn@namegdef#1{\expandafter\gdef\csname #1\endcsname} +\def\cntdwn@namexdef#1{\expandafter\xdef\csname #1\endcsname} +\let\cntdwnlTimers\@empty +\let\cntdwnaTimers\@empty +% \end{macrocode} +% \paragraph*{Language localizations} +% \begin{macrocode} +\newcommand{\cntdwnYear}{year} +\newcommand{\cntdwnYears}{years} +\newcommand{\cntdwnDay}{day} +\newcommand{\cntdwnDays}{days} +\newcommand{\cntdwnHour}{hour} +\newcommand{\cntdwnHours}{hours} +\newcommand{\cntdwnMinute}{minute} +\newcommand{\cntdwnMinutes}{minutes} +\newcommand{\cntdwnSecond}{second} +\newcommand{\cntdwnSeconds}{seconds} +% \end{macrocode} +% The following JavaScript is common to both the \texttt{shortcount} and \texttt{longcount} options. +% \begin{macrocode} +\begin{insDLJS*}[_timerObjsLoaded]{cntdwncom} +\begin{newsegment}{CntDwn: DLJS for the cntdwn Package} +/* + Document Level JavaScript for cntdwn + D. P. Story copyright 2010 +*/ +var _timerObjsLoaded=true; +\end{newsegment} +\begin{newsegment}{CntDwn: Timer Objects} +var _oTime = new Object; + _oTime.second=1000; + _oTime.minute=60*_oTime.second; + _oTime.hour=60*_oTime.minute; + _oTime.day=24*_oTime.hour; + _oTime.year = 365*_oTime.day; +% \end{macrocode} +% The commands \cs{cntdwnlTimers} and \cs{cntdwnaTimers} expand to objects and array assignments, +% respectively. +% \begin{macrocode} +\cntdwnlTimers +var aTimers = new Array(); +\cntdwnaTimers +\end{newsegment} +\end{insDLJS*} +% \end{macrocode} +%\changes{v.6}{2014/11/26}{Replaced the names of the fields that begin with +%underscore with \cs{CDO}} +% \begin{macrocode} +\begingroup +\catcode`\_12 +\gdef\CDO{_o} +\endgroup +%</package> +%<*shortcnt> +% \end{macrocode} +% \section{Short Countdown Commands} +% We introduce several commands for creating a countdown, for displaying the countdown, +% and for controlling the countdown. +% +% \begin{macro}{\cntdwnopts} +% Sets the appearances, using \textsf{eforms}, for the interactive buttons +% \cs{cntdwnStartT}, \cs{cntdwnPauseT}, and \cs{cntdwnStopT} +% \begin{macrocode} +\newcommand{\cntdwnopts}[1]{\TU{#1}\H{N}\S{S}\BG{}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\cntdwnDisplay} +% Displays the count of the (short) countdown. +% \begin{macrocode} +\newcommand{\cntdwnDisplay}[4][]{% + \expandafter\ifnum\csname#2@autorun\endcsname=1\relax + \def\autorun@presets{% + \AA{\AAPageOpen{if (!\CDO#2.isCounting&&!\CDO#2.bNotify4) + sStartTimer(\CDO#2);}}}\else + \let\autorun@presets\@empty\fi + \textField[\Ff\FfReadOnly\Q{1}#1\presets{\autorun@presets} + ]{\CDO#2.cntdwn.TimeRemaining}{#3}{#4}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\cntdwnStartT} +% This start button does three things, pushing it starts/resumes the count, shift-clicking +% starts the count over from the beginning, when the count reaches the first notification +% time, the button turns green. +% \begin{macrocode} +\newcommand{\cntdwnStartT}[4][]{% + \pushButton[\presets{\cntdwnopts{Start}} + \A{\JS{sStartTimer(\CDO#2);}}#1]{\CDO#2.cntdwn.Notify1}{#3}{#4}} +% \end{macrocode} +% \begin{macro}{\cntdwnStart} +% This button has the same features as \cs{cntdwnStartT} except it is not the target +% of the code, that is, it \emph{does not turn green} when the first notification time is reached. +% \begin{macrocode} +\newcommand{\cntdwnStart}[4][]{% + \pushButton[\TU{Start}\A{\JS{sStartTimer(\CDO#2);}}#1 + ]{\CDO#2.cntdwn.Start}{#3}{#4}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\cntdwnPauseT} +% This pause button does two things, pushing it pauses the count +% when the count reaches the second notification +% time, the button turns yellow. +% \begin{macrocode} +\newcommand{\cntdwnPauseT}[4][]{% + \pushButton[\presets{\cntdwnopts{Pause}} + \A{\JS{sPauseTimer(\CDO#2);}}#1 + ]{\CDO#2.cntdwn.Notify2}{#3}{#4}} +% \end{macrocode} +% \begin{macro}{\cntdwnPause} +% This button has the same features as \cs{cntdwnPauseT} except it is not the target +% of the code, that is, it \emph{does not turn yellow} when the second notification time is reached. +% \begin{macrocode} +\newcommand{\cntdwnPause}[4][]{% + \pushButton[\TU{Pause}\A{\JS{sPauseTimer(\CDO#2);}}#1 + ]{\CDO#2.cntdwn.Pause}{#3}{#4}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\cntdwnStopT} +% This stop button does two things, pushing it stops the count +% and clears `End' fields. When the count reaches the third notification +% time, the button turns blinks red, and when the end of the time limit +% is reached, it turns solid red. +% \begin{macrocode} +\newcommand{\cntdwnStopT}[4][]{% + \pushButton[\presets{\cntdwnopts{Stop}} + \A{\JS{sStopTimer(\CDO#2);}}#1 + ]{\CDO#2.cntdwn.Notify3}{#3}{#4}} +% \end{macrocode} +% \begin{macro}{\cntdwnStop} +% This button has the same features as \cs{cntdwnStopT} except it is not the target +% of the code, that is, it \emph{does not turn red} when the second notification time is reached. +% \begin{macrocode} +\newcommand{\cntdwnStop}[4][]{% + \pushButton[\TU{Stop}\A{\JS{sStopTimer(\CDO#2);}}#1 + ]{\CDO#2.cntdwn.Stop}{#3}{#4}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\cntdwnEndTarget} +% The default end of time event (\texttt{EndOfTime}) sends a message to a multiline +% text field. That field can be constructed using \cs{cntdwnEndTarget} +% \begin{macrocode} +\newcommand{\cntdwnEndTarget}[4][]{% + \textField[\Ff\FfReadOnly\Ff\FfMultiline#1 + ]{\CDO#2.cntdwn.End}{#3}{#4}} +% \end{macrocode} +% \end{macro} +% \subsection{Defining a short countdown} +% \begin{macro}{\setShortCntDwn} +% Use this command to define a timer. It takes two arguments: (1) the name of the timer, +% which must be unique among all named timers; (2) key-value pairs that define the +% details of the timer. +% \begin{macrocode} +\newcommand{\setShortCntDwn}[2]{\begingroup + \@ifundefined{#1@timername}{\cntdwn@namegdef{#1@timername}{#1}}% + {\PackageError{cntdwn}{The name `#1' is already defined as a timer + variable.}{Choose a unique timer variable name, + one different from `#1'.}}% + \def\seconds{_oTime.second}\def\minutes{_oTime.minute}% + \def\hours{_oTime.hour}% + \setkeys{cntdwn}{endmsg,#2}% + \cntdwn@namexdef{#1@autorun}{\ctndwn@autorun}% +% \end{macrocode} +% An object that holds countdown data. The values in this object are +%\begin{itemize} +% \item \texttt{length} $=$ length of the countdown (countup) in minutes +% \item \texttt{notify1} $=$ time (in minutes) when the first notification is given +% \item \texttt{notify2} $=$ time (in minutes) when the second notification is given +% \item \texttt{notify3} $=$ time (in minutes) when the third notification is given +% \item \texttt{refreshrate} $=$ time (in milliseconds) to refresh (default is 1000) +% \item \texttt{event1} $=$ the value of this key is a function that is executed when the first notification point is reached +% \item \texttt{event2} $=$ the value of this key is a function that is executed when the second notification point is reached +% \item \texttt{event3} $=$ the value of this key is a function that is executed when the third notification point is reached +% \item \texttt{endEvent} $=$ the value of this key is a function that is executed when the countdown is completed +%\end{itemize} +% \begin{macrocode} + \def\r{^^J}\def\t{\space\space\space\space}% + \cntdwn@namexdef{#1TimerObject}{% +% \end{macrocode} +% We build the timer object that contains all the data for running a timer. +% \begin{macrocode} + var _o#1 = {\r\t + name: "_o#1",\r\t + length: \cntdwn@length,\r\t + timeleft: \cntdwn@length,\r\t + notify1: \cntdwn@notifyi,\r\t + notify2: \cntdwn@notifyii,\r\t + notify3: \cntdwn@notifyiii,\r\t + refreshrate: \cntdwn@refreshrate,\r\t + event1: "\cntdwn@eventi",\r\t + event2: "\cntdwn@eventii",\r\t + event3: "\cntdwn@eventiii",\r\t + endEvent: "\cntdwn@eventiv",\r\t + weStopOnEnd: \cntdwn@ifstop,\r\t + isStopwatch: \isStopwatch,\r\t + startcolor: \cntdwn@startcolor,\r\t + pausecolor: \cntdwn@pausecolor,\r\t + stopcolor: \cntdwn@stopcolor,\r\t + endMsg: "\cntdwn@endmsg",\r\t +% \end{macrocode} +% The keys above are determined by \cs{setShortCntDwn}, the ones below have constant +% initial values. +% \begin{macrocode} + bNotify1:false,\r\t + bNotify2:false,\r\t + bNotify3:false,\r\t + bNotify4:false,\r\t + isCounting:false,\r\t + bBlinkOn:false,\r\t + startTime:0,\r\t + pauseTime:0,\r\t + EndOfTime:0,\r\t + blinkTimeOut:null,\r\t + timeout:null\r + }; + }% +% \end{macrocode} +% Once the macro is defined, we add it to \cs{cntdwnlTimers}. +% \begin{macrocode} + \ifx\cntdwnlTimers\@empty + \else\g@addto@macro\cntdwnlTimers{^^J}\fi + \expandafter\g@addto@macro\expandafter\cntdwnlTimers + \expandafter{\csname#1TimerObject\endcsname}% +% \end{macrocode} +% We also create an associative array named \texttt{aTimers}, here we +% add the name of the timer to the array. +% \begin{macrocode} + \ifx\cntdwnaTimers\@empty\else\g@addto@macro\cntdwnaTimers{^^J}\fi + \g@addto@macro\cntdwnaTimers{aTimers["_o#1"]=_o#1;}% + \endgroup} +\def\thetimername#1{\csname#1@timername\endcsname} +% \end{macrocode} +% We require \cs{setShortCntDwn} to be executed only in the preamble, as this +% command updates the JavaScript code found below. +% \begin{macrocode} +\@onlypreamble\setShortCntDwn +% \end{macrocode} +% \end{macro} +% \subsubsection{Key-value Pairs for \texorpdfstring{\cs{setShortCntDwn}} +% {\textbackslash{setShortCntDwn}}} +% We define the key-value pairs for \cs{setShortCntDwn}. +%\par\medskip +% \DescribeMacro{stopwatch} Determines whether the counter counts up or down. +% The key \texttt{stopwatch} cause the counter to count up; the default is to +% countdown (\texttt{stopwatch=false}). +% \begin{macrocode} +\define@boolkey{cntdwn}{stopwatch}[true]{% + \edef\isStopwatch{\ifKV@cntdwn@stopwatch true\else false\fi}} +% \end{macrocode} +% \DescribeMacro{autorun} A boolean, if true, the counter automatically +% starts when the page is open that contains the counter display +% (\cs{cntdwnDisplay}) +% \begin{macrocode} +\define@boolkey{cntdwn}{autorun}[true]{% + \edef\ctndwn@autorun{\ifKV@cntdwn@autorun1\else0\fi}} +% \end{macrocode} +% \DescribeMacro{length} The length of the count in minutes. +% \begin{macrocode} +\define@key{cntdwn}{length}[20*\minutes]{\def\cntdwn@length{#1}} +% \end{macrocode} +% \DescribeMacro{notify1}\DescribeMacro{notify2}\DescribeMacro{notify3} +% \texttt{notify1}, \texttt{notify2}, \texttt{notify2} measured in minutes. +% When the timer countdowns, we should have \texttt{notify1>notify2>notify3}; +% when counting up, we should have \texttt{notify1<notify2<notify3}. +% \begin{macrocode} +\define@key{cntdwn}{notify1}[5*\minutes]{\def\cntdwn@notifyi{#1}} +\define@key{cntdwn}{notify2}[3*\minutes]{\def\cntdwn@notifyii{#1}} +\define@key{cntdwn}{notify3}[1*\minutes]{\def\cntdwn@notifyiii{#1}} +% \end{macrocode} +% \DescribeMacro{refreshrate} is the refresh rate of the counter, measured in +% milliseconds. The default is 1000 (1 seconds). +% \begin{macrocode} +\define@key{cntdwn}{refreshrate}[1000]{\def\cntdwn@refreshrate{#1}} +% \end{macrocode} +% \DescribeMacro{event1}\DescribeMacro{event2}\DescribeMacro{event3}\DescribeMacro{endEvent} +% When the first, second, third notifications are reached +% (\texttt{notify1}, \texttt{notify2}, and \texttt{notify3}), events +% (JavaScript functions) are executed. \textsf{Cntdwn} provides default events, +% \texttt{sDefNotify1}, \texttt{sDefNotify2}, \texttt{sDefNotify3}, and \texttt{sDefEndEvent}, +% which are defined below in the JavaScript section. +% \begin{macrocode} +% events, values are JavaScript function names +\define@key{cntdwn}{event1}[sDefNotify1]{\def\cntdwn@eventi{#1}} +\define@key{cntdwn}{event2}[sDefNotify2]{\def\cntdwn@eventii{#1}} +\define@key{cntdwn}{event3}[sDefNotify3]{\def\cntdwn@eventiii{#1}} +\define@key{cntdwn}{endEvent}[sDefEndEvent]{\def\cntdwn@eventiv{#1}} +% \end{macrocode} +% \DescribeMacro{onfinish} determines what happens to the counter when +% the time is up. This is a choice key, the permissible values are \texttt{stop} +% and \texttt{continue}. +% \begin{macrocode} +\define@choicekey{cntdwn}{onfinish}[\val\nr]{stop,continue}[stop]{% + \ifcase\nr\relax\def\cntdwn@ifstop{true}\or + \def\cntdwn@ifstop{false}\fi} +% \end{macrocode} +%\DescribeMacro{startcolor}\DescribeMacro{pausecolor}\DescribeMacro{stopcolor} +% Alert colors for countdown. The values are JavaScript colors. +% \begin{macrocode} +\define@key{cntdwn}{startcolor}[color.green]{% + \def\cntdwn@startcolor{#1}} +\define@key{cntdwn}{pausecolor}[color.yellow]{% + \def\cntdwn@pausecolor{#1}} +\define@key{cntdwn}{stopcolor}[color.red]{\def\cntdwn@stopcolor{#1}} +\newcommand{\cnddwnDefaultEndMsg}{This ends the + Presentation, any questions?} +\define@key{cntdwn}{endmsg}[\cnddwnDefaultEndMsg]{% + \def\cntdwn@endmsg{#1}} +% \end{macrocode} +% We set the default values of all timers. +% \begin{macrocode} +\setkeys{cntdwn}{stopwatch=false,onfinish,length,% + notify1,notify2,notify3,refreshrate,startcolor,pausecolor,% + stopcolor,event1,event2,event3,endEvent,autorun=false,endmsg} +% \end{macrocode} +% \begin{macrocode} +\begin{insDLJS*}[shrtcntdwn]{shrtcntdwn} +% \end{macrocode} +% \begin{macrocode} +\begin{newsegment}{CntDwn: Countdown JavaScript} +% \end{macrocode} +% \subsection{JavaScript for the short countdown} +% \DescribeEnv{shrtcntdwn} This is the function that performs the countdown. +% \begin{macrocode} +function shrtcntdwn(cTimer){ + var oTimer=aTimers[cTimer]; + var _delta,nDays,pDays,nHours,pHours,nMinutes, + pMinutes,nSeconds,pSeconds,timeValue,isEndReached; + _delta=(oTimer.isStopwatch)?new Date()% +-new Date(oTimer.startTime):new Date(oTimer.EndOfTime)-new Date(); + oTimer.timeleft=_delta; + _delta=(_delta<0)?-_delta:_delta; + this.delay=true; + nDays = Math.floor(_delta/_oTime.day); + pDays = _delta\%_oTime.day; + nHours = Math.floor(pDays/_oTime.hour); + pHours = pDays\%_oTime.hour; + nMinutes = Math.floor(pHours/_oTime.minute ); + pMinutes = pHours\%_oTime.minute; + nSeconds = Math.floor(pMinutes/_oTime.second); + pSeconds = pMinutes\%_oTime.second; +% \end{macrocode} +% Calculate the time remaining, prefixing single digit numbers with a zero +% \begin{macrocode} + timeValue=((nHours>=1)?((nHours<10)?"0":"")+nHours+":":"") + +((nMinutes<10)?"0":"")+nMinutes + +":"+((nSeconds<10)?"0":"")+nSeconds; + try { this.getField(oTimer.name% ++".cntdwn.TimeRemaining").value= timeValue; } + catch(e) {}; +% \end{macrocode} +% If the difference is negative, we've reached the end of the time period +% \begin{macrocode} + isEndReached=(oTimer.isStopwatch)?oTimer.timeleft>oTimer.length% +:oTimer.timeleft< 0; + if ( isEndReached && !oTimer.bNotify4) { + oTimer.bNotify4=true; + eval(oTimer.endEvent)(this,cTimer); + if (oTimer.weStopOnEnd) { + oTimer.isCounting=false; + try { app.clearInterval(oTimer.timeout); + oTimer.timeout=null; } catch(e){}; + } + try { app.clearInterval(oTimer.blinkTimeOut); + oTimer.blinkTimeOut=null; } catch(e){}; + this.delay=false;this.dirty=false; + if (oTimer.weStopOnEnd) return; + } +% \end{macrocode} +% If difference has reached one of our thresholds, run the notify event action +% \begin{macrocode} + if (oTimer.isStopwatch) { + if (!oTimer.bNotify1&&(_delta>oTimer.notify1)) + {oTimer.bNotify1=true;eval(oTimer.event1)(this,cTimer);} + if (!oTimer.bNotify2&&(_delta>oTimer.notify2)) + {oTimer.bNotify2=true;eval(oTimer.event2)(this,cTimer);} + if (!oTimer.bNotify3&&(_delta>oTimer.notify3)) + {oTimer.bNotify3=true;eval(oTimer.event3)(this,cTimer);} + } else { + if (!oTimer.bNotify1&&(_delta<oTimer.notify1)) + {oTimer.bNotify1=true;eval(oTimer.event1)(this,cTimer);} + if (!oTimer.bNotify2&&(_delta<oTimer.notify2)) + {oTimer.bNotify2=true;eval(oTimer.event2)(this,cTimer);} + if (!oTimer.bNotify3&&(_delta<oTimer.notify3)) + {oTimer.bNotify3=true;eval(oTimer.event3)(this,cTimer);} + } + this.delay=false;this.dirty=false; +} +% \end{macrocode} +% \DescribeEnv{sDefNotify1} The default first notification event. +% \begin{macrocode} +function sDefNotify1(doc,cTimer) { + var oTimer=aTimers[cTimer]; + var f = doc.getField(cTimer+".cntdwn.Notify1"); + if (f!=null) f.fillColor = oTimer.startcolor; + app.beep(); +} +% \end{macrocode} +% \DescribeEnv{sDefNotify2} The default second notification event. +% \begin{macrocode} +function sDefNotify2(doc,cTimer) { + var oTimer=aTimers[cTimer]; + var f = doc.getField(cTimer+".cntdwn.Notify2"); + if (f!=null) f.fillColor = oTimer.pausecolor; + app.beep(); +} +% \end{macrocode} +% \DescribeEnv{sDefNotify3} The default third notification event. +% \begin{macrocode} +function sDefNotify3(doc,cTimer) { + var oTimer=aTimers[cTimer]; + app.beep(); + var f = doc.getField(cTimer+".cntdwn.Notify3"); + if ( f!=null) + oTimer.blinkTimeOut=app.setInterval(% +"_sBlinkRed(\""+cTimer+"\")",500); +} +% \end{macrocode} +% \DescribeEnv{\_sBlinkRed} The default event \texttt{sDefNotify3} calls this function +% to blink the third notification field. +% \begin{macrocode} +function _sBlinkRed(cTimer) { + var oTimer=aTimers[cTimer]; + var f=this.getField(cTimer+".cntdwn.Notify3"); + f.fillColor = ( oTimer.bBlinkOn )?color.white:oTimer.stopcolor; + oTimer.bBlinkOn=!oTimer.bBlinkOn; + this.dirty=false; +} +% \end{macrocode} +% \DescribeEnv{sDefEndEvent} The default event of the end of the countdown. This function +% is fired when the count is completed. +% This function performs an end of countdown action, +% here we populate a field announcing the end of the countdown. An animation is +% possible here too. +% \begin{macrocode} +function sDefEndEvent(doc,cTimer) { + var oTimer=aTimers[cTimer]; + var f=doc.getField(cTimer+".cntdwn.Notify3"); + if (f!=null) f.fillColor = oTimer.stopcolor; + f=doc.getField(cTimer+".cntdwn.End"); + if (f!=null) f.value = oTimer.endMsg; +} +% \end{macrocode} +% \DescribeEnv{sPauseTimer} Pause the timer. +% \begin{macrocode} +function sPauseTimer(oTimer) { + oTimer.isCounting=false; + oTimer.pauseTime=new Date().valueOf(); + try { app.clearInterval(oTimer.timeout); + oTimer.timeout=null; } catch(e){}; +} +% \end{macrocode} +% \DescribeEnv{sStopTimer} Stop the timer. +% \begin{macrocode} +function sStopTimer(oTimer) { + oTimer.isCounting=false; + oTimer.startTime=oTimer.pauseTime=0; + oTimer.timeleft=oTimer.length; + try { app.clearInterval(oTimer.timeout); + oTimer.timeout=null; } catch(e){}; + try { app.clearInterval(oTimer.blinkTimeOut); + oTimer.blinkTimeOut=null; } catch(e){}; + try { this.getField(oTimer.name% ++".cntdwn.Notify1").fillColor = color.white; } catch(e) {} + try { this.getField(oTimer.name% ++".cntdwn.Notify2").fillColor = color.white; } catch(e) {} + try { this.getField(oTimer.name% ++".cntdwn.Notify3").fillColor = color.white; } catch(e) {} + oTimer.bNotify1=oTimer.bNotify2=oTimer.bNotify3% +=oTimer.bNotify4=false; + this.resetForm([oTimer.name]); + this.dirty=false; +} +% \end{macrocode} +% \DescribeEnv{sStartTimer} Start the timer. +% \begin{macrocode} +function sStartTimer(oTimer) { + if (oTimer.isCounting) return; + oTimer.isCounting=true; + if (oTimer.startTime == 0 || (event.shift) % +|| (oTimer.weStopOnEnd&&oTimer.bNotify4) ){ + sStopTimer(oTimer); + oTimer.startTime=new Date().valueOf(); + } + oTimer.pauseTime=(oTimer.pauseTime==0)?0:new Date()% +-new Date(oTimer.pauseTime)+oTimer.refreshrate; + oTimer.startTime+=oTimer.pauseTime; + if (oTimer.isStopwatch) + oTimer.EndOfTime=oTimer.startTime+((event.shift)?oTimer.length% +:oTimer.timeleft); + else + oTimer.EndOfTime=new Date().valueOf()% ++((event.shift)?oTimer.length:oTimer.timeleft); + oTimer.timeout=app.setInterval(% +"shrtcntdwn(\""+oTimer.name+"\")",oTimer.refreshrate); +} +\end{newsegment} +\end{insDLJS*} +%</shortcnt> +%<*lngcnt> +% \end{macrocode} +% \section{Long Countdown Commands} +% In this section, we countdown to a future event, or count-up from a previous event. These are +% long countdowns, measured in years, days, hours, minutes, and seconds. We also define a clock +% timer. +% +% \subsection{Define a long countdown} +% +% The author can optionally show the current time/date, and the target time/date. The required +% field is the one that displays the countdown. +% +% \begin{macro}{\lcntdwnDisplay} This field is the target of the countdown. It holds +% the current formatted countdown. +% \begin{macrocode} +\newcommand{\lcntdwnDisplay}[4][]{% + \let\autorun@presets\@empty + \expandafter\ifnum\csname#2@autorun\endcsname=1\relax + \edef\autorun@presets{% + \AAPageOpen{if (\CDO#2.bAutorunEnabled && \CDO#2.timeout==null) lStartTimer(\CDO#2);}}\fi + \expandafter\ifnum\csname#2@autopause\endcsname=1\relax + \edef\autorun@presets{\autorun@presets + \AAPageClose{if (\CDO#2.timeout!=null) lcntdwnPause(\CDO#2);}}\fi + \edef\autorun@presets{\noexpand\AA{\autorun@presets}}% + \textField[\Ff\FfReadOnly\textSize{0}#1 + \presets{\autorun@presets}]% + {\CDO#2.lcntdwn.timeToFromEvent}{#3}{#4}} +% \end{macrocode} +% \end{macro} +% \DescribeMacro{\lcntdwnToggle} A simple button to toggle the count off and one. +% \begin{macrocode} +\newcommand{\lcntdwnToggle}[4][]{% + \pushButton[\TU{Toggle Countdown}\A{\JS{lcntdwnToggle(\CDO#2);}}#1 + ]{\CDO#2.lcntdwn.Toggle}{#3}{#4}} +% \end{macrocode} +% \begin{macro}{\setLongCntDwn} +% Use this command to define a timer. It takes two arguments: (1) the name of the timer, +% which must be unique among all named timers; (2) key-value pairs that define the +% details of the timer. +% \begin{macrocode} +\newcommand{\setLongCntDwn}[2]{\begingroup + \@ifundefined{#1@timername}{\cntdwn@namegdef{#1@timername}{#1}}% + {\PackageError{cntdwn}{The name `#1' is already defined as a timer + variable.}{Choose a unique timer variable name, + one different from `#1'.}}% + \setkeys{lcntdwn}{date,endmsg,#2}% + \def\seconds{_oTime.second}\def\minutes{_oTime.minute}% + \def\hours{_oTime.hour}\def\days{_oTime.day}% + \def\weeks{7*_oTime.day}\def\years{_oTime.year}% + \cntdwn@namexdef{#1@autorun}{\lctndwn@autorun}% + \cntdwn@namexdef{#1@autopause}{\lctndwn@autopause}% + \ifx\lcntdwn@date\@empty\def\lcntdwn@date{1970/01/01}% + \PackageWarning{cntdwn}{!!Beware!! + The `date' key was not supplied,\MessageBreak + using the default date 1970/01/01}\fi + \def\r{^^J}\def\t{\space\space\space\space}% + \cntdwn@namexdef{#1TimerObject}{% +% \end{macrocode} +% We build the timer object that contains all the data for running a timer. +% \begin{macrocode} + var _o#1 = {\r\t + name: "_o#1",\r\t + pdfdate:"D:\lcntdwn@date\lcntdwn@time\lcntdwn@tz",\r\t + target: null,\r\t + refreshrate: 1000,\r\t + notify1: \lcntdwn@notifyi,\r\t + notify2: \lcntdwn@notifyii,\r\t + notify3: \lcntdwn@notifyiii,\r\t + notify5: \lcntdwn@notifyv,\r\t + notify6: \lcntdwn@notifyvi,\r\t + notify7: \lcntdwn@notifyvii,\r\t + eventhandler: "\lcntdwn@eventhandler",\r\t + refreshrate: \lcntdwn@refreshrate,\r\t + timedateFunc: "\lcntdwn@timedateFunc",\r\t + displayfunc: "\lcntdwn@displayfunc",\r\t + endtimecolor: \cntdwn@endtimecolor,\r\t + weStopOnEnd: \lcntdwn@ifstop,\r\t + endMsg: "\lcntdwn@endmsg",\r\t + bAutorunEnabled:\lcntdwn@autorunenabled,\r\t +% \end{macrocode} +% The keys above are determined by \cs{setLongCntDwn}, the ones below have constant +% initial values. +% \begin{macrocode} + bNotify1:false,\r\t + bNotify2:false,\r\t + bNotify3:false,\r\t + bNotify4:false,\r\t + bNotify5:false,\r\t + bNotify6:false,\r\t + bNotify7:false,\r\t + lastSignDelta:1,\r\t + timeout:null\r + }; + }% +% \end{macrocode} +% Once the macro is defined, we add it to \cs{cntdwnlTimers}. +% \begin{macrocode} + \ifx\cntdwnlTimers\@empty + \else\g@addto@macro\cntdwnlTimers{^^J}\fi + \expandafter\g@addto@macro\expandafter\cntdwnlTimers + \expandafter{\csname#1TimerObject\endcsname}% +% \end{macrocode} +% We also create an associative array named \texttt{aTimers}, here we +% add the name of the timer to the array. +% \begin{macrocode} + \ifx\cntdwnaTimers\@empty\else\g@addto@macro\cntdwnaTimers{^^J}\fi + \g@addto@macro\cntdwnaTimers{aTimers["_o#1"]=_o#1;}% + \endgroup} +% \end{macrocode} +% \subsubsection{Key-value Pairs for \texorpdfstring{\cs{setLongCntDwn}}{\textbackslash{setLongCntDwn}}} +% \end{macro} +% In the next segment, we parse the \texttt{date} value. +% \begin{macrocode} +\def\@lcntdwn@parse@YYYY#1#2#3#4{% + {\count0=#1\relax\count0=#2\relax + \count0=#3\relax\count0=#4\relax}% + \def\lcntdwn@date{#1#2#3#4}% + \@ifnextchar\@nil{\@gobbletonil}% + {\@ifnextchar/{\expandafter\@lcntdwn@parse@MM\@gobble}% + {\def\lcntdwn@date{#1#2#3#4}}}% +} +\def\@lcntdwn@parse@MM#1#2{% + {\count0=#1\relax\count0=#2\relax}% + \edef\lcntdwn@date{\lcntdwn@date#1#2}% + \@ifnextchar\@nil{\@gobbletonil}% + {\@ifnextchar/{\expandafter\@lcntdwn@parse@DD\@gobble}% + {\edef\lcntdwn@date{\lcntdwn@date#1#2}}}% +} +\def\@lcntdwn@parse@DD#1#2{% + {\count0=#1\relax\count0=#2\relax}% + \edef\lcntdwn@date{\lcntdwn@date#1#2}% + \@gobbletonil +} +% \end{macrocode} +% In the next segment, we parse the \texttt{time} value. +% \begin{macrocode} +\def\@lcntdwn@parse@HH#1#2{% + {\count0=#1\relax\count0=#2\relax}% + \def\lcntdwn@time{#1#2} + \@ifnextchar\@nil{\@gobbletonil}% + {\@ifnextchar:{\expandafter\@lcntdwn@parse@mm\@gobble}% + {\def\lcntdwn@time{#1#2}}}% +} +\def\@lcntdwn@parse@mm#1#2{% + {\count0=#1\relax\count0=#2\relax}% + \edef\lcntdwn@time{\lcntdwn@time#1#2}% + \@ifnextchar\@nil{\@gobbletonil}% + {\@ifnextchar:{\expandafter\@lcntdwn@parse@SS\@gobble}% + {\edef\lcntdwn@time{\lcntdwn@time#1#2}}}% +} +\def\@lcntdwn@parse@SS#1#2{% + {\count0=#1\relax\count0=#2\relax}% + \edef\lcntdwn@time{\lcntdwn@time#1#2}% + \@gobbletonil +} +% \end{macrocode} +% In the next segment, we parse the \texttt{timezone} value. +% \begin{macrocode} +% offset from UTC Z|[+-]HHMM +\def\tz@Z{Z}\def\tz@p{+}\def\tz@m{-} +\def\lcntdwn@parse@tz{\@ifnextchar\@nil + {\let\lcntdwn@tz\@empty}{\@lcntdwn@parse@tz}% +} +\def\@lcntdwn@parse@tz#1{% + \def\argi{#1}\ifx\argi\tz@Z + \def\lcntdwn@tz{Z}\def\@next{\@gobbletonil}% + \else\ifx\argi\tz@p\def\lcntdwn@tz{+}% + \def\@next{\tz@gethrs}\else + \ifx\argi\tz@m\def\lcntdwn@tz{-}% + \def\@next{\tz@gethrs}\else + \let\lcntdwn@tz\@empty\def\@next{\@gobbletonil}% + \fi\fi\fi\@next +} +\def\@gobbletonil#1\@nil{} +\def\tz@gethrs#1#2{{\count0=#1\relax\count0=#2\relax}% + \edef\lcntdwn@tz{\lcntdwn@tz#1#2'}% + \@ifnextchar\@nil{\@gobbletonil}{\tz@getmnts}} +\def\tz@getmnts#1#2{{\count0=#1\relax\count0=#2\relax}% + \edef\lcntdwn@tz{\lcntdwn@tz#1#2'}\@gobbletonil} +% \end{macrocode} +% \begin{macrocode} +% YYYY/MM/DD +\define@key{lcntdwn}{date}[]{% + \edef\argi{#1}\ifx\argi\@empty + \def\lcntdwn@date{}\let\@next\relax\else + \def\@next{\expandafter\@lcntdwn@parse@YYYY\argi\@nil}\fi + \@next +} +% HH:MM:SS +\define@key{lcntdwn}{time}[]{% + \edef\argi{#1}\ifx\argi\@empty + \let\lcntdwn@time\@empty\let\@next\relax\else + \def\@next{\expandafter\@lcntdwn@parse@HH\argi\@nil}\fi + \@next +} +% offset from UTC Z|[+-]HHMM +\define@key{lcntdwn}{tzoffset}[]{% + \def\argi{#1}\ifx\argi\@empty + \let\lcntdwn@tz\@empty\let\@next\relax\else + \def\@next{\lcntdwn@parse@tz#1\@nil}\fi + \@next +} +\define@boolkey{lcntdwn}{autorun}[true]{% + \edef\lctndwn@autorun{\ifKV@lcntdwn@autorun1\else0\fi}} +\define@boolkey{lcntdwn}{autopause}[true]{% + \edef\lctndwn@autopause{\ifKV@lcntdwn@autopause1\else0\fi}} +\define@boolkey{lcntdwn}{autorunenabled}[true]{% + \edef\lcntdwn@autorunenabled{\ifKV@lcntdwn@autorunenabled + true\else false\fi}} +% \end{macrocode} +% \DescribeMacro{notify1}\DescribeMacro{notify2}\DescribeMacro{notify3} +% \DescribeMacro{notify5}\DescribeMacro{notify6}\DescribeMacro{notify7} +% \texttt{notify1}, \texttt{notify2}, \texttt{notify2} are pre-event times. +% The times must satisfy the relation\texttt{notify1>notify2>notify3}. +% \texttt{notify5}, \texttt{notify6}, and \texttt{notify7} +% are post-event times, the must satisf \texttt{notify5<notify6<notify7}. +% Times are relative to the main event (time 0). +% \begin{macrocode} +\define@key{lcntdwn}{notify1}[null]{\def\lcntdwn@notifyi{#1}} +\define@key{lcntdwn}{notify2}[null]{\def\lcntdwn@notifyii{#1}} +\define@key{lcntdwn}{notify3}[null]{\def\lcntdwn@notifyiii{#1}} +\define@key{lcntdwn}{notify5}[null]{\def\lcntdwn@notifyv{#1}} +\define@key{lcntdwn}{notify6}[null]{\def\lcntdwn@notifyvi{#1}} +\define@key{lcntdwn}{notify7}[null]{\def\lcntdwn@notifyvii{#1}} +% \end{macrocode} +% \begin{environment}{eventhandler} +% The JavaScript function that handles +% the event of reaching one of the notification time values. +% \begin{macrocode} +% events, values are JavaScript function names +\define@key{lcntdwn}{eventhandler}[_NoOpt]{% + \def\lcntdwn@eventhandler{#1}} +% \end{macrocode} +% \end{environment} +% \DescribeMacro{refreshrate} is the refresh rate of the counter, measured in +% milliseconds. The default is 1000 (1 second). +% \begin{macrocode} +\define@key{lcntdwn}{refreshrate}[1000]{\def\lcntdwn@refreshrate{#1}} +% \end{macrocode} +% \DescribeMacro{currtimefunc} This keys allows a document author to define his/her +% own JS function to display the time and date. The default is to show time and +% date in separate fields. +% \begin{macrocode} +\define@key{lcntdwn}{currtimefunc}[_defaultTimeDateFunc]{% + \def\lcntdwn@timedateFunc{#1}} +% \end{macrocode} +% \DescribeMacro{displayfunc} This key allows you to define how the display the countdown. +% Use a clock timer defined by \cs{setClockTimer}, not supported by timers created by +% \cs{setLongCntDwn}. +% \begin{macrocode} +\define@key{lcntdwn}{displayfunc}[_defaultLDisplayFunc]{% + \def\lcntdwn@displayfunc{#1}} +% \end{macrocode} +% \DescribeMacro{endtimecolor} The color of the count changes when the end time value is reached. +% the default is \texttt{color.red}, use this key to change the default color. +% \begin{macrocode} +\define@key{lcntdwn}{endtimecolor}[color.red]{% + \def\cntdwn@endtimecolor{#1}} +% \end{macrocode} +% \DescribeMacro{onfinish} A choice key to determine how the timer behave when the +% end time is reached. Choices are \texttt{stop} or \texttt{continue} (the default). +% \begin{macrocode} +\define@choicekey{lcntdwn}{onfinish}[\val\nr]{stop,continue}[stop]{% + \ifcase\nr\relax\def\lcntdwn@ifstop{true}\or + \def\lcntdwn@ifstop{false}\fi} +% \end{macrocode} +% \DescribeMacro{endmsg} When \texttt{onfinish=stop} a message appears in the +% display, the default message is ``The time has expired.'' This message may be +% change locally by this key, or globally by redefining the command +% \cs{lcnddwnDefaultEndMsg}. +% \begin{macrocode} +\newcommand{\lcnddwnDefaultEndMsg}{The time has expired} +\define@key{lcntdwn}{endmsg}[\lcnddwnDefaultEndMsg]{% + \def\lcntdwn@endmsg{#1}} +% \end{macrocode} +% \paragraph*{Set the defaults for the long countdown} +% \begin{macrocode} +\setkeys{lcntdwn}{time,tzoffset,refreshrate,autorun,autopause,% + autorunenabled,notify1,notify2,notify3,notify5,notify6,notify7,% + eventhandler,endtimecolor,displayfunc,currtimefunc,% + onfinish=continue,endmsg} +% \end{macrocode} +% \subsection{Creating a clock} +% A clock is a special timer what displays the current time and date. +% Clocks defined by \cs{setClockTimer} show local time, by default, but +% can also show time/date in other time zones. +% \begin{macro}{\setClockTimer} +% Set the name and key-value pairs that describe the properties of this clock. +% \begin{macrocode} +\newcommand{\setClockTimer}[2]{\begingroup + \@ifundefined{#1@timername}{\cntdwn@namegdef{#1@timername}{#1}}% + {\PackageError{cntdwn}{The name `#1' is already defined as a timer + variable.}{Choose a unique timer variable name, + one different from `#1'.}}% + \setkeys{lcntdwn}{#2}% + \def\seconds{_oTime.second}\def\minutes{_oTime.minute}% + \def\hours{_oTime.hour}\def\days{_oTime.day}% + \def\weeks{7*_oTime.day}\def\years{_oTime.year}% + \cntdwn@namexdef{#1@autorun}{\lctndwn@autorun}% + \cntdwn@namexdef{#1@autopause}{\lctndwn@autopause}% +% \end{macrocode} +% \begin{macrocode} + \def\r{^^J}\def\t{\space\space\space\space}% + \cntdwn@namexdef{#1TimerObject}{% +% \end{macrocode} +% We build the clock timer object that contains all the data for running the clock. +% \begin{macrocode} + var _o#1 = {\r\t + name: "_o#1",\r\t + tzoffset:"\lcntdwn@tz",\r\t + refreshrate: \lcntdwn@refreshrate,\r\t + timedateFunc: "\lcntdwn@timedateFunc",\r\t + timeout:null\r + }; + }% +% \end{macrocode} +% Once the macro is defined, we add it to \cs{cntdwnlTimers}. +% \begin{macrocode} + \ifx\cntdwnlTimers\@empty + \else\g@addto@macro\cntdwnlTimers{^^J}\fi + \expandafter\g@addto@macro\expandafter\cntdwnlTimers + \expandafter{\csname#1TimerObject\endcsname}% +% \end{macrocode} +% We also create an associative array named \texttt{aTimers}, here we +% add the name of the timer to the array. +% \begin{macrocode} + \ifx\cntdwnaTimers\@empty\else\g@addto@macro\cntdwnaTimers{^^J}\fi + \g@addto@macro\cntdwnaTimers{aTimers["_o#1"]=_o#1;}% + \endgroup} +% \end{macrocode} +% \end{macro} +% \DescribeMacro{\cntdwnclocktime} The text field that displays the time. It is also +% the one that responds to the \texttt{autorun} and \texttt{autopause} options. +% \begin{macrocode} +\newcommand{\cntdwnclocktime}[4][]{% + \let\autorun@presets\@empty + \expandafter\ifnum\csname#2@autorun\endcsname=1\relax + \edef\autorun@presets{% + \AAPageOpen{if (\CDO#2.timeout==null) clStartTimer(\CDO#2);}}\fi + \expandafter\ifnum\csname#2@autopause\endcsname=1\relax + \edef\autorun@presets{\autorun@presets + \AAPageClose{if (\CDO#2.timeout!=null) clcntdwnPause(\CDO#2);}}\fi + \edef\autorun@presets{\noexpand\AA{\autorun@presets}}% + \textField[\Ff\FfReadOnly\Q{1}\textSize{0}#1 + \presets{\autorun@presets}]% + {\CDO#2.clock.time}{#3}{#4}} +% \end{macrocode} +% \DescribeMacro{\cntdwnclockdate} The text field that displays the date. This field +% is optional; both time and date may be displayed on the \cs{cntdwnclocktime} display, +% this would require a custom value for the \texttt{timedateFunc} property. +% \begin{macrocode} +\newcommand{\cntdwnclockdate}[4][]{\textField[% + \Ff\FfReadOnly\Q{1}\textSize{0}#1]{\CDO#2.clock.date}{#3}{#4}} +% \end{macrocode} +% \DescribeMacro{\clockToggle} A simple button to toggle the clock off and one. +% \begin{macrocode} +\newcommand{\clockToggle}[4][]{% + \pushButton[\TU{Toggle Countdown}\A{\JS{clockToggle(\CDO#2);}}#1 + ]{\CDO#2.lcntdwn.Toggle}{#3}{#4}} +% \end{macrocode} +% \subsection{JavaScript for long countdowns} +% \begin{macrocode} +\begin{insDLJS*}[lngcntdwn]{lngcntdwn} +\begin{newsegment}{CntDwn: Convert Time Function} +/* + This function converts the PDF Date Format to a JavaScript + Date object. The PDF Date Format is specified in section + 3.8.3 in the PDF Reference. +*/ +function pdfDate2oDate( pdfDate ) { + // if present, remove the "D:" in format + if ( pdfDate.indexOf("D:") != -1 ) + pdfDate = pdfDate.substring(2); + // now see if the O component is there + var re = /[\+\-Z]/; + var nIndex = pdfDate.search(re); + // separate the time date info from the time zone offset info + if ( nIndex != -1 ) { + var cTimeZone = pdfDate.substring(nIndex); + pdfDate = pdfDate.substring(0, nIndex); + } else cTimeZone = ""; + // seg is an array of arrays. The first element is the field width, + // the second entry is the default value. + var seg = [[4,1970],[2,1],[2,1],[2,0],[2,0],[2,0]]; + // an array to hold time arguments for the date constructor. + var args = new Array(); + // as we determine the values of the PDF Date Format, push them onto + // the args array, if not present, push the default value on. + for ( var i=0; i < seg.length; i++) { + if ( pdfDate.length > 0 ) { + args.push(Number( pdfDate.substring(0, seg[i][0]) ) ); + pdfDate = pdfDate.substring( seg[i][0] ); + } else args.push( seg[i][1] ); + } + // adjust month to base zero + args[1] = args[1] - 1; + // see if there is time zone info + var pm = ""; + if ( cTimeZone.length > 0 ) { + pm = cTimeZone.charAt(0); + var zoneOffsetHr=Number(cTimeZone.substring(1,3)); + cTimeZone=cTimeZone.substring(3); + var zoneOffsetMin=0; + if ( cTimeZone.length > 0 && cTimeZone.charAt(0) == "'" ) + var zoneOffsetMin = Number( cTimeZone.substring(1,3) ); + var totalOffset=zoneOffsetHr*60+zoneOffsetMin; + totalOffset*= 60000; + totalOffset=( pm == "-" )?-1*totalOffset:totalOffset; + var msTime=Date.UTC.apply(global,args); + msTime = msTime - totalOffset; + var d = new Date( msTime ); + } else { + var dateArgs = args.toSource().replace(/[\[\]]/g,""); + var d = eval("new Date(" + dateArgs + ")" ); + } + return d +} +\end{newsegment} +\begin{newsegment}{CntDwn: Long Countdown JavaScript} +function lngcntdwn(cTimer){ + var _delta,nYears,pYears,nDays,pDays,nHours,pHours,nMinutes, + pMinutes,nSeconds,pSeconds,f,thisSignDelta,msYear; + var oTimer=aTimers[cTimer]; + var Clock=new Date(); + this.delay=true; + _delta=oTimer.target-Clock; + var o=lCalcYears(oTimer,Clock,_delta); + nYears=o.nYears; + pYears=o.pYears; + _delta=o.delta; +% \end{macrocode} +% Having made the correct calculation for the number of years, \texttt{pYears} +% returns to us ready to calculate the number of days. +% \begin{macrocode} + nDays=Math.floor(pYears/_oTime.day); + pDays=pYears\%_oTime.day; + nHours=Math.floor(pDays/_oTime.hour); + pHours=pDays\%_oTime.hour; + nMinutes=Math.floor(pHours/_oTime.minute); + pMinutes=pHours\%_oTime.minute; + nSeconds=Math.round(pMinutes/_oTime.second); + pSeconds=pMinutes\%_oTime.second; +% \end{macrocode} +% if \texttt{\_delta = oTimer.target - Clock} is positive, event is in future +% at this time, if negative, it is in the past. +% \begin{macrocode} + f=this.getField(cTimer+".lcntdwn.timeToFromEvent"); + thisSignDelta=(_delta<0)?-1:1; + if (thisSignDelta*oTimer.lastSignDelta<0&&!oTimer.bNotify4) { + if (f!=null) f.textColor=oTimer.endtimecolor; + oTimer.bNotify4=true; + oTimer.lastSignDelta=thisSignDelta; + eval(oTimer.eventhandler)(this,cTimer,4); + if (oTimer.weStopOnEnd) { + try { app.clearInterval(oTimer.timeout); + oTimer.timeout=null; } catch(e){}; + if (f!=null) f.value=oTimer.endMsg; + return; + } + } + if (!oTimer.bNotify4&&_delta>0){ // event in future + if (!oTimer.bNotify1&&oTimer.notify1!=null% +&&_delta<oTimer.notify1) { + oTimer.bNotify1=true; + eval(oTimer.eventhandler)(this,cTimer,1); + } else { + if (!oTimer.bNotify2&&oTimer.notify2!=null% +&&_delta<oTimer.notify2) { + oTimer.bNotify2=true; + skipCheckB=true; + eval(oTimer.eventhandler)(this,cTimer,2); + } else { + if (!oTimer.bNotify3&&oTimer.notify3!=null% +&&_delta<oTimer.notify3) { + oTimer.bNotify3=true; + eval(oTimer.eventhandler)(this,cTimer,3); + } + } + } + } + if (oTimer.bNotify4&&_delta<0){// event in past + var neg_delta=-1*_delta; + if (!oTimer.bNotify5&&oTimer.notify5!=null&&% +neg_delta>oTimer.notify5) { + oTimer.bNotify5=true; + eval(oTimer.eventhandler)(this,cTimer,5); + } else { + if (!oTimer.bNotify6&&oTimer.notify6!=null&&% +neg_delta>oTimer.notify6) { + oTimer.bNotify6=true; + eval(oTimer.eventhandler)(this,cTimer,6); + } else { + if (!oTimer.bNotify7&&oTimer.notify7!=null&&% +neg_delta>oTimer.notify7) { + oTimer.bNotify7=true; + eval(oTimer.eventhandler)(this,cTimer,7); + } + } + } + } +% \end{macrocode} +% Display the current time and date, and the countdown. +% \begin{macrocode} +% eval(oTimer.timedateFunc)(Clock,cTimer); + eval(oTimer.displayfunc)(f,nYears,nDays,nHours,nMinutes,nSeconds); + this.delay=false; + this.dirty=false; +} +function _defaultTimeDateFunc(oTime,cTimer) { + try{ this.getField(cTimer+".clock.time").value% +=util.printd("H:MM:ss",oTime); } catch(e) {}; + try { this.getField(cTimer+".clock.date").value=% +util.printd("mm/dd/yyyy", oTime); } catch(e) {}; +} +function _defaultLDisplayFunc(f,nYears,nDays,nHours,nMinutes,nSeconds) { + var strYears=(nYears==0)?""% +:(""+nYears+((nYears == 1)?" \cntdwnYear, ":" \cntdwnYears, ")); + var strDays=(nDays== 0)?""% +:(""+nDays+((nDays==1)?" \cntdwnDay, ":" \cntdwnDays, ")); + var strHours=(nHours==0)?""% +:(""+nHours+((nHours==1)?" \cntdwnHour, ":" \cntdwnHours, ")); + var strMinutes=(nMinutes==0)?""% +:(""+nMinutes+((nMinutes==1)?" \cntdwnMinute, ":" \cntdwnMinutes, ")); + var strSeconds=""+nSeconds+((nSeconds<2)?" \cntdwnSecond "% +:" \cntdwnSeconds "); + var cCntDwnDisplay=strYears+strDays+strHours+strMinutes+strSeconds; + try { f.value=cCntDwnDisplay; } catch(e) {} +} +function lCalcYears(oTimer,Clock,_delta) { + var nYears,lengthOfYears,targetpdfdate,targetYear,thisYear, + otherYear,currAnnivDate,otherAnnivDate,tCurrAnnivDate, + tOtherAnnivDate,msYear=0; +% \end{macrocode} +% Get the \texttt{pdfdate} for the target event, and\dots +% \begin{macrocode} + targetpdfdate=oTimer.pdfdate; +% \end{macrocode} +% get the target year and the current year. The \texttt{otherYear} is +% the year previous to the current year, if \texttt{\_delta<0}; otherwise, +% it is the year following the current year. +% \begin{macrocode} + targetYear=Number(targetpdfdate.substring(2,6)); + thisYear=Clock.getFullYear(); + otherYear=(_delta<0)?thisYear-1:thisYear+1; +% \end{macrocode} +% Build the \texttt{pdfdate} for the anniversary date in this year, and +% for the \texttt{other\-Anniv\-Date}. +% \begin{macrocode} + currAnnivDate=targetpdfdate.substring(0,2)% ++thisYear+targetpdfdate.substring(6); + otherAnnivDate=targetpdfdate.substring(0,2)% ++otherYear+targetpdfdate.substring(6); +% \end{macrocode} +% \texttt{tCurrAnnivDate} is the anniversary date (object) of target event in the current year, +% and \texttt{tOtherAnnivDate} is either the previous anniversary date (if \texttt{\_delta<0}), +% or the next anniversary date. +% \begin{macrocode} + tCurrAnnivDate=pdfDate2oDate( currAnnivDate ); + tOtherAnnivDate=pdfDate2oDate( otherAnnivDate ); + if (_delta<0) { + if ( Clock < tCurrAnnivDate ){ +% \end{macrocode} +% If we have not reached the anniversary date in the current year, the the number +% of years that have passed since the target event is based on the date of the target +% event, and the previous anniversary date of the event. +% \begin{macrocode} + nYears=otherYear-targetYear; + lengthOfYears=oTimer.target-tOtherAnnivDate; +% \end{macrocode} +% We have reached the anniversary date in the current date. \texttt{nYears} +% is based on the current year and the year of the target vent. +% \begin{macrocode} + } else { + nYears=thisYear-targetYear; + lengthOfYears=oTimer.target-tCurrAnnivDate; + } + } else {// _delta>=0 + if ( Clock > tCurrAnnivDate ) { +% \end{macrocode} +% We have passed the most recent anniversary in this year, so number of years +% between the current date and the target event (which is in the future) is based +% on the \texttt{otherYear} (the next anniversary date) and the target year. +% \begin{macrocode} + nYears=targetYear-otherYear; + lengthOfYears=oTimer.target-tOtherAnnivDate; + } else { +% \end{macrocode} +% We have not passed the anniversary in this year, so number of years +% between the current date and the target event (which is in the future) is based +% on the \texttt{thisYear} and the target year. +% \begin{macrocode} + nYears=targetYear-thisYear; + lengthOfYears=oTimer.target-tCurrAnnivDate; + } + } +% \end{macrocode} +% Now we subtract out the number of years (in milliseconds) from the difference +% in time between the event and the current time. +% \begin{macrocode} + _delta-=lengthOfYears; + pYears=Math.abs(_delta); + return { + nYears:nYears, + pYears:pYears, + delta:_delta + }; +} +function lStartTimer(oTimer) { + var cTimer=oTimer.name; + oTimer.target=pdfDate2oDate(oTimer.pdfdate).getTime(); + var bWasNotified=oTimer.bNotify4; + var _delta=oTimer.target-new Date(); + oTimer.lastSignDelta=(_delta<0)?-1:1; + if ( _delta > 0 ) { + oTimer.bNotify1=(_delta<oTimer.notify1); + oTimer.bNotify2=(_delta<oTimer.notify2); + oTimer.bNotify3=(_delta<oTimer.notify3); + } else { + oTimer.bNotify4=true; + oTimer.bNotify5=(-1*_delta>oTimer.notify5); + oTimer.bNotify6=(-1*_delta>oTimer.notify6); + oTimer.bNotify7=(-1*_delta>oTimer.notify7); + } +% \end{macrocode} +% On start up, if the target event has not been notified, we fire up +% the main event. +% \begin{macrocode} + if (!bWasNotified&&oTimer.bNotify4) { + var f=this.getField(cTimer+".lcntdwn.timeToFromEvent"); + if (f!=null) f.textColor=oTimer.endtimecolor; + eval(oTimer.eventhandler)(this,cTimer,4); + } +% \end{macrocode} +% If we start the timer and we have already passed the main event, and we +% are to stop on end, we put in the final message, and do not start the counter. +% \begin{macrocode} + if (_delta<0&&oTimer.weStopOnEnd) { + f.value=oTimer.endMsg; + return; + } + oTimer.timeout=app.setInterval(% +"lngcntdwn(\""+cTimer+"\")",oTimer.refreshrate); +} +function lcntdwnPause(oTimer) { + try { app.clearInterval(oTimer.timeout); + oTimer.timeout=null; } catch(e){}; +} +function lcntdwnToggle(oTimer) { + if (oTimer.timeout==null) // stopped or paused + lStartTimer(oTimer); + else + lcntdwnPause(oTimer); +} +function _NoOpt(doc,cTimer,nEvent){} +% \end{macrocode} +% \subsection{JavaScript to control a clock} +% Controls for the clock +% \begin{macrocode} +function lngClockHandler(cTimer) { + var oTimer=aTimers[cTimer]; + var Clock = new Date(); + if ( oTimer.tzoffset != "" ) { + var localTime = Clock.getTime(); + var localOffset = Clock.getTimezoneOffset()*60000; + // obtain UTC time in msec + var utc = localTime + localOffset; + var tzoffset=(oTimer.tzoffset=="Z")?0:oTimer.tzoffset; + var nonlocal=utc+oTimer.tzoffset; + Clock = new Date(nonlocal); + } + this.delay=true; + eval(oTimer.timedateFunc)(Clock,cTimer); + this.dirty=false; + this.delay=false; +} +function clStartTimer(oTimer) { + var tzoffset=oTimer.tzoffset; + if ( tzoffset !="" && tzoffset !="Z" ) { + var sign=tzoffset.charAt(0); + offset=tzoffset.substring(1); + var a=tzoffset.split("'"); + var hrs=Number(a[0]); + var mins=Number(a[1]); + tzoffset=hrs*3600000+mins*60000; + tzoffset=((sign=="+")?1:-1)*tzoffset; + oTimer.tzoffset=tzoffset; + } + var cTimer=oTimer.name; + oTimer.timeout=app.setInterval(% +"lngClockHandler(\""+cTimer+"\")",oTimer.refreshrate); +} +function clockToggle(oTimer) { + if (oTimer.timeout==null) // stopped or paused + clStartTimer(oTimer); + else + lcntdwnPause(oTimer); +} +\end{newsegment} +\end{insDLJS*} +% \end{macrocode} +% \begin{macrocode} +%</lngcnt> +%<*package> +%</package> +% \end{macrocode} +% \Finale +\endinput diff --git a/texmf-dist/source/latex/cntdwn/cntdwn.ins b/texmf-dist/source/latex/cntdwn/cntdwn.ins new file mode 100644 index 00000000..27fe75d6 --- /dev/null +++ b/texmf-dist/source/latex/cntdwn/cntdwn.ins @@ -0,0 +1,65 @@ +%% +%% This file will generate fast loadable files and documentation +%% driver files from the doc files in this package when run through +%% LaTeX or TeX. +%% +%% Copyright 1999-2006 D. P. Story +%% +%% This file is part of the `AcroTeX eDucation Bundle'. +%% ------------------------------------------- +%% +%% It may be distributed under the conditions of the LaTeX Project Public +%% License, either version 1.2 of this license or (at your option) any +%% later version. The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.2 or later is part of all distributions of LaTeX +%% version 1999/12/01 or later. +%% +%% --------------- start of docstrip commands ------------------ +%% +\def\filedate{2010/08/02} +\def\batchfile{cntdwn.ins} +% +% If you can assume that the target audience for the document all have +% Acrobat Reader 5.0 or later, then chance the following switch to true, +% else, leave it as false. + +\input docstrip +\ifx\generate\undefined + \Msg{**********************************************} + \Msg{*} + \Msg{* This installation requires docstrip} + \Msg{* version 2.4 or later.} + \Msg{*} + \Msg{* An older version of docstrip has been input} + \Msg{*} + \Msg{**********************************************} + \errhelp{Move or rename old docstrip.tex and get a newer one.} + \errmessage{Old docstrip in input path} + \batchmode + \csname @@end\endcsname\end +\fi + +\keepsilent +\askforoverwritefalse +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\preamble +\endpreamble + +\generate{% + \file{cntdwn.sty}{\from{cntdwn.dtx}{copyright,package}} + \file{shrtcnt.def}{\from{cntdwn.dtx}{copyright,shortcnt}} + \file{lngcnt.def}{\from{cntdwn.dtx}{copyright,lngcnt}} +} + +\Msg{***************************************************************} +\Msg{*} +\Msg{* \space To finish the installation you have to copy the files } +\Msg{*} +\Msg{* \space *.sty, *.cfg and *.def into a directory searched by TeX} +\Msg{*} +\Msg{***************************************************************} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\endinput diff --git a/texmf-dist/source/latex/cntdwn/examples/clock_tst.tex b/texmf-dist/source/latex/cntdwn/examples/clock_tst.tex new file mode 100644 index 00000000..ee2b4f8a --- /dev/null +++ b/texmf-dist/source/latex/cntdwn/examples/clock_tst.tex @@ -0,0 +1,56 @@ +\documentclass{article} +\usepackage[designvi,usesf,tight]{web} +\usepackage{eforms} +\usepackage[longcount]{cntdwn} + +\title{The \texttt{cntdwn} Package + \texorpdfstring{\\[6pt]}{: }Clock Timers} +\author{D. P. Story} +\subject{Demo file illustrating clocks, local and foreign time zones} +\keywords{AeB, AcroTeX, clocks, countdown, cntdwn package} + +\university{Acro\negthinspace\TeX.Net} +\email{dpstory@acrotex.net} +\version{1.0} +\copyrightyears{2010} +\revisionLabel{} + +\setClockTimer{LocalClock}{} +\setClockTimer{CESTClock}{tzoffset=+0200} % this is summer time, CET is +0100 + +\parskip6pt\parindent0pt + +\begin{document} + +\maketitle + +The clocks below show local time and date (the time/date your computer +shows), and the time and date of Central Europe during the summer (CEST), the +time when this demo file was originally created. + +\begin{tabular}{rcc} +Local Time: &% +\cntdwnclocktime{LocalClock}{1in}{11bp}&% +\cntdwnclockdate{LocalClock}{1in}{11bp}\\[3bp] +CEST: &% +\cntdwnclocktime{CESTClock}{1in}{11bp}&% +\cntdwnclockdate{CESTClock}{1in}{11bp}% +\end{tabular} + +In the preamble we have +\begin{verbatim} +\setClockTimer{LocalClock}{} +\setClockTimer{CESTClock}{tzoffset=+0200} +\end{verbatim} +and in the body of the document we have +\begin{verbatim} +\begin{tabular}{rcc} +Local Time: &\cntdwnclocktime{LocalClock}{1in}{11bp}&% +\cntdwnclockdate{LocalClock}{1in}{11bp}\\[3bp] +CEST: &\cntdwnclocktime{CESTClock}{1in}{11bp}&% +\cntdwnclockdate{CESTClock}{1in}{11bp}% +\end{tabular} +\end{verbatim} +These commands are available through the \texttt{longcount} option of the \texttt{cntdwn} +package. +\end{document} diff --git a/texmf-dist/source/latex/cntdwn/examples/lngcntdwn_tst.tex b/texmf-dist/source/latex/cntdwn/examples/lngcntdwn_tst.tex new file mode 100644 index 00000000..e4b0ae7d --- /dev/null +++ b/texmf-dist/source/latex/cntdwn/examples/lngcntdwn_tst.tex @@ -0,0 +1,62 @@ +\documentclass{article} +\usepackage[designi,usesf]{web} +\usepackage{eforms} +\usepackage[longcount]{cntdwn} + +\title{The \texttt{cntdwn} Package + \texorpdfstring{\\[6pt]}{: }Long Countdown} +\author{D. P. Story} +\subject{Demo file illustrating the long countdown of the cntdwn package} +\keywords{AeB, AcroTeX, clocks, countdown, cntdwn package} + +\university{Acro\negthinspace\TeX.Net} +\email{dpstory@acrotex.net} +\version{1.0} +\copyrightyears{2010} +\revisionLabel{} + +\thispagestyle{empty} +\parindent0pt\parskip6pt + + +\setLongCntDwn{NewYearsLocal} +{% + date=2015/01/01, + time=00:01:00, + endmsg=Happy New Year from wherever I currently am!, + onfinish=stop +} +\setLongCntDwn{NewYearsCET} +{% + date=2015/01/01, + time=00:01:00, + tzoffset=+0100, + endmsg=Happy New Year from wherever central Europe!, + onfinish=stop +} + + +\begin{document} + +\maketitle + +The long countdown shows the time remaining to an event in the (usually +distant) future. + +\begin{tabular}{rc} +\multicolumn{2}{c}{Time to New Years Day}\\[3bp] +Local:&\lcntdwnDisplay{NewYearsLocal}{2.5in}{11bp}\\[3bp] +CET:&\lcntdwnDisplay{NewYearsCET}{2.5in}{11bp} +\end{tabular} + +In central Europe, the two countdowns should read the same, in the U.S., +they may differ by at least 5 hours. + +When the count has reached 0 seconds, a message appears in the text field +wishing you a Happy New Year, from Acro\negthinspace\TeX. I hope you stay +up until 1 second after midnight to see the message. Then, you can set +the dates to \texttt{2016/01/01} for me, now there's a good fellow. + +This code is available through the \texttt{longcount} option of the \texttt{cntdwn} package. + +\end{document} diff --git a/texmf-dist/source/latex/cntdwn/examples/shrtcntdwn_tst.tex b/texmf-dist/source/latex/cntdwn/examples/shrtcntdwn_tst.tex new file mode 100644 index 00000000..4ebf62ac --- /dev/null +++ b/texmf-dist/source/latex/cntdwn/examples/shrtcntdwn_tst.tex @@ -0,0 +1,79 @@ +\documentclass{article} +\usepackage[designi,usesf]{web} +\usepackage{eforms} +\usepackage{cntdwn} + +\title{The \texttt{cntdwn} Package + \texorpdfstring{\\[6pt]}{: }Short Countdown} +\author{D. P. Story} +\subject{Demo file illustrating the short countdown of the cntdwn package} +\keywords{AeB, AcroTeX, clocks, countdown, cntdwn package} + +\university{Acro\negthinspace\TeX.Net} +\email{dpstory@acrotex.net} +\version{1.0} +\copyrightyears{2010} +\revisionLabel{} + +\thispagestyle{empty} +\parindent0pt\parskip6pt + +\setShortCntDwn{CntDwnTimer} +{% + autorun, + length=1*\minutes, + notify1=45*\seconds, + notify2=30*\seconds, + notify3=15*\seconds +} +\setShortCntDwn{CntUpTimer} +{% + stopwatch, + length=1*\minutes, + notify1=15*\seconds, + notify2=30*\seconds, + notify3=45*\seconds, + endmsg=Thank you for trying the cntdwn package from AcroTeX!, + onfinish=continue, +} +\begin{document} + +\maketitle + + +Counting down: Length 1 minute, \texttt{notify1} at 45 seconds, \texttt{notify2} at 30 +seconds, and \texttt{notify3} at 15 seconds. + +Time Remaining: +\cntdwnDisplay{CntDwnTimer}{.5in}{11bp} +\cntdwnStartT{CntDwnTimer}{11bp}{11bp} +\cntdwnPauseT{CntDwnTimer}{11bp}{11bp} +\cntdwnStopT{CntDwnTimer}{11bp}{11bp} + +\begin{center} +\cntdwnEndTarget[\BC{}\textSize{20}\textColor{blue}\Q{1}]{CntDwnTimer}{.67\linewidth}{1in} +\end{center} + +\newpage + +Counting up: Length 1 minute, \texttt{notify1} at 15 seconds, \texttt{notify2} at 30 +seconds, and \texttt{notify3} at 45 seconds. This counter set to start +manually, press the Start button (second from left). + +Time Remaining: +\cntdwnDisplay{CntUpTimer}{.5in}{11bp} +\cntdwnStartT{CntUpTimer}{11bp}{11bp} +\cntdwnPauseT{CntUpTimer}{11bp}{11bp} +\cntdwnStopT{CntUpTimer}{11bp}{11bp} + +You can optionally have explicit buttons instead of, or in addition to, the +three right most buttons: +\cntdwnStart[\CA{Start}\textSize{7}]{CntUpTimer}{}{9bp} +\cntdwnPause[\CA{Pause}\textSize{7}]{CntUpTimer}{}{9bp} +\cntdwnStop[\CA{Stop}\textSize{7}]{CntUpTimer}{}{9bp} + +\begin{center} +\cntdwnEndTarget[\BC{}\textSize{20}\textColor{blue}\Q{1}]{CntUpTimer}{.67\linewidth}{1in} +\end{center} + +\end{document} |