HTML-CalendarMonth-2.04/0000755000175000017500000000000012704220202013413 5ustar sisksiskHTML-CalendarMonth-2.04/META.yml0000644000175000017500000000103212704220202014660 0ustar sisksisk--- abstract: unknown author: - unknown build_requires: ExtUtils::MakeMaker: 0 configure_requires: ExtUtils::MakeMaker: 0 dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.120921' license: unknown meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: HTML-CalendarMonth no_index: directory: - t - inc requires: Class::Accessor: 0 DateTime::Locale: 0.45 File::Which: 0 HTML::ElementTable: 1.18 Time::Local: 0 version: 2.04 HTML-CalendarMonth-2.04/Changes0000644000175000017500000001374712704220071014726 0ustar sisksiskRevision history for HTML-CalendarMonth 2.04 Fri Apr 15 13:08:28 EDT 2016 - *really* fixed version check for DateTime::Locale 1.03 2.03 Wed Apr 13 15:25:20 EDT 2016 - Updated tests to work with DateTime::Locale 1.03 based on CLDR 29 2.02 Tue Nov 17 16:18:40 EST 2015 - Adjusted version cutoff for legacy locale tests 2.01 Tue Nov 17 14:26:35 EST 2015 - fixed minor bug with undefined 'today' attribute 2.00 Tue Nov 17 13:48:44 EST 2015 - Updated for compatibility with DateTime::Locale versions 0.90 and greater. Backwards compatibility retained. - updated tests 1.26 Fri Aug 26 15:08:49 EDT 2011 - fixed css/header interactions - updated tests 1.25 Fri Sep 24 03:09:38 EDT 2010 - Switched to File::Which for finding cal/ncal - Added some sanity checks for the cal/ncal output 1.23 Sat Jun 12 21:12:45 EDT 2010 - Updated interface with DateTime::Locale (will eventually require another update when Locale::CLDR is released - Deprecated offsets; too much complexity for little gain - Fixed week-of-year bug in end-of-year edge cases (first week has higher number than the next) RT #53795 - Made row globbing optimize on row elements if possible - Updated default HTML style to be more CSS friendly (inspired by RT #37548) - Added option for semantic CSS classes on cells (past, present, future) ala RT #37549 - Updated test data - Improved date tool auto detect - Fixed Date::Manip parse error for negative day deltas - Doc updates - Test updates - Added linux 'ncal' harness 1.19 Sat Mar 15 00:47:26 EDT 2008 - Fixed longstanding test failure due to HTML::Tree (properly) deciding to put quotes around numeric attributes in tags. - Also changed i8n test to Zulu rather than Basque since the DateTime::Local::eu (Basque) module no longer has abbreviated day names - Some of the DateTool modules had a minor bug in add_days() not checking for defined vs 0 - I released a calendar-related module update on the Ides of March. I'm just sayin'. 1.18 Fri Feb 24 15:53:41 EST 2006 - Fixed some scoping issues in DateTool/DateCalc.pm (thanks Carl Franks) - Fixed a Win32 test module location issue (File::Spec tricks) (thanks Carl Franks) 1.17 Fri Jan 6 16:09:46 EST 2006 - Updated tests with more recent test cases 1.16 Fri Oct 21 16:23:48 EDT 2005 - Polished tests - Fixed a Date::Calc testing procedure 1.15 Fri Apr 1 12:43:09 EST 2005 - Split out tests - Version roll hopefully ironed out some cpan tester dependency issues 1.14 Mon Mar 28 15:32:54 EST 2005 - forced dependency on HTML::ElementTable 1.13 or greater - minor brush ups 1.13 Mon Feb 28 16:02:31 EST 2005 - Streamlined accessor/mutator logic. Uses Class::Accessor now. - Fixed a week of year bug introduced in the recent changes. - General cleanup - Added more tests (including one i8n test) 1.12 Mon Feb 28 00:31:16 EST 2005 - Fixed auto-select bug that slipped through tests. :( - Fixed tests. 1.11 Sun Feb 27 23:58:04 EST 2005 - No reason to reinvent the wheel. Language support has now been entirely replaced with full locale support as provided by DateTime::Locale (does not require installation of entire DateTime suite, if that's an issue) - Calendrical calculations have now been fully abstracted out to a back end interface. Calendars can be generated given the presence of any one of the following and subject to the circumstances of the request: * native Time::Local (but limited to dates between 1970 and 2038) * Date::Calc * DateTime * Date::Manip * unix 'cal' command 1.10 Sat Feb 26 00:47:37 EST 2005 - Added more robust language support. Currently supports en, de, and fr. 1.09 Tue Mar 26 05:21:59 CST 2002 - Fixed obscure bug that caused March 31 2002 to be dropped; related to a localtime/gmtime issue with DST effects. - Added tests for calendars over 1-year span plus special cases such as the aforementioned March 31 2002 instance. 1.08 Mon Jan 8 19:15:16 CST 2001 - Added Date::Manip fallback from Date::Calc, so a C compiler is not strictly necessary for folks wanting week-of-year numbering or exotic dates. 1.07 Wed Nov 8 01:42:40 CST 2000 - Day-of-week bug REALLY fixed. Should now work properly with all perumutations of calendar pecularities and concepts of what the first day of the week should be. 1.06 Wed Oct 4 13:37:31 CDT 2000 - Day-of-week bug fixed for cases where Sunday is the first day of the month (such as Oct, 2000), or last day of the month (such as Dec, 2000), over various configurations of what is considered the first day of the week. 1.04 Sun Sep 17 12:13:40 CDT 2000 - Documentation tweaks and corrections. 1.03 Wed Apr 26 12:06:23 CDT 2000 - Added HTML::ElementTable dependency check in Makefile.PL - Various bug fixes, under less common circumstances. - Code syntax tweaks. 1.02 Tue Jan 25 20:05:05 CST 2000 - Cleaned up -w noise - Added mailing list information 1.01 Thu Sep 16 15:33:41 CDT 1999 - Distribution patch - Purged erroneus Date::Manip references 1.00 Tue Jul 27 21:55:43 CDT 1999 - abstracted item/coord translations to cell refs rather than redundant coord lookups - initial release 0.09 Thu Jul 8 19:02:39 CDT 1999 - added week counts and arbitrary 1st DOW 0.08 Fri Jul 10 19:58:28 1998 - first public version HTML-CalendarMonth-2.04/LICENSE0000644000175000017500000004343612622653617014455 0ustar sisksiskThis is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Terms of the Perl programming language system itself a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License" --- The GNU General Public License, Version 1, February 1989 --- This is free software, licensed under: The GNU General Public License, Version 1, February 1989 GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The license agreements of most software companies try to keep users at the mercy of those companies. By contrast, our General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. The General Public License applies to the Free Software Foundation's software and to any other program whose authors commit to using it. You can use it for your programs, too. When we speak of free software, we are referring to freedom, not price. Specifically, the General Public License is designed to make sure that you have the freedom to give away or sell copies of free software, that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of a such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any work containing the Program or a portion of it, either verbatim or with modifications. Each licensee is addressed as "you". 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this General Public License and to the absence of any warranty; and give any other recipients of the Program a copy of this General Public License along with the Program. You may charge a fee for the physical act of transferring a copy. 2. You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following: a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and b) cause the whole of any work that you distribute or publish, that in whole or in part contains the Program or any part thereof, either with or without modifications, to be licensed at no charge to all third parties under the terms of this General Public License (except that you may choose to grant warranty protection to some or all third parties, at your option). c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the simplest and most usual way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this General Public License. d) You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. Mere aggregation of another independent work with the Program (or its derivative) on a volume of a storage or distribution medium does not bring the other work under the scope of these terms. 3. You may copy and distribute the Program (or a portion or derivative of it, under Paragraph 2) in object code or executable form under the terms of Paragraphs 1 and 2 above provided that you also do one of the following: a) accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or, b) accompany it with a written offer, valid for at least three years, to give any third party free (except for a nominal charge for the cost of distribution) a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or, c) accompany it with the information you received as to where the corresponding source code may be obtained. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form alone.) Source code for a work means the preferred form of the work for making modifications to it. For an executable file, complete source code means all the source code for all modules it contains; but, as a special exception, it need not include source code for modules which are standard libraries that accompany the operating system on which the executable file runs, or for standard header files or definitions files that accompany that operating system. 4. You may not copy, modify, sublicense, distribute or transfer the Program except as expressly provided under this General Public License. Any attempt otherwise to copy, modify, sublicense, distribute or transfer the Program is void, and will automatically terminate your rights to use the Program under this License. However, parties who have received copies, or rights to use copies, from you under this General Public License will not have their licenses terminated so long as such parties remain in full compliance. 5. By copying, distributing or modifying the Program (or any work based on the Program) you indicate your acceptance of this license to do so, and all its terms and conditions. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. 7. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of the license which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the license, you may choose any version ever published by the Free Software Foundation. 8. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to humanity, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19xx name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (a program to direct compilers to make passes at assemblers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice That's all there is to it! --- The Artistic License 1.0 --- This is free software, licensed under: The Artistic License 1.0 The Artistic License Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: - "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. - "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder. - "Copyright Holder" is whoever is named in the copyright or copyrights for the package. - "You" is you, if you're thinking about copying or distributing this Package. - "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) - "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as ftp.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) accompany any non-standard executables with their corresponding Standard Version executables, giving the non-standard executables non-standard names, and clearly documenting the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this Package. 7. C or perl subroutines supplied by you and linked into this Package shall not be considered part of this Package. 8. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End HTML-CalendarMonth-2.04/README0000644000175000017500000000427012622703161014307 0ustar sisksiskHTML-CalendarMonth ------------------- HTML::CalendarMonth is a module that simplifies the rendering of a calendar month in HTML. It is NOT a scheduling system. Calendars are represented as HTML::Element based structures, derived from the HTML::ElementTable class. The module includes support for 'week of the year' numbering, arbitrary 1st day of the week definitions, and locale support. If you wish to use 'week of the year' numbering, or want to explore dates beyond the capability of the internal perl time functions, then you will need Date::Calc, DateTime, or Date::Manip. INSTALLATION You install HTML-Calendar, as you would install any perl module library, by running these commands: perl Makefile.PL make make test make install DOCUMENTATION See HTML/CalendarMonth.pm for the code. See Changes for recent changes. POD style documentation is included in the module. This is normally converted to a manual page and installed as part of the "make install" process. You should also be able to use the 'perldoc' utility to extract and read documentation from the module directly. Some examples can be found here: http://www.mojotoad.com/sisk/projects/HTML-CalendarMonth/examples.html SUPPORT There is a mailing list for HTML::Calendar. To subscribe or view past messages, please visit the following URL: http://lists.sourceforge.net/mailman/listinfo/html-calmonth-general Questions and comments may also be directed to Matt Sisk AVAILABILITY The package is available from CPAN: http://www.cpan.org/authors/id/M/MS/MSISK/ The package is also available at the Toadstool: http://www.mojotoad.com/sisk/projects/HTML-CalendarMonth/ ACKNOWLEDGMENTS Thanks to William R. Ward for some conceptual nudging. Thanks to Fabian Aichele, Jarkko Hietaniemi, Wolfgang Jürgensen, and David 'Sniper' Rigaudiere for some suggestions on global calendar customs. Thanks to Gael Marziou, Raul Rivero, Ricardo Signes, T. Bugra Uytun, and Philipp W. for some helpful bug spotting. COPYRIGHT Copyright (c) 1999-2015 Matthew P. Sisk. All rights reserved. All wrongs revenged. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. HTML-CalendarMonth-2.04/META.json0000644000175000017500000000174012704220202015036 0ustar sisksisk{ "abstract" : "unknown", "author" : [ "unknown" ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.120921", "license" : [ "unknown" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "HTML-CalendarMonth", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "Class::Accessor" : "0", "DateTime::Locale" : "0.45", "File::Which" : "0", "HTML::ElementTable" : "1.18", "Time::Local" : "0" } } }, "release_status" : "stable", "version" : "2.04" } HTML-CalendarMonth-2.04/Makefile.PL0000644000175000017500000000057012703516317015405 0ustar sisksiskuse strict; use warnings; use ExtUtils::MakeMaker; my %prereq_pm = ( "Class::Accessor" => 0, "DateTime::Locale" => "0.45", "File::Which" => 0, "HTML::ElementTable" => "1.18", "Time::Local" => 0, ); WriteMakefile( NAME => 'HTML-CalendarMonth', VERSION_FROM => 'lib/HTML/CalendarMonth.pm', PREREQ_PM => \%prereq_pm, ); HTML-CalendarMonth-2.04/t/0000755000175000017500000000000012704220202013656 5ustar sisksiskHTML-CalendarMonth-2.04/t/07_ncal.t0000644000175000017500000000102012622653617015302 0ustar sisksisk#!/usr/bin/perl use strict; use FindBin; use lib $FindBin::RealBin; use testload; my($test_count, $method); BEGIN { $method = 'ncal'; $test_count = bulk_count() + odd_count() + woy_count() + 3; } use Test::More tests => $test_count; use constant DTC => 'HTML::CalendarMonth::DateTool'; use_ok(DTC); SKIP: { skip("$method not installed", $test_count - 1) unless DTC->_ncal_cmd; check_datetool($method); check_bulk_with_datetool($method); check_odd_with_datetool($method); check_woy_with_datetool($method); } HTML-CalendarMonth-2.04/t/02_timelocal.t0000644000175000017500000000064712622653617016347 0ustar sisksisk#!/usr/bin/perl use strict; use FindBin; use lib $FindBin::RealBin; use testload; my($test_count, $method); BEGIN { $method = 'Time::Local'; $test_count = bulk_count() + odd_count() + 2; } use Test::More tests => $test_count; SKIP: { eval "use $method"; skip("$method not installed", $test_count) if $@; check_datetool($method); check_bulk_with_datetool($method); check_odd_with_datetool($method); } HTML-CalendarMonth-2.04/t/dat/0000755000175000017500000000000012704220202014426 5ustar sisksiskHTML-CalendarMonth-2.04/t/dat/head.dat0000644000175000017500000001315012622653617016044 0ustar sisksisk2010/01 0 0 0 0 1
12
3456789
10111213141516
17181920212223
24252627282930
31
2010/01 0 0 0 0 2
123
45678910
11121314151617
18192021222324
25262728293031
2010/01 0 0 0 1 1
1253
34567891
101112131415162
171819202122233
242526272829304
315
2010/01 0 0 0 1 2
12353
456789101
111213141516172
181920212223243
252627282930314
2010/01 0 0 1 0 1
SunMonTueWedThuFriSat
12
3456789
10111213141516
17181920212223
24252627282930
31
2010/01 0 0 1 0 2
MonTueWedThuFriSatSun
123
45678910
11121314151617
18192021222324
25262728293031
2010/01 0 0 1 1 1
SunMonTueWedThuFriSat
1253
34567891
101112131415162
171819202122233
242526272829304
315
2010/01 0 0 1 1 2
MonTueWedThuFriSatSun
12353
456789101
111213141516172
181920212223243
252627282930314
HTML-CalendarMonth-2.04/t/dat/i8n_leg1.dat0000644000175000017500000001327212622672132016547 0ustar sisksisk2010/03 ga_IE
Márta2010
DomhLuanMáirtCéadDéarAoineSath
123456
78910111213
14151617181920
21222324252627
28293031
2010/03 es_MX
marzo2010
lunmarmiéjueviesábdom
1234567
891011121314
15161718192021
22232425262728
293031
2010/03 fr_FR
mars2010
lun.mar.mer.jeu.ven.sam.dim.
1234567
891011121314
15161718192021
22232425262728
293031
2010/03 de_DE
März2010
Mo.Di.Mi.Do.Fr.Sa.So.
1234567
891011121314
15161718192021
22232425262728
293031
2010/03 ru_RU
Март2010
ПнВтСрЧтПтСбВс
1234567
891011121314
15161718192021
22232425262728
293031
2010/03 pt_BR
março2010
segterquaquisexsábdom
1234567
891011121314
15161718192021
22232425262728
293031
2010/03 zu_ZA
uMashi2010
MsoBilThaSinHlaMgqSon
1234567
891011121314
15161718192021
22232425262728
293031
HTML-CalendarMonth-2.04/t/dat/odd.dat0000644000175000017500000001427012622653617015715 0ustar sisksisk2000/10 1
October2000
SunMonTueWedThuFriSat
1234567
891011121314
15161718192021
22232425262728
293031
2000/10 2
October2000
MonTueWedThuFriSatSun
1
2345678
9101112131415
16171819202122
23242526272829
3031
2000/12 1
December2000
SunMonTueWedThuFriSat
12
3456789
10111213141516
17181920212223
24252627282930
31
2000/12 2
December2000
MonTueWedThuFriSatSun
123
45678910
11121314151617
18192021222324
25262728293031
2002/03 1
March2002
SunMonTueWedThuFriSat
12
3456789
10111213141516
17181920212223
24252627282930
31
2002/03 2
March2002
MonTueWedThuFriSatSun
123
45678910
11121314151617
18192021222324
25262728293031
1752/09 1
September1752
SunMonTueWedThuFriSat
12141516
17181920212223
24252627282930
1752/09 2
September1752
MonTueWedThuFriSatSun
1214151617
18192021222324
252627282930
HTML-CalendarMonth-2.04/t/dat/i8n_leg2.dat0000644000175000017500000001325112622673074016553 0ustar sisksisk2010/03 ga-IE
Márta2010
DomhLuanMáirtCéadDéarAoineSath
123456
78910111213
14151617181920
21222324252627
28293031
2010/03 es-MX
marzo2010
dom.lun.mar.mié.jue.vie.sáb.
123456
78910111213
14151617181920
21222324252627
28293031
2010/03 fr-FR
mars2010
lun.mar.mer.jeu.ven.sam.dim.
1234567
891011121314
15161718192021
22232425262728
293031
2010/03 de-DE
März2010
MoDiMiDoFrSaSo
1234567
891011121314
15161718192021
22232425262728
293031
2010/03 ru-RU
март2010
пнвтсрчтптсбвс
1234567
891011121314
15161718192021
22232425262728
293031
2010/03 pt-BR
março2010
segterquaquisexsábdom
1234567
891011121314
15161718192021
22232425262728
293031
2010/03 zu-ZA
Mashi2010
SonMsoBilThaSinHlaMgq
123456
78910111213
14151617181920
21222324252627
28293031
HTML-CalendarMonth-2.04/t/dat/narrow.dat0000644000175000017500000001142212622653617016453 0ustar sisksisk2010/08 1
August2010
SMTWTFS
1234567
891011121314
15161718192021
22232425262728
293031
2010/08 2
August2010
MTWTFSS
1
2345678
9101112131415
16171819202122
23242526272829
3031
2010/09 1
September2010
SMTWTFS
1234
567891011
12131415161718
19202122232425
2627282930
2010/09 2
September2010
MTWTFSS
12345
6789101112
13141516171819
20212223242526
27282930
2010/10 1
October2010
SMTWTFS
12
3456789
10111213141516
17181920212223
24252627282930
31
2010/10 2
October2010
MTWTFSS
123
45678910
11121314151617
18192021222324
25262728293031
HTML-CalendarMonth-2.04/t/dat/i8n.dat0000644000175000017500000001324512703515746015646 0ustar sisksisk2010/03 ga-IE
Márta2010
DomhLuanMáirtCéadDéarAoineSath
123456
78910111213
14151617181920
21222324252627
28293031
2010/03 es-MX
marzo2010
dom.lun.mar.mié.jue.vie.sáb.
123456
78910111213
14151617181920
21222324252627
28293031
2010/03 fr-FR
mars2010
lun.mar.mer.jeu.ven.sam.dim.
1234567
891011121314
15161718192021
22232425262728
293031
2010/03 de-DE
März2010
MoDiMiDoFrSaSo
1234567
891011121314
15161718192021
22232425262728
293031
2010/03 ru-RU
март2010
пнвтсрчтптсбвс
1234567
891011121314
15161718192021
22232425262728
293031
2010/03 pt-BR
março2010
domsegterquaquisexsáb
123456
78910111213
14151617181920
21222324252627
28293031
2010/03 zu-ZA
Mashi2010
SonMsoBilThaSinHlaMgq
123456
78910111213
14151617181920
21222324252627
28293031
HTML-CalendarMonth-2.04/t/dat/bulk.dat0000644000175000017500000034551412622653617016114 0ustar sisksisk2010/01 1
January2010
SunMonTueWedThuFriSat
12
3456789
10111213141516
17181920212223
24252627282930
31
2010/01 2
January2010
MonTueWedThuFriSatSun
123
45678910
11121314151617
18192021222324
25262728293031
2010/02 1
February2010
SunMonTueWedThuFriSat
123456
78910111213
14151617181920
21222324252627
28
2010/02 2
February2010
MonTueWedThuFriSatSun
1234567
891011121314
15161718192021
22232425262728
2010/03 1
March2010
SunMonTueWedThuFriSat
123456
78910111213
14151617181920
21222324252627
28293031
2010/03 2
March2010
MonTueWedThuFriSatSun
1234567
891011121314
15161718192021
22232425262728
293031
2010/04 1
April2010
SunMonTueWedThuFriSat
123
45678910
11121314151617
18192021222324
252627282930
2010/04 2
April2010
MonTueWedThuFriSatSun
1234
567891011
12131415161718
19202122232425
2627282930
2010/05 1
May2010
SunMonTueWedThuFriSat
1
2345678
9101112131415
16171819202122
23242526272829
3031
2010/05 2
May2010
MonTueWedThuFriSatSun
12
3456789
10111213141516
17181920212223
24252627282930
31
2010/06 1
June2010
SunMonTueWedThuFriSat
12345
6789101112
13141516171819
20212223242526
27282930
2010/06 2
June2010
MonTueWedThuFriSatSun
123456
78910111213
14151617181920
21222324252627
282930
2010/07 1
July2010
SunMonTueWedThuFriSat
123
45678910
11121314151617
18192021222324
25262728293031
2010/07 2
July2010
MonTueWedThuFriSatSun
1234
567891011
12131415161718
19202122232425
262728293031
2010/08 1
August2010
SunMonTueWedThuFriSat
1234567
891011121314
15161718192021
22232425262728
293031
2010/08 2
August2010
MonTueWedThuFriSatSun
1
2345678
9101112131415
16171819202122
23242526272829
3031
2010/09 1
September2010
SunMonTueWedThuFriSat
1234
567891011
12131415161718
19202122232425
2627282930
2010/09 2
September2010
MonTueWedThuFriSatSun
12345
6789101112
13141516171819
20212223242526
27282930
2010/10 1
October2010
SunMonTueWedThuFriSat
12
3456789
10111213141516
17181920212223
24252627282930
31
2010/10 2
October2010
MonTueWedThuFriSatSun
123
45678910
11121314151617
18192021222324
25262728293031
2010/11 1
November2010
SunMonTueWedThuFriSat
123456
78910111213
14151617181920
21222324252627
282930
2010/11 2
November2010
MonTueWedThuFriSatSun
1234567
891011121314
15161718192021
22232425262728
2930
2010/12 1
December2010
SunMonTueWedThuFriSat
1234
567891011
12131415161718
19202122232425
262728293031
2010/12 2
December2010
MonTueWedThuFriSatSun
12345
6789101112
13141516171819
20212223242526
2728293031
2011/01 1
January2011
SunMonTueWedThuFriSat
1
2345678
9101112131415
16171819202122
23242526272829
3031
2011/01 2
January2011
MonTueWedThuFriSatSun
12
3456789
10111213141516
17181920212223
24252627282930
31
2011/02 1
February2011
SunMonTueWedThuFriSat
12345
6789101112
13141516171819
20212223242526
2728
2011/02 2
February2011
MonTueWedThuFriSatSun
123456
78910111213
14151617181920
21222324252627
28
2011/03 1
March2011
SunMonTueWedThuFriSat
12345
6789101112
13141516171819
20212223242526
2728293031
2011/03 2
March2011
MonTueWedThuFriSatSun
123456
78910111213
14151617181920
21222324252627
28293031
2011/04 1
April2011
SunMonTueWedThuFriSat
12
3456789
10111213141516
17181920212223
24252627282930
2011/04 2
April2011
MonTueWedThuFriSatSun
123
45678910
11121314151617
18192021222324
252627282930
2011/05 1
May2011
SunMonTueWedThuFriSat
1234567
891011121314
15161718192021
22232425262728
293031
2011/05 2
May2011
MonTueWedThuFriSatSun
1
2345678
9101112131415
16171819202122
23242526272829
3031
2011/06 1
June2011
SunMonTueWedThuFriSat
1234
567891011
12131415161718
19202122232425
2627282930
2011/06 2
June2011
MonTueWedThuFriSatSun
12345
6789101112
13141516171819
20212223242526
27282930
2011/07 1
July2011
SunMonTueWedThuFriSat
12
3456789
10111213141516
17181920212223
24252627282930
31
2011/07 2
July2011
MonTueWedThuFriSatSun
123
45678910
11121314151617
18192021222324
25262728293031
2011/08 1
August2011
SunMonTueWedThuFriSat
123456
78910111213
14151617181920
21222324252627
28293031
2011/08 2
August2011
MonTueWedThuFriSatSun
1234567
891011121314
15161718192021
22232425262728
293031
2011/09 1
September2011
SunMonTueWedThuFriSat
123
45678910
11121314151617
18192021222324
252627282930
2011/09 2
September2011
MonTueWedThuFriSatSun
1234
567891011
12131415161718
19202122232425
2627282930
2011/10 1
October2011
SunMonTueWedThuFriSat
1
2345678
9101112131415
16171819202122
23242526272829
3031
2011/10 2
October2011
MonTueWedThuFriSatSun
12
3456789
10111213141516
17181920212223
24252627282930
31
2011/11 1
November2011
SunMonTueWedThuFriSat
12345
6789101112
13141516171819
20212223242526
27282930
2011/11 2
November2011
MonTueWedThuFriSatSun
123456
78910111213
14151617181920
21222324252627
282930
2011/12 1
December2011
SunMonTueWedThuFriSat
123
45678910
11121314151617
18192021222324
25262728293031
2011/12 2
December2011
MonTueWedThuFriSatSun
1234
567891011
12131415161718
19202122232425
262728293031
2012/01 1
January2012
SunMonTueWedThuFriSat
1234567
891011121314
15161718192021
22232425262728
293031
2012/01 2
January2012
MonTueWedThuFriSatSun
1
2345678
9101112131415
16171819202122
23242526272829
3031
2012/02 1
February2012
SunMonTueWedThuFriSat
1234
567891011
12131415161718
19202122232425
26272829
2012/02 2
February2012
MonTueWedThuFriSatSun
12345
6789101112
13141516171819
20212223242526
272829
2012/03 1
March2012
SunMonTueWedThuFriSat
123
45678910
11121314151617
18192021222324
25262728293031
2012/03 2
March2012
MonTueWedThuFriSatSun
1234
567891011
12131415161718
19202122232425
262728293031
2012/04 1
April2012
SunMonTueWedThuFriSat
1234567
891011121314
15161718192021
22232425262728
2930
2012/04 2
April2012
MonTueWedThuFriSatSun
1
2345678
9101112131415
16171819202122
23242526272829
30
2012/05 1
May2012
SunMonTueWedThuFriSat
12345
6789101112
13141516171819
20212223242526
2728293031
2012/05 2
May2012
MonTueWedThuFriSatSun
123456
78910111213
14151617181920
21222324252627
28293031
2012/06 1
June2012
SunMonTueWedThuFriSat
12
3456789
10111213141516
17181920212223
24252627282930
2012/06 2
June2012
MonTueWedThuFriSatSun
123
45678910
11121314151617
18192021222324
252627282930
2012/07 1
July2012
SunMonTueWedThuFriSat
1234567
891011121314
15161718192021
22232425262728
293031
2012/07 2
July2012
MonTueWedThuFriSatSun
1
2345678
9101112131415
16171819202122
23242526272829
3031
2012/08 1
August2012
SunMonTueWedThuFriSat
1234
567891011
12131415161718
19202122232425
262728293031
2012/08 2
August2012
MonTueWedThuFriSatSun
12345
6789101112
13141516171819
20212223242526
2728293031
2012/09 1
September2012
SunMonTueWedThuFriSat
1
2345678
9101112131415
16171819202122
23242526272829
30
2012/09 2
September2012
MonTueWedThuFriSatSun
12
3456789
10111213141516
17181920212223
24252627282930
2012/10 1
October2012
SunMonTueWedThuFriSat
123456
78910111213
14151617181920
21222324252627
28293031
2012/10 2
October2012
MonTueWedThuFriSatSun
1234567
891011121314
15161718192021
22232425262728
293031
2012/11 1
November2012
SunMonTueWedThuFriSat
123
45678910
11121314151617
18192021222324
252627282930
2012/11 2
November2012
MonTueWedThuFriSatSun
1234
567891011
12131415161718
19202122232425
2627282930
2012/12 1
December2012
SunMonTueWedThuFriSat
1
2345678
9101112131415
16171819202122
23242526272829
3031
2012/12 2
December2012
MonTueWedThuFriSatSun
12
3456789
10111213141516
17181920212223
24252627282930
31
2013/01 1
January2013
SunMonTueWedThuFriSat
12345
6789101112
13141516171819
20212223242526
2728293031
2013/01 2
January2013
MonTueWedThuFriSatSun
123456
78910111213
14151617181920
21222324252627
28293031
2013/02 1
February2013
SunMonTueWedThuFriSat
12
3456789
10111213141516
17181920212223
2425262728
2013/02 2
February2013
MonTueWedThuFriSatSun
123
45678910
11121314151617
18192021222324
25262728
2013/03 1
March2013
SunMonTueWedThuFriSat
12
3456789
10111213141516
17181920212223
24252627282930
31
2013/03 2
March2013
MonTueWedThuFriSatSun
123
45678910
11121314151617
18192021222324
25262728293031
2013/04 1
April2013
SunMonTueWedThuFriSat
123456
78910111213
14151617181920
21222324252627
282930
2013/04 2
April2013
MonTueWedThuFriSatSun
1234567
891011121314
15161718192021
22232425262728
2930
2013/05 1
May2013
SunMonTueWedThuFriSat
1234
567891011
12131415161718
19202122232425
262728293031
2013/05 2
May2013
MonTueWedThuFriSatSun
12345
6789101112
13141516171819
20212223242526
2728293031
2013/06 1
June2013
SunMonTueWedThuFriSat
1
2345678
9101112131415
16171819202122
23242526272829
30
2013/06 2
June2013
MonTueWedThuFriSatSun
12
3456789
10111213141516
17181920212223
24252627282930
2013/07 1
July2013
SunMonTueWedThuFriSat
123456
78910111213
14151617181920
21222324252627
28293031
2013/07 2
July2013
MonTueWedThuFriSatSun
1234567
891011121314
15161718192021
22232425262728
293031
2013/08 1
August2013
SunMonTueWedThuFriSat
123
45678910
11121314151617
18192021222324
25262728293031
2013/08 2
August2013
MonTueWedThuFriSatSun
1234
567891011
12131415161718
19202122232425
262728293031
2013/09 1
September2013
SunMonTueWedThuFriSat
1234567
891011121314
15161718192021
22232425262728
2930
2013/09 2
September2013
MonTueWedThuFriSatSun
1
2345678
9101112131415
16171819202122
23242526272829
30
2013/10 1
October2013
SunMonTueWedThuFriSat
12345
6789101112
13141516171819
20212223242526
2728293031
2013/10 2
October2013
MonTueWedThuFriSatSun
123456
78910111213
14151617181920
21222324252627
28293031
2013/11 1
November2013
SunMonTueWedThuFriSat
12
3456789
10111213141516
17181920212223
24252627282930
2013/11 2
November2013
MonTueWedThuFriSatSun
123
45678910
11121314151617
18192021222324
252627282930
2013/12 1
December2013
SunMonTueWedThuFriSat
1234567
891011121314
15161718192021
22232425262728
293031
2013/12 2
December2013
MonTueWedThuFriSatSun
1
2345678
9101112131415
16171819202122
23242526272829
3031
2014/01 1
January2014
SunMonTueWedThuFriSat
1234
567891011
12131415161718
19202122232425
262728293031
2014/01 2
January2014
MonTueWedThuFriSatSun
12345
6789101112
13141516171819
20212223242526
2728293031
2014/02 1
February2014
SunMonTueWedThuFriSat
1
2345678
9101112131415
16171819202122
232425262728
2014/02 2
February2014
MonTueWedThuFriSatSun
12
3456789
10111213141516
17181920212223
2425262728
2014/03 1
March2014
SunMonTueWedThuFriSat
1
2345678
9101112131415
16171819202122
23242526272829
3031
2014/03 2
March2014
MonTueWedThuFriSatSun
12
3456789
10111213141516
17181920212223
24252627282930
31
2014/04 1
April2014
SunMonTueWedThuFriSat
12345
6789101112
13141516171819
20212223242526
27282930
2014/04 2
April2014
MonTueWedThuFriSatSun
123456
78910111213
14151617181920
21222324252627
282930
2014/05 1
May2014
SunMonTueWedThuFriSat
123
45678910
11121314151617
18192021222324
25262728293031
2014/05 2
May2014
MonTueWedThuFriSatSun
1234
567891011
12131415161718
19202122232425
262728293031
2014/06 1
June2014
SunMonTueWedThuFriSat
1234567
891011121314
15161718192021
22232425262728
2930
2014/06 2
June2014
MonTueWedThuFriSatSun
1
2345678
9101112131415
16171819202122
23242526272829
30
2014/07 1
July2014
SunMonTueWedThuFriSat
12345
6789101112
13141516171819
20212223242526
2728293031
2014/07 2
July2014
MonTueWedThuFriSatSun
123456
78910111213
14151617181920
21222324252627
28293031
2014/08 1
August2014
SunMonTueWedThuFriSat
12
3456789
10111213141516
17181920212223
24252627282930
31
2014/08 2
August2014
MonTueWedThuFriSatSun
123
45678910
11121314151617
18192021222324
25262728293031
2014/09 1
September2014
SunMonTueWedThuFriSat
123456
78910111213
14151617181920
21222324252627
282930
2014/09 2
September2014
MonTueWedThuFriSatSun
1234567
891011121314
15161718192021
22232425262728
2930
2014/10 1
October2014
SunMonTueWedThuFriSat
1234
567891011
12131415161718
19202122232425
262728293031
2014/10 2
October2014
MonTueWedThuFriSatSun
12345
6789101112
13141516171819
20212223242526
2728293031
2014/11 1
November2014
SunMonTueWedThuFriSat
1
2345678
9101112131415
16171819202122
23242526272829
30
2014/11 2
November2014
MonTueWedThuFriSatSun
12
3456789
10111213141516
17181920212223
24252627282930
2014/12 1
December2014
SunMonTueWedThuFriSat
123456
78910111213
14151617181920
21222324252627
28293031
2014/12 2
December2014
MonTueWedThuFriSatSun
1234567
891011121314
15161718192021
22232425262728
293031
2015/01 1
January2015
SunMonTueWedThuFriSat
123
45678910
11121314151617
18192021222324
25262728293031
2015/01 2
January2015
MonTueWedThuFriSatSun
1234
567891011
12131415161718
19202122232425
262728293031
2015/02 1
February2015
SunMonTueWedThuFriSat
1234567
891011121314
15161718192021
22232425262728
2015/02 2
February2015
MonTueWedThuFriSatSun
1
2345678
9101112131415
16171819202122
232425262728
2015/03 1
March2015
SunMonTueWedThuFriSat
1234567
891011121314
15161718192021
22232425262728
293031
2015/03 2
March2015
MonTueWedThuFriSatSun
1
2345678
9101112131415
16171819202122
23242526272829
3031
2015/04 1
April2015
SunMonTueWedThuFriSat
1234
567891011
12131415161718
19202122232425
2627282930
2015/04 2
April2015
MonTueWedThuFriSatSun
12345
6789101112
13141516171819
20212223242526
27282930
2015/05 1
May2015
SunMonTueWedThuFriSat
12
3456789
10111213141516
17181920212223
24252627282930
31
2015/05 2
May2015
MonTueWedThuFriSatSun
123
45678910
11121314151617
18192021222324
25262728293031
2015/06 1
June2015
SunMonTueWedThuFriSat
123456
78910111213
14151617181920
21222324252627
282930
2015/06 2
June2015
MonTueWedThuFriSatSun
1234567
891011121314
15161718192021
22232425262728
2930
2015/07 1
July2015
SunMonTueWedThuFriSat
1234
567891011
12131415161718
19202122232425
262728293031
2015/07 2
July2015
MonTueWedThuFriSatSun
12345
6789101112
13141516171819
20212223242526
2728293031
2015/08 1
August2015
SunMonTueWedThuFriSat
1
2345678
9101112131415
16171819202122
23242526272829
3031
2015/08 2
August2015
MonTueWedThuFriSatSun
12
3456789
10111213141516
17181920212223
24252627282930
31
2015/09 1
September2015
SunMonTueWedThuFriSat
12345
6789101112
13141516171819
20212223242526
27282930
2015/09 2
September2015
MonTueWedThuFriSatSun
123456
78910111213
14151617181920
21222324252627
282930
2015/10 1
October2015
SunMonTueWedThuFriSat
123
45678910
11121314151617
18192021222324
25262728293031
2015/10 2
October2015
MonTueWedThuFriSatSun
1234
567891011
12131415161718
19202122232425
262728293031
2015/11 1
November2015
SunMonTueWedThuFriSat
1234567
891011121314
15161718192021
22232425262728
2930
2015/11 2
November2015
MonTueWedThuFriSatSun
1
2345678
9101112131415
16171819202122
23242526272829
30
2015/12 1
December2015
SunMonTueWedThuFriSat
12345
6789101112
13141516171819
20212223242526
2728293031
2015/12 2
December2015
MonTueWedThuFriSatSun
123456
78910111213
14151617181920
21222324252627
28293031
HTML-CalendarMonth-2.04/t/dat/woy.dat0000644000175000017500000000422712622653617015766 0ustar sisksisk2000/01
January2000
SunMonTueWedThuFriSat
152
23456781
91011121314152
161718192021223
232425262728294
30315
2000/12
December2000
SunMonTueWedThuFriSat
1248
345678949
1011121314151650
1718192021222351
2425262728293052
311
HTML-CalendarMonth-2.04/t/20_i8n.t0000644000175000017500000000053112622653617015064 0ustar sisksisk#!/usr/bin/perl use strict; use FindBin; use lib $FindBin::RealBin; use testload; my $test_count; BEGIN { $test_count = i8n_count() + 1 } use Test::More tests => $test_count; use HTML::CalendarMonth::Locale; my @stoof = HTML::CalendarMonth::Locale->locales; ok(@stoof > 20, 'i8n: ' . scalar @stoof . ' locale ids retreived'); check_i8n(); HTML-CalendarMonth-2.04/t/00_basic.t0000644000175000017500000000023212622653617015443 0ustar sisksiskuse Test::More tests => 3; BEGIN { use_ok('HTML::CalendarMonth'); use_ok('HTML::CalendarMonth::Locale'); use_ok('HTML::CalendarMonth::DateTool'); } HTML-CalendarMonth-2.04/t/01_autodetect.t0000644000175000017500000000067312622653617016535 0ustar sisksisk#!/usr/bin/perl use strict; use FindBin; use lib $FindBin::RealBin; use testload; use HTML::CalendarMonth::DateTool; my($test_count, $detected); BEGIN { $test_count = bulk_count() + 1; eval { $detected = HTML::CalendarMonth::DateTool->new }; } use Test::More tests => $test_count; ok($detected, 'auto-detected a datetool'); SKIP: { skip("no datetools installed", $test_count - 1) unless $detected; check_bulk_with_datetool(); } HTML-CalendarMonth-2.04/t/06_cal.t0000644000175000017500000000073412622653617015136 0ustar sisksisk#!/usr/bin/perl use strict; use FindBin; use lib $FindBin::RealBin; use testload; my($test_count, $method); BEGIN { $method = 'cal'; $test_count = bulk_count() + odd_count() + 3; } use Test::More tests => $test_count; use constant DTC => 'HTML::CalendarMonth::DateTool'; use_ok(DTC); SKIP: { skip("$method not installed", $test_count - 1) unless DTC->_cal_cmd; check_datetool($method); check_bulk_with_datetool($method); check_odd_with_datetool($method); } HTML-CalendarMonth-2.04/t/05_datecalc.t0000644000175000017500000000072412622653617016135 0ustar sisksisk#!/usr/bin/perl use strict; use FindBin; use lib $FindBin::RealBin; use testload; my($test_count, $method); BEGIN { $method = 'Date::Calc'; $test_count = bulk_count() + odd_count() + woy_count() + 2; } use Test::More tests => $test_count; SKIP: { eval "use $method"; skip("$method not installed", $test_count) if $@; check_datetool($method); check_bulk_with_datetool($method); check_odd_with_datetool($method); check_woy_with_datetool($method); } HTML-CalendarMonth-2.04/t/21_narrow.t0000644000175000017500000000034512622653617015702 0ustar sisksisk#!/usr/bin/perl use strict; use FindBin; use lib $FindBin::RealBin; use testload; my $test_count; BEGIN { $test_count = narrow_count() } use Test::More tests => $test_count; use HTML::CalendarMonth::Locale; check_narrow(); HTML-CalendarMonth-2.04/t/04_datemanip.t0000644000175000017500000000072512622653617016337 0ustar sisksisk#!/usr/bin/perl use strict; use FindBin; use lib $FindBin::RealBin; use testload; my($test_count, $method); BEGIN { $method = 'Date::Manip'; $test_count = bulk_count() + odd_count() + woy_count() + 2; } use Test::More tests => $test_count; SKIP: { eval "use $method"; skip("$method not installed", $test_count) if $@; check_datetool($method); check_bulk_with_datetool($method); check_odd_with_datetool($method); check_woy_with_datetool($method); } HTML-CalendarMonth-2.04/t/testload.pm0000644000175000017500000001535512704217651016062 0ustar sisksiskpackage testload; use vars qw( @ISA @EXPORT $Dat_Dir ); use strict; use warnings; use Test::More; use Cwd qw( abs_path ); my $DEBUG = 0; require Exporter; @ISA = qw(Exporter); use vars qw( $Dat_Dir $Bulk_File $Head_File $Odd_File $Woy_File $Narrow_File $I8N_File $I8N_Legacy1_File $I8N_Legacy2_File ); @EXPORT = qw( $Dat_Dir $Bulk_File $Head_File $Odd_File $Woy_File $I8N_File $Narrow_File check_datetool check_bulk_with_datetool check_odd_with_datetool check_woy_with_datetool check_i8n check_narrow bulk_count odd_count woy_count i8n_count narrow_count clean ); use File::Spec; use HTML::CalendarMonth; use HTML::CalendarMonth::DateTool; BEGIN { my($vol, $dir, $file) = File::Spec->splitpath(abs_path(__FILE__)); $dir = File::Spec->catdir($dir, 'dat'); $Dat_Dir = File::Spec->catpath($vol, $dir, ''); } $Bulk_File = File::Spec->catdir($Dat_Dir, 'bulk.dat'); $Head_File = File::Spec->catdir($Dat_Dir, 'head.dat'); $Odd_File = File::Spec->catdir($Dat_Dir, 'odd.dat'); $Woy_File = File::Spec->catdir($Dat_Dir, 'woy.dat'); $Narrow_File = File::Spec->catdir($Dat_Dir, 'narrow.dat'); $I8N_File = File::Spec->catdir($Dat_Dir, 'i8n.dat'); $I8N_Legacy1_File = File::Spec->catdir($Dat_Dir, 'i8n_leg1.dat'); $I8N_Legacy2_File = File::Spec->catdir($Dat_Dir, 'i8n_leg2.dat'); my(@Bulk, @Head, @Odd, @Woy, @I8N, @Nar); sub _load_file { my $f = shift; my $cal = shift || []; local(*F); return unless open(F, '<', $f); while (my $h = ) { chomp $h; my($d, $wb, @other) = split(/\s+/, $h); my($y, $m) = split(/\//, $d); my $c = ; chomp $c; push(@$cal, [$d, $y, $m, $wb, \@other, clean($c)]); } $cal; } _load_file($Bulk_File, \@Bulk ); _load_file($Head_File, \@Head ); _load_file($Odd_File, \@Odd ); _load_file($Woy_File, \@Woy ); _load_file($Narrow_File, \@Nar); if (HTML::CalendarMonth::Locale->_locale_version >= 1.03) { _load_file($I8N_File, \@I8N ); } elsif (HTML::CalendarMonth::Locale->_locale_version >= 0.93) { _load_file($I8N_Legacy2_File, \@I8N ); } else { _load_file($I8N_Legacy1_File, \@I8N ); } sub bulk_count { scalar @Bulk } sub head_count { scalar @Head } sub odd_count { scalar @Odd } sub woy_count { scalar @Woy } sub i8n_count { scalar @I8N } sub narrow_count { scalar @Nar } # Today's date my($month, $year) = (localtime(time))[4,5]; ++$month; $year += 1900; my $today = sprintf("%d/%02d", $year, $month); my $year_from_now = sprintf("%d/%02d", $year+1, $month); # keep the next year @Bulk = grep { $_ ge $today && $_->[0] le $year_from_now } @Bulk; ### sub clean { my $str = shift || Carp::confess "string required"; $str =~ s/^\s*//; $str =~ s/\s*$//; # guard against HTML::Tree starting to quote numeric attrs as of # v3.19_02 $str =~ s/\"(\d+)\"/$1/g; $str; } sub check_datetool { my $datetool = shift; my $module = HTML::CalendarMonth::DateTool->_toolmap($datetool); ok($module, "toolmap($datetool) : $module"); require_ok($module); } sub check_bulk_with_datetool { my $datetool = shift; my @days; foreach (@Bulk) { my($d, $y, $m, $wb, $other, $tc) = @$_; my $c = HTML::CalendarMonth->new( year => $y, month => $m, week_begin => $wb, datetool => $datetool, ); @days = $c->dayheaders unless @days; my $day1 = $days[$wb - 1]; my $method = $c->_caltool->_name; $method = "auto-select ($method)" unless $datetool; my $msg = sprintf( "(%d/%02d %s 1st day) using %s", $y, $m, $day1, $method ); cmp_ok(clean($c->as_HTML), 'eq', $tc, $msg); } } sub check_head_with_datetool { my $datetool = shift; my @days; foreach (@Head) { my($d, $y, $m, $wb, $other, $tc) = @$_; my($hm, $hy, $hd, $hw) = @$other; my $c = HTML::CalendarMonth->new( year => $y, month => $m, week_begin => $wb, head_m => $hm, head_y => $hy, head_dow => $hd, head_week => $hw, datetool => $datetool, ); my $method = $c->_caltool->_name; $method = "auto-select ($method)" unless $datetool; my $msg = sprintf( "(%d/%02d hm:%d hy:%d hd:%d hw:%d) using %s", $y, $m, $hm, $hy, $hd, $hw, $method ); cmp_ok(clean($c->as_HTML), 'eq', $tc, $msg); } } sub check_odd_with_datetool { my $datetool = shift; my @days; foreach (@Odd) { my($d, $y, $m, $wb, $other, $tc) = @$_; SKIP: { my $c; eval { $c = HTML::CalendarMonth->new( year => $y, month => $m, week_begin => $wb, datetool => $datetool, ); }; if ($@ || !$c) { croak $@ unless $@ =~ /(no|in)\s*valid date tool/i; skip("$datetool odd $y/$m", 1); } @days = $c->dayheaders unless @days; my $day1 = $days[$wb - 1]; my $method = $c->_caltool->_name; $method = "auto-select ($method)" unless $datetool; my $msg = sprintf( "(%d/%02d %s 1st day) using %s", $y, $m, $day1, $method ); cmp_ok(clean($c->as_HTML), 'eq', $tc, $msg); } } } sub check_woy_with_datetool { my $datetool = shift; foreach (@Woy) { my($d, $y, $m, $wb, $other, $tc) = @$_; my $c = HTML::CalendarMonth->new( year => $y, month => $m, head_week => 1, datetool => $datetool, ); my $msg = sprintf("(%d/%02d week of year) using %s", $y, $m, $datetool); cmp_ok(clean($c->as_HTML), 'eq', $tc, $msg); } } sub check_i8n { foreach (@I8N) { my($d, $y, $m, $id, $other, $tc) = @$_; my $c = HTML::CalendarMonth->new( year => $y, month => $m, locale => $id, ); my $name = $c->loc->loc->name; my $msg = sprintf( "(%d/%02d i8n) %s (wb:%d) using auto-detect", $y, $m, $name, $c->week_begin ); cmp_ok(clean($c->as_HTML), 'eq', $tc, $msg); } } sub check_narrow { my @days; foreach (@Nar) { my($d, $y, $m, $wb, $other, $tc) = @$_; my $c = HTML::CalendarMonth->new( year => $y, month => $m, week_begin => $wb, full_days => -1, ); @days = $c->dayheaders unless @days; my $day1 = $days[$wb - 1]; my $msg = sprintf( "(%d/%02d %s/%s 1st day) narrow/alias using auto-detect", $y, $m, $day1, $c->item_alias($day1) ); cmp_ok(clean($c->as_HTML), 'eq', $tc, $msg); } } sub debug_dump { my($l1, $str1, $l2, $str2) = @_; local(*DUMP); open(DUMP, ">$DEBUG") or die "Could not dump to $DEBUG: $!\n"; print DUMP "
$l1$l2
\n"; print DUMP "$str1\n\n"; print DUMP "$str2\n
\n"; close(DUMP); print STDERR "\nDumped tables to $DEBUG. Aborting test.\n"; exit; } 1; HTML-CalendarMonth-2.04/t/03_datetime.t0000644000175000017500000000072212622653617016165 0ustar sisksisk#!/usr/bin/perl use strict; use FindBin; use lib $FindBin::RealBin; use testload; my($test_count, $method); BEGIN { $method = 'DateTime'; $test_count = bulk_count() + odd_count() + woy_count() + 2; } use Test::More tests => $test_count; SKIP: { eval "use $method"; skip("$method not installed", $test_count) if $@; check_datetool($method); check_bulk_with_datetool($method); check_odd_with_datetool($method); check_woy_with_datetool($method); } HTML-CalendarMonth-2.04/MANIFEST0000644000175000017500000000152112704220202014543 0ustar sisksiskChanges LICENSE MANIFEST Makefile.PL README lib/HTML/CalendarMonth.pm lib/HTML/CalendarMonth/DateTool.pm lib/HTML/CalendarMonth/DateTool/Cal.pm lib/HTML/CalendarMonth/DateTool/DateCalc.pm lib/HTML/CalendarMonth/DateTool/DateManip.pm lib/HTML/CalendarMonth/DateTool/DateTime.pm lib/HTML/CalendarMonth/DateTool/Ncal.pm lib/HTML/CalendarMonth/DateTool/TimeLocal.pm lib/HTML/CalendarMonth/Locale.pm t/00_basic.t t/01_autodetect.t t/02_timelocal.t t/03_datetime.t t/04_datemanip.t t/05_datecalc.t t/06_cal.t t/07_ncal.t t/20_i8n.t t/21_narrow.t t/dat/bulk.dat t/dat/head.dat t/dat/i8n.dat t/dat/i8n_leg1.dat t/dat/i8n_leg2.dat t/dat/narrow.dat t/dat/odd.dat t/dat/woy.dat t/testload.pm META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) HTML-CalendarMonth-2.04/lib/0000755000175000017500000000000012704220202014161 5ustar sisksiskHTML-CalendarMonth-2.04/lib/HTML/0000755000175000017500000000000012704220202014725 5ustar sisksiskHTML-CalendarMonth-2.04/lib/HTML/CalendarMonth.pm0000644000175000017500000010772712704220013020020 0ustar sisksiskpackage HTML::CalendarMonth; { $HTML::CalendarMonth::VERSION = '2.04'; } use strict; use warnings; use Carp; use HTML::ElementTable 1.18; use HTML::CalendarMonth::Locale; use HTML::CalendarMonth::DateTool; use base qw( Class::Accessor HTML::ElementTable ); my %Objects; # default complex attributes my %Calmonth_Attrs = ( head_m => 1, # month heading mode head_y => 1, # year heading mode head_dow => 1, # DOW heading mode head_week => 0, # weak of year year_span => 2, # default col span of year today => undef, # DOM, if not now week_begin => 1, # what DOW (1-7) is the 1st DOW? historic => 1, # if able to choose, use ncal/cal # rather than Date::Calc, which # blindly extrapolates Gregorian alias => {}, # what gets displayed if not # the default item month => undef, # these will get initialized year => undef, locale => 'en_US', full_days => 0, full_months => 1, datetool => undef, enable_css => 1, semantic_css => 0, # internal muckety muck _cal => undef, _itoch => {}, _ctoih => {}, _caltool => undef, _weeknums => undef, dow1st => undef, lastday => undef, loc => undef, # deprecated row_offset => undef, col_offset => undef, ); __PACKAGE__->mk_accessors(keys %Calmonth_Attrs); # Class::Accessor overrides sub set { my($self, $key) = splice(@_, 0, 2); if (@_ == 1) { $Objects{$self}{$key} = $_[0]; } elsif (@_ > 1) { $Objects{$self}{$key} = [@_]; } else { Carp::confess("wrong number of arguments received"); } } sub get { my $self = shift; if (@_ == 1) { return $Objects{$self}{$_[0]}; } elsif ( @_ > 1 ) { return @{$Objects{$self}{@_}}; } else { Carp::confess("wrong number of arguments received."); } } sub _is_calmonth_attr { shift; exists $Calmonth_Attrs{shift()} } sub _set_defaults { my $self = shift; foreach (keys %Calmonth_Attrs) { $self->$_($Calmonth_Attrs{$_}); } $self; } sub DESTROY { delete $Objects{shift()} } # last dow col, first week row use constant LDC => 6; use constant FWR => 2; # alias sub item_alias { my($self, $item) = splice(@_, 0, 2); defined $item or croak "item name required"; $self->alias->{$item} = shift if @_; $self->alias->{$item} || $item; } sub item_aliased { my($self, $item) = splice(@_, 0, 2); defined $item or croak "item name required.\n"; defined $self->alias->{$item}; } # header toggles sub _head { # Set/test entire heading (month,year,and dow headers) (does not # affect week number column). Return true if either heading active. my $self = shift; $self->head_m(@_) && $self->head_dow(@_) if @_; $self->_head_my || $self->head_dow; } sub _head_my { # Set/test month and year header mode my($self, $mode) = splice(@_, 0, 2); $self->head_m($mode) && $self->head_y($mode) if defined $mode; $self->head_m || $self->head_y; } sub _initialized { my $self = shift; @_ ? $self->{_initialized} = shift : $self->{_initialized}; } # circa interface sub _date { # set target month, year my $self = shift; if (@_) { my ($month, $year) = @_; $month && defined $year || croak "date method requires month and year"; croak "Date already set" if $self->_initialized(); # get rid of possible leading 0's $month += 0; $year += 0; $month <= 12 && $month >= 1 or croak "Month $month out of range (1-12)\n"; $year > 0 or croak "Negative years are unacceptable\n"; $self->month($self->monthname($month)); $self->year($year); $month = $self->monthnum($month); # trigger _gencal...this should be the only place where this occurs $self->_gencal; } return($self->month, $self->year); } # class factory access use constant CLASS_HET => 'HTML::ElementTable'; use constant CLASS_DATETOOL => 'HTML::CalendarMonth::DateTool'; use constant CLASS_LOCALE => 'HTML::CalendarMonth::Locale'; sub _gencal { # generate internal calendar representation my $self = shift; # new calendar...clobber day-specific settings my $itoc = $self->_itoch({}); my $ctoi = $self->_ctoih({}); # figure out dow of 1st day of the month as well as last day of the # month (uses date calculator backends) $self->_anchor_month(); # row count for weeks in grid my $wcnt = 0; my ($dowc) = $self->dow1st; my $skips = $self->_caltool->_skips; # for each day foreach (1 .. $self->lastday) { next if $skips->{$_}; my $r = $wcnt + FWR; my $c = $dowc; # this is a bootstrap until we know the number of rows in the month. $itoc->{$_} = [$r, $c]; $dowc = ++$dowc % 7; ++$wcnt unless $dowc || $_ == $self->lastday; } $self->{_week_rows} = $wcnt; my $row_extent = $wcnt + FWR; my $col_extent = LDC; $col_extent += 1 if $self->head_week; $self->SUPER::extent($row_extent, $col_extent); # table can contain the days now, so replace our bootstrap coordinates # with references to the actual elements. foreach (keys %$itoc) { my $cellref = $self->cell(@{$itoc->{$_}}); $self->_itoc($_, $cellref); $self->_ctoi($cellref, $_); } # week num affects month/year spans my $width = $self->head_week ? 8 : 7; # month/year headers my $cellref = $self->cell(0, 0); $self->_itoc($self->month, $cellref); $self->_ctoi($cellref, $self->month); $cellref = $self->cell(0, $width - $self->year_span); $self->_itoc($self->year, $cellref); $self->_ctoi($cellref, $self->year); $self->item($self->month)->replace_content($self->item_alias($self->month)); $self->item($self->year)->replace_content($self->item_alias($self->year)); if ($self->_head_my) { if ($self->head_m && $self->head_y) { $self->item($self->year) ->attr('colspan', $self->year_span); $self->item($self->month)->attr('colspan', $width - $self->year_span); } elsif ($self->head_y) { $self->item($self->month)->mask(1); $self->item($self->year)->attr('colspan', $width); } elsif ($self->head_m) { $self->item($self->year)->mask(1); $self->item($self->month)->attr('colspan', $width); } } else { $self->row(0)->mask(1); } # DOW headers my $trans; my $days = $self->loc->days; foreach (0..$#$days) { # Transform for week_begin 1..7 $trans = ($_ + $self->week_begin - 1) % 7; my $cellref = $self->cell(1, $_); $self->_itoc($days->[$trans], $cellref); $self->_ctoi($cellref, $days->[$trans]); } if ($self->head_dow) { grep($self->item($_)->replace_content($self->item_alias($_)), @$days); } else { $self->row(1)->mask(1); } # week number column if ($self->head_week) { # week nums can collide with days. Use "w" in front of the number # for uniqueness, and automatically alias to just the number (unless # already aliased, of course). $self->_gen_week_nums(); my $ws; my $row_count = FWR; foreach ($self->_numeric_week_nums) { $ws = "w$_"; $self->item_alias($ws, $_) unless $self->item_aliased($ws); my $cellref = $self->cell($row_count, $self->last_col); $self->_itoc($ws, $cellref); $self->_ctoi($cellref, $ws); $self->item($ws)->replace_content($self->item_alias($ws)); ++$row_count; } } # fill in days of the month my $i; foreach my $r (FWR .. $self->last_row) { foreach my $c (0 .. LDC) { $self->cell($r,$c)->replace_content($self->item_alias($i)) if ($i = $self->item_at($r,$c)); } } # css classes if ($self->enable_css) { $self->push_attr(class => 'hcm-table'); $self->item_row($self->dayheaders)->push_attr(class => 'hcm-day-head') if $self->head_dow; $self->item($self->year)->push_attr(class => 'hcm-year-head') if $self->head_y; $self->item($self->month)->push_attr(class => 'hcm-month-head') if $self->head_m; $self->item($self->week_nums) ->push_attr(class => 'hcm-week-head') if $self->head_week; } if ($self->semantic_css) { my $today = $self->today; if ($today < 0) { $self->item($self->days)->push_attr(class => 'hcm-past'); } elsif ($today == 0) { $self->item($self->days)->push_attr(class => 'hcm-future'); } else { for my $d ($self->days) { if ($d < $today) { $self->item($d)->push_attr(class => 'hcm-past'); } elsif ($d > $today) { $self->item($d)->push_attr(class => 'hcm-future'); } else { $self->item($d)->push_attr(class => 'hcm-today'); } } } } $self; } sub default_css { my $hbgc = '#DDDDDD'; my $bc = '#888888'; my $str = <<__CSS; __CSS } sub _datetool { my $self = shift; my $ct; if (! ($ct = $self->_caltool)) { $ct = $self->_caltool(CLASS_DATETOOL->new( year => $self->year, month => $self->month, weeknum => $self->head_week, historic => $self->historic, datetool => $self->datetool, )); } $ct; } sub _anchor_month { # Figure out what our month grid looks like. # Let HTML::CalendarMonth::DateTool determine which method is # appropriate. my $self = shift; my $month = $self->monthnum($self->month); my $year = $self->year; my $tool = $self->_datetool; my $dow1st = $tool->dow1st; # 0..6, starting with Sun my $lastday = $tool->lastday; # week_begin given as 1..7 starting with Sun $dow1st = ($dow1st - ($self->week_begin - 1)) % 7; $self->dow1st($dow1st); $self->lastday($lastday); $self; } sub _gen_week_nums { # Generate week-of-the-year numbers. The first week is generally # agreed upon to be the week that contains the 4th of January. # # For purposes of shenanigans with 'week_begin', we anchor the week # number off of Thursday in each row. my $self = shift; my($year, $month, $lastday) = ($self->year, $self->monthnum, $self->lastday); my $tool = $self->_caltool; croak "Oops. " . ref $tool . " not set up for week of year calculations.\n" unless $tool->can('week_of_year'); my $fdow = $self->dow1st; my $delta = 4 - $fdow; if ($delta < 0) { $delta += 7; } my @ft = $tool->add_days($delta, 1); my $ldow = $tool->dow($lastday); $delta = 4 - $ldow; if ($delta > 0) { $delta -= 7; } my @lt = $tool->add_days($delta, $lastday); my $fweek = $tool->week_of_year(@ft); my $lweek = $tool->week_of_year(@lt); my @wnums = $fweek > $lweek ? ($fweek, 1 .. $lweek) : ($fweek .. $lweek); # do we have days above our first Thursday? if ($self->row_of($ft[0]) != FWR) { unshift(@wnums, $wnums[0] -1); } # do we have days below our last Thursday? if ($self->row_of($lt[0]) != $self->last_row) { push(@wnums, $wnums[-1] + 1); } # first visible week is from last year if ($wnums[0] == 0) { $wnums[0] = $tool->week_of_year($tool->add_days(-7, $ft[0])); } # last visible week is from subsequent year if ($wnums[-1] > $lweek) { $wnums[-1] = $tool->week_of_year($tool->add_days(7, $lt[0])); } $self->_weeknums(\@wnums); } # month hooks sub row_items { # given a list of items, return all items in rows shared by the # provided items. my $self = shift; my %items; foreach my $item (@_) { my $row = ($self->coords_of($item))[0]; foreach my $col (0 .. $self->last_col) { my $i = $self->item_at($row, $col) || next; ++$items{$i}; } } keys %items > 1 ? keys %items : (keys %items)[0]; } sub col_items { # return all item cells in the columns occupied by the provided list # of items. my $self = shift; $self->_col_items(0, $self->last_row, @_); } sub daycol_items { # same as col_items(), but excludes header cells. my $self = shift; $self->_col_items(FWR, $self->last_row, @_); } sub _col_items { # given row bounds and a list of items, return all item elements # in the columns occupied by the provided items. Does not return # empty cells. my($self, $rfirst, $rlast) = splice(@_, 0, 3); my %items; my($item, $row, $col, %i); foreach my $item (@_) { my $col = ($self->coords_of($item))[1]; foreach my $row ($rfirst .. $rlast) { my $i = $self->item_at($row,$col) || next; ++$items{$i}; } } keys %items > 1 ? keys %items : (keys %items)[0]; } sub daytime { # return seconds since epoch for a given day my($self, $day) = splice(@_, 0, 2); $day or croak "must specify day of month"; croak "day does not exist" unless $self->_daycheck($day); $self->_caltool->day_epoch($day); } sub week_nums { # return list of all week number labels my @wnums = map("w$_", shift->_numeric_week_nums); wantarray ? @wnums : \@wnums; } sub _numeric_week_nums { # return list of all week numbers as numbers my $self = shift; return unless $self->head_week; wantarray ? @{$self->_weeknums} : $self->_weeknums; } sub days { # return list of all days of the month (1..$c->lastday). my $self = shift; my $skips = $self->_caltool->_skips; my @days = grep { !$skips->{$_} } (1 .. $self->lastday); wantarray ? @days : \@days; } sub dayheaders { # return list of all day headers (Su..Sa). shift->loc->days; } sub headers { # return list of all headers (month,year,dayheaders) my $self = shift; wantarray ? ($self->year, $self->month, $self->dayheaders) : [$self->year, $self->month, $self->dayheaders]; } sub items { # return list of all items (days, headers) my $self = shift; wantarray ? ($self->headers, $self->days) : [$self->headers, $self->days]; } sub last_col { # what's the max col of the calendar? my $self = shift; $self->head_week ? LDC + 1 : LDC; } sub last_day_col { LDC } sub last_row { # last row of the calendar my $self = shift; return ($self->coords_of($self->lastday))[0]; } *last_week_row = \&last_row; sub first_week_row { FWR }; sub past_days { my $self = shift; my $today = $self->today; if ($today < 0) { return $self->days; } elsif ($today == 0) { return; } return(1 .. $today); } sub future_days { my $self = shift; my $today = $self->today; if ($today < 0) { return; } elsif ($today == 0) { return $self->days; } return($today .. $self->last_day); } # custom glob interfaces sub item { # return TD elements containing items my $self = shift; @_ || croak "item(s) must be provided"; $self->cell(grep(defined $_, map($self->coords_of($_), @_))); } sub item_row { # return a glob of the rows of a list of items, including empty cells. my $self = shift; $self->row(map { $self->row_of($_) } @_); } sub item_day_row { # same as item_row, but excludes possible week number cells my $self = shift; return $self->item_row(@_) unless $self->head_week; my(%rows, @coords); for my $r (map { $self->row_of($_) } @_) { next if ++$rows{$r} > 1; for my $c (0 .. 6) { push(@coords, ($r, $c)); } } $self->cell(@coords); } sub item_week_nums { # glob of all week numbers my $self = shift; $self->item($self->week_nums); } sub item_col { # return a glob of the cols of a list of items, including empty cells. my $self = shift; $self->_item_col(0, $self->last_row, @_); } sub item_daycol { # same as item_col(), but excludes header cells. my $self = shift; $self->_item_col(2, $self->last_row, @_); } sub _item_col { # given row bounds and a list of items, return a glob representing # the cells in the columns occupied by the provided items, including # empty cells. my($self, $rfirst, $rlast) = splice(@_, 0, 3); defined $rfirst && defined $rlast or Carp::confess "No items provided"; my(%seen, @coords); foreach my $col (map { $self->col_of($_) } @_) { next if ++$seen{$col} > 1; foreach my $row ($rfirst .. $rlast) { push(@coords, $row, $col); } } $self->cell(@coords); } sub item_box { # return a glob of the box defined by two items my($self, $item1, $item2) = splice(@_, 0, 3); defined $item1 && defined $item2 or croak "Two items required"; $self->box($self->coords_of($item1), $self->coords_of($item2)); } sub all { # return a glob of all calendar cells, including empty cells. my $self = shift; $self->box( 0,0 => $self->last_row, $self->last_col ); } sub alldays { # return a glob of all cells other than header cells my $self = shift; $self->box( 2, 0 => $self->last_row, 6 ); } sub allheaders { # return a glob of all header cells my $self = shift; $self->item($self->headers); } # transformation Methods sub coords_of { # convert an item into grid coordinates my $self = shift; croak "undefined value passed to coords_of()" if @_ && ! defined $_[0]; my $ref = $self->_itoc(@_); my @pos = ref $ref ? $ref->position : (); @pos ? (@pos[$#pos - 1, $#pos]) : (); } sub item_at { # convert grid coords into item my $self = shift; $self->_ctoi($self->cell(@_)); } sub _itoc { # item to grid my($self, $item, $ref) = splice(@_, 0, 3); defined $item or croak "item required"; my $itoc = $self->_itoch; if ($ref) { croak "Reference required" unless ref $ref; $itoc->{$item} = $ref; } $itoc->{$item}; } sub _ctoi { # cell reference to item my($self, $refstring, $item) = splice(@_, 0, 3); defined $refstring or croak "cell id required"; my $ctoi = $self->_ctoih; if (defined $item) { $ctoi->{$refstring} = $item; } $ctoi->{$refstring}; } sub row_of { my $self = shift; ($self->coords_of(@_))[0]; } sub col_of { my $self = shift; ($self->coords_of(@_))[1]; } sub monthname { # check/return month...returns name. Accepts month number or string. my $self = shift; return $self->month unless @_; my $loc = $self->loc; my @names; for my $m (@_) { $m = ($m - 1) % 12 if $m && $m =~ /^\d+$/; $m = $loc->monthname($m) || croak "month not found " . join(', ', @_); return $m if @_ == 1; push(@names, $m); } @names; } sub monthnum { # check/return month, returns number. Accepts month number or string. my $self = shift; my @months = @_ ? @_ : $self->month; my $loc = $self->loc; my @nums; for my $m (@months) { $m = ($m - 1) % 12 if $m && $m =~ /^\d+$/; $m = $loc->monthnum($m); croak "month not found ", join(', ', @_) unless defined $m; $m += 1; return $m if @_ == 1; push(@nums, $m); } @nums; } sub dayname { # check/return day...returns name. Accepts 1..7, or Su..Sa my $self = shift; @_ || croak "day string or num required"; my $loc = $self->loc; my @names; for my $d (@_) { if ($d =~ /^\d+$/) { $d = (($d - 1) % 7) + $self->week_begin - 1; } $d = $loc->dayname($d) || croak "day not found ", join(', ', @_); return $d if @_ == 1; push(@names, $d); } @names; } sub daynum { # check/return day number 1..7, returns number. Accepts 1..7, # or Su..Sa my $self = shift; @_ || croak "day string or num required"; my $loc = $self->loc; my @nums; for my $d (@_) { if ($d =~ /^\d+$/) { $d = (($d - 1) % 7) + $self->week_begin - 1; } $d = $loc->daynum($d); croak "day not found ", join(', ', @_) unless defined $d; $d += 1; return $d if @_ == 1; push(@nums, $d); } @nums; } # tests-n-checks sub _dayheadcheck { # test day head names my($self, $name) = splice(@_, 0, 2); $name or croak "name missing"; return if $name =~ /^\d+$/; $self->daynum($name); } sub _daycheck { # check if an item is a day of the month (1..31) my($self, $item) = splice(@_, 0, 2); croak "item required" unless $item; # can't just invert _headcheck because coords_of() needs _daycheck, # and _headcheck uses coords_of() $item =~ /^\d{1,2}$/ && $item <= 31; } sub _headcheck { # check if an item is a header !_daycheck(@_); } # constructors/destructors sub new { my $class = shift; my %parms = @_; my(%attrs, %tattrs); foreach (keys %parms) { if (__PACKAGE__->_is_calmonth_attr($_)) { $attrs{$_} = $parms{$_}; } else { $tattrs{$_} = $parms{$_}; } } my $self = CLASS_HET->new(%tattrs); bless $self, $class; # set defaults $self->_set_defaults; my $month = delete $attrs{month}; my $year = delete $attrs{year}; if (!$month || !$year) { my ($nmonth,$nyear) = (localtime(time))[4,5]; ++$nmonth; $nyear += 1900; $month ||= $nmonth; $year ||= $nyear; } $self->month($month); $self->year($year); # set overrides for my $k (keys %attrs) { $self->$k($attrs{$k}) if defined $attrs{$k}; } my $loc = CLASS_LOCALE->new( id => $self->locale, full_days => $self->full_days, full_months => $self->full_months, ) or croak "Problem creating locale " . $self->locale . "\n"; $self->loc($loc); my $dt = CLASS_DATETOOL->new( year => $self->year, month => $self->month, weeknum => $self->head_week, historic => $self->historic, datetool => $self->datetool, ); $self->_caltool($dt); $self->week_begin($loc->first_day_of_week + 1) unless defined $attrs{week_begin}; my $dom_now = defined $attrs{today} ? $dt->_dom_now(delete $attrs{today}) : $dt->_dom_now; $self->today($dom_now); my $alias = $attrs{alias} || {}; if ($self->full_days < 0) { my @full = $self->loc->days; my @narrow = $self->loc->narrow_days; for my $i (0 .. $#narrow) { $alias->{$full[$i]} = $narrow[$i]; } } if ($self->full_months < 0) { my @full = $self->loc->months; my @narrow = $self->loc->narrow_months; for my $i (0 .. $#narrow) { $alias->{$full[$i]} = $narrow[$i]; } } $self->alias($alias) if keys %$alias; # for now, this is the only time this will every happen for this # object. It is now 'initialized'. $self->_date($month, $year); $self; } ### overrides (our table is static) sub extent { } sub maxrow { shift->SUPER::maxrow } sub maxcol { shift->SUPER::maxcol } ### deprecated use constant row_offset => 0; use constant col_offset => 0; use constant first_col => 0; use constant first_row => 0; use constant first_week_col => 0; use constant last_week_col => 6; ### 1; __END__ =head1 NAME HTML::CalendarMonth - Generate and manipulate HTML calendar months =head1 SYNOPSIS use HTML::CalendarMonth; # Using regular HTML::Element creation my $c = HTML::CalendarMonth->new( month => 8, year => 2010 ); print $c->as_HTML; # Full locale support via DateTime::Locale my $c2 = HTML::CalendarMonth->new( month => 8, year => 2010, locale => 'zu-ZA' ); print $c2->as_HTML; # HTML-Tree integration my $tree = HTML::TreeBuilder->parse_file('cal.html'); $tree->find_by_attribute(class => 'hcm-calendar')->replace_with($c); print $tree->as_HTML; # clean up if you're not done, HTML::Element structures must be # manually destroyed $c->delete; $c2->delete; =head1 DESCRIPTION HTML::CalendarMonth is a subclass of HTML::ElementTable. See L for how that class works, for it affects this module on many levels. Like HTML::ElementTable, HTML::CalendarMonth is an enhanced HTML::Element with methods added to facilitate the manipulation of the calendar table elements as a whole. The primary interaction with HTML::CalendarMonth is through I rather than cell coordinates like HTML::ElementTable uses. An I is merely a string that represents the content of the cell of interest within the calendar. For instance, the element representing the 14th day of the month would be returned by C<$c-Eitem(14)>. Similarly, the element representing the header for Monday would be returned by C<$c- Eitem('Mo')>. If the year happened to by 2010, then C<$c- Eitem(2010)> would return the cell representing the year. Since years and particular months change frequently, it is probably more useful to take advantage of the C and C methods, which return their respective values. The following is therefore the same as explicitely referencing the year: C<$c-Eitem($c- Eyear())>. Multiple cells of the calendar can be manipulated as if they were a single element. For instance, C<$c-Eitem(15)-Eattr(class =E 'fancyday')> would alter the class of the cell representing the 15th. By the same token, C<$c-Eitem(15, 16, 17, 23)-Eattr(class =E 'fancyday')> would do the same thing for all cells containing the days passed to the C method. Underneath, the calendar is still nothing more than a table structure, the same as provided by the HTML::ElementTable class. In addition to the I based access methods above, calendar cells can still be accessed using row and column grid coordinates using the C method provided by the table class. All coordinate-based methods in the table class are accessible to the calendar class. The module includes support for week-of-the-year numbering, arbitrary 1st day of the week definitions, and locale support. Dates that are beyond the range of the built-in time functions of perl are handled either by the ncal/cal command, Date::Calc, DateTime, or Date::Manip. The presence of any one of these utilities and modules will suffice for these far flung date calculations. One of these utilities (with the exception of 'cal') is also required if you want to use week-of- year numbering. Full locale support is offered via DateTime::Locale. For a full list of supported locale id's, look at HTML::CalendarMonth::Locale->locales(). =head1 METHODS All arguments appearing in [brackets] are optional, and do not represent anonymous array references. =head2 Constructor =over =item new() With no arguments, the constructor will return a calendar object representing the current month with a default appearance. The initial configuration of the calendar is controlled by special attributes. Non- calendar related attributes are passed along to HTML::ElementTable. Any non-table related attributes left after that are passed to HTML::Element while constructing the EtableE tag. See L if you are interested in attributes that can be passed along to that class. Special Attributes for HTML::CalendarMonth: =over =item month 1-12, or Jan-Dec. Defaults to current month. =item year Four digit representation. Defaults to current year. =item head_m Specifies whether to display the month header. Default 1. =item head_y Specifies whether to display the year header. Default 1. =item head_dow Specifies whether to display days of the week header. Default 1. =item head_week Specifies whether to display the week-of-year numbering. Default 0. =item locale Specifies the id of the locale in which to render the calendar. Default is 'en-US'. By default, this will also control determine which day is considered to be the first day of the week. See L for more information. If for some reason you prefer to use different labels than those provided by C, see the C attribute below. NOTE: DateTime::Locale versions 0.92 and earlier use underscores rather than dashes, e.g. 'en_US'. =item full_days Specifies whether or not to use full day names or their abbreviated names. Default is 0, use abbreviated names. Use -1 for 'narrow' mode, the shortest (not guaranteed to be unique) abbreviations. =item full_months Specifies whether or not to use full month names or their abbreviated names. Default is 1, use full names. Use -1 for 'narrow' mode, the shortest (not guaranteed to be unique) abbreviations. =item alias Takes a hash reference mapping labels provided by C to any custom label you prefer. Lookups, such as C, will still use the locale string, but when the calendar is rendered the aliased value will appear. =item week_begin Specify first day of the week, which can be 1..7, starting with Sunday. In order to specify Monday, set this to 2, and so on. By default, this is determined based on the locale. =item enable_css Set some handy CSS class attributes on elements, enabled by default. Currently the classes are: hcm-table Set on the EtableE tag of the calendar hcm-day-head Set on the day-of-week EtrE or EtdE tags hcm-year-head Set on the EtdE tag for the year hcm-month-head Set on the EtdE tag for the month hcm-week-head Set on the EtdE tags for the week-of-year =item semantic_css Sets some additional CSS class attributes on elements, disabled by default. The notion of 'today' is taken either from the system clock (default) or from the 'today' parameter as provided to new(). Currently these classes are: hcm-today Set on the EtdE tag for today, if present hcm-past Set on the EtdE tags for prior days, if present hcm-future Set on the EtdE tags for subsequent days, if present =item today Specify the value for 'today' if different from the local time as reported by the system clock (the default). If specified as two or less digits, it is assumed to be one of the days of the month in the current calendar. If more than two digits, it is assumed to be a epoch time in seconds. Otherwise it must be given as a string of the form 'YYYY-mm- dd'. Note that the default value as determined by the system clock uses localtime rather than gmtime. =item historic This option is ignored for dates that do not exceed the range of the built- in perl time functions. For dates that B exceed these ranges, this option specifies the default calculation method. When set, if the 'ncal' or 'cal' command is available on your system, that will be used rather than the Date::Calc or Date::Manip modules. This can be an issue since the date modules blindly extrapolate the Gregorian calendar, whereas ncal/cal will revert to the Julian calendar during September 1752. If either ncal or cal are not available on your system, this attribute is meaningless. Defaults to 1. =back =back =head2 Item Query Methods The following methods return lists of item *symbols* (28, 29, 'Thu', ...) that are related in some way to the provided list of items. The returned symbols may then be used as arguments to the glob methods detailed further below. =over =item row_items(item1, [item2, ...]) Returns all item symbols in rows shared by the provided item symbols. =item col_items(item1, [item2, ...]) Returns all item symbols in columns shared by the provided item symbols. =item daycol_items(col_item1, [col_item2, ...]) Same as col_items(), but the returned item symbols are limited to those that are not header items (month, year, day-of-week). =item row_of(item1, [item2, ...]) Returns the row indices of rows containing the provided item symbols. =item col_of(item1, [item2, ...]) Returns the column indices of columns containing the provided item symbols. =item lastday() Returns the day number (symbol) of the last day of the month. =item dow1st() Returns the column index for the first day of the month. =item days() Returns a list of all days of the month as numbers. =item week_nums() Returns a list of week-of-year numbers for this month. =item dayheaders() Returns a list of all day headers (Su..Sa) =item headers() Returns a list of all headers (month, year, dayheaders) =item items() Returns a list of all item symbols (day number, header values) in the calendar. =item last_col() Returns the index of the last column of the calendar (note that this could be the week-of-year column if head_week is enabled). =item last_day_col() Returns the index of the last column of the calendar containing days of the month (same as last_col() unless week-of-year is enabled). =item first_week_row() Returns the index of the first row of the calendar containing day items (ie, the first week). =item last_row() Returns the index of the last row of the calendar. =item today() Returns the day of month for 'today', if present in the current calendar. =item past_days() Returns a list of days prior to 'today'. If 'today' is in a future month, all days are returned. If 'today' is in a past month, no days are returned. =item future_days() Returns a list of days after 'today'. If 'today' is in a past month, all days are returned. If 'today' is in a future month, no days are returned. =back =head2 Glob Methods Glob methods return references that are functionally equivalent to an individual calendar cell. Mostly, they provide item based analogues to the glob methods provided in HTML::ElementTable. In methods dealing with rows, columns, and boxes, the globs include empty calendar cells (which would otherwise need to be accessed through native HTML::ElementTable methods). The row and column numbers returned by the item methods above are compatible with the grid based methods in HTML::ElementTable. For details on how these globs work, check out L and L. =over =item item(item1, [item2, ...]) Returns all cells containing the provided item symbols. =item item_row(item1, [item2, ...]) Returns all cells in all rows occupied by the provided item symbols. =item item_day_row(item1, [item2, ...]) Same as item_row() except excludes week-of-year cells, if present. =item item_col(item1, [item2, ...]) Returns all cells in all columns occupied by the provided item symbols. =item item_daycol(item1, [item2, ...]) Same as item_col() except limits the cells to non header cells. =item item_week_nums() Returns all week-of-year cells, if present. =item item_box(item1a, item1b, [item2a, item2b, ...]) Returns all cells in the boxes defined by the item pairs provided. =item allheaders() Returns all header cells. =item alldays() Returns all non header cells, including empty cells. =item all() Returns all cells in the calendar, including empty cells. =back =head2 Transformation Methods The following methods provide ways of translating between various item symbols, coordinates, and other representations. =over =item coords_of(item) Returns the row and column coordinates of the provided item symbol, for use with the grid based methods in HTML::ElementTable. =item item_at(row,column) Returns the item symbol of the item at the provided coordinates, for use with the item based methods of HTML::CalendarMonth. =item monthname(monthnum) Returns the name (item symbol) of the month number provided, where I can be 1..12. =item monthnum(monthname) Returns the number (1..12) of the month name provided. Only a minimal case-insensitive match on the month name is necessary; the proper item symbol for the month will be determined from this match. =item dayname(daynum) Returns the name (item symbol) of the day of week header for a number of a day of the week, where I is 1..7. =item daynum(dayname) Returns the number of the day of the week given the symbolic name for that day (Su..Sa). =item daytime(day) Returns the number in seconds since the epoch for a given day. The day must be present in the current calendar. =back =head2 Other Methods =over =item default_css() Returns a simple style sheet as a string that can be used in an HTML document in conjunction with the classes assigned to elements when css is enabled. =back =head1 REQUIRES HTML::ElementTable =head1 OPTIONAL Date::Calc, DateTime, or Date::Manip (only if you want week-of- year numbering or non-contemporary dates on a system without the I command) =head1 AUTHOR Matthew P. Sisk, EFE =head1 COPYRIGHT Copyright (c) 1998-2015 Matthew P. Sisk. All rights reserved. All wrongs revenged. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 SEE ALSO A useful page of examples can be found at http://www.mojotoad.com/sisk/projects/HTML-CalendarMonth. For information on iso639 standards for abbreviations for language names, see http://www.loc.gov/standards/iso639-2/englangn.html HTML::ElementTable(3), HTML::Element(3), perl(1) =for Pod::Coverage col_offset row_offset item_alias item_aliased last_week_row HTML-CalendarMonth-2.04/lib/HTML/CalendarMonth/0000755000175000017500000000000012704220202017444 5ustar sisksiskHTML-CalendarMonth-2.04/lib/HTML/CalendarMonth/DateTool.pm0000644000175000017500000003026112622653617021542 0ustar sisksiskpackage HTML::CalendarMonth::DateTool; { $HTML::CalendarMonth::DateTool::VERSION = '1.26'; } # Base class for determining what date calculation package to use. use strict; use warnings; use Carp; use File::Which qw( which ); my %Toolmap = ( 'Time::Local' => 'TimeLocal', 'Date::Calc' => 'DateCalc', 'DateTime' => 'DateTime', 'Date::Manip' => 'DateManip', 'ncal' => 'Ncal', 'cal' => 'Cal', ); my %Classmap; $Classmap{lc $Toolmap{$_}} = $_ foreach keys %Toolmap; my($Cal_Cmd, $Ncal_Cmd); sub _toolmap { shift; my $str = shift; my $tool = $Toolmap{$str}; unless ($tool) { foreach (values %Toolmap) { if ($str =~ /^$_$/i) { $tool = $_; last; } } } return unless $tool; join('::', __PACKAGE__, $tool); } sub new { my $class = shift; my $self = {}; bless $self, $class; my %parms = @_; $self->{year} = $parms{year}; $self->{month} = $parms{month}; $self->{weeknum} = $parms{weeknum}; $self->{historic} = $parms{historic}; if (! $self->{year}) { my @dmy = $self->_dmy_now; $self->{year} = $dmy[2]; $self->{month} ||= $dmy[1]; } $self->{month} ||= 1; if ($parms{datetool}) { $self->{datetool} = $self->_toolmap($parms{datetool}) or croak "Sorry, didn't find a tool for datetool '$parms{datetool}'\n"; } my $dc = $self->_summon_date_class; unless (eval "require $dc") { croak "Problem loading $dc ($@)\n"; } # rebless into new class bless $self, $dc; } sub year { shift->{year} } sub month { shift->{month} } sub weeknum { shift->{weeknum} } sub historic { shift->{historic} } sub datetool { shift->{datetool} } sub _name { my $class = shift; $class = ref $class || $class; lc((split(/::/, $class))[-1]); } sub _cal_cmd { my $self = shift; if (! defined $Cal_Cmd) { $Cal_Cmd = which('cal') || ''; if ($Cal_Cmd) { my @out = grep { ! /^\s*$/ } `$Cal_Cmd 9 1752`; # September 1752 #Su Mo Tu We Th Fr Sa # 1 2 14 15 16 #17 18 19 20 21 22 23 #24 25 26 27 28 29 30 my @pat = ( qr/^\s*\S+\s+\d+$/, qr/^\s*\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s*$/, qr/^\s*\d+\s+\d+\s+\d+\s+\d+\s+\d+\s*$/, qr/^\s*\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s*$/, qr/^\s*\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s*$/, ); if (@out == @pat) { for my $i (0 .. $#out) { if ($out[$i] !~ $pat[$i]) { $Cal_Cmd = ''; last; } } } else { $Cal_Cmd = ''; } } } $Cal_Cmd; } sub _ncal_cmd { my $self = shift; if (! defined $Ncal_Cmd) { $Ncal_Cmd = which('ncal') || ''; if ($Ncal_Cmd) { my @out = grep { ! /^\s*$/ } map { s/^\s*//; $_ } `$Ncal_Cmd 9 1752`; # September 1752 #Mo 18 25 #Tu 1 19 26 #We 2 20 27 #Th 14 21 28 #Fr 15 22 29 #Sa 16 23 30 #Su 17 24 my @pat = ( qr/^\s*\S+\s+\d+$/, qr/^\s*\S+\s+\d+\s+\d+\s*$/, qr/^\s*\S+\s+\d+\s+\d+\s+\d+\s*$/, qr/^\s*\S+\s+\d+\s+\d+\s+\d+\s*$/, qr/^\s*\S+\s+\d+\s+\d+\s+\d+\s*$/, qr/^\s*\S+\s+\d+\s+\d+\s+\d+\s*$/, qr/^\s*\S+\s+\d+\s+\d+\s+\d+\s*$/, qr/^\s*\S+\s+\d+\s+\d+\s*$/, ); if (@out == @pat) { for my $i (0 .. $#out) { if ($out[$i] !~ $pat[$i]) { $Ncal_Cmd = ''; last; } } } else { $Ncal_Cmd = ''; } } } $Ncal_Cmd; } sub day_epoch { # in case our subclasses are lazy my($self, $day, $month, $year) = @_; $month ||= $self->month; $year ||= $self->year; Time::Local::timegm(0,0,0,1,$month,$year); } sub _skips { my $self = shift; @_ ? $self->{skips} = shift : $self->{skips}; } sub dow1st { (shift->dow1st_and_lastday)[0] } sub lastday { (shift->dow1st_and_lastday)[1] } sub _dmy_now { my $self = shift; my $ts = @_ ? shift : time; my($d, $m, $y) = (localtime($ts))[3,4,5]; ++$m; $y += 1900; ($d, $m, $y); } sub _dom_now { my $self = shift; my $ts = @_ ? shift : time; my($d, $m, $y); if ($ts =~ /^\d+$/) { if (length $ts <= 2) { ($d, $m, $y) = ($ts, $self->month, $self->year); croak "invalid day of month (1 .. " . $self->lastday . ") '$ts'" unless $ts >= 1 && $ts <= $self->lastday; } else { ($d, $m, $y) = $self->_dmy_now($ts); } } else { ($y, $m, $d) = $ts =~ m{^(\d+)/(\d\d)/(\d\d)$}; croak "invalid yyyy/mm/dd date string '$ts'" unless defined $d; } my($cy, $cm) = ($self->year, $self->month); my $first = sprintf("%04d/%02d/%02d", $cy, $cm, 1); my $last = sprintf("%04d/%02d/%02d", $cy, $cm, $self->lastday); my $pivot = sprintf("%04d/%02d/%02d", $y, $m, $d); return -1 if $pivot gt $last; return 0 if $pivot lt $first; $d; } sub _summon_date_class { my $self = shift; my @tools; if (my $c = $self->datetool) { eval "use $c"; die "invalid date tool $c : $@" if $@; @tools = $c->_name; } else { @tools = qw( timelocal datecalc datetime datemanip ncal cal ); } my($dc, @fails); for my $tool (@tools) { my $method = join('_', '', lc($tool), 'fails'); if (my $f = $self->$method) { push(@fails, [$tool, $f]); } else { $dc = $self->_toolmap($tool); last; } } return $dc if $dc; if (@tools == 1) { croak "invalid date tool " . join(': ', @{$fails[0]}); } else { croak join("\n", "no valid date tool found:", map(sprintf("%11s: %s", @$_), @fails), "\n" ); } } sub _dump_tests { my $self = shift; print "Time::Local : ", $self->_timelocal_fails || 1, "\n"; print " Date::Calc : ", $self->_datecalc_fails || 1, "\n"; print " DateTime : ", $self->_datetime_fails || 1, "\n"; print "Date::Manip : ", $self->_datemanip_fails || 1, "\n"; print " ncal : ", $self->_ncal_fails || 1, "\n"; print " cal : ", $self->_cal_fails || 1, "\n"; } sub _is_julian { my $self = shift; my $y = $self->year; $y < 1752 || ($y == 1752 && $self->month <= 9); } sub _timelocal_fails { my $self = shift; return "not installed" unless $self->_timelocal_present; return "week-of-year numbering unsupported" if $self->weeknum; my $y = $self->year; return "only years between 1970 and 2038 supported" if $y < 1970 || $y >= 2038; return; } sub _ncal_fails { my $self = shift; return "command not found" unless $self->_ncal_present; return "week-of-year numbering not supported prior to 1752/09" if $self->weeknum && $self->_is_julian; return; } sub _cal_fails { my $self = shift; return "command not found" unless $self->_cal_present; return "week-of-year numbering not supported" if $self->weeknum; return; } sub _datecalc_fails { my $self = shift; return "not installed" unless $self->_datecalc_present; return "historic mode prior to 1752/09 not supported" if $self->historic && $self->_is_julian; return; } sub _datetime_fails { my $self = shift; return "not installed" unless $self->_datetime_present; return "historic mode prior to 1752/09 not supported" if $self->historic && $self->_is_julian; return; } sub _datemanip_fails { my $self = shift; return "not installed" unless $self->_datemanip_present; return "historic mode prior to 1752/09 not supported" if $self->historic && $self->_is_julian; eval { require Date::Manip && Date::Manip::Date_Init() }; return "init failure: $@" if $@; return; } sub _timelocal_present { eval "require Time::Local"; return !$@ } sub _datecalc_present { eval "require Date::Calc"; return !$@ } sub _datetime_present { eval "require DateTime"; return !$@ } sub _datemanip_present { eval "require Date::Manip"; return !$@ } sub _ncal_present { shift->_ncal_cmd } sub _cal_present { shift->_cal_cmd }; 1; __END__ =head1 NAME HTML::CalendarMonth::DateTool - Base class for determining which date package to use for calendrical calculations. =head1 SYNOPSIS my $date_tool = HTML::CalendarMonth::DateTool->new( year => $YYYY_year, month => $one_thru_12_month, weeknum => $weeknum_mode, historic => $historic_mode, datetool => $specific_datetool_if_desired, ); =head1 DESCRIPTION This module attempts to utilize the best date calculation package available on the current system. For most contemporary dates this usually ends up being the internal Time::Local package of perl. For more exotic dates, or when week number of the years are desired, other methods are attempted including DateTime, Date::Calc, Date::Manip, and the linux/unix 'ncal' or 'cal' commands. Each of these has a specific subclass of this module offering the same utility methods needed by HTML::CalendarMonth. =head1 METHODS =over =item new() Constructor. Takes the following parameters: =over =item year Year of calendar in question (required). If you are rendering exotic dates (i.e. dates outside of 1970 to 2038) then something besides Time::Local will be used for calendrical calculations. =item month Month of calendar in question (required). 1 through 12. =item weeknum Optional. When specified, will limit class excursions to those that are currently set up for week of year calculations. =item historic Optional. If the the ncal or cal commands are available, use one of them rather than other available date modules since these utilities accurately handle some specific historical artifacts such as the transition from Julian to Gregorian. =item datetool Optional. Mostly for debugging, this option can be used to indicate a specific HTML::CalendarMonth::DateTool subclass for instantiation. The value can be either the actual utility class, e.g., Date::Calc, or the name of the CalendarMonth handler leaf class, e.g. DateCalc. Use 'ncal' or 'cal', respectively, for the wrappers around those commands. =back =back There are number of methods automatically available: =over =item month() =item year() =item weeknum() =item historical() =item datetool() Accessors for the parameters provided to C above. =item dow1st() Returns the day of week number for the 1st of the C and C specified during the call to C. Relies on the presence of C. Should be 0..6 starting with Sun. =item lastday() Returns the last day of the month for the C and C specified during the call to C. Relies on the presence of C. =back =head1 Overridden methods Subclasses of this module must provide at least the C and C methods. =over =item dow1st_and_lastday() Required. Provides a list containing the day of the week of the first day of the month (0..6 starting with Sun) along with the last day of the month. =item day_epoch() Optional unless interested in epoch values for wacky dates. For a given day, and optionally C and C if they are different from those specified in C, provide the unix epoch in seconds for that day at midnight. =back If the subclass is expected to provide week of year numbers, three more methods are necessary: =over =item dow() For a given day, and optionally C and C if they are different from those specified in C, provide the day of week number. (0=Sunday, 6=Saturday). =item add_days($days, $delta, $day, [$month], [$year]) For a given day, and optionally C and C if they are different from those specified in C, provide a list of year, month, and day once C days have been added. =item week_of_year($day, [$month], [$year]) For a given day, and optionally C and C if they are different from those specified in C, provide a list with the week number of the year along with the year. (some days of a particular year can end up belonging to the prior or following years). =back =head1 AUTHOR Matthew P. Sisk, EFE =head1 COPYRIGHT Copyright (c) 2010 Matthew P. Sisk. All rights reserved. All wrongs revenged. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 SEE ALSO HTML::CalendarMonth(3), Time::Local(3), DateTime(3), Date::Calc(3), Date::Manip(3), cal(1) HTML-CalendarMonth-2.04/lib/HTML/CalendarMonth/DateTool/0000755000175000017500000000000012704220202021157 5ustar sisksiskHTML-CalendarMonth-2.04/lib/HTML/CalendarMonth/DateTool/DateManip.pm0000644000175000017500000000322312622653617023402 0ustar sisksiskpackage HTML::CalendarMonth::DateTool::DateManip; { $HTML::CalendarMonth::DateTool::DateManip::VERSION = '1.26'; } # Interface to Date::Manip use strict; use warnings; use Carp; use base qw( HTML::CalendarMonth::DateTool ); use Date::Manip qw( Date_DaysInMonth Date_DayOfWeek DateCalc UnixDate Date_SecsSince1970 ParseDateDelta ); sub dow1st_and_lastday { my($self, $month, $year) = @_; $month ||= $self->month; $year ||= $self->year; ($self->dow(1), Date_DaysInMonth($month, $year)); } sub day_epoch { my($self, $day, $month, $year) = @_; $day || croak "day required.\n"; $month ||= $self->month; $year ||= $self->year; Date_SecsSince1970($month, $day, $year, 0, 0, 0); } sub dow { # Date::Manip uses 1..7 as indicies in the week, starting with Monday. # Convert to 0..6 starting with Sunday. my($self, $day, $month, $year) = @_; $day || croak "day required.\n"; $month ||= $self->month; $year ||= $self->year; Date_DayOfWeek($month, $day, $year) % 7; } sub add_days { my($self, $delta, $day, $month, $year) = @_; defined $delta || croak "delta (in days) required.\n"; $day || croak "day required.\n"; $month ||= $self->month; $year ||= $self->year; my $date = DateCalc( sprintf("%04d%02d%02d", $year, $month, $day), "$delta days" ); my($y, $m, $d) = $date =~ /^(\d{4})(\d\d)(\d\d)/; $_ += 0 foreach ($y, $m, $d); ($d, $m, $y); } sub week_of_year { my($self, $day, $month, $year) = @_; $day || croak "day required.\n"; $month ||= $self->month; $year ||= $self->year; my $week = UnixDate(sprintf("%04d%02d%02d", $year, $month, $day), '%U'); $week += 0; ($year, $week); } 1; HTML-CalendarMonth-2.04/lib/HTML/CalendarMonth/DateTool/Cal.pm0000644000175000017500000000163712622653617022246 0ustar sisksiskpackage HTML::CalendarMonth::DateTool::Cal; { $HTML::CalendarMonth::DateTool::Cal::VERSION = '1.26'; } # Interface to unix 'cal' command use strict; use warnings; use Carp; use base qw( HTML::CalendarMonth::DateTool ); sub dow1st_and_lastday { my($self, $month, $year) = @_; $month ||= $self->month; $year ||= $self->year; my $cmd = $self->_cal_cmd or croak "cal command not found\n"; my @cal = grep(!/^\s*$/,`$cmd $month $year`); chomp @cal; my @days = grep(/\d+/,split(/\s+/,$cal[2])); my $dow1st = 6 - $#days; my($lastday) = $cal[$#cal] =~ /(\d+)\s*$/; # With dow1st and lastday, one builds a calendar sequentially. # Historically, in particular Sep 1752, days have been skipped. Here's # the chance to catch that. $self->_skips(undef); if ($month == 9 && $year == 1752) { my %skips; grep(++$skips{$_}, 3 .. 13); $self->_skips(\%skips); } ($dow1st, $lastday); } 1; HTML-CalendarMonth-2.04/lib/HTML/CalendarMonth/DateTool/DateCalc.pm0000644000175000017500000000272012622653617023201 0ustar sisksiskpackage HTML::CalendarMonth::DateTool::DateCalc; { $HTML::CalendarMonth::DateTool::DateCalc::VERSION = '1.26'; } # Interface to Date::Calc use strict; use warnings; use Carp; use base qw( HTML::CalendarMonth::DateTool ); use Date::Calc qw( Days_in_Month Day_of_Week Add_Delta_Days Weeks_in_Year Week_of_Year Week_Number Mktime ); sub dow1st_and_lastday { my($self, $month, $year) = @_; $month ||= $self->month; $year ||= $self->year; ($self->dow(1), Days_in_Month($year, $month)); } sub day_epoch { my($self, $day, $month, $year) = @_; $month ||= $self->month; $year ||= $self->year; Mktime($year, $month, $day, 0, 0, 0); } sub dow { my($self, $day, $month, $year) = @_; $day || croak "day required.\n"; $month ||= $self->month; $year ||= $self->year; # Date::Calc uses 1..7 as indicies in the week, starting with Monday. # Convert to 0..6, starting with Sunday. Day_of_Week($year, $month, $day) % 7; } sub add_days { my($self, $delta, $day, $month, $year) = @_; defined $delta || croak "delta (in days) required.\n"; $day || croak "day required.\n"; $month ||= $self->month; $year ||= $self->year; my($y, $m, $d) = Add_Delta_Days($year, $month, $day, $delta); ($d, $m, $y); } sub week_of_year { my($self, $day, $month, $year) = @_; $day || croak "day required.\n"; $month ||= $self->month; $year ||= $self->year; my $week; ($week, $year) = Week_of_Year($year, $month, $day); ($year, $week); } 1; HTML-CalendarMonth-2.04/lib/HTML/CalendarMonth/DateTool/DateTime.pm0000644000175000017500000000372412622653617023242 0ustar sisksiskpackage HTML::CalendarMonth::DateTool::DateTime; { $HTML::CalendarMonth::DateTool::DateTime::VERSION = '1.26'; } # Interface to DateTime use strict; use warnings; use Carp; use base qw( HTML::CalendarMonth::DateTool ); use DateTime; sub dow1st_and_lastday { my($self, $month, $year) = @_; $month ||= $self->month; $year ||= $self->year; my $lastday = $self->_last_dom_dt($year, $month); my $dow1st = $self->dow(1); ($dow1st, $lastday->day); } sub day_epoch { my($self, $day, $month, $year) = @_; $day || croak "day required.\n"; $month ||= $self->month; $year ||= $self->year; my $dt = $self->_new_dt($year, $month, $day); $dt->epoch; } sub dow { my($self, $day, $month, $year) = @_; $day || croak "day required.\n"; $month ||= $self->month; $year ||= $self->year; my $dt = $self->_new_dt($year, $month, $day); # convert from 1..7, starting with Mon, to 0..6, starting with Sun $dt->dow % 7; } sub add_days { my($self, $delta, $day, $month, $year) = @_; defined $delta || croak "delta (in days) required.\n"; $day || croak "day required.\n"; $month ||= $self->month; $year ||= $self->year; my $dt = $self->_new_dt($year, $month, $day); $dt->add(days => $delta); ($dt->day, $dt->month, $dt->year); } sub week_of_year { my($self, $day, $month, $year) = @_; $day || croak "day required.\n"; $month ||= $self->month; $year ||= $self->year; my $dt = $self->_new_dt($year, $month, $day); # returns ($year, $week) $dt->week; } sub _new_dt { my $self = shift; my($year, $month, $day) = @_; $year or croak "year and month required\n"; my %parms = (year => $year); $parms{month} = $month if $month; $parms{day} = $day if $day; $parms{hour} = 0; $parms{minute} = 0; $parms{second} = 0; DateTime->new(%parms); } sub _last_dom_dt { my $self = shift; my($year, $month) = @_; $year && $month or croak "year and month required.\n"; DateTime->last_day_of_month(year => $year, month => $month); } 1; HTML-CalendarMonth-2.04/lib/HTML/CalendarMonth/DateTool/Ncal.pm0000644000175000017500000000633112622653617022420 0ustar sisksiskpackage HTML::CalendarMonth::DateTool::Ncal; { $HTML::CalendarMonth::DateTool::Ncal::VERSION = '1.26'; } # Interface to linux 'ncal' command use strict; use warnings; use Carp; use base qw( HTML::CalendarMonth::DateTool ); sub dow1st_and_lastday { my($self, $month, $year) = @_; $month ||= $self->month; $year ||= $self->year; if (my $r = $self->{_res}{$year}{$month}) { return(@$r); } my $cmd = $self->_ncal_cmd or croak "ncal command not found\n"; my @cal = grep(!/^\s*$/,`$cmd -w $month $year`); shift @cal if $cal[0] =~ /\D+/; my @woy; if ($cal[-1] =~ /^\s*\d+/) { @woy = (pop @cal) =~ /(\d+)/g; } my($dow1st, %woy, %dow); my $last_day = 0; for my $di (0 .. $#cal) { my $dow_row = $cal[$di]; $dow_row =~ s/^\s+//; $dow_row =~ s/\s+$//; $dow_row =~ s/\s{3,}/ 0 /g; $dow_row =~ s/\D+/ /g; $dow_row =~ s/^\s+//; my @days = split(/\s+/, $dow_row); $dow1st = ($di + 1) % 7 if !$dow1st && $days[0]; for my $i (0 .. $#days) { my $d = $days[$i] || next; $last_day = $d if $d > $last_day; $woy{$d} = $woy[$i]; $dow{$d} = $di; } } # catch switchover from Julian to Gregorian $self->_skips(undef); if ($month == 9 && $year == 1752) { my %skips; grep(++$skips{$_}, 3 .. 13); $self->_skips(\%skips); } delete $self->{_woy}; delete $self->{_dow}; delete $self->{_res}; $self->{_woy}{$year}{$month} = \%woy if %woy; $self->{_dow}{$year}{$month} = \%dow if %dow; $self->{_res}{$year}{$month} = [$dow1st, $last_day]; ($dow1st, $last_day); } sub week_of_year { my($self, $day, $month, $year) = @_; $month ||= $self->month; $year ||= $self->year; croak "week of year not supported by ncal prior to 10/1752" if $year < 1752 || ($year == 1752 && $month < 10); $self->dow1st_and_lastday unless $self->{_woy}{$year}{$month}; $self->{_woy}{$year}{$month}{$day}; } sub dow { my($self, $day, $month, $year) = @_; $month ||= $self->month; $year ||= $self->year; $self->dow1st_and_lastday unless $self->{_dow}{$year}{$month}; $self->{_dow}{$year}{$month}{$day}; } sub add_days { my($self, $delta, $day, $month, $year) = @_; $month ||= $self->month; $year ||= $self->year; if ($delta <= 0) { $delta = abs($delta); if ($delta < $day) { return($day - $delta, $month, $year); } else { my @days = reverse 1 .. $day; while (@days < $delta) { --$month; if ($month <= 0) { --$year; $month = 12; } my($dow1st, $last_day) = $self->dow1st_and_lastday($month, $year); push(@days, reverse 1 .. $last_day); } return($days[$delta], $month, $year); } } else { my $last_day; if (my $res = $self->{_res}{$year}{$month}) { $last_day = $res->[1]; } else { $last_day = ($self->dow1st_and_lastday($month, $year))[1]; } if ($delta + $day <= $last_day) { return($day + $delta, $month, $year); } my @days = $day .. $last_day; while (@days < $delta) { ++$month; if ($month > 12) { ++$year; $month = 1; } my($dow1st, $last_day) = $self->dow1st_and_lastday($month, $year); push(@days, 1 .. $last_day); } return($days[$delta], $month, $year); } } 1; HTML-CalendarMonth-2.04/lib/HTML/CalendarMonth/DateTool/TimeLocal.pm0000644000175000017500000000156312622653617023416 0ustar sisksiskpackage HTML::CalendarMonth::DateTool::TimeLocal; { $HTML::CalendarMonth::DateTool::TimeLocal::VERSION = '1.26'; } # Interface to Time::Local use strict; use warnings; use Carp; use base qw( HTML::CalendarMonth::DateTool ); use Time::Local; sub dow1st_and_lastday { my($self, $month, $year) = @_; $month ||= $self->month; $year ||= $self->year; # map month to 0-12 --$month; # years since 1900...hooh-rah for POSIX... $year -= 1900; my $nmonth = $month + 1; my $nyear = $year; if ($nmonth > 11) { # Happy new year $nmonth = 0; ++$nyear; } # Leave dow of 1st in 0-based format my $dow1st = (gmtime(Time::Local::timegm(0,0,0,1,$month,$year)))[6]; # Last day is one day prior to 1st of month after my $lastday = (gmtime(Time::Local::timegm(0,0,0,1,$nmonth,$nyear) - 60*60*24))[3]; ($dow1st, $lastday); } 1; HTML-CalendarMonth-2.04/lib/HTML/CalendarMonth/Locale.pm0000644000175000017500000002665612622714112021227 0ustar sisksiskpackage HTML::CalendarMonth::Locale; { $HTML::CalendarMonth::Locale::VERSION = '2.00'; } # Front end class around DateTime::Locale. In addition to providing # access to the DT::Locale class and locale-specific instance, this # class prepares some other hashes and lookups utilized by # HTML::CalendarMonth. use strict; use warnings; use Carp; use DateTime::Locale 0.45; sub _locale_version { $DateTime::Locale::VERSION } my($CODE_METHOD, $CODES_METHOD); if (_locale_version() > 0.92) { $CODE_METHOD = "code"; $CODES_METHOD = "codes"; } else { $CODE_METHOD = "id"; $CODES_METHOD = "ids"; } my %Register; sub new { my $class = shift; my $self = {}; bless $self, $class; my %parms = @_; # id is for backwards compatibility my $code = $parms{code} || $parms{id} or croak "Locale code required (eg 'en-US')\n"; $self->{full_days} = defined $parms{full_days} ? $parms{full_days} : 0; $self->{full_months} = defined $parms{full_months} ? $parms{full_months} : 1; # returned code might be different from given code unless ($Register{$code}) { my $dtl = $self->locale->load($code) or croak "Problem loading locale '$code'"; $Register{$code} = $Register{$dtl->$CODE_METHOD} = { loc => $dtl }; } $self->{code} = $Register{$code}{loc}->$CODE_METHOD; $self; } sub locale { 'DateTime::Locale' } sub loc { $Register{shift->code}{loc} } sub locales { shift->locale->$CODES_METHOD } sub code { shift->{code} } *id = *code; sub full_days { shift->{full_days} } sub full_months { shift->{full_months} } sub first_day_of_week { shift->loc->first_day_of_week % 7 } sub days { my $self = shift; my $code = $self->code; unless ($Register{$code}{days}) { my $method = $self->full_days ? 'day_stand_alone_wide' : 'day_stand_alone_abbreviated'; # adjust to H::CM standard expectation, 1st day Sun # Sunday is first, regardless of what the calendar considers to be # the first day of the week my @days = @{$self->loc->$method}; unshift(@days, pop @days); $Register{$code}{days} = \@days; } wantarray ? @{$Register{$code}{days}} : $Register{$code}{days}; } sub narrow_days { my $self = shift; my $code = $self->code; unless ($Register{$code}{narrow_days}) { # Sunday is first, regardless of what the calendar considers to be # the first day of the week my @days = @{ $self->loc->day_stand_alone_narrow }; unshift(@days, pop @days); $Register{$code}{narrow_days} = \@days; } wantarray ? @{$Register{$code}{narrow_days}} : $Register{$code}{narrow_days}; } sub months { my $self = shift; my $code = $self->code; unless ($Register{$code}{months}) { my $method = $self->full_months > 0 ? 'month_stand_alone_wide' : 'month_stand_alone_abbreviated'; $Register{$code}{months} = [@{$self->loc->$method}]; } wantarray ? @{$Register{$code}{months}} : $Register{$code}{months}; } sub narrow_months { my $self = shift; my $code = $self->code; $Register{$code}{narrow_months} ||= [@{$self->loc->month_stand_alone_narrow}]; wantarray ? @{$Register{$code}{narrow_months}} : $Register{$code}{narrow_months}; } sub days_minmatch { my $self = shift; $Register{$self->code}{days_mm} ||= $self->lc_minmatch_hash($self->days); } *minmatch = \&days_minmatch; sub _days_minmatch_pattern { my $dmm = shift->days_minmatch; join('|', sort keys %$dmm); } *minmatch_pattern = \&_days_minmatch_pattern; sub months_minmatch { my $self = shift; $Register{$self->code}{months_mm} ||= $self->lc_minmatch_hash($self->months); } sub _months_minmatch_pattern { my $mmm = shift->months_minmatch; join('|', sort keys %$mmm); } sub daynums { my $self = shift; my $code = $self->code; unless ($Register{$code}{daynum}) { my %daynum; my $days = $self->days; $daynum{$days->[$_]} = $_ foreach 0 .. $#$days; $Register{$code}{daynum} = \%daynum; } wantarray ? %{$Register{$code}{daynum}} : $Register{$code}{daynum}; } sub _daymatch { my($self, $day) = @_; return unless defined $day; if ($day =~ /^\d+$/) { $day %= 7; return($day, $self->days->[$day]); } my $p = $self->_days_minmatch_pattern; if ($day =~ /^($p)/i) { $day = $self->days_minmatch->{lc $1}; return($self->daynums->{$day}, $day); } return (); } sub daynum { (shift->_daymatch(@_))[0] } sub dayname { (shift->_daymatch(@_))[1] } sub monthnums { my $self = shift; my $code = $self->code; unless ($Register{$code}{monthnum}) { my %monthnum; my $months = $self->months; $monthnum{$months->[$_]} = $_ foreach 0 .. $#$months; $Register{$code}{monthnum} = \%monthnum; } wantarray ? %{$Register{$code}{monthnum}} : $Register{$code}{monthnum}; } sub _monthmatch { my($self, $mon) = @_; return unless defined $mon; if ($mon =~ /^\d+$/) { $mon %= 12; return($mon, $self->months->[$mon]); } my $p = $self->_months_minmatch_pattern; if ($mon =~ /^($p)/i) { $mon = $self->months_minmatch->{lc $1}; return($self->monthnums->{$mon}, $mon); } return (); } sub monthnum { (shift->_monthmatch(@_))[0] } sub monthname { (shift->_monthmatch(@_))[1] } ### sub locale_map { my $self = shift; my %map; foreach my $code ($self->locales) { $map{$code} = $self->locale->load($code)->name; } wantarray ? %map : \%map; } ### sub lc_minmatch_hash { # given a list, provide a reverse lookup of case-insensitive minimal # values for each label in the list my $whatever = shift; my @orig_labels = @_; my @labels = map { lc $_ } @orig_labels; my $cc = 1; my %minmatch; while (@labels) { my %scratch; foreach my $i (0 .. $#labels) { my $str = $labels[$i]; my $chrs = substr($str, 0, $cc); $scratch{$chrs} ||= []; push(@{$scratch{$chrs}}, $i); } my @keep_i; foreach (keys %scratch) { if (@{$scratch{$_}} == 1) { $minmatch{$_} = $orig_labels[$scratch{$_}[0]]; } else { push(@keep_i, @{$scratch{$_}}); } } @labels = @labels[@keep_i]; @orig_labels = @orig_labels[@keep_i]; ++$cc; } \%minmatch; } sub minmatch_hash { # given a list, provide a reverse lookup of minimal values for each # label in the list my $whatever = shift; my @labels = @_; my $cc = 1; my %minmatch; while (@labels) { my %scratch; foreach my $i (0 .. $#labels) { my $str = $labels[$i]; my $chrs = substr($str, 0, $cc); $scratch{$chrs} ||= []; push(@{$scratch{$chrs}}, $i); } my @keep_i; foreach (keys %scratch) { if (@{$scratch{$_}} == 1) { $minmatch{$_} = $labels[$scratch{$_}[0]]; } else { push(@keep_i, @{$scratch{$_}}); } } @labels = @labels[@keep_i]; ++$cc; } \%minmatch; } 1; __END__ =head1 NAME HTML::CalendarMonth::Locale - Front end class for DateTime::Locale =head1 SYNOPSIS use HTML::CalendarMonth::Locale; my $loc = HTML::CalendarMonth::Locale->new( code => 'en-US' ); # list of days of the week for locale my @days = $loc->days; # list of months of the year for locale my @months = $loc->months; # the name of the current locale, as supplied the code parameter to # new() my $locale_name = $loc->code; # the actual DateTime::Locale object my $loc = $loc->loc; 1; =head1 DESCRIPTION HTML::CalendarMonth utilizes the powerful locale capabilities of DateTime::Locale for rendering its calendars. The default locale is 'en-US' but many others are available. To see this list, invoke the class method HTML::CalendarMonth::Locale->locales() which in turn invokes DateTime::Locale::codes(). This module is mostly intended for internal usage within HTML::CalendarMonth, but some of its functionality may be of use for developers: =head1 METHODS =over =item new() Constructor. Takes the following parameters: =over =item code Locale code, e.g. 'en-US'. =item full_days Specifies whether full day names or their abbreviations are desired. Default 0, use abbreviated days. =item full_months Specifies whether full month names or their abbreviations are desired. Default 1, use full months. =back =item code() Returns the locale code used during object construction. =item locale() Accessor method for the DateTime::Locale class, which in turn offers several class methods of specific interest. See L. =item locale_map() Returns a hash of all available locales, mapping their code to their full name. =item loc() Accessor method for the DateTime::Locale instance as specified by C. See L. =item locales() Lists all available locale codes. Equivalent to locale()->codes(), or DateTime::Locale->codes(). =item days() Returns a list of days of the week, Sunday first. These are the actual unique day strings used for rendering calendars, so depending on which attributes were provided to C, this list will either be abbreviations or full names. The default uses abbreviated day names. Returns a list in list context or an array ref in scalar context. =item narrow_days() Returns a list of short day abbreviations, beginning with Sunday. The narrow abbreviations are not guaranteed to be unique (i.e. 'S' for both Sat and Sun). =item days_minmatch() Provides a hash reference containing minimal case-insensitive match strings for each day of the week, e.g., 'sa' for Saturday, 'm' for Monday, etc. =item months() Returns a list of months of the year, beginning with January. Depending on which attributes were provided to C, this list will either be full names or abbreviations. The default uses full names. Returns a list in list context or an array ref in scalar context. =item narrow_months() Returns a list of short month abbreviations, beginning with January. The narrow abbreviations are not guaranteed to be unique. =item months_minmatch() Provides a hash reference containing minimal case-insensitive match strings for each month of the year, e.g., 'n' for November, 'ja' for January, 'jul' for July, 'jun' for June, etc. =item daynums() Provides a hash reference containing day of week indices for each fully qualified day name as returned by days(). =item daynum($day) Provides the day of week index for a particular day name. =item dayname($day) Provides the fully qualified day name for a given string or day index. =item monthnums() Provides a hash reference containing month of year indices for each fully qualified month name as returned by months(). =item monthnum($month) Provides the month of year index for a particular month name. =item monthname($month) Provides the month name for a given string or month index. =item minmatch_hash(@list) This is the method used to generate the case-insensitive minimal match hash referenced above. Given an arbitrary list, a hash reference will be returned with minimal match strings as keys and the original strings as values. =item lc_minmatch_hash(@list) Same as minmatch_hash, except keys are forced to lower case. =item first_day_of_week() Returns a number from 0 to 6 representing the first day of the week for this locale, where 0 represents Sunday. =back =head1 AUTHOR Matthew P. Sisk, EFE =head1 COPYRIGHT Copyright (c) 2010-2015 Matthew P. Sisk. All rights reserved. All wrongs revenged. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 SEE ALSO HTML::CalendarMonth(3), DateTime::Locale(3) =for Pod::Coverage minmatch minmatch_pattern id