Changeset 8005


Ignore:
Timestamp:
07/02/10 11:11:49 (23 months ago)
Author:
CrawfordCurrie
Message:

Foswiki:Tasks.Item8548: split the plugin into a load-on-demand core module, and changed it to use a registered tag handler. Made it NO_PREFS_IN_TOPIC. Both changes for performance reasons. Changed the load method to expand includes in the same way as CalendarPlugin does (it would be good to share some code here). Foswiki:Tasks.Item1491: hacked/worked around problem with EditTablePlugin by enabling the recursion block in that plugin. Tested for compatibility with CalDAVPlugin.

Location:
trunk/HolidaylistPlugin
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/HolidaylistPlugin/data/System/HolidaylistPlugin.txt

    r5607 r8005  
    1 %META:TOPICINFO{author="ProjectContributor" date="1181041089" format="1.0" version="$Rev: 18212 $"}% 
    21<!-- 
    32This topic is part of the documentation for HolidaylistPlugin and is 
     
    87http://develop.twiki.org/~twiki4/cgi-bin/view/Bugs/HolidaylistPlugin 
    98--> 
    10  
    11 ---+!! <nop>HolidaylistPlugin</nop> 
    12  
    13 The !HolidaylistPlugin handles the tag %<nop>HOLIDAYLIST</nop>% that inserts a vacation list on the current page. Smilies are used to indicate if a person is in work or on holiday.  
    14  
    15 The plugin creates a table filled with Smilies and today's date will be the first column. There is a row in the table for each person and each day is flagged as either: :mad: (in work), :ok: (a day off) or 8-) (absent for some time), :-I (not at work; used if you type a location). You can also use other smilies (like :skull:). 
     9<!-- 
     10    * Set SHORTDESCRIPTION = %$SHORTDESCRIPTION% 
     11--> 
     12 
     13---+!! %TOPIC% 
     14 
     15%SHORTDESCRIPTION% 
     16 
     17The !%TOPIC% handles the %<nop>HOLIDAYLIST</nop>% macro to inserts a vacation list on the current page. Smilies are used to indicate if a person is in work or on holiday.  
     18 
     19The plugin creates a table filled with Smilies where today's date will be the first column. There is a row in the table for each person and each day is flagged as either: :mad: (in work), :ok: (a day off) or 8-) (absent for some time), :-I (not at work; used if you type a location). You can also use other smilies (like :skull:). 
    1620 
    1721*Example (image):* 
     
    2024</div> 
    2125 
     26__WARNING__ As of version 1.031 of the plugin, it no longer supports 
     27preferences set in this topic. If you have locally customised preferences 
     28this way, you will need to move those preference settings into 
     29%USERSWEB%.SitePreferences, remembering to put =HOLIDAYLISTPLUGIN_= 
     30before the preference names (see the examples below). 
     31 
    2232%TOC% 
    2333 
     
    6474---++ Syntax 
    6575The syntax follows that of the !CalendarPlugin. See Foswiki:Extensions.CalendarPlugin for more details. 
    66  
    67  
    6876 
    6977| *Entry type* | *Syntax* | *Example* | 
     
    8492| Public Holidays | just type '@all' in the name field | ==&nbsp;* 25 Dec 2005 - Christmas Day @all== |  
    8593 
    86  
    8794*Notes and hints:* 
    8895        * At least one space character have to stay before and after a seperator ('-'). This allows you to use a '-' in names, locations or icons, e.g. if you have a composite name like Eva-Maria. 
     
    107114</verbatim> 
    108115 
     116You can also use the Foswiki:Extensions.CalDAVPlugin to recover calendars from 
     117a !CalDAV server. 
     118 
    109119#AttriButes 
    110120---++ Attributes 
     
    112122| *Attribute* | *Comment* | *Default / Example* | 
    113123|  *Behavior*  ||| 
    114 | allowvarsininclude | allows you to use TWiki variables within INCLUDE statement parameters of your source topics (disabled by default for a fast INCLUDE handling) | =allowvarsininclude="off"= | 
    115124| compatmode  | if set to "1" all Foswiki:Extensions.CalendarPlugin event types are supported (related: compatmodeicon) | =compatmode="0"= | 
    116125| daynames | custom daynames (a list separated by a '&brvbar;' and starting on Monday; overrides lang attribute) | =daynames="M&brvbar;T&brvbar;W&brvbar;T&brvbar;F&brvbar;S&brvbar;S"= | 
     
    197206| stattitle | statistics tooltip; overrides statrowtitle and statcoltitle | undefined / =stattitle="%{ll}"= | 
    198207 
    199  
    200208*Hints:*  
    201209        * You can use %SYSTEMWEB%.TextFormattingRules for some attribute values: tablecaption, name, holidayicon, adayofficon, workicon, notatworkicon, compatmodeicon, pubholidayicon 
     
    274282        * 6 Jun 2005 - 15 Jun 2005 - Kelly - Berlin - :-| color(red) fgcolor(white) 
    275283 
    276 ---++ Plugin Settings 
    277  
    278         * One line description, is shown in the %SYSTEMWEB%.TextFormattingRules topic: 
    279                 * Set SHORTDESCRIPTION = Create a table with a list of people on holidays 
    280  
     284---++ Settings 
     285 
     286The following settings are available as preferences: 
    281287        * Days to show (default: 30) 
    282                 * # Set DAYS = 30 
     288                * # Set HOLIDAYLISTPLUGIN_DAYS = 30 
    283289 
    284290        * Language (default: English - see manual page of Date::Calc perl module, e.g: English, Deutsch, Fran&ccedil;ais, Espa&ntilde;ol, Nederlands, Dansk, suomi, ...).  
    285                 * # Set LANG = Deutsch 
     291                * # Set HOLIDAYLISTPLUGIN_LANG = Deutsch 
    286292 
    287293        * Content of the first cell (default: Name): 
    288                 * # Set NAME = Name 
     294                * # Set HOLIDAYLISTPLUGIN_NAME = Name 
    289295 
    290296        * Set work icon (default: &amp;nbsp; - old behavior: =:<nop>mad:= ): 
    291                 * # Set WORKICON = :mad: 
     297                * # Set HOLIDAYLISTPLUGIN_WORKICON = :mad: 
    292298 
    293299        * Set compatibility mode (default: 0; disables all Foswiki:Extensions.CalendarPlugin event types) and icon (default: =8<nop>-)=) 
    294                 * # Set COMPATMODE = 1 
    295                 * # Set COMPATMODEICON = 8-) 
     300                * # Set HOLIDAYLISTPLUGIN_COMPATMODE = 1 
     301                * # Set HOLIDAYLISTPLUGIN_COMPATMODEICON = 8-) 
    296302 
    297303        * Set unknown parameter message (default: =%<nop>RED% Sorry, some parameters are unknown: %<nop>UNKNOWNPARAMSLIST% %<nop>ENDCOLOR% &lt;br/&gt; Allowed parameters are (see !%SYSTEMWEB%.HolidaylistPlugin topic for more details): %<nop>KNOWNPARAMSLIST%=) 
    298                 * # Set UNKNOWNPARAMSMSG = %RED% Following parameter(s) is/are unknown: %UNKNOWNPARAMSLIST% %ENDCOLOR% 
     304                * # Set HOLIDAYLISTPLUGIN_UNKNOWNPARAMSMSG = %RED% Following parameter(s) is/are unknown: %UNKNOWNPARAMSLIST% %ENDCOLOR% 
    299305 
    300306        * Enable/Disable public holiday support (default: 1; public holiday support is enabled), show public holidays as separate lines in table (default: 0; public holidays are not shown as separate rows in table); public holiday icon (default: =<nop>:-)=) 
    301                 * # Set ENABLEPUBHOLIDAYS = 1 
    302                 * # Set SHOWPUBHOLIDAYS = 0 
    303                 * # Set PUBHOLIDAYICON = :-) 
     307                * # Set HOLIDAYLISTPLUGIN_ENABLEPUBHOLIDAYS = 1 
     308                * # Set HOLIDAYLISTPLUGIN_SHOWPUBHOLIDAYS = 0 
     309                * # Set HOLIDAYLISTPLUGIN_PUBHOLIDAYICON = :-) 
    304310   
    305311*Note:* Every attribute of %<nop>HOLIDAYLIST% can also be used as plugin setting. You only have to use capital letters. 
     
    307313---++ Plugin Installation Instructions 
    308314 
    309         * Install required CPAN modules (e.g. =perl -MCPAN -e "install Date::Calc"= ) 
    310         * Download the ZIP file from the Plugin web (see below) 
    311         * Unzip ==%TOPIC%.zip== in your Foswiki installation directory. Content: 
    312 | *File:* | *Description:* | 
    313 | ==data/System/%TOPIC%.txt== | Plugin topic | 
    314 | ==data/System/VarHOLIDAYLIST.txt== | Documentation | 
    315 | ==lib/Foswiki/Plugins/%TOPIC%.pm== | Plugin Perl module | 
    316 | ==pub/System/%TOPIC%/example.gif== | Example image | 
    317         * Test if the plugin is correctly installed: Copy the example above into a new topic and change the year number to the current year. 
    318  
    319  
    320 ---++ Plugin Info 
    321  
    322 |  Plugin Author: | TWiki:Main.PeterJones, TWiki:Main.DanielRohde | 
    323 |  Plugin Version: | v1.030 (24 Nov 2009) | 
     315%$INSTALL_INSTRUCTIONS% 
     316 
     317---++ Info 
     318 
     319|  Author: | Foswiki:Main.DanielRohde (from an original by Foswiki:Main.PeterJones) | 
     320|  Version: | %$VERSION% | 
     321|  Release: | %$RELEASE% | 
    324322|  Change History: | <!-- versions below in reverse order -->&nbsp; | 
    325 |  v1.030 (24 Nov 2009) | TWiki:Main.DanielRohde: improved INCLUDE support requested by Foswiki:Main.IngoKappler; added multi language support for entry definitions; fixed unknown language bug; fixed performance issue reported by Foswiki:Main.IngoKappler (thx Foswiki:Main.MichaelDaum) |  
    326 |  v1.029 (6 Mar 2009) | TWiki:Main.DanielRohde: changed some defaults (showmonthheader, monthheaderformat, headerformat); fixed alignments (statistics, monthheader); added maxheight attribute; allowed color definitions in icon fields | 
    327 |  v1.026 (28 Oct 2008) | TWiki:Main.DanielRohde: added missing anchor in showoptions form action; added row color feature (new attributes: namecolors, rowcolors); added order feature (new attribute: order); added namepos attribute (place names left and/or right of a row) | 
    328 |  v1.025 (17 Oct 2008) | TWiki:Main.DanielRohde: added div tag with style overflow:auto requested by Matthew Thomson; added query parameters feature (hlp_&lt;attribute&gt; in URIs); added option form feature (new attributes: showoptions, optionspos, optionsformat) requested by Matthew Thomson; improved performance; fixed minor icon related bugs | 
    329 |  v1.024 (29 Jul 2008) | TWiki:Main.DanielRohde: added statistics feature requested by TWiki:Main.GarySprague | 
    330 |  v1.023 (19 Jan 2008) | Foswiki:Main.KennethLavrsen: fixed Item5190 - does not like whitespace after the smiley. This makes the plugin work with TWiki 4.2.0 and Wysiwyg | 
    331 |  v1.022 (18 Jun 2007) | TWiki:Main.DanielRohde: added documentation requested by TWiki:Main.PeterThoeny; fixed type (on=off bug) | 
    332 |  v1.021 (20 Apr 2007) | TWiki:Main.DanielRohde: fixed minor HTML bug reported by TWiki:Main.JfMacaud; added month header feature (showmonthheader attribute) requested by Rikard Johansson; fixed some minor bugs (documentation, preferences handling); | 
    333 |  v1.020 (21 Sep 2006) | TWiki:Main.DanielRohde: added week attribute requested by TWiki:Main.JanFilipsky; added tooltip to day headers; | 
    334 |  v1.019 (7 Aug 2006) | TWiki:Main.DanielRohde: improved navigation; fixed %<nop>ICON% tag handling bug reported by TWiki:Main.UlfJastrow; | 
    335 |  v1.018 (25 Jul 2006) | TWiki:Main.DanielRohde: fixed periodic event bug; added navigation feature |  
    336 |  v1.017 (31 May 2006) | TWiki:Main.DanielRohde: fixed minor bug (periodic repeater) | 
    337 |  v1.016 (27 Apr 2006) | TWiki:Main.DanielRohde: fixed some major bugs: deep recursion bug reported by TWiki:Main.ChrisHausen; exception handling bug (concerns Foswiki) | 
    338 |  v1.015 (9 Feb 2006) | TWiki:Main.DanielRohde: added class attribute (holidaylistPluginTable) to table tag for stylesheet support (thanx TWiki:Main.HaraldJoerg and Foswiki:Main.ArthurClemens); fixed mod_perl preload bug (removed 'use warnings;') reported by Foswiki:Main.KennethLavrsen | 
    339 |  v1.014 (23 Jan 2006) | TWiki:Main.DanielRohde: incorporated documentation fixes by Foswiki:Main.KennethLavrsen (Bugs:Item1440) |  
    340 |  v1.013 (8 Nov 2005) | TWiki:Main.DanielRohde: added Perl strict pragma; |  
    341 |  v1.012 (5 Sep 2005): | TWiki:Main.DanielRohde: added public holiday support requested by TWiki:Main.IlltudDaniel; improved documentation; improved forced link handling in alt/title attributes of img tags; fixed documentation bug reported by TWiki:Main.FranzJosefSilli | 
    342 |  v1.011 (11 Jul 2005): | TWiki:Main.DanielRohde: improved performance; fixed major periodic repeater bug; added parameter check; fixed flag parameter handling; allowed language specific month and day names for entries; fixed minor repeater bugs; added new attributes: monthnames, daynames, width, unknownparamsmsg | 
    343 |  v1.010 (5 Jul 2005): | TWiki:Main.DanielRohde: added exception handling; added compatibility mode (new attributes: compatmode, compatmodeicon) with full CalendarPlugin event type support; added documentation | 
    344 |  v1.009 (29 Jun 2005): | TWiki:Main.DanielRohde: fixed major bug (!WikiNames and forced links in names) reported by Foswiki:Main.KennethLavrsen; fixed documentation bugs; added INCLUDE expansion (for topics in topic attribute value); added name rendering | 
    345 |  v1.008 (23 Jun 2005): | TWiki:Main.DanielRohde: added new attributes (nwidth,tcwidth,removeatwork,tablecaptionalign,headerformat); performance fixes; allowed digits in month attribute  | 
    346 |  v1.007 (17 Jun 2005): | TWiki:Main.DanielRohde: personal icon support; new attributes (month,year); icon tooltips with dates/person/location/icon; fixed '-' bug | 
    347 |  v1.006 (16 Jun 2005): | TWiki:Main.DanielRohde: added new features (location support; today(fg/bg)color) | 
    348 |  v1.005 (16 Jun 2005): | TWiki:Main.DanielRohde: added new features (start date support; weekendbgcolor); fixed documentation bugs; | 
    349 |  v1.004 (14 Jun 2005): | TWiki:Main.DanielRohde: some performance improvements; code cleanup; documentation | 
    350 |  v1.003 (13 Jun 2005): | TWiki:Main.DanielRohde: fix plugin preference handling; rename some subroutines | 
    351 |  v1.002 (13 Jun 2005): | TWiki:Main.DanielRohde: renders some options; fixes some documentation bugs and a white space bug | 
    352 |  v1.001 (10 Jun 2005): | TWiki:Main.DanielRohde: A complete reimplementation with many bug fixes and some new features. | 
    353 |  v1.021 (01 Jun 2005): | TWiki:Main.PeterJones: Initial version | 
    354 |  CPAN Dependencies: | *required:* CPAN:Date::Calc | 
    355 |  Other Dependencies: | %SYSTEMWEB%.SmiliesPlugin | 
    356 |  Perl Version: | 5.008 | 
     323|  1.031 | Foswiki:Tasks.Item8548: split the plugin into a load-on-demand core module, and changed it to use a registered tag handler. Made it NO_PREFS_IN_TOPIC. Both changes for performance reasons. Changed the load method to expand includes in the same way as CalendarPlugin does (it would be good to share some code here). Foswiki:Tasks.Item1491: hacked/worked around problem with !EditTablePlugin by enabling the recursion block in that plugin. Tested for compatibility with !CalDAVPlugin and !EditTablePlugin - seems OK. | 
     324|  1.030 (24 Nov 2009) | Foswiki:Main.DanielRohde: improved INCLUDE support requested by Foswiki:Main.IngoKappler; added multi language support for entry definitions; fixed unknown language bug; fixed performance issue reported by Foswiki:Main.IngoKappler (thx Foswiki:Main.MichaelDaum) |  
     325|  1.029 (6 Mar 2009) | Foswiki:Main.DanielRohde: changed some defaults (showmonthheader, monthheaderformat, headerformat); fixed alignments (statistics, monthheader); added maxheight attribute; allowed color definitions in icon fields | 
     326|  1.026 (28 Oct 2008) | Foswiki:Main.DanielRohde: added missing anchor in showoptions form action; added row color feature (new attributes: namecolors, rowcolors); added order feature (new attribute: order); added namepos attribute (place names left and/or right of a row) | 
     327|  1.025 (17 Oct 2008) | Foswiki:Main.DanielRohde: added div tag with style overflow:auto requested by Matthew Thomson; added query parameters feature (hlp_&lt;attribute&gt; in URIs); added option form feature (new attributes: showoptions, optionspos, optionsformat) requested by Matthew Thomson; improved performance; fixed minor icon related bugs | 
     328|  1.024 (29 Jul 2008) | Foswiki:Main.DanielRohde: added statistics feature requested by Foswiki:Main.GarySprague | 
     329|  1.023 (19 Jan 2008) | Foswiki:Main.KennethLavrsen: fixed Item5190 - does not like whitespace after the smiley. This makes the plugin work with TWiki 4.2.0 and Wysiwyg | 
     330|  1.022 (18 Jun 2007) | Foswiki:Main.DanielRohde: added documentation requested by Foswiki:Main.PeterThoeny; fixed type (on=off bug) | 
     331|  1.021 (20 Apr 2007) | Foswiki:Main.DanielRohde: fixed minor HTML bug reported by Foswiki:Main.JfMacaud; added month header feature (showmonthheader attribute) requested by Rikard Johansson; fixed some minor bugs (documentation, preferences handling); | 
     332|  1.020 (21 Sep 2006) | Foswiki:Main.DanielRohde: added week attribute requested by Foswiki:Main.JanFilipsky; added tooltip to day headers; | 
     333|  1.019 (7 Aug 2006) | Foswiki:Main.DanielRohde: improved navigation; fixed %<nop>ICON% tag handling bug reported by Foswiki:Main.UlfJastrow; | 
     334|  1.018 (25 Jul 2006) | Foswiki:Main.DanielRohde: fixed periodic event bug; added navigation feature |  
     335|  1.017 (31 May 2006) | Foswiki:Main.DanielRohde: fixed minor bug (periodic repeater) | 
     336|  1.016 (27 Apr 2006) | Foswiki:Main.DanielRohde: fixed some major bugs: deep recursion bug reported by Foswiki:Main.ChrisHausen; exception handling bug (concerns Foswiki) | 
     337|  1.015 (9 Feb 2006) | Foswiki:Main.DanielRohde: added class attribute (holidaylistPluginTable) to table tag for stylesheet support (thanx Foswiki:Main.HaraldJoerg and Foswiki:Main.ArthurClemens); fixed mod_perl preload bug (removed 'use warnings;') reported by Foswiki:Main.KennethLavrsen | 
     338|  1.014 (23 Jan 2006) | Foswiki:Main.DanielRohde: incorporated documentation fixes by Foswiki:Main.KennethLavrsen (Bugs:Item1440) |  
     339|  1.013 (8 Nov 2005) | Foswiki:Main.DanielRohde: added Perl strict pragma; |  
     340|  1.012 (5 Sep 2005): | Foswiki:Main.DanielRohde: added public holiday support requested by Foswiki:Main.IlltudDaniel; improved documentation; improved forced link handling in alt/title attributes of img tags; fixed documentation bug reported by Foswiki:Main.FranzJosefSilli | 
     341|  1.011 (11 Jul 2005): | Foswiki:Main.DanielRohde: improved performance; fixed major periodic repeater bug; added parameter check; fixed flag parameter handling; allowed language specific month and day names for entries; fixed minor repeater bugs; added new attributes: monthnames, daynames, width, unknownparamsmsg | 
     342|  1.010 (5 Jul 2005): | Foswiki:Main.DanielRohde: added exception handling; added compatibility mode (new attributes: compatmode, compatmodeicon) with full CalendarPlugin event type support; added documentation | 
     343|  1.009 (29 Jun 2005): | Foswiki:Main.DanielRohde: fixed major bug (!WikiNames and forced links in names) reported by Foswiki:Main.KennethLavrsen; fixed documentation bugs; added INCLUDE expansion (for topics in topic attribute value); added name rendering | 
     344|  1.008 (23 Jun 2005): | Foswiki:Main.DanielRohde: added new attributes (nwidth,tcwidth,removeatwork,tablecaptionalign,headerformat); performance fixes; allowed digits in month attribute  | 
     345|  1.007 (17 Jun 2005): | Foswiki:Main.DanielRohde: personal icon support; new attributes (month,year); icon tooltips with dates/person/location/icon; fixed '-' bug | 
     346|  1.006 (16 Jun 2005): | Foswiki:Main.DanielRohde: added new features (location support; today(fg/bg)color) | 
     347|  1.005 (16 Jun 2005): | Foswiki:Main.DanielRohde: added new features (start date support; weekendbgcolor); fixed documentation bugs; | 
     348|  1.004 (14 Jun 2005): | Foswiki:Main.DanielRohde: some performance improvements; code cleanup; documentation | 
     349|  1.003 (13 Jun 2005): | Foswiki:Main.DanielRohde: fix plugin preference handling; rename some subroutines | 
     350|  1.002 (13 Jun 2005): | Foswiki:Main.DanielRohde: renders some options; fixes some documentation bugs and a white space bug | 
     351|  1.001 (10 Jun 2005): | Foswiki:Main.DanielRohde: A complete reimplementation with many bug fixes and some new features. | 
     352|  1.021 (01 Jun 2005): | Foswiki:Main.PeterJones: Initial version | 
     353|  Dependencies: | %$DEPENDENCIES% | 
    357354|  License: | GPL ([[http://www.gnu.org/copyleft/gpl.html][GNU General Public License]]) | 
    358 |  Plugin Home: | http://foswiki.org/Extensions/%TOPIC% | 
    359 |  Feedback: | http://foswiki.org/Extensions/%TOPIC%Dev | 
    360  
    361 __Related Topics:__ %SYSTEMWEB%.SmiliesPlugin, [[%SYSTEMWEB%.Plugins][Plugins]], Foswiki:Extensions.CalendarPlugin 
    362   
    363 -- TWiki:Main.PeterJones - 01 Jun 2005 
    364 %BR% -- TWiki:Main.DanielRohde - 10 Jun 2005 
     355|  Home: | http://foswiki.org/Extensions/%TOPIC% | 
     356|  Support: | http://foswiki.org/Support/%TOPIC% | 
    365357 
    366358%META:FILEATTACHMENT{name="example.gif" attr="h" comment="Example" date="1119006048" path="example.gif" size="15447" user="rohdedan" version="1.1"}% 
  • trunk/HolidaylistPlugin/lib/Foswiki/Plugins/HolidaylistPlugin.pm

    r5607 r8005  
    1 # Plugin for Foswiki - The Free and Open Source Wiki, http://foswiki.org/ 
    2 # 
    3 # Copyright (C) 2000-2003 Andrea Sterbini, a.sterbini@flashnet.it 
    4 # Copyright (C) 2001-2004 Peter Thoeny, peter@thoeny.com 
    5 # Copyright (C) 2005-2009 Daniel Rohde 
    6 # 
    7 # This program is free software; you can redistribute it and/or 
    8 # modify it under the terms of the GNU General Public License 
    9 # as published by the Free Software Foundation; either version 2 
    10 # of the License, or (at your option) any later version. 
    11 # 
    12 # This program is distributed in the hope that it will be useful, 
    13 # but WITHOUT ANY WARRANTY; without even the implied warranty of 
    14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    15 # GNU General Public License for more details, published at  
    16 # http://www.gnu.org/copyleft/gpl.html 
    17 # 
    18 # ========================= 
    19  
    20  
    21 # ========================= 
     1# See bottom of file for license and copyright information 
    222package Foswiki::Plugins::HolidaylistPlugin;     
    233 
    24 # ========================= 
     4use strict; 
     5use warnings; 
    256 
    26 use strict; 
    27 ### use warnings; 
     7# See plugin topic for complete release history 
     8our $VERSION = '$Rev: 18212 $'; 
     9our $RELEASE = '1.1.0'; 
     10our $SHORTDESCRIPTION = 'Create a table with a list of people on holidays'; 
     11our $NO_PREFS_IN_TOPIC = 1; 
    2812 
    29 use Date::Calc qw(:all); 
    30 use CGI; 
    31  
    32 # ========================= 
    33 use vars qw( 
    34         $web $topic $user $installWeb $VERSION $RELEASE $REVISION $pluginName 
    35         $debug  
    36         %defaults @renderedOptions @flagOptions $refText  
    37         @unknownParams %options 
    38         %table %locationtable %icontable  
    39         %months %daysofweek 
    40         $months_rx $date_rx $daterange_rx $bullet_rx $bulletdate_rx $bulletdaterange_rx $dow_rx $day_rx 
    41         $year_rx $monthyear_rx $monthyearrange_rx 
    42         $defaultsInitialized 
    43         $theWeb $theTopic $attributes 
    44         $startDays 
    45         @processedTopics 
    46         $hlid  
    47         %rendererCache 
    48     ); 
    49  
    50 # This should always be $Rev: 18212 $ so that Foswiki can determine the checked-in 
    51 # status of the plugin. It is used by the build automation tools, so 
    52 # you should leave it alone. 
    53 $VERSION = '$Rev: 18212 $'; 
    54  
    55 # This is a free-form string you can use to "name" your own plugin version. 
    56 # It is *not* used by the build automation tools, but is reported as part 
    57 # of the version number in PLUGINDESCRIPTIONS. 
    58  
    59  
    60 $REVISION = '1.0.30'; #dro# improved INCLUDE support requested by Foswiki:Main.IngoKappler; added multi language support for entry definitions; fixed unknown language bug 
    61 #$REVISION = '1.0.29'; #dro# changed some defaults (showmonthheader, monthheaderformat, headerformat); fixed alignments (statistics, monthheader); added maxheight attribute; allowed color definitions in icon fields 
    62 #$REVISION = '1.0.26'; #dro# added missing anchor in showoptions form action; added row color feature (new attributes: namecolors, rowcolors); added order feature (new attribute: order); added namepos attribute (place names left and/or right of a row) 
    63 #$REVISION = '1.0.25'; #dro# added div tag with style overflow:auto requested by Matthew Thomson; added query parameters feature (hlp_&lt;attribute&gt; in URIs); added option form feature (new attributes: showoptions, optionspos, optionsformat) requested by Matthew Thomson; improved performance; fixed minor icon related bugs; 
    64 #$REVISION = '1.0.24'; #dro# added statistics feature requested by TWiki:Main.GarySprague 
    65 #$REVISION = '1.0.23'; #kjl# fixed Item5190 - does not like whitespace after the smiley. This makes the plugin work with TWiki 4.2.0 and Wysiwyg 
    66 #$REVISION = '1.0.22'; #dro# added documentation requested by TWiki:Main.PeterThoeny; fixed typo (on=off bug) 
    67 #$REVISION = '1.021'; #dro# fixed minor HTML bug reported by TWiki:Main.JfMacaud; added month header feature (showmonthheader attribute) requested by Rikard Johansson; fixed some minor bugs (documentation, preferences handling); 
    68 #$REVISION = '1.020'; #dro# added week attribute requested by TWiki:Main.JanFilipsky; added tooltip to day headers; 
    69 #$REVISION = '1.019'; #dro# improved navigation; fixed %<nop>ICON% tag handling bug reported by TWiki:Main.UlfJastrow; 
    70 #$REVISION = '1.018'; #dro# fixed periodic event bug; added navigation feature 
    71 #$REVISION = '1.017'; #dro# fixed minor bug (periodic repeater) 
    72 #$REVISION = '1.016'; #dro# fixed some major bugs: deep recursion bug reported by TWiki:Main.ChrisHausen; exception handling bug (concerns Foswiki) 
    73 #$REVISION = '1.015'; #dro# added class attribute (holidaylistPluginTable) to table tag for stylesheet support (thanx TWiki:Main.HaraldJoerg and Foswiki:Main.ArthurClemens); fixed mod_perl preload bug (removed 'use warnings;') reported by Foswiki:Main.KennethLavrsen 
    74 #$REVISION = '1.014'; #dro# incorporated documentation fixes by Foswiki:Main.KennethLavrsen (Bugs:Item1440)  
    75 #$REVISION = '1.013'; #dro# added Perl strict pragma;  
    76 #$VERSION = '1.012'; #dro# added public holiday support requested by TWiki:Main.IlltudDaniel; improved documentation; improved forced link handling in alt/title attributes of img tags; fixed documentation bug reported by TWiki:Main.FranzJosefSilli 
    77 #$VERSION = '1.011'; #dro# improved performance; fixed major periodic repeater bug; added parameter check; fixed flag parameter handling; allowed language specific month and day names for entries; fixed minor repeater bugs; added new attributes: monthnames, daynames, width, unknownparamsmsg; 
    78 #$VERSION = '1.010'; #dro# added exception handling; added compatibility mode (new attributes: compatmode, compatmodeicon) with full CalendarPlugin event type support; added documentation 
    79 #$VERSION = '1.009'; #dro# fixed major bug (WikiNames and forced links in names) reported by Foswiki:Main.KennethLavrsen; fixed documentation bugs; added INCLUDE expansion (for topics in topic attribute value); added name rendering 
    80 #$VERSION = '1.008'; #dro# added new attributes (nwidth,tcwidth,removeatwork,tablecaptionalign,headerformat); performance fixes; allowed digits in the month attribute 
    81 #$VERSION = '1.007'; #dro# personal icon support; new attributes (month,year); icon tooltips with dates/person/location/icon; fixed '-' bug 
    82 #$VERSION = '1.006'; #dro# added new features (location support; todaybgcolor; todayfgcolor) 
    83 #$VERSION = '1.005'; #dro# added new features (startdate support; weekendbgcolor); fixed documentation bugs 
    84 #$VERSION = '1.004'; #dro# some performance improvements; code cleanup; documentation 
    85 #$VERSION = '1.003'; #dro# fix plugin preferences handling; format column name; rename some subroutines 
    86 #$VERSION = '1.002'; #dro# renders some options; fixes: white space bug, documentation bugs;  
    87 #$VERSION = '1.001'; #dro# complete reimplementation of HolidaylistPlugin 
    88 #$VERSION = '1.021'; #pj# initial version 
    89  
    90 $pluginName = 'HolidaylistPlugin';  # Name of this Plugin 
    91  
    92 # ========================= 
    93 sub initPlugin 
    94 { 
    95     ( $topic, $web, $user, $installWeb ) = @_; 
    96  
    97     # check for Plugins.pm versions 
    98     if( $Foswiki::Plugins::VERSION < 1.021 ) { 
    99         Foswiki::Func::writeWarning( "Version mismatch between $pluginName and Plugins.pm" ); 
    100         return 0; 
    101     } 
    102  
    103     # Get plugin debug flag 
    104     $debug = Foswiki::Func::getPluginPreferencesFlag( "DEBUG" ); 
    105  
    106     $defaultsInitialized = 0; 
    107  
    108     # Plugin correctly initialized 
    109     Foswiki::Func::writeDebug( "- Foswiki::Plugins::${pluginName}::initPlugin( $web.$topic ) is OK" ) if $debug; 
    110  
     13sub initPlugin { 
     14    Foswiki::Func::registerTagHandler( 
     15        'HOLIDAYLIST', sub { 
     16            require Foswiki::Plugins::HolidaylistPlugin::Core; 
     17            return Foswiki::Plugins::HolidaylistPlugin::Core::HOLIDAYLIST(@_); 
     18        }); 
    11119    return 1; 
    11220} 
    11321 
    114 # ========================= 
    115 sub commonTagsHandler 
    116 { 
    117 ### my ( $text, $topic, $web ) = @_;   # do not uncomment, use $_[0], $_[1]... instead 
     221; 
     23__END__ 
    11824 
    119     Foswiki::Func::writeDebug( "- ${pluginName}::commonTagsHandler( $_[2].$_[1] )" ) if $debug; 
     25Copyright (C) 2000-2003 Andrea Sterbini, a.sterbini@flashnet.it 
     26Copyright (C) 2001-2004 Peter Thoeny, peter@thoeny.com 
     27Copyright (C) 2005-2009 Daniel Rohde 
     28Copyright (C) 2008-2010 Foswiki Contributors 
    12029 
    121     return if Foswiki::Func::getContext()->{'save'}; 
     30This program is free software; you can redistribute it and/or 
     31modify it under the terms of the GNU General Public License 
     32as published by the Free Software Foundation; either version 2 
     33of the License, or (at your option) any later version. 
    12234 
    123     # This is the place to define customized tags and variables 
    124     # Called by Foswiki::handleCommonTags, after %INCLUDE:"..."% 
    125  
    126     #### eval is bad because Foswiki works with exceptions 
    127     ####eval { 
    128             $_[0] =~ s/%HOLIDAYLIST%/&handleHolidaylist("", $_[0], $_[1], $_[2])/ge; 
    129             $_[0] =~ s/%HOLIDAYLIST{(.*?)}%/&handleHolidaylist($1, $_[0], $_[1], $_[2])/ge; 
    130     ####}; 
    131     ####Foswiki::Func::writeWarning("${pluginName}: $@") if $@; 
    132  
    133  
    134 } 
    135 # ========================= 
    136 sub initDefaults() { 
    137         my $webbgcolor = &Foswiki::Func::getPreferencesValue("WEBBGCOLOR", $web) || 'white'; 
    138         %defaults = ( 
    139                 days            => 30,          # days to show 
    140                 lang            => 'English',   # language 
    141                 tablecaption    => '&nbsp;',    # table caption 
    142                 cellpadding     => 1,           # table cellpadding  
    143                 cellspacing     => 0,           # table cellspacing 
    144                 border          => 1,           # table border 
    145                 topic           => "$web.$topic",       # topic with calendar entries 
    146                 tableheadercolor=>  $webbgcolor,        # table header color 
    147                 tablebgcolor    => 'white',     # table background color 
    148                 workicon => '&nbsp;',           # on work icon (old behavior: ':mad:') 
    149                 holidayicon => '8-)',           # on holiday icon 
    150                 adayofficon => ':ok:',          # a day off icon 
    151                 showweekends    => 0,           # show weekends with month day and weekday in header and icons in cells 
    152                 name            => 'Name',      # first cell entry 
    153                 weekendbgcolor  => $webbgcolor, # background color of weekend cells 
    154                 startdate       => undef,       # start date or a day offset 
    155                 notatworkicon   => ':-I',       # not at work icon 
    156                 todaybgcolor    => undef,       # background color for today cells (usefull for a defined startdate) 
    157                 todayfgcolor    => undef,       # foreground color for today cells (usefull for a dark todaybgcolor) 
    158                 month           => undef,       # the month or a offset 
    159                 year            => undef,       # the year or a offset 
    160                 tcwidth         => undef,       # width of the smily cells 
    161                 nwidth          => undef,       # width of the first column 
    162                 removeatwork    => 0,           # removes names without calendar entries from table if set to "1" 
    163                 tablecaptionalign=> 'top',      # table caption alignment (top|bottom|left|right) 
    164                 headerformat    => '<font size="-2">%a<br/>%e</font>',  # format of the header 
    165                 compatmode      => 0,           # compatibility mode (allows all CalendarPlugin event types) 
    166                 compatmodeicon  => ':-)',       # compatibility mode icon 
    167                 daynames        => undef,       # day names (overrides lang attribute) 
    168                 monthnames      => undef,       # month names (overrides lang attribute) 
    169                 width           => undef,       # table width 
    170                 unknownparamsmsg=> '%RED% Sorry, some parameters are unknown: %UNKNOWNPARAMSLIST% %ENDCOLOR% <br/> Allowed parameters are (see %SYSTEMWEB%.HolidaylistPlugin topic for more details): %KNOWNPARAMSLIST%', 
    171                 enablepubholidays       => 1,           # enable public holidays 
    172                 showpubholidays => 0,           # show public holidays in a separate row 
    173                 pubholidayicon  => ':-)',       # public holiday icon 
    174                 navnext => '&gt;|',             # navigation button to the next n days 
    175                 navnexthalf =>'&gt;',           # navigation button to the next n/2 days 
    176                 navnexttitle => 'Next %n day(s)', 
    177                 navnexthalftitle => 'Next %n day(s)', 
    178                 navprev => '<br/>|&lt;',                # navigation button to the last n days 
    179                 navprevhalf => '&lt;',          # navigation button to the last n/2 days 
    180                 navprevtitle => 'Previous %n day(s)', 
    181                 navprevhalftitle => 'Previous %n day(s)', 
    182                 navhome => '%d', 
    183                 navhometitle => 'Go to the start date', 
    184                 navenable => 1, 
    185                 navdays => undef, 
    186                 week => undef, 
    187                 showmonthheader => 1, 
    188                 monthheaderformat => '%b', 
    189                 showstatcol => 0, 
    190                 statcolheader => '#', 
    191                 statcolformat => '%{hh}', 
    192                 statcoltitle => '%{ll}', 
    193                 showstatrow => 0, 
    194                 statrowformat => '%{hh}', 
    195                 statrowheader => '#', 
    196                 statrowtitle => '%{ll}', 
    197                 statformat_ll => '%{ll:%LOCATION} x %LOCATION; ', 
    198                 statformat_l => '%{l:%LOCATION} x %LOCATION; ', 
    199                 statformat_ii => '%{ii:%ICON} x %ICON ; ', 
    200                 statformat_i => '%{i:%ICON} x %ICON ; ', 
    201                 statformat_0 => 0, 
    202                 statformat => undef, 
    203                 stattitle => undef, 
    204                 statheader => undef, 
    205                 showstatsum => 1, 
    206                 statformat_perc => '%3.1f%%', 
    207                 statformat_unknown => 'unknown', 
    208                 optionsformat => 'Month: %MONTHSEL, Year: %YEARSEL %BUTTON(Change)', 
    209                 showoptions => 0, 
    210                 optionspos=> 'bottom', 
    211                 rowcolors => '#ffffff,#f0f0f0', 
    212                 namecolors => undef, 
    213                 order => undef, 
    214                 namepos => 'left', 
    215                 maxheight => undef, 
    216                 allowvarsininclude => 0, 
    217         ); 
    218  
    219         # reminder: don't forget change documentation (HolidaylistPlugin topic) if you add a new rendered option 
    220         @renderedOptions = ( 'tablecaption', 'name', 'holidayicon', 'adayofficon', 'workicon', 'notatworkicon', 'compatmodeicon', 'pubholidayicon' ); 
    221  
    222         # options to turn or switch things on (1) or off (0) 
    223         # this special handling allows 'on'/'yes';'off'/'no' values additionally to '1'/'0' 
    224         @flagOptions = ( 'showweekends', 'removeatwork', 'compatmode', 'enablepubholidays', 'showpubholidays', 'navenable','showmonthheader','showstatcol', 'showstatrow','showstatsum','showoptions','allowvarsininclude'); 
    225  
    226         %months = ( Jan=>1, Feb=>2, Mar=>3, Apr=>4, May=>5, Jun=>6,  
    227                     Jul=>7, Aug=>8, Sep=>9, Oct=>10, Nov=>11, Dec=>12 ); 
    228  
    229         %daysofweek = ( Mon=>1, Tue=>2, Wed=>3, Thu=>4, Fri=>5, Sat=>6, Sun=>7 ); 
    230  
    231         $hlid = 0; 
    232  
    233         $defaultsInitialized = 1; 
    234  
    235 } 
    236  
    237 # ========================= 
    238 sub initRegexs { 
    239         # some regular expressions: 
    240         $months_rx = join('|', map(quotemeta($_), keys(%months))); 
    241         $dow_rx = join('|', map(quotemeta($_), keys(%daysofweek))); 
    242         $year_rx = "[12][0-9]{3}"; 
    243         $monthyear_rx = "($months_rx)\\s+$year_rx"; 
    244         $monthyearrange_rx = "$monthyear_rx\\s+\\-\\s+$monthyear_rx"; 
    245         $day_rx = "[0-3]?[0-9](\.|th)?"; 
    246         $date_rx = "$day_rx\\s+($months_rx)\\s+$year_rx"; 
    247         $daterange_rx = "$date_rx\\s*-\\s*$date_rx"; 
    248         $bullet_rx = "^\\s+\\*\\s*"; 
    249         $bulletdate_rx = "$bullet_rx$date_rx\\s*-"; 
    250         $bulletdaterange_rx = "$bulletdate_rx\\s*$date_rx\\s*-"; 
    251 } 
    252 # ========================= 
    253 sub initOptions() { 
    254         my ($attributes) = @_; 
    255  
    256         my %params = &Foswiki::Func::extractParameters($attributes); 
    257  
    258         my @allOptions = keys %defaults; 
    259  
    260         # Check attributes: 
    261         @unknownParams= ( ); 
    262         foreach my $option (keys %params) { 
    263                 push (@unknownParams, $option) unless grep(/^\Q$option\E$/, @allOptions); 
    264         } 
    265         return 0 if $#unknownParams != -1;  
    266  
    267         my $cgi = Foswiki::Func::getCgiQuery(); 
    268  
    269         # Setup options (attributes>plugin preferences>defaults): 
    270         %options= (); 
    271         foreach my $option (@allOptions) { 
    272                 my $v = $cgi->param("hlp_${option}_$hlid") ; 
    273                 if (!defined $v) { $v = (!defined $cgi->param("hlp_id")) || ($cgi->param("hlp_id") eq $hlid) ? $cgi->param("hlp_${option}") : undef; } 
    274                 $v = $params{$option} unless defined $v; 
    275                 if (defined $v) { 
    276                         if (grep /^\Q$option\E$/, @flagOptions) { 
    277                                 $options{$option} = ($v!~/^(0|false|no|off)$/i); 
    278                         } else { 
    279                                 $options{$option} = $v; 
    280                         } 
    281                 } else { 
    282                         if (grep /^\Q$option\E$/, @flagOptions) { 
    283                                 $v = Foswiki::Func::getPreferencesFlag("\U${pluginName}_$option\E") || undef; 
    284                         } else { 
    285                                 $v = Foswiki::Func::getPreferencesValue("\U${pluginName}_$option\E") || undef; 
    286                         } 
    287                         $v = undef if (defined $v) && ($v eq ""); 
    288                         $options{$option}=(defined $v)? $v : $defaults{$option}; 
    289                 } 
    290  
    291         } 
    292         # Render some options: 
    293         foreach my $option (@renderedOptions) { 
    294                 if ($options{$option} !~ /^(\s|\&nbsp\;)*$/) { 
    295                         $options{$option}=_renderText($options{$option}, $web); 
    296                 } 
    297         } 
    298  
    299         my $defaultlang=undef; 
    300         foreach my $lang (split /\s*,\s*/, $options{lang}) { 
    301                 chomp $lang; 
    302                 eval { Date::Calc::Language(Date::Calc::Decode_Language($lang)); }; 
    303  
    304                 $defaultlang=$lang unless defined $defaultlang; 
    305  
    306                 # Setup language specific month and day names: 
    307                 for (my $i=1; $i < 13; $i++) { 
    308                         if ($i < 8) { 
    309                                 my $dt = Day_of_Week_to_Text($i); 
    310                                 $daysofweek{$dt} = $i; 
    311                                 $daysofweek{Day_of_Week_Abbreviation($i)} = $i; 
    312                                 $daysofweek{substr($dt, 0, 2)} = $i; 
    313                         } 
    314                         my $mt = Month_to_Text($i); 
    315                         $months{$mt} = $i; 
    316                         $months{substr($mt,0,3)} = $i; 
    317                 } 
    318         } 
    319         eval { Date::Calc::Language(Date::Calc::Decode_Language($defaultlang)); }; 
    320  
    321         # Setup user defined daynames: 
    322         if ((defined $options{daynames}) && (defined $defaults{daynames}) && ($options{daynames} ne $defaults{daynames})) { 
    323                 my @dn = split /\s*\|\s*/, $options{daynames}; 
    324                 if ($#dn == 6) { 
    325                         for (my $i=1; $i<8; $i++) { 
    326                                 $daysofweek{$dn[$i-1]}=$i; 
    327                         } 
    328                 } 
    329         } 
    330         # Setup user defined monthnames: 
    331         if ((defined $options{monthnames}) && (defined $defaults{monthnames}) && ($options{monthnames} ne $defaults{monthnames})) { 
    332                 my @mn = split /\s*\|\s*/, $options{monthnames}; 
    333                 if ($#mn == 11) { 
    334                         for (my $i=1; $i<13; $i++) { 
    335                                 $months{$mn[$i-1]} = $i; 
    336                         }        
    337                 } 
    338         } 
    339  
    340         # Setup statcol(format|title) and statrow(format|title) defaults 
    341         if ($options{showweekends}) { 
    342                 $options{statcolformat}='%{h}' if $options{statcolformat} eq $defaults{statcolformat}; 
    343                 $options{statcoltitle}='%{l}' if $options{statcoltitle} eq $defaults{statcoltitle}; 
    344                 $options{statrowformat}='%{h}' if $options{statrowformat} eq $defaults{statrowformat}; 
    345                 $options{statrowtitle}='%{l}' if $options{statrowtitle} eq $defaults{statrowtitle}; 
    346         } 
    347  
    348         @processedTopics = ( ); 
    349         return 1; 
    350  
    351 } 
    352 # ========================= 
    353 sub handleHolidaylist() { 
    354         ($attributes, $refText, $theTopic, $theWeb) = @_; 
    355  
    356         local(%options, @unknownParams); 
    357         local(%table, %locationtable, %icontable); 
    358  
    359         # order of &init... calls is important 
    360  
    361         &initDefaults() unless $defaultsInitialized; 
    362  
    363         $hlid++; 
    364  
    365         return &createUnknownParamsMessage() unless &initOptions($attributes); 
    366  
    367         &initRegexs();  
    368  
    369         return &renderHolidaylist(&handlePublicHolidays(&fetchHolidaylist(&getTopicText()))); 
    370 } 
    371 # ========================= 
    372 sub createUnknownParamsMessage { 
    373         my $msg; 
    374         $msg = Foswiki::Func::getPreferencesValue("UNKNOWNPARAMSMSG") || undef; 
    375         $msg = $defaults{unknownparamsmsg} unless defined $msg; 
    376         $msg =~ s/\%UNKNOWNPARAMSLIST\%/join(', ', sort @unknownParams)/eg; 
    377         $msg =~ s/\%KNOWNPARAMSLIST\%/join(', ', sort keys %defaults)/eg; 
    378         return $msg; 
    379 } 
    380 # ========================= 
    381 sub getStartDate() { 
    382         my ($yy,$mm,$dd) = Today(); 
    383  
    384         # handle startdate (absolute or offset) 
    385         if (defined $options{startdate}) { 
    386                 my $sd = $options{startdate}; 
    387                 $sd =~ s/^\s*(.*?)\s*$/$1/; # cut whitespaces 
    388                 if ($sd =~ /^$date_rx$/) { 
    389                         my ($d,$m,$y); 
    390                         ($d,$m,$y) = split(/\s+/, $sd); 
    391                         ($dd, $mm, $yy) = ($d, $months{$m},$y) if check_date($y, $months{$m},$d); 
    392                 } elsif ($sd =~ /^([\+\-]?\d+)$/) { 
    393                         ($yy, $mm, $dd) = Add_Delta_Days($yy, $mm, $dd, $1); 
    394                 } 
    395         }  
    396         # handle year (absolute or offset) 
    397         if (defined $options{year}) { 
    398                 my $year = $options{year}; 
    399                 if ($year =~ /^(\d{4})$/) { 
    400                         $yy=$year; 
    401                 } elsif ($year =~ /^([\+\-]?\d+)$/) { 
    402                         ($yy,$mm,$dd) = Add_Delta_YM($yy,$mm,$dd, $1, 0); 
    403                 }  
    404         } 
    405         # handle month (absolute or offset) 
    406         if (defined $options{month}) { 
    407                 my $month = $options{month}; 
    408                 my $matched = 1; 
    409                 if ($month=~/^($months_rx)$/) { 
    410                         $mm=$months{$1}; 
    411                 } elsif ($month=~/^([\+\-]\d+)$/) { 
    412                         ($yy,$mm,$dd) = Add_Delta_YM($yy,$mm,$dd, 0, $1); 
    413                 } elsif (($month=~/^\d?\d$/)&&($month>0)&&($month<13)) { 
    414                         $mm=$month; 
    415                 } else { 
    416                         $matched = 0; 
    417                 } 
    418                 if ($matched) { 
    419                         $dd=1; 
    420                         $options{days}=Days_in_Month($yy, $mm); 
    421                 } 
    422         } 
    423         # handle week (absolute or offset)  
    424         if (defined $options{week}) { 
    425                 my $week = $options{week}; 
    426                 my $matched = 0; 
    427                 if (($week =~ /^\d+$/)&&($week>0)&&($week<=Weeks_in_Year($yy))) { 
    428                         $matched = 1; 
    429                 } elsif ($week =~ /^[\+\-]\d+$/) { 
    430                         $matched = 1; 
    431                         ($yy,$mm,$dd) = Add_Delta_Days($yy,$mm,$dd, 7 * $week); 
    432                         $week = Week_of_Year($yy,$mm,$dd); 
    433                 } 
    434                 ($yy,$mm,$dd) = Monday_of_Week($week, $yy) if ($matched); 
    435         } 
    436         # handle paging: 
    437         my $cgi=Foswiki::Func::getCgiQuery(); 
    438         if (defined $cgi->param('hlppage'.$hlid)) { 
    439                 if ($cgi->param('hlppage'.$hlid) =~ m/^([\+\-]?[\d\.]+)$/) { 
    440                         my $hlppage = $1;  
    441                         my $days = int( (defined $options{'navdays'}?$options{'navdays'}:$options{'days'}) * $hlppage ); 
    442                         ($yy,$mm,$dd) = Add_Delta_Days($yy,$mm,$dd, $days); 
    443                 } 
    444         } 
    445  
    446         return ($dd,$mm,$yy); 
    447 } 
    448 # ========================= 
    449 sub getDays { 
    450         my ($date,$ldom) = @_; 
    451         my $days = undef; 
    452  
    453         $date=~s/^\s*//; 
    454         $date=~s/\s*$//; 
    455  
    456         my ($yy,$mm,$dd); 
    457         if ($date =~ /^$date_rx$/) { 
    458                 ($dd,$mm,$yy) = split /\s+/, $date; 
    459                 $mm = $months{$mm}; 
    460         } elsif ($date =~ /^$monthyear_rx$/) { 
    461                 ($mm, $yy) = split /\s+/, $date; 
    462                 $mm = $months{$mm}; 
    463                 $dd = $ldom? Days_in_Month($yy, $mm) : 1; 
    464         } else { 
    465                 return undef; 
    466         } 
    467         $dd=~/(\d+)/; 
    468         $dd=$1; 
    469         $days = check_date($yy,$mm,$dd) ? Date_to_Days($yy,$mm,$dd) : undef; 
    470  
    471         return $days; 
    472  
    473 } 
    474 # ========================= 
    475 sub getTableRefs { 
    476         my ($person) = @_; 
    477         # cut whitespaces 
    478         $person=~s/\s+$//; 
    479  
    480         my $ptableref = $table{$person}; 
    481         my $ltableref = $locationtable{$person}; 
    482         my $itableref = $icontable{$person}; 
    483  
    484         if (!defined $ptableref) { 
    485                 $ptableref=[]; 
    486                 $table{$person}=$ptableref; 
    487                 $ltableref=[]; 
    488                 $locationtable{$person}=$ltableref; 
    489                 $itableref=[]; 
    490                 $icontable{$person}=$itableref; 
    491         } 
    492  
    493         return ($ptableref, $ltableref, $itableref); 
    494          
    495 } 
    496 # ========================= 
    497 sub handleDateRange { 
    498         my ($person, $start, $end, $descr, $location, $icon, $excref) = @_; 
    499  
    500         my ($ptableref,$ltableref,$itableref) = &getTableRefs($person); 
    501  
    502         my  $date = $startDays; 
    503         for (my $i=0; ($i < $options{days}) && (($date+$i)<=$end); $i++) { 
    504                 next if $$excref[$i]; 
    505                 if (($date+$i)>=$start) { 
    506                         $$ltableref[$i]{descr}=$descr; 
    507                         $$ltableref[$i]{location}=$location; 
    508                         if (defined $icon) { 
    509                                 $$ptableref[$i]=4; 
    510                                 $$itableref[$i]=$icon; 
    511                         } elsif (defined $location) { 
    512                                 $$ptableref[$i]=3; 
    513                         } else { 
    514                                 $$ptableref[$i]= ($start!=$end) ? 1 : 2; 
    515                         } 
    516                 } 
    517         } 
    518 } 
    519 # ========================= 
    520 sub fetchHolidaylist { 
    521         my ($text) = @_; 
    522         %table = ( ); 
    523         %locationtable = ( ); 
    524         %icontable = ( ); 
    525  
    526         my ($dd,$mm,$yy) = &getStartDate(); 
    527  
    528         $startDays = Date_to_Days($yy,$mm,$dd); 
    529          
    530         my ($eyy, $emm, $edd) = Add_Delta_Days($yy,$mm,$dd,$options{days}); 
    531         my ($endDays) = Date_to_Days($eyy,$emm,$edd);  
    532          
    533         my ($line, $descr); 
    534         foreach $line (grep(/$bullet_rx/, split(/\r?\n/, $text))) { 
    535                 my ($person, $start, $end, $location, $icon); 
    536  
    537                 $line =~ s/\s+$//; 
    538                 $line =~ s/$bullet_rx//g;  
    539  
    540                 $descr = $line; 
    541  
    542                 &replaceSpecialDateNotations($line) if $options{compatmode};  
    543  
    544                 my $excref = &fetchExceptions($line, $startDays, $endDays); 
    545  
    546                 if ( ($line =~ m/^$daterange_rx/) || ($line =~ m/^$monthyearrange_rx/) ) { 
    547                         my ($sdate, $edate); 
    548                         ($sdate,$edate,$person,$location,$icon) = split /\s+\-\s+/, $line, 5; 
    549                         ($start, $end ) = ( &getDays($sdate, 0), &getDays($edate, 1) ); 
    550                         next unless (defined $start) && (defined $end); 
    551  
    552                         &handleDateRange($person, $start, $end, $descr, $location, $icon, $excref);  
    553  
    554                 } elsif ( ($line =~ m/^$date_rx/) || ($line =~ m/^$monthyear_rx/) ) { 
    555                         my $date; 
    556                         ($date, $person, $location, $icon) = split /\s+\-\s+/, $line, 4; 
    557                         ($start, $end) = ( &getDays($date,0), &getDays($date,1) ); 
    558                         next unless (defined $start) && (defined $end); 
    559  
    560                         &handleDateRange($person, $start, $end, $descr, $location, $icon, $excref); 
    561                 } elsif ($options{compatmode}) { 
    562                         &handleCalendarEvents($line, $descr, $yy,$mm,$dd, $startDays, $endDays, $excref); 
    563                 } 
    564  
    565         } 
    566         return (\%table, \%locationtable, \%icontable); 
    567 } 
    568 # ========================= 
    569 sub handlePublicHolidays { 
    570         my ($tableRef, $locationTableRef, $iconTableRef) = @_; 
    571         if ($options{enablepubholidays}) { 
    572                 my $all = '!!__@ALL__!!'; 
    573                 $$tableRef{$all} = [ ]; 
    574                 $$locationTableRef{$all} = [ ]; 
    575                 $$iconTableRef{$all} = [ ]; 
    576                 my ($aptableref,$altableref,$aitableref) = ( $$tableRef{$all}, $$locationTableRef{$all}, $$iconTableRef{$all}); 
    577                 for my $person ( keys %{$tableRef} ) { 
    578                         if (($person ne $all) && ($person =~ /\@all/i) ) { 
    579                                 my ($ptableref,$ltableref,$itableref) =  
    580                                         ( $$tableRef{$person}, $$locationTableRef{$person}, $$iconTableRef{$person}); 
    581                                 for ( my $i=0; $i<$options{days}; $i++) { 
    582                                         if (defined $$ptableref[$i]) { 
    583                                                 $$aptableref[$i] = 6; 
    584                                                 $$altableref[$i] = (defined $$ltableref[$i]) ? $$ltableref[$i] : $$ptableref[$i]; 
    585                                                 $$aitableref[$i] = $$itableref[$i]; 
    586                                         } 
    587                                 } 
    588                         } 
    589                 }        
    590         } 
    591         return ($tableRef, $locationTableRef, $iconTableRef); 
    592 } 
    593 # ========================= 
    594 sub replaceSpecialDateNotations { 
    595         # replace special (business) notations: 
    596         ### DDD Wn yyyy 
    597         ### DDD Week n yyyy 
    598         $_[0] =~s /($dow_rx)\s+W(eek)?\s*([0-9]?[0-9])\s+($year_rx)/getFullDateFromBusinessDate($1,$3,$4)/egi; 
    599         ### Wn yyyy 
    600         ### Week n yyyy 
    601         $_[0] =~s /W(eek)?\s*([0-9]?[0-9])\s+($year_rx)/getFullDateFromBusinessDate('Mon',$2,$3)/egi; 
    602 } 
    603 # ========================= 
    604 sub fetchExceptions { 
    605         my ($line, $startDays, $endDays) = @_; 
    606  
    607         my @exceptions = ( ); 
    608  
    609         $_[0] =~s /X\s+{\s*([^}]+)\s*}// || return \@exceptions; 
    610         my $ex=$1; 
    611  
    612  
    613         for my $x ( split /\s*\,\s*/, $ex ) { 
    614                 my ($start, $end) = (undef, undef); 
    615                 if (($x =~ m/^$daterange_rx$/)||($x =~ m/^$monthyearrange_rx/)) { 
    616                         my ($sdate,$edate) = split /\s*\-\s*/, $x; 
    617                         $start = &getDays($sdate,0); 
    618                         $end = &getDays($edate,1); 
    619  
    620                 } elsif (($x =~ m/^$date_rx/)||($x =~ m/^$monthyear_rx/)) { 
    621                         $start = &getDays($x,0); 
    622                         $end = &getDays($x, 1); 
    623                 } 
    624                 next unless defined $start && ($start <= $endDays); 
    625                 next unless defined $end &&   ($end >= $startDays); 
    626  
    627                 for (my $i=0; ($i<$options{days})&&(($startDays+$i)<=$end); $i++) { 
    628                         $exceptions[$i] = 1 if ( (($startDays+$i)>=$start) && (($startDays+$i)<=$end) ); 
    629                 } 
    630         } 
    631  
    632         return \@exceptions; 
    633 } 
    634 # ========================= 
    635 sub getFullDateFromBusinessDate { 
    636         my($t_dow, $week, $year) = @_; 
    637         my ($ret); 
    638         my ($y1,$m1,$d1); 
    639         if (check_business_date($year, $week, $daysofweek{$t_dow})) { 
    640                 ($y1, $m1, $d1) = Business_to_Standard($year,$week,$daysofweek{$t_dow}); 
    641                 $ret = "$d1 ".Month_to_Text($m1)." $y1"; 
    642         } 
    643         return $ret; 
    644 } 
    645 # ========================= 
    646 sub handleCalendarEvents { 
    647         my ($line, $descr, $yy,$mm,$dd, $startDays, $endDays, $excref) = @_; 
    648         my ($strdate, $person, $location, $icon); 
    649  
    650         if  ($line =~ m/^A\s+$date_rx/) { 
    651                 ### Yearly: A dd MMM yyyy 
    652                 ($strdate, $person, $location, $icon) = split /\s+\-\s+/, $line, 4; 
    653                 my ($ptableref,$ltableref,$itableref) = &getTableRefs($person); 
    654                 $strdate=~s/^A\s+//; 
    655                 my ($dd1, $mm1, $yy1) = split /\s+/, $strdate; 
    656                 $mm1 = $months{$mm1}; 
    657  
    658                 return unless check_date($yy1, $mm1, $dd1); 
    659  
    660                 for (my $i=0; $i < $options{days}; $i++) { 
    661                         next if $$excref[$i]; 
    662                         my ($y,$m,$d) = Add_Delta_Days($yy,$mm,$dd,$i); 
    663                          
    664                         if (($mm1==$m) && ($dd1==$d)) { 
    665                                 $$ptableref[$i] = 5; 
    666                                 $$ltableref[$i]{descr} = $descr . ' ('.($y-$yy1).')'; 
    667                                 $$ltableref[$i]{location} = $location; 
    668                                 $$itableref[$i] = $icon; 
    669                         } 
    670                 } 
    671         } elsif ($line =~ m/^$day_rx\s+($months_rx)/) { 
    672                 ### Interval: dd MMM 
    673                 ($strdate, $person, $location, $icon) = split /\s+\-\s+/, $line, 4; 
    674                 my ($ptableref,$ltableref,$itableref) = &getTableRefs($person); 
    675                 my ($dd1, $mm1) = split /\s+/, $strdate; 
    676                 $mm1 = $months{$mm1}; 
    677                 return if $dd1>31; 
    678  
    679                 for (my $i=0; $i < $options{days}; $i++) { 
    680                         next if $$excref[$i]; 
    681                         my ($y,$m,$d) = Add_Delta_Days($yy,$mm,$dd,$i); 
    682                         if (($m==$mm1)&&($d==$dd1)) { 
    683                                 $$ptableref[$i] = 5; 
    684                                 $$ltableref[$i]{descr} = $descr; 
    685                                 $$ltableref[$i]{location} = $location; 
    686                                 $$itableref[$i] = $icon; 
    687                         } 
    688                 } 
    689         } elsif ($line =~ m/^[0-9L](\.|th)?\s+($dow_rx)(\s+($months_rx))?/) { 
    690                 ### Interval: w DDD MMM  
    691                 ### Interval: L DDD MMM  
    692                 ### Monthly: w DDD 
    693                 ### Monthly: L DDD 
    694  
    695                 ($strdate, $person, $location, $icon) = split /\s+\-\s+/, $line, 4; 
    696                 my ($ptableref,$ltableref,$itableref) = &getTableRefs($person); 
    697                 my ($n1,$dow1,$mm1) = split /\s+/, $strdate; 
    698                 $dow1 = $daysofweek{$dow1}; 
    699                 $mm1 = $months{$mm1} if defined $mm1; 
    700  
    701                 for (my $i=0; $i < $options{days}; $i++) { 
    702                         next if $$excref[$i]; 
    703                         my ($y,$m,$d) = Add_Delta_Days($yy,$mm,$dd,$i); 
    704                         if ((! defined $mm1) || ($m == $mm1)) { 
    705                                 my ($yy2,$mm2,$dd2); 
    706                                 if ($n1 eq 'L') { 
    707                                         $n1 = 6; 
    708                                         do { 
    709                                                 $n1--; 
    710                                                 ($yy2, $mm2, $dd2)=Nth_Weekday_of_Month_Year($y, $m, $dow1, $n1);  
    711                                         } until ($yy2); 
    712                                 } else { 
    713                                         eval { # may fail with a illegal factor 
    714                                                 ($yy2, $mm2, $dd2) = Nth_Weekday_of_Month_Year($y, $m, $dow1, $n1); 
    715                                         }; 
    716                                         next if $@; 
    717                                 } 
    718  
    719                                 if (($dd2)&&($dd2==$d)) { 
    720                                         $$ptableref[$i] = 5; 
    721                                         $$ltableref[$i]{descr} = $descr; 
    722                                         $$ltableref[$i]{location} = $location; 
    723                                         $$itableref[$i] = $icon; 
    724                                 } 
    725                         } 
    726                 } 
    727         } elsif ($line =~ m/^$day_rx\s+\-/) { 
    728                 ### Monthly: dd 
    729                 ($strdate, $person, $location, $icon) = split /\s+\-\s+/, $line, 4; 
    730                 my ($ptableref,$ltableref,$itableref) = &getTableRefs($person); 
    731                 return if $strdate > 31; 
    732                 for (my $i=0; $i < $options{days}; $i++) { 
    733                         next if $$excref[$i]; 
    734                         my ($y,$m,$d) = Add_Delta_Days($yy,$mm,$dd,$i); 
    735                         if ($strdate == $d) { 
    736                                 $$ptableref[$i] = 5; 
    737                                 $$ltableref[$i]{descr} = $descr; 
    738                                 $$ltableref[$i]{location} = $location; 
    739                                 $$itableref[$i] = $icon; 
    740                         } 
    741                 } 
    742         } elsif ($line =~ m/^E\s+($dow_rx)/) { 
    743                 ### Monthly: E DDD dd MMM yyy - dd MMM yyyy 
    744                 ### Monthly: E DDD dd MMM yyy 
    745                 ### Monthly: E DDD 
    746  
    747                 my $strdate2 = undef; 
    748                 if ($line =~ m/^E\s+($dow_rx)\s+$daterange_rx/) { 
    749                         ($strdate, $strdate2, $person, $location, $icon) = split /\s+\-\s+/, $line, 5; 
    750                 } else { 
    751                         ($strdate, $person, $location, $icon) = split /\s+\-\s+/, $line, 4; 
    752                 } 
    753                 my ($ptableref,$ltableref,$itableref) = &getTableRefs($person);  
    754  
    755                 $strdate=~s/^E\s+//; 
    756                 my ($dow1) = split /\s+/, $strdate; 
    757                 $dow1=$daysofweek{$dow1}; 
    758  
    759                 $strdate=~s/^\S+\s*//; 
    760  
    761                 my ($start, $end) = (undef, undef); 
    762                 if ((defined $strdate)&&($strdate ne "")) { 
    763                         $start = &getDays($strdate); 
    764                         return unless defined $start; 
    765                 } 
    766  
    767                 if (defined $strdate2) { 
    768                         $end = &getDays($strdate2); 
    769                         return unless defined $end; 
    770                 } 
    771  
    772                 return if (defined $start) && ($start > $endDays); 
    773                 return if (defined $end) && ($end < $startDays); 
    774  
    775                 for (my $i=0; $i < $options{days}; $i++) { 
    776                         next if $$excref[$i]; 
    777                         my ($y,$m,$d) = Add_Delta_Days($yy,$mm,$dd,$i); 
    778                         my $date = Date_to_Days($y,$m,$d); 
    779                         my $dow = Day_of_Week($y, $m, $d); 
    780                         if ( ($dow==$dow1) 
    781                             && ( (!defined $start) || ($date>=$start) ) 
    782                             && ( (!defined $end)   || ($date<=$end) ) 
    783                            ) { 
    784                                 $$ptableref[$i] = 5; 
    785                                 $$ltableref[$i]{descr} = $descr; 
    786                                 $$ltableref[$i]{location} = $location; 
    787                                 $$itableref[$i] = $icon; 
    788                         } 
    789                 } 
    790  
    791         } elsif ($line =~ m/^E\d+\s+$date_rx/) { 
    792                 ### Periodic: En dd MMM yyyy - dd MMM yyyy 
    793                 ### Periodic: En dd MMM yyyy 
    794                 my $strdate2 = undef; 
    795                 if ($line =~ m/^E\d+\s+$daterange_rx/) { 
    796                         ($strdate, $strdate2, $person, $location, $icon) = split /\s+\-\s+/, $line, 5; 
    797                 } else { 
    798                         ($strdate, $person, $location, $icon) = split /\s+\-\s+/, $line, 4; 
    799                 } 
    800                 my ($ptableref,$ltableref,$itableref) = &getTableRefs($person); 
    801  
    802                 $strdate=~s/^E//; 
    803                 my ($n1) = split /\s+/, $strdate; 
    804  
    805                 return unless $n1 > 0; 
    806  
    807                 $strdate=~s/^\d+\s+//; 
    808  
    809                 my ($start, $end) = (undef, undef); 
    810                 my ($dd1, $mm1, $yy1) = split /\s+/, $strdate; 
    811                 $mm1 = $months{$mm1}; 
    812  
    813                 $start = &getDays($strdate); 
    814                 return unless defined $start; 
    815  
    816                 $end = &getDays($strdate2) if defined $strdate2; 
    817                 return if (defined $strdate2)&&(!defined $end); 
    818  
    819                 return if (defined $start) && ($start > $endDays); 
    820                 return if (defined $end) && ($end < $startDays); 
    821  
    822                 if ( $start < $startDays ) { 
    823                         ($yy1, $mm1, $dd1) = Add_Delta_Days($yy1, $mm1, $dd1,  
    824                         ### $n1 * int( (abs($startDays-$start)/$n1) + ($startDays-$start!=0?1:0) ) ); 
    825                                 $n1 * int( (abs($startDays-$start)/$n1) + ((abs($startDays-$start) % $n1)!=0?1:0) ) ); 
    826                         $start = Date_to_Days($yy1, $mm1, $dd1); 
    827                 } 
    828  
    829                 # start at first occurence and increment by repeating count ($n1) 
    830                 for (my $i=(abs($startDays-$start) % $n1); (($i < $options{days})&&((!defined $end) || ( ($startDays+$i) <= $end)) ); $i+=$n1) { 
    831                         next if $$excref[$i]; 
    832                         if (($startDays+$i) >= $start) { 
    833                                 $$ptableref[$i] = 5; 
    834                                 $$ltableref[$i]{descr} = $descr; 
    835                                 $$ltableref[$i]{location} = $location; 
    836                                 $$itableref[$i] = $icon; 
    837                         } 
    838                 } # for 
    839         } # if 
    840  
    841 } # sub handleCalendarEvents 
    842 # ========================= 
    843 sub mystrftime($$$$) { 
    844         my ($yy,$mm,$dd,$format) = @_; 
    845         my $text = defined $format ? $format : $options{headerformat}; 
    846  
    847         my $dow = Day_of_Week($yy,$mm,$dd); 
    848         my $t_dow =  undef; 
    849         if (defined $options{daynames}) { 
    850                 my @dn = split  /\|/, $options{daynames}; 
    851                 $t_dow = $dn[$dow-1] if $#dn == 6; 
    852         } 
    853         $t_dow = Day_of_Week_to_Text($dow) unless defined $t_dow; 
    854  
    855         my $t_mm = undef;;  
    856         if (defined $options{monthnames}) { 
    857                 my @mn = split /\|/, $options{monthnames}; 
    858                 $t_mm = $mn[$mm-1] if $#mn == 11; 
    859         } 
    860         $t_mm = Month_to_Text($mm) unless defined $t_mm; 
    861  
    862         my $doy = Day_of_Year($yy,$mm,$dd); 
    863         my $wn = Week_Number($yy,$mm,$dd); 
    864         my $t_wn = $wn<10?"0$wn":$wn; 
    865  
    866         my $y = substr("$yy",-2,2); 
    867  
    868         my %tmap = ( 
    869                         '%a'    => substr($t_dow, 0, 2), '%A'   => $t_dow, 
    870                         '%b'    => substr($t_mm,0,3), '%B'      => $t_mm, 
    871                         '%c'    => Date_to_Text_Long($yy,$mm,$dd), '%C' => This_Year(), 
    872                         '%d'    => $dd<10?"0$dd":$dd, '%D' => "$mm/$dd/$yy", 
    873                         '%e'    => $dd, 
    874                         '%F'    => "$yy-$mm-$dd", 
    875                         '%g'    => $y, '%G' => $yy, 
    876                         '%h'    => substr($t_mm,0,3), 
    877                         '%j'    => ($doy<100)? (($doy<10)?"00$doy":"0$doy") : $doy, 
    878                         '%m'    => ($mm<10)?"0$mm":$mm, 
    879                         '%n'    => '<br/>', 
    880                         '%t'    => "<code>\t</code>", 
    881                         '%u'    => $dow, '%U' => $t_wn, 
    882                         '%V'    => $t_wn, 
    883                         '%w'    => $dow-1, '%W' => $t_wn, 
    884                         '%x'    => Date_to_Text($yy,$mm,$dd), 
    885                         '%y'    => $y,  '%Y' => $yy, 
    886                         '%%'    => '%' 
    887                 ); 
    888          
    889         # replace all known conversion specifiers: 
    890         $text =~ s/(%[a-z\%\+]?)/(defined $tmap{$1})?$tmap{$1}:$1/ieg; 
    891  
    892         return $text; 
    893 } 
    894 # ========================= 
    895 sub renderHolidaylist() { 
    896         my ($tableRef, $locationTableRef, $iconTableRef) = @_; 
    897         my $text = ""; 
    898  
    899         my ($ty,$tm,$td) = Today(); 
    900         my $today = Date_to_Days($ty,$tm,$td); 
    901  
    902  
    903         my $optionrow = $options{showoptions}?renderOptions() : ''; 
    904  
    905         # create table header: 
    906          
    907         $text .=  $optionrow if ($options{optionspos}=~/^(top|both)$/i); 
    908         $text .= '<noautolink>'.CGI::a({-name=>'hlpid'.$hlid},""); 
    909         $text .= CGI::start_table({-class=>'holidaylistPluginTable', -border=>$options{border}, -cellpadding=>$options{cellpadding}, 
    910                                         -cellspacing=>$options{cellspacing}, -bgcolor=>$options{tablebgcolor}, -width=>$options{width}}); 
    911  
    912         $text .= CGI::caption({-align=>$options{tablecaptionalign}}, $options{tablecaption}); 
    913  
    914         my $header = ""; 
    915         my $namecell = ""; 
    916         $namecell .= CGI::th({-align=>'left',-width=>$options{nwidth}, -rowspan=>($options{showmonthheader}?2:1) }, 
    917                         $options{name}.($options{'navenable'}?&renderNav(-1).&renderNav(0).&renderNav(1):'')); 
    918  
    919         my ($dd,$mm,$yy) = getStartDate(); 
    920          
    921         # render month header: 
    922         my $monthheader = ""; 
    923         if ($options{showmonthheader}) { 
    924                 my $restdays = $options{days}; 
    925                 my ($yy1,$mm1,$dd1) = ($yy, $mm, $dd); 
    926                 while ($restdays > 0) { 
    927                         my $daysdiff = Days_in_Month($yy1,$mm1) - $dd1 + 1; 
    928                         $daysdiff = $restdays if ($restdays-$daysdiff<0); 
    929                         $monthheader .= CGI::th({-colspan=>$daysdiff, -align=>'center', -title=> Month_to_Text($mm1).' '.$yy1}, &mystrftime($yy1,$mm1,$dd1,$options{monthheaderformat})); 
    930                         ($yy1,$mm1,$dd1) = Add_Delta_Days($yy1,$mm1,$dd1, $daysdiff); 
    931                         $restdays -= $daysdiff; 
    932                 } 
    933                 if ($options{showstatcol}) { 
    934                         foreach my $h (split(/\|/,getStatOption('statheader','statcolheader'))) { 
    935                                 $monthheader .= CGI::th({-valign=>'bottom', -align=>'center', rowspan=>2, -bgcolor=>$options{tableheadercolor}}, $h); 
    936                         } 
    937                 } 
    938         } 
    939  
    940         # render header: 
    941  
    942         for (my $i=0; $i< $options{days}; $i++) { 
    943                 my ($yy1,$mm1,$dd1) = Add_Delta_Days($yy, $mm, $dd, $i); 
    944                 my $dow = Day_of_Week($yy1,$mm1,$dd1); 
    945                 my $date = Date_to_Days($yy1, $mm1, $dd1); 
    946  
    947                 my $bgcolor = $options{tableheadercolor}; 
    948                 $bgcolor=$options{weekendbgcolor} unless $dow < 6; 
    949                 $bgcolor=$options{todaybgcolor} if (defined $options{todaybgcolor})&&($today == $date); 
    950                  
    951                 my %params = ( -align=>'center', -bgcolor=>$bgcolor, -title=>Date_to_Text_Long($yy1,$mm1,$dd1) ); 
    952                 $params{-width}=$options{tcwidth} if ((defined $options{tcwidth})&&(($dow<6)||$options{showweekends})); 
    953                 $params{-style}='color:'.$options{todayfgcolor} if ($today==$date)&&(defined $options{todayfgcolor}); 
    954                 $header .= CGI::th(\%params, (($dow < 6)|| $options{showweekends}) ? &mystrftime($yy1,$mm1,$dd1) : '&nbsp;'); 
    955         } 
    956         if ((!$options{showmonthheader}) && $options{showstatcol}) { 
    957                 foreach my $h (split(/\|/,getStatOption('statheader','statcolheader'))) { 
    958                         $header.=CGI::th({-valign=>'bottom',-align=>'center',-bgcolor=>$options{tableheadercolor}}, $h); 
    959                 } 
    960          
    961         } 
    962         $text .= CGI::Tr({-bgcolor=>$options{tableheadercolor}}, ($options{namepos}=~/^(left|both)$/i?$namecell:'').$monthheader.($options{namepos}=~/^(right|both)$/i?$namecell:'')).CGI::Tr($header) if $options{showmonthheader}; 
    963         $text .= CGI::Tr({-bgcolor=>$options{tableheadercolor}}, ($options{namepos}=~/^(left|both)$/i?$namecell:'').$header.($options{namepos}=~/^(right|both)$/i?$namecell:'')) unless $options{showmonthheader}; 
    964  
    965         # create table with names and dates: 
    966  
    967         my %iconstates = ( 0 => $options{workicon}, 
    968                            1 => $options{holidayicon}, 
    969                            2 => $options{adayofficon}, 
    970                            3 => $options{notatworkicon}, 
    971                            4 => $options{notatworkicon}, 
    972                            5 => $options{compatmodeicon}, 
    973                            6 => $options{pubholidayicon} 
    974                         ); 
    975  
    976         my @rowcolors = defined $options{rowcolors} ? split(/[\,\|\;\:]/, $options{rowcolors}) : ( $options{tablebgcolor} ); 
    977         my %namecolors = %{ _getNameColors() }; 
    978  
    979         my %sumstatistics; 
    980         my %rowstatistics; 
    981         foreach my $person ( @{_reorderPersons($tableRef)} ) { 
    982                 my $ptableref=$$tableRef{$person}; 
    983                 my $ltableref=$$locationTableRef{$person}; 
    984                 my $itableref=$$iconTableRef{$person}; 
    985  
    986                 my $aptableref=$$tableRef{'!!__@ALL__!!'}; 
    987                 my $altableref=$$locationTableRef{'!!__@ALL__!!'}; 
    988                 my $aitableref=$$iconTableRef{'!!__@ALL__!!'}; 
    989  
    990  
    991                 # ignore entries with @all 
    992                 next if $options{enablepubholidays} && (!$options{showpubholidays}) && ($person =~ /\@all/i); 
    993                 next if $person eq '!!__@ALL__!!'; 
    994  
    995                 # ignore table rows without an entry if removeatwork == 1 
    996                 next if $options{removeatwork} && !grep(/[^0]+/, join('', map( $_ || 0, @{$ptableref}))); 
    997  
    998  
    999                 my %statistics; 
    1000  
    1001                 my $rowcolor = shift @rowcolors; 
    1002                 push @rowcolors, $rowcolor; 
    1003                 $rowcolor = $namecolors{$person} if defined $namecolors{$person}; 
    1004  
    1005                 $person =~ s/\@all//ig if $options{enablepubholidays}; 
    1006  
    1007                 my $tr = ""; 
    1008                 my $pcell = CGI::th({-align=>'left',-style=>'white-space:nowrap;text-wrap:none;'},'<noautolink>'._renderText($person,$web).'</noautolink>'); 
    1009                 $tr .= $pcell if $options{namepos}=~/^(left|both)$/i; 
    1010  
    1011                 for (my $i=0; $i<$options{days}; $i++) { 
    1012                         my ($yy1, $mm1, $dd1) = Add_Delta_Days($yy, $mm, $dd, $i); 
    1013                         my $dow = Day_of_Week($yy1, $mm1, $dd1); 
    1014  
    1015                         my $bgcolor = $rowcolor; 
    1016                         $bgcolor = $options{weekendbgcolor} unless $dow < 6; 
    1017                         $bgcolor = $options{todaybgcolor} if (defined $options{todaybgcolor}) && ($today == Date_to_Days($yy1, $mm1, $dd1)); 
    1018  
    1019                         my $td = ""; 
    1020  
    1021                         if ($options{enablepubholidays} && defined $$aptableref[$i] && $$aptableref[$i]>0) { 
    1022                                 $statistics{pubholidays}++; 
    1023                                 $rowstatistics{$i}{pubholidays}++; 
    1024                                 $sumstatistics{pubholidays}++; 
    1025                         } 
    1026                         if ((defined $$ptableref[$i] && $$ptableref[$i]>0)  
    1027                                         || ( $options{enablepubholidays} && defined $$aptableref[$i] && $$aptableref[$i]>0)) { 
    1028                                 $statistics{holidays}++; 
    1029                                 $statistics{icons}{$$itableref[$i]}++ if defined $$itableref[$i];  
    1030                                 $statistics{icons}{$options{statformat_unknown}}++ if ! defined $$itableref[$i];  
    1031                                 $statistics{locations}{$$ltableref[$i]{location}}++ if defined $$ltableref[$i]{location}; 
    1032                                 $statistics{locations}{$options{statformat_unknown}}++ if ! defined $$ltableref[$i]{location}; 
    1033                                 $rowstatistics{$i}{holidays}++; 
    1034                                 $rowstatistics{$i}{icons}{$$itableref[$i]}++ if defined $$itableref[$i];  
    1035                                 $rowstatistics{$i}{icons}{$options{statformat_unknown}}++ if ! defined $$itableref[$i];  
    1036                                 $rowstatistics{$i}{locations}{$$ltableref[$i]{location}}++ if defined $$ltableref[$i]{location}; 
    1037                                 $rowstatistics{$i}{locations}{$options{statformat_unknown}}++ if ! defined $$ltableref[$i]{location}; 
    1038                                 $sumstatistics{holidays}++; 
    1039                                 $sumstatistics{icons}{$$itableref[$i]}++ if defined $$itableref[$i];  
    1040                                 $sumstatistics{icons}{$options{statformat_unknown}}++ if ! defined $$itableref[$i];  
    1041                                 $sumstatistics{locations}{$$ltableref[$i]{location}}++ if defined $$ltableref[$i]{location}; 
    1042                                 $sumstatistics{locations}{$options{statformat_unknown}}++ if !defined $$ltableref[$i]{location}; 
    1043                                  
    1044                         } else { 
    1045                                 $statistics{work}++; 
    1046                                 $rowstatistics{$i}{work}++; 
    1047                                 $sumstatistics{work}++; 
    1048                         } 
    1049                         $statistics{days}++; 
    1050                         $statistics{'days-w'}++ if $dow < 6; 
    1051                         $rowstatistics{$i}{days}=1; 
    1052                         $rowstatistics{$i}{'days-w'}=1; 
    1053                         $sumstatistics{days}++; 
    1054                         $sumstatistics{'days-w'}++ if $dow < 6; 
    1055  
    1056                  
    1057                         my $title = substTitle($person .' / '.Date_to_Text_Long($yy1,$mm1,$dd1)); 
    1058                         my $fgcolor = undef; 
    1059  
    1060                         if (($dow < 6)||$options{showweekends}) {  
    1061                                 my $icon= $iconstates{ defined $$ptableref[$i]?$$ptableref[$i]:0}; 
    1062                                 if ($dow<6 && $options{enablepubholidays} && defined $$aptableref[$i] && $$aptableref[$i]>0) { 
    1063                                         $statistics{'pubholidays-w'}++; 
    1064                                         $rowstatistics{$i}{'pubholidays-w'}++; 
    1065                                         $sumstatistics{'pubholidays-w'}++; 
    1066                                 } 
    1067                          
    1068  
    1069                                 # override personal holidays with public holidays: 
    1070                                 if ($options{enablepubholidays} && defined $$aptableref[$i]) { 
    1071                                         $icon = $iconstates{$$aptableref[$i]}; 
    1072                                         $$itableref[$i]=$$aitableref[$i]; 
    1073                                         $$ltableref[$i]=$$altableref[$i]; 
    1074                                 } 
    1075  
    1076  
    1077                                 if ($dow < 6 && defined $$ptableref[$i] && $$ptableref[$i]>0 && ( (!defined $$aptableref[$i]) || ($$aptableref[$i]<=0))) { 
    1078                                         $statistics{'holidays-w'}++; 
    1079                                         $statistics{'icons-w'}{(defined $$itableref[$i]?$$itableref[$i]:$icon)}++; 
    1080                                         $statistics{'locations-w'}{$$ltableref[$i]{location}}++ if defined $$ltableref[$i]{location}; 
    1081                                         $statistics{'locations-w'}{$options{statformat_unknown}}++ if ! defined $$ltableref[$i]{location}; 
    1082                                         $rowstatistics{$i}{'holidays-w'}++; 
    1083                                         $rowstatistics{$i}{'icons-w'}{(defined $$itableref[$i]?$$itableref[$i]:$icon)}++; 
    1084                                         $rowstatistics{$i}{'locations-w'}{$$ltableref[$i]{location}}++ if defined $$ltableref[$i]{location}; 
    1085                                         $rowstatistics{$i}{'locations-w'}{$options{statformat_unknown}}++ if ! defined $$ltableref[$i]{location}; 
    1086                                         $sumstatistics{'holidays-w'}++; 
    1087                                         $sumstatistics{'icons-w'}{(defined $$itableref[$i]?$$itableref[$i]:$icon)}++; 
    1088                                         $sumstatistics{'locations-w'}{$$ltableref[$i]{location}}++ if defined $$ltableref[$i]{location}; 
    1089                                         $sumstatistics{'locations-w'}{$options{statformat_unknown}}++ if ! defined $$ltableref[$i]{location}; 
    1090                                 } else { 
    1091                                         $statistics{'work-w'}++; 
    1092                                         $rowstatistics{$i}{'work-w'}++; 
    1093                                         $sumstatistics{'work-w'}++; 
    1094                                 } 
    1095  
    1096  
    1097                                 if (defined $$itableref[$i]) { 
    1098                                         $icon = $$itableref[$i]; 
    1099                                         $icon = _renderText($icon, $web) if $icon !~ /^(\s|\&nbsp\;)*$/; 
    1100                                 } 
    1101  
    1102                                 my $location = $$ltableref[$i]{descr} if defined $ltableref; 
    1103                                 if (defined $location) { 
    1104                                         $location =~ s/\s*(\@all|(fg)?color\([^\)]+\))//ig if $options{enablepubholidays}; # remove @all 
    1105                                         $location=substTitle($location); 
    1106                                         $location=CGI::escapeHTML($location); 
    1107  
    1108                                         $icon=~s/<img /<img alt="$location" /is unless $icon=~s/(<img[^>]+alt=")[^">]+("[^>]*>)/$1$location$2/is; 
    1109                                         $icon=~s/<img /<img title="$location" /is unless $icon=~s/(<img[^>]+title=")[^">]+("[^>]*>)/$1$location$2/is; 
    1110                                         $title=$location if defined $location; 
    1111                                 } 
    1112                                 if ($icon=~s/fgcolor\(([^\)]+)\)//g) { 
    1113                                         $fgcolor = $1; 
    1114                                 } 
    1115                                 if ($icon=~s/color\(([^\)]+)\)//g) { 
    1116                                         $bgcolor=$1; 
    1117                                         $td.= ($icon!~/^\s*$/)?$icon:'&nbsp;'; 
    1118                                 } else { 
    1119                                         $td.= $icon; 
    1120                                 } 
    1121                         } else { 
    1122                                 $td.= '&nbsp;'; 
    1123                         } 
    1124                         $tr .= CGI::td({-align=>'center', -style=>(defined $fgcolor?"color:$fgcolor;":"")."background-color:$bgcolor;", -title=>$title }, $td); 
    1125                 } 
    1126                 $tr .= renderStatisticsCol(\%statistics) if ($options{showstatcol}); 
    1127                 $tr .= $pcell if $options{namepos}=~/^(right|both)$/i; 
    1128                 $text .= CGI::Tr({-bgcolor=>$rowcolor}, $tr); 
    1129         } 
    1130         $text .= renderStatisticsRow(\%rowstatistics, \%sumstatistics) if ($options{showstatrow}); 
    1131         $text .= renderStatisticsSumRow(\%sumstatistics) if ($options{showstatcol}&&(!$options{showstatrow})&&($options{showstatsum})); 
    1132         $text .= CGI::end_table(); 
    1133         $text .=  $optionrow if ($options{optionspos}=~/^(bottom|both)$/i); 
    1134         $text .= '</noautolink>'; 
    1135  
    1136         $text = CGI::div({-class=>'holidayListPluginDiv',-style=>'overflow:auto;'.(defined $options{maxheight}?"max-height:$options{maxheight}":"")},$text); 
    1137  
    1138         return $text; 
    1139 } 
    1140 # ========================= 
    1141 sub _int { 
    1142         return $_[0]=~/(\d+)/ ? $1 : 0; 
    1143 } 
    1144 # ========================= 
    1145 sub _reorderPersons { 
    1146         my ($tableRef) = @_; 
    1147         my @persons = (); 
    1148         if (defined $options{order}) { 
    1149                 if ($options{order} =~ /\[:nextfirst:\]/i) { 
    1150                         @persons = sort { join('', map( $_ || 0, @{$$tableRef{$b}})) cmp join('',map($_ || 0, @{$$tableRef{$a}})) }  keys %{$tableRef}; 
    1151                 } elsif ($options{order} =~/\[:ralpha:\]/) { 
    1152                         @persons = sort { $b cmp $a } keys %{$tableRef}; 
    1153                 } elsif ($options{order} =~/\[:num:\]/) { 
    1154                         @persons = sort { _int($a) <=> _int($b) }  keys %{$tableRef}; 
    1155                 } elsif ($options{order} =~/\[:rnum:\]/) { 
    1156                         @persons = sort { _int($b) <=> _int($a) }  keys %{$tableRef}; 
    1157                 } else { 
    1158                         @persons = split(/\s*[\,\;\|]\s*/, $options{order});  
    1159                         if ($options{order}=~/\[:rest:\]/i) { 
    1160                                 my @rest = (); 
    1161                                 foreach my $p (sort keys %{$tableRef}) { 
    1162                                         push @rest, $p unless grep(/^\Q$p\E$/,@persons); 
    1163                                 } 
    1164                                 my $order = $options{order}; 
    1165                                 $order =~ s/\[:rest:\]/join(',', @rest)/eig; 
    1166                                 @persons = split(/\s*[\,\;\|]\s*/, $order);  
    1167                         } 
    1168                 } 
    1169         } else { 
    1170                 @persons = sort keys %{$tableRef}; 
    1171         } 
    1172         return \@persons; 
    1173  
    1174 } 
    1175 # ========================= 
    1176 sub _getNameColors { 
    1177         my %colors =  ( ); 
    1178         return \%colors unless defined $options{namecolors}; 
    1179         foreach my $entry (split(/\s*[\,\|\;]\s*/, $options{namecolors})) { 
    1180                 my ($name,$color) = split(/\:/,$entry); 
    1181                 $colors{$name}=$color; 
    1182         } 
    1183         return \%colors; 
    1184 } 
    1185 # ========================= 
    1186 sub substTitle { 
    1187         my ($title) =  @_; 
    1188  
    1189         $title =~ s/<!--.*?-->//g; # remove HTML comments 
    1190         $title =~ s/ - <img[^>]+>//ig; # throw image address away 
    1191         $title =~ s/<\/?\S+[^>]*>//g; 
    1192  
    1193         $title =~s /&nbsp;/ /g; 
    1194         $title =~ s/\%(\w+[^\%]+?)\%//g; # delete Vars 
    1195         $title =~ s/\[\[[^\]]+\]\[([^\]]+)\]\]/$1/g; # replace forced link with comment 
    1196         $title =~ s/\[\[([^\]]+)\]\]/$1/g; # replace forced link with comment 
    1197         $title =~ s/\[\[/!\[\[/g; # quote forced links - !!!unused 
    1198         $title =~ s/[A-Z][a-z0-9]+[\.\/]([A-Z])/$1/g; # delete Web names 
    1199         ##$title =~ s/([A-Z][a-z]+\w*[A-Z][a-z0-9]+)/$1/g; # quote WikiNames 
    1200         return $title; 
    1201 } 
    1202 # ========================= 
    1203 sub substStatisticsVars { 
    1204         my ($textformat, $titleformat, $statisticsref ) = @_; 
    1205         return (_substStatisticsVars($textformat, $statisticsref), substTitle(_substStatisticsVars($titleformat,$statisticsref))); 
    1206 } 
    1207  
    1208 # ========================= 
    1209 sub _substStatisticsVars { 
    1210         my ($textformat, $statisticsref) = @_; 
    1211  
    1212         my $text = $textformat; 
    1213  
    1214  
    1215         $statisticsref = { } unless defined $statisticsref; 
    1216  
    1217         my %statistics = %{$statisticsref}; 
    1218  
    1219         if ($textformat=~/\%{ll:?}/i) { 
    1220                 my $t=""; 
    1221                 foreach my $location (sort keys %{$statistics{'locations-w'}}) { 
    1222                         my $f=$options{statformat_ll}; 
    1223                         $f=~s/\%LOCATION/$location/g; 
    1224                         $t.=$f; 
    1225                 } 
    1226                 $text=~s/\%{ll:?}/$t/g; 
    1227         } 
    1228         if ($textformat=~/\%{l}/i) { 
    1229                 my $t=""; 
    1230                 foreach my $location (sort keys %{$statistics{'locations'}}) { 
    1231                         my $f=$options{statformat_l}; 
    1232                         $f=~s/\%LOCATION/$location/g; 
    1233                         $t.=$f; 
    1234                 } 
    1235                 $text=~s/\%{l:?}/$t/g; 
    1236         } 
    1237         if ($textformat=~/\%{ii:?}/i) { 
    1238                 my $t=""; 
    1239                 foreach my $icon (keys %{$statistics{'icons-w'}}) { 
    1240                         my $f=$options{statformat_ii}; 
    1241                         $f=~s/\%ICON/$icon/g; 
    1242                         $t.=$f; 
    1243                 } 
    1244                 $text=~s/\%{ii:?}/$t/g; 
    1245         } 
    1246         if ($textformat=~/\%{i:?}/i) { 
    1247                 my $t=""; 
    1248                 foreach my $icon (keys %{$statistics{'icons-w'}}) { 
    1249                         my $f=$options{statformat_i}; 
    1250                         $f=~s/\%ICON/$icon/g; 
    1251                         $t.=$f; 
    1252                 } 
    1253                 $text=~s/\%{i:?}/$t/g; 
    1254         } 
    1255         sub _vz { 
    1256                 return defined $_[0]?$_[0]:defined $options{statformat_0}?$options{statformat_0}:0; 
    1257         }; 
    1258         $text=~s/\%{i:([^}]+)}/_vz($statistics{icons}{$1})/egi; 
    1259         $text=~s/\%{ii:([^}]+)}/_vz($statistics{'icons-w'}{$1})/egi; 
    1260         $text=~s/\%{l:([^}]+)}/_vz($statistics{locations}{$1})/egi; 
    1261         $text=~s/\%{ll:([^}]+)}/_vz($statistics{'locations-w'}{$1})/egi; 
    1262  
    1263         $text=~s/\%hh/_vz($statistics{'holidays-w'})/egi; 
    1264         $text=~s/\%h/_vz($statistics{holidays})/egi; 
    1265         $text=~s/\%{h:?}/_vz($statistics{holidays})/egi; 
    1266         $text=~s/\%{hh:?}/_vz($statistics{'holidays-w'})/egi; 
    1267  
    1268         $text=~s/\%pp/_vz($statistics{'pubholidays-w'})/egi; 
    1269         $text=~s/\%p/_vz($statistics{pubholidays})/egi; 
    1270         $text=~s/\%{p:?}/_vz($statistics{pubholidays})/egi; 
    1271         $text=~s/\%{pp:?}/_vz($statistics{'pubholidays-w'})/egi; 
    1272  
    1273         $text=~s/\%ww/_vz($statistics{'work-w'})/egi; 
    1274         $text=~s/\%w/_vz($statistics{work})/egi; 
    1275         $text=~s/\%{w:?}/_vz($statistics{work})/egi; 
    1276         $text=~s/\%{ww:?}/_vz($statistics{'work-w'})/egi; 
    1277  
    1278         $text=~s/\%dd/_vz($statistics{'days-w'})/egi; 
    1279         $text=~s/\%d/_vz($statistics{days})/egi; 
    1280         $text=~s/\%{d:?}/_vz($statistics{days})/egi; 
    1281         $text=~s/\%{dd:?}/_vz($statistics{'days-w'})/egi; 
    1282  
    1283  
    1284         # percentages: 
    1285         sub _dz { 
    1286                 return defined $_[0]?$_[0]:0; 
    1287         }; 
    1288         sub _perc { 
    1289                 return _dz($_[1])==0 ? "n.d." : sprintf($options{statformat_perc},(_dz($_[0]) * 100 / _dz($_[1]))); 
    1290         } 
    1291         # locations to days: 
    1292         $text=~s/\%{ld:([^}]+)}/_perc($statistics{locations}{$1}, $statistics{days})/egi; 
    1293         $text=~s/\%{ldd:([^}]+)}/_perc($statistics{locations}{$1}, $statistics{'days-w'})/egi; 
    1294         $text=~s/\%{lld:([^}]+)}/_perc($statistics{locations}{$1}, $statistics{days})/egi; 
    1295         $text=~s/\%{lldd:([^}]+)}/_perc($statistics{locations}{$1}, $statistics{'days-w'})/egi; 
    1296  
    1297         # locations to holidays: 
    1298         $text=~s/\%{lh:([^}]+)}/_perc($statistics{locations}{$1}, $statistics{holidays})/egi; 
    1299         $text=~s/\%{lhh:([^}]+)}/_perc($statistics{locations}{$1}, $statistics{'holidays-w'})/egi; 
    1300         $text=~s/\%{llh:([^}]+)}/_perc($statistics{locations}{$1}, $statistics{holidays})/egi; 
    1301         $text=~s/\%{llhh:([^}]+)}/_perc($statistics{locations}{$1}, $statistics{'holidays-w'})/egi; 
    1302  
    1303         # icons to days: 
    1304         $text=~s/\%{id:([^}]+)}/_perc($statistics{icons}{$1}, $statistics{days})/egi; 
    1305         $text=~s/\%{idd:([^}]+)}/_perc($statistics{icons}{$1}, $statistics{'days-w'})/egi; 
    1306         $text=~s/\%{iid:([^}]+)}/_perc($statistics{icons}{$1}, $statistics{days})/egi; 
    1307         $text=~s/\%{iidd:([^}]+)}/_perc($statistics{icons}{$1}, $statistics{'days-w'})/egi; 
    1308  
    1309         # icons to holidays: 
    1310         $text=~s/\%{ih:([^}]+)}/_perc($statistics{icons}{$1}, $statistics{holidays})/egi; 
    1311         $text=~s/\%{ihh:([^}]+)}/_perc($statistics{icons}{$1}, $statistics{'holidays-w'})/egi; 
    1312         $text=~s/\%{iih:([^}]+)}/_perc($statistics{icons}{$1}, $statistics{holidays})/egi; 
    1313         $text=~s/\%{iihh:([^}]+)}/_perc($statistics{icons}{$1}, $statistics{'holidays-w'})/egi; 
    1314  
    1315         # holidays to days: 
    1316         $text=~s/\%{hd:?}/_perc($statistics{holidays},$statistics{days})/egi; 
    1317         $text=~s/\%{hdd:?}/_perc($statistics{holidays},$statistics{'days-w'})/egi; 
    1318         $text=~s/\%{hhd:?}/_perc($statistics{'holidays-w'}, $statistics{days})/egi; 
    1319         $text=~s/\%{hhdd:?}/_perc($statistics{'holidays-w'}, $statistics{'days-w'})/egi; 
    1320  
    1321         # public holidays to days: 
    1322         $text=~s/\%{pd:?}/_perc($statistics{pubholidays},$statistics{days})/egi; 
    1323         $text=~s/\%{pdd:?}/_perc($statistics{pubholidays},$statistics{'days-w'})/egi; 
    1324         $text=~s/\%{ppd:?}/_perc($statistics{'pubholidays-w'}, $statistics{days})/egi; 
    1325         $text=~s/\%{ppdd:?}/_perc($statistics{'pubholidays-w'}, $statistics{'days-w'})/egi; 
    1326  
    1327         # working days to days: 
    1328         $text=~s/\%{wd:?}/_perc($statistics{work}, $statistics{days})/egi; 
    1329         $text=~s/\%{wdd:?}/_perc($statistics{work}, $statistics{'days-w'})/egi; 
    1330         $text=~s/\%{wwd:?}/_perc($statistics{'work-w'}, $statistics{days})/egi; 
    1331         $text=~s/\%{wwdd:?}/_perc($statistics{'work-w'}, $statistics{'days-w'})/egi; 
    1332          
    1333         return $text; 
    1334 } 
    1335 # ========================= 
    1336 sub getStatOption { 
    1337         return (defined $options{$_[0]}) ? $options{$_[0]} : $options{$_[1]}; 
    1338 } 
    1339 # ========================= 
    1340 sub renderStatisticsSumRow { 
    1341         my ($sumstatisticsref) = @_; 
    1342         my $cgi=Foswiki::Func::getCgiQuery(); 
    1343         my $text = ""; 
    1344         my $row=""; 
    1345         my @stattitles=split(/\|/,getStatOption('stattitle','statcoltitle')); 
    1346         foreach my $statcol (split(/\|/,getStatOption('statformat','statcolformat'))) { 
    1347                 my $stattitle = shift @stattitles; 
    1348                 $stattitle = getStatOption('stattitle','statcoltitle') unless defined $stattitle; 
    1349                 my ($txt,$t) = substStatisticsVars($statcol, $stattitle, $sumstatisticsref); 
    1350                 $row.=$cgi->th({-valign=>'top', -title=>$t}, $txt); 
    1351         } 
    1352         $row.=$cgi->th('&nbsp;') if $options{namepos}=~/^(right|both)$/i; 
    1353         my $colspan=$options{days}; 
    1354         $colspan++ if $options{namepos}=~/^(left|both)$/i; 
    1355         $text.= $cgi->Tr({-bgcolor=>$options{tableheadercolor}},$cgi->th({-colspan=>$colspan,-align=>'right'},'&nbsp;').$row); 
    1356  
    1357         return $text; 
    1358 } 
    1359 # ========================= 
    1360 sub renderStatisticsRow { 
    1361         my ($statisticsref, $sumstatisticsref) = @_; 
    1362         my $cgi=Foswiki::Func::getCgiQuery(); 
    1363         my $text = ""; 
    1364         my ($dd,$mm,$yy) = getStartDate(); 
    1365  
    1366         my ($ty,$tm,$td) = Today(); 
    1367         my $today = Date_to_Days($ty,$tm,$td); 
    1368  
    1369         my $statrowformat = getStatOption('statformat','statrowformat'); 
    1370         my $statrowtitle  = getStatOption('stattitle', 'statrowtitle'); 
    1371         my $statrowheader = getStatOption('statheader','statrowheader'); 
    1372  
    1373         my @rowformats = split(/\|/, $statrowformat); 
    1374         my @rowheaders = split(/\|/, $statrowheader); 
    1375         my @rowtitles = split(/\|/, $statrowtitle); 
    1376         my $showsums=0; 
    1377         foreach my $rowformat (@rowformats) { 
    1378                 my $rowheader = shift(@rowheaders); 
    1379                 my $rowtitle  = shift(@rowtitles); 
    1380                 $rowheader = $statrowheader unless defined $rowheader; 
    1381                 $rowtitle = $statrowtitle unless defined $rowtitle; 
    1382                 my $row = ""; 
    1383                 for (my $i=0; $i<$options{days}; $i++) { 
    1384                         my ($yy1,$mm1,$dd1) = Add_Delta_Days($yy,$mm,$dd,$i); 
    1385                         my $dow = Day_of_Week($yy1,$mm1,$dd1); 
    1386                         my $date = Date_to_Days($yy1,$mm1,$dd1); 
    1387                         my ($text,$title) = substStatisticsVars($rowformat, $rowtitle, $$statisticsref{$i}); 
    1388                          
    1389                         my $style=""; 
    1390                         $style.="color:$options{todayfgcolor};" if (defined $options{todayfgcolor}) && ($date == $today); 
    1391                         $style.="background-color:$options{todaybgcolor};" if (defined $options{todaybgcolor}) && ($date == $today); 
    1392                         if (($dow<6)||($options{showweekends})) { 
    1393                                 $row.=$cgi->th({-style=>$style,-title=>$title, -valign=>'top', -align=>'center'},$text); 
    1394                         } else { 
    1395                                 $row.=$cgi->th({-style=>$style,-title=>$title},'&nbsp;'); 
    1396                         } 
    1397                 } 
    1398  
    1399                 if ((!$showsums)&&($options{showstatcol})) { 
    1400                         $showsums=1; 
    1401                         my @rowspanf = split(/\|/,$statrowformat); 
    1402                         my $rowspan=$#rowspanf + 1; 
    1403                         if ($options{showstatsum}) { 
    1404                                 my @stattitles=split(/\|/,getStatOption('stattitle','statcoltitle')); 
    1405                                 foreach my $statcol (split(/\|/,getStatOption('statformat','statcolformat'))) { 
    1406                                         my $stattitle = shift @stattitles; 
    1407                                         $stattitle = getStatOption('stattitle','statcoltitle') unless defined $stattitle; 
    1408                                         my ($txt,$t) = substStatisticsVars($statcol, $stattitle, $sumstatisticsref); 
    1409                                         $row.=$cgi->th({-valign=>"top", -rowspan=>$rowspan, -title=>$t}, $txt); 
    1410                                 } 
    1411                         } else { 
    1412                                 my @colspanf = split(/\|/,getStatOption('statformat','statcolformat')); 
    1413                                 my $colspan = $#colspanf + 1; 
    1414                                 $row.=$cgi->th({-rowspan=>$rowspan, -colspan=>$colspan},'&nbsp;'); 
    1415                         } 
    1416                 } 
    1417                  
    1418                 $text.=$cgi->Tr({-bgcolor=>$options{tableheadercolor}},  
    1419                                  ( $options{namepos}=~/^(left|both)$/i ? $cgi->th({-align=>'right', -valign=>'top'},$rowheader) : '') 
    1420                                 .$row 
    1421                                 .( $options{namepos}=~/^(right|both)$/i ? $cgi->th({-align=>'left', -valign=>'top'},$rowheader) : '')); 
    1422         } 
    1423  
    1424         return $text; 
    1425 } 
    1426 # ========================= 
    1427 sub renderStatisticsCol { 
    1428         my ($statisticsref) = @_; 
    1429         my $text=""; 
    1430         my $cgi=Foswiki::Func::getCgiQuery(); 
    1431  
    1432         my @statcoltitles = split(/\|/, getStatOption('stattitle','statcoltitle')); 
    1433         foreach my $statcol (split /\|/, getStatOption('statformat','statcolformat')) { 
    1434                 my $statcoltitle = shift(@statcoltitles); 
    1435                 $statcoltitle=getStatOption('stattitle','statcoltitle') unless defined $statcoltitle; 
    1436                 ($statcol,$statcoltitle)=substStatisticsVars($statcol,$statcoltitle,$statisticsref); 
    1437                 $text.=$cgi->th({-bgcolor=>$options{tableheadercolor}, -class=>"hlpStatisticsColumn", -title=>$statcoltitle, -align=>'right'}, $statcol); 
    1438         } 
    1439         return $text; 
    1440 } 
    1441  
    1442 # ========================= 
    1443 sub renderNav { 
    1444         my ($nextp) = @_; 
    1445         my $nav = ""; 
    1446  
    1447         my $cgi = &Foswiki::Func::getCgiQuery(); 
    1448         my $newcgi = new CGI($cgi); 
    1449         my $newhalfcgi = new CGI($cgi); 
    1450  
    1451         my $days = (defined $options{'navdays'})?$options{'navdays'}:$options{'days'}; 
    1452  
    1453         my $qphlppage = $cgi->param('hlppage'.$hlid); 
    1454         $qphlppage = "0" unless defined $qphlppage; 
    1455         $qphlppage =~ m/^([\+\-]?[\d\.]+)$/; 
    1456         my $hlppage = $1; 
    1457         $hlppage = 0 unless defined $hlppage; 
    1458  
    1459         $hlppage += $nextp; 
    1460         my $halfpage = 0; 
    1461         $halfpage= $hlppage - 0.5 if $nextp==1; 
    1462         $halfpage= $hlppage + 0.5 if $nextp==-1; 
    1463  
    1464         if (($nextp==0)||($hlppage == 0)) { 
    1465                 $newcgi->delete('hlppage'.$hlid); 
    1466         } else { 
    1467                 $newcgi->param(-name=>'hlppage'.$hlid,-value=>$hlppage); 
    1468         } 
    1469         if (($nextp==0)||($halfpage == 0)) { 
    1470                 $newhalfcgi->delete('hlppage'.$hlid); 
    1471         } else { 
    1472                 $newhalfcgi->param(-name=>'hlppage'.$hlid,-value=>$halfpage); 
    1473         } 
    1474  
    1475         $newcgi->delete('contenttype'); 
    1476         $newhalfcgi->delete('contenttype'); 
    1477  
    1478         my $href = $newcgi->self_url(); 
    1479         $href=~s/\#.*$//; 
    1480         $href.="#hlpid$hlid"; 
    1481  
    1482         my $halfhref = $newhalfcgi->self_url(); 
    1483         $halfhref=~s/\#.$//;     
    1484         $halfhref.="#hlpid$hlid"; 
    1485  
    1486         my $title = $options{'navhometitle'}; 
    1487         my $d = int($days*($hlppage-$nextp)); 
    1488         if ($d==0) { 
    1489                 $d=''; 
    1490         } else { 
    1491                 $d='+'.$d if ($d>0); 
    1492         } 
    1493  
    1494         $title = $options{'navnexttitle'} if $nextp==1; 
    1495         $title = $options{'navprevtitle'} if $nextp==-1; 
    1496         $title=~s/%n/$days/g; 
    1497         $title=~s/%d/$d/eg; 
    1498  
    1499         my $halftitle = ""; 
    1500         $halftitle = $options{'navnexthalftitle'} if $nextp==1; 
    1501         $halftitle = $options{'navprevhalftitle'} if $nextp==-1; 
    1502         my $halfdays = int($days/2); 
    1503         $halftitle=~s/%n/$halfdays/g; 
    1504         $halftitle=~s/%d/$d/eg; 
    1505  
    1506         my $text = $options{'navhome'}; 
    1507         $text = $options{'navnext'} if $nextp==1; 
    1508         $text = $options{'navprev'} if $nextp==-1; 
    1509         $text=~s/%n/$days/g; 
    1510         $text=~s/%d/$d/eg; 
    1511  
    1512         my $halftext = ""; 
    1513         $halftext = $options{'navnexthalf'} if $nextp==1; 
    1514         $halftext = $options{'navprevhalf'} if $nextp==-1; 
    1515  
    1516  
    1517         $nav.=$cgi->a({-href=>$halfhref,-title=>$halftitle}, $halftext) if ($nextp==1); 
    1518         $nav.=$cgi->a({-href=>$href,-title=>$title}, $text); 
    1519         $nav.=$cgi->a({-href=>$halfhref,-title=>$halftitle}, $halftext) if ($nextp==-1); 
    1520  
    1521  
    1522         return $nav; 
    1523 } 
    1524 ### dro: following code is derived from Foswiki:Extensions.CalendarPlugin: 
    1525 # ========================= 
    1526 sub getTopicText() { 
    1527  
    1528         my ($web, $topic); 
    1529  
    1530         my $topics = $options{topic}; 
    1531         my @topics = split /,\s*/, $topics; 
    1532  
    1533         my $text = ""; 
    1534         foreach my $topicpair (@topics) { 
    1535                 if ($topicpair =~ m/([^\.]+)\.([^\.]+)/) { 
    1536                         ($web, $topic) = ($1, $2); 
    1537                 } else { 
    1538                         $web = $theWeb; 
    1539                         $topic = $topicpair; 
    1540                 } 
    1541  
    1542                 # ignore processed topics; 
    1543                 grep( /^\Q$web.$topic\E$/, @processedTopics ) && next; 
    1544  
    1545                 push(@processedTopics, "$web.$topic"); 
    1546  
    1547                 if (($topic eq $theTopic) && ($web eq $theWeb)) { 
    1548                         # use current text so that preview can show unsaved events 
    1549                         $text .= $refText; 
    1550                 } else { 
    1551                         $text .= &readTopicText($web, $topic); 
    1552                 } 
    1553         } 
    1554  
    1555         $text = parseInclude($text, \@processedTopics); 
    1556         $text =~s/\%HOLIDAYLIST({.*?})?%//sg; 
    1557         $text = Foswiki::Func::expandCommonVariables($text,$topic,$web); 
    1558  
    1559          
    1560         return $text; 
    1561          
    1562 } 
    1563 sub parseInclude { 
    1564         my ($text, $theProcessedTopicsRef) = @_; 
    1565          
    1566         if ($options{allowvarsininclude}) {  
    1567                 $text  =~ s/%INCLUDE{(.*)}%/parseIncludeOptions($1, $theProcessedTopicsRef )/ges; 
    1568         } else { 
    1569                 $text  =~ s/%INCLUDE{(.*?)}%/expandIncludedEvents( $1, $theProcessedTopicsRef)/ges; 
    1570         } 
    1571  
    1572         return $text; 
    1573 } 
    1574  
    1575 sub parseIncludeOptions { 
    1576         my ($behindincl, $theProcessedTopicsRef) = @_; 
    1577  
    1578         my($attributes, $rest)=("",$behindincl); 
    1579  
    1580         ### mark vars: 
    1581         $behindincl=~s/(%\w+{.*?})%/$1_____HLP____%/sg; 
    1582  
    1583         ### extract attributes and rest: 
    1584         $behindincl =~ /^(.*?)}%(.*)$/s; 
    1585         ($attributes, $rest) = ($1, $2); 
    1586  
    1587         ### unmark vars: 
    1588         $attributes =~ s/_____HLP____//sg; 
    1589         $rest=~ s/_____HLP____//sg; 
    1590  
    1591          
    1592         ### include text: 
    1593         my $text = &expandIncludedEvents($attributes,$theProcessedTopicsRef, $web, $topic); 
    1594  
    1595         ### handle INCLUDEs in rest: 
    1596         $rest  =~ s/%INCLUDE{(.*)}%/parseIncludeOptions($1, $theProcessedTopicsRef, $web, $topic )/ges; 
    1597  
    1598         return $text.$rest.'}%'; 
    1599 } 
    1600  
    1601 # ========================= 
    1602 sub readTopicText 
    1603 { 
    1604         my( $theWeb, $theTopic ) = @_; 
    1605         my $text = ''; 
    1606         if( $Foswiki::Plugins::VERSION >= 1.010 ) { 
    1607                 $text = &Foswiki::Func::readTopicText( $theWeb, $theTopic, '', 1 ); 
    1608         } else { 
    1609                 $text = &Foswiki::Func::readTopic( $theWeb, $theTopic ); 
    1610         } 
    1611         # return raw topic text, including meta data 
    1612         return $text; 
    1613 } 
    1614 # ========================= 
    1615 sub expandIncludedEvents 
    1616 { 
    1617         my( $theAttributes, $theProcessedTopicsRef) = @_; 
    1618  
    1619         $theAttributes = $options{allowvarsininclude}?  Foswiki::Func::expandCommonVariables( $theAttributes, $theTopic, $theWeb) : $theAttributes; 
    1620  
    1621         my $webTopic = Foswiki::Func::extractNameValuePair( $theAttributes ); 
    1622         my $section = Foswiki::Func::extractNameValuePair( $theAttributes, 'section'); 
    1623         my $pattern = Foswiki::Func::extractNameValuePair( $theAttributes, 'pattern'); 
    1624          
    1625         my ($topic,$web) = ($theTopic, $theWeb); 
    1626         if( $webTopic =~ /^([^\.]+)[\.\/](.*)$/ ) { 
    1627                 $web = $1; 
    1628                 $topic = $2; 
    1629         } else { 
    1630                 $topic = $webTopic; 
    1631         } 
    1632  
    1633         # prevent recursive loop: 
    1634         grep (/^\Q$web.$topic\E$/, @{$theProcessedTopicsRef}) and return ""; 
    1635  
    1636         push( @{$theProcessedTopicsRef}, "$web.$topic" ); 
    1637  
    1638         my $text = &readTopicText( $web, $topic ); 
    1639  
    1640         $text = getTopicSectionText($text, $section) if (defined $section && $section ne ""); 
    1641         $text = getTopicPatternText($text, $pattern) if (defined $pattern && $pattern ne ""); 
    1642  
    1643  
    1644         $text = getTopicIncludeText($text); 
    1645  
    1646         # recursively expand includes: 
    1647         $text = parseInclude($text, $theProcessedTopicsRef); 
    1648  
    1649         return $text; 
    1650 } 
    1651 # ========================= 
    1652 sub getTopicIncludeText { 
    1653         my ($text) = @_; 
    1654         return ($text =~ /\%STARTINCLUDE\%(.*?)\%STOPINCLUDE\%/s) ? $1 : $text; 
    1655 } 
    1656 # ========================= 
    1657 sub getTopicPatternText { 
    1658         my ($text, $pattern) = @_; 
    1659         return $text =~ /($pattern)/s ? $1 : $text; 
    1660 } 
    1661 # ========================= 
    1662 sub getTopicSectionText { 
    1663         my ($text, $section) = @_; 
    1664         return $text if $text !~ /%STARTSECTION{([^}]*)}(.*?)%ENDSECTION{[^}]*}/s; 
    1665         $text =~ s/%STARTSECTION\{([^\}]*)\}(.*?)%ENDSECTION\{[^\}]*\}//s; 
    1666         my ($sectionAttr,$sectionText) = ($1,$2); 
    1667         my $sectionName = Foswiki::Func::extractNameValuePair($sectionAttr); 
    1668         return ($section eq $sectionName) ? $sectionText : getTopicSectionText($text, $section); 
    1669 } 
    1670 # ========================= 
    1671 sub renderOptions { 
    1672         my $text = $options{optionsformat}; 
    1673         my $navdays = $options{navdays}; 
    1674         $navdays = $options{days} unless defined $navdays; 
    1675  
    1676         my ($dd,$mm,$yy) = getStartDate(); 
    1677         my $week = Week_of_Year($yy,$mm,$dd); 
    1678         my $wiy = Weeks_in_Year($yy); 
    1679          
    1680         while ($text=~/\%(STARTDATE|WEEK|MONTH|YEAR)OFFS(\(([^\)]*)\))?/) { 
    1681                 my $what=$1; 
    1682                 my ($a,$b,$s) = _getOptionRange($3,'-3:+3'); 
    1683                 my @vals = (''); 
    1684                 for (my $offs=$a; $offs!=$b+$s; $offs+=$s) { 
    1685                         push @vals,($offs>=0?'+':'').$offs; 
    1686                 } 
    1687                 $text =~ s/\%\Q$what\EOFFS(\([^\)]*\))?/CGI::popup_menu(-title=>"\L$what\E offset",-name=>"hlp_\L$what\E_$hlid",-values=>\@vals, -default=>$options{lc($what)})/e; 
    1688         } 
    1689         while ($text=~/\%(WEEK|MONTH|YEAR)SEL(\(([^\)]*)\))?/) { 
    1690                 my ($what,$range)=($1,$3); 
    1691                 my $default =""; 
    1692                 $default = ($yy-3).':'.($yy+3) if $what eq 'YEAR'; 
    1693                 $default = '1:12' if $what eq 'MONTH'; 
    1694                 $default = "1:$wiy" if $what eq 'WEEK'; 
    1695                 my ($a,$b,$s) = _getOptionRange($range,$default); 
    1696  
    1697                 my @vals = (''); 
    1698                 for (my $offs=$a; $offs!=$b+$s; $offs+=$s) { 
    1699                         push @vals, $offs; 
    1700                 } 
    1701  
    1702                 $text =~ s/\%\Q$what\ESEL(\([^\)]*\))?/CGI::popup_menu(-title=>"\L$what\E",-name=>"hlp_\L$what\E_$hlid",-values=>\@vals, -default=>$options{lc($what)})/e; 
    1703         } 
    1704         while ($text=~/\%(STARTDATE|WEEK|MONTH|YEAR)(\(([^\)]*)\))?/) { 
    1705                 my ($what,$default)=($1,$3); 
    1706                 $default = $options{lc($what)} unless defined $default; 
    1707                 $text =~ s/\%\Q$what\E(\([^\)]*\))?/CGI::textfield(-title=>"\L$what\E",-name=>"hlp_\L$what\E_$hlid",-default=>$default)/e; 
    1708         } 
    1709  
    1710  
    1711         $text=~s/%BUTTON(\(([^\)]*)\))?/CGI::submit(-name=>'hlp_change_'.$hlid,-value=>(defined $2?$2:'Change'))/eg; 
    1712          
    1713         $text = CGI::start_form(-action=>"#hlpid$hlid",-method=>'get'). $text . CGI::end_form(); 
    1714         return $text; 
    1715 } 
    1716 sub _getOptionRange { 
    1717         my ($range,$default) = @_; 
    1718         $range=$default if !defined $range; 
    1719         my ($a,$b,$s) = split(/:/,$range); 
    1720         $s=1 unless defined $s; 
    1721         $b=$a unless defined $b; 
    1722  
    1723         # avoid endless loops: 
    1724         $s=1 if (abs($a-$b) % abs($s)) != 0; 
    1725          
    1726         # change sign of steps: 
    1727         $s=$a>$b?-abs($s):abs($s); 
    1728  
    1729         # avoid large ranges: 
    1730         $b=$a+(100*$s) if (abs($a-$b)/abs($s))>100; 
    1731          
    1732         return ($a,$b,$s); 
    1733 } 
    1734 sub _renderText { 
    1735         my ($text, $web) = @_; 
    1736         my $ret = $text; 
    1737         if (defined $rendererCache{$web} && defined $rendererCache{$web}{$text}) { 
    1738                 $ret = $rendererCache{$web}{$text}; 
    1739         } else { 
    1740                 $ret = Foswiki::Func::renderText($text, $web); 
    1741                 $rendererCache{$web}{$text}=$ret; 
    1742         } 
    1743         return $ret; 
    1744 } 
    1745  
    1746 1; 
     35This program is distributed in the hope that it will be useful, 
     36but WITHOUT ANY WARRANTY; without even the implied warranty of 
     37MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     38GNU General Public License for more details, published at  
     39http://www.gnu.org/copyleft/gpl.html 
  • trunk/HolidaylistPlugin/lib/Foswiki/Plugins/HolidaylistPlugin/DEPENDENCIES

    r1047 r8005  
    1 Foswiki::Plugins::SmiliesPlugin,,perl,Required 
    2 Date::Calc,,cpan,Required 
     1Foswiki::Plugins::SmiliesPlugin,>=0,perl,Required 
     2Date::Calc,>=0,cpan,Required 
  • trunk/HolidaylistPlugin/lib/Foswiki/Plugins/HolidaylistPlugin/MANIFEST

    r1047 r8005  
    22data/System/VarHOLIDAYLIST.txt 0644 Documentation 
    33lib/Foswiki/Plugins/HolidaylistPlugin.pm 0644 Perl module 
     4lib/Foswiki/Plugins/HolidaylistPlugin/Core.pm 0644 Perl module 
    45pub/System/HolidaylistPlugin/example.gif 0644 Example image 
Note: See TracChangeset for help on using the changeset viewer.