Excel-Template-0.34/000755 000765 000120 00000000000 11747312641 014166 5ustar00rboadmin000000 000000 Excel-Template-0.34/Changes000644 000765 000120 00000014346 11747312435 015472 0ustar00rboadmin000000 000000 Revision history for Perl distribution Excel::Template 0.34 Sun Apr 29 21:21:38 CEST 2012 Behavior of merge_range adjusted, now it works: Content . (As described in the POD) Merge range formatting tends to collide with non-merged formatting, thanks to Nigel Metheringham. Fixed some documentation errors, thanks to Robert James Clay. Made Spreadsheet::WriteExcel links in format docs more generic (Nigel Metheringham) Added missing cell comment documentation 0.33 Sun Feb 20 20:07:43 CET 2011 Implemented the COMMENT argument 0.32 Mon Jul 5 18:58:05 CEST 2010 Official release for development release 0.31_1 0.31_1 Mon Jun 28 16:51:44 CEST 2010 - Add autofilter to worksheet - Swichting to Module::Install 0.31 Mo Dec 17 13:41:00 2007 - Add hide_gridlines to worksheet 0.30 Sa Dec 01 00:00:00 2007 - Add write_date_time to write a datetime-value into a cell 0.29 Mon Oct 08 12:00:00 2007 - Added merge_range as written by Stevan Little 0.28 Fri Jul 31 22:00:00 2005 - Added landscape and portrait orientations for worksheets 0.27 Tue Jul 25 10:00:00 2006 - Fixed how widths are whitelisted to allow '.' for fractions 0.26 Fri Jun 02 15:30:00 2006 - Fixed how widths are whitelisted to allow '.' for fractions - Fixed how certain formats are copied - Added - Added 0.25 Thu May 26 11:00:00 2005 - Changed how the template file is opened to use 3-arg open() if available 0.24 Thu Mar 10 11:00:00 2005 - Implemented the KEEP_LEADING_ZEROS node - This wraps the keep_leading_zeros() worksheet method - Improved code coverage with more and better tests - Am now above 90% coverage. - Fixed bug involving relative values. - Fixed bug involving formats when multiple Excel-Template objects ran in the same process. - Improved POD linking - Every module/node reference in POD should link to the appropriate POD 0.23 Fri Feb 25 15:00:00 2005 - Improved code coverage with more and better tests - Fixed POD bug with Devel::Cover results - Fixed bugs found in Factory::register while writing tests - Base class wasn't loaded when class was registered. - If registered class didn't exist, wouldn't die until parse() 0.22 Thu Feb 24 15:00:00 2005 - new() now accepts either FILE or FILENAME - parse() now accepts a filehandle or a filename 0.21 Thu Feb 24 12:00:00 2005 - Fixed documentation bug in BACKREF (Thanks to Paul Williams) - Added code to Makefile.PL to skip .swp files in the Makefile - Added RENDERER option to new() - Deprecated BIG_FILE - Added pod.t and pod_coverage.t - Tests now run under 5.005_02 without warnings 0.20 Wed Jan 26 12:00:00 2005 - Removed PM_FILTER by adding an optional USE_UNICODE runtime parameter. - Added a "type" attribute to CELL to allow printing by the write_*() family 0.19 Wed Dec 08 12:00:00 2004 - Fixed META.yml - Added more values to the MANIFEST.SKIP - Fixed PM_FILTER to work on Win32 (Thanks, Corion!) - Improved POD 0.18 Fri Nov 12 14:45:00 2004 - Removed 'use warnings' from all tests - All warnings are suppressed unless $^W is true - Added 'height' value for ROW - Added 'width' value for CELL - Fixed PM_FILTER to work on Redhat 0.17 Sat Nov 06 23:30:00 2004 - Added worksheet protection - Fixed several bugs found by adding more tests - SCOPE node actually works - CONDITIONAL / IF now handles string values correctly 0.16 Fri Nov 05 13:30:00 2004 - Fixed Makefile.PL so that it uses PM_FILTER instead of rolling its own - This means that the Unicode handling is cleaner from a source perspective - Added MANIFEST.SKIP to skip /.svn/ and 'vi' .swp files during distcheck - Finally have a semi-real testing suite! - Added minimal Spreadsheet::WriteExcel mockobject - Fixed several bugs in formats found by building tests - HIDDEN node now actually works - LOCKED node now actually works 0.15 Thu Nov 04 16:15:00 2004 - Fixed bugs that were: - preventing a worksheet from using a variable name in a loop - allowing two worksheets to have the same name - preventing a worksheet from being called '0' or '0.0' - Added back-references. This allows for one cell to refer to another cell in an Excel-aware way, especially in formulas. - Added the following nodes: - BACKREF - RANGE 0.14 Thu Nov 04 13:30:00 2004 - Added new format support for (nearly) all formats supported by Spreadsheet::WriteExcel - Fixed email address everywhere 0.13 Thu Oct 29 07:30:00 2004 - Fixed email address and added GoogleGroup 0.12 Thu Apr 08 07:30:00 2004 - Fixed bug regarding empty arrays as loop variables 0.11 Wed Mar 17 16:00:00 2004 - Fixed bug introduced in 0.10 (Loops were not case-insensitive) 0.10 Wed Mar 17 16:00:00 2004 - Parameters are now case-insensitive 0.09 Mon Feb 02 16:00:00 2004 - Fixed bug with multiple worksheets 0.08 Fri Jan 30 14:00:00 2004 - Added Base to the params for XML::Parser to allow for entity includes 0.07 Fri Jan 23 08:30:00 2004 - Fixed the MANIFEST to account for missing files 0.06 Mon Jan 20 11:00:00 2004 - Added formulas (no back-references yet) - Improved POD a little 0.05 Wed Jan 16 12:30:00 2004 - Fixed a bug in formats 0.04 Wed Jan 16 12:00:00 2004 - Added BIG_FILES as an option, which will use Spreadsheet::WriteExcel::Big as the renderer (yet unimplemented) - Changed the output() method to use a tied IO::Scalar (which is now a requirement. - Firmed up the infrastructure in Excel::Template::Format - Added the following tags - FORMAT - HIDDEN - LOCKED - OUTLINE - SHADOW - STRIKEOUT 0.03 Wed Dec 03 20:30:00 2003 - Added XML::Parser as a required pre-requisite module - Added Italic format - Removed $VERSION from Excel::Template::Base (Unneeded) - No documentation or testing changes 0.02 Sun Nov 30 17:00:00 2003 - documentation improvements - No actual functional changes 0.01 Tue Nov 18 14:23:42 2003 - original version; created by ExtUtils::ModuleMaker 0.32 Excel-Template-0.34/LICENSE000644 000765 000024 00000050101 11406453233 015201 0ustar00rbostaff000000 000000 Terms of Perl 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 General Public License (GPL) Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU 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. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), 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 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 show them these terms so they know 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. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. 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 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 derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 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 License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. 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. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary 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 License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 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 Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing 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 for copying, distributing or modifying the Program or works based on it. 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. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. 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 this 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 this License, you may choose any version ever published by the Free Software Foundation. 10. 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 11. 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. 12. 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 --------------------------------------------------------------------------- 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. Aggregation of this Package with a commercial distribution is always permitted provided that the use of this Package is embedded; that is, when no overt attempt is made to make this Package's interfaces visible to the end user of the commercial distribution. Such use shall not be construed as a distribution of this Package. 9. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 10. 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 Excel-Template-0.34/MANIFEST000644 000765 000120 00000004670 11530263632 015321 0ustar00rboadmin000000 000000 Changes inc/Module/AutoInstall.pm inc/Module/Install.pm inc/Module/Install/AutoInstall.pm inc/Module/Install/Base.pm inc/Module/Install/Can.pm inc/Module/Install/Fetch.pm inc/Module/Install/Include.pm inc/Module/Install/Makefile.pm inc/Module/Install/Metadata.pm inc/Module/Install/Win32.pm inc/Module/Install/WriteAll.pm lib/Excel/Template.pm lib/Excel/Template/Base.pm lib/Excel/Template/Container.pm lib/Excel/Template/Container/Bold.pm lib/Excel/Template/Container/Conditional.pm lib/Excel/Template/Container/Format.pm lib/Excel/Template/Container/Hidden.pm lib/Excel/Template/Container/Italic.pm lib/Excel/Template/Container/KeepLeadingZeros.pm lib/Excel/Template/Container/Locked.pm lib/Excel/Template/Container/Loop.pm lib/Excel/Template/Container/Outline.pm lib/Excel/Template/Container/Row.pm lib/Excel/Template/Container/Scope.pm lib/Excel/Template/Container/Shadow.pm lib/Excel/Template/Container/Strikeout.pm lib/Excel/Template/Container/Workbook.pm lib/Excel/Template/Container/Worksheet.pm lib/Excel/Template/Context.pm lib/Excel/Template/Element.pm lib/Excel/Template/Element/Backref.pm lib/Excel/Template/Element/Cell.pm lib/Excel/Template/Element/Formula.pm lib/Excel/Template/Element/FreezePanes.pm lib/Excel/Template/Element/Image.pm lib/Excel/Template/Element/MergeRange.pm lib/Excel/Template/Element/Range.pm lib/Excel/Template/Element/Var.pm lib/Excel/Template/Factory.pm lib/Excel/Template/Format.pm lib/Excel/Template/Iterator.pm lib/Excel/Template/TextObject.pm LICENSE Makefile.PL MANIFEST This list of files META.yml README t/001_load.t t/002.xml t/002_workbook.t t/003.xml t/003_worksheet.t t/004.xml t/004_cell.t t/005.xml t/005_formats.t t/006.xml t/006_variables.t t/007.xml t/007_cell_formats.t t/008.xml t/008_formula.t t/009.xml t/009_loop.t t/010.xml t/010_scope.t t/011.xml t/011_conditional.t t/012.xml t/012_backref.t t/013.xml t/013_range.t t/014.xml t/014_heightwidth.t t/015.xml t/015_cell_type.t t/016.xml t/016_renderers.t t/017_filehandle.t t/018_register.t t/019_output.t t/020_worksheet_attributes.t t/021_loop_error.t t/022_keep_leading_zeros.t t/023_relative_values.t t/024_image.t t/025_freezepanes.t t/026_vars_in_format.t t/026_vars_in_format.xml t/027_landscape.t t/028_merge_range.t t/029_worksheet_autofilter.t t/030.xml t/030_cell_comment.t t/998_pod.t t/999_pod_coverage.t t/mock.pm t/Register_018.pm t/Spreadsheet/WriteExcel.pm t/Spreadsheet/WriteExcel/Big.pm t/Spreadsheet/WriteExcel/Worksheet.pm t/Spreadsheet/WriteExcelXML.pm Excel-Template-0.34/META.yml000644 000765 000120 00000001621 11747312613 015436 0ustar00rboadmin000000 000000 --- abstract: Excel::Template author: - 'Rob Kinyon ' build_requires: ExtUtils::MakeMaker: 6.42 File::Path: 0 File::Temp: 0 Test::Deep: 0.095 Test::Exception: 0.21 Test::More: 0.47 configure_requires: ExtUtils::MakeMaker: 6.42 distribution_type: module generated_by: 'Module::Install version 1.01' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Excel-Template no_index: directory: - inc - t requires: File::Basename: 0 IO::Scalar: 0 Spreadsheet::WriteExcel: 0.42 Spreadsheet::WriteExcel::Utility: 0 Test::More: 0 XML::Parser: 0 perl: 5.6.0 resources: license: http://dev.perl.org/licenses/ repository: type: git url: git://git.shadowcat.co.uk/p5sagit/Excel-Template.git web: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=p5sagit/Excel-Template.git;a=summary version: 0.34 Excel-Template-0.34/Makefile.PL000644 000765 000024 00000002257 11406526213 016156 0ustar00rbostaff000000 000000 use inc::Module::Install; name 'Excel-Template'; perl_version '5.006'; all_from 'lib/Excel/Template.pm'; author q{Rob Kinyon }; license 'perl'; resources( repository => { url => 'git://git.shadowcat.co.uk/p5sagit/Excel-Template.git', web => 'http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=p5sagit/Excel-Template.git;a=summary', type => 'git', }, ); test_requires 'File::Path' => 0; test_requires 'File::Temp' => 0; test_requires 'Test::Deep' => '0.095'; test_requires 'Test::More' => '0.47'; test_requires 'Test::Exception' => '0.21'; requires 'Test::More' => 0; requires 'XML::Parser' => 0; requires 'IO::Scalar' => 0; requires 'File::Basename' => 0; requires 'Spreadsheet::WriteExcel' => '0.42'; requires 'Spreadsheet::WriteExcel::Utility' => 0; if ($] < 5.008) { print "#\n"; print "# Note: If you want to work with Unicode, you will need to install\n"; print "# the optional module Unicode::String and set USE_UNICODE to true.\n"; print "#\n"; recommends 'Unicode::String'; } auto_install; WriteAll; Excel-Template-0.34/README000644 000765 000024 00000000514 11406453233 015057 0ustar00rbostaff000000 000000 Excel::Template is a layout system to use the data structure from HTML::Template and create a Microsoft Excel file. CAVEAT: All limitations stated in Spreadsheet::WriteExcel are in force, as that is the module used for rendering. If the XLS file is corrupted, I would first make sure you aren't doing anything that it says is bad. Excel-Template-0.34/inc/000755 000765 000120 00000000000 11747312641 014737 5ustar00rboadmin000000 000000 Excel-Template-0.34/lib/000755 000765 000120 00000000000 11747312641 014734 5ustar00rboadmin000000 000000 Excel-Template-0.34/t/000755 000765 000120 00000000000 11747312641 014431 5ustar00rboadmin000000 000000 Excel-Template-0.34/t/001_load.t000644 000765 000024 00000000226 11406453233 016126 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 2; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new (); isa_ok( $object, $CLASS ); Excel-Template-0.34/t/002.xml000644 000765 000024 00000000015 11406453233 015461 0ustar00rbostaff000000 000000 Excel-Template-0.34/t/002_workbook.t000644 000765 000024 00000001002 11406453233 017036 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( filename => 't/002.xml', ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ Excel-Template-0.34/t/003.xml000644 000765 000024 00000000176 11406510116 015464 0ustar00rbostaff000000 000000 Excel-Template-0.34/t/003_worksheet.t000644 000765 000024 00000001653 11406510116 017223 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( filename => 't/003.xml', ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( '' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::add_worksheet( 'foo' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::add_worksheet( '' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::add_worksheet( '' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::hide_gridlines( '2' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ Excel-Template-0.34/t/004.xml000644 000765 000024 00000000176 11406453233 015473 0ustar00rbostaff000000 000000 Test1 Excel-Template-0.34/t/004_cell.t000644 000765 000024 00000001450 11406453233 016131 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( filename => 't/004.xml', ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( 'cell' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '0', 'Test1', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '1', 'Test2', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '2', '', '1' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ Excel-Template-0.34/t/005.xml000644 000765 000024 00000001474 11406453233 015476 0ustar00rbostaff000000 000000 Excel-Template-0.34/t/005_formats.t000644 000765 000024 00000004552 11406453233 016674 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( filename => 't/005.xml', ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_format( 'bold', '1' ) Spreadsheet::WriteExcel::add_format( 'hidden', '1' ) Spreadsheet::WriteExcel::add_format( 'italic', '1' ) Spreadsheet::WriteExcel::add_format( 'locked', '1' ) Spreadsheet::WriteExcel::add_format( 'font_outline', '1' ) Spreadsheet::WriteExcel::add_format( 'font_shadow', '1' ) Spreadsheet::WriteExcel::add_format( 'font_strikeout', '1' ) Spreadsheet::WriteExcel::add_format( 'shrink', '1' ) Spreadsheet::WriteExcel::add_format( 'text_wrap', '1' ) Spreadsheet::WriteExcel::add_format( 'text_justlast', '1' ) Spreadsheet::WriteExcel::add_format( 'size', '3' ) Spreadsheet::WriteExcel::add_format( 'num_format', '3' ) Spreadsheet::WriteExcel::add_format( 'underline', '3' ) Spreadsheet::WriteExcel::add_format( 'rotation', '3' ) Spreadsheet::WriteExcel::add_format( 'indent', '3' ) Spreadsheet::WriteExcel::add_format( 'pattern', '3' ) Spreadsheet::WriteExcel::add_format( 'border', '3' ) Spreadsheet::WriteExcel::add_format( 'bottom', '3' ) Spreadsheet::WriteExcel::add_format( 'top', '3' ) Spreadsheet::WriteExcel::add_format( 'left', '3' ) Spreadsheet::WriteExcel::add_format( 'right', '3' ) Spreadsheet::WriteExcel::add_format( 'font', '3' ) Spreadsheet::WriteExcel::add_format( 'color', '3' ) Spreadsheet::WriteExcel::add_format( 'align', '3' ) Spreadsheet::WriteExcel::add_format( 'valign', '3' ) Spreadsheet::WriteExcel::add_format( 'bg_color', '3' ) Spreadsheet::WriteExcel::add_format( 'fg_color', '3' ) Spreadsheet::WriteExcel::add_format( 'border_color', '3' ) Spreadsheet::WriteExcel::add_format( 'bottom_color', '3' ) Spreadsheet::WriteExcel::add_format( 'top_color', '3' ) Spreadsheet::WriteExcel::add_format( 'left_color', '3' ) Spreadsheet::WriteExcel::add_format( 'right_color', '3' ) Spreadsheet::WriteExcel::add_format( 'bold', '1', 'italic', '1' ) Spreadsheet::WriteExcel::add_format( 'bold', '1', 'hidden', '1', 'italic', '1' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ Excel-Template-0.34/t/006.xml000644 000765 000024 00000000260 11406453233 015467 0ustar00rbostaff000000 000000 PRE POST Excel-Template-0.34/t/006_variables.t000644 000765 000024 00000001644 11406453233 017171 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 5; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( filename => 't/006.xml', ); isa_ok( $object, $CLASS ); ok( $object->param( test1 => 'test1', test2 => 'test2', ), 'Parameters set', ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( 'cell' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '0', 'test1', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '1', 'test2', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '2', 'PRE test1 POST', '1' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ Excel-Template-0.34/t/007.xml000644 000765 000024 00000000243 11406453233 015471 0ustar00rbostaff000000 000000 Excel-Template-0.34/t/007_cell_formats.t000644 000765 000024 00000001623 11406453233 017671 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( filename => 't/007.xml', ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( 'cell' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '0', '', '1' ) Spreadsheet::WriteExcel::add_format( 'bold', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '1', '', '2' ) Spreadsheet::WriteExcel::add_format( 'bold', '1', 'italic', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '2', '', '3' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ Excel-Template-0.34/t/008.xml000644 000765 000024 00000000215 11406453233 015471 0ustar00rbostaff000000 000000 Test1 Excel-Template-0.34/t/008_formula.t000644 000765 000024 00000001503 11406453233 016662 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( filename => 't/008.xml', ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( 'formula' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::write_formula( '0', '0', 'Test1', '1' ) Spreadsheet::WriteExcel::Worksheet::write_formula( '0', '1', 'Test2', '1' ) Spreadsheet::WriteExcel::Worksheet::write_formula( '0', '2', '', '1' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ Excel-Template-0.34/t/009.xml000644 000765 000024 00000001146 11406453233 015476 0ustar00rbostaff000000 000000 Excel-Template-0.34/t/009_loop.t000644 000765 000024 00000004206 11406453233 016172 0ustar00rbostaff000000 000000 BEGIN{ $^W = 0 } use strict; use Test::More tests => 5; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( filename => 't/009.xml', ); isa_ok( $object, $CLASS ); ok( $object->param( loopy => [ { value => 1 }, { value => 2 }, { value => 3 }, ], outer => [ { iter => 'a', inner => [ { value => 1 }, { value => 2 } ] }, { iter => 'b', inner => [ { value => 3 }, { value => 4 } ] }, ], worksheets => [ { value => 1 }, { value => 2 }, { value => 3 }, ], no_iters => [ ], ), 'Parameters set', ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( 'loops' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '0', '1', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '1', 'text', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '1', '0', '2', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '1', '1', 'text', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '2', '0', '3', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '2', '1', 'text', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '3', '0', 'a', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '3', '1', '1', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '3', '2', '2', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '4', '0', 'b', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '4', '1', '3', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '4', '2', '4', '1' ) Spreadsheet::WriteExcel::add_worksheet( '1' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::add_worksheet( '2' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::add_worksheet( '3' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ Excel-Template-0.34/t/010.xml000644 000765 000024 00000000201 11406453233 015455 0ustar00rbostaff000000 000000 Excel-Template-0.34/t/010_scope.t000644 000765 000024 00000001342 11406453233 016320 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( filename => 't/010.xml', ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( 'scope' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '0', '1', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '1', '1', '1' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ Excel-Template-0.34/t/011.xml000644 000765 000024 00000002672 11406453233 015474 0ustar00rbostaff000000 000000 Excel-Template-0.34/t/011_conditional.t000644 000765 000024 00000005651 11406453233 017522 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 5; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( filename => 't/011.xml', ); isa_ok( $object, $CLASS ); ok( $object->param( loopy => [ { int => 0, char => 'n' }, { int => 0, char => 'y' }, { int => 1, char => 'z' }, { int => -1, char => 'y' }, ], ), 'Parameters set', ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( 'conditional' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '0', 'bool false', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '1', 'num == passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '2', 'num >= passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '3', 'num <= passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '4', 'char ne passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '5', 'char lt passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '6', 'char le passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '1', '0', 'bool false', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '1', '1', 'num == passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '1', '2', 'num >= passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '1', '3', 'num <= passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '1', '4', 'char eq passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '1', '5', 'char ge passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '1', '6', 'char le passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '2', '0', 'bool true', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '2', '1', 'num != passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '2', '2', 'num > passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '2', '3', 'num >= passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '2', '4', 'char ne passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '2', '5', 'char gt passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '2', '6', 'char ge passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '3', '0', 'bool true', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '3', '1', 'num != passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '3', '2', 'num < passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '3', '3', 'num <= passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '3', '4', 'char eq passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '3', '5', 'char ge passes', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '3', '6', 'char le passes', '1' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ Excel-Template-0.34/t/012.xml000644 000765 000024 00000000260 11406453233 015464 0ustar00rbostaff000000 000000 = Excel-Template-0.34/t/012_backref.t000644 000765 000024 00000001454 11406453233 016612 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( filename => 't/012.xml', ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( 'backref' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '0', 'not me', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '1', 'me', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '2', '=B1', '1' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ Excel-Template-0.34/t/013.xml000644 000765 000024 00000000315 11406453233 015466 0ustar00rbostaff000000 000000 =SUM() Excel-Template-0.34/t/013_range.t000644 000765 000024 00000001556 11406453233 016315 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( filename => 't/013.xml', ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( 'backref' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '0', '1', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '1', '2', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '2', '3', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '3', '=SUM(A1:C1)', '1' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ Excel-Template-0.34/t/014.xml000644 000765 000024 00000000257 11406453233 015474 0ustar00rbostaff000000 000000 Excel-Template-0.34/t/014_heightwidth.t000644 000765 000024 00000001644 11406453233 017530 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( filename => 't/014.xml', ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( 'heightwidth' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::set_row( '0', '30' ) Spreadsheet::WriteExcel::Worksheet::set_column( '0', '0', '10' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '0', '1', '1' ) Spreadsheet::WriteExcel::Worksheet::set_column( '1', '1', '0.5' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '1', '1', '1' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ Excel-Template-0.34/t/015.xml000644 000765 000024 00000000451 11406453233 015471 0ustar00rbostaff000000 000000 String Number Blank URL Formula DateTime Excel-Template-0.34/t/015_cell_type.t000644 000765 000024 00000002055 11406453233 017176 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( filename => 't/015.xml', ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( 'cell_type' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::write_string( '0', '0', 'String', '1' ) Spreadsheet::WriteExcel::Worksheet::write_number( '0', '1', 'Number', '1' ) Spreadsheet::WriteExcel::Worksheet::write_blank( '0', '2', 'Blank', '1' ) Spreadsheet::WriteExcel::Worksheet::write_url( '0', '3', 'URL', '1' ) Spreadsheet::WriteExcel::Worksheet::write_formula( '0', '4', 'Formula', '1' ) Spreadsheet::WriteExcel::Worksheet::write_date_time( '0', '5', 'DateTime', '1' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ Excel-Template-0.34/t/016.xml000644 000765 000024 00000000015 11406453233 015466 0ustar00rbostaff000000 000000 Excel-Template-0.34/t/016_renderers.t000644 000765 000024 00000003044 11406453233 017207 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 10; use lib 't'; use mock; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); { mock::reset; my $object = $CLASS->new( renderer => 'big', filename => 't/016.xml', ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::Big::new( 'filename' ) Spreadsheet::WriteExcel::Big::add_format( '' ) Spreadsheet::WriteExcel::Big::close( '' ) __END_EXPECTED__ } { mock::reset; my $object = $CLASS->new( renderer => Excel::Template->RENDER_XML, filename => 't/016.xml', ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcelXML::new( 'filename' ) Spreadsheet::WriteExcelXML::add_format( '' ) Spreadsheet::WriteExcelXML::close( '' ) __END_EXPECTED__ } { mock::reset; my $object = $CLASS->new( renderer => Excel::Template->RENDER_NML, filename => 't/016.xml', ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ } Excel-Template-0.34/t/017_filehandle.t000644 000765 000024 00000001562 11406453233 017315 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( file => \*DATA, ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( '' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::add_worksheet( 'foo' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::add_worksheet( '' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ __DATA__ Excel-Template-0.34/t/018_register.t000644 000765 000024 00000004355 11406453233 017052 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 15; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); { local $^W=0; ok( !$CLASS->register(), "Must pass in class, name, and isa" ); ok( !$CLASS->register( class => 'Register_018' ), "Must pass in class, name, and isa" ); ok( !$CLASS->register( name => 'header' ), "Must pass in class, name, and isa" ); ok( !$CLASS->register( isa => 'cell' ), "Must pass in class, name, and isa" ); ok( !$CLASS->register( class => 'Register_018', isa => 'cell' ), "Must pass in class, name, and isa" ); ok( !$CLASS->register( class => 'Register_018', name => 'header' ), "Must pass in class, name, and isa" ); ok( !$CLASS->register( name => 'header', isa => 'cell' ), "Must pass in class, name, and isa" ); eval { $CLASS->register( class => 'NOT::A::CLASS', name => 'not_a_node', isa => 'cell', ); }; like( $@, qr/Cannot find or compile/, "Verify registering a non-existent class fails" ); ok( !$CLASS->register( class => 'NOT::A::CLASS', name => 'cell', isa => 'row', ), "Cannot add a nodename we already have", ); ok( !$CLASS->register( class => 'NOT::A::CLASS', name => 'new_node', isa => 'not_a_node', ), "Cannot inherit from a nodename we don't have", ); } ok( $CLASS->register( class => 'Register_018', name => 'header', isa => 'cell', ), "Register Register_018 class", ); my $object = $CLASS->new( file => \*DATA, ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( '' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::add_format( 'align', 'center', 'bold', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '0', 'test', '2' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ __DATA__
Excel-Template-0.34/t/019_output.t000644 000765 000024 00000001033 11406453233 016555 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( filename => \*DATA, ); isa_ok( $object, $CLASS ); ok( my $output = $object->output( 'filename' ), "Something returned" ); my $val = <<__END_EXPECTED__; Spreadsheet::WriteExcel::new\\( 'GLOB\\([^)]+\\)' \\) Spreadsheet::WriteExcel::add_format\\( '' \\) Spreadsheet::WriteExcel::close\\( '' \\) __END_EXPECTED__ like( $output, qr/$val/, 'Calls match up' ); __DATA__ Excel-Template-0.34/t/020_worksheet_attributes.t000644 000765 000024 00000001436 11406453233 021475 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( filename => \*DATA, ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( 'worksheet attributes' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '0', '03', '1' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ __DATA__ Excel-Template-0.34/t/021_loop_error.t000644 000765 000024 00000001111 11406453233 017365 0ustar00rbostaff000000 000000 BEGIN{ $^W = 0 } use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( file => \*DATA, ); isa_ok( $object, $CLASS ); ok( $object->param( test => [ { value => 1 }, { value => 2 }, [ value => 3 ], ], ), 'Parameters set', ); ok( !$object->write_file( 'filename' ), 'Failed to write file' ); __DATA__ Excel-Template-0.34/t/022_keep_leading_zeros.t000644 000765 000024 00000003230 11406453233 021041 0ustar00rbostaff000000 000000 BEGIN{ $^W = 0 } use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( file => \*DATA, ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Successfuly wrote file' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( '' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '0', 'before', '1' ) Spreadsheet::WriteExcel::Worksheet::keep_leading_zeros( '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '1', 'inside', '1' ) Spreadsheet::WriteExcel::Worksheet::keep_leading_zeros( '0' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '2', 'after', '1' ) Spreadsheet::WriteExcel::add_worksheet( '' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::keep_leading_zeros( '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '0', 'within', '1' ) Spreadsheet::WriteExcel::add_worksheet( '' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '0', 'after', '1' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ __DATA__ Excel-Template-0.34/t/023_relative_values.t000644 000765 000024 00000003223 11406453233 020405 0ustar00rbostaff000000 000000 BEGIN{ $^W = 0 } use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( file => \*DATA, ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Successfuly wrote file' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( '' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::set_row( '0', '8' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '0', '', '1' ) Spreadsheet::WriteExcel::Worksheet::set_row( '1', '10' ) Spreadsheet::WriteExcel::Worksheet::write( '1', '0', '', '1' ) Spreadsheet::WriteExcel::Worksheet::set_row( '2', '6' ) Spreadsheet::WriteExcel::Worksheet::write( '2', '0', '', '1' ) Spreadsheet::WriteExcel::Worksheet::set_row( '3', '16' ) Spreadsheet::WriteExcel::Worksheet::write( '3', '0', '', '1' ) Spreadsheet::WriteExcel::Worksheet::set_row( '4', '4' ) Spreadsheet::WriteExcel::Worksheet::write( '4', '0', '', '1' ) Spreadsheet::WriteExcel::Worksheet::set_row( '5', '8' ) Spreadsheet::WriteExcel::Worksheet::write( '5', '0', '', '1' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ __DATA__ Excel-Template-0.34/t/024_image.t000644 000765 000024 00000002630 11406453233 016277 0ustar00rbostaff000000 000000 BEGIN{ $^W = 0 } use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( file => \*DATA, ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Successfuly wrote file' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( '' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '0', 'before', '1' ) Spreadsheet::WriteExcel::Worksheet::insert_bitmap( '0', '1', '/full/path', '0', '0', '0', '0' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '2', 'after', '1' ) Spreadsheet::WriteExcel::Worksheet::insert_bitmap( '0', '3', '/full/path', '2', '2', '0', '0' ) Spreadsheet::WriteExcel::Worksheet::insert_bitmap( '0', '4', '/full/path', '0', '0', '2', '2' ) Spreadsheet::WriteExcel::Worksheet::insert_bitmap( '0', '5', '/full/path', '0', '1', '1.1', '0' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ __DATA__ Excel-Template-0.34/t/025_freezepanes.t000644 000765 000024 00000001666 11406453233 017535 0ustar00rbostaff000000 000000 BEGIN{ $^W = 0 } use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( file => \*DATA, ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Successfuly wrote file' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( '' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '0', 'before', '1' ) Spreadsheet::WriteExcel::Worksheet::freeze_panes( '0', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '1', 'after', '1' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ __DATA__ Excel-Template-0.34/t/026_vars_in_format.t000644 000765 000024 00000002332 11406453233 020227 0ustar00rbostaff000000 000000 BEGIN{ $^W = 0 } use strict; use Test::More tests => 5; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( filename => 't/026_vars_in_format.xml', ); isa_ok( $object, $CLASS ); ok( $object->param( loopy => [ { value => 1, color => 'red' }, { value => 2, color => 'green' }, { value => 3, color => 'yellow' }, ], ), 'Parameters set', ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( 'loops' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::add_format( 'bg_color', 'red' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '0', '1', '2' ) Spreadsheet::WriteExcel::add_format( 'bg_color', 'green' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '1', '2', '3' ) Spreadsheet::WriteExcel::add_format( 'bg_color', 'yellow' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '2', '3', '4' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ Excel-Template-0.34/t/026_vars_in_format.xml000644 000765 000024 00000000321 11406453233 020560 0ustar00rbostaff000000 000000 Excel-Template-0.34/t/027_landscape.t000644 000765 000024 00000002222 11406453233 017147 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( file => \*DATA, ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( 'landscape' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::set_landscape( '' ) Spreadsheet::WriteExcel::add_worksheet( 'landscape2' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::set_landscape( '' ) Spreadsheet::WriteExcel::add_worksheet( 'portrait' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::set_portrait( '' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ __DATA__ Excel-Template-0.34/t/028_merge_range.t000644 000765 000120 00000002775 11747312220 017466 0ustar00rboadmin000000 000000 BEGIN{ $^W = 0 } use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( file => \*DATA, ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Successfuly wrote file' ); my @calls = mock::get_calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( '' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '0', '', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '1', '', '1' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::Worksheet::merge_range( 'A1:B1', 'This is the Foo Range', '2' ) Spreadsheet::WriteExcel::add_worksheet( '' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '0', '', '1' ) Spreadsheet::WriteExcel::Worksheet::write( '0', '1', '', '1' ) Spreadsheet::WriteExcel::Worksheet::merge_range( 'A1:B1', 'This is the Foo Range2', '2' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ __DATA__ This is the Foo Range2 Excel-Template-0.34/t/029_worksheet_autofilter.t000644 000765 000024 00000001713 11406513002 021463 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 4; use lib 't'; use mock; use Data::Dumper; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( filename => \*DATA, ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; # warn Dumper \@calls; is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' ); Spreadsheet::WriteExcel::new( 'filename' ) Spreadsheet::WriteExcel::add_format( '' ) Spreadsheet::WriteExcel::add_worksheet( '' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::autofilter( 'A1:D11' ) Spreadsheet::WriteExcel::add_worksheet( '' ) Spreadsheet::WriteExcel::Worksheet::new( '' ) Spreadsheet::WriteExcel::Worksheet::autofilter( '0', '0', '10', '3' ) Spreadsheet::WriteExcel::close( '' ) __END_EXPECTED__ __DATA__ Excel-Template-0.34/t/030.xml000644 000765 000024 00000000265 11530262603 015466 0ustar00rbostaff000000 000000 Test1 Excel-Template-0.34/t/030_cell_comment.t000644 000765 000024 00000001741 11530262515 017654 0ustar00rbostaff000000 000000 use strict; use Test::More tests => 4; use lib 't'; use mock; mock::reset; my $CLASS = 'Excel::Template'; use_ok( $CLASS ); my $object = $CLASS->new( filename => 't/030.xml', ); isa_ok( $object, $CLASS ); ok( $object->write_file( 'filename' ), 'Something returned' ); my @calls = mock::get_calls; is_deeply([@calls],[ q[Spreadsheet::WriteExcel::new( 'filename' )], q[Spreadsheet::WriteExcel::add_format( '' )], q[Spreadsheet::WriteExcel::add_worksheet( 'cell' )], q[Spreadsheet::WriteExcel::Worksheet::new( '' )], q[Spreadsheet::WriteExcel::Worksheet::write( '0', '0', 'Test1', '1' )], q[Spreadsheet::WriteExcel::Worksheet::write_comment( '0', '0', 'Test1' )], q[Spreadsheet::WriteExcel::Worksheet::write( '0', '1', 'Test2', '1' )], q[Spreadsheet::WriteExcel::Worksheet::write_comment( '0', '1', 'Test2' )], q[Spreadsheet::WriteExcel::Worksheet::write( '0', '2', 'Test3', '1' )], q[Spreadsheet::WriteExcel::close( '' )], ],'Calls match up'); Excel-Template-0.34/t/998_pod.t000644 000765 000024 00000000220 11406453233 016014 0ustar00rbostaff000000 000000 use strict; use Test::More; eval "use Test::Pod 1.14"; plan skip_all => "Test::Pod 1.14 required for testing POD" if $@; all_pod_files_ok(); Excel-Template-0.34/t/999_pod_coverage.t000644 000765 000024 00000001061 11406453233 017674 0ustar00rbostaff000000 000000 use strict; use Test::More; eval "use Test::Pod::Coverage 1.04"; plan skip_all => "Test::Pod::Coverage 1.04 required for testing POD coverage" if $@; # These are methods that need naming work my @private_methods = qw( render new min max resolve deltas enter_scope exit_scope iterate_over_children ); # These are method names that have been commented out, for now # max_of total_of # begin_page end_page my $private_regex = do { local $"='|'; qr/^(?:@private_methods)$/ }; all_pod_coverage_ok( { also_private => [ $private_regex ], }); Excel-Template-0.34/t/Register_018.pm000644 000765 000024 00000000662 11406453233 017160 0ustar00rbostaff000000 000000 package Register_018; use strict; sub render { my ($self, $context) = @_; my $old_format = $context->active_format; my $format = $context->format_object->copy( $context, $old_format, align => 'center', bold => 1, ); $context->active_format($format); my $child_success = $self->SUPER::render($context); $context->active_format($old_format); return $child_success; } 1; __END__ Excel-Template-0.34/t/Spreadsheet/000755 000765 000120 00000000000 11747312641 016700 5ustar00rboadmin000000 000000 Excel-Template-0.34/t/mock.pm000644 000765 000024 00000000203 11406453233 015724 0ustar00rbostaff000000 000000 package mock; use strict; use vars qw/ @calls /; @calls = (); sub reset { @calls = (); } sub get_calls { @calls } 1; __END__ Excel-Template-0.34/t/Spreadsheet/WriteExcel/000755 000765 000120 00000000000 11747312641 020753 5ustar00rboadmin000000 000000 Excel-Template-0.34/t/Spreadsheet/WriteExcel.pm000644 000765 000024 00000001765 11406453233 021333 0ustar00rbostaff000000 000000 package Spreadsheet::WriteExcel; use strict; use mock; use Spreadsheet::WriteExcel::Worksheet; sub new { my $self = bless { }, shift; { local $" = "', '"; push @mock::calls, ref($self) . "::new( '@_' )"; } $self->{file} = shift; return $self; } sub close { my $self = shift; { local $" = "', '"; push @mock::calls, ref($self) . "::close( '@_' )"; } if ( ref $self->{file} ) { my $fh = $self->{file}; print $fh join "\n", @mock::calls, ''; } } sub add_worksheet { my $self = shift; { local $" = "', '"; push @mock::calls, ref($self) . "::add_worksheet( '@_' )"; } return Spreadsheet::WriteExcel::Worksheet->new; } my $format_num = 1; sub add_format { my $self = shift; my %x = @_; my @x = map { $_ => $x{$_} } sort keys %x; { local $" = "', '"; push @mock::calls, ref($self) . "::add_format( '@x' )"; } return $format_num++; } 1; __END__ Excel-Template-0.34/t/Spreadsheet/WriteExcelXML.pm000644 000765 000024 00000000510 11406453233 021677 0ustar00rbostaff000000 000000 package Spreadsheet::WriteExcelXML; use strict; use vars qw/ @ISA /; @ISA = qw( Spreadsheet::WriteExcel ); use Spreadsheet::WriteExcel; use mock; sub new { my $self = bless { }, shift; { local $" = "', '"; push @mock::calls, ref($self) . "::new( '@_' )"; } return $self; } 1; __END__ Excel-Template-0.34/t/Spreadsheet/WriteExcel/Big.pm000644 000765 000024 00000000512 11406453233 022021 0ustar00rbostaff000000 000000 package Spreadsheet::WriteExcel::Big; use strict; use vars qw/ @ISA /; @ISA = qw( Spreadsheet::WriteExcel ); use Spreadsheet::WriteExcel; use mock; sub new { my $self = bless { }, shift; { local $" = "', '"; push @mock::calls, ref($self) . "::new( '@_' )"; } return $self; } 1; __END__ Excel-Template-0.34/t/Spreadsheet/WriteExcel/Worksheet.pm000644 000765 000024 00000001277 11530262240 023276 0ustar00rbostaff000000 000000 package Spreadsheet::WriteExcel::Worksheet; use strict; use mock; sub new { my $self = bless { }, shift; { local $" = "', '"; push @mock::calls, __PACKAGE__ . "::new( '@_' )"; } return $self; } my @funcs = qw( write_string write_number write_blank write_url write_formula write_date_time write set_row set_column keep_leading_zeros insert_bitmap freeze_panes set_landscape set_portrait merge_range hide_gridlines autofilter write_comment ); foreach my $func ( @funcs ) { no strict 'refs'; *$func = sub { my $self = shift; local $" = "', '"; push @mock::calls, __PACKAGE__ . "::${func}( '@_' )"; }; } 1; __END__ Excel-Template-0.34/lib/Excel/000755 000765 000120 00000000000 11747312641 015774 5ustar00rboadmin000000 000000 Excel-Template-0.34/lib/Excel/Template/000755 000765 000120 00000000000 11747312641 017547 5ustar00rboadmin000000 000000 Excel-Template-0.34/lib/Excel/Template.pm000644 000765 000024 00000037253 11747312332 020132 0ustar00rbostaff000000 000000 package Excel::Template; use strict; BEGIN { use Excel::Template::Base; use vars qw ($VERSION @ISA); $VERSION = '0.34'; @ISA = qw( Excel::Template::Base ); } use File::Basename; use XML::Parser; use IO::Scalar; use constant RENDER_NML => 'normal'; use constant RENDER_BIG => 'big'; use constant RENDER_XML => 'xml'; my %renderers = ( RENDER_NML, 'Spreadsheet::WriteExcel', RENDER_BIG, 'Spreadsheet::WriteExcel::Big', RENDER_XML, 'Spreadsheet::WriteExcelXML', ); sub new { my $class = shift; my $self = $class->SUPER::new(@_); $self->{FILE} = $self->{FILENAME} if !defined $self->{FILE} && defined $self->{FILENAME}; $self->parse_xml($self->{FILE}) if defined $self->{FILE}; my @renderer_classes = ( 'Spreadsheet::WriteExcel' ); if (exists $self->{RENDERER} && $self->{RENDERER}) { if (exists $renderers{ lc $self->{RENDERER} }) { unshift @renderer_classes, $renderers{ lc $self->{RENDERER} }; } elsif ($^W) { warn "'$self->{RENDERER}' is not recognized\n"; } } elsif (exists $self->{BIG_FILE} && $self->{BIG_FILE}) { warn "Use of BIG_FILE is deprecated.\n"; unshift @renderer_classes, 'Spreadsheet::WriteExcel::Big'; } $self->{RENDERER} = undef; foreach my $class (@renderer_classes) { (my $filename = $class) =~ s!::!/!g; eval { require "$filename.pm"; $class->import; }; if ($@) { warn "Could not find or compile '$class'\n" if $^W; } else { $self->{RENDERER} = $class; last; } } defined $self->{RENDERER} || die "Could not find a renderer class. Tried:\n\t" . join("\n\t", @renderer_classes) . "\n"; $self->{USE_UNICODE} = ~~0 if $] >= 5.008; return $self; } sub param { my $self = shift; # Allow an arbitrary number of hashrefs, so long as they're the first things # into param(). Put each one onto the end, de-referenced. push @_, %{shift @_} while ref $_[0] eq 'HASH'; (@_ % 2) && die __PACKAGE__, "->param() : Odd number of parameters to param()\n"; my %params = @_; $params{uc $_} = delete $params{$_} for keys %params; @{$self->{PARAM_MAP}}{keys %params} = @params{keys %params}; return ~~1; } sub write_file { my $self = shift; my ($filename) = @_; my $xls = $self->{RENDERER}->new($filename) || die "Cannot create XLS in '$filename': $!\n"; eval { $self->_prepare_output($xls); }; print $@ if $@; $xls->close; return if $@; return ~~1; } sub output { my $self = shift; my $output; tie *XLS, 'IO::Scalar', \$output; $self->write_file(\*XLS) or return; return $output; } sub parse_xml { my $self = shift; my ($file) = @_; my @stack; my @parms = ( Handlers => { Start => sub { shift; my $name = uc shift; my $node = Excel::Template::Factory->_create_node($name, @_); die "'$name' (@_) didn't make a node!\n" unless defined $node; if ( $node->isa( 'WORKBOOK' ) ) { $self->{WORKBOOK} = $node; } elsif ( $node->is_embedded ) { return unless @stack; if (exists $stack[-1]{TXTOBJ} && $stack[-1]{TXTOBJ}->isa('TEXTOBJECT')) { push @{$stack[-1]{TXTOBJ}{STACK}}, $node; } } else { push @{$stack[-1]{ELEMENTS}}, $node if @stack; } push @stack, $node; }, Char => sub { shift; return unless @stack; my $parent = $stack[-1]; if ( exists $parent->{TXTOBJ} && $parent->{TXTOBJ}->isa('TEXTOBJECT') ) { push @{$parent->{TXTOBJ}{STACK}}, @_; } }, End => sub { shift; return unless @stack; pop @stack if $stack[-1]->isa(uc $_[0]); }, }, ); if ( ref $file ) { *INFILE = $file; } else { my ($filename, $dirname) = fileparse($file); push @parms, Base => $dirname; eval q{ open( INFILE, '<', $file ) || die "Cannot open '$file' for reading: $!\n"; }; if ( $@ ) { if ( $@ =~ /Too many arguments for open/ ) { open( INFILE, "< $file" ) || die "Cannot open '$file' for reading: $!\n"; } else { die $@; } } } my $parser = XML::Parser->new( @parms ); $parser->parse(do { local $/ = undef; }); close INFILE unless ref $file; return ~~1; } *parse = *parse = \&parse_xml; sub _prepare_output { my $self = shift; return unless $self->{WORKBOOK}; my ($xls) = @_; my $context = Excel::Template::Factory->_create( 'CONTEXT', XLS => $xls, PARAM_MAP => [ $self->{PARAM_MAP} ], UNICODE => $self->{UNICODE}, ); $self->{WORKBOOK}->render($context); return ~~1; } sub register { shift; Excel::Template::Factory->register(@_) } 1; __END__ =head1 NAME Excel::Template - Excel::Template =head1 SYNOPSIS First, make a template. This is an XML file, describing the layout of the spreadsheet. For example, test.xml: Now, create a small program to use it: #!/usr/bin/perl -w use strict; use Excel::Template; # Create the Excel template my $template = Excel::Template->new( filename => 'test.xml', ); # Add a few parameters $template->param( HOME => $ENV{HOME}, PATH => $ENV{PATH}, ); $template->write_file('test.xls'); If everything worked, then you should have a spreadsheet called text.xls in your working directory that looks something like: A B C +----------------+----------------+---------------- 1 | /home/me | /bin:/usr/bin | +----------------+----------------+---------------- 2 | | | +----------------+----------------+---------------- 3 | | | =head1 DESCRIPTION This is a module used for templating Excel files. Its genesis came from the need to use the same datastructure as L, but provide Excel files instead. The existing modules don't do the trick, as they require replication of logic that's already been done within L. =head1 MOTIVATION I do a lot of Perl/CGI for reporting purposes. In nearly every place I've been, I've been asked for HTML, PDF, and Excel. L provides the first, and L does the second pretty well. But, generating Excel was the sticking point. I already had the data structure for the other templating modules, but I just didn't have an easy mechanism to get that data structure into an XLS file. =head1 USAGE =head2 new() This creates a Excel::Template object. =head3 Parameters =over 4 =item * FILE / FILENAME Excel::Template will parse the template in the given file or filehandle automatically. (You can also use the parse() method, described below.) If you want to use the __DATA__ section, you can do so by passing FILE => \*DATA =item * RENDERER The default rendering engine is L. You may, if you choose, change that to another choice. The legal values are: =over 4 =item * Excel::Template->RENDER_NML This is the default of L. =item * Excel::Template->RENDER_BIG This attempts to load L. =item * Excel::Template->RENDER_XML This attempts to load L. =back =item * USE_UNICODE This will use L to represent strings instead of Perl's internal string handling. You must already have L installed on your system. The USE_UNICODE parameter will be ignored if you are using Perl 5.8 or higher as Perl's internal string handling is unicode-aware. NOTE: Certain older versions of L and mod_perl clash for some reason. Upgrading to the latest version of L should fix the problem. =back =head3 Deprecated =over 4 =item * BIG_FILE Instead, use RENDERER => Excel::Template->RENDER_BIG =back =head2 param() This method is exactly like L's param() method. =head2 parse() / parse_xml() This method actually parses the template file. It can either be called separately or through the new() call. It will die() if it runs into a situation it cannot handle. If a filename is passed in (vs. a filehandle), the directory name will be passed in to L as the I parameter. This will allow for XML directives to work as expected. =head2 write_file() Create the Excel file and write it to the specified filename, if possible. (This is when the actual merging of the template and the parameters occurs.) =head2 output() It will act just like L's output() method, returning the resultant file as a stream, usually for output to the web. (This is when the actual merging of the template and the parameters occurs.) =head2 register() This allows you to register a class as handling a node. q.v. L for more info. =head1 SUPPORTED NODES This is a partial list of nodes. See the other classes in this distro for more details on specific parameters and the like. Every node can set the ROW and COL parameters. These are the actual ROW/COL values that the next CELL-type tag will write into. =over 4 =item * L This is the node representing the workbook. It is the parent for all other nodes. =item * L This is the node representing a given worksheet. =item * L This node represents a conditional expression. Its children may or may not be rendered. It behaves just like L's TMPL_IF. =item * L This node represents a loop. It behaves just like L's TMPL_LOOP. =item * L This node represents a row of data. This is the 1 in A1. There is no COLUMN node, as of yet. =item * L This node varies the format for its children. All formatting options supported in L are supported here. There are also a number of formatting shortcuts, such as L and L. =item * L This refers back to a cell previously named. =item * L This is the actual cell in a spreadsheet. =item * L This is a formula in a spreadsheet. =item * L This is a BACKREF for a number of identically-named cells. =item * L This is a variable. It is generally used when the 'text' attribute isn't sufficient. =back =head1 BUGS None, that I know of. =head1 SUPPORT This is production quality software, used in several production web applications. =head1 MAINTAINERS Jens Gassmann Robert Bohne Rob Kinyon =head1 CONTRIBUTORS There is a mailing list at http://groups.google.com/group/ExcelTemplate or exceltemplate@googlegroups.com =head2 Robert Bohne =over 4 =item * Swichting to Module::Install =item * Add autofilter to worksheet =back =head2 Robert Graff =over 4 =item * Finishing formats =item * Fixing several bugs in worksheet naming =back =head2 Jens Gassmann =over 4 =item * Add hide_gridlines to worksheet =back =head1 TEST COVERAGE I use L to test the coverage of my tests. Every release, I intend to improve these numbers. Excel::Template is also part of the CPAN Kwalitee initiative, being one of the top 100 non-core modules downloaded from CPAN. If you wish to help out, please feel free to contribute tests, patches, and/or suggestions. ---------------------------- ------ ------ ------ ------ ------ ------ ------ File stmt bran cond sub pod time total ---------------------------- ------ ------ ------ ------ ------ ------ ------ blib/lib/Excel/Template.pm 93.8 60.0 58.8 100.0 100.0 31.8 83.3 ...ib/Excel/Template/Base.pm 94.4 50.0 n/a 100.0 0.0 4.4 80.0 ...cel/Template/Container.pm 100.0 50.0 33.3 100.0 0.0 2.0 83.3 ...emplate/Container/Bold.pm 100.0 n/a n/a 100.0 0.0 0.1 95.0 .../Container/Conditional.pm 95.9 90.0 66.7 100.0 0.0 0.3 91.0 ...plate/Container/Format.pm 100.0 n/a n/a 100.0 0.0 1.5 96.8 ...plate/Container/Hidden.pm 100.0 n/a n/a 100.0 0.0 0.0 95.0 ...plate/Container/Italic.pm 100.0 n/a n/a 100.0 0.0 0.0 95.0 ...ainer/KeepLeadingZeros.pm 100.0 100.0 n/a 100.0 0.0 0.0 96.3 ...plate/Container/Locked.pm 100.0 n/a n/a 100.0 0.0 0.0 95.0 ...emplate/Container/Loop.pm 96.8 50.0 50.0 100.0 0.0 0.1 82.7 ...late/Container/Outline.pm 100.0 n/a n/a 100.0 0.0 0.0 95.0 ...Template/Container/Row.pm 100.0 75.0 n/a 100.0 0.0 0.1 90.6 ...mplate/Container/Scope.pm 100.0 n/a n/a 100.0 n/a 0.0 100.0 ...plate/Container/Shadow.pm 100.0 n/a n/a 100.0 0.0 0.0 95.0 ...te/Container/Strikeout.pm 100.0 n/a n/a 100.0 0.0 0.0 95.0 ...ate/Container/Workbook.pm 100.0 n/a n/a 100.0 n/a 7.0 100.0 ...te/Container/Worksheet.pm 95.5 87.5 100.0 100.0 0.0 1.1 90.2 ...Excel/Template/Context.pm 98.0 80.0 75.0 100.0 73.3 17.0 90.7 ...Excel/Template/Element.pm 100.0 n/a n/a 100.0 n/a 0.1 100.0 ...mplate/Element/Backref.pm 100.0 50.0 33.3 100.0 0.0 0.1 87.1 .../Template/Element/Cell.pm 97.9 75.0 80.0 100.0 0.0 5.6 88.6 ...mplate/Element/Formula.pm 100.0 n/a n/a 100.0 0.0 0.0 94.1 ...te/Element/FreezePanes.pm 100.0 n/a n/a 100.0 0.0 0.0 95.5 ...Template/Element/Image.pm 100.0 100.0 n/a 100.0 0.0 0.0 94.3 ...Template/Element/Range.pm 100.0 66.7 n/a 100.0 0.0 0.1 88.9 ...l/Template/Element/Var.pm 100.0 n/a n/a 100.0 0.0 0.0 94.1 ...Excel/Template/Factory.pm 100.0 73.1 66.7 100.0 100.0 22.3 91.4 .../Excel/Template/Format.pm 98.4 75.0 33.3 100.0 66.7 2.6 90.5 ...xcel/Template/Iterator.pm 98.6 80.0 70.6 100.0 50.0 0.3 88.8 ...el/Template/TextObject.pm 92.9 62.5 33.3 100.0 0.0 3.3 80.9 Total 97.8 74.7 64.6 100.0 35.7 100.0 89.4 ---------------------------- ------ ------ ------ ------ ------ ------ ------ =head1 COPYRIGHT This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. The full text of the license can be found in the LICENSE file included with this module. =head1 SEE ALSO perl(1), L, L =cut Excel-Template-0.34/lib/Excel/Template/Base.pm000644 000765 000024 00000003677 11406453233 021005 0ustar00rbostaff000000 000000 package Excel::Template::Base; use strict; use Excel::Template::Factory; sub new { my $class = shift; push @_, %{shift @_} while ref $_[0] eq 'HASH'; (@_ % 2) and die "$class->new() called with odd number of option parameters\n"; my %x = @_; # Do not use a hashref-slice here because of the uppercase'ing my $self = {}; $self->{uc $_} = $x{$_} for keys %x; bless $self, $class; } *isa = *isa = \&Excel::Template::Factory::isa; *is_embedded = *is_embedded = \&Excel::Template::Factory::is_embedded; #sub calculate { ($_[1])->get(@_[0,2]) } #{ # my $self = shift; # my ($context, $attr) = @_; # # return $context->get($self, $attr); #} sub enter_scope { ($_[1])->enter_scope($_[0]) } #{ # my $self = shift; # my ($context) = @_; # # return $context->enter_scope($self); #} sub exit_scope { ($_[1])->exit_scope($_[0], $_[2]) } #{ # my $self = shift; # my ($context, $no_delta) = @_; # # return $context->exit_scope($self, $no_delta); #} sub deltas { # my $self = shift; # my ($context) = @_; return {}; } # Everyone seems to have their own versions. # Maybe, it's part of the API to require that you have the right one of these # defined? #sub resolve #{ # my $self = shift; # my ($context) = @_; # # ''; #} # #sub render #{ # my $self = shift; # my ($context) = @_; # # 1; #} 1; __END__ =head1 NAME Excel::Template::Base - Excel::Template::Base =head1 PURPOSE Base class for all Excel::Template classes =head1 NODE NAME None =head1 INHERITANCE None =head1 ATTRIBUTES None =head1 CHILDREN None =head1 EFFECTS None =head1 DEPENDENCIES None =head1 METHODS =head2 calculate This is a wrapper around Excel::Template::Context->get() =head2 isa This is a wrapper around Excel::Template::Factory->isa() =head2 is_embedded This is a wrapper around Excel::Template::Factory->is_embedded() =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO =cut Excel-Template-0.34/lib/Excel/Template/Container/000755 000765 000120 00000000000 11747312641 021471 5ustar00rboadmin000000 000000 Excel-Template-0.34/lib/Excel/Template/Container.pm000644 000765 000120 00000004701 11747252337 022036 0ustar00rboadmin000000 000000 package Excel::Template::Container; use strict; BEGIN { use vars qw(@ISA); @ISA = qw(Excel::Template::Base); use Excel::Template::Base; } # Containers are objects that can contain arbitrary elements, such as # PageDefs or Loops. sub new { my $class = shift; my $self = $class->SUPER::new(@_); $self->{ELEMENTS} = [] unless exists $self->{ELEMENTS} && ref $self->{ELEMENTS} eq 'ARRAY'; return $self; } # Removed as unused code #sub _do_page #{ # my $self = shift; # my ($method, $context) = @_; # # for my $e (@{$self->{ELEMENTS}}) # { # $e->enter_scope($context); # $e->$method($context); # $e->exit_scope($context, 1); # } # # return 1; #} # #sub begin_page { _do_page 'begin_page', @_ } #sub end_page { _do_page 'end_page', @_ } sub iterate_over_children { my $self = shift; my ($context) = @_; my $continue = 1; for my $e ( @{$self->{ELEMENTS}}) { $e->enter_scope($context); my $rc = $e->render($context); $continue = $rc if $continue; $e->exit_scope($context); } return $continue; } sub render { $_[0]->iterate_over_children($_[1]) } #{ # my $self = shift; # my ($context) = @_; # # return $self->iterate_over_children($context); #} # Removed as unused code #sub max_of #{ # my $self = shift; # my ($context, $attr) = @_; # # my $max = $context->get($self, $attr); # # ELEMENT: # foreach my $e (@{$self->{ELEMENTS}}) # { # $e->enter_scope($context); # # my $v = $e->isa('CONTAINER') # ? $e->max_of($context, $attr) # : $e->calculate($context, $attr); # # $max = $v if $max < $v; # # $e->exit_scope($context, 1); # } # # return $max; #} # #sub total_of #{ # my $self = shift; # my ($context, $attr) = @_; # # my $total = 0; # # ELEMENT: # foreach my $e (@{$self->{ELEMENTS}}) # { # $e->enter_scope($context); # # $total += $e->isa('CONTAINER') # ? $e->total_of($context, $attr) # : $e->calculate($context, $attr); # # $e->exit_scope($context, 1); # } # # return $total; #} 1; __END__ =head1 NAME Excel::Template::Container - Excel::Template::Container =head1 PURPOSE =head1 NODE NAME =head1 INHERITANCE =head1 ATTRIBUTES =head1 CHILDREN =head1 AFFECTS =head1 DEPENDENCIES =head1 USAGE =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO =cut Excel-Template-0.34/lib/Excel/Template/Context.pm000644 000765 000120 00000015024 11747252337 021540 0ustar00rboadmin000000 000000 package Excel::Template::Context; use strict; BEGIN { use vars qw(@ISA); @ISA = qw(Excel::Template::Base); use Excel::Template::Base; } use Excel::Template::Format; # This is a helper object. It is not instantiated by the user, nor does it # represent an XML node. Rather, every container will use this object to # maintain the context for its children. my %isAbsolute = map { $_ => ~~1 } qw( ROW COL ); sub new { my $class = shift; my $self = $class->SUPER::new(@_); $self->{ACTIVE_WORKSHEET} = undef; $self->{FORMAT_OBJECT} = Excel::Template::Format->new; $self->{ACTIVE_FORMAT} = $self->{FORMAT_OBJECT}->blank_format($self); $self->{WORKSHEET_NAMES} = undef; $self->{__MARKS} = {}; # Removed NAME_MAP until I figure out what the heck it's for for (qw( STACK PARAM_MAP )) { next if defined $self->{$_} && ref $self->{$_} eq 'ARRAY'; $self->{$_} = []; } $self->{$_} = 0 for keys %isAbsolute; return $self; } sub use_unicode { $_[0]->{UNICODE} && 1 } sub _find_param_in_map { my $self = shift; my ($map, $param, $depth) = @_; $param = uc $param; $depth ||= 0; my ($val, $found); for my $map (reverse @{$self->{$map}}) { next unless exists $map->{$param}; $depth--, next if $depth; $found = ~~1; $val = $map->{$param}; last; } die "Parameter '$param' not found\n" if !$found && $self->{DIE_ON_NO_PARAM}; return $val; } sub param { my $self = shift; $self->_find_param_in_map( 'PARAM_MAP', @_, ); } #sub named_param #{ # my $self = shift; # $self->_find_param_in_map( # 'NAME_MAP', # @_, # ); #} sub resolve { my $self = shift; my ($obj, $key, $depth) = @_; $key = uc $key; $depth ||= 0; my $obj_val = $obj->{$key}; $obj_val = $self->param($1) if $obj_val =~ /^\$(\S+)$/o; #GGG Remove this once NAME_MAP is working # $obj_val = $self->named_param($1) # if $obj_val =~ /^\\(\S+)$/o; #GGG Does this adequately test values to make sure they're legal?? # A value is defined as: # 1) An optional operator (+, -, *, or /) # 2) A decimal number #GGG Convert this to use //x my ($op, $val) = $obj_val =~ m/^\s*([\+\*\/\-])?\s*([\d.]*\d)\s*$/oi; # Unless it's a relative value, we have what we came for. return $obj_val unless $op; my $prev_val = $isAbsolute{$key} ? $self->{$key} : $self->get($obj, $key, $depth + 1); return $obj_val unless defined $prev_val; return $prev_val unless defined $obj_val; # Prevent divide-by-zero issues. return $prev_val if $op eq '/' and $val == 0; my $new_val; for ($op) { /^\+$/ && do { $new_val = ($prev_val + $val); last; }; /^\-$/ && do { $new_val = ($prev_val - $val); last; }; /^\*$/ && do { $new_val = ($prev_val * $val); last; }; /^\/$/ && do { $new_val = ($prev_val / $val); last; }; die "Unknown operator '$op' in arithmetic resolve\n"; } return $new_val if defined $new_val; return; } sub enter_scope { my $self = shift; my ($obj) = @_; push @{$self->{STACK}}, $obj; for my $key (keys %isAbsolute) { next unless exists $obj->{$key}; $self->{$key} = $self->resolve($obj, $key); } return ~~1; } sub exit_scope { my $self = shift; my ($obj, $no_delta) = @_; unless ($no_delta) { my $deltas = $obj->deltas($self); $self->{$_} += $deltas->{$_} for keys %$deltas; } pop @{$self->{STACK}}; return ~~1; } sub get { my $self = shift; my ($dummy, $key, $depth) = @_; $depth ||= 0; $key = uc $key; return unless @{$self->{STACK}}; my $obj = $self->{STACK}[-1]; return $self->{$key} if $isAbsolute{$key}; my $val = undef; my $this_depth = $depth; foreach my $e (reverse @{$self->{STACK}}) { next unless exists $e->{$key}; next if $this_depth-- > 0; $val = $self->resolve($e, $key, $depth); last; } $val = $self->{$key} unless defined $val; return $val unless defined $val; return $self->param($1, $depth) if $val =~ /^\$(\S+)$/o; return $val; } sub active_format { my $self = shift; $self->{ACTIVE_FORMAT} = $_[0] if @_; $self->{ACTIVE_FORMAT}; } sub new_worksheet { my $self = shift; my ($worksheet) = @_; $self->{ROW} = $self->{COL} = 0; $self->{REFERENCES} = {}; my $name = $self->get( $worksheet, 'NAME' ); if ( defined $name && length $name ) { if ( exists $self->{WORKSHEET_NAMES}{$name} ) { $name = ''; } else { $self->{WORKSHEET_NAMES}{$name} = undef; } } else { $name = ''; } return $self->active_worksheet( $self->{XLS}->add_worksheet( $name ), ); } sub mark { my $self = shift; if ( @_ > 1 ) { my %args = @_; @{$self->{__MARKS}}{keys %args} = values %args; } return $self->{__MARKS}{$_[0]} } sub active_worksheet { my $self = shift; $self->{ACTIVE_WORKSHEET} = $_[0] if @_; $self->{ACTIVE_WORKSHEET}; } sub add_reference { my $self = shift; my ($ref, $row, $col) = @_; $self->{REFERENCES}{$ref} ||= []; push @{$self->{REFERENCES}{$ref}}, [ $row, $col ]; return ~~1; } sub get_all_references { my $self = shift; my $ref = uc shift; $self->{REFERENCES}{$ref} ||= []; return @{ $self->{REFERENCES}{$ref} }; } sub get_last_reference { my $self = shift; my $ref = uc shift; $self->{REFERENCES}{$ref} ||= []; return @{ $self->{REFERENCES}{$ref}[-1] }; } sub format_object { $_[0]{FORMAT_OBJECT} } 1; __END__ =head1 NAME Excel::Template::Context - Excel::Template::Context =head1 PURPOSE This is a helper node that provides the global context for the nodes do their processing within. It provides attribute scoping, parameter resolution, and other very nice things. Documentation is provided for if you wish to subclass another node. =head1 NODE NAME None =head1 INHERITANCE None =head1 ATTRIBUTES None =head1 CHILDREN None =head1 AFFECTS Everything =head1 DEPENDENCIES None =head1 METHODS =head2 active_format =head2 active_worksheet =head2 add_reference =head2 format_object =head2 get =head2 get_all_references =head2 get_last_reference =head2 mark =head2 new_worksheet =head2 param =head2 use_unicode =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO =cut Excel-Template-0.34/lib/Excel/Template/Element/000755 000765 000120 00000000000 11747312641 021140 5ustar00rboadmin000000 000000 Excel-Template-0.34/lib/Excel/Template/Element.pm000644 000765 000120 00000000673 11747257603 021512 0ustar00rboadmin000000 000000 package Excel::Template::Element; use strict; BEGIN { use vars qw(@ISA); @ISA = qw(Excel::Template::Base); use Excel::Template::Base; } 1; __END__ =head1 NAME Excel::Template::Element - Excel::Template::Element =head1 PURPOSE =head1 NODE NAME =head1 INHERITANCE =head1 ATTRIBUTES =head1 CHILDREN =head1 AFFECTS =head1 DEPENDENCIES =head1 USAGE =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO =cut Excel-Template-0.34/lib/Excel/Template/Factory.pm000644 000765 000120 00000011104 11747252337 021516 0ustar00rboadmin000000 000000 package Excel::Template::Factory; use strict; my %Manifest = ( # These are the instantiable nodes 'IF' => 'Excel::Template::Container::Conditional', 'LOOP' => 'Excel::Template::Container::Loop', 'ROW' => 'Excel::Template::Container::Row', 'SCOPE' => 'Excel::Template::Container::Scope', 'WORKBOOK' => 'Excel::Template::Container::Workbook', 'WORKSHEET' => 'Excel::Template::Container::Worksheet', 'BACKREF' => 'Excel::Template::Element::Backref', 'CELL' => 'Excel::Template::Element::Cell', 'FORMULA' => 'Excel::Template::Element::Formula', 'FREEZEPANES' => 'Excel::Template::Element::FreezePanes', 'MERGE_RANGE' => 'Excel::Template::Element::MergeRange', 'IMAGE' => 'Excel::Template::Element::Image', 'RANGE' => 'Excel::Template::Element::Range', 'VAR' => 'Excel::Template::Element::Var', 'FORMAT' => 'Excel::Template::Container::Format', # These are all the Format short-cut objects # They are also instantiable 'BOLD' => 'Excel::Template::Container::Bold', 'HIDDEN' => 'Excel::Template::Container::Hidden', 'ITALIC' => 'Excel::Template::Container::Italic', 'LOCKED' => 'Excel::Template::Container::Locked', 'OUTLINE' => 'Excel::Template::Container::Outline', 'SHADOW' => 'Excel::Template::Container::Shadow', 'STRIKEOUT' => 'Excel::Template::Container::Strikeout', 'KEEP_LEADING_ZEROS' => 'Excel::Template::Container::KeepLeadingZeros', # These are the helper objects # They are also in here to make E::T::Factory::isa() work. 'CONTEXT' => 'Excel::Template::Context', 'ITERATOR' => 'Excel::Template::Iterator', 'TEXTOBJECT' => 'Excel::Template::TextObject', 'CONTAINER' => 'Excel::Template::Container', 'ELEMENT' => 'Excel::Template::Element', 'BASE' => 'Excel::Template::Base', ); my %isBuildable = map { $_ => ~~1 } qw( WORKBOOK WORKSHEET FORMAT BOLD HIDDEN ITALIC LOCKED OUTLINE SHADOW STRIKEOUT IF ROW LOOP SCOPE KEEP_LEADING_ZEROS CELL FORMULA FREEZEPANES IMAGE MERGE_RANGE VAR BACKREF RANGE ); { my %Loaded; sub _load_class { my $self = shift; my ($class) = @_; unless ( exists $Loaded{$class} ) { (my $filename = $class) =~ s!::!/!g; eval { require "$filename.pm"; }; if ($@) { die "Cannot find or compile PM file for '$class' ($filename) because $@\n"; } $Loaded{$class} = ~~1; } return ~~1; } } { my @param_names = qw(name class isa); sub register { my $self = shift; my %params = @_; for (@param_names) { unless ($params{$_}) { warn "$_ was not supplied to register()\n" if $^W; return; } } my $name = uc $params{name}; if (exists $Manifest{$name}) { warn "$params{name} already exists in the manifest.\n" if $^W; return; } my $isa = uc $params{isa}; unless (exists $Manifest{$isa}) { warn "$params{isa} does not exist in the manifest.\n" if $^W; return; } { no strict 'refs'; unshift @{"$params{class}::ISA"}, $Manifest{$isa}; } $self->_load_class( $Manifest{$isa} ); $self->_load_class( $params{class} ); $Manifest{$name} = $params{class}; $isBuildable{$name} = ~~1; return ~~1; } } sub _create { my $self = shift; my $name = uc shift; return unless exists $Manifest{$name}; $self->_load_class( $Manifest{$name} ); return $Manifest{$name}->new(@_); } sub _create_node { my $self = shift; my $name = uc shift; return unless exists $isBuildable{$name}; return $self->_create($name, @_); } sub isa { return unless @_ >= 2; exists $Manifest{uc $_[1]} ? UNIVERSAL::isa($_[0], $Manifest{uc $_[1]}) : UNIVERSAL::isa(@_) } sub is_embedded { return unless @_ >= 1; isa( $_[0], $_ ) && return ~~1 for qw( VAR BACKREF RANGE ); return; } 1; __END__ =head1 NAME Excel::Template::Factory - Excel::Template::Factory =head1 PURPOSE To provide a common way to instantiate Excel::Template nodes =head1 USAGE =head2 register() Use this to register your own nodes. Example forthcoming. =head1 METHODS =head2 isa This is a customized isa() wrapper for syntactic sugar =head2 is_embedded =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO =cut Excel-Template-0.34/lib/Excel/Template/Format.pm000644 000765 000120 00000011365 11747254303 021343 0ustar00rboadmin000000 000000 package Excel::Template::Format; use strict; # This is the format repository. Spreadsheet::WriteExcel does not cache the # known formats. So, it is very possible to continually add the same format # over and over until you run out of RAM or addressability in the XLS file. In # real life, less than 10-20 formats are used, and they're re-used in various # places in the file. This provides a way of keeping track of already-allocated # formats and making new formats based on old ones. sub new { bless {}, shift } sub _assign { $_[0]{$_[1]} = $_[2]; $_[0]{$_[2]} = $_[1] } # my $self = shift; # my ($key, $format) = @_; # $self->{$key} = $format; # $self->{$format} = $key; #} sub _retrieve_key { $_[0]{ $_[1] } } # my $self = shift; # my ($format) = @_; # return $self->{$format}; #} *_retrieve_format = \&_retrieve_key; #sub _retrieve_format { # my $self = shift; # my ($key) = @_; # return $self->{$key}; #} { my @_boolean_formats = qw( bold italic locked hidden font_outline font_shadow font_strikeout text_wrap text_justlast shrink is_merged ); my @_integer_formats = qw( size underline rotation indent pattern border bottom top left right ); my @_string_formats = qw( num_format font color align valign bg_color fg_color border_color bottom_color top_color left_color right_color ); my @_fake_slots = qw( is_merged ); sub _params_to_key { my %params = @_; $params{lc $_} = delete $params{$_} for keys %params; # force fake slots to be zero if not set $params{$_} ||= 0 for @_fake_slots; my @parts = ( (map { $params{$_} ? 1 : '' } @_boolean_formats), (map { $params{$_} ? $params{$_} + 0 : '' } @_integer_formats), (map { $params{$_} || '' } @_string_formats), ); return join( "\n", @parts ); } sub _key_to_params { my ($key) = @_; my @key_parts = split /\n/, $key; my @boolean_parts = splice @key_parts, 0, scalar( @_boolean_formats ); my @integer_parts = splice @key_parts, 0, scalar( @_integer_formats ); my @string_parts = splice @key_parts, 0, scalar( @_string_formats ); my %params; $params{ $_boolean_formats[$_] } = ~~1 for grep { $boolean_parts[$_] } 0 .. $#_boolean_formats; $params{ $_integer_formats[$_] } = $integer_parts[$_] for grep { defined $integer_parts[$_] && length $integer_parts[$_] } 0 .. $#_integer_formats; $params{ $_string_formats[$_] } = $string_parts[$_] for grep { $string_parts[$_] } 0 .. $#_string_formats; return %params; } sub copy { my $self = shift; my ($context, $old_fmt, %properties) = @_; # This is a key used for non-format book-keeping. delete $properties{ ELEMENTS }; defined(my $key = _retrieve_key($self, $old_fmt)) || die "Internal Error: Cannot find key for format '$old_fmt'!\n"; my %params = _key_to_params($key); PROPERTY: while ( my ($prop, $value) = each %properties ) { $prop = lc $prop; foreach (@_boolean_formats) { if ($prop eq $_) { $params{$_} = ($value && $value !~ /false/i); next PROPERTY; } } foreach (@_integer_formats, @_string_formats) { if ($prop eq $_) { $params{$_} = $value; next PROPERTY; } } warn "Property '$prop' is unrecognized\n" if $^W; } my $new_key = _params_to_key(%params); my $format = _retrieve_format($self, $new_key); return $format if $format; delete $params{$_} for @_fake_slots; $format = $context->{XLS}->add_format(%params); _assign($self, $new_key, $format); return $format; } } sub blank_format { my $self = shift; my ($context) = @_; my $blank_key = _params_to_key(); my $format = _retrieve_format($self, $blank_key); return $format if $format; $format = $context->{XLS}->add_format; _assign($self, $blank_key, $format); return $format; } 1; __END__ =head1 NAME Excel::Template::Format - Excel::Template::Format =head1 PURPOSE Helper class for FORMAT =head1 NODE NAME None =head1 INHERITANCE None =head1 ATTRIBUTES None =head1 CHILDREN None =head1 EFFECTS None =head1 DEPENDENCIES None =head1 METHODS =head2 blank_format Provides a blank format for use =head2 copy Clones an existing format, so that a new format can be built from it =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO FORMAT =cut Excel-Template-0.34/lib/Excel/Template/Iterator.pm000644 000765 000120 00000010735 11747252337 021711 0ustar00rboadmin000000 000000 package Excel::Template::Iterator; use strict; BEGIN { use vars qw(@ISA); @ISA = qw(Excel::Template::Base); use Excel::Template::Base; } sub new { my $class = shift; my $self = $class->SUPER::new(@_); unless (Excel::Template::Factory::isa($self->{CONTEXT}, 'CONTEXT')) { die "Internal Error: No context object passed to ", __PACKAGE__, $/; } $self->{MAXITERS} ||= 0; # This is the index we will work on NEXT, in whatever direction the # iterator is going. $self->{INDEX} = -1; # This is a short-circuit parameter to let the iterator function in a # null state. $self->{NO_PARAMS} = 0; unless ($self->{NAME} =~ /\w/) { $self->{NO_PARAMS} = 1; warn "INTERNAL ERROR: 'NAME' was blank was blank when passed to ", __PACKAGE__, $/ if $^W; return $self; } # Cache the reference to the appropriate data. $self->{DATA} = $self->{CONTEXT}->param($self->{NAME}); unless (ref $self->{DATA} eq 'ARRAY') { $self->{NO_PARAMS} = 1; warn "'$self->{NAME}' does not have a list of parameters", $/ if $^W; return $self; } unless (@{$self->{DATA}}) { $self->{NO_PARAMS} = 1; } $self->{MAX_INDEX} = $#{$self->{DATA}}; return $self; } sub enter_scope { my $self = shift; return 0 if $self->{NO_PARAMS}; for my $x ($self->{DATA}[$self->{INDEX}]) { $x->{uc $_} = delete $x->{$_} for keys %$x; } push @{$self->{CONTEXT}{PARAM_MAP}}, $self->{DATA}[$self->{INDEX}]; return 1; } sub exit_scope { my $self = shift; return 0 if $self->{NO_PARAMS}; # There has to be the base parameter map and at least the one that # Iterator::enter_scope() added on top. @{$self->{CONTEXT}{PARAM_MAP}} > 1 || die "Internal Error: ", __PACKAGE__, "'s internal param_map off!", $/; pop @{$self->{CONTEXT}{PARAM_MAP}}; return 1; } sub can_continue { my $self = shift; return 0 if $self->{NO_PARAMS}; return 1 if $self->more_params; return 0; } sub more_params { my $self = shift; return 0 if $self->{NO_PARAMS}; return 1 if $self->{MAX_INDEX} > $self->{INDEX}; return 0; } # Call this method BEFORE incrementing the index to the next value. sub _do_globals { my $self = shift; my $data = $self->{DATA}[$self->{INDEX}]; # Perl's arrays are 0-indexed. Thus, the first element is at index "0". # This means that odd-numbered elements are at even indices, and vice-versa. # This also means that MAX (the number of elements in the array) can never # be the value of an index. It is NOT the last index in the array. $data->{'__FIRST__'} ||= ($self->{INDEX} == 0); $data->{'__INNER__'} ||= (0 < $self->{INDEX} && $self->{INDEX} < $self->{MAX_INDEX}); $data->{'__LAST__'} ||= ($self->{INDEX} == $self->{MAX_INDEX}); $data->{'__ODD__'} ||= !($self->{INDEX} % 2); return 1; } sub next { my $self = shift; return 0 if $self->{NO_PARAMS}; return 0 unless $self->more_params; $self->exit_scope; $self->{INDEX}++; $self->_do_globals; $self->enter_scope; return 1; } # This method doesn't seem to be used ... # If it is reinstated, here's the POD for it #=head2 back_up # #Go to the previous iteration of the loop # #sub back_up #{ # my $self = shift; # # return 0 if $self->{NO_PARAMS}; # # $self->exit_scope; # # $self->{INDEX}--; # # $self->_do_globals; # # $self->enter_scope; # # return 1; #} # This method doesn't seem to be used ... # If it is reinstated, here's the POD for it #=head2 reset # #Resets the iterator # #sub reset #{ # my $self = shift; # # return 0 if $self->{NO_PARAMS}; # # $self->{INDEX} = -1; # # return 1; #} 1; __END__ =head1 NAME Excel::Template::Iterator - Excel::Template::Iterator =head1 PURPOSE This is meant for internal use only. Documentation is provided for subclassing. =head1 NODE NAME None =head1 INHERITANCE None =head1 ATTRIBUTES None =head1 CHILDREN None =head1 AFFECTS This is a helper class for LOOP =head1 DEPENDENCIES None =head1 METHODS =head2 can_continue Determines if the iterator can continue. Currently, this wraps more_params(), but there other possible situations, such as the page ending. =head2 more_params Determines if the iterator for the loop has more parameters that it can consume =head2 next Go to the next iteration of the loop =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO LOOP =cut Excel-Template-0.34/lib/Excel/Template/TextObject.pm000755 000765 000120 00000002607 11747252337 022175 0ustar00rboadmin000000 000000 package Excel::Template::TextObject; use strict; BEGIN { use vars qw(@ISA); @ISA = qw(Excel::Template::Base); use Excel::Template::Base; } # This is a helper object. It is not instantiated by the user, # nor does it represent an XML object. Rather, certain elements, # such as , can use this object to do text with variable # substitutions. sub new { my $class = shift; my $self = $class->SUPER::new(@_); $self->{STACK} = [] unless defined $self->{STACK} && ref $self->{STACK} eq 'ARRAY'; return $self; } sub resolve { my $self = shift; my ($context) = @_; my $use_unicode = $context->use_unicode; my $t; if ($use_unicode) { require Unicode::String; $t = Unicode::String::utf8(''); } else { $t = ''; } for my $tok (@{$self->{STACK}}) { my $val = $tok; $val = $val->resolve($context) if Excel::Template::Factory::is_embedded( $val ); $t .= $use_unicode ? Unicode::String::utf8("$val") : $val; } return $t; } 1; __END__ =head1 NAME Excel::Template::TextObject - Excel::Template::TextObject =head1 PURPOSE =head1 NODE NAME =head1 INHERITANCE =head1 ATTRIBUTES =head1 CHILDREN =head1 AFFECTS =head1 DEPENDENCIES =head1 USAGE =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO =cut Excel-Template-0.34/lib/Excel/Template/Element/Backref.pm000755 000765 000120 00000002616 11747252337 023050 0ustar00rboadmin000000 000000 package Excel::Template::Element::Backref; use strict; use Spreadsheet::WriteExcel::Utility; BEGIN { use vars qw(@ISA); @ISA = qw(Excel::Template::Element); use Excel::Template::Element; } sub resolve { my $self = shift; my ($context) = @_; my $ref_name = $context->resolve($self, 'REF'); my ($row, $col) = $context->get_last_reference( $ref_name ); return '' unless defined $row && defined $col; return xl_rowcol_to_cell( $row, $col ); } 1; __END__ =head1 NAME Excel::Template::Element::Backref - Excel::Template::Element::Backref =head1 PURPOSE Returns the cell location (i.e. B2) of the last cell to name this reference. To return the location of the entire range of cells to name this reference see RANGE. =head1 NODE NAME BACKREF =head1 INHERITANCE Excel::Template::Element =head1 ATTRIBUTES =over 4 =item * REF This is the name of the reference to look up. =back =head1 CHILDREN None =head1 EFFECTS None =head1 DEPENDENCIES This will only be used within CELL tags. =head1 USAGE In the example... =+ The formula in row 2 would be =A1+C1. C1 is the last to reference "that_cell". =head1 AUTHOR Rob Kinyon (rkinyon@columbus.rr.com) =head1 SEE ALSO CELL, RANGE =cut Excel-Template-0.34/lib/Excel/Template/Element/Cell.pm000755 000765 000024 00000011456 11747257443 022415 0ustar00rbostaff000000 000000 package Excel::Template::Element::Cell; use strict; BEGIN { use vars qw(@ISA); @ISA = qw(Excel::Template::Element); use Excel::Template::Element; } sub new { my $class = shift; my $self = $class->SUPER::new(@_); $self->{TXTOBJ} = Excel::Template::Factory->_create('TEXTOBJECT'); return $self; } sub _get_text { my $self = shift; my ($context) = @_; my $txt = $context->get($self, 'TEXT'); if (defined $txt) { my $txt_obj = Excel::Template::Factory->_create('TEXTOBJECT'); push @{$txt_obj->{STACK}}, $txt; $txt = $txt_obj->resolve($context); } else { $txt = $self->{TXTOBJ}->resolve($context) } return $txt; } my %legal_types = ( 'blank' => 'write_blank', 'formula' => 'write_formula', 'number' => 'write_number', 'string' => 'write_string', 'url' => 'write_url', 'date_time' => 'write_date_time', ); sub render { my $self = shift; my ($context, $method) = @_; unless ( $method ) { my $type = $context->get( $self, 'TYPE' ); if ( defined $type ) { my $type = lc $type; if ( exists $legal_types{ $type } ) { $method = $legal_types{ $type }; } else { warn "'$type' is not a legal cell type.\n" if $^W; } } } $method ||= 'write'; my ($row, $col) = map { $context->get($self, $_) } qw(ROW COL); my $ref = $context->get( $self, 'REF' ); if (defined $ref && length $ref) { $context->add_reference( uc( $ref ), $row, $col ); } # Apply the cell width to the current column if (my $width = $context->get($self, 'WIDTH')) { $width =~ s/[^\d.]//g; $width *= 1; if ($width > 0) { $context->active_worksheet->set_column($col, $col, $width); } } $context->active_worksheet->$method( $row, $col, $self->_get_text($context), $context->active_format, ); my $comment = $context->get($self, 'COMMENT'); if (defined $comment && length $comment){ $context->active_worksheet->write_comment($row, $col,$comment); } return 1; } sub deltas { return { COL => +1, }; } 1; __END__ =head1 NAME Excel::Template::Element::Cell - Excel::Template::Element::Cell =head1 PURPOSE To actually write stuff to the worksheet =head1 NODE NAME CELL =head1 INHERITANCE L =head1 ATTRIBUTES =over 4 =item * TEXT This is the text to write to the cell. This can either be text or a parameter with a dollar-sign in front of the parameter name. =item * COL Optionally, you can specify which column you want this cell to be in. It can be either a number (zero-based) or an offset. See L for more info on offset-based numbering. =item * REF Adds the current cell to the a list of cells that can be backreferenced. This is useful when the current cell needs to be referenced by a formula. See L and L. =item * WIDTH Sets the width of the column the cell is in. The last setting for a given column will win out. =item * TYPE This allows you to specify what write_*() method will be used. The default is to call write() and let L make the right call. However, you may wish to override it. L will not do any form of validation on what you provide. You are assumed to know what you're doing. The legal types (taken from L) are: =item * COMMENT Add a comment to the cell =over 4 =item * blank =item * formula =item * number =item * string =item * url =item * date_time =back other write_* methods as defined defined L would be integrated by request =back =head1 CHILDREN L =head1 EFFECTS This will consume one column in the current row. =head1 DEPENDENCIES None =head1 USAGE Some other text here Some text here In the above example, four cells are written out. The first two have text hard-coded. The second two have variables. The third and fourth items have another thing that should be noted. If you have text where you want a variable in the middle, you have to use the latter form. Variables within parameters are the entire parameter's value. Please see L for what constitutes a legal formula. =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO L, L, L =cut Excel-Template-0.34/lib/Excel/Template/Element/Formula.pm000644 000765 000024 00000002625 11406453233 023121 0ustar00rbostaff000000 000000 package Excel::Template::Element::Formula; use strict; BEGIN { use vars qw(@ISA); @ISA = qw(Excel::Template::Element::Cell); use Excel::Template::Element::Cell; } sub render { $_[0]->SUPER::render( $_[1], 'write_formula' ) } #{ # my $self = shift; # my ($context) = @_; # # return $self->SUPER::render( $context, 'write_formula' ); #} 1; __END__ =head1 NAME Excel::Template::Element::Formula - Excel::Template::Element::Formula =head1 PURPOSE To write formulas to the worksheet =head1 NODE NAME FORMULA =head1 INHERITANCE Excel::Template::Element::Cell =head1 ATTRIBUTES All attributes a CELL can have, a FORMULA can have, including the ability to be referenced using the 'ref' attribute. =head1 CHILDREN None =head1 EFFECTS This will consume one column on the current row. =head1 DEPENDENCIES None =head1 USAGE =SUM(A1:A5) =(A1 + ) In the above example, four formulas are written out. The first two have the formula hard-coded. The second two have variables. The third and fourth items have another thing that should be noted. If you have a formula where you want a variable in the middle, you have to use the latter form. Variables within parameters are the entire parameter's value. =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO CELL =cut Excel-Template-0.34/lib/Excel/Template/Element/FreezePanes.pm000644 000765 000024 00000001613 11406453233 023717 0ustar00rbostaff000000 000000 package Excel::Template::Element::FreezePanes; use strict; BEGIN { use vars qw(@ISA); @ISA = qw(Excel::Template::Element); use Excel::Template::Element; } sub render { my $self = shift; my ($context) = @_; my ($row, $col) = map { $context->get( $self, $_ ) } qw( ROW COL ); $context->active_worksheet->freeze_panes( $row, $col ); return 1; } 1; __END__ =head1 NAME Excel::Template::Element::FreezePanes - Excel::Template::Element::FreezePanes =head1 PURPOSE To insert an image into the worksheet =head1 NODE NAME FREEZEPANES =head1 INHERITANCE L =head1 EFFECTS This will not conume any columns or rows. It is a zero-width assertion. =head1 DEPENDENCIES None =head1 USAGE This will do a Freeze Pane at the current cell. =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO Nothing =cut Excel-Template-0.34/lib/Excel/Template/Element/Image.pm000644 000765 000024 00000003470 11406453233 022535 0ustar00rbostaff000000 000000 package Excel::Template::Element::Image; use strict; BEGIN { use vars qw(@ISA); @ISA = qw(Excel::Template::Element); use Excel::Template::Element; } sub render { my $self = shift; my ($context) = @_; my ($row, $col, $path, $offset, $scale) = map { $context->get($self, $_) } qw( ROW COL PATH OFFSET SCALE ); my @offsets = (0,0); if ( $offset =~ /^\s*([\d.]+)\s*,\s*([\d.]+)/ ) { @offsets = ($1,$2); } my @scales = (0,0); if ( $scale =~ /^\s*([\d.]+)\s*,\s*([\d.]+)/ ) { @scales = ($1,$2); } $context->active_worksheet->insert_bitmap( $row, $col, $path, @offsets, @scales, ); return 1; } sub deltas { return { COL => +1, }; } 1; __END__ =head1 NAME Excel::Template::Element::Image - Excel::Template::Element::Image =head1 PURPOSE To insert an image into the worksheet =head1 NODE NAME IMAGE =head1 INHERITANCE L =head1 EFFECTS This will consume one column in the current row. =head1 DEPENDENCIES None =head1 USAGE Please see L for more information about the offset and scaling options as well as any other restrictions that might be in place. This node does B perform any sort of validation upon your parameters. You are assumed to know what you are doing. Note that the offset and scaling values are "X,Y". You I provide both values, even if the Y value is 0. If you provide a 0 value for either scaling option, L will default that to 1. =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO Nothing =cut Excel-Template-0.34/lib/Excel/Template/Element/MergeRange.pm000644 000765 000120 00000004217 11747261053 023516 0ustar00rboadmin000000 000000 package Excel::Template::Element::MergeRange; use strict; BEGIN { use vars qw(@ISA); @ISA = qw(Excel::Template::Element::Cell); use Excel::Template::Element::Cell; use Excel::Template::Element::Range; } sub render { my $self = shift; my ($context) = @_; my $ref_name = $context->resolve($self, 'REF'); my @refs = $context->get_all_references( $ref_name ); (@refs) || die "You must specify a ref for MERGE_RANGE"; my $range = Excel::Template::Element::Range->_join_refs(@refs); # NOTE: # we need to copy the current format # because Spreadsheet::WriteExcel will # mark any format used in a merged cell # as being specifically for a merged cell # and therefore not usable elsewhere. my $old_format = $context->active_format; my %values; while ( my ($k, $v) = each %$self ) { $values{$k} = $context->resolve( $self, $k ); } # force is_merged on here to differentiate the formats $values{is_merged} = 1; my $format = $context->format_object->copy( $context, $old_format, %values, ); $context->active_format($format); $context->active_worksheet->merge_range( $range, $self->_get_text($context), $format, ); $context->active_format($old_format); return 1; } 1; __END__ =head1 NAME Excel::Template::Element::MergeRange - Excel::Template::Element::MergeRange =head1 PURPOSE To merge a range of cells in a spreadsheet =head1 NODE NAME MERGE_RANGE =head1 INHERITANCE L =head1 EFFECTS This will merge a range of cells. =head1 DEPENDENCIES None =head1 USAGE Text to insert into merged range Or a cross rows: Text to insert into merged range =head1 AUTHOR Stevan Little (stevan.little@iinteractive.com) =head1 SEE ALSO Nothing =cut Excel-Template-0.34/lib/Excel/Template/Element/Range.pm000755 000765 000120 00000003517 11747252337 022550 0ustar00rboadmin000000 000000 package Excel::Template::Element::Range; use strict; use Spreadsheet::WriteExcel::Utility; BEGIN { use vars qw(@ISA); @ISA = qw(Excel::Template::Element); use Excel::Template::Element; } sub min { $_[0] < $_[1] ? $_[0] : $_[1] } sub max { $_[0] > $_[1] ? $_[0] : $_[1] } sub resolve { my $self = shift; my ($context) = @_; my $ref_name = $context->resolve($self, 'REF'); my @refs = $context->get_all_references( $ref_name ); return '' unless @refs; return $self->_join_refs(@refs); } sub _join_refs { my ($self, @refs) = @_; my ($top, $left, $bottom, $right) = ( $refs[0][0], $refs[0][1] ) x 2; shift @refs; foreach my $ref ( @refs ) { $top = min( $top, $ref->[0]); $bottom = max( $bottom, $ref->[0]); $left = min( $left, $ref->[1]); $right = max( $right, $ref->[1]); } return join( ':', xl_rowcol_to_cell($top, $left), xl_rowcol_to_cell($bottom, $right) ); } 1; __END__ =head1 NAME Excel::Template::Element::Range - Excel::Template::Element::Range =head1 PURPOSE Returns a range of cell locations (i.e. B2:C2) that contains all calls using this reference. To return the location of the last cell, use BACKREF. =head1 NODE NAME RANGE =head1 INHERITANCE Excel::Template::Element =head1 ATTRIBUTES =over 4 =item * REF This is the name of the reference to look up. =back =head1 CHILDREN None =head1 EFFECTS None =head1 DEPENDENCIES This will only be used within CELL tags. =head1 USAGE In the example... =SUM() The formula in row 2 would be =SUM(B1:C1). =head1 AUTHOR Rob Kinyon (rkinyon@columbus.rr.com) =head1 SEE ALSO CELL, BACKREF =cut Excel-Template-0.34/lib/Excel/Template/Element/Var.pm000644 000765 000120 00000002006 11747252337 022231 0ustar00rboadmin000000 000000 package Excel::Template::Element::Var; use strict; BEGIN { use vars qw(@ISA); @ISA = qw(Excel::Template::Element); use Excel::Template::Element; } sub resolve { ($_[1])->param($_[1]->resolve($_[0], 'NAME')) } 1; __END__ =head1 NAME Excel::Template::Element::Var - Excel::Template::Element::Var =head1 PURPOSE To provide parameter substitution. =head1 NODE NAME VAR =head1 INHERITANCE Excel::Template::Element =head1 ATTRIBUTES =over 4 =item * NAME This is the name of the parameter to substitute here. =back =head1 CHILDREN None =head1 EFFECTS None =head1 DEPENDENCIES This will only be used within CELL tags. =head1 USAGE This is used exactly like HTML::Template's TMPL_VAR. There is one exception - since you can have variable names inside the parameters, you can do something like: Where the actual name to be substituted is, itself, a parameter. =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO CELL =cut Excel-Template-0.34/lib/Excel/Template/Container/Bold.pm000644 000765 000024 00000001672 11406453233 022726 0ustar00rbostaff000000 000000 package Excel::Template::Container::Bold; use strict; BEGIN { use vars qw(@ISA); @ISA = qw( Excel::Template::Container::Format ); use Excel::Template::Container::Format; } sub new { my $class = shift; my $self = $class->SUPER::new(@_); $self->{BOLD} = 1; return $self; } 1; __END__ =head1 NAME Excel::Template::Container::Bold - Excel::Template::Container::Bold =head1 PURPOSE To format all children in bold =head1 NODE NAME BOLD =head1 INHERITANCE Excel::Template::Container::Format =head1 ATTRIBUTES None =head1 CHILDREN None =head1 EFFECTS None =head1 DEPENDENCIES None =head1 USAGE ... Children here In the above example, the children will be displayed (if they are displaying elements) in a bold format. All other formatting will remain the same and the "bold"-ness will end at the end tag. =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO FORMAT =cut Excel-Template-0.34/lib/Excel/Template/Container/Conditional.pm000644 000765 000024 00000010360 11406513115 024277 0ustar00rbostaff000000 000000 package Excel::Template::Container::Conditional; #GGG Convert to be a special case of ? use strict; BEGIN { use vars qw(@ISA); @ISA = qw(Excel::Template::Container); use Excel::Template::Container; } my %isOp = ( '=' => '==', (map { $_ => $_ } ( '>', '<', '==', '!=', '>=', '<=' )), (map { $_ => $_ } ( 'gt', 'lt', 'eq', 'ne', 'ge', 'le' )), ); sub _conditional_passes { my $self = shift; my ($context) = @_; my $name = $context->get($self, 'NAME'); return 0 unless $name =~ /\S/; my $val = $context->param($name); $val = @{$val} while ref $val eq 'ARRAY'; $val = ${$val} while ref $val eq 'SCALAR'; my $value = $context->get($self, 'VALUE'); if (defined $value) { my $op = $context->get($self, 'OP'); $op = defined $op && exists $isOp{$op} ? $isOp{$op} : '=='; my $res; for ($op) { /^>$/ && do { $res = ($val > $value); last }; /^<$/ && do { $res = ($val < $value); last }; /^==$/ && do { $res = ($val == $value); last }; /^!=$/ && do { $res = ($val != $value); last }; /^>=$/ && do { $res = ($val >= $value); last }; /^<=$/ && do { $res = ($val <= $value); last }; /^gt$/ && do { $res = ($val gt $value); last }; /^lt$/ && do { $res = ($val lt $value); last }; /^eq$/ && do { $res = ($val eq $value); last }; /^ne$/ && do { $res = ($val ne $value); last }; /^ge$/ && do { $res = ($val ge $value); last }; /^le$/ && do { $res = ($val le $value); last }; die "Unknown operator '$op' in conditional resolve", $/; } return $res && 1; } my $istrue = $val && 1; my $is = uc($context->get($self, 'IS') || 'TRUE'); if ($is eq 'TRUE') { return 0 unless $istrue; } else { warn "Conditional 'is' value was [$is], defaulting to 'FALSE'" . $/ if $is ne 'FALSE' && $^W; return 0 if $istrue; } return 1; } sub render { my $self = shift; my ($context) = @_; return 1 unless $self->_conditional_passes($context); return $self->iterate_over_children($context); } #sub max_of #{ # my $self = shift; # my ($context, $attr) = @_; # # return 0 unless $self->_conditional_passes($context); # # return $self->SUPER::max_of($context, $attr); #} # #sub total_of #{ # my $self = shift; # my ($context, $attr) = @_; # # return 0 unless $self->_conditional_passes($context); # # return $self->SUPER::total_of($context, $attr); #} 1; __END__ =head1 NAME Excel::Template::Container::Conditional - Excel::Template::Container::Conditional =head1 PURPOSE To provide conditional execution of children nodes =head1 NODE NAME IF =head1 INHERITANCE L =head1 ATTRIBUTES =over 4 =item * NAME This is the name of the parameter to test. It is resolved like any other parameter name. (q.v. L for more info.) =item * VALUE If VALUE is set, then a comparison operation is done. The value of NAME is compared to VALUE using the value of OP. =item * OP If VALUE is set, then this is checked. If it isn't present, then '==' (numeric equality) is assumed. OP must be one of Perl the numeric comparison operators or the string comparison operators. All 6 of each kind is supported. B: If you want to use < or <=, you must instead use < or <=. This is to make sure it will parse with L. You should not need to use > or >= instead of > and >=, respectively. =item * IS If VALUE is not set, then IS is checked. IS is allowed to be either "TRUE" or "FALSE". The boolean value of NAME is checked against IS. =back =head1 CHILDREN None =head1 EFFECTS None =head1 DEPENDENCIES None =head1 USAGE ... Children here In the above example, the children will be executed if the value of __ODD__ (which is set by the L node) is false. So, for all even iterations. =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO L, L =cut Excel-Template-0.34/lib/Excel/Template/Container/Format.pm000644 000765 000120 00000010646 11747252337 023273 0ustar00rboadmin000000 000000 package Excel::Template::Container::Format; use strict; BEGIN { use vars qw(@ISA); @ISA = qw( Excel::Template::Container ); use Excel::Template::Container; } use Excel::Template::Format; sub render { my $self = shift; my ($context) = @_; my $old_format = $context->active_format; my %values; while ( my ($k, $v) = each %$self ) { $values{$k} = $context->resolve( $self, $k ); } my $format = $context->format_object->copy( $context, $old_format, %values, ); $context->active_format($format); my $child_success = $self->iterate_over_children($context); $context->active_format($old_format); return $child_success; } 1; __END__ =head1 NAME Excel::Template::Container::Format - Excel::Template::Container::Format =head1 PURPOSE To format all children according to the parameters =head1 NODE NAME FORMAT =head1 INHERITANCE Excel::Template::Container =head1 ATTRIBUTES Boolean attributes should be set to 1, 0, true, or false. Color values can be the color name or the color index. See L =over 4 =item * align Set to either left, center, right, fill, or justify. Default is left. See also valign. =item * bg_color Set to a color value. Default is none. =item * bold This will set bold to on or off, depending on the boolean value. =item * border Set the border for all for edges of a cell. Also see bottom, top, left, and right. Valid values are 0 - 7. See L =item * border_color Sets the color value for the border. See also border, top_color, bottom_color, left_color and right_color. =item * bottom See border. =item * bottom_color See border_color =item * color This will set the color of the text, depending on color value. Default is black. =item * fg_color Set to a color value. This color will be used in foreground of some patterns. See color to change the color of text. Also see bg_color and pattern. =item * font This will sent the font face. Default is Arial. =item * font_outline This will set font_outline to on or off, depending on the boolean value. (q.v. OUTLINE tag) =item * font_shadow This will set font_shadow to on or off, depending on the boolean value. (q.v. SHADOW tag). This only applies to Excel for Macintosh. =item * font_strikeout This will set font_strikeout to on or off, depending on the boolean value. (q.v. STRIKEOUT tag) =item * hidden This will set whether the cell is hidden to on or off, depending on the boolean value. =item * indent Set the indentation level for a cell. Positive integers are allowed. =item * italic This will set italic to on or off, depending on the boolean value. (q.v. ITALIC tag) =item * left See border. =item * left_color See border_color. =item * num_format Set to the index of one of Excel's built-in number formats. See L =item * pattern Set to an integer, 0 - 18. Sets the background fill pattern of a ell. Default is 1, solid. =item * right See border. =item * right_color See border color. =item * rotation Set the rotation of the text in a cell. The rotation can be any angle in the range -90 to 90 degrees. The angle 270 is also supported. This indicates text where the letters run from top to bottom. =item * shrink A boolean value. If true, text will shrink to fit a cell. =item * size This will set the size of the font. Default is 10. Unless a row height is specifically set, the row will grow taller as necessary. =item * text_justlast A boolean value to justify the last line. Only applies to Far Eastern versions of Excel. =item * text_wrap A boolean value. When set to true, text will wrap in a cell instead of crossing over into empty cells. If the row height is not set, the row will grow taller to accommodate the wrapping text. =item * top See border. =item * top_color See border_color =item * valign Set to top, vcenter, bottom, or vjustify. Default is vcenter. See also align. =back =head1 CHILDREN None =head1 EFFECTS None =head1 DEPENDENCIES None =head1 USAGE ... Children here In the above example, the children will be displayed (if they are displaying elements) in a bold format. All other formatting will remain the same and the "bold"-ness will end at the end tag. =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO BOLD, HIDDEN, ITALIC, OUTLINE, SHADOW, STRIKEOUT =cut Excel-Template-0.34/lib/Excel/Template/Container/Hidden.pm000644 000765 000024 00000002133 11406453233 023232 0ustar00rbostaff000000 000000 package Excel::Template::Container::Hidden; use strict; BEGIN { use vars qw(@ISA); @ISA = qw( Excel::Template::Container::Format ); use Excel::Template::Container::Format; } sub new { my $class = shift; my $self = $class->SUPER::new(@_); $self->{HIDDEN} = 1; return $self; } 1; __END__ =head1 NAME Excel::Template::Container::Hidden - Excel::Template::Container::Hidden =head1 PURPOSE To format all children in hidden =head1 NODE NAME HIDDEN =head1 INHERITANCE Excel::Template::Container::Format =head1 ATTRIBUTES None =head1 CHILDREN None =head1 EFFECTS None =head1 DEPENDENCIES You must have protected the worksheet containing any cells that are affected by this format. Otherwise, this node will have no effect. =head1 USAGE ... Children here In the above example, the children will be displayed (if they are displaying elements) in a hidden format. All other formatting will remain the same and the "hidden"-ness will end at the end tag. =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO WORKSHEET, FORMAT =cut Excel-Template-0.34/lib/Excel/Template/Container/Italic.pm000644 000765 000024 00000001716 11406453233 023252 0ustar00rbostaff000000 000000 package Excel::Template::Container::Italic; use strict; BEGIN { use vars qw(@ISA); @ISA = qw( Excel::Template::Container::Format ); use Excel::Template::Container::Format; } sub new { my $class = shift; my $self = $class->SUPER::new(@_); $self->{ITALIC} = 1; return $self; } 1; __END__ =head1 NAME Excel::Template::Container::Italic - Excel::Template::Container::Italic =head1 PURPOSE To format all children in italic =head1 NODE NAME ITALIC =head1 INHERITANCE Excel::Template::Container::Format =head1 ATTRIBUTES None =head1 CHILDREN None =head1 EFFECTS None =head1 DEPENDENCIES None =head1 USAGE ... Children here In the above example, the children will be displayed (if they are displaying elements) in a italic format. All other formatting will remain the same and the "italic"-ness will end at the end tag. =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO FORMAT =cut Excel-Template-0.34/lib/Excel/Template/Container/KeepLeadingZeros.pm000644 000765 000024 00000003311 11406453233 025231 0ustar00rbostaff000000 000000 package Excel::Template::Container::KeepLeadingZeros; use strict; BEGIN { use vars qw(@ISA); @ISA = qw(Excel::Template::Container); use Excel::Template::Container; } sub render { my $self = shift; my ($context) = @_; my $worksheet = $context->active_worksheet; $worksheet ? $worksheet->keep_leading_zeros( 1 ) : $context->mark( keep_leading_zeros => 1 ); my $rv = $self->SUPER::render($context); $worksheet ? $worksheet->keep_leading_zeros( 0 ) : $context->mark( keep_leading_zeros => 0 ); return $rv; } 1; __END__ =head1 NAME Excel::Template::Container::KeepLeadingZeros - Excel::Template::Container::KeepLeadingZeros =head1 PURPOSE To set the keep_leading_zeros flag for the surrounding worksheet or any worksheets that might be contained within this node. =head1 NODE NAME KEEP_LEADING_ZEROS =head1 INHERITANCE L =head1 ATTRIBUTES None =head1 CHILDREN None =head1 EFFECTS Alters how leading zeros are interpreted by L. =head1 DEPENDENCIES None =head1 USAGE ... Cells here will NOT have leading-zeros preserved ... Cells here will have leading-zeros preserved ... Cells here will NOT have leading-zeros preserved ... Cells here will have leading-zeros preserved ... Cells here will have leading-zeros preserved =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO L, L =cut Excel-Template-0.34/lib/Excel/Template/Container/Locked.pm000644 000765 000024 00000002133 11406453233 023240 0ustar00rbostaff000000 000000 package Excel::Template::Container::Locked; use strict; BEGIN { use vars qw(@ISA); @ISA = qw( Excel::Template::Container::Format ); use Excel::Template::Container::Format; } sub new { my $class = shift; my $self = $class->SUPER::new(@_); $self->{LOCKED} = 1; return $self; } 1; __END__ =head1 NAME Excel::Template::Container::Locked - Excel::Template::Container::Locked =head1 PURPOSE To format all children in locked =head1 NODE NAME LOCKED =head1 INHERITANCE Excel::Template::Container::Format =head1 ATTRIBUTES None =head1 CHILDREN None =head1 EFFECTS None =head1 DEPENDENCIES You must have protected the worksheet containing any cells that are affected by this format. Otherwise, this node will have no effect. =head1 USAGE ... Children here In the above example, the children will be displayed (if they are displaying elements) in a locked format. All other formatting will remain the same and the "locked"-ness will end at the end tag. =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO WORKSHEET, FORMAT =cut Excel-Template-0.34/lib/Excel/Template/Container/Loop.pm000644 000765 000120 00000007230 11747252337 022747 0ustar00rboadmin000000 000000 package Excel::Template::Container::Loop; use strict; BEGIN { use vars qw(@ISA); @ISA = qw(Excel::Template::Container); use Excel::Template::Container; } sub new { my $class = shift; my $self = $class->SUPER::new(@_); if (exists $self->{MAXITERS} && $self->{MAXITERS} < 1) { die " MAXITERS must be greater than or equal to 1", $/; } else { $self->{MAXITERS} = 0; } return $self; } sub _make_iterator { my $self = shift; my ($context) = @_; return Excel::Template::Factory->_create('ITERATOR', NAME => $context->get($self, 'NAME'), MAXITERS => $context->get($self, 'MAXITERS'), CONTEXT => $context, ); } sub render { my $self = shift; my ($context) = @_; unless ($self->{ITERATOR} && $self->{ITERATOR}->more_params) { $self->{ITERATOR} = $self->_make_iterator($context); } my $iterator = $self->{ITERATOR}; $iterator->enter_scope; while ($iterator->can_continue) { $iterator->next; $self->iterate_over_children($context); # It doesn't seem that iterate_over_children() can ever fail, because # I'm not sure that render() can return false. In PDF::Template, where # this module got most of its code, render() can certainly return false, # in the case of page-breaks. I left the code in because it didn't seem # like it would hurt. #unless ($self->iterate_over_children($context)) #{ # $iterator->back_up; # last; #} } $iterator->exit_scope; return 0 if $iterator->more_params; return 1; } # These methods are used in PDF::Template to calculate pagebreaks. I'm not sure # if they will ever be needed in Excel::Template. #sub total_of #{ # my $self = shift; # my ($context, $attr) = @_; # # my $iterator = $self->_make_iterator($context); # # my $total = 0; # # $iterator->enter_scope; # while ($iterator->can_continue) # { # $iterator->next; # $total += $self->SUPER::total_of($context, $attr); # } # $iterator->exit_scope; # # return $total; #} # #sub max_of #{ # my $self = shift; # my ($context, $attr) = @_; # # my $iterator = $self->_make_iterator($context); # # my $max = $context->get($self, $attr); # # $iterator->enter_scope; # while ($iterator->can_continue) # { # $iterator->next; # my $v = $self->SUPER::max_of($context, $attr); # # $max = $v if $max < $v; # } # $iterator->exit_scope; # # return $max; #} 1; __END__ =head1 NAME Excel::Template::Container::Loop - Excel::Template::Container::Loop =head1 PURPOSE To provide looping =head1 NODE NAME LOOP =head1 INHERITANCE Excel::Template::Container =head1 ATTRIBUTES =over 4 =item * NAME This is the name of the loop. It's used to identify within the parameter set what variables to expose to the children nodes each iteration. =back =head1 CHILDREN None =head1 EFFECTS None =head1 DEPENDENCIES None =head1 USAGE ... Children here ... In the above example, the children nodes would have access to the LOOPY array of hashes as parameters. Each iteration through the array would expose a different hash of parameters to the children. These loops work just like HTML::Template's loops. (I promise I'll give more info here!) There is one difference - I prefer using Perl-like scoping, so accessing of variables outside the LOOP scope from within is perfectly acceptable. You can also hide outside variables with inner values, if you desire, just like Perl. =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO =cut Excel-Template-0.34/lib/Excel/Template/Container/Outline.pm000644 000765 000024 00000001735 11406453233 023465 0ustar00rbostaff000000 000000 package Excel::Template::Container::Outline; use strict; BEGIN { use vars qw(@ISA); @ISA = qw( Excel::Template::Container::Format ); use Excel::Template::Container::Format; } sub new { my $class = shift; my $self = $class->SUPER::new(@_); $self->{FONT_OUTLINE} = 1; return $self; } 1; __END__ =head1 NAME Excel::Template::Container::Outline - Excel::Template::Container::Outline =head1 PURPOSE To format all children in outline =head1 NODE NAME OUTLINE =head1 INHERITANCE Excel::Template::Container::Format =head1 ATTRIBUTES None =head1 CHILDREN None =head1 EFFECTS None =head1 DEPENDENCIES None =head1 USAGE ... Children here In the above example, the children will be displayed (if they are displaying elements) in a outline format. All other formatting will remain the same and the "outline"-ness will end at the end tag. =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO FORMAT =cut Excel-Template-0.34/lib/Excel/Template/Container/Row.pm000644 000765 000024 00000002616 11406453233 022614 0ustar00rbostaff000000 000000 package Excel::Template::Container::Row; use strict; BEGIN { use vars qw(@ISA); @ISA = qw(Excel::Template::Container); use Excel::Template::Container; } sub render { my $self = shift; my ($context) = @_; $context->{COL} = 0; # Apply the height to the current row if (my $height = $context->get($self, 'HEIGHT')) { $height =~ s/\D//g; $height *= 1; if ($height > 0) { $context->active_worksheet->set_row( $context->get( $self, 'ROW' ), $height, ); } } return $self->SUPER::render($context); } sub deltas { return { ROW => +1, }; } 1; __END__ =head1 NAME Excel::Template::Container::Row - Excel::Template::Container::Row =head1 PURPOSE To provide a row context for CELL tags =head1 NODE NAME ROW =head1 INHERITANCE Excel::Template::Container =head1 ATTRIBUTES =over 4 =item * HEIGHT Sets the height of the row. The last setting for a given row will win out. =back =head1 CHILDREN None =head1 EFFECTS Each ROW tag will consume one row of the workbook. When the ROW tag starts, it will set the COL value to 0. =head1 DEPENDENCIES None =head1 USAGE ... Children here Generally, you will have CELL and/or FORMULA tags within a ROW. =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO CELL, FORMULA =cut Excel-Template-0.34/lib/Excel/Template/Container/Scope.pm000644 000765 000120 00000001757 11747252337 023117 0ustar00rboadmin000000 000000 package Excel::Template::Container::Scope; use strict; BEGIN { use vars qw(@ISA); @ISA = qw(Excel::Template::Container); use Excel::Template::Container; } # This is used as a placeholder for scoping values across any number # of children. It does nothing on its own. 1; __END__ =head1 NAME Excel::Template::Container::Scope - Excel::Template::Container::Scope =head1 PURPOSE To provide scoping of parameters for children =head1 NODE NAME SCOPE =head1 INHERITANCE Excel::Template::Container =head1 ATTRIBUTES None =head1 CHILDREN None =head1 EFFECTS None =head1 DEPENDENCIES None =head1 USAGE ... Children here ... In the above example, the children would all have access to the parameters param1 and param2. This is useful if you have a section of your template that all has the same set of parameter values, but don't have a common parent. =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO =cut Excel-Template-0.34/lib/Excel/Template/Container/Shadow.pm000644 000765 000024 00000001723 11406453233 023270 0ustar00rbostaff000000 000000 package Excel::Template::Container::Shadow; use strict; BEGIN { use vars qw(@ISA); @ISA = qw( Excel::Template::Container::Format ); use Excel::Template::Container::Format; } sub new { my $class = shift; my $self = $class->SUPER::new(@_); $self->{FONT_SHADOW} = 1; return $self; } 1; __END__ =head1 NAME Excel::Template::Container::Shadow - Excel::Template::Container::Shadow =head1 PURPOSE To format all children in shadow =head1 NODE NAME SHADOW =head1 INHERITANCE Excel::Template::Container::Format =head1 ATTRIBUTES None =head1 CHILDREN None =head1 EFFECTS None =head1 DEPENDENCIES None =head1 USAGE ... Children here In the above example, the children will be displayed (if they are displaying elements) in a shadow format. All other formatting will remain the same and the "shadow"-ness will end at the end tag. =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO FORMAT =cut Excel-Template-0.34/lib/Excel/Template/Container/Strikeout.pm000644 000765 000024 00000001730 11406453233 024032 0ustar00rbostaff000000 000000 package Excel::Template::Container::Strikeout; use strict; BEGIN { use vars qw(@ISA); @ISA = qw( Excel::Template::Container::Format ); use Excel::Template::Container::Format; } sub new { my $class = shift; my $self = $class->SUPER::new(@_); $self->{FONT_STRIKEOUT} = 1; return $self; } 1; __END__ =head1 NAME Excel::Template::Container::Strikeout - Excel::Template::Container::Strikeout =head1 PURPOSE To format all children in bold =head1 NODE NAME STRIKEOUT =head1 INHERITANCE Excel::Template::Container::Format =head1 ATTRIBUTES None =head1 CHILDREN None =head1 EFFECTS None =head1 DEPENDENCIES None =head1 USAGE ... Children here In the above example, the children will be displayed (if they are displaying elements) in a bold format. All other formatting will remain the same and the "bold"-ness will end at the end tag. =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO FORMAT =cut Excel-Template-0.34/lib/Excel/Template/Container/Workbook.pm000644 000765 000024 00000001327 11406453233 023640 0ustar00rbostaff000000 000000 package Excel::Template::Container::Workbook; use strict; BEGIN { use vars qw(@ISA); @ISA = qw( Excel::Template::Container ); use Excel::Template::Container; } 1; __END__ =head1 NAME Excel::Template::Container::Workbook - Excel::Template::Container::Workbook =head1 PURPOSE The root node =head1 NODE NAME WORKBOOK =head1 INHERITANCE Excel::Template::Container =head1 ATTRIBUTES Currently, none. There will be attributes added here, regarding how the workbook as a whole will behave. =head1 CHILDREN None =head1 EFFECTS None =head1 DEPENDENCIES None =head1 USAGE ... Children here =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO Nothing =cut Excel-Template-0.34/lib/Excel/Template/Container/Worksheet.pm000644 000765 000024 00000007631 11406527476 024035 0ustar00rbostaff000000 000000 package Excel::Template::Container::Worksheet; use strict; BEGIN { use vars qw(@ISA); @ISA = qw(Excel::Template::Container); use Excel::Template::Container; } sub exit_scope { $_[1]->active_worksheet(undef) } sub render { my $self = shift; my ($context) = @_; my $worksheet = $context->new_worksheet($self); my $password = $context->get( $self, 'PROTECT' ); if ( defined $password ) { $worksheet->protect($password); } $worksheet->keep_leading_zeros(1) if $context->mark('keep_leading_zeros'); if ( $context->get( $self, 'LANDSCAPE' ) && !$self->{PORTRAIT} ) { $worksheet->set_landscape; } elsif ( $context->get( $self, 'PORTRAIT' ) ) { $worksheet->set_portrait; } my $hide_gridlines = $context->get( $self, 'HIDE_GRIDLINES'); if ( defined $hide_gridlines ) { $worksheet->hide_gridlines( $hide_gridlines ); } my $autofilter = $context->get( $self, "AUTOFILTER"); if ( defined $autofilter ) { if ($autofilter =~ /^\D/) { $worksheet->autofilter($autofilter); }else{ $autofilter =~ s/ //g; my ($row1, $col1, $row2, $col2) = split(',',$autofilter); $worksheet->autofilter($row1, $col1, $row2, $col2); } } return $self->SUPER::render($context); } 1; __END__ =head1 NAME Excel::Template::Container::Worksheet - Excel::Template::Container::Worksheet =head1 PURPOSE To provide a new worksheet. =head1 NODE NAME WORKSHEET =head1 INHERITANCE Excel::Template::Container =head1 ATTRIBUTES =over 4 =item * NAME This is the name of the worksheet to be added. =item * PROTECT If the attribute exists, it will mark the worksheet as being protected. Whatever value is set will be used as the password. This activates the HIDDEN and LOCKED nodes. =item * KEEP_LEADING_ZEROS This will change the behavior of the worksheet to preserve leading zeros. =item * HIDE_GRIDLINE his method is used to hide the gridlines on the screen and printed page. Gridlines are the lines that divide the cells on a worksheet. Screen and printed gridlines are turned on by default in an Excel worksheet. If you have defined your own cell borders you may wish to hide the default gridlines. $worksheet->hide_gridlines(); The following values of $option are valid: 0 : Don't hide gridlines 1 : Hide printed gridlines only 2 : Hide screen and printed gridlines If you don't supply an argument or use undef the default option is 1, i.e. only the printed gridlines are hidden. =item * LANDSCAPE This will set the worksheet's orientation to landscape. =item * PORTRAIT This will set the worksheet's orientation to portrait. While this is the default, it's useful to override the default at times. For example, in the following situation: ... ... ... In that example, the first and third worksheets will be landscape (inheriting it from the workbook node), but the second worksheet will be portrait. =item * AUTOFILTER With these attribute, you can add the autofilter to a worksheet. An autofilter is a way of adding drop down lists to the headers of a 2D range of worksheet data. This is turn allow users to filter the data based on simple criteria so that some data is shown and some is hidden. Example to add an autofilter to a worksheet: =back =head1 CHILDREN None =head1 EFFECTS None =head1 DEPENDENCIES None =head1 USAGE ... Children here In the above example, the children will be executed in the context of the "My Taxes" worksheet. =head1 AUTHOR Rob Kinyon (rob.kinyon@gmail.com) =head1 SEE ALSO ROW, CELL, FORMULA =cut Excel-Template-0.34/inc/Module/000755 000765 000120 00000000000 11747312641 016164 5ustar00rboadmin000000 000000 Excel-Template-0.34/inc/Module/AutoInstall.pm000644 000765 000120 00000054231 11747312612 020764 0ustar00rboadmin000000 000000 #line 1 package Module::AutoInstall; use strict; use Cwd (); use ExtUtils::MakeMaker (); use vars qw{$VERSION}; BEGIN { $VERSION = '1.03'; } # special map on pre-defined feature sets my %FeatureMap = ( '' => 'Core Features', # XXX: deprecated '-core' => 'Core Features', ); # various lexical flags my ( @Missing, @Existing, %DisabledTests, $UnderCPAN, $HasCPANPLUS ); my ( $Config, $CheckOnly, $SkipInstall, $AcceptDefault, $TestOnly, $AllDeps ); my ( $PostambleActions, $PostambleUsed ); # See if it's a testing or non-interactive session _accept_default( $ENV{AUTOMATED_TESTING} or ! -t STDIN ); _init(); sub _accept_default { $AcceptDefault = shift; } sub missing_modules { return @Missing; } sub do_install { __PACKAGE__->install( [ $Config ? ( UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} ) : () ], @Missing, ); } # initialize various flags, and/or perform install sub _init { foreach my $arg ( @ARGV, split( /[\s\t]+/, $ENV{PERL_AUTOINSTALL} || $ENV{PERL_EXTUTILS_AUTOINSTALL} || '' ) ) { if ( $arg =~ /^--config=(.*)$/ ) { $Config = [ split( ',', $1 ) ]; } elsif ( $arg =~ /^--installdeps=(.*)$/ ) { __PACKAGE__->install( $Config, @Missing = split( /,/, $1 ) ); exit 0; } elsif ( $arg =~ /^--default(?:deps)?$/ ) { $AcceptDefault = 1; } elsif ( $arg =~ /^--check(?:deps)?$/ ) { $CheckOnly = 1; } elsif ( $arg =~ /^--skip(?:deps)?$/ ) { $SkipInstall = 1; } elsif ( $arg =~ /^--test(?:only)?$/ ) { $TestOnly = 1; } elsif ( $arg =~ /^--all(?:deps)?$/ ) { $AllDeps = 1; } } } # overrides MakeMaker's prompt() to automatically accept the default choice sub _prompt { goto &ExtUtils::MakeMaker::prompt unless $AcceptDefault; my ( $prompt, $default ) = @_; my $y = ( $default =~ /^[Yy]/ ); print $prompt, ' [', ( $y ? 'Y' : 'y' ), '/', ( $y ? 'n' : 'N' ), '] '; print "$default\n"; return $default; } # the workhorse sub import { my $class = shift; my @args = @_ or return; my $core_all; print "*** $class version " . $class->VERSION . "\n"; print "*** Checking for Perl dependencies...\n"; my $cwd = Cwd::cwd(); $Config = []; my $maxlen = length( ( sort { length($b) <=> length($a) } grep { /^[^\-]/ } map { ref($_) ? ( ( ref($_) eq 'HASH' ) ? keys(%$_) : @{$_} ) : '' } map { +{@args}->{$_} } grep { /^[^\-]/ or /^-core$/i } keys %{ +{@args} } )[0] ); # We want to know if we're under CPAN early to avoid prompting, but # if we aren't going to try and install anything anyway then skip the # check entirely since we don't want to have to load (and configure) # an old CPAN just for a cosmetic message $UnderCPAN = _check_lock(1) unless $SkipInstall; while ( my ( $feature, $modules ) = splice( @args, 0, 2 ) ) { my ( @required, @tests, @skiptests ); my $default = 1; my $conflict = 0; if ( $feature =~ m/^-(\w+)$/ ) { my $option = lc($1); # check for a newer version of myself _update_to( $modules, @_ ) and return if $option eq 'version'; # sets CPAN configuration options $Config = $modules if $option eq 'config'; # promote every features to core status $core_all = ( $modules =~ /^all$/i ) and next if $option eq 'core'; next unless $option eq 'core'; } print "[" . ( $FeatureMap{ lc($feature) } || $feature ) . "]\n"; $modules = [ %{$modules} ] if UNIVERSAL::isa( $modules, 'HASH' ); unshift @$modules, -default => &{ shift(@$modules) } if ( ref( $modules->[0] ) eq 'CODE' ); # XXX: bugward combatability while ( my ( $mod, $arg ) = splice( @$modules, 0, 2 ) ) { if ( $mod =~ m/^-(\w+)$/ ) { my $option = lc($1); $default = $arg if ( $option eq 'default' ); $conflict = $arg if ( $option eq 'conflict' ); @tests = @{$arg} if ( $option eq 'tests' ); @skiptests = @{$arg} if ( $option eq 'skiptests' ); next; } printf( "- %-${maxlen}s ...", $mod ); if ( $arg and $arg =~ /^\D/ ) { unshift @$modules, $arg; $arg = 0; } # XXX: check for conflicts and uninstalls(!) them. my $cur = _load($mod); if (_version_cmp ($cur, $arg) >= 0) { print "loaded. ($cur" . ( $arg ? " >= $arg" : '' ) . ")\n"; push @Existing, $mod => $arg; $DisabledTests{$_} = 1 for map { glob($_) } @skiptests; } else { if (not defined $cur) # indeed missing { print "missing." . ( $arg ? " (would need $arg)" : '' ) . "\n"; } else { # no need to check $arg as _version_cmp ($cur, undef) would satisfy >= above print "too old. ($cur < $arg)\n"; } push @required, $mod => $arg; } } next unless @required; my $mandatory = ( $feature eq '-core' or $core_all ); if ( !$SkipInstall and ( $CheckOnly or ($mandatory and $UnderCPAN) or $AllDeps or _prompt( qq{==> Auto-install the } . ( @required / 2 ) . ( $mandatory ? ' mandatory' : ' optional' ) . qq{ module(s) from CPAN?}, $default ? 'y' : 'n', ) =~ /^[Yy]/ ) ) { push( @Missing, @required ); $DisabledTests{$_} = 1 for map { glob($_) } @skiptests; } elsif ( !$SkipInstall and $default and $mandatory and _prompt( qq{==> The module(s) are mandatory! Really skip?}, 'n', ) =~ /^[Nn]/ ) { push( @Missing, @required ); $DisabledTests{$_} = 1 for map { glob($_) } @skiptests; } else { $DisabledTests{$_} = 1 for map { glob($_) } @tests; } } if ( @Missing and not( $CheckOnly or $UnderCPAN ) ) { require Config; print "*** Dependencies will be installed the next time you type '$Config::Config{make}'.\n"; # make an educated guess of whether we'll need root permission. print " (You may need to do that as the 'root' user.)\n" if eval '$>'; } print "*** $class configuration finished.\n"; chdir $cwd; # import to main:: no strict 'refs'; *{'main::WriteMakefile'} = \&Write if caller(0) eq 'main'; return (@Existing, @Missing); } sub _running_under { my $thing = shift; print <<"END_MESSAGE"; *** Since we're running under ${thing}, I'll just let it take care of the dependency's installation later. END_MESSAGE return 1; } # Check to see if we are currently running under CPAN.pm and/or CPANPLUS; # if we are, then we simply let it taking care of our dependencies sub _check_lock { return unless @Missing or @_; my $cpan_env = $ENV{PERL5_CPAN_IS_RUNNING}; if ($ENV{PERL5_CPANPLUS_IS_RUNNING}) { return _running_under($cpan_env ? 'CPAN' : 'CPANPLUS'); } require CPAN; if ($CPAN::VERSION > '1.89') { if ($cpan_env) { return _running_under('CPAN'); } return; # CPAN.pm new enough, don't need to check further } # last ditch attempt, this -will- configure CPAN, very sorry _load_cpan(1); # force initialize even though it's already loaded # Find the CPAN lock-file my $lock = MM->catfile( $CPAN::Config->{cpan_home}, ".lock" ); return unless -f $lock; # Check the lock local *LOCK; return unless open(LOCK, $lock); if ( ( $^O eq 'MSWin32' ? _under_cpan() : == getppid() ) and ( $CPAN::Config->{prerequisites_policy} || '' ) ne 'ignore' ) { print <<'END_MESSAGE'; *** Since we're running under CPAN, I'll just let it take care of the dependency's installation later. END_MESSAGE return 1; } close LOCK; return; } sub install { my $class = shift; my $i; # used below to strip leading '-' from config keys my @config = ( map { s/^-// if ++$i; $_ } @{ +shift } ); my ( @modules, @installed ); while ( my ( $pkg, $ver ) = splice( @_, 0, 2 ) ) { # grep out those already installed if ( _version_cmp( _load($pkg), $ver ) >= 0 ) { push @installed, $pkg; } else { push @modules, $pkg, $ver; } } return @installed unless @modules; # nothing to do return @installed if _check_lock(); # defer to the CPAN shell print "*** Installing dependencies...\n"; return unless _connected_to('cpan.org'); my %args = @config; my %failed; local *FAILED; if ( $args{do_once} and open( FAILED, '.#autoinstall.failed' ) ) { while () { chomp; $failed{$_}++ } close FAILED; my @newmod; while ( my ( $k, $v ) = splice( @modules, 0, 2 ) ) { push @newmod, ( $k => $v ) unless $failed{$k}; } @modules = @newmod; } if ( _has_cpanplus() and not $ENV{PERL_AUTOINSTALL_PREFER_CPAN} ) { _install_cpanplus( \@modules, \@config ); } else { _install_cpan( \@modules, \@config ); } print "*** $class installation finished.\n"; # see if we have successfully installed them while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) { if ( _version_cmp( _load($pkg), $ver ) >= 0 ) { push @installed, $pkg; } elsif ( $args{do_once} and open( FAILED, '>> .#autoinstall.failed' ) ) { print FAILED "$pkg\n"; } } close FAILED if $args{do_once}; return @installed; } sub _install_cpanplus { my @modules = @{ +shift }; my @config = _cpanplus_config( @{ +shift } ); my $installed = 0; require CPANPLUS::Backend; my $cp = CPANPLUS::Backend->new; my $conf = $cp->configure_object; return unless $conf->can('conf') # 0.05x+ with "sudo" support or _can_write($conf->_get_build('base')); # 0.04x # if we're root, set UNINST=1 to avoid trouble unless user asked for it. my $makeflags = $conf->get_conf('makeflags') || ''; if ( UNIVERSAL::isa( $makeflags, 'HASH' ) ) { # 0.03+ uses a hashref here $makeflags->{UNINST} = 1 unless exists $makeflags->{UNINST}; } else { # 0.02 and below uses a scalar $makeflags = join( ' ', split( ' ', $makeflags ), 'UNINST=1' ) if ( $makeflags !~ /\bUNINST\b/ and eval qq{ $> eq '0' } ); } $conf->set_conf( makeflags => $makeflags ); $conf->set_conf( prereqs => 1 ); while ( my ( $key, $val ) = splice( @config, 0, 2 ) ) { $conf->set_conf( $key, $val ); } my $modtree = $cp->module_tree; while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) { print "*** Installing $pkg...\n"; MY::preinstall( $pkg, $ver ) or next if defined &MY::preinstall; my $success; my $obj = $modtree->{$pkg}; if ( $obj and _version_cmp( $obj->{version}, $ver ) >= 0 ) { my $pathname = $pkg; $pathname =~ s/::/\\W/; foreach my $inc ( grep { m/$pathname.pm/i } keys(%INC) ) { delete $INC{$inc}; } my $rv = $cp->install( modules => [ $obj->{module} ] ); if ( $rv and ( $rv->{ $obj->{module} } or $rv->{ok} ) ) { print "*** $pkg successfully installed.\n"; $success = 1; } else { print "*** $pkg installation cancelled.\n"; $success = 0; } $installed += $success; } else { print << "."; *** Could not find a version $ver or above for $pkg; skipping. . } MY::postinstall( $pkg, $ver, $success ) if defined &MY::postinstall; } return $installed; } sub _cpanplus_config { my @config = (); while ( @_ ) { my ($key, $value) = (shift(), shift()); if ( $key eq 'prerequisites_policy' ) { if ( $value eq 'follow' ) { $value = CPANPLUS::Internals::Constants::PREREQ_INSTALL(); } elsif ( $value eq 'ask' ) { $value = CPANPLUS::Internals::Constants::PREREQ_ASK(); } elsif ( $value eq 'ignore' ) { $value = CPANPLUS::Internals::Constants::PREREQ_IGNORE(); } else { die "*** Cannot convert option $key = '$value' to CPANPLUS version.\n"; } } else { die "*** Cannot convert option $key to CPANPLUS version.\n"; } } return @config; } sub _install_cpan { my @modules = @{ +shift }; my @config = @{ +shift }; my $installed = 0; my %args; _load_cpan(); require Config; if (CPAN->VERSION < 1.80) { # no "sudo" support, probe for writableness return unless _can_write( MM->catfile( $CPAN::Config->{cpan_home}, 'sources' ) ) and _can_write( $Config::Config{sitelib} ); } # if we're root, set UNINST=1 to avoid trouble unless user asked for it. my $makeflags = $CPAN::Config->{make_install_arg} || ''; $CPAN::Config->{make_install_arg} = join( ' ', split( ' ', $makeflags ), 'UNINST=1' ) if ( $makeflags !~ /\bUNINST\b/ and eval qq{ $> eq '0' } ); # don't show start-up info $CPAN::Config->{inhibit_startup_message} = 1; # set additional options while ( my ( $opt, $arg ) = splice( @config, 0, 2 ) ) { ( $args{$opt} = $arg, next ) if $opt =~ /^force$/; # pseudo-option $CPAN::Config->{$opt} = $arg; } local $CPAN::Config->{prerequisites_policy} = 'follow'; while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) { MY::preinstall( $pkg, $ver ) or next if defined &MY::preinstall; print "*** Installing $pkg...\n"; my $obj = CPAN::Shell->expand( Module => $pkg ); my $success = 0; if ( $obj and _version_cmp( $obj->cpan_version, $ver ) >= 0 ) { my $pathname = $pkg; $pathname =~ s/::/\\W/; foreach my $inc ( grep { m/$pathname.pm/i } keys(%INC) ) { delete $INC{$inc}; } my $rv = $args{force} ? CPAN::Shell->force( install => $pkg ) : CPAN::Shell->install($pkg); $rv ||= eval { $CPAN::META->instance( 'CPAN::Distribution', $obj->cpan_file, ) ->{install} if $CPAN::META; }; if ( $rv eq 'YES' ) { print "*** $pkg successfully installed.\n"; $success = 1; } else { print "*** $pkg installation failed.\n"; $success = 0; } $installed += $success; } else { print << "."; *** Could not find a version $ver or above for $pkg; skipping. . } MY::postinstall( $pkg, $ver, $success ) if defined &MY::postinstall; } return $installed; } sub _has_cpanplus { return ( $HasCPANPLUS = ( $INC{'CPANPLUS/Config.pm'} or _load('CPANPLUS::Shell::Default') ) ); } # make guesses on whether we're under the CPAN installation directory sub _under_cpan { require Cwd; require File::Spec; my $cwd = File::Spec->canonpath( Cwd::cwd() ); my $cpan = File::Spec->canonpath( $CPAN::Config->{cpan_home} ); return ( index( $cwd, $cpan ) > -1 ); } sub _update_to { my $class = __PACKAGE__; my $ver = shift; return if _version_cmp( _load($class), $ver ) >= 0; # no need to upgrade if ( _prompt( "==> A newer version of $class ($ver) is required. Install?", 'y' ) =~ /^[Nn]/ ) { die "*** Please install $class $ver manually.\n"; } print << "."; *** Trying to fetch it from CPAN... . # install ourselves _load($class) and return $class->import(@_) if $class->install( [], $class, $ver ); print << '.'; exit 1; *** Cannot bootstrap myself. :-( Installation terminated. . } # check if we're connected to some host, using inet_aton sub _connected_to { my $site = shift; return ( ( _load('Socket') and Socket::inet_aton($site) ) or _prompt( qq( *** Your host cannot resolve the domain name '$site', which probably means the Internet connections are unavailable. ==> Should we try to install the required module(s) anyway?), 'n' ) =~ /^[Yy]/ ); } # check if a directory is writable; may create it on demand sub _can_write { my $path = shift; mkdir( $path, 0755 ) unless -e $path; return 1 if -w $path; print << "."; *** You are not allowed to write to the directory '$path'; the installation may fail due to insufficient permissions. . if ( eval '$>' and lc(`sudo -V`) =~ /version/ and _prompt( qq( ==> Should we try to re-execute the autoinstall process with 'sudo'?), ((-t STDIN) ? 'y' : 'n') ) =~ /^[Yy]/ ) { # try to bootstrap ourselves from sudo print << "."; *** Trying to re-execute the autoinstall process with 'sudo'... . my $missing = join( ',', @Missing ); my $config = join( ',', UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} ) if $Config; return unless system( 'sudo', $^X, $0, "--config=$config", "--installdeps=$missing" ); print << "."; *** The 'sudo' command exited with error! Resuming... . } return _prompt( qq( ==> Should we try to install the required module(s) anyway?), 'n' ) =~ /^[Yy]/; } # load a module and return the version it reports sub _load { my $mod = pop; # class/instance doesn't matter my $file = $mod; $file =~ s|::|/|g; $file .= '.pm'; local $@; return eval { require $file; $mod->VERSION } || ( $@ ? undef: 0 ); } # Load CPAN.pm and it's configuration sub _load_cpan { return if $CPAN::VERSION and $CPAN::Config and not @_; require CPAN; # CPAN-1.82+ adds CPAN::Config::AUTOLOAD to redirect to # CPAN::HandleConfig->load. CPAN reports that the redirection # is deprecated in a warning printed at the user. # CPAN-1.81 expects CPAN::HandleConfig->load, does not have # $CPAN::HandleConfig::VERSION but cannot handle # CPAN::Config->load # Which "versions expect CPAN::Config->load? if ( $CPAN::HandleConfig::VERSION || CPAN::HandleConfig->can('load') ) { # Newer versions of CPAN have a HandleConfig module CPAN::HandleConfig->load; } else { # Older versions had the load method in Config directly CPAN::Config->load; } } # compare two versions, either use Sort::Versions or plain comparison # return values same as <=> sub _version_cmp { my ( $cur, $min ) = @_; return -1 unless defined $cur; # if 0 keep comparing return 1 unless $min; $cur =~ s/\s+$//; # check for version numbers that are not in decimal format if ( ref($cur) or ref($min) or $cur =~ /v|\..*\./ or $min =~ /v|\..*\./ ) { if ( ( $version::VERSION or defined( _load('version') )) and version->can('new') ) { # use version.pm if it is installed. return version->new($cur) <=> version->new($min); } elsif ( $Sort::Versions::VERSION or defined( _load('Sort::Versions') ) ) { # use Sort::Versions as the sorting algorithm for a.b.c versions return Sort::Versions::versioncmp( $cur, $min ); } warn "Cannot reliably compare non-decimal formatted versions.\n" . "Please install version.pm or Sort::Versions.\n"; } # plain comparison local $^W = 0; # shuts off 'not numeric' bugs return $cur <=> $min; } # nothing; this usage is deprecated. sub main::PREREQ_PM { return {}; } sub _make_args { my %args = @_; $args{PREREQ_PM} = { %{ $args{PREREQ_PM} || {} }, @Existing, @Missing } if $UnderCPAN or $TestOnly; if ( $args{EXE_FILES} and -e 'MANIFEST' ) { require ExtUtils::Manifest; my $manifest = ExtUtils::Manifest::maniread('MANIFEST'); $args{EXE_FILES} = [ grep { exists $manifest->{$_} } @{ $args{EXE_FILES} } ]; } $args{test}{TESTS} ||= 't/*.t'; $args{test}{TESTS} = join( ' ', grep { !exists( $DisabledTests{$_} ) } map { glob($_) } split( /\s+/, $args{test}{TESTS} ) ); my $missing = join( ',', @Missing ); my $config = join( ',', UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} ) if $Config; $PostambleActions = ( ($missing and not $UnderCPAN) ? "\$(PERL) $0 --config=$config --installdeps=$missing" : "\$(NOECHO) \$(NOOP)" ); return %args; } # a wrapper to ExtUtils::MakeMaker::WriteMakefile sub Write { require Carp; Carp::croak "WriteMakefile: Need even number of args" if @_ % 2; if ($CheckOnly) { print << "."; *** Makefile not written in check-only mode. . return; } my %args = _make_args(@_); no strict 'refs'; $PostambleUsed = 0; local *MY::postamble = \&postamble unless defined &MY::postamble; ExtUtils::MakeMaker::WriteMakefile(%args); print << "." unless $PostambleUsed; *** WARNING: Makefile written with customized MY::postamble() without including contents from Module::AutoInstall::postamble() -- auto installation features disabled. Please contact the author. . return 1; } sub postamble { $PostambleUsed = 1; return <<"END_MAKE"; config :: installdeps \t\$(NOECHO) \$(NOOP) checkdeps :: \t\$(PERL) $0 --checkdeps installdeps :: \t$PostambleActions END_MAKE } 1; __END__ #line 1071 Excel-Template-0.34/inc/Module/Install/000755 000765 000120 00000000000 11747312641 017572 5ustar00rboadmin000000 000000 Excel-Template-0.34/inc/Module/Install.pm000644 000765 000120 00000030135 11747312612 020130 0ustar00rboadmin000000 000000 #line 1 package Module::Install; # For any maintainers: # The load order for Module::Install is a bit magic. # It goes something like this... # # IF ( host has Module::Install installed, creating author mode ) { # 1. Makefile.PL calls "use inc::Module::Install" # 2. $INC{inc/Module/Install.pm} set to installed version of inc::Module::Install # 3. The installed version of inc::Module::Install loads # 4. inc::Module::Install calls "require Module::Install" # 5. The ./inc/ version of Module::Install loads # } ELSE { # 1. Makefile.PL calls "use inc::Module::Install" # 2. $INC{inc/Module/Install.pm} set to ./inc/ version of Module::Install # 3. The ./inc/ version of Module::Install loads # } use 5.005; use strict 'vars'; use Cwd (); use File::Find (); use File::Path (); use vars qw{$VERSION $MAIN}; BEGIN { # All Module::Install core packages now require synchronised versions. # This will be used to ensure we don't accidentally load old or # different versions of modules. # This is not enforced yet, but will be some time in the next few # releases once we can make sure it won't clash with custom # Module::Install extensions. $VERSION = '1.01'; # Storage for the pseudo-singleton $MAIN = undef; *inc::Module::Install::VERSION = *VERSION; @inc::Module::Install::ISA = __PACKAGE__; } sub import { my $class = shift; my $self = $class->new(@_); my $who = $self->_caller; #------------------------------------------------------------- # all of the following checks should be included in import(), # to allow "eval 'require Module::Install; 1' to test # installation of Module::Install. (RT #51267) #------------------------------------------------------------- # Whether or not inc::Module::Install is actually loaded, the # $INC{inc/Module/Install.pm} is what will still get set as long as # the caller loaded module this in the documented manner. # If not set, the caller may NOT have loaded the bundled version, and thus # they may not have a MI version that works with the Makefile.PL. This would # result in false errors or unexpected behaviour. And we don't want that. my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm'; unless ( $INC{$file} ) { die <<"END_DIE" } Please invoke ${\__PACKAGE__} with: use inc::${\__PACKAGE__}; not: use ${\__PACKAGE__}; END_DIE # This reportedly fixes a rare Win32 UTC file time issue, but # as this is a non-cross-platform XS module not in the core, # we shouldn't really depend on it. See RT #24194 for detail. # (Also, this module only supports Perl 5.6 and above). eval "use Win32::UTCFileTime" if $^O eq 'MSWin32' && $] >= 5.006; # If the script that is loading Module::Install is from the future, # then make will detect this and cause it to re-run over and over # again. This is bad. Rather than taking action to touch it (which # is unreliable on some platforms and requires write permissions) # for now we should catch this and refuse to run. if ( -f $0 ) { my $s = (stat($0))[9]; # If the modification time is only slightly in the future, # sleep briefly to remove the problem. my $a = $s - time; if ( $a > 0 and $a < 5 ) { sleep 5 } # Too far in the future, throw an error. my $t = time; if ( $s > $t ) { die <<"END_DIE" } Your installer $0 has a modification time in the future ($s > $t). This is known to create infinite loops in make. Please correct this, then run $0 again. END_DIE } # Build.PL was formerly supported, but no longer is due to excessive # difficulty in implementing every single feature twice. if ( $0 =~ /Build.PL$/i ) { die <<"END_DIE" } Module::Install no longer supports Build.PL. It was impossible to maintain duel backends, and has been deprecated. Please remove all Build.PL files and only use the Makefile.PL installer. END_DIE #------------------------------------------------------------- # To save some more typing in Module::Install installers, every... # use inc::Module::Install # ...also acts as an implicit use strict. $^H |= strict::bits(qw(refs subs vars)); #------------------------------------------------------------- unless ( -f $self->{file} ) { foreach my $key (keys %INC) { delete $INC{$key} if $key =~ /Module\/Install/; } local $^W; require "$self->{path}/$self->{dispatch}.pm"; File::Path::mkpath("$self->{prefix}/$self->{author}"); $self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self ); $self->{admin}->init; @_ = ($class, _self => $self); goto &{"$self->{name}::import"}; } local $^W; *{"${who}::AUTOLOAD"} = $self->autoload; $self->preload; # Unregister loader and worker packages so subdirs can use them again delete $INC{'inc/Module/Install.pm'}; delete $INC{'Module/Install.pm'}; # Save to the singleton $MAIN = $self; return 1; } sub autoload { my $self = shift; my $who = $self->_caller; my $cwd = Cwd::cwd(); my $sym = "${who}::AUTOLOAD"; $sym->{$cwd} = sub { my $pwd = Cwd::cwd(); if ( my $code = $sym->{$pwd} ) { # Delegate back to parent dirs goto &$code unless $cwd eq $pwd; } unless ($$sym =~ s/([^:]+)$//) { # XXX: it looks like we can't retrieve the missing function # via $$sym (usually $main::AUTOLOAD) in this case. # I'm still wondering if we should slurp Makefile.PL to # get some context or not ... my ($package, $file, $line) = caller; die <<"EOT"; Unknown function is found at $file line $line. Execution of $file aborted due to runtime errors. If you're a contributor to a project, you may need to install some Module::Install extensions from CPAN (or other repository). If you're a user of a module, please contact the author. EOT } my $method = $1; if ( uc($method) eq $method ) { # Do nothing return; } elsif ( $method =~ /^_/ and $self->can($method) ) { # Dispatch to the root M:I class return $self->$method(@_); } # Dispatch to the appropriate plugin unshift @_, ( $self, $1 ); goto &{$self->can('call')}; }; } sub preload { my $self = shift; unless ( $self->{extensions} ) { $self->load_extensions( "$self->{prefix}/$self->{path}", $self ); } my @exts = @{$self->{extensions}}; unless ( @exts ) { @exts = $self->{admin}->load_all_extensions; } my %seen; foreach my $obj ( @exts ) { while (my ($method, $glob) = each %{ref($obj) . '::'}) { next unless $obj->can($method); next if $method =~ /^_/; next if $method eq uc($method); $seen{$method}++; } } my $who = $self->_caller; foreach my $name ( sort keys %seen ) { local $^W; *{"${who}::$name"} = sub { ${"${who}::AUTOLOAD"} = "${who}::$name"; goto &{"${who}::AUTOLOAD"}; }; } } sub new { my ($class, %args) = @_; delete $INC{'FindBin.pm'}; { # to suppress the redefine warning local $SIG{__WARN__} = sub {}; require FindBin; } # ignore the prefix on extension modules built from top level. my $base_path = Cwd::abs_path($FindBin::Bin); unless ( Cwd::abs_path(Cwd::cwd()) eq $base_path ) { delete $args{prefix}; } return $args{_self} if $args{_self}; $args{dispatch} ||= 'Admin'; $args{prefix} ||= 'inc'; $args{author} ||= ($^O eq 'VMS' ? '_author' : '.author'); $args{bundle} ||= 'inc/BUNDLES'; $args{base} ||= $base_path; $class =~ s/^\Q$args{prefix}\E:://; $args{name} ||= $class; $args{version} ||= $class->VERSION; unless ( $args{path} ) { $args{path} = $args{name}; $args{path} =~ s!::!/!g; } $args{file} ||= "$args{base}/$args{prefix}/$args{path}.pm"; $args{wrote} = 0; bless( \%args, $class ); } sub call { my ($self, $method) = @_; my $obj = $self->load($method) or return; splice(@_, 0, 2, $obj); goto &{$obj->can($method)}; } sub load { my ($self, $method) = @_; $self->load_extensions( "$self->{prefix}/$self->{path}", $self ) unless $self->{extensions}; foreach my $obj (@{$self->{extensions}}) { return $obj if $obj->can($method); } my $admin = $self->{admin} or die <<"END_DIE"; The '$method' method does not exist in the '$self->{prefix}' path! Please remove the '$self->{prefix}' directory and run $0 again to load it. END_DIE my $obj = $admin->load($method, 1); push @{$self->{extensions}}, $obj; $obj; } sub load_extensions { my ($self, $path, $top) = @_; my $should_reload = 0; unless ( grep { ! ref $_ and lc $_ eq lc $self->{prefix} } @INC ) { unshift @INC, $self->{prefix}; $should_reload = 1; } foreach my $rv ( $self->find_extensions($path) ) { my ($file, $pkg) = @{$rv}; next if $self->{pathnames}{$pkg}; local $@; my $new = eval { local $^W; require $file; $pkg->can('new') }; unless ( $new ) { warn $@ if $@; next; } $self->{pathnames}{$pkg} = $should_reload ? delete $INC{$file} : $INC{$file}; push @{$self->{extensions}}, &{$new}($pkg, _top => $top ); } $self->{extensions} ||= []; } sub find_extensions { my ($self, $path) = @_; my @found; File::Find::find( sub { my $file = $File::Find::name; return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is; my $subpath = $1; return if lc($subpath) eq lc($self->{dispatch}); $file = "$self->{path}/$subpath.pm"; my $pkg = "$self->{name}::$subpath"; $pkg =~ s!/!::!g; # If we have a mixed-case package name, assume case has been preserved # correctly. Otherwise, root through the file to locate the case-preserved # version of the package name. if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) { my $content = Module::Install::_read($subpath . '.pm'); my $in_pod = 0; foreach ( split //, $content ) { $in_pod = 1 if /^=\w/; $in_pod = 0 if /^=cut/; next if ($in_pod || /^=cut/); # skip pod text next if /^\s*#/; # and comments if ( m/^\s*package\s+($pkg)\s*;/i ) { $pkg = $1; last; } } } push @found, [ $file, $pkg ]; }, $path ) if -d $path; @found; } ##################################################################### # Common Utility Functions sub _caller { my $depth = 0; my $call = caller($depth); while ( $call eq __PACKAGE__ ) { $depth++; $call = caller($depth); } return $call; } # Done in evals to avoid confusing Perl::MinimumVersion eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@; sub _read { local *FH; open( FH, '<', $_[0] ) or die "open($_[0]): $!"; my $string = do { local $/; }; close FH or die "close($_[0]): $!"; return $string; } END_NEW sub _read { local *FH; open( FH, "< $_[0]" ) or die "open($_[0]): $!"; my $string = do { local $/; }; close FH or die "close($_[0]): $!"; return $string; } END_OLD sub _readperl { my $string = Module::Install::_read($_[0]); $string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg; $string =~ s/(\n)\n*__(?:DATA|END)__\b.*\z/$1/s; $string =~ s/\n\n=\w+.+?\n\n=cut\b.+?\n+/\n\n/sg; return $string; } sub _readpod { my $string = Module::Install::_read($_[0]); $string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg; return $string if $_[0] =~ /\.pod\z/; $string =~ s/(^|\n=cut\b.+?\n+)[^=\s].+?\n(\n=\w+|\z)/$1$2/sg; $string =~ s/\n*=pod\b[^\n]*\n+/\n\n/sg; $string =~ s/\n*=cut\b[^\n]*\n+/\n\n/sg; $string =~ s/^\n+//s; return $string; } # Done in evals to avoid confusing Perl::MinimumVersion eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@; sub _write { local *FH; open( FH, '>', $_[0] ) or die "open($_[0]): $!"; foreach ( 1 .. $#_ ) { print FH $_[$_] or die "print($_[0]): $!"; } close FH or die "close($_[0]): $!"; } END_NEW sub _write { local *FH; open( FH, "> $_[0]" ) or die "open($_[0]): $!"; foreach ( 1 .. $#_ ) { print FH $_[$_] or die "print($_[0]): $!"; } close FH or die "close($_[0]): $!"; } END_OLD # _version is for processing module versions (eg, 1.03_05) not # Perl versions (eg, 5.8.1). sub _version ($) { my $s = shift || 0; my $d =()= $s =~ /(\.)/g; if ( $d >= 2 ) { # Normalise multipart versions $s =~ s/(\.)(\d{1,3})/sprintf("$1%03d",$2)/eg; } $s =~ s/^(\d+)\.?//; my $l = $1 || 0; my @v = map { $_ . '0' x (3 - length $_) } $s =~ /(\d{1,3})\D?/g; $l = $l . '.' . join '', @v if @v; return $l + 0; } sub _cmp ($$) { _version($_[0]) <=> _version($_[1]); } # Cloned from Params::Util::_CLASS sub _CLASS ($) { ( defined $_[0] and ! ref $_[0] and $_[0] =~ m/^[^\W\d]\w*(?:::\w+)*\z/s ) ? $_[0] : undef; } 1; # Copyright 2008 - 2011 Adam Kennedy. Excel-Template-0.34/inc/Module/Install/AutoInstall.pm000644 000765 000120 00000003632 11747312612 022371 0ustar00rboadmin000000 000000 #line 1 package Module::Install::AutoInstall; use strict; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.01'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } sub AutoInstall { $_[0] } sub run { my $self = shift; $self->auto_install_now(@_); } sub write { my $self = shift; $self->auto_install(@_); } sub auto_install { my $self = shift; return if $self->{done}++; # Flatten array of arrays into a single array my @core = map @$_, map @$_, grep ref, $self->build_requires, $self->requires; my @config = @_; # We'll need Module::AutoInstall $self->include('Module::AutoInstall'); require Module::AutoInstall; my @features_require = Module::AutoInstall->import( (@config ? (-config => \@config) : ()), (@core ? (-core => \@core) : ()), $self->features, ); my %seen; my @requires = map @$_, map @$_, grep ref, $self->requires; while (my ($mod, $ver) = splice(@requires, 0, 2)) { $seen{$mod}{$ver}++; } my @build_requires = map @$_, map @$_, grep ref, $self->build_requires; while (my ($mod, $ver) = splice(@build_requires, 0, 2)) { $seen{$mod}{$ver}++; } my @configure_requires = map @$_, map @$_, grep ref, $self->configure_requires; while (my ($mod, $ver) = splice(@configure_requires, 0, 2)) { $seen{$mod}{$ver}++; } my @deduped; while (my ($mod, $ver) = splice(@features_require, 0, 2)) { push @deduped, $mod => $ver unless $seen{$mod}{$ver}++; } $self->requires(@deduped); $self->makemaker_args( Module::AutoInstall::_make_args() ); my $class = ref($self); $self->postamble( "# --- $class section:\n" . Module::AutoInstall::postamble() ); } sub auto_install_now { my $self = shift; $self->auto_install(@_); Module::AutoInstall::do_install(); } 1; Excel-Template-0.34/inc/Module/Install/Base.pm000644 000765 000120 00000002147 11747312612 021004 0ustar00rboadmin000000 000000 #line 1 package Module::Install::Base; use strict 'vars'; use vars qw{$VERSION}; BEGIN { $VERSION = '1.01'; } # Suspend handler for "redefined" warnings BEGIN { my $w = $SIG{__WARN__}; $SIG{__WARN__} = sub { $w }; } #line 42 sub new { my $class = shift; unless ( defined &{"${class}::call"} ) { *{"${class}::call"} = sub { shift->_top->call(@_) }; } unless ( defined &{"${class}::load"} ) { *{"${class}::load"} = sub { shift->_top->load(@_) }; } bless { @_ }, $class; } #line 61 sub AUTOLOAD { local $@; my $func = eval { shift->_top->autoload } or return; goto &$func; } #line 75 sub _top { $_[0]->{_top}; } #line 90 sub admin { $_[0]->_top->{admin} or Module::Install::Base::FakeAdmin->new; } #line 106 sub is_admin { ! $_[0]->admin->isa('Module::Install::Base::FakeAdmin'); } sub DESTROY {} package Module::Install::Base::FakeAdmin; use vars qw{$VERSION}; BEGIN { $VERSION = $Module::Install::Base::VERSION; } my $fake; sub new { $fake ||= bless(\@_, $_[0]); } sub AUTOLOAD {} sub DESTROY {} # Restore warning handler BEGIN { $SIG{__WARN__} = $SIG{__WARN__}->(); } 1; #line 159 Excel-Template-0.34/inc/Module/Install/Can.pm000644 000765 000120 00000003333 11747312613 020632 0ustar00rboadmin000000 000000 #line 1 package Module::Install::Can; use strict; use Config (); use File::Spec (); use ExtUtils::MakeMaker (); use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.01'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } # check if we can load some module ### Upgrade this to not have to load the module if possible sub can_use { my ($self, $mod, $ver) = @_; $mod =~ s{::|\\}{/}g; $mod .= '.pm' unless $mod =~ /\.pm$/i; my $pkg = $mod; $pkg =~ s{/}{::}g; $pkg =~ s{\.pm$}{}i; local $@; eval { require $mod; $pkg->VERSION($ver || 0); 1 }; } # check if we can run some command sub can_run { my ($self, $cmd) = @_; my $_cmd = $cmd; return $_cmd if (-x $_cmd or $_cmd = MM->maybe_command($_cmd)); for my $dir ((split /$Config::Config{path_sep}/, $ENV{PATH}), '.') { next if $dir eq ''; my $abs = File::Spec->catfile($dir, $_[1]); return $abs if (-x $abs or $abs = MM->maybe_command($abs)); } return; } # can we locate a (the) C compiler sub can_cc { my $self = shift; my @chunks = split(/ /, $Config::Config{cc}) or return; # $Config{cc} may contain args; try to find out the program part while (@chunks) { return $self->can_run("@chunks") || (pop(@chunks), next); } return; } # Fix Cygwin bug on maybe_command(); if ( $^O eq 'cygwin' ) { require ExtUtils::MM_Cygwin; require ExtUtils::MM_Win32; if ( ! defined(&ExtUtils::MM_Cygwin::maybe_command) ) { *ExtUtils::MM_Cygwin::maybe_command = sub { my ($self, $file) = @_; if ($file =~ m{^/cygdrive/}i and ExtUtils::MM_Win32->can('maybe_command')) { ExtUtils::MM_Win32->maybe_command($file); } else { ExtUtils::MM_Unix->maybe_command($file); } } } } 1; __END__ #line 156 Excel-Template-0.34/inc/Module/Install/Fetch.pm000644 000765 000120 00000004627 11747312613 021171 0ustar00rboadmin000000 000000 #line 1 package Module::Install::Fetch; use strict; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.01'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } sub get_file { my ($self, %args) = @_; my ($scheme, $host, $path, $file) = $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return; if ( $scheme eq 'http' and ! eval { require LWP::Simple; 1 } ) { $args{url} = $args{ftp_url} or (warn("LWP support unavailable!\n"), return); ($scheme, $host, $path, $file) = $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return; } $|++; print "Fetching '$file' from $host... "; unless (eval { require Socket; Socket::inet_aton($host) }) { warn "'$host' resolve failed!\n"; return; } return unless $scheme eq 'ftp' or $scheme eq 'http'; require Cwd; my $dir = Cwd::getcwd(); chdir $args{local_dir} or return if exists $args{local_dir}; if (eval { require LWP::Simple; 1 }) { LWP::Simple::mirror($args{url}, $file); } elsif (eval { require Net::FTP; 1 }) { eval { # use Net::FTP to get past firewall my $ftp = Net::FTP->new($host, Passive => 1, Timeout => 600); $ftp->login("anonymous", 'anonymous@example.com'); $ftp->cwd($path); $ftp->binary; $ftp->get($file) or (warn("$!\n"), return); $ftp->quit; } } elsif (my $ftp = $self->can_run('ftp')) { eval { # no Net::FTP, fallback to ftp.exe require FileHandle; my $fh = FileHandle->new; local $SIG{CHLD} = 'IGNORE'; unless ($fh->open("|$ftp -n")) { warn "Couldn't open ftp: $!\n"; chdir $dir; return; } my @dialog = split(/\n/, <<"END_FTP"); open $host user anonymous anonymous\@example.com cd $path binary get $file $file quit END_FTP foreach (@dialog) { $fh->print("$_\n") } $fh->close; } } else { warn "No working 'ftp' program available!\n"; chdir $dir; return; } unless (-f $file) { warn "Fetching failed: $@\n"; chdir $dir; return; } return if exists $args{size} and -s $file != $args{size}; system($args{run}) if exists $args{run}; unlink($file) if $args{remove}; print(((!exists $args{check_for} or -e $args{check_for}) ? "done!" : "failed! ($!)"), "\n"); chdir $dir; return !$?; } 1; Excel-Template-0.34/inc/Module/Install/Include.pm000644 000765 000120 00000001015 11747312612 021506 0ustar00rboadmin000000 000000 #line 1 package Module::Install::Include; use strict; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.01'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } sub include { shift()->admin->include(@_); } sub include_deps { shift()->admin->include_deps(@_); } sub auto_include { shift()->admin->auto_include(@_); } sub auto_include_deps { shift()->admin->auto_include_deps(@_); } sub auto_include_dependent_dists { shift()->admin->auto_include_dependent_dists(@_); } 1; Excel-Template-0.34/inc/Module/Install/Makefile.pm000644 000765 000120 00000027032 11747312612 021647 0ustar00rboadmin000000 000000 #line 1 package Module::Install::Makefile; use strict 'vars'; use ExtUtils::MakeMaker (); use Module::Install::Base (); use Fcntl qw/:flock :seek/; use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.01'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } sub Makefile { $_[0] } my %seen = (); sub prompt { shift; # Infinite loop protection my @c = caller(); if ( ++$seen{"$c[1]|$c[2]|$_[0]"} > 3 ) { die "Caught an potential prompt infinite loop ($c[1]|$c[2]|$_[0])"; } # In automated testing or non-interactive session, always use defaults if ( ($ENV{AUTOMATED_TESTING} or -! -t STDIN) and ! $ENV{PERL_MM_USE_DEFAULT} ) { local $ENV{PERL_MM_USE_DEFAULT} = 1; goto &ExtUtils::MakeMaker::prompt; } else { goto &ExtUtils::MakeMaker::prompt; } } # Store a cleaned up version of the MakeMaker version, # since we need to behave differently in a variety of # ways based on the MM version. my $makemaker = eval $ExtUtils::MakeMaker::VERSION; # If we are passed a param, do a "newer than" comparison. # Otherwise, just return the MakeMaker version. sub makemaker { ( @_ < 2 or $makemaker >= eval($_[1]) ) ? $makemaker : 0 } # Ripped from ExtUtils::MakeMaker 6.56, and slightly modified # as we only need to know here whether the attribute is an array # or a hash or something else (which may or may not be appendable). my %makemaker_argtype = ( C => 'ARRAY', CONFIG => 'ARRAY', # CONFIGURE => 'CODE', # ignore DIR => 'ARRAY', DL_FUNCS => 'HASH', DL_VARS => 'ARRAY', EXCLUDE_EXT => 'ARRAY', EXE_FILES => 'ARRAY', FUNCLIST => 'ARRAY', H => 'ARRAY', IMPORTS => 'HASH', INCLUDE_EXT => 'ARRAY', LIBS => 'ARRAY', # ignore '' MAN1PODS => 'HASH', MAN3PODS => 'HASH', META_ADD => 'HASH', META_MERGE => 'HASH', PL_FILES => 'HASH', PM => 'HASH', PMLIBDIRS => 'ARRAY', PMLIBPARENTDIRS => 'ARRAY', PREREQ_PM => 'HASH', CONFIGURE_REQUIRES => 'HASH', SKIP => 'ARRAY', TYPEMAPS => 'ARRAY', XS => 'HASH', # VERSION => ['version',''], # ignore # _KEEP_AFTER_FLUSH => '', clean => 'HASH', depend => 'HASH', dist => 'HASH', dynamic_lib=> 'HASH', linkext => 'HASH', macro => 'HASH', postamble => 'HASH', realclean => 'HASH', test => 'HASH', tool_autosplit => 'HASH', # special cases where you can use makemaker_append CCFLAGS => 'APPENDABLE', DEFINE => 'APPENDABLE', INC => 'APPENDABLE', LDDLFLAGS => 'APPENDABLE', LDFROM => 'APPENDABLE', ); sub makemaker_args { my ($self, %new_args) = @_; my $args = ( $self->{makemaker_args} ||= {} ); foreach my $key (keys %new_args) { if ($makemaker_argtype{$key}) { if ($makemaker_argtype{$key} eq 'ARRAY') { $args->{$key} = [] unless defined $args->{$key}; unless (ref $args->{$key} eq 'ARRAY') { $args->{$key} = [$args->{$key}] } push @{$args->{$key}}, ref $new_args{$key} eq 'ARRAY' ? @{$new_args{$key}} : $new_args{$key}; } elsif ($makemaker_argtype{$key} eq 'HASH') { $args->{$key} = {} unless defined $args->{$key}; foreach my $skey (keys %{ $new_args{$key} }) { $args->{$key}{$skey} = $new_args{$key}{$skey}; } } elsif ($makemaker_argtype{$key} eq 'APPENDABLE') { $self->makemaker_append($key => $new_args{$key}); } } else { if (defined $args->{$key}) { warn qq{MakeMaker attribute "$key" is overriden; use "makemaker_append" to append values\n}; } $args->{$key} = $new_args{$key}; } } return $args; } # For mm args that take multiple space-seperated args, # append an argument to the current list. sub makemaker_append { my $self = shift; my $name = shift; my $args = $self->makemaker_args; $args->{$name} = defined $args->{$name} ? join( ' ', $args->{$name}, @_ ) : join( ' ', @_ ); } sub build_subdirs { my $self = shift; my $subdirs = $self->makemaker_args->{DIR} ||= []; for my $subdir (@_) { push @$subdirs, $subdir; } } sub clean_files { my $self = shift; my $clean = $self->makemaker_args->{clean} ||= {}; %$clean = ( %$clean, FILES => join ' ', grep { length $_ } ($clean->{FILES} || (), @_), ); } sub realclean_files { my $self = shift; my $realclean = $self->makemaker_args->{realclean} ||= {}; %$realclean = ( %$realclean, FILES => join ' ', grep { length $_ } ($realclean->{FILES} || (), @_), ); } sub libs { my $self = shift; my $libs = ref $_[0] ? shift : [ shift ]; $self->makemaker_args( LIBS => $libs ); } sub inc { my $self = shift; $self->makemaker_args( INC => shift ); } sub _wanted_t { } sub tests_recursive { my $self = shift; my $dir = shift || 't'; unless ( -d $dir ) { die "tests_recursive dir '$dir' does not exist"; } my %tests = map { $_ => 1 } split / /, ($self->tests || ''); require File::Find; File::Find::find( sub { /\.t$/ and -f $_ and $tests{"$File::Find::dir/*.t"} = 1 }, $dir ); $self->tests( join ' ', sort keys %tests ); } sub write { my $self = shift; die "&Makefile->write() takes no arguments\n" if @_; # Check the current Perl version my $perl_version = $self->perl_version; if ( $perl_version ) { eval "use $perl_version; 1" or die "ERROR: perl: Version $] is installed, " . "but we need version >= $perl_version"; } # Make sure we have a new enough MakeMaker require ExtUtils::MakeMaker; if ( $perl_version and $self->_cmp($perl_version, '5.006') >= 0 ) { # MakeMaker can complain about module versions that include # an underscore, even though its own version may contain one! # Hence the funny regexp to get rid of it. See RT #35800 # for details. my $v = $ExtUtils::MakeMaker::VERSION =~ /^(\d+\.\d+)/; $self->build_requires( 'ExtUtils::MakeMaker' => $v ); $self->configure_requires( 'ExtUtils::MakeMaker' => $v ); } else { # Allow legacy-compatibility with 5.005 by depending on the # most recent EU:MM that supported 5.005. $self->build_requires( 'ExtUtils::MakeMaker' => 6.42 ); $self->configure_requires( 'ExtUtils::MakeMaker' => 6.42 ); } # Generate the MakeMaker params my $args = $self->makemaker_args; $args->{DISTNAME} = $self->name; $args->{NAME} = $self->module_name || $self->name; $args->{NAME} =~ s/-/::/g; $args->{VERSION} = $self->version or die <<'EOT'; ERROR: Can't determine distribution version. Please specify it explicitly via 'version' in Makefile.PL, or set a valid $VERSION in a module, and provide its file path via 'version_from' (or 'all_from' if you prefer) in Makefile.PL. EOT $DB::single = 1; if ( $self->tests ) { my @tests = split ' ', $self->tests; my %seen; $args->{test} = { TESTS => (join ' ', grep {!$seen{$_}++} @tests), }; } elsif ( $Module::Install::ExtraTests::use_extratests ) { # Module::Install::ExtraTests doesn't set $self->tests and does its own tests via harness. # So, just ignore our xt tests here. } elsif ( -d 'xt' and ($Module::Install::AUTHOR or $ENV{RELEASE_TESTING}) ) { $args->{test} = { TESTS => join( ' ', map { "$_/*.t" } grep { -d $_ } qw{ t xt } ), }; } if ( $] >= 5.005 ) { $args->{ABSTRACT} = $self->abstract; $args->{AUTHOR} = join ', ', @{$self->author || []}; } if ( $self->makemaker(6.10) ) { $args->{NO_META} = 1; #$args->{NO_MYMETA} = 1; } if ( $self->makemaker(6.17) and $self->sign ) { $args->{SIGN} = 1; } unless ( $self->is_admin ) { delete $args->{SIGN}; } if ( $self->makemaker(6.31) and $self->license ) { $args->{LICENSE} = $self->license; } my $prereq = ($args->{PREREQ_PM} ||= {}); %$prereq = ( %$prereq, map { @$_ } # flatten [module => version] map { @$_ } grep $_, ($self->requires) ); # Remove any reference to perl, PREREQ_PM doesn't support it delete $args->{PREREQ_PM}->{perl}; # Merge both kinds of requires into BUILD_REQUIRES my $build_prereq = ($args->{BUILD_REQUIRES} ||= {}); %$build_prereq = ( %$build_prereq, map { @$_ } # flatten [module => version] map { @$_ } grep $_, ($self->configure_requires, $self->build_requires) ); # Remove any reference to perl, BUILD_REQUIRES doesn't support it delete $args->{BUILD_REQUIRES}->{perl}; # Delete bundled dists from prereq_pm, add it to Makefile DIR my $subdirs = ($args->{DIR} || []); if ($self->bundles) { my %processed; foreach my $bundle (@{ $self->bundles }) { my ($mod_name, $dist_dir) = @$bundle; delete $prereq->{$mod_name}; $dist_dir = File::Basename::basename($dist_dir); # dir for building this module if (not exists $processed{$dist_dir}) { if (-d $dist_dir) { # List as sub-directory to be processed by make push @$subdirs, $dist_dir; } # Else do nothing: the module is already present on the system $processed{$dist_dir} = undef; } } } unless ( $self->makemaker('6.55_03') ) { %$prereq = (%$prereq,%$build_prereq); delete $args->{BUILD_REQUIRES}; } if ( my $perl_version = $self->perl_version ) { eval "use $perl_version; 1" or die "ERROR: perl: Version $] is installed, " . "but we need version >= $perl_version"; if ( $self->makemaker(6.48) ) { $args->{MIN_PERL_VERSION} = $perl_version; } } if ($self->installdirs) { warn qq{old INSTALLDIRS (probably set by makemaker_args) is overriden by installdirs\n} if $args->{INSTALLDIRS}; $args->{INSTALLDIRS} = $self->installdirs; } my %args = map { ( $_ => $args->{$_} ) } grep {defined($args->{$_} ) } keys %$args; my $user_preop = delete $args{dist}->{PREOP}; if ( my $preop = $self->admin->preop($user_preop) ) { foreach my $key ( keys %$preop ) { $args{dist}->{$key} = $preop->{$key}; } } my $mm = ExtUtils::MakeMaker::WriteMakefile(%args); $self->fix_up_makefile($mm->{FIRST_MAKEFILE} || 'Makefile'); } sub fix_up_makefile { my $self = shift; my $makefile_name = shift; my $top_class = ref($self->_top) || ''; my $top_version = $self->_top->VERSION || ''; my $preamble = $self->preamble ? "# Preamble by $top_class $top_version\n" . $self->preamble : ''; my $postamble = "# Postamble by $top_class $top_version\n" . ($self->postamble || ''); local *MAKEFILE; open MAKEFILE, "+< $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!"; eval { flock MAKEFILE, LOCK_EX }; my $makefile = do { local $/; }; $makefile =~ s/\b(test_harness\(\$\(TEST_VERBOSE\), )/$1'inc', /; $makefile =~ s/( -I\$\(INST_ARCHLIB\))/ -Iinc$1/g; $makefile =~ s/( "-I\$\(INST_LIB\)")/ "-Iinc"$1/g; $makefile =~ s/^(FULLPERL = .*)/$1 "-Iinc"/m; $makefile =~ s/^(PERL = .*)/$1 "-Iinc"/m; # Module::Install will never be used to build the Core Perl # Sometimes PERL_LIB and PERL_ARCHLIB get written anyway, which breaks # PREFIX/PERL5LIB, and thus, install_share. Blank them if they exist $makefile =~ s/^PERL_LIB = .+/PERL_LIB =/m; #$makefile =~ s/^PERL_ARCHLIB = .+/PERL_ARCHLIB =/m; # Perl 5.005 mentions PERL_LIB explicitly, so we have to remove that as well. $makefile =~ s/(\"?)-I\$\(PERL_LIB\)\1//g; # XXX - This is currently unused; not sure if it breaks other MM-users # $makefile =~ s/^pm_to_blib\s+:\s+/pm_to_blib :: /mg; seek MAKEFILE, 0, SEEK_SET; truncate MAKEFILE, 0; print MAKEFILE "$preamble$makefile$postamble" or die $!; close MAKEFILE or die $!; 1; } sub preamble { my ($self, $text) = @_; $self->{preamble} = $text . $self->{preamble} if defined $text; $self->{preamble}; } sub postamble { my ($self, $text) = @_; $self->{postamble} ||= $self->admin->postamble; $self->{postamble} .= $text if defined $text; $self->{postamble} } 1; __END__ #line 541 Excel-Template-0.34/inc/Module/Install/Metadata.pm000644 000765 000120 00000043123 11747312612 021651 0ustar00rboadmin000000 000000 #line 1 package Module::Install::Metadata; use strict 'vars'; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.01'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } my @boolean_keys = qw{ sign }; my @scalar_keys = qw{ name module_name abstract version distribution_type tests installdirs }; my @tuple_keys = qw{ configure_requires build_requires requires recommends bundles resources }; my @resource_keys = qw{ homepage bugtracker repository }; my @array_keys = qw{ keywords author }; *authors = \&author; sub Meta { shift } sub Meta_BooleanKeys { @boolean_keys } sub Meta_ScalarKeys { @scalar_keys } sub Meta_TupleKeys { @tuple_keys } sub Meta_ResourceKeys { @resource_keys } sub Meta_ArrayKeys { @array_keys } foreach my $key ( @boolean_keys ) { *$key = sub { my $self = shift; if ( defined wantarray and not @_ ) { return $self->{values}->{$key}; } $self->{values}->{$key} = ( @_ ? $_[0] : 1 ); return $self; }; } foreach my $key ( @scalar_keys ) { *$key = sub { my $self = shift; return $self->{values}->{$key} if defined wantarray and !@_; $self->{values}->{$key} = shift; return $self; }; } foreach my $key ( @array_keys ) { *$key = sub { my $self = shift; return $self->{values}->{$key} if defined wantarray and !@_; $self->{values}->{$key} ||= []; push @{$self->{values}->{$key}}, @_; return $self; }; } foreach my $key ( @resource_keys ) { *$key = sub { my $self = shift; unless ( @_ ) { return () unless $self->{values}->{resources}; return map { $_->[1] } grep { $_->[0] eq $key } @{ $self->{values}->{resources} }; } return $self->{values}->{resources}->{$key} unless @_; my $uri = shift or die( "Did not provide a value to $key()" ); $self->resources( $key => $uri ); return 1; }; } foreach my $key ( grep { $_ ne "resources" } @tuple_keys) { *$key = sub { my $self = shift; return $self->{values}->{$key} unless @_; my @added; while ( @_ ) { my $module = shift or last; my $version = shift || 0; push @added, [ $module, $version ]; } push @{ $self->{values}->{$key} }, @added; return map {@$_} @added; }; } # Resource handling my %lc_resource = map { $_ => 1 } qw{ homepage license bugtracker repository }; sub resources { my $self = shift; while ( @_ ) { my $name = shift or last; my $value = shift or next; if ( $name eq lc $name and ! $lc_resource{$name} ) { die("Unsupported reserved lowercase resource '$name'"); } $self->{values}->{resources} ||= []; push @{ $self->{values}->{resources} }, [ $name, $value ]; } $self->{values}->{resources}; } # Aliases for build_requires that will have alternative # meanings in some future version of META.yml. sub test_requires { shift->build_requires(@_) } sub install_requires { shift->build_requires(@_) } # Aliases for installdirs options sub install_as_core { $_[0]->installdirs('perl') } sub install_as_cpan { $_[0]->installdirs('site') } sub install_as_site { $_[0]->installdirs('site') } sub install_as_vendor { $_[0]->installdirs('vendor') } sub dynamic_config { my $self = shift; unless ( @_ ) { warn "You MUST provide an explicit true/false value to dynamic_config\n"; return $self; } $self->{values}->{dynamic_config} = $_[0] ? 1 : 0; return 1; } sub perl_version { my $self = shift; return $self->{values}->{perl_version} unless @_; my $version = shift or die( "Did not provide a value to perl_version()" ); # Normalize the version $version = $self->_perl_version($version); # We don't support the reall old versions unless ( $version >= 5.005 ) { die "Module::Install only supports 5.005 or newer (use ExtUtils::MakeMaker)\n"; } $self->{values}->{perl_version} = $version; } sub all_from { my ( $self, $file ) = @_; unless ( defined($file) ) { my $name = $self->name or die( "all_from called with no args without setting name() first" ); $file = join('/', 'lib', split(/-/, $name)) . '.pm'; $file =~ s{.*/}{} unless -e $file; unless ( -e $file ) { die("all_from cannot find $file from $name"); } } unless ( -f $file ) { die("The path '$file' does not exist, or is not a file"); } $self->{values}{all_from} = $file; # Some methods pull from POD instead of code. # If there is a matching .pod, use that instead my $pod = $file; $pod =~ s/\.pm$/.pod/i; $pod = $file unless -e $pod; # Pull the different values $self->name_from($file) unless $self->name; $self->version_from($file) unless $self->version; $self->perl_version_from($file) unless $self->perl_version; $self->author_from($pod) unless @{$self->author || []}; $self->license_from($pod) unless $self->license; $self->abstract_from($pod) unless $self->abstract; return 1; } sub provides { my $self = shift; my $provides = ( $self->{values}->{provides} ||= {} ); %$provides = (%$provides, @_) if @_; return $provides; } sub auto_provides { my $self = shift; return $self unless $self->is_admin; unless (-e 'MANIFEST') { warn "Cannot deduce auto_provides without a MANIFEST, skipping\n"; return $self; } # Avoid spurious warnings as we are not checking manifest here. local $SIG{__WARN__} = sub {1}; require ExtUtils::Manifest; local *ExtUtils::Manifest::manicheck = sub { return }; require Module::Build; my $build = Module::Build->new( dist_name => $self->name, dist_version => $self->version, license => $self->license, ); $self->provides( %{ $build->find_dist_packages || {} } ); } sub feature { my $self = shift; my $name = shift; my $features = ( $self->{values}->{features} ||= [] ); my $mods; if ( @_ == 1 and ref( $_[0] ) ) { # The user used ->feature like ->features by passing in the second # argument as a reference. Accomodate for that. $mods = $_[0]; } else { $mods = \@_; } my $count = 0; push @$features, ( $name => [ map { ref($_) ? ( ref($_) eq 'HASH' ) ? %$_ : @$_ : $_ } @$mods ] ); return @$features; } sub features { my $self = shift; while ( my ( $name, $mods ) = splice( @_, 0, 2 ) ) { $self->feature( $name, @$mods ); } return $self->{values}->{features} ? @{ $self->{values}->{features} } : (); } sub no_index { my $self = shift; my $type = shift; push @{ $self->{values}->{no_index}->{$type} }, @_ if $type; return $self->{values}->{no_index}; } sub read { my $self = shift; $self->include_deps( 'YAML::Tiny', 0 ); require YAML::Tiny; my $data = YAML::Tiny::LoadFile('META.yml'); # Call methods explicitly in case user has already set some values. while ( my ( $key, $value ) = each %$data ) { next unless $self->can($key); if ( ref $value eq 'HASH' ) { while ( my ( $module, $version ) = each %$value ) { $self->can($key)->($self, $module => $version ); } } else { $self->can($key)->($self, $value); } } return $self; } sub write { my $self = shift; return $self unless $self->is_admin; $self->admin->write_meta; return $self; } sub version_from { require ExtUtils::MM_Unix; my ( $self, $file ) = @_; $self->version( ExtUtils::MM_Unix->parse_version($file) ); # for version integrity check $self->makemaker_args( VERSION_FROM => $file ); } sub abstract_from { require ExtUtils::MM_Unix; my ( $self, $file ) = @_; $self->abstract( bless( { DISTNAME => $self->name }, 'ExtUtils::MM_Unix' )->parse_abstract($file) ); } # Add both distribution and module name sub name_from { my ($self, $file) = @_; if ( Module::Install::_read($file) =~ m/ ^ \s* package \s* ([\w:]+) \s* ; /ixms ) { my ($name, $module_name) = ($1, $1); $name =~ s{::}{-}g; $self->name($name); unless ( $self->module_name ) { $self->module_name($module_name); } } else { die("Cannot determine name from $file\n"); } } sub _extract_perl_version { if ( $_[0] =~ m/ ^\s* (?:use|require) \s* v? ([\d_\.]+) \s* ; /ixms ) { my $perl_version = $1; $perl_version =~ s{_}{}g; return $perl_version; } else { return; } } sub perl_version_from { my $self = shift; my $perl_version=_extract_perl_version(Module::Install::_read($_[0])); if ($perl_version) { $self->perl_version($perl_version); } else { warn "Cannot determine perl version info from $_[0]\n"; return; } } sub author_from { my $self = shift; my $content = Module::Install::_read($_[0]); if ($content =~ m/ =head \d \s+ (?:authors?)\b \s* ([^\n]*) | =head \d \s+ (?:licen[cs]e|licensing|copyright|legal)\b \s* .*? copyright .*? \d\d\d[\d.]+ \s* (?:\bby\b)? \s* ([^\n]*) /ixms) { my $author = $1 || $2; # XXX: ugly but should work anyway... if (eval "require Pod::Escapes; 1") { # Pod::Escapes has a mapping table. # It's in core of perl >= 5.9.3, and should be installed # as one of the Pod::Simple's prereqs, which is a prereq # of Pod::Text 3.x (see also below). $author =~ s{ E<( (\d+) | ([A-Za-z]+) )> } { defined $2 ? chr($2) : defined $Pod::Escapes::Name2character_number{$1} ? chr($Pod::Escapes::Name2character_number{$1}) : do { warn "Unknown escape: E<$1>"; "E<$1>"; }; }gex; } elsif (eval "require Pod::Text; 1" && $Pod::Text::VERSION < 3) { # Pod::Text < 3.0 has yet another mapping table, # though the table name of 2.x and 1.x are different. # (1.x is in core of Perl < 5.6, 2.x is in core of # Perl < 5.9.3) my $mapping = ($Pod::Text::VERSION < 2) ? \%Pod::Text::HTML_Escapes : \%Pod::Text::ESCAPES; $author =~ s{ E<( (\d+) | ([A-Za-z]+) )> } { defined $2 ? chr($2) : defined $mapping->{$1} ? $mapping->{$1} : do { warn "Unknown escape: E<$1>"; "E<$1>"; }; }gex; } else { $author =~ s{E}{<}g; $author =~ s{E}{>}g; } $self->author($author); } else { warn "Cannot determine author info from $_[0]\n"; } } #Stolen from M::B my %license_urls = ( perl => 'http://dev.perl.org/licenses/', apache => 'http://apache.org/licenses/LICENSE-2.0', apache_1_1 => 'http://apache.org/licenses/LICENSE-1.1', artistic => 'http://opensource.org/licenses/artistic-license.php', artistic_2 => 'http://opensource.org/licenses/artistic-license-2.0.php', lgpl => 'http://opensource.org/licenses/lgpl-license.php', lgpl2 => 'http://opensource.org/licenses/lgpl-2.1.php', lgpl3 => 'http://opensource.org/licenses/lgpl-3.0.html', bsd => 'http://opensource.org/licenses/bsd-license.php', gpl => 'http://opensource.org/licenses/gpl-license.php', gpl2 => 'http://opensource.org/licenses/gpl-2.0.php', gpl3 => 'http://opensource.org/licenses/gpl-3.0.html', mit => 'http://opensource.org/licenses/mit-license.php', mozilla => 'http://opensource.org/licenses/mozilla1.1.php', open_source => undef, unrestricted => undef, restrictive => undef, unknown => undef, ); sub license { my $self = shift; return $self->{values}->{license} unless @_; my $license = shift or die( 'Did not provide a value to license()' ); $license = __extract_license($license) || lc $license; $self->{values}->{license} = $license; # Automatically fill in license URLs if ( $license_urls{$license} ) { $self->resources( license => $license_urls{$license} ); } return 1; } sub _extract_license { my $pod = shift; my $matched; return __extract_license( ($matched) = $pod =~ m/ (=head \d \s+ L(?i:ICEN[CS]E|ICENSING)\b.*?) (=head \d.*|=cut.*|)\z /xms ) || __extract_license( ($matched) = $pod =~ m/ (=head \d \s+ (?:C(?i:OPYRIGHTS?)|L(?i:EGAL))\b.*?) (=head \d.*|=cut.*|)\z /xms ); } sub __extract_license { my $license_text = shift or return; my @phrases = ( '(?:under )?the same (?:terms|license) as (?:perl|the perl (?:\d )?programming language)' => 'perl', 1, '(?:under )?the terms of (?:perl|the perl programming language) itself' => 'perl', 1, 'Artistic and GPL' => 'perl', 1, 'GNU general public license' => 'gpl', 1, 'GNU public license' => 'gpl', 1, 'GNU lesser general public license' => 'lgpl', 1, 'GNU lesser public license' => 'lgpl', 1, 'GNU library general public license' => 'lgpl', 1, 'GNU library public license' => 'lgpl', 1, 'GNU Free Documentation license' => 'unrestricted', 1, 'GNU Affero General Public License' => 'open_source', 1, '(?:Free)?BSD license' => 'bsd', 1, 'Artistic license 2\.0' => 'artistic_2', 1, 'Artistic license' => 'artistic', 1, 'Apache (?:Software )?license' => 'apache', 1, 'GPL' => 'gpl', 1, 'LGPL' => 'lgpl', 1, 'BSD' => 'bsd', 1, 'Artistic' => 'artistic', 1, 'MIT' => 'mit', 1, 'Mozilla Public License' => 'mozilla', 1, 'Q Public License' => 'open_source', 1, 'OpenSSL License' => 'unrestricted', 1, 'SSLeay License' => 'unrestricted', 1, 'zlib License' => 'open_source', 1, 'proprietary' => 'proprietary', 0, ); while ( my ($pattern, $license, $osi) = splice(@phrases, 0, 3) ) { $pattern =~ s#\s+#\\s+#gs; if ( $license_text =~ /\b$pattern\b/i ) { return $license; } } return ''; } sub license_from { my $self = shift; if (my $license=_extract_license(Module::Install::_read($_[0]))) { $self->license($license); } else { warn "Cannot determine license info from $_[0]\n"; return 'unknown'; } } sub _extract_bugtracker { my @links = $_[0] =~ m#L<( https?\Q://rt.cpan.org/\E[^>]+| https?\Q://github.com/\E[\w_]+/[\w_]+/issues| https?\Q://code.google.com/p/\E[\w_\-]+/issues/list )>#gx; my %links; @links{@links}=(); @links=keys %links; return @links; } sub bugtracker_from { my $self = shift; my $content = Module::Install::_read($_[0]); my @links = _extract_bugtracker($content); unless ( @links ) { warn "Cannot determine bugtracker info from $_[0]\n"; return 0; } if ( @links > 1 ) { warn "Found more than one bugtracker link in $_[0]\n"; return 0; } # Set the bugtracker bugtracker( $links[0] ); return 1; } sub requires_from { my $self = shift; my $content = Module::Install::_readperl($_[0]); my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+([\d\.]+)/mg; while ( @requires ) { my $module = shift @requires; my $version = shift @requires; $self->requires( $module => $version ); } } sub test_requires_from { my $self = shift; my $content = Module::Install::_readperl($_[0]); my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+([\d\.]+)/mg; while ( @requires ) { my $module = shift @requires; my $version = shift @requires; $self->test_requires( $module => $version ); } } # Convert triple-part versions (eg, 5.6.1 or 5.8.9) to # numbers (eg, 5.006001 or 5.008009). # Also, convert double-part versions (eg, 5.8) sub _perl_version { my $v = $_[-1]; $v =~ s/^([1-9])\.([1-9]\d?\d?)$/sprintf("%d.%03d",$1,$2)/e; $v =~ s/^([1-9])\.([1-9]\d?\d?)\.(0|[1-9]\d?\d?)$/sprintf("%d.%03d%03d",$1,$2,$3 || 0)/e; $v =~ s/(\.\d\d\d)000$/$1/; $v =~ s/_.+$//; if ( ref($v) ) { # Numify $v = $v + 0; } return $v; } sub add_metadata { my $self = shift; my %hash = @_; for my $key (keys %hash) { warn "add_metadata: $key is not prefixed with 'x_'.\n" . "Use appopriate function to add non-private metadata.\n" unless $key =~ /^x_/; $self->{values}->{$key} = $hash{$key}; } } ###################################################################### # MYMETA Support sub WriteMyMeta { die "WriteMyMeta has been deprecated"; } sub write_mymeta_yaml { my $self = shift; # We need YAML::Tiny to write the MYMETA.yml file unless ( eval { require YAML::Tiny; 1; } ) { return 1; } # Generate the data my $meta = $self->_write_mymeta_data or return 1; # Save as the MYMETA.yml file print "Writing MYMETA.yml\n"; YAML::Tiny::DumpFile('MYMETA.yml', $meta); } sub write_mymeta_json { my $self = shift; # We need JSON to write the MYMETA.json file unless ( eval { require JSON; 1; } ) { return 1; } # Generate the data my $meta = $self->_write_mymeta_data or return 1; # Save as the MYMETA.yml file print "Writing MYMETA.json\n"; Module::Install::_write( 'MYMETA.json', JSON->new->pretty(1)->canonical->encode($meta), ); } sub _write_mymeta_data { my $self = shift; # If there's no existing META.yml there is nothing we can do return undef unless -f 'META.yml'; # We need Parse::CPAN::Meta to load the file unless ( eval { require Parse::CPAN::Meta; 1; } ) { return undef; } # Merge the perl version into the dependencies my $val = $self->Meta->{values}; my $perl = delete $val->{perl_version}; if ( $perl ) { $val->{requires} ||= []; my $requires = $val->{requires}; # Canonize to three-dot version after Perl 5.6 if ( $perl >= 5.006 ) { $perl =~ s{^(\d+)\.(\d\d\d)(\d*)}{join('.', $1, int($2||0), int($3||0))}e } unshift @$requires, [ perl => $perl ]; } # Load the advisory META.yml file my @yaml = Parse::CPAN::Meta::LoadFile('META.yml'); my $meta = $yaml[0]; # Overwrite the non-configure dependency hashs delete $meta->{requires}; delete $meta->{build_requires}; delete $meta->{recommends}; if ( exists $val->{requires} ) { $meta->{requires} = { map { @$_ } @{ $val->{requires} } }; } if ( exists $val->{build_requires} ) { $meta->{build_requires} = { map { @$_ } @{ $val->{build_requires} } }; } return $meta; } 1; Excel-Template-0.34/inc/Module/Install/Win32.pm000644 000765 000120 00000003403 11747312613 021031 0ustar00rboadmin000000 000000 #line 1 package Module::Install::Win32; use strict; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.01'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } # determine if the user needs nmake, and download it if needed sub check_nmake { my $self = shift; $self->load('can_run'); $self->load('get_file'); require Config; return unless ( $^O eq 'MSWin32' and $Config::Config{make} and $Config::Config{make} =~ /^nmake\b/i and ! $self->can_run('nmake') ); print "The required 'nmake' executable not found, fetching it...\n"; require File::Basename; my $rv = $self->get_file( url => 'http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe', ftp_url => 'ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe', local_dir => File::Basename::dirname($^X), size => 51928, run => 'Nmake15.exe /o > nul', check_for => 'Nmake.exe', remove => 1, ); die <<'END_MESSAGE' unless $rv; ------------------------------------------------------------------------------- Since you are using Microsoft Windows, you will need the 'nmake' utility before installation. It's available at: http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe or ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe Please download the file manually, save it to a directory in %PATH% (e.g. C:\WINDOWS\COMMAND\), then launch the MS-DOS command line shell, "cd" to that directory, and run "Nmake15.exe" from there; that will create the 'nmake.exe' file needed by this module. You may then resume the installation process described in README. ------------------------------------------------------------------------------- END_MESSAGE } 1; Excel-Template-0.34/inc/Module/Install/WriteAll.pm000644 000765 000120 00000002376 11747312613 021662 0ustar00rboadmin000000 000000 #line 1 package Module::Install::WriteAll; use strict; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.01'; @ISA = qw{Module::Install::Base}; $ISCORE = 1; } sub WriteAll { my $self = shift; my %args = ( meta => 1, sign => 0, inline => 0, check_nmake => 1, @_, ); $self->sign(1) if $args{sign}; $self->admin->WriteAll(%args) if $self->is_admin; $self->check_nmake if $args{check_nmake}; unless ( $self->makemaker_args->{PL_FILES} ) { # XXX: This still may be a bit over-defensive... unless ($self->makemaker(6.25)) { $self->makemaker_args( PL_FILES => {} ) if -f 'Build.PL'; } } # Until ExtUtils::MakeMaker support MYMETA.yml, make sure # we clean it up properly ourself. $self->realclean_files('MYMETA.yml'); if ( $args{inline} ) { $self->Inline->write; } else { $self->Makefile->write; } # The Makefile write process adds a couple of dependencies, # so write the META.yml files after the Makefile. if ( $args{meta} ) { $self->Meta->write; } # Experimental support for MYMETA if ( $ENV{X_MYMETA} ) { if ( $ENV{X_MYMETA} eq 'JSON' ) { $self->Meta->write_mymeta_json; } else { $self->Meta->write_mymeta_yaml; } } return 1; } 1;