pax_global_header00006660000000000000000000000064131431223540014510gustar00rootroot0000000000000052 comment=2641493b64c9999cb3b4b5f72e910d436b702a6a llgal-llgal-0.13.19/000077500000000000000000000000001314312235400140475ustar00rootroot00000000000000llgal-llgal-0.13.19/COPYING000066400000000000000000000430761314312235400151140ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE 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 Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. llgal-llgal-0.13.19/Changes000066400000000000000000001422721314312235400153520ustar00rootroot00000000000000llgal (0.13.19) * The llgal website has moved to http://bgoglin.free.fr/llgal * The repository moved to http://github.com/bgoglin/llgal * The mailing list is now llgal@googlegroups.com -- Brice Goglin Thu, 10 Aug 2017 20:24:00 +0200 llgal (0.13.18) * Fix slidenames for subgalleries when -n is used (reported by Richard Betham in Debian bug #652929). * Fix the recognition of existing captions file entries when filenames contain special characters. * Check whether there is a user-given thumbnail before listing as links when -L is given. Thanks to Gabor Kiss for the patch in Debian bug #683809. * Make --cf work with subdirectory entries by not removing the extension and just using the entire directory name (reported by Bruno Raoult). * New option (thumbnails_dimensions_from_css) to avoid any thumbnail dimension in generated HTML. * Add support for replacing with the corresponding Exif tag in the slide template. Thanks to Charles Nepote. * Really initialize exiftool only once per gallery. -- Brice Goglin Mon, 01 Aug 2016 22:25:00 +0200 llgal (0.13.17) * Fix the description of -n in the manpage (thanks Paul Menzel in Debian bug #579096). * Fix miscellaneous typos everywhere, reported by Debian's lintian. * Adapt default convert command-line for graphicsmagick compatibility (reported by Kenyon Ralph in Debian bug #604106). -- Brice Goglin Tue, 02 Aug 2011 12:31:00 +0100 llgal (0.13.16) * Add exifdesc to --cc to generate the caption from the Exif image description (thanks Fmiser). * Add LNKNOSLIDE: entry support for direct links without slide, as if LNK_link_to_target was set to 1 (requested by Nathalie Furmento). * Add --nf and slide_link_to_full_image to remove links from scaled images in slides to full unscaled images (thanks Maximilian Wilhelm). * Display Exif coordinates in decimal format (thanks Fmiser). * Fix typos in the german translation (thanks Nadar). * Fix replacing of (thanks Steffen Klatt). * Fix support for filenames with initial dash character in convert command-lines (thanks Tiago Bortoletto Vaz in Debian bug #570553). * Fix PARENT and PREV/NEXT links between galleries, honor user changes in the captions file instead of overriding with the default values (reported by Gerfried Fuchs in Debian bug #478699). * Clarify in the manpage that replacing variables will never automatically add double-quotes (requested by Samuel Thibault). * Document better how to provide custom thumbnails and scaled images using mythumb_ and myscaled_ prefixes. -- Brice Goglin Sat, 27 Feb 2010 20:46:00 +0100 llgal (0.13.15) * Thumbnails now always point to the slide, even if it just contains a link to a file, directory, movie or URL. + Add MVI/FIL/DIR/LNK_link_to_target options to revert to the previous behavior (thumbnail pointing to the target). * Add an optional parameter to --ct to pass the strfime format instead of having to pass both --ct and --ctf. The old --ctf is kept for backward compatibility but not documented anymore. * Do not insert the default index title in the captions file if it is already defined (reported by Sebastian Schmidt in Debian bug #452945). + The index_title configuration options is replaced with index_title_default. * Do not escape URLs from LNK entries. * Use internal Perl functions instead of calling external programs when manipulating basic files. -- Brice Goglin Sat, 15 Dec 2007 18:12:00 +0100 llgal (0.13.14) * Add German translation, thanks Thomas Heßling! * Add Italian translation, thanks Gianelle Alessio! -- Brice Goglin Sun, 18 Nov 2007 16:20:00 +0100 llgal (0.13.13) * Improve the speed to 'Listing entries...' dramatically (reported by Martin Ferrari in Debian bug #431939): + Retrieve image dimensions while listing entries, either with ExifTool if it is already needed for something else, or with Image::Size. + Check image validity by looking at its dimensions instead of calling the very slow 'identify' command. * Check the validity of thumbnails and scaled images too, also by looking at their dimensions: + bad user-given thumbnails or scaled images are ignored; + bad llgal-generated ones lead to skipping their whole entry. * A couple minor optimizations by caching values computed multiple times (image dimensions, filenames, exif tags list, ...). * Make sure --www changes the access rights of original images too. * Do not warn when the LANGUAGE environment variable is defined but empty. -- Brice Goglin Sun, 08 Jul 2007 16:37:00 +0200 llgal (0.13.12) * Add configuration file option slide_dimensions_from_css to remove absolute image sizes in slides and let the user configure it from the CSS (requested by Olivier Schwander). * Fix --lang which did not work when current locale and --lang argument have different encodings (UTF-8 versus no UTF-8). * Add a warning then the LANGUAGE environment variable is defined. + Ship a dummy english translation so that LANGUAGE is correctly used when it contains an english locale. * Howto improvements: + Add how-to jump to the next slide when clicking on the current one (requested by Elmar Eberhardt and others). + Add how-to scale images and drop the originals. + Add a paragraph about why changing --tx without --ty (or the contrary) might not give the expected results since changing one does not affect the other one. - Also document all this in the manpages and llgalrc example. + Add a paragraph about when thumbnails or scaled images are regenerated and how to force it. + Add a paragraph about having the images in slides adapt to the window size using the new slide_dimensions_from_css option. + Minor fixes. -- Brice Goglin Tue, 17 Apr 2007 00:01:00 +0200 llgal (0.13.11) * Fix sorting of entries (with criteria {rev,}{time,date,size}) in recursive mode (reported by Sebastien Mei). * Restore the prefetch header in the slide template. * Add index and contents headers to both slides and index templates. * Install the config file in the doc/ directory instead of /etc/llgal/ since it only contains documentation, no actual configuration. + Point to it in the SEE ALSO section of llgalrc manpage. * Hack the parameters that are passed during Perl modules installation to deal with MakeMaker not using PREFIX in the common way. Without this change, setting PREFIX=/usr/local on the make install command line was installing in /usr/local/local/perl. -- Brice Goglin Sat, 24 Mar 2007 01:54:00 +0100 llgal (0.13.10) * Fix removing of old www-pages and generation of thumbnails and scaled images when target directory contains special characters (thanks to Jeremie Koenig for the patch in Debian bug #408873). * Fix typo in llgalrc.5. -- Brice Goglin Mon, 29 Jan 2007 21:21:00 +0100 llgal (0.13.9) * Add missing double-quotes in command-lines when generating scaled images and thumbnails so that filenames with spaces are supported (reported by Florian Schlichting in Debian bug #398814). * Some improvements regarding the manpage: + Add configuration file option names near the corresponding command-line options (requested by Florian Schlichting in Debian bug #398826). + Add a note in CONFIGURATION about how configuration files are used during recursive gallery generation with -R (caused by Florian Schlichting's Debian bug #398826). + Add a manpage for llgalrc and move configuration file options from the main manpage into it. + Add install-man and uninstall-man in the Makefile to install manpages on demand. + A few fixes. * Some minor fixes in the comments in llgalrc. -- Brice Goglin Thu, 16 Nov 2006 21:47:00 +0100 llgal (0.13.8) * Drop --con and *convert_options, and replace them with more generic options (scaled/thumbnail_create_command) where special fields are replaced. + See the new section THUMBNAILS AND SCALED IMAGES GENERATION in the manpage for details. + Add tweak_image_generation.txt in doc/examples/ to show how to use it to replace convert with another image processing library (requested by Emmanuel Jeandel) or apply effects during image generation (requested somehow by Alexandre Buisse). * Add questions about speed and images-modification-features in the How-To. * Fix the command line that is inserted in the HTML headers by replacing double-quotes. * Add install-doc and uninstall-doc in the Makefile to help distrib to install documentation (requested and fixed by Alexandre Buisse). -- Brice Goglin Thu, 09 Nov 2006 11:07:00 +0100 llgal (0.13.7) * Add <--SLIDE-NUMBER--> to be replaced with the slide number (with leading zeros), <--SLIDE-COUNTER--> to be replaced with the slide counter according to slide_counter_format as in the caption, and to be replaced by the number of slides. * Addition of doc/examples/ for various examples: + dynamic_comments_in_slides/ contains some files to explain "How do I let people add comments to my slides dynamically?" (also added to the How-To). * Disable the film effect by default (requested by lots of people) and thus change --nf to --fe to reenable it. * Fix W3C compliance of the film tile (reported by Jean-Claude Noel). + Add alt_film_tile_text configuration options to change the film alternative text. * Fix W3C compliance of horizontal lines generated with LINE entries. * Support building/installing only some locales by passing something like LOCALES="fr de" on the make command line (requested by Alexandre buisse). * Minor fixes in the manpage. * Fix missing Perl use (*convert_options were broken). * Cleanup Perl regexps. * Fix Perl modularization, no need to use Exporter module since we access modular functions by prefixing with the module name. -- Brice Goglin Thu, 19 Sep 2006 21:47:00 -0400 llgal (0.13.6) * Fix a major bug in slides' layout, which led to always use text-slide style even for images, making the margins wrong. * Fix the locale of gettext translations (such as "Précédent" in French) by adding missing headers in the po files (thanks to Samuel Thibault for the fix and Nicolas Guénot for the report). * Fix linking between subgalleries when making no slides. * Fix computing of thumbnail row width when deciding how many thumbnails to output on a row, use the correct width for padded thumbnail boxes. * Fix missing link from listed text in the index to the corresponding text slide when -L is passed (reported by Émilie Le Roux). * Fix uninitialized dimensions string when not generating any slide. * Fix verbose configuration option definition in recursive mode since it was breaking generated config file (reported by Gerfried Fuchs). * Fix error reporting mixed with unfinished lines (especially during percentage progression), and add missing errno printing and ending dot. * Fix configuration option line parsing error handling and displaying. * -L only suppresses thumbnails, not slides since the main goal was to create a list of subgallery links without slides, but it may be achieved with -L -s anyway. + Document how to use -L -s to create a text menu of sub-galleries (see the How-To file). * Replace link_between_last_and_first_slide with link_between_last_and_first and make it work with subgallery linking too (requested by Gerfried Fuchs in Debian bug #377780). * Do not link text thumbnails to a slide when not generating any slide. * Do not take templates in the parent .llgal directory when running in recursive mode, use the local ones instead (reported by Gerfried Fuchs). To take the parent one, --template may be used. * Get captions.header from any template directory so that it works when installed anywhere. Add a notice message, and be sure messages don't mess up with the on-going caption generation percentage. * Do not load Image::ExifTool unless required by --exif, --cc or --ct (requested by Alexandre Buisse). * Add a CSS style for captions (requested by Alexandre Buisse). * Add the command line options to the generated slides, and to the captions file (on both creation and appending) * Add to the list of replaced fields, without immediately using it for now. * Add empty lines around the captions headers in the generated captions file. * Document how to prevent llgal from erasing the captions file (see the How-To file). * Add the date to the program name when compiling it from SVN. -- Brice Goglin Sun, 03 Sep 2006 11:26:00 -0400 llgal (0.13.5) * When linking to galleries, add the index filename to the URL so that these links work even without a web server (thanks to Michael Waschbüsch for the patch). * Document how to add keyboard shortcuts to the gallery with HTML accesskeys (see the How-To file). * Various fix for links to previous/next galleries: + Only keep the last part of the path to generate the name that is used in links to prev/next galleries. + Fix broken PREV/NEXT: entry generation in the gallery. + Fix links to prev/next galleries when the current gallery current both some subdirectories and regular files. + Drop --prev/next-gal and {prev,next}_gallery_link{,_target} since only the captions file is more suited to configure this. {prev,next}_gallery_link_text remains to configure the link text prefix. * Document --parent-gal options in the usage since it is not internal anymore (reported by Samuel Thibault). -- Brice Goglin Thu, 04 Jul 2006 23:41:00 -0400 llgal (0.13.4) * --exif without argument shows all exif tags that exist in the image. * Add --Pall (and recursive_sections) to create a section of images for each subdirectory as if -P was used for each of them. * Add entitle_sections configuration option to explicitely enable the generation of a title for each section. separate_sections now only configures the generation of a horizontal line. --Ps still enables both. * Add REPLACE keyword in the captions for a configurable replacement in the HTML pages (requested by Alexandre Buisse). * -v is now --verbose (and verbose configuration option has been added). + Add/convert some messages to be printed when --verbose is passed. + --version is now -V. * Improve replacement of fields when generating the slides and index HTML pages. + More tiny optimizations of the HTML slide and index generation by precomputing more fields. * Add link_between_last_and_first_slide configuration option to disable the links between the last and first slides. * Fix generation of configuration file when an old has to be renamed. * Fix image title and alternative in HTML slides. * Some fixes in the manpage. * Update captions.header with last caption entry types. * Add a doc/ subdirectory: + The How-To is now also included in the tarball. + UPGRADE is now HTML'ized as upgrade.html. -- Brice Goglin Thu, 11 May 2006 11:40:00 +0200 llgal (0.13.3) * Add -P (and section_dir) to use photos in a special subdirectory instead of the working directory. May be used multiple times to create a unique gallery with photos from several subdirectories (requested by Samuel Mimram and Samuel Thibault). + Add --Ps (separate_sections) to automaticaly add BREAK and TXT entries at the beginning of each section. * When -n is passed, slide filename is generated from the image filename and the slide filename prefix (it helps cleaning HTML files). + Add a note about slide_filenameprefix == "" which could lead to removal of non-llgal HTML files. * When -L is passed, TXT entries are listed without thumbnails in the index, but they still appear as a slide (it will help creating sections). * Fix several operations on thumbnails and scaled images when -d is passed. * Do not waste time in ExifTool when there's nothing to do (do not read tags when none is required, and initialize on demand). * Optimize slide generation a little bit by pre-computing fields before actually filling the template. * Improve percentage printing for progression. -- Brice Goglin Sun, 30 Apr 2006 23:31:00 +0200 llgal (0.13.2) * --cf now does not include the filename extension in the caption (requested by Alexandre Buisse). + make_caption_from_extension may be used to add the extension as previously. * Support subdirectory images that the user may add to the gallery by inserting their path in the captions file. + Thumbnails and scaled image filenames are generated after replacing the path separator (/) with the new configurable path_separator_replacement. * Do not create a thumbnail or scaled image if the original is already smaller than the maximal dimensions. * Fix -h/--help. -- Brice Goglin Thu, 27 Apr 2006 00:32:00 +0200 llgal (0.13.1) * Force regeneration of thumbnails and scaled when the original image has been modified since their creation. * Fix --option (reported by Alexandre Buisse). -- Brice Goglin Tue, 18 Apr 2006 16:51:00 -0700 llgal (0.13) * Add --exif (and show_exif_tags) to display a table of exif tags under each image slide (requested by Alexandre Buisse). The layout is defined by in the slide template and some new CSS styles. * Replace show_no_slide_counter in the configuration file with slide_counter_format where %n, %0n and %t will be replaced dynamically. The old show_no_slide_counter now corresponds to slide_counter_format="". + By default, the slide counter gets leading zeros (requested by Alexandre Buisse). * Add the BREAK keyword to be used in captions file to force a line break in a row of thumbnails (requested by Alexandre Buisse). * Improve slide filename: + Change default prefix to 'slide_'. + Drop slide_filenameprefix_nofile and use slide_filename_prefix for slides that have no file associated with them. + Add leading zeros to the number in the slide filename. * By default, thumbnail width is now limited (113px). + When a thumbnail_max_width is defined, force all thumbnail boxes to this width by padding the thumbnail. + The previous behavior (unlimited width and unpadded thumbnails) may be restored with thumbnail_width_max=0. * Replace --bigxy and --bigy with --sx and --sy to reduce slide images. * Replace --xy and -y with --tx and --ty to change thumbnail size. * Replace -r with --nf to omit film effect in the index. * Drop -t option to change the film time effect height (filmtile_height) since the layout does not need it anymore. The user may easily change the film tile image without having llgal do it. * Fix the film effect when the tile image size is modified by forcing the height of the row to be exactly the height of the image. We could use nice CSS to do so, but Internet Explorer CSS support sucks too much. * Use $(MAKE) instead of make in recursive invocation in the Makefile (FreeBSD breakage reported by George Wood). * Use Image::ExifTool instead of Image::Infos (thanks to Alexandre Buisse). * Do not remove all html files on --clean and when regenerating the gallery, but only those files that match index filename or slide filename prefix (requested by Alexandre Buisse). * Do not scale image when smaller than the thumbnail. * Do not warn when the local llgal directory is ignored outside of early configuration if the value would not actually change. * Fix slide numbering depending on LINE entries. * Fix a warning about an uninitialized value being used when --ct without any timestamp available (reported by Alexandre Buisse). * Fix a warning about an uninitialized value being used when the gallery is empty. * Perl-modularization. -- Brice Goglin Sun, 16 Apr 2006 19:53:00 -0400 llgal (0.12.2) * Add --lang and --codeset to change the locale or encoding (and the corresponding language and codeset configuration option). --lang appears to not work if the LANGUAGE environment variable is set. * -L now lists links between the thumbnail rows according to the order of the entries. Listing at the end is still possible by moving the entries at the end of the captions file. * Add the LINE keyword to be used in captions file to generate a horizontal line. * Recursion is now processed in the same process, enabling future shared information between galleries for improved links. + Remove --indent internal option. + Keep --parent/prev/next-gal in case the user wants to override them. * Cleanup and improve configuration file generation: + Do not export unmodified options since it would prevent a default modification to be seen. + If the configuration file to create already exists, rename it with with the current timestamp and generate a new one. + Add the current timestamp to the generated configuration file. + The special target "local" creates .llgal/llgalrc in the destination directory. + When recursive, "local" generates a configuration file in all subdirs while not "local" only generates in the working directory. + Print a message when generating. * Large rework of configuration parsing: + Additional files passed with --config or additional_configuration_file are parsed as soon as the option is met, before processing any of the following options. + Avoid parsing a configuration file multiple times in case of recursive galleries. + Cleanup and improve option checking, with better error reporting: - Options that are not a string must now be numeric. * make_recursive configuration option is now called recursive. * Replace template_dir with additional_template_dir in configuration file and move it to various options together with additional_configuration_file. * Restrict directory configuration to cleanup the code: + Remove llgal_share_dir and user_share_dir since additional_template_dir is enough. + The local llgal directory name may be changed only by the system-wide (/etc/llgal/llgalrc) or the user-wide file ($HOME/.llgal/llgalrc). * Replace
in the generated HTML with margins in the CSS. * User-provided scaled images are also used in slides even if --bigy/--bigxy was not passed (no scaled images). * When the local llgal directory name is changed (with local_llgal_directory) the local configuration file is read from the corresponding directory, not from .llgal/. * Hardcode default english values in usage to avoid messing the code. * Don't forget to remove the templates that might have been gotten in the local llgal directory (with --gt) and not been modified. * Remove useless buggy print in captions generation. * Fix manpage additional_configuration_file name (instead of config_file). * Fix slide_height_max processing. * Fix some special cases in --www. * Some cleanups. -- Brice Goglin Tue, 7 Mar 2006 22:44:00 -0500 llgal (0.12.1) * Set HTML encoding header depending on the locale with the new LLGAL-CODESET replace pattern in the templates (reported by Marcus Better in Debian bug #343546). * Really really parse command-line options after configuration files. * Pass -w to perl interpreter and fix several warnings. * Add a "requested by" in the Changes. * Document LLGAL-OPTIONS replace pattern in the manpage. -- Brice Goglin Wed, 21 Dec 2005 00:59:26 -0500 llgal (0.12) * Add internationalization support for the text that is automatically embedded in the HTML pages. See LANGUAGE in the manpage for details. * Add french translation. * Support custom thumbnails for all file-based entries with the mythumb_ prefix (and an additional image extension for non-images) in the .llgal directory (requested by Sebastien Mei). * Support custom scaled images for all file-based entries with the myscaled_ prefix (and an additional image extension for non-images) in the .llgal directory. * Add credits_text option and replace CREDITS in the templates. * Add bmp to default image extenstions and ogm and wmv to movie when scanning the working directory. * image_extensions and movie_extensions are now explicitely a |-separated list without regexp inside. * Fix -d and -R by checking the destination directory after -d has been parsed (reported by Marcus Better in Debian bug #329168). This is done by parsing -d very early, which is required since it changes the location of the local configuration file (hopefully, it cannot be overridden in a configuration file). * Cleanup destination directory name printing. * Major cleanup of the manpage. * Minor fix in the README. * Typos in the Changes. -- Brice Goglin Thu, 15 Dec 2005 12:47:26 -0500 llgal (0.11.4) * Really parse command-line options after configuration files (thanks to Dave Holland in Debian bug #340315). * Trailing spaces and other small cleanups. -- Brice Goglin Tue, 22 Nov 2005 13:18:26 -0500 llgal (0.11.3) * Add --uc and css_location to use a CSS style-sheet that is already available on the web. * Add --ui to use images for filmtile and links that are available on the web. + Add filmtile_location, index_link_image_location, prev_slide_link_image_location and next_slide_link_image_location for a per-image configuration. * Fix -d with an absolute directory. * Fix --option which was broken since last release. + Do not show usage after the error message when a --option parameter could not be parsed. * Fix missing update of sanity checks, numerical options processing, and various other options that were broken since previous release (reported by Hanus Adler in Debian bug #337380). * Do not parse behavior options at the beginning since there's no more any reason. Command line options are thus processed after all configuration files. This makes -f work if a config file contains force_image_regeneration = 0 (reported by Hanus Adler in Debian bug #337380). * Rename tile_height with filmtile_height for consistency. * Fix percentage printing by showing both entry listing and preparing. * Fix slidetemplate to use images for link on the bottom as on the top. * Check that all filenames given in the configuration don't contain a slash. * When compiling from SVN, add a +svn suffix to the version. * Add a VERSION file. -- Brice Goglin Wed, 9 Nov 2005 00:44:26 -0500 llgal (0.11.2) * Add --php to generate webpages with the php extension instead of html (requested by David Baelde). Templates are still named with the html extensions. The www_extension configuration option also enables extension configuration. The -i option (index_filename) thus now takes a filename without extension. * -R now implies -S (suggested by Brian Donlan's Debian bug #329168): * When called with -d, llgal only reads the llgalrc configuration file in the destination directory since the local one may be easily added through --config. * Add recursive --gt (give templates to all subdirectories). * Slides without file now have they slide_filename numbered with the number of the slide for make_slide_filename_from_filename (-n) instead of starting from 1. * Add prev_gallery_link_target to split enabling and target. Add missing documentation for prev/next_gallery_link[_text]/link_subgalleries and fix option processing. * Add force_image_regeneration configuration option for -f. * Rework the internal code to easy multiple gallery generation in the same process. * Reorganize usage and manpage with an 'additional behavior' and 'selecting files' sections. * Add TEMPLATES section in the manpage to document the replacement of fields when generating webpages from the templates. * Update all contact addresses and URLs since the project is now hosted by Gna!. -- Brice Goglin Thu, 22 Sep 2005 10:00:00 +0200 llgal (0.11.1) * Rename /etc/llgalrc to /etc/llgal/llgalrc. Also read ~/.llgal/llgalrc and .llgal/llgalrc. + Warn if an old file is found, and skip it. * Add --li and --lt options to replace link labels in slides with image (requested by Cyrill Helg): + index.png, prev.png and next.png are added to show arrows for --li. + A thumbnail is shown to preview prev/next slide (if IMG) for --lt. + slidetemplate is a little bit modified. - The Index link is now _betwee_ Prev and Next. + The css template is a little bit extended. + Add configurable text that is shown when the mouse pointer is over these links. * Allow to change the label of links to index/prev/next in slides with prev/next_slide/index_link_text. * Add --Rl to add links between subgalleries. + Add --next/prev-gal internal options to set links to prev/next galleries. * Write the title and parent/prev/next gallery in the captions file when generating. Update them when appending (without removing the previous definition if it exists). + Add PARENT/PREV/NEXT captions line for gallery links. * Rename parent_link* to parent_gallery_link*. Replace --parent with --parent-gal and undocument in --help (keep in manpage). * Rename _linktext options to _link_text. * Remove no_default_link_text since link text values might be modified at runtime, and also after captions generation. * Rename MVI/FIL/DIR_default_link_text to MVI/FIL/DIR_link_text. * Remove --sp and --tp command line options, keeping their configuration options (scaled_image_filenameprefix and thumbnail_image_filenameprefix). * One more reorganization of options in llgalrc and generated config files. Hope this one will be fine. * Fix compilation and installation when DESTDIR is overridden. * Fix and cleanup documentation and Makefile. -- Brice Goglin Wed, 14 Sep 2005 09:43:55 +0200 llgal (0.11) * The local llgal directory is now .llgal instead of .llgal.files. + A warning is shown if .llgal.files exists. * Add -L and list_links to list links after the gallery index instead of creating slides and thumbnails (requested by David Baelde). * All links in the index directly open the target instead of the slide, not only MVI and FIL (requested by Samuel Thibault). * The captions file is now automatically used if it exists (-c option got removed). * Improved usage of image comments for captions: + use JFIF/GIF comment by default (closes Wolfram Quester's Debian bug #324478). + support array of strings in JFIF comment. + remove \000 in JFIF comment. + make_caption_from_image_comment is now a string option of comma separated fields: - std and exif are supported. - each type is tried until one returns a non-empty value. - basic types maybe combined with a plus to concat their values. + update --cc option behavior: - no argument means default (std before exif). - 0 means no caption from comment. - any other string defines make_caption_from_image_comment. * Cleanup title of image, alternatives, ... + Add over_scaled/thumbnail_text configuration options to change texts that are shown when the mouse pointer is over images. - Add "Click to enlarge" default prefix for thumbnails. + Add alt_scaled/thumbnail/full_text configuration options to change alternatives prefix, and add defaults. + Show dimensions and filesize in alt and title. + Add title to links in the index and in slides. + Remove colon between image title prefix and image. + Use same basis for image alternative and title. + Don't use basename anymore, always use the whole filename instead. + When possible, the HTML title parameter is in href instead of img. * Cleanup location and copying of special llgal files (requested by Loïs Taulelle) : + index/slidetemplate.html are not copied to .llgal anymore. + The user might put a special revision of index/slidetemplate.html in .llgal, llgal will use it. + Add --gt option to copy templates in the local, user or any other template directory. + Add --templates option (add template_dir configuration option) to add a custom template directory. * Move several text configuration options to a common Text section in llgalrc and in the manpage. + Add a LANGUAGE section in the manpage for changing text options. * Add iname and size sort options, add rev prefix to reverse the order. * Remove destination_dir configuration option. * caption_removal_line config option is now captions_removal_line. * Warning if it seems llgal is running inside .llgal. * Add all default values of configuration options in the manpage. * Add captions.header file which contains what's inserted at the beginning of generated captions files. * Allow empty gallery. * Spaces are now supported in convert options. * Check for -h or -v earlier. * Add .tif[f] and .mov to default image and movie extensions (requested by Cyrill Helg). * Don't use file operators to check file permissions (closes Marcus Better's Debian bug #325171). * Remove "in "at the end of DIR_default_linktext. * Fix completely broken -R processing (reported by Cyrill Helg). * Fix chmod'ing for --www. * Fix bogus output of configuration file for MVI/FIL/DIR_default_linktext and no_default_linktext. * Fix string config option that might be empty or not. * Fix bogus parsing of additional_configuration_file option. * Update contact address to gna.org and add it to README. * Lots of cleanups and typos. -- Brice Goglin Sat, 7 Sep 2005 23:30:55 +0200 llgal (0.10.1.1) * Fix bogus check of .llgal.files attributes. -- Brice Goglin Sat, 20 Aug 2005 01:32:55 +0200 llgal (0.10.1) * Rework the text that is shown in links (MVI, FIL and DIR types) by default (when no captions file exists): - Show the extension, not only the filename. - Add an prefix text depending on the link type. - Add MVI/FIL/DIR_default_linktext options to change this text. - Add no_default_text option so that this text is not shown (only the filename is shown). * Document and improve link to parent gallery in subgalleries: - make_parent option adds a header and a footer linking to the parent (like --parent). - parent_linktext option changes the text in these links. * Add an UPGRADE file to document upgrading galleries from igal to llgal. * Cleanup a few stuff in the CSS. * Fix some inline styles in the HTML code. * Fix quotes around string option in the manpage. * Fix a few missing $ in regexp matching lines in configuration files. * Fix a few typos. * Remove "reel" near "film effect" everywhere. -- Brice Goglin Fri, 19 Aug 2005 16:42:10 +0200 llgal (0.10) * Add the FIL type for files that are neither an image nor a movie. FIL is similar to LNK, but the file size is shown since it can be locally accessed. * Improve scanning of files in the working directory when no captions file exists: - By default, only images and movies are added to the gallery. - Add image/movie_extensions options to change which files are recognized as images or movies. - Add -A to force addition of all files to the gallery, not only images an movies. - Add -S to force addition of all subdirectories to the gallery. - Add --exclude and --include to remove or re-add files to the list of processed files in the working directory. Multiple instances are allowed and the order is respected. - Add --sort to sort with another criteria than name. - Sort filenames before creating entries so that slide numbering does not become wrong later. * -R now does only run recursively in subdirectories, it does not scan existing subdirectories in the working directory anymore: - If no captions file exists, -R should now be used together with -S to both define the list of subdirectories and then process them recursively. - If a captions file exists, all subdirectories that it defines are processed when -R is passed. * convert options are now converted into an array, spaces inside options are not supported for now. * Check that additional configuration files (--config ) exist and are regular files. * Fix captions file header. * Fix Debian tarball generation. * Fix typos in the README. * Remove version number in slidetemplate.html since it's useless and never up-to-date. * Remove useless check for old igal filenames. * Cleanup system usage and error reporting. * Use -s to get file size. * Use _ to optimize consecutive file test operations. * A few typos. -- Brice Goglin Wed, 17 Aug 2005 11:29:59 +0200 llgal (0.9.10) * Fix cleaning (not recursive by default). * Fix directory when stating of images/movies. * Make subdirectory world readable and traversable for --www. * Don't make scaled images world readable for --www when there's no scaled images. * Do not exit after processing --www. * Don't allow --bigxy with -s (same than --bigy with -s). * Old HTML files have to be removed from the main directory, not local_llgal_dir. * Add Character Encoding section to the manpage. * Make non-ascii character warning shorter. * Use cmp instead of diff to avoid verbose messages. * Cleanup system usage and check return value. * Large cleanup of warning code. * Don't forget to include Changes and COPYING in the tarball. * A few typos. -- Brice Goglin Fri, 5 Aug 2005 00:59:07 +0200 llgal (0.9.9) * Implement recursive caption and subgallery generation with -R. * Implement recursive cleaning without checking whether a subdirectory is in the caption file. * Add --parent internal option to add link to parent gallery in subgalleries (not documented). * Add --indent internal option to indent subgalleries messages (not documented). * Split usage into behavior and layout options. * Cleanup separation between behavior and layout in the manpage. * Add missing description of --gencfg in the manpage. * Remove messages when chmod'ing for --www. * Cleanup code indentation around die. * A few typos. -- Brice Goglin Wed, 3 Aug 2005 03:17:43 +0200 llgal (0.9.8) * -c is now only used to read captions from file. Generating captions is done with --gc. * Caption file generation now scans an existing caption file and add a caption for all missing files. * A few typos. -- Brice Goglin Tue, 2 Aug 2005 12:12:18 +0200 llgal (0.9.7) * -C becomes --cf (use file names as captions). * -x becomes --nc (do not show image counter in caption) * Add a clean target to the Makefile. -- Brice Goglin Mon, 1 Aug 2005 21:54:12 +0200 llgal (0.9.6) * Check file existency and image validity. * Cleanup error reporting and file skipping on errors. * Add a README file to help manual installation. * Add -v and --version. * Automatically set version in usage at install. -- Brice Goglin Sun, 1 May 2005 18:19:09 +0200 llgal (0.9.5) * Fix text slides (do not make a link). * Do not generate thumbnails or scaled images when generating captions. * Show percentage when generating captions. * Fix some messages. -- Brice Goglin Sun, 24 Apr 2005 00:02:27 +0200 llgal (0.9.4) * Show progession with percentage instead of dots. -- Brice Goglin Wed, 13 Apr 2005 00:16:02 +0200 llgal (0.9.3) * Fix caption parsing so that "IMG: " is the default type. -- Brice Goglin Tue, 12 Apr 2005 19:09:41 +0200 llgal (0.9.2) * Use llgal.in to replace /etc/ and /usr/share/ directories during install. * Generate Gentoo tarball in the Makefile (thanks to David Baelde for the ebuild). -- Brice Goglin Sat, 9 Apr 2005 20:10:38 +0200 llgal (0.9.1) * Allow slide_filenameprefix to be empty in configuration file. * Fix timestamp saving in configuration file. * Remove version from manpage. -- Brice Goglin Sun, 27 Mar 2005 00:29:05 +0100 llgal (0.9) * Add --bigxy and slide_width_max option. * Replace --ce and make_caption_from_exif with --cc and make_caption_from_image_comment. * Add --ct and make_caption_from_image_timestamp to get timestamp for image tags (based on James R. Van Zandt's patch proposed in igal's Debian bug #162720). * Add --ctf and timestamp_format_in_caption to change timestamp format in caption. * Cleanup EXIF comment by removing end \0 and \n. * Captions and textlink are now stored in a HTML-safe manner. * Delay unsafe url warning after the last entry preparation. * Merge and cleanup all processing of each entry. * Cleanup llgal file obtention. -- Brice Goglin Fri, 4 Mar 2005 22:41:37 +0100 llgal (0.8.2) * Use Perl Image::Info to get JPEG EXIF or GIF comment. * Remove exiftags usage. * Support non-ascii filenames. * Fix filename sort. * Replace & and " with html codes in title, text and caption. * Final fix of caption reading regexps to force required fields to be non-empty. * Replace bigy_* option with scaled_*. * Default scaled image prefix is now "scaled_". * Don't always reopen the slidetemplate file. * Cleanup of internal entry fields. -- Brice Goglin Thu, 3 Mar 2005 00:01:35 +0100 llgal (0.8.1) * Add homepage to usage. * Fix captions reading regexps to (Thanks Samuel Mimram). * Fix captions reading which required two spaces before MVI/LNK/DIR captions. * Add more flexibility with only one space between two ----. * Thumbnails always link to slides, except for movies. * Fix show_no_slide_counter option processing. -- Brice Goglin Tue, 1 Mar 2005 16:45:53 +0100 llgal (0.8) * Show line number and contents when reporting an error while reading captions or config files. * Be more flexible with spaces in captions: the last one is facultative when there's no caption; the one after TYP: at the beginning too. * Rename several options: - no_film_effect => show_no_film_effect - no_slide_counter => show_no_slide_counter - slidename_from_filename => make_slide_filename_from_filename - slidetitle_from_caption => make_slide_title_from_caption - caption_from_exif => make_caption_from_exif - caption_from_filename => make_caption_from_filename - caption_under_thumbnails => show_caption_under_thumbnails - thumb_prefixfilename => thumbnail_image_prefixfilename - slide_prefixfilename => bigy_image_prefixfilename * Add several options: - make_recursive [-R] to enable recursive behavior (disabled by default) - bigy/thumbnail_convert_options for additional specific options when creating thumbnails or bigy images with convert - make_slide_filename_from_extension option to add extension to slidename generated from filename to avoid slidename collision if two images have same name and different extensions. - slide_filenameprefix option to prefix generated HTML slide filename. - slide_filenameprefix_nofile to define the prefix of slides when generated from filename while there's no associated file. * Change default slide image prefix to "bigy_". * Allow slide show with only one entry. * Translate remaining french text to english in manpage. * Check exifcom existency so that package dependencies may be released. -- Brice Goglin Mon, 28 Feb 2005 20:31:11 +0100 llgal (0.7) * Add --gencfg to generate a config file. * --con or convert_options may be used several times. * Fix URL for images and movies when there are multiple dots in the filename. * Passing a negative number to a numeric options restores it to default. * It is now possible to limit pixels per row without limiting thumbnails per row (--wx -w 0) * When combining --ce and -C, caption are generated from EXIF tags first. If nothing was obtained, filename is used instead. * Replace thumbnail_height/dimension_max with width/height and cleanup. * Add additional_configuration_file for --config in config files. * Fix missing --sp and --tp in manpage. * Fix missing double-dash in long options in various files. * Check non-emptyness of several string options. * Check additional config file existency. * Sort options in llgal, llgalrc and manpage. * Large cleanup of numerical options processing, with integer checks. * Check slide and thumbnail creation return value. * Warning are shown only once, afterwards. * Use real defaults in usage(). * Cleanup usage(). * Remove useless convert_options_list. -- Brice Goglin Sat, 26 Feb 2005 19:57:16 +0100 llgal (0.6) * Fix thumbnails address in index when running llgal with -d. * Fix text slide dimension calculation in case of --bigy. * Respect POSIX command line options naming convention. * Merge all command line options with configuration options. * Allow to pass additional options through --option. * Allow to pass additional configuration files through --config. * Add index_title and index_filename configuration options. * text_slide_width/height configuration options become numeric. * The local .llgalrc file is now read after all other configuration files so that the .llgalrc in the destination (llgal called with -d) with directory might be overridden. * Allow spaces in configuration options. * Several special options are processed before reading configuration files. * Cleanup GetOpt configuration. * Add missing configuration examples to llgalrc and manpage. * Merge -h and --help options processing. * Fix --clean message. * Fix /etc creation in debian/rules. -- Brice Goglin Tue, 22 Feb 2005 00:12:00 +0200 llgal (0.5) * llgal now generates XHTML1.1 compliant pages. * Cleanup index and slide layout. * Cleanup CSS and HTML codes. * Text slide dimensions are now configurable and will be limited by --bigy. * Fix infinite loop when opt_wx is too small by adding a warning and forcing image placement when it's too large for being inserted alone on a row. * Cleanup messages about generic files. -- Brice Goglin Sun, 20 Feb 2005 16:28:00 +0200 llgal (0.4) * Add support for subdirectories: process them as links for now. * Index points to url instead of slides for non-image slides. * Fix llgal.css where center was broken for tables. * Reduce default size of captions when showed in index with -u. * Enable all configuration options in /etc/llgalrc, $HOME/.llgalrc and local .llgalrc files. * Fix man page. -- Brice Goglin Sun, 20 Feb 2005 01:17:00 +0200 llgal (0.3) * Add --ce to generate captions from EXIF tags. * Don't remove the generated caption file when the user removed a special line. * Don't remove llgal files when they are different from generic files. * --cleanall removes everything, even if modified. * Show big image dimensions and size in slide when -bigy. * Fix image alternatives and titles, and slide titles. * Remove useless javascript and NEXT-IMAGE in slides. * Cleanup support of files with several dot in their names. * Cleanup generated HTML, almost XHTML 1.1 compliant. * Fix copyright and description. * A few fixes. -- Brice Goglin Sat, 19 Feb 2005 16:00:00 +0200 llgal (0.2) * Enable -n to set slide filenames as image names. * Add .html to slide filenames generated from image names. * Enable -w and -wx options to fix index width. * Fix -wx option processing (reinitialize total width for each row). * Enable -a, -ad and -as options to show dimensions and sizes. * Fix size and dimension calculations and showing. * Add -asu option to change file size unit. * Enable and fix -www option. * Enable -s option and fix movie, link and text links. * Enable -h, -i, -k, -p, -r, -t, -u, -x, -con, -sp and -tp options. * Prevent -s and -bigy at same time. * Reduce default font-size for size and dimension in index. * Add an empty line after comments at top of generated caption file. * Fix alphabetic order of files in generated caption file. * Merge slide array with main entry array. -- Brice Goglin Sat, 19 Feb 2005 12:00:00 +0200 llgal (0.1) * Initial release. -- Brice Goglin Mon, 07 Feb 2005 20:30:00 +0200 llgal-llgal-0.13.19/Makefile000066400000000000000000000071361314312235400155160ustar00rootroot00000000000000NAME = llgal ifeq ($(shell [ -d .git ] && echo 1),1) VERSION = $(shell cat VERSION)+git$(shell date +%Y%m%d).$(shell git show -s --pretty=format:%h) else VERSION = $(shell cat VERSION) endif DATA_SUBDIR = data LIB_SUBDIR = lib PO_SUBDIR = po DOC_SUBDIR = doc DESTDIR = PREFIX = /usr/local EXEC_PREFIX = $(PREFIX) BINDIR = $(EXEC_PREFIX)/bin DATADIR = $(PREFIX)/share SYSCONFDIR = $(PREFIX)/etc MANDIR = $(PREFIX)/man LOCALEDIR = $(DATADIR)/locale DOCDIR = $(DATADIR)/doc PERL_INSTALLDIRS = TARBALL = $(NAME)-$(VERSION) DEBIAN_TARBALL = $(NAME)_$(VERSION).orig .PHONY: llgal clean install uninstall tarball all:: llgal llgal:: llgal.in VERSION build-lib update-po sed -e 's!@DATADIR@!$(DESTDIR)$(DATADIR)!g' -e 's!@SYSCONFDIR@!$(DESTDIR)$(SYSCONFDIR)!g' \ -e 's!@LOCALEDIR@!$(DESTDIR)$(LOCALEDIR)!' -e 's!@VERSION@!$(VERSION)!g' \ < llgal.in > llgal chmod 755 llgal clean:: clean-lib clean-po rm -f llgal install:: install-lib install-po install -d -m 0755 $(DESTDIR)$(BINDIR)/ $(DESTDIR)$(DATADIR)/llgal/ $(DESTDIR)$(SYSCONFDIR)/llgal/ install -m 0755 llgal $(DESTDIR)$(BINDIR)/llgal install -m 0644 $(DATA_SUBDIR)/* $(DESTDIR)$(DATADIR)/llgal/ uninstall:: uninstall-lib uninstall-po rm $(DESTDIR)$(BINDIR)/llgal rm -rf $(DESTDIR)$(DATADIR)/llgal/ rmdir $(DESTDIR)$(SYSCONFDIR)/llgal/ || true tarball:: mkdir /tmp/$(TARBALL)/ cp llgal.in /tmp/$(TARBALL) cp llgal.1 llgalrc.5 /tmp/$(TARBALL) cp Makefile /tmp/$(TARBALL) cp Changes /tmp/$(TARBALL) cp COPYING README VERSION /tmp/$(TARBALL) cp -a $(DOC_SUBDIR)/ /tmp/$(TARBALL) cp -a $(DATA_SUBDIR)/ /tmp/$(TARBALL) cp -a $(LIB_SUBDIR) /tmp/$(TARBALL) mkdir /tmp/$(TARBALL)/$(PO_SUBDIR)/ cp $(PO_SUBDIR)/Makefile /tmp/$(TARBALL)/$(PO_SUBDIR)/ cp $(PO_SUBDIR)/*.po /tmp/$(TARBALL)/$(PO_SUBDIR)/ cd /tmp && tar cfz $(DEBIAN_TARBALL).tar.gz $(TARBALL) cd /tmp && tar cfj $(TARBALL).tar.bz2 $(TARBALL) mv /tmp/$(DEBIAN_TARBALL).tar.gz /tmp/$(TARBALL).tar.bz2 .. rm -rf /tmp/$(TARBALL) # Perl modules .PHONY: build-lib clean-lib install-lib uninstall-lib prepare-lib $(LIB_SUBDIR)/Makefile.PL: $(LIB_SUBDIR)/Makefile.PL.in VERSION sed -e 's!@VERSION@!$(VERSION)!g' < $(LIB_SUBDIR)/Makefile.PL.in > $(LIB_SUBDIR)/Makefile.PL $(LIB_SUBDIR)/Makefile: $(LIB_SUBDIR)/Makefile.PL cd $(LIB_SUBDIR) && perl Makefile.PL INSTALLDIRS=$(PERL_INSTALLDIRS) prepare-lib: $(LIB_SUBDIR)/Makefile build-lib: prepare-lib $(MAKE) -C $(LIB_SUBDIR) install-lib: prepare-lib $(MAKE) -C $(LIB_SUBDIR) install PREFIX= SITEPREFIX=$(PREFIX) PERLPREFIX=$(PREFIX) VENDORPREFIX=$(PREFIX) clean-lib: prepare-lib $(MAKE) -C $(LIB_SUBDIR) distclean rm $(LIB_SUBDIR)/Makefile.PL uninstall-lib: prepare-lib $(MAKE) -C $(LIB_SUBDIR) uninstall # PO files .PHONY: update-po clean-po install-po uninstall-po update-po: $(MAKE) -C $(PO_SUBDIR) update clean-po: $(MAKE) -C $(PO_SUBDIR) clean install-po: $(MAKE) -C $(PO_SUBDIR) install LOCALEDIR=$(DESTDIR)$(LOCALEDIR) uninstall-po: $(MAKE) -C $(PO_SUBDIR) uninstall LOCALEDIR=$(DESTDIR)$(LOCALEDIR) # Install the doc, only called on-demand by distrib-specific Makefile .PHONY: install-doc uninstall-doc install-doc: $(MAKE) -C $(DOC_SUBDIR) install DOCDIR=$(DESTDIR)$(DOCDIR) uninstall-doc: $(MAKE) -C $(DOC_SUBDIR) uninstall DOCDIR=$(DESTDIR)$(DOCDIR) # Install the manpages, only called on-demand by distrib-specific Makefile .PHONY: install-man uninstall-man install-man:: install -d -m 0755 $(DESTDIR)$(MANDIR)/man1/ $(DESTDIR)$(MANDIR)/man5/ install -m 0644 llgal.1 $(DESTDIR)$(MANDIR)/man1/ install -m 0644 llgalrc.5 $(DESTDIR)$(MANDIR)/man5/ uninstall-man:: rm $(DESTDIR)$(MANDIR)/man1/llgal.1 rm $(DESTDIR)$(MANDIR)/man5/llgalrc.5 llgal-llgal-0.13.19/README000066400000000000000000000041511314312235400147300ustar00rootroot00000000000000llgal is an easy and fast on-line gallery generator based on iGal. Its primary goal is to NOT require any boring useless expensive feature in your webserver, such as PHP, JavaScript, SQL, ... Thus, llgal generates static web-pages. llgal installation instructions =============================== You don't care about this if you use Debian or Gentoo or any other distribution that includes prepackaged lltag versions. Run 'make' followed by 'make install' as root. If you don't want or can't install as root, you may use 'make install DESTDIR=/home/login/where/you/want'. Note that you need to pass the same DESTDIR parameter during compilation (with 'make') since the installation directory is hardcoded in llgal. By default, everything is installed in /usr/local/. Most directories might be replaced by overriding their default values on the command line. For instance, a traditional installation might be achieved with make install PREFIX=/usr SYSCONFDIR=/etc MANDIR=/usr/share/man \ LOCALEDIR=/usr/share/locale Note that 'make uninstall' (with same options) allows to uninstall. llgal requirements ================== llgal requires perl and imagemagick packages. The following perl libraries are also needed: * Image::Size * URI * Locale::gettext These dependencies are automatically installed when installing Debian or Gentoo prepackaged versions. Additionally, some options (--cc, --ct and --exfi) require the following library to extract tags from images: * Image::ExifTool If not installed, llgal with work fine as long as none of these options is used. When on is called, llgal will issue an error message advicing to install the library. If you need to install these libraries by yourself, you may for instance find them on CPAN: * http://search.cpan.org/~exiftool/Image-ExifTool-6.00/lib/Image/ExifTool.pod * http://search.cpan.org/~rjray/Image-Size-2.992/Size.pm * http://search.cpan.org/~gaas/URI-1.35/URI.pm * http://search.cpan.org/~pvandry/gettext-1.05/gettext.pm llgal is known to work with these versions. If you experience any problem, please see http://bgoglin.free.fr/llgal or report to . llgal-llgal-0.13.19/VERSION000066400000000000000000000000101314312235400151060ustar00rootroot000000000000000.13.19 llgal-llgal-0.13.19/data/000077500000000000000000000000001314312235400147605ustar00rootroot00000000000000llgal-llgal-0.13.19/data/captions.header000066400000000000000000000013601314312235400177520ustar00rootroot00000000000000 # Use the following syntax (without the beginning '# ') to define captions line: # TITLE: title of the index # PARENT: label of the link to the parent gallery # PREV: label of the link to the previous gallery ---- url of the previous gallery # NEXT: label of the link to the next gallery ---- url of the next gallery # INDEXHEAD: one header line in the index # INDEXFOOT: one header line in the index # TXT: text ---- caption # LNK: url ---- slide link text ---- caption # LNKNOSLIDE: url ---- direct link text without slide # IMG: imagefile ---- caption # MVI: moviefile ---- slide link text ---- caption # FIL: file ---- slide link text ---- caption # DIR: directory ---- slide link text ---- caption # BREAK # LINE # REPLACE: text ---- replacement llgal-llgal-0.13.19/data/index.png000066400000000000000000000074651314312235400166110ustar00rootroot00000000000000‰PNG  IHDR00Wù‡gAMA¯È7ŠéìIDATxœ½šyŒ]Õ}Ç?¿sî½oÕãY¼B†16^b0ƒ1;ÁÒ¤µT)­PB” $Ô¤ Ž„ÚÒT*(QÒ’ª‰HIÒª)‘Óâ M, †Ø,†1ÆÏ>žõ½yoÞv—Ó?Î{3cûÙ˜¥=ÒÑՌιçûûý¾çûûsŸð‘´kWlA›ë0²a °ú”AÓÀqà DÏ“—gàÁì‡]Y>øÔ»Ò¤R—#²ä3À &²Ïù•TµÏ/; fFö˜(?xüÿËEz÷gûÙ„‰ ¨€rÀqAÄK RKíÎ/3„ÅYˆ|ý…9ÚcrÀwÈÿ¾™ù¿3 qïo¡ä^”l#Š ¬ Éf+7â,Y ‰%¤šš‰%4¦]-D"¹¹€rѧ˜ÏÍÍ`rãâOÙÈh †~Œy”¹ÂCðw³¥ŠÔî¯!Ü FH,…·úR’ÝŸ ±³“®ؼzº`E+,mGcíŒ S€ èÞa蟂B¶Liø- ½ÏdÇ,‘WñÙEùcÞ€ÔŸ­Gä!D}’ ŽKrí ÄVndƶ­…KVÃÚåÐÖ®Ã"ªW·DÙHø!LÏBßìö…Þw GP|ûYüéAp<@Ž™û)<øè7 ý•µàýÂ&ü nÛjvpáÅk¸qüöe°¬’q Ô¡äC%°=˜§(@ik¤çØ9ƒSðÔoàç½Ð?0Gîà“û`¢D•ˆ¸‹ÂÚÑïÇ€Øîáòk0„‰ž«Hm¾…ë6{üá°n…Qónf&³-ZÀÆœ,B`ê3æ@:©„¥ÚñqxäØw*£G˜zþ‡˜J´¡¹ƒÂ߯Sןº§í< ²…("ѳ¶+>Íí—k¾|twYå¦svñÁI˜-Z¾‡Ñ‚‹{-A¥ò%Èí{š“°q5d 0-Aâ­T&ú1~ ”ºïŠw¨üº÷"ðå騳[ñK$×ï sëÍ|å6¸a#t4R0[€á) "[°”©y¹Öj³µ6F+hIãÀÿ¼½ 3}ǘzî»6§ˆ í¿þÊÙ#¾æOuOì¼OбõVîÞ©ùԥМ²NÚ^ò-¸¸kiàPö-¥J¾542P¬,x¿¡Z¯ýß!W²Ïž. ‚¾¹tº“ÒèÛ`"…R›q/ß‹ÿâ\}ÒºÔ?žÓ²Œ¦+ÿ€;wÄøÝ+,xcàØ É,ð<2U=èh ظ .»z–AÌ…ñ,TüúF,6¤T±ÆwwB¡ #Q;á\ühw9HŒÊ ?­o€wõw€‹ˆB–íÛ–qçõVÓ•‚Ã#0–©fÖEœŽª&s+ÂÕëaóùŒÙ¾¼ÕqxdaÔ3¢fH%„0„®V8<aóÇ(O'ÌM‚Òkp/yÿ¥¹“ °zÿ„~<Þ½•ó·^Ë=;m8c.¼3c3 äðÆêÛxæJpÃ&X¿òt®/m´ªÓ?¾°_N}ÏüûªFxÚÒ³oJ£Ó_&Ï¥òüÓ`¥@õ7˜¨I§[Hl¸•Ëzà‚NHz04e³hY™ïõÔxƪѵëaê3îW6¬‚mëì>)Wìž9SK¡ :¡³œ¥+‰wö@àÜ·»À±ÞÿêF”ìįàv¬eù²·\lUa"‡‡B¿¸)L2yصÍòö½ÚÅçÛçû«ÉM}¼«¡»¦!ݳ•ÒÈÛk¨ðŽîª+¥q=œ®õl¿È‚q´ y¡l½ï‡ =ˆ¬jLÎÂm—žøÅFl½ÐªSÅ?{$J>¬n‡æ8xkˆuv#&B}3T)$¨«1îÒn–÷ô°ýBpLçáDÖªLex?‚|ÙnèÛô~ÛM·›=W² ;gq/ûÕ(tÚÓFjå&D "²“ÖûÖ9´ÜÛ¤´¾É!nÇ…¬èÔ´5Øð¾3l7¦sJ¶"›[>}9lúàkíæÍÜÓÁ¯Øªº^ BXÖ ‡†¡ÒØò`LØáhß"Z­Fy¨ôR:š¬Zª6ƪF­B«J·\b5þöë7Z'íÝo%·^Ö\.R­ˆÃeÄp‘#®³Y¥=T,Ms➕̉Y ¸\åcÅÏ…/ÜøÑ€¯µ—X*=óÄ<ËëÅz!bç9 ¼$N² ?7Ž(Ýî õzЉtšö&Ȭî÷Û V…<¾xÓÙ¥òÅC%ÎëtéZr2ïúÇ|´‚íîis\ ¿w•ú/Y'-Díl¡Ð·¥‹ ?J·+QªS” Ê!ч©< MV³cMuBøýkÏþé—‹|ëñ2Žs:™'f…û™åð@¹î\øü pù›Í+Q9°D@48©-i¥”N‰ÒˆÖ(­Pb+ÌñY ¾\-{×,ƒ«Öü+Eþþ‰ ±t# ÉÓ‰ìŦƒ&¾þ£<½Çë¡Ä C³[^> ™?ê)í"J#J‹B+%Z!Z¡4±™ÚñQuw´œüs‹|so•lD”E§‰ $RC…îÿ~–±)¿î»–·Ú£im}ĪމYÈ•-½”æ1+¤ ¢%h›—™™³(Ö Ïƒ7úf §#Û×[æ¡Ç˸É4Ž#ÔÁØðG=f¢FþüŸf› N72r""о-ŽÛ3t`,{ŤQ¢DëŒh(&`®bgáè NC¾½£ðð•¨øV¢ûU¿üQ•lÂiB :Ãá%_Œ¨D†H7Ç9–oâkÿœabfÁˆ04|÷©Ç&`hŽMXÅÀªS,fs’„ED;ˆÖEG´:bw¹!ð‹LR,k„DÜò®àCaí°gÈ«GgYÞ"ʆãSšx2ãÊÆ Žófö@ø ËXí¼®”ø2C}ô_°™ —@KÚ^T!çv‰jB{ttëÜ6)©zù}`Œ=Rj Ú@1;Kf¨åy ü¾ä;Yñ÷5K¼OiçüüØ0Ó¹ÍL§mò °ÙPâFAü ¥èšœ“3°µOkÊž=<Gz)æp¼&žÚ™øÕ/³[¹ŽÉOO1uüÚÒ6+&âÕð¿Gw«ÏzM+ËésyO­·4TUÍÌ £Ý ÏgÆg^Y0˜ÙÇEé×D)ús€Ñá ™ÀÒhIƒ•±Å÷L]Týø‘Aë÷ž_3²5 MI("ýRÊåQ®.¢d7C\<ÉÀ-ßÖ®Gy®Hß+™,ZZ´¤ªWçn5¹œ¡Ç=Ï Ö)†g´c)t¦ùŽcùÞ”´ëEâÁÈ¡# ¼Þ‹ö÷Bí½'©üÌØÄŒð„13:ÁС>ò ­íö4æ8õCîyà#ìyµD®¸ èGFʼ6Jž…2Õ¯Mµu¨2ß>ŠvP2‰Š¾±óiÁn»ê_׈ëĘÀÖÛ·sÞºÔÂôTa¡>?µ‰@>[ )šcã —\1äÀ€O¬­XÜ©›äŒ±"чƘý{ªÙ¬Ï ?~ŽìDí:DQxçäÏw=²xîi‚WØ3•^½ë%qôõ ƒãÄ’¤;‘ê"鸕À…Ï[ó]A<éR‡£Ó0^vhhk$‘tP§ŒUÕÞ·‚Ñ”°õR.‚l¦È«?ÝÏÔÈŽç|{"Êý-ýŸÄÏ3*ZûM?ùœýàâ“hH°ý3WÒ±ª™&ÒU¥)0[‚RµŒÀ,D¥V.Ô<\ó¼aaœ« ƒÏJf%‚é ÌBžÿ÷—<­«ÚP®àiH{@ʳ7®¶.©)Ñ|Í#Ö㮆¤k=Ý’€%IhˆÙ(C˜3ðÎëüôÔA&‡§ñâ³§T(|±‰øÊÅ10fŒ æfÏàÜpôìÿ¿eÊÃæ’Ã+IEND®B`‚llgal-llgal-0.13.19/data/indextemplate.html000066400000000000000000000016361314312235400205170ustar00rootroot00000000000000 <!--TITLE-->

llgal-llgal-0.13.19/data/llgal.css000066400000000000000000000041041314312235400165640ustar00rootroot00000000000000/* Body */ body { font-family: verdana, sans-serif; background: #333333; color: #dddddd; } /* Links */ a:link { color: #95ddff; } a:visited { color: #aaaaaa; } a:hover { color: #bbddff; background: #555555; } img.image-link { border-style: none; } /* Various */ .small { font-size: 75%; } .large { font-size: 200%; } .center { text-align: center; } .center table { margin-left: auto; margin-right: auto; } /* Index table */ table.index { border: 0px; padding: 0px; margin-top: 9px; margin-bottom: 9px; } table.with-tile { background-color: #000000; } table.index td { padding: 0px; } table.index td.thumb img { vertical-align: middle; border-style: none; } table.index td.text-thumb { border-width: 1px; border-style: solid; border-color: #ffffff; text-align: center; font-size: 50%; } table.index td.tiled { background-image: url("tile.png"); background-repeat: repeat-x; text-align: left; font-size: 0px; } table.index td.thumb-dim { font-size: 50%; } table.index td.thumb-caption { font-size: 75%; background: none; } hr.index { width: 80%; height: 0px; border-width: 2px; } /* Slides */ table.slide { background-color: #000000; border-width: 3px; border-style: solid; border-color: #ffffff; border-spacing: 0px; } table.slide td.image-slide { padding: 0px; } table.slide td.image-slide img { vertical-align: middle; border-style: none; } table.slide td.text-slide { text-align: center; vertical-align: middle; font-size: 200%; font-style: italic; } p.caption { text-align: center; } /* Headers and footers */ .header { font-size: 120%; padding-top: 6px; padding-bottom: 6px; } .footer { font-size: 120%; padding-top: 6px; padding-bottom: 6px; } /* EXIF table */ table.exif { border: 0px; border-spacing: 1px; background: #ffffff; } table.exif td.exif-name { text-align: right; background: #333333; padding-left: 6px; padding-right: 6px; } table.exif td.exif-value { text-align: left; background: #333333; padding-left: 6px; padding-right: 6px; } llgal-llgal-0.13.19/data/next.png000066400000000000000000000075171314312235400164560ustar00rootroot00000000000000‰PNG  IHDR00Wù‡gAMA¯È7ŠéIDATxœµšyŒÝÕuÇ?çÞûû½÷æ½Ï›±gñ6ÞÀ`À¼@ SC€„”Ñ(Q‹P¥Ô´@J‹Ô&Eä6Ti«T"U…*­T'ŠÂR ĆÒ0¦llÆöÌØ³ïoûm·Ü÷ìñðÆf½ÒѼy¿»œå{–{~OøÔÆ­åJ¼d¨ €ƒÅ"0¶â}LWÞ‚¿Ÿü4N•O´:}wâ]Œ²—"rØ‹A2`Oͱ3O°6Aä–ç°¼öÿ(îØËi‹>kîé@éï€ÜŽH IqÊ€6î¯(·½ؤJ1$1D{®=€ØEÿ1¥¿ÞóÙ ºg%žþ3-@I6A7w’Y¸5¯ë7á5äðS)<Ï€hâ0 B‚R 4BåÄ*‡!ª‚Hxk¿OaÇóŸ¾Ù{· üQç‡ ‚É/ÁëÚļåkÉ6gèÈêXÔ-Yh΂Q0U†ã£Ð;êþöŒÂÔûQéÞC¥÷-lTqÖC,ÖÞOaÇ÷>-Ù{@d;6·xà¯ÜLûòU\v‘φepÁbX2š å¹…¶ŠêÄB’@ÃdŽÁãðê!Øû>?zœ¨çuЇ^Á†0Xû aôm*wþ¨…\êϹ“(ÀäZñW]AÇÚ+Øx¾æ–pé ÈgÁhÇhA%„0‚0†8¬sÐ< Z`º ¯½Oî…×»a轃Þzš`´·êCö,÷QØñâÇàšÈ5<‡¨e¼ö•ä6ÞÆêóçóÍk`ËhÎ9-'J†ÉÊî;;+®Hõ4OC&¹¤}'äKûá‘_Á‘„Òþç˜Úûx)@B°[™ÞñR=.u}æ7M.ÿ ¢n!1 –Ó²ùkl¹|>÷Ý ›ÎÆŒÓðxúFáÈ M@¡âŠˆí,J Ž• 'l±:E¬XÇÇ„Bf‰µ„#=€Õ ëñ6ÿšp÷Ї û…¿@©{˘ù+hüoñõë¹ûFXÕ Ï1bÔ1?0¥ÀiÜRżuÌÆÉ)H’SÏ Q 妪Vko†Ï eEŸ9VN¼Ú´#¬'ØýOÌÊ wïUˆü-q˜òÚ–“ßüÛ|c[#·oqÑE+š„î§A%ö\´)N°(v~`qÚ"·õIË$3«R%pÑJ ¬î„É" ™•èT–ò‰ƒ ²ÿŠ¥»Ÿ˜)Äé¤îY‰V;Il§Îåi¼â¶\ÞÊö/8æEàØ°£J•©Öß8h(µ]pa—[gÁ‰–Iê Ç0]qJ:¦2]Äãý„£} ½Kð®%Üõj}2Wý ¢~“¨BfÍõ\¸i5ß¹ –Î߃CýÐ;RešY°H`¢è¬°mœ·È…Ô–FXÞî|¥wÄEx!âZ@œ4Â;} Í]”úöc+Pê<ýC8šœ.@î®ù ÿŠ$jòžÇ¢Í7±ýÍ…]Ž‘£CÐ3옉óM–[rpåù§£R€®06 ýcn["©GÕp<¯p¬ åÞ·A›<þÂ^‚ݯƒ{^ÞŸ",Á_q›Î÷X·²)ž‚Ãý%&ç5Š‚þ ÷ÿbgÍÔ n¸Ö¯„BPÍñÜDNvA[R‹.B54»Z µƒìööSHßµãÿ˜$J›Ö¥,Þ´•ßû¼æÜN§‘7º¡V1_ÓRì49]vN'Ž÷Éé„Åùˆ|ããƒ,ksN~¨ÿT™ NQâÖ*Ð;åc¼¥¾w­3à½J°k¿³@:½N”š‡€×u—¯õY³Ø%™c.ÌY Q4ƒ‡Õq§Í¨}Š¡â_ž.0>ÕµÀ5:KL!¨eí9¨Š6ÈùY¶/ß$`dãI Hæê¯ ÉÕf^-—ÜÈ—.3¬Yì{»Ç™Ôμ&ì -Š…Øgÿ¡ËÚM¹ú©fy›cîÐÀ™-ÅòÝ9ƒ…Dʇñ–âm~TÁwÒæ:Ä’^tÙæ4‹óÎñwÑ#ŽO×JÃT& îs-Ö×ê ­5G'øçgJŒŒ×·„gàæMðùµ.™•ƒÓ÷™Mù,(^~1ÊO£=½D¥Ò[­z%J.í¡›:éh†Ž¼Ã]ßh5ÅPŽ :­+®¢œëÐJéŒG_!ǃÿ:ÅÑ•9á´m|q#·w½ýÊ«p€Éµ¢¼4ˆ ¢6e¸X‰öQëåXÙæêœñŒL:¬¡"¨ ⾇jù0ÇePD3RlâáŸøÃ[„ ý9}bpþkŸKˆJN¯âÄE1”ŸE¥ˆK!"ªÍhc.eð2Y:óŽÉ÷úáý·!8†ç7†Un³Úȥꋻ‘Å9F&–wžªHgÛ®€”Ÿ¾â‚ÇÌy"Õl¯ 4>þ¼6Ê• PºÍˆ’NІT:E6íÊâcƒûàpÕpëfhmœƒÙ3¤Ï:ë¦ 0V€g÷:¥ÔdqV0Êm¥3Mˆ(É*ÄhQQÏ7äR0]rf”8<#°uíÇeþãá+Ÿs.®ÞªTý J ÁÝsT*ƒˆ JùJ±¢¢Æs@›(9­[ÜB­¡)ûÙ2_MHû–(©úAÕßj õùyo®ýŒƒN>hP’гwI’€Ö‰Æî>)ìŒîQ¥$¶Œ9ÌXà4ØšƒlÚmè…Œv„ó;ë³>4ó½ÇŠì9‘¢µYãé¹÷Jy®tÑ´ÅáA¦Ѿ‡(õÈØkOíŸ!L¼zûkJ©_Ï£ÿÀAz÷3¸þç‚&—Ðê:Ù òSPN,“I]Øüàù /÷¥ÈfõÉPÏi=Z«g–-ÄaHßþw±"ˆ’a¢ð»°3>M€Xó x†8J8òÚ>F‹Pˆ3·7;g2fFšE©jôùᯂè”W+ ÷ÿ¢È;ciÚZÍœëçÞu´ä\?©œ€NÃѽûèîÁ¤R Ícc{îè©í}ZŒ(ûùц®¯"Z_K"Móɤ…Ï™5JœØZ×'ßú Ð;R¨ÄLø·BÞK‘Ëj—ðf­QÚÕ9FCK478ET€‘¾1þ÷>—DÞ%–;K=;Gj<×- ®Ùù¬ [ÃJÈêË×pÉÖµ4iÈzÕ>P aµç_î”CKE`íi2¾ÌysK,ø òÈúPŠ`<‚¾ÃÃüÏ» J¢Õ¤ Ãû¾vpæÚºQ:Ûuë+bômÌ’ñÁqÂJD~é”ÓИv·&+®F7u,‘ò…tZ“N+R¾ êh^ªýÔ–,ÌÏBC J1€ãÝÃìyò)—*(Ï„Xûíá—n{a6¯u(Ý9Ú°ôÖÊèßQƒÇ†H7¤È/iA)Wf}×µ3¦zѨ„¢$´ªæ›$3ž )Çø¼´Kx SúŽñòã¯R.V0¾k|þ+?¨ÇëÓSûum1‡µY KÎ]Ȇk×ÐÞž!«¡¡ú&µVµ†±»üWbWÎDŒðµ#Oú,âj¯B#ã1oì:@÷Û½”¦Ë(-±MìCïy€CwÖmmœ5¿v\ÿøïÇ›£ ¦©5ËE—­dÙê.H‘R¿¦ºS‚c¾Öi†SU«ª•ÞÕyAì ¿‘i˱îaöï9B÷;Çñ|ƒ(±6¹«ÿ©/>z&þ>\°þG^gçÒT"wÄQŒM,Ù¦4—\y.«/ZHS£&çAZ9LJ­…=kØã c÷V¦ïØ8¯¾ø.ýÇÆ°I‚ñ ‰MD_>ñÌ—Þ=k©L[tãSw¢Ôï£du'X ­m¬<¯ƒM´´6ДKÑØ ñ=‡s‘S½B%az:bd´Èèð4ÇÑÓ=BD£dÐ"FêÆƒgeè£ ÀåÿžYÔÑü A=€ÐÇ Il1žÆxŠTÊ#??G6ç“Îx£(CJ¥±ái Óâ8! \×À B`­ýIPÿrè—7þ(ì|ì{,¸á?; ºX6…fIEND®B`‚llgal-llgal-0.13.19/data/prev.png000066400000000000000000000074261314312235400164530ustar00rootroot00000000000000‰PNG  IHDR00Wù‡gAMA¯È7ŠéÍIDATxœ½šyŒ]Õ}Ç?g¹÷½ûÞ›}óxÁ6ï`cl'à 0{I*ƒÒTm“J­«E ´@U‰üÑ´¨R›„¤TJ"E" ´´$Mq"ƒI‹Yìƒm<ã™ñì3ofÞ~—Ó?Î}ž±g1à$GúÍÕ›y÷žï÷·ŸßÁoj%\†×"Ùf%ˆ‹ C˜N0ï@´Ÿ\ùÿàëå ÝV\нÞCW¡Ìe v»:0ö¯ÆX9ómaÅr A¼‹1ωƒÈÂëäøÝH?¸!®4¡P.(„D¸)¤“ŒI¢RùÄWå€T`ÌiàäÊ_…¯{¼‡6¡Ì߸ ¹p’8m8mkéfœt=^:EÂK ¥ÂƒüJ@¹X¤œ›ÀG‰²½”zÞ!š!-ÃQ0ß&àk°/ø ¸·–Tj/Bü5‚B]ÛŠn]Abá%´¯ZÍÒvXÜKšìµ­’ #Cš€þ,t C÷(œ„þÓãNÂï;Be¸ ú 5ó !S|ôõ 'z`R!®'ôÁDxkv‘Z»“ R\¿nÚK[ ¥\mAGÆFC5Lü9Œ _‚®!øÉ!Ø÷.t €ßœñ_=C89 :P„è>rÿô­O ùÅ%h÷ „ØAPF×´‘X³ƒå¯fëj¸s t´CM¤´š®P Á ˆµoL¿€Ö킎÷ÄýïCow–É·H©û×þ’ü£Or&;|XVó¿VVH,º„ÌÆßç²õuÜs#l¼2qŒú*0: cyKÂL³À™„½* IÒ H%,ù÷{áÛ/Ã[Pì>ÂØïcÊÐ.„æO)<úÙ`ªYÁg¾ØŒp¾l$ôñÖì¢~Ë>³ÓãþÛà²eà¹à‡pzN @ïŒä X­‡QìJ±„ÓÄ¡P†‰L _†æZØÔ&‚žJ ²aÁX/Q! J]‡óÉ þþ×>{kq½§¬ÏWðÖì¤}ëmüÙ ‚Ï퀋š­' Ð7ƒÖ§ËjŒõÿé€#3»„Ql½2äJà(X·jÐ]n J-¦Ô{–]¤Ú³õø¯vÎO ½óÏ‘ò^ü2î¢uÔo¾‹½»Ÿ½šj¬¹»‡¡sŠåØ»yÉc &–X ϱD4œX~kƒˆàØdºa)ÅSïĵO|gËÓø¯åg'~`BýQX«jš©Ýú'ܵÓ㮵àÁ‚ïòí*%AkÏC[=\Ýk—@}ÚÆF±bcb.kT¥ìÛxZÚ ùœ®4&ñ>í4‚ð¨ìivî¶E°™Ð'uém\±yu´7ÚôØ9dÓŸ­­çlÁh.j6XÂé$´ÖÁ¢&8Ú ¦{Í°Š± CXÔ îb*ç'‡@ªÕ¨Mß%80y6Ô—#å— }×[u-Ë>±‹¿ù=Áê…6cé¾Ñ©ÌR NAhàô,k…]—ZkL_ž ƒ¶˜ÁÔ½sJLBkhÎÀ±!…jXN±ç0Æ/'‘z ý tEñVÛ5B eT¦ oín6­”t,°à{F¬ÛTóºKÚœ?˜…Õ aç% çHÌAhðé9ŸT3U{#,¬Y×Drá}òR[/°Ò›W£äíDNk- RÜrÔ¥!›·æãâT ìÕ7ž°Ål6ÍW×p6àƒ¾€Ð|x•ÀÆC%°Ï@¦c "‘Š‹‰Ø6E@9„”RhgÁZ¶­‡‹[mf99¥Šu“ š&¡M¥ËZàºKg0:ðäËE&KŠ0¶ÚG‘b–4B[ è¦Åx‹×C"¤úl×@hµƒ(ÀiZÊ‚UëØµmµßŸµà£p Tµú®[Û×Mµ 35ïóÍ jð’ʇê/g.WYʃ·h-ÅžÃH-·…uÛ¶kê©—RÜj 8 ׳¤]Ò”±7íµ~¨äT+P­ªW¯‚-+çÞthÌçñ‹ •Ò¤SÖw~>½e~ð;®H±ãü_›u…¾ùcxå0¤Ü³JZòP©„Ò%2)R"¤B*‰R¶©š°š*Æ­î-W}LTa){¶Úþ©P™ª7ÕØÀ€Ô „Ö!R*‰ˆEÅE6o;Ë›óm]éw±Zê 6eã-Œ€¢+ƒ2„”­”B ! H…ãºPϘmÈ”‚¾±ˆÎ¾ˆåí¿}£!}c •¢ÂXF&§b&™_ „ UQ %F¤! +d „„጗lêÒRðà%î¿C³yMrÎÍM\­ÙÏyç]Ù\È?>WæÄ°ØT^ íÔÅMØïH ÆŸiR–´²K °L¶TÃâð6óÁ›)¾ôLž'¿àÐP3;Â0‚|çí“>©xCÏԤęóÃôkµ³ Œà—¿ö99QC"iñ ‰x+%§Úø°< B#¤×RÊ·„ øy&ÊÍx.¤=ÀÕ|íº’ž|š¿øV‘¯~.I{ãLZÁm›=úò.O½jë‰ÂÈœ­DfªÍÔIÍH&SÔÖ*„™Ê@"pÀ ôC*CHÇAÙ¯#?Ø/’ÉqúuT&É–y[½@éi¦ëHŽ y|ùùÚeQÓ̘h©“Üw«d¼/±÷«Y Óô:Ÿµ¡„TR2TP¼z´ÄŠVA[ýì1qõÅ0Y†÷ áÎOb.Ñ 2žM«JÃð±£L÷#´:>‘+Ü/"%Þ‘Jú>ã½tYÆipk…s%R¼—Mòµÿ©à³ô @&wï‚•í6ŸÏöœùD)Hy–„Ðà‹Œuw"µƒòYŽß7!râ å¸ä‡úÉ #Ehk°Á¬Kä\i©Wt<þö¹Ùüì$êÒ*¯>9ßZàÄëìêAi'ˆ"ó™òÛŸÿ,é%{…VwEQ(K¹ÍËI%é„íA"aù¬MxIÉ`Aq¸»ÄŠA}Ê× ߨWæä„ÆuÄüàe Þ³ñW‰ , ë­cÿßCh×ÁÆ^ûèb>‹@±û¹÷RK÷,VZo,NäÑZS¿¤…¤i×6t¥(~¡"í˜QÊØ2\WÐ;)9tªLRúÆ#ž~£ÂÓš´§Î¾çÓÀ7glÐçB(æÊzåWø•!e1ŠäÞR÷¿Ÿªbž‘Ä®}j‰ÖÎ~ŒYb"ÃÆ›·°êÊ%xÒŽÕJ¶h;D!f>@H(W"üJ€ EÚSsL÷튰 ¨OØÌF0æCv´Äö3Ö?ŠT c»‡~~×ãÓï‘ÀK§ž›ð–Þù¦Pj›¢a¤wˆdM ™Ö¤´“ãLÒf#,àjÁQÚjÓuɤÂM*¼„œ½pÉøt¥-覴Õ~h¬æ³ãEí;DßÉ~ë:ðôP4ù]/œu–›³Š7ï|v›Òú§&4Ž‚×o`å•Ë©IBcý>ˆlM”¦ú˜{ÌbâÕ7®ž¶ ñ”ý\ ![ìh™_>€¡žaœ„ƒ‰Ìã?ýÔݳ=sÞWLm7¼°K(ù=™v¯\ÀU×­gA{š´´.e ñÄÍ Ãèl¯‘ÂöE ®´-·«ìïýrä*ðö«'xïàIòÙJKŒ1_7QöáŸüq~6Œç}É×vó · ¡¿# 9¨„dê=®¹õr–v4Sï'­J1mðkζLÍ–ª×êt;ÆÊ02Z柿Çûow!„@iE…Oõ¿tûgçÃ÷¡^³¶Þü_—j%BÜ!ÚQ´_ÔÄŠõ‹X¹¦•†:…+ ©âÉÁUûùJd³Yчþ<‡ž¢ûøcC“hW¡`0_èË <Á¾Ï—.˜@u-ºõ¥ûPò¡€Ö…u¬\¿¦– Mij]RII2nÞ EúvÆ4‘ó+12’£çƒ: PÌWPZ"¥¨øQôϧxóŒ÷aL eû3·¡á{¢& "¢0ÂIhG‘©MR×¢®ÁÃ'Æ@n²ÄD¶ÈØHžrÑÇ÷C¢È µD"à ‰¢{z_¼ñ¼/·/ˆ@uµÝþãåÊQÛ¥Û숌ÁEVL| ;³‘ÈX„6Só:ðŸAhö÷}#wU>*Ž ùo•)2w¼´ÌuwÃ!äbõ@=e[1Ê@É@Ì€‰L†}=]Ç~Æ{/hrúÿ×ê¥$ry|IEND®B`‚llgal-llgal-0.13.19/data/slidetemplate.html000066400000000000000000000033621314312235400205060ustar00rootroot00000000000000 <!--SLIDE-TITLE-->

           

           

llgal-llgal-0.13.19/data/tile.png000066400000000000000000000003551314312235400164260ustar00rootroot00000000000000‰PNG  IHDR¼ðëk´IDATxÚc````d`a@Ì X \˜‰“‰…!ÅÍÇÄÊÂÌÂã«ÊóÉ©(Hò2B¸lVþ~þ¶ºj\P~\PIuq‚™.7”Ÿ?kÍìj?s(?)îøÝÝ3­áü¤“ÏÎ.ÏvB’vnk>œsôÙ•Å9.BP~jÂÑgÏ6çÛ @ùÉmçž=ÛU SÏà7¹aû‚2%˜„’ãåDxy™`çVÓ“äacc  +ŸŒ%ÍIEND®B`‚llgal-llgal-0.13.19/doc/000077500000000000000000000000001314312235400146145ustar00rootroot00000000000000llgal-llgal-0.13.19/doc/Makefile000066400000000000000000000005401314312235400162530ustar00rootroot00000000000000.PHONY: install uninstall install: install -d -m 0755 $(DOCDIR) find . -type d -exec install -d -m 0755 $(DOCDIR)/{} \; find . -type f -not -name Makefile -exec install -m 0644 {} $(DOCDIR)/{} \; uninstall: find . -type f -not -name Makefile -exec rm -f $(DOCDIR)/{} \; find . -depth -type d -exec rmdir $(DOCDIR)/{} \; rmdir $(DOCDIR) || true llgal-llgal-0.13.19/doc/examples/000077500000000000000000000000001314312235400164325ustar00rootroot00000000000000llgal-llgal-0.13.19/doc/examples/dynamic_comments_in_slides/000077500000000000000000000000001314312235400240145ustar00rootroot00000000000000llgal-llgal-0.13.19/doc/examples/dynamic_comments_in_slides/README000066400000000000000000000021101314312235400246660ustar00rootroot00000000000000How do I let people add comments to my slides dynamically? ========================================================== Some PHP code may be used to handle dynamic comments in slides. The slide template in this directory should be used together with llgal --php. It will generate PHP slides with comments stuff at the bottom: * slide_.php displays the contents of comments_.txt if it exists * a form is available to add new comments in comments_.txt Look at the bottom of slidetemplate.html to see the relevant code. The PHP script add_comments.php in this directory is executed when the form Submit button is clicked. It will format the comment text, add it to the corresponding comments_.php, and go back to the slide. Of course, this is just a very simple example. It may be improved a lot by adding other fields in the form (especially the name and email of the author of the comment) and the date. Right now, formatting is done when the comment is added. But some people might want to keep comments_.txt unformatted and have slide_.php format the text when displaying it. llgal-llgal-0.13.19/doc/examples/dynamic_comments_in_slides/add_comment.php000066400000000000000000000016051314312235400270010ustar00rootroot00000000000000\n", $new_comment); /* change escaped quotes into non-escaped */ $new_comment = str_replace("\'", "'", $new_comment); $new_comment = str_replace('\"', '"', $new_comment); /* open the comment file */ $fp = fopen ($comment_file, "a") or die ("Couldn't open the file to add comment for ".$slide_url."\n"); /* lock it to protect against concurrent accesses */ flock($fp, LOCK_EX); /* Add the comment and format it */ fwrite($fp, "New comment:
\n"); fwrite($fp, "".$new_comment.""); fwrite($fp, "
\n"); /* unlock and close the file */ flock($fp, LOCK_UN); fclose ($fp); /* go back to the slide */ header("Location: ".$slide_url); ?> llgal-llgal-0.13.19/doc/examples/dynamic_comments_in_slides/slidetemplate.html000066400000000000000000000043211314312235400275360ustar00rootroot00000000000000 <!--SLIDE-TITLE-->

           

           

Comments:
.txt'); ?>


Add a comment:

llgal-llgal-0.13.19/doc/examples/tweak_image_generation.txt000066400000000000000000000010431314312235400236610ustar00rootroot00000000000000By default, llgal uses convert to generate thumbnails and scaled images from your original images. You may change how the generation is done in order to either: * replace convert with a specific image processing library that might be more optimized for your specific images. * apply some effects, for instance drop a shadow. It may be achieved by changing the values of scaled_create_command and thumbnail_create_command options in a configuration file. See the section THUMBNAILS AND SCALED IMAGES GENERATION in the manpage for details. llgal-llgal-0.13.19/doc/howto.html000066400000000000000000000520211314312235400166420ustar00rootroot00000000000000 llgal - On-line gallery generator - How-To?

llgal How-To?

This How-To is available on-line and in the tarball and distribution packages.

Basics

How do I use llgal?

Place some images and movies in a directory and simply run llgal inside it. It will generate an index file and some slides.

How do I modify a gallery?

You may add or remove some images in the working directory, and re-run llgal with different options to update the gallery contents or layout. If an image has been modified, you may have to force the regeneration of thumbnails and scaled images with -f.

How do I reduce the size of the slides?

If your images are large, you should try
  llgal --sy 480
to limit the height of the image to 480 pixels in slides. Note that a click on the slide will actually open the original full-size image. You may even ignore the original images completely by passing --nf so as to remove links from slides' scaled images to the original unscaled full images.

How do I set the title and captions?

You may set the title on the command line through:
  llgal --title "My title"
To change captions, the easiest way is to ask llgal to generate captions first, with:
  llgal --gc
Then, you may edit the captions file (.llgal/captions) to update all captions. You then run llgal again, it will detect the existence of the captions file and use it.
  llgal

Captions and special slides

How do I generate captions from images?

When generating the captions file with --gc, llgal may automatically generate several fields for each image. Available fields are image comments, filename and image timestamp. llgal will try to generate each field and concat them to create the caption. To generate captions from the filename only, run:
  llgal --gc --cf
To generate captions from the image timestamp (extracted from Exif tags when existing) and filename:
  llgal --gc --cf --ct
To generate captions from the image comments (extract from JFIF or Exif), timestamp and filename:
  llgal --gc --cc --cf --ct
These commands will generate a captions file that you might then use when generating the gallery. You might also directly generate captions during the gallery generation through something like:
  llgal --cc --ct
Note that if a captions file exists, command line options about captions generation are omitted. Also note that --cc and --ct require the Image::ExifTool Perl module to be installed.

How do I add a slide containing some text or link?

After generating the captions file with --gc, you might add a special slide containing only some text by inserting the following line in the file:
TXT: the text that is shown in the slide ---- the caption under the slide
Regenerating the gallery will then add this slide. The following line add a special slide with a link instead of plain text:
LNK: the url ---- the label of the link in the slide ---- the caption under the slide
If you do not want those slides containing a single link or text to appear like this, you may use -L so that they will be listed as a text line in the index. You may also use LNKNOSLIDE: entries to add links without slides.

How do I add new entries to a captions file?

Re-running llgal with --gc will rescan the existing files and add the missing ones at the end of the captions file. You then re-run llgal to update the gallery regarding the new captions file.

How do I keep the list of images involved in a gallery?

The captions file may also be used to keep track of the contents of a gallery. Even if you do not add some captions or title in the captions file, you may use it to list the exact set of images that you want to appear in the gallery.

Managing slides

How do I change the order of the slides?

The order of the slides might be changed with the sort option on command-line. For instance, --sort=iname sorts by name case insensitively, while --sort=revdate sorts by date, in reverse order. It is also possible to set the order by changing captions positions in the captions file.

How do I select which files are included in a gallery?

By default, llgal does only include images and movies in the gallery. It is possible to force it to use all existing files in the directory (except *.html and .*) with:
  llgal -A
It is also possible to exclude some files with --exclude regexp where regexp is a Perl regexp. For instance, to exclude all AVI files starting with MVI:
  llgal --exclude 'MVI.*\.AVI'
File that were excluded might be reincluded by using the similar --include option. Finally, it is always possible to exclude files by generating a captions file and removing some entries. Note that the captions file is a good way to keep the list of images that are involved in the gallery, even if you do not want any caption.

Layout

How do I change the layout of the slides and index?

The main layout of generated webpages is based on HTML templates (indextemplate.html and slidetemplate.html) and a CSS style-sheet (llgal.css). It is possible to place modified versions of these files in the .llgal directory (or in $HOME/.llgal/) to change the layout.

Why does llgal ignore the image dimension limits that I give?

Since converting images might be slow, llgal does not always regenerate thumbnails and scaled images. By default, it only does if the original images has been changed since last generation. To force regeneration, for instance if you changed the thumbnails (with --tx or --ty) or scaled images dimensions (with --sx or --sy), you may use -f (or force_image_regeneration).

Does changing the maximal thumbnail dimensions really work?

By default, the width and height of thumbnails are both limited. Both dimension limits may be changed with --tx or --ty, but changing a single one does affect the other one. It means that the other should be changed too in most of the circumstances. Note that changing one of these options requires to force regeneration of thumbnails.

How can I get the images in slides to adapt their size to the window?

llgal has been designed to create fixed-size slides. If, instead, you would like your images in slides to follow the size of the window, you may use the slide_dimensions_from_css option, either from a configuration file or with --option on the command line. llgal will then remove all absolute dimensions for images in HTML slides. Finally, you will be able to set the image width through the CSS slide sheet (llgal.css), for instance by adding width: 100% in table.slide td.image-slide img.

How do I change the text that llgal generates in slides and index?

All text that appears in generated slides might be configured through configuration options. One day, there might be a full internationalization support through gettext.

How can I go to the next slide when clicking on the current one?

By default, you need to click on Next to go to the next slide. If you passed --sx or --sy, clicking on the slide will lead you to the original image. If not, clicking does nothing. If you want this click to jump to the next slide, you just need to modify the slidetemplate and replace
       <!--THIS-SLIDE-->
with
       <a href="<!--NEXT-SLIDE-->"><!--THIS-SLIDE--></a>
and regenerate the gallery. Of course, if you keep using --sx or --sy, you will get into problems since there will be 2 hyperlinks on each slide.

How do I set a thumbnail for a video or a subgallery?

All non-image slides and thumbnails are usually basic text. It is possible to force llgal to use a special thumbnail or scaled image by adding a special file in the local .llgal directory with prefix mythumb_ or myscaled_. For instance, mythumb_image24.jpg will be used as a thumbnail for image image24.jpg. mythumb_subdir3.jpg will be used for sub-directory subdir3. And myscaled_bar.avi.jpg will be used as a scaled image for movie bar.avi. The extension for the thumbnail or scaled image may be any image extension that llgal recognizes.

How do I get image EXIF tags in my slides?

Most images contains some meta-data called EXIF tags that may be useful to some people. llgal can display a table of some EXIF values under each image slide. The name of the tags correspond to what the exiftool program uses (see for instance exiftool --list).
  llgal --exif Aperture,FocalLength,ImageHeight,ImageWidth,FileModifyDate
Note that --exif requires the Image::ExifTool Perl module to be installed.

Configuration

How do I save/restore a configuration?

If you like using the same options for all your galleries and don't want to remember the option, you may ask llgal to generate a configuration file with:
  llgal --gencfg my_llgalrc
This file might be used later with
  llgal --config my_llgalrc
It may also be placed in the user llgal configuration file $HOME/.llgal/llgalrc. The configuration file contains a list of configuration lines. All command line options, and even much more, are available by this way. It is possible to pass any configuration option on the command line with --option. For instance, to set which file extensions llgal will match to find movies, use:
  llgal --option 'movie_extensions="mpe?g|avi|mov|ogm"'

Multiple directories and subdirectories

How do I include several subdirectories in a unique gallery?

If your photos are organized in several subdirectories of the working directory, you can use -P to take the photos from them instead of from the working directory.
  llgal -P subdir1 -P subdir2 -P subdir3
If you want these subdirectories to appear as sections, llgal can generate a horizontal line between each subdirectory and add a title in the index with --Ps. Additionally, llgal can display the title as regular text in the index instead of a text thumbnail with -L.
  llgal -P subdir1 -P subdir2 -P subdir3 --Ps -L
As usual, these horizontal lines and titles are generated as TXT and LINE entries are processed from the captions file. Thus, you may start by creating a captions file, edit it and then generate the gallery.
  llgal -P subdir1 -P subdir2 -P subdir3 --Ps --gc
  vi .llgal/captions
  llgal -L

How do I include all subdirectories in a unique gallery?

Instead of passing -P for each subdirectory, you may ask llgal to include all images from all subdirectories.
  llgal --Pall

How do I add a new subdirectory contents to a gallery?

You may a the list of files of a subdirectory to an existing gallery if its captions file if available, by regenerating it:
  llgal -P newsubdir --gc
The directory contents is added at the end of the captions file, which may be reordered by the user. The gallery may then be regenerated from the new captions file by re-running llgal.

How do I create multiple subgalleries at once?

If your directory contains subdirectories, you might use -S to create slides linking to these subgalleries. With -R, the subgalleries will even be generated right after the main gallery. The list of subgalleries might be changed by modifying DIR: entries in the captions file.

How do I modify a single gallery in a set of subgalleries?

Galleries that were created recursively (with -R) may be linked with their parents, children and brothers. If you plan to regenerate some galleries independently, you should take care of saving the configuration with --gencfg or generating a captions file. All linking information is stored inside these files. Regeneration is then easy (with --config in the first case).

How do I create a text menu linking to multiple galleries?

Assuming you have a main directory containing multiple subdirectories where you already created sub-galleries, you may do:
  llgal -L -s
Using -L will create text links instead of thumbnails linking to sub-galleries, while -s will avoid any slide to be created.
As you may want slides in the sub-galleries, adding -R is not recommended here since -s would remove slides from both the main gallery and the sub-galleries. If you need -R anyway, you may for instance avoid this problem by dropping -s on the command and inserting make_no_slides=1 in the main gallery configuration file (.llgal/llgalrc). Since the local configuration file is used for the local gallery and not for sub-galleries (even with -R), make_no_slides=1 won't affect sub-galleries.

Miscellaneous

How do I add keyboard shortcuts to my gallery?

The HTML accesskey feature may be use to navigate in llgal's galleries with keyboard shortcuts. But as this feature is very browser dependant and might conflict with some regular shortcuts in certain browsers, it is not enabled by default in llgal. Access keys can be configured by changing the templates and adding accesskey=<letter> to links. For instance, changing the slidetemplate.html code to the following one will define p, n and i as accesskeys to previous slide, next slide and return to the index. It means that Alt+p, Alt+n and Alt+i will be the actual shortcuts in Mozilla Firefox.
      <a href="<!--PREV-SLIDE-->" accesskey=p><!--PREV-SLIDE-LINK-TEXT--></a>
      &nbsp; &nbsp; &nbsp;
      <a href="<!--INDEX-FILE-->" accesskey=i><!--INDEX-LINK-TEXT--></a>
      &nbsp; &nbsp; &nbsp;
      <a href="<!--NEXT-SLIDE-->" accesskey=n><!--NEXT-SLIDE-LINK-TEXT--></a>
Note that the slide template might be modified by getting a copy with in the local or user-wide configuration directory using --gt.

How do I prevent llgal from erasing my captions file?

llgal --clean erases all files that have not been modified regarding to their original template. The captions file does not have a template, so llgal will only erase it if it contains the following line:
# REMOVE THIS LINE IF LLGAL SHOULD NOT REMOVE THIS FILE
When the user generates the captions file himself, he is not supposed to add this line, which means llgal won't erase the file. But, when the captions are generated with llgal --gc, this line will be added automatically. Hence, if the user modifies the captions file, he should start by removing this line first to protect his modifications from future erasing.
Note that llgal --cleanall erases ALL files, even if you kept the above line in the captions file.

How do I let people add comments to my slides dynamically?

The --php option of llgal enables generation of PHP slides instead of HTML. By default, no PHP code is inserted. But, you may change the templates to add some PHP code to do whatever you want, including handle dynamic comments that people may add to your slides. llgal comes with some examples, including the directory dynamic_comments_in_slides/ which gives a quick and dirty example to do so.

Why is llgal so slow?

llgal uses ImageMagick (and especially convert) to generate thumbnails (and scaled images if --sx or --sy was passed). It can be pretty long if you have lots of large images. To avoid being slow everytime you re-run llgal, thumbnails and scaled images are only generated once (except when the original has been modified since or when -f is passed, see Why does llgal ignore the image dimension limits that I give?). There might be some way to improve the overall speed of thumbnails and scaled images generation by changing the corresponding command line with scaled_create_command and thumbnail_create_command in the configuration file. You may for instance use another conversion program which is more optimized than ImageMagick to process your specific images. See tweak_image_generation.txt in the examples in the documentation for details.

Why does llgal not provide any feature to rotate or modify images?

llgal is only a gallery generator. Adding features to rotate images (for instance using Exif tags) or modify images (for instance to apply some filters) would open the door for thousands of options that llgal does not really require (and the command line interface is already pretty complex). We prefer keeping those features in other softwares that the user runs before using llgal. Also, there is no technical reason to include such filters in llgal. Applying them with another specialized software before generating the gallery is as easy, and such software will always provide more features than llgal.

How do I scale my images to a smaller size and drop the originals?

llgal is not supposed to be used for this (see Why does llgal not provide any feature to rotate or modify images?). You should use an external tool earlier and then apply llgal on the scaled images. If you really want to use llgal to scale images down, you should use --sx and/or --sy. The scaled images will be placed in .llgal/scaled_*. To drop the originals and use the scaled images directly, you should first remove the originals from the main directory. Then move the scaled images from .llgal to the main directory and remove the scaled_ suffix (rename 's@^\.llgal/scaled_@@' .llgal/scaled_* should do the trick). Finally, re-run the same llgal command line without --sx and/or --sy. You should get the same gallery as before, without the links from the slides to the original images.

The llgal team.
$Id: howto.html,v 1.1 2006/05/07 00:46:01 bgoglin Exp $
llgal-llgal-0.13.19/doc/llgalrc000066400000000000000000000310171314312235400161610ustar00rootroot00000000000000# llgal configuration options. # These options may be defined in /etc/llgal/llgalrc, a per-user # ${HOME}/.llgal/llgalrc file or a directory-specific .llgal/llgalrc. # Most of these options may later be overridden by command line options. # Default are shown in examples below. # Syntax is one of these: # variable = "string" # variable = decimal number # variable = 0 or 1 for disabling or enabled # For now, only static values are supported. # Brackets indicate corresponding command line options. ##### Name of generic llgal files ##### # Name of the captions header file that is inserted at the beginning # of generated captions files. # captions_header_filename = "captions.header" # Name of the CSS file. # Such a file will be stored under $local_llgal_dir. # css_filename = "llgal.css" # Name of the film tile image. # Such a file will be stored under $local_llgal_dir. # Note that this filename must match the one that is used in the CSS file. # filmtile_filename = "tile.png" # Name for image link to the index, previous or next slide # index_link_image_filename = "index.png" # prev_slide_link_image_filename = "prev.png" # next_slide_link_image_filename = "next.png" # Name of the index template. # Such a template file will be used during gallery generation. # indextemplate_filename = "indextemplate.html" # Name of the slide template. # Such a template file will be used during gallery generation. # slidetemplate_filename = "slidetemplate.html" ##### Location of llgal files if available on the web ##### # Location of the CSS file if available on the web [--uc ]. # If ending with '/', css_filename will be added. # css_location = "" # Location of llgal image files if available on the web. # If ending with '/', their generic filename will be added. # These locations may be set alltogether with --ui . # filmtile_location = "" # index_link_image_location = "" # prev_slide_link_image_location = "" # next_slide_link_image_location = "" ##### Location and name of generated files ##### # Local subdirectory where llgal files generated files will be stored. # This option is only available in system- and user-wide configuration # files. # Note that HTML files are generated in place while captions and CSS # are kept in this subdirectory. # Gallery specific HTML templates and llgalrc configuration file # might also be defined here. # local_llgal_dir = ".llgal" # Name of the generated index file [-i ] # index_filename = "index" # Prefix of generated HTML slide filenames # Note that this prefix is used to decide what HTML to delete when --clean # is passed. Setting this option to an empty string will make llgal remove # all HTML files. # slide_filenameprefix = "slide_" # Prefix used to determine the filenames of scaled image that are # shown in slides (in case of --sx or --sy). # These files will be stored under $local_llgal_dir. # scaled_image_filenameprefix = "scaled_" # Prefix used to determine thumbnail filenames from original images. # These files will be stored under $local_llgal_dir. # thumbnail_image_filenameprefix = "thumb_" # Name of the captions file that will be generated when llgal is called # with --gc. This file will be stored under $local_llgal_dir. # captions_filename = "captions" # Additional prefix of user-provided scaled images # user_scaled_image_filenameprefix = "my" # Additional prefix of user-provided thumbnails # user_thumbnail_image_filenameprefix = "my" # Character to use to replace / in the thumbnail/scaled of subdir images # path_separator_replacement = "@" ##### Index ##### # Cellpadding in the index table [-p ] # Must be >= 0, setting to < 0 resets to default # index_cellpadding = 3 # Display links and text as regular text instead of thumbnails # in the main gallery thumbnail index [-L] # list_links = 0 # Pixels per row of thumbnails in index [--wx ] # Must be > 0, 0 means unlimited, setting to < 0 resets to default # pixels_per_row = 0 # Thumbnails per row in index [-w ] # Must be > 0, 0 means unlimited, setting to < 0 resets to default # thumbnails_per_row = 5 # Do not output any absolute thumbnail sizes in HTML code and assume the # CSS style sheet will take care of it (in table.index [td.image-slide [img]]) # slide_dimensions_from_css = 0 # Maximal height of thumbnails [--ty ] # Must be > 0, setting to < 0 resets to default # Changing this value does not affect the maximal width (see thumbnail_width_max) # thumbnail_height_max = 75 # Maximal width of thumbnails [--tx ] # Must be > 0, 0 means unlimited, setting to < 0 resets to default # Changing this value does not affect the maximal height (see thumbnail_height_max) # thumbnail_width_max = 113 # Write captions under thumbnails [-u] # show_caption_under_thumbnails = 0 # Show a film effect in the index of thumbnails [--fe] # show_film_effect = 0 # Make thumbnail links point to the target object instead of # the corresponding slide # MVI_link_to_target = 0 # FIL_link_to_target = 0 # DIR_link_to_target = 0 # LNK_link_to_target = 0 ##### Slides ##### # Make no slides [-s] # make_no_slides = 0 # Use filename as slide filename [-n] # make_slide_filename_from_filename = 0 # Also use extension in the slide filename to differenciate # slide filename of images that have same filenames. # make_slide_filename_from_extension = 0 # Do not output any absolute image size in the HTML code and assume the # CSS style sheet will take care of it (in table.slide td.image-slide img) # slide_dimensions_from_css = 0 # Maximal width of slides [--sx ] # Must be > 0, 0 means unlimited, setting to < 0 resets to default # slide_width_max = 0 # Maximal height of slides [--sy ] # Must be > 0, 0 means unlimited, setting to < 0 resets to default # slide_height_max = 0 # Default size of non-image slides. # Must be > 0, setting to < 0 resets to default # Note that the --sx and --sy options may lead to reduction of these values. # text_slide_width = 400 # text_slide_height = 300 # Use an image instead of a text label for the link to the index, # previous or next slide [--li] # index_link_image = 0 # next_slide_link_image = 0 # prev_slide_link_image = 0 # Use a thumbnail preview instead of a text label for the link # to the previous or next slide [--lt] # next_slide_link_preview = 0 # prev_slide_link_preview = 0 # Generate slide titles from captions [-k] # make_slide_title_from_caption = 0 # Generate links between last and first slides or galleries. # link_between_last_and_first = 1 # Display a table of EXIF tags under each image slide [--exif] # The tags are given with their name in exiftool -list and separated # with a comma. # show_exif_tags = "" # Display a table of all available EXIF tags under each image slide [--exif] # show_all_exif_tags = 0 ##### Captions ##### # This line will be added to the captions file llgal will generate when # called with --gc. If the user doesn't want llgal to remove this captions # file when called with --clean, it just needs to remove this line from # the file. # captions_removal_line = "REMOVE THIS LINE IF LLGAL SHOULD NOT REMOVE THIS FILE" # Generate captions from comment stored in images [--cc []] # make_caption_from_image_comment = "" # Also generate captions from timestamp stored in images [--ct] # make_caption_from_image_timestamp = 0 # Generate captions from filenames without their extension [--cf] # make_caption_from_filename = 0 # Generate captions from filenames with their extension # make_caption_from_extension = 0 # Show dimensions and/or size of the images and movies [-a, --ad, --as] # show_dimensions = 0 # show_size = 0 # Change the format of the counter shown on the slides # %n is replaced by the slide number, %0n gets leading zeros, # and %t is replaced by the number of slides. # Setting to "" disables the slide counter [--nc] # slide_counter_format = "   (%0n/%t)" ##### Text ##### # Default title of the gallery. # May be overridden with [--title ] or TITLE: in the captions file. # index_title_default = "Index of pictures" # Change text in links to parent directory. # parent_gallery_link_text = "Back to parent gallery" # Change text in links to previous gallery. # prev_gallery_link_text = "Previous gallery " # Change text in links to next directory. # next_gallery_link_text = "Next gallery " # Label of the link from a slide to the index # index_link_text = "Index" # Label of the link from a slide to the previous one # prev_slide_link_text = "<<Prev" # Label of the link from a slide to the next one # next_slide_link_text = "Next>>" # Text prefixing the filename when generating link text # for movies without a captions file. # MVI_link_text = "Open movie " # Text prefixing the filename when generating link text # for files without a captions file. # FIL_link_text = "Download file " # Text prefixing the filename when generating link text # for directories without a captions file. # DIR_link_text = "Open subgallery " # Text shown as image alternative for full-size images in slides # alt_full_text = "" # Text shown as image alternative for scaled images in slides # alt_scaled_text = "Scaled image " # Text shown as image alternative for thumbnails in the index # alt_thumbnail_text = "Thumbnail " # Text shown as an image alternative for the film tile in the index # alt_film_tile_text = "Film tile" # Text shown when the mouse pointer is over a scaled image in a slide # over_scaled_text = "Click to see full size " # Text shown when the mouse pointer is over a thumbnail # over_thumbnail_text = "Click to enlarge " # Text shown when the mouse pointer is over a link from a slide to the index # over_index_link_text = "Return to the index" # Text shown when the mouse pointer is over a link from a slide to the previous one # over_prev_slide_link_text = "Previous slide " # Text shown when the mouse pointer is over a link from a slide to the next one # over_next_slide_link_text = "Next slide " # Unit to be used when printing sizes [--asu ] # show_size_unit = "kB" # Set timestamp format in captions (when enabled) using strftime format [--ct ] # timestamp_format_in_caption = "%Y-%m-%d %H:%M:%S" # Credits line at the bottom of the index # credits_text = "created with llgal" ##### What files to insert in the gallery ##### # Extensions that are matched when searching images (|-separated list) # image_extensions = "jpg|jpeg|gif|png|tif|tiff|bmp" # Extensions that are matched when searching movies (|-separated list) # movie_extensions = "mpg|mpeg|avi|mov|ogm|wmv|mp4|3gp" # Add all files to the list of entries # not only images and movies [-A] # add_all_files = 0 # Add subdirectories to the list of entries [-S] # add_subdirs = 0 # Exclude files whose name matches [--exclude ] # This option may be used several times. # exclude = "regexp" # Include files whose name matches and were previously excluded [--include ]. # This option may be used several times. # The order of includes and excludes is respected. # include = "regexp" # Sort criteria when scanning files in the working directory [--sort] # sort_criteria = "name" ##### Sections ##### # Add a new subdirectory to the list of sections [-P] # section_dir = "subdir" # Add all subdirectories to the list of sections [--Pall] # recursive_sections = 0 # Add the subdirectory name as a title at the beginning of each section [--Ps] # entitle_sections = 0 # Add a horizontal line at the beginning of each section in the index [--Ps] # separate_sections = 0 ##### Recursion ##### # Run recursively in subdirectories [-R] # recursive = 0 # Add links between subgalleries [--Rl] # link_subgalleries = 0 # Add links to the parent directory [--parent-gal] # parent_gallery_link = 0 ##### Various ##### # Additional configuration file [--config ] # This option may be used multiple times. # additional_configuration_file = "my_llgal.rc" # Additional template directories [--templates]. # This option may be used multiple times. # additional_template_dir = "path" # Codeset to be set in HTML headers [--codeset ] # codeset = "codeset" # Language to be used for generated text in HTML pages [--lang ] # If set, the LANGUAGE environment variable might prevent this option from working. # language = "locale" # Command to be used to generate scaled images and thumbnails # thumbnail_create_command = "convert -scale x -- " # scaled_create_command = "convert -scale x -- " # Force regeneration of thumbnails and scaled images [-f]. # force_image_regeneration = 0 # Print notice messages [-v] # verbose = 0 # Give access rights for www access [--www] # www_access_rights = 0 # Extension of generate webpages [--php] # www_extension = "html" llgal-llgal-0.13.19/doc/upgrade.html000066400000000000000000000106221314312235400171320ustar00rootroot00000000000000 How-to upgrade a gallery from igal to llgal?

How-to upgrade a gallery from igal to llgal?

This upgrade documentation is available on-line and in the tarball and distribution packages.

File location

igal places all files in the working directory with existing images.

  • .captions
  • .indextemplate.html
  • .slidetemplate.html
  • .slide_<image>
  • .thumb_<image>
  • .tile.png
  • igal.css

llgal moves all these files in a .llgal, making the starting dot useless. .slide_<image> is also replaced by .scaled_<image>.

  • .llgal/captions
  • .llgal/indextemplate.html
  • .llgal/slidetemplate.html
  • .llgal/scaled_<image>
  • .llgal/thumb_<image>
  • .llgal/tile.png
  • .llgal/llgal.css

Note that earlier versions of llgal use .llgal.files instead of .llgal.

CSS style sheet

The CSS style sheet has been updated. If you modified it, you should probably diff against the original igal.css, and apply the difference (by hand) to llgal.css.

Command line options

  • All long options (more than one character) now requires a double dash.
  • igal -clean is now llgal --cleanall since llgal --clean only removes file that have not been modified.
  • Captions generation uses --gc instead of -c. The caption is automatically used if it exists, -c is not used anymore. Captions generation from filename is --cf instead of -C.
  • Do not show image counter in captions is now --nc instead of -x.
  • The film effect in the index of thumbnails is now disabled by default. Instead of disabling it with -r, you may now enable it with --fe.
  • --sp and --tp options got removed. But scaled_image_filenameprefix and thumbnail_image_filenameprefix configuration options allow prefix modification.
  • -bigy (limit image height in slides) is replaced with --sy. -y (limit thumbnail height) is replaced with --ty.
  • -t has been removed, the user just need to modify the tile.png image to get an updated layout.
  • --con has been removed, image generation command line may now be configured by changing scaled_create_command and thumbnail_create_command configuration options.

How-to upgrade

If you don't care about processing time:

  • Save your .captions file if it exists
  • Note the command line you used when creating the gallery (see in the header of index.html)
  • Remove everything but the images with igal -clean
  • Create a .llgal directory and move your captions files inside (remember it is now named captions instead of .captions)
  • Run llgal with same options (see section 3 for details)

Recomputing the whole gallery might be long, especially if you have tons of images, since thumbnails (and scaled images if --bigy/--bigxy is passed) have to be generated.

If you don't want to regenerate these, see section File location and move .thumb_* and .slide_* files to .llgal/thumb_* and scaled_* so that llgal uses them.


The llgal team.
$Id: upgrade.html,v 1.1 2006/05/07 09:21:15 bgoglin Exp $
llgal-llgal-0.13.19/lib/000077500000000000000000000000001314312235400146155ustar00rootroot00000000000000llgal-llgal-0.13.19/lib/Llgal/000077500000000000000000000000001314312235400156505ustar00rootroot00000000000000llgal-llgal-0.13.19/lib/Llgal/Config.pm000066400000000000000000001304101314312235400174120ustar00rootroot00000000000000package Llgal::Config ; use strict ; require Llgal::Messages ; require Llgal::Utils ; use Getopt::Long ; use I18N::Langinfo qw(langinfo CODESET) ; use Locale::gettext ; use POSIX qw(strftime) ; use Text::ParseWords ; ###################################################################### # default values that will be restored if the associated option is set to -1 my $index_cellpadding_default = 3 ; my $pixels_per_row_default = 0 ; # unlimited my $thumbnail_width_max_default = 113 ; my $thumbnail_height_max_default = 75 ; my $thumbnails_per_row_default = 5 ; my $slide_height_max_default = 0 ; # unlimited my $slide_width_max_default = 0 ; # unlimited my $text_slide_width_default = 400 ; my $text_slide_height_default = 300 ; ###################################################################### # early cmdline parsing sub early_parse_cmdline_options { my $self = shift ; Getopt::Long::Configure('passthrough') ; GetOptions( 'd=s' => \$self->{destination_dir}, ) ; # restore default behavior: process all options and warn on error Getopt::Long::Configure('nopassthrough') ; } ###################################################################### # gettext strings are prefixed to distinguish between identical strings sub init_llgal_gettext { my $self = shift ; textdomain ("llgal") ; bindtextdomain ("llgal", $self->{locale_dir}) ; } sub llgal_gettext { my $id = shift ; my $string = gettext ($id) ; $string =~ s/^[^|]+\|// ; return $string ; } ###################################################################### # configuration variables characteristics # normal option characteristics my $OPT_IS_NUMERIC = 1 ; my $OPT_IS_STRING = 2 ; my $OPT_IS_NONEMPTY_STRING = 3 ; my $normal_opts_type = { # Name of generic llgal files captions_header_filename => $OPT_IS_NONEMPTY_STRING, css_filename => $OPT_IS_NONEMPTY_STRING, filmtile_filename => $OPT_IS_NONEMPTY_STRING, index_link_image_filename => $OPT_IS_NONEMPTY_STRING, prev_slide_link_image_filename => $OPT_IS_NONEMPTY_STRING, next_slide_link_image_filename => $OPT_IS_NONEMPTY_STRING, indextemplate_filename => $OPT_IS_NONEMPTY_STRING, slidetemplate_filename => $OPT_IS_NONEMPTY_STRING, # location of generic llgal files that are available on the web css_location => $OPT_IS_STRING, filmtile_location => $OPT_IS_STRING, index_link_image_location => $OPT_IS_STRING, prev_slide_link_image_location => $OPT_IS_STRING, next_slide_link_image_location => $OPT_IS_STRING, # Location and name of generated files index_filename => $OPT_IS_NONEMPTY_STRING, slide_filenameprefix => $OPT_IS_STRING, scaled_image_filenameprefix => $OPT_IS_NONEMPTY_STRING, thumbnail_image_filenameprefix => $OPT_IS_NONEMPTY_STRING, captions_filename => $OPT_IS_NONEMPTY_STRING, user_scaled_image_filenameprefix => $OPT_IS_NONEMPTY_STRING, user_thumbnail_image_filenameprefix => $OPT_IS_NONEMPTY_STRING, path_separator_replacement => $OPT_IS_NONEMPTY_STRING, # Index index_cellpadding => $OPT_IS_NUMERIC, # >= 0, -1 for default list_links => $OPT_IS_NUMERIC, pixels_per_row => $OPT_IS_NUMERIC, # > 0, 0 for unlimited, -1 for default thumbnails_per_row => $OPT_IS_NUMERIC, # > 0, 0 for unlimited, -1 for default thumbnails_dimensions_from_css => $OPT_IS_NUMERIC, thumbnail_height_max => $OPT_IS_NUMERIC, # > 0, -1 for default thumbnail_width_max => $OPT_IS_NUMERIC, # > 0, 0 for unlimited, -1 for default show_caption_under_thumbnails => $OPT_IS_NUMERIC, show_film_effect => $OPT_IS_NUMERIC, MVI_link_to_target => $OPT_IS_NUMERIC, FIL_link_to_target => $OPT_IS_NUMERIC, DIR_link_to_target => $OPT_IS_NUMERIC, LNK_link_to_target => $OPT_IS_NUMERIC, # Slides make_no_slides => $OPT_IS_NUMERIC, make_slide_filename_from_filename => $OPT_IS_NUMERIC, make_slide_filename_from_extension => $OPT_IS_NUMERIC, slide_dimensions_from_css => $OPT_IS_NUMERIC, slide_width_max => $OPT_IS_NUMERIC, # > 0, 0 for unlimited, -1 for default slide_height_max => $OPT_IS_NUMERIC, # > 0, 0 for unlimited, -1 for default text_slide_width => $OPT_IS_NUMERIC, # > 0, -1 for default text_slide_height => $OPT_IS_NUMERIC, # > 0, -1 for default index_link_image => $OPT_IS_NUMERIC, prev_slide_link_image => $OPT_IS_NUMERIC, next_slide_link_image => $OPT_IS_NUMERIC, prev_slide_link_preview => $OPT_IS_NUMERIC, next_slide_link_preview => $OPT_IS_NUMERIC, link_between_last_and_first => $OPT_IS_NUMERIC, make_slide_title_from_caption => $OPT_IS_NUMERIC, show_all_exif_tags => $OPT_IS_NUMERIC, slide_link_to_full_image => $OPT_IS_NUMERIC, # Captions captions_removal_line => $OPT_IS_NONEMPTY_STRING, make_caption_from_image_comment => $OPT_IS_STRING, make_caption_from_image_timestamp => $OPT_IS_NUMERIC, make_caption_from_filename => $OPT_IS_NUMERIC, make_caption_from_extension => $OPT_IS_NUMERIC, show_dimensions => $OPT_IS_NUMERIC, show_size => $OPT_IS_NUMERIC, slide_counter_format => $OPT_IS_STRING, # Text index_title_default => $OPT_IS_STRING, index_link_text => $OPT_IS_NONEMPTY_STRING, parent_gallery_link_text => $OPT_IS_NONEMPTY_STRING, prev_gallery_link_text => $OPT_IS_STRING, next_gallery_link_text => $OPT_IS_STRING, prev_slide_link_text => $OPT_IS_NONEMPTY_STRING, next_slide_link_text => $OPT_IS_NONEMPTY_STRING, MVI_link_text => $OPT_IS_STRING, FIL_link_text => $OPT_IS_STRING, DIR_link_text => $OPT_IS_STRING, alt_full_text => $OPT_IS_STRING, alt_scaled_text => $OPT_IS_STRING, alt_thumbnail_text => $OPT_IS_STRING, alt_film_tile_text => $OPT_IS_STRING, over_scaled_text => $OPT_IS_STRING, over_thumbnail_text => $OPT_IS_STRING, over_index_link_text => $OPT_IS_STRING, over_prev_slide_link_text => $OPT_IS_STRING, over_next_slide_link_text => $OPT_IS_STRING, show_size_unit => $OPT_IS_STRING, timestamp_format_in_caption => $OPT_IS_NONEMPTY_STRING, credits_text => $OPT_IS_STRING, # What files to insert image_extensions => $OPT_IS_STRING, movie_extensions => $OPT_IS_STRING, add_all_files => $OPT_IS_NUMERIC, add_subdirs => $OPT_IS_NUMERIC, sort_criteria => $OPT_IS_NONEMPTY_STRING, # Sections entitle_sections => $OPT_IS_NUMERIC, separate_sections => $OPT_IS_NUMERIC, recursive_sections => $OPT_IS_NUMERIC, # Recursion parent_gallery_link => $OPT_IS_NUMERIC, link_subgalleries => $OPT_IS_NUMERIC, # Various codeset => $OPT_IS_STRING, language => $OPT_IS_STRING, scaled_create_command => $OPT_IS_STRING, thumbnail_create_command => $OPT_IS_STRING, force_image_regeneration => $OPT_IS_NUMERIC, recursive => $OPT_IS_NUMERIC, www_access_rights => $OPT_IS_NUMERIC, www_extension => $OPT_IS_NONEMPTY_STRING, } ; # options whose input or output is non-trivial: # options that have a special parsing routine my $special_opts_with_input = { local_llgal_dir => 1, exclude => 1, include => 1, additional_configuration_file => 1, additional_template_dir => 1, show_exif_tags => 1, section_dir => 1, verbose => 1, } ; # internal options that have a special outputting routine my $special_opts_with_output = { excludes => 1, template_dirs => 1, show_exif_tags => 1, section_dirs => 1, } ; # stuff that is not stored in the option hash but need be outputted my $special_nonopts_with_output = { local_llgal_dir => 1, verbose => 1, } ; # internal options that are never output my $special_opts_without_output = { default_thumb_xdim => 1, default_thumb_ydim => 1, } ; # options whose merging is done as array my $special_opts_merging_as_array = { excludes => 1, template_dirs => 1, } ; ###################################################################### # manage configuration variables # overwrite current_opts (1st argument) with overwriting_opts (2nd) sub merge_opts { my $current_opts = shift ; my $overwriting_opts = shift ; foreach my $key (keys %{$overwriting_opts}) { if (defined $overwriting_opts->{$key}) { if (defined $special_opts_merging_as_array->{$key} and defined $current_opts->{$key}) { $current_opts->{$key} = [@{$current_opts->{$key}}, @{$overwriting_opts->{$key}}] ; } else { $current_opts->{$key} = $overwriting_opts->{$key} } } } } # overwrite current_opts with overwriting_opts in a new hash, without changing the originals sub merge_opts_into { my $current_opts = shift ; my $overwriting_opts = shift ; my $new_opts = {} ; merge_opts ($new_opts, $current_opts) ; merge_opts ($new_opts, $overwriting_opts) ; return $new_opts ; } # set default to all uninitialized options sub add_defaults { my $current_opts = shift ; my $default_opts = { # Name of generic llgal files captions_header_filename => "captions.header", css_filename => "llgal.css", filmtile_filename => "tile.png", index_link_image_filename => "index.png", prev_slide_link_image_filename => "prev.png", next_slide_link_image_filename => "next.png", indextemplate_filename => "indextemplate.html", slidetemplate_filename => "slidetemplate.html", # Location of llgal files if already on the web css_location => "", filmtile_location => "", index_link_image_location => "", prev_slide_link_image_location => "", next_slide_link_image_location => "", # Location and name of generated files # name of the index file (-i) index_filename => "index", # prefix of HTML slide filenames slide_filenameprefix => "slide_", # scaled and thumbnail image filename prefix scaled_image_filenameprefix => "scaled_", thumbnail_image_filenameprefix => "thumb_", # captions filename captions_filename => "captions", # additional prefix of user-provided scaled images user_scaled_image_filenameprefix => "my", # additional prefix of user-provided thumbnails user_thumbnail_image_filenameprefix => "my", # character to use to replace / in the thumbnail/scaled of subdir images path_separator_replacement => "@", # Index # cellpadding value for the thumbnail index tables (-p) index_cellpadding => $index_cellpadding_default, # list links outside f the table (-L) list_links => 0, # how many pixels per row at most in index (--wx) pixels_per_row => $pixels_per_row_default, # how many thumbnails per row at most in index (-w) thumbnails_per_row => $thumbnails_per_row_default, # do not output thumbnails dimensions thumbnails_dimensions_from_css => 0, # max height of a thumbnail (--ty) thumbnail_height_max => $thumbnail_height_max_default, # scale thumb longer dimension (--tx) thumbnail_width_max => $thumbnail_width_max_default, # write captions under thumbnails on index page (-u) show_caption_under_thumbnails => 0, # show the film effect in the index of thumbnails (--fe) show_film_effect => 0, # link thumbnails to target instead of slide MVI_link_to_target => 0, FIL_link_to_target => 0, DIR_link_to_target => 0, LNK_link_to_target => 0, # Slides # make no slides, just thumbnail links to images (-s) make_no_slides => 0, # use image names as slide names (-n) make_slide_filename_from_filename => 0, # also use image extension in the slide names make_slide_filename_from_extension => 0, # do not output dimensions for slides, let the css do it slide_dimensions_from_css => 0, # max width of the slides (--sx) slide_width_max => $slide_width_max_default, # max height of the slides (--sy) slide_height_max => $slide_height_max_default, # default text slide width text_slide_width => $text_slide_width_default, # default text slide height text_slide_height => $text_slide_height_default, # use an image for link from a slide to the index, previous or next slide index_link_image => 0, prev_slide_link_image => 0, next_slide_link_image => 0, # use an image preview for link from a slide to the previous or next slide prev_slide_link_preview => 0, next_slide_link_preview => 0, # do not link between last and first slides or galleries link_between_last_and_first => 1, # use captions as slide titles (-k) make_slide_title_from_caption => 0, # show a table of exif tags show_exif_tags => [], # link scaled to full slide_link_to_full_image => 1, # Captions # this line will be placed in caption generated file # the user may remove it to prevent llgal from removing the caption file with --clean captions_removal_line => "REMOVE THIS LINE IF LLGAL SHOULD NOT REMOVE THIS FILE", # use image comment as captions (--cc) make_caption_from_image_comment => 0, # use image timestamp as captions (--ct) make_caption_from_image_timestamp => 0, # preserve image names as captions (--cf) make_caption_from_filename => 0, # to write image dimensions (-a or --ad) show_dimensions => 0, # to write image size (-a or --as) show_size => 0, # omit the image slide from the caption (--nc) slide_counter_format => "   (%0n/%t)", # Text # title of the gallery (--title) index_title_default => llgal_gettext ("index_title|Index of pictures"), # label of link to the parent gallery parent_gallery_link_text => llgal_gettext ("parent_gallery_link_text|Back to parent gallery"), # label of link to previous gallery prev_gallery_link_text => llgal_gettext ("prev_gallery_link_text|Previous gallery "), # label of link to previous gallery next_gallery_link_text => llgal_gettext ("next_gallery_link_text|Next gallery "), # label of link from slides to index index_link_text => llgal_gettext ("index_link_text|Index"), # label of link from a slide to the previous one prev_slide_link_text => llgal_gettext ("prev_slide_link_text|<<Prev"), # label of link from a slide to the next one next_slide_link_text => llgal_gettext ("next_slide_link_text|Next>>"), # label of text inserted as a section title section_text => llgal_gettext ("section_text|Section "), # text prefixing the link text MVI_link_text => llgal_gettext ("MVI_link_text|Open movie "), FIL_link_text => llgal_gettext ("FIL_link_text|Download file "), DIR_link_text => llgal_gettext ("DIR_link_text|Open subgallery "), # alternative text for full-size images in slides alt_full_text => llgal_gettext ("alt_full_text|"), # alternative text for scaled images in slides alt_scaled_text => llgal_gettext ("alt_scaled_text|Scaled image "), # alternative text for thumbnails in the index alt_thumbnail_text => llgal_gettext ("alt_thumbnail_text|Thumbnail "), # alternative text for film tile alt_film_tile_text => llgal_gettext ("alt_film_tile_text|Film Tile"), # text shown when the mouse pointer is over a scaled image in a slide over_scaled_text => llgal_gettext ("over_scaled_text|Click to see full size "), # text shown when the mouse pointer is over a thumbnail over_thumbnail_text => llgal_gettext ("over_thumbnail_text|Click to enlarge "), # text shown when the mouse pointer is over a link to the index over_index_link_text => llgal_gettext ("over_index_link_text|Return to the index"), # text shown when the mouse pointer is over a link to the previous slide over_prev_slide_link_text => llgal_gettext ("over_prev_slide_link_text|Previous slide "), # text shown when the mouse pointer is over a link to the next slide over_next_slide_link_text => llgal_gettext ("over_next_slide_link_text|Next slide "), # change kB to another unit (--asu) show_size_unit => llgal_gettext ("show_size_unit|kB"), # format of the timestamp in captions, when enabled (--ct) timestamp_format_in_caption => llgal_gettext ("timestamp_format_in_caption|%y-%m-%d %H:%M:%S"), # credits line at the bottom of the index credits_text => llgal_gettext ("credits_text|created with llgal"), # What files to insert in the gallery # image and movie extensions image_extensions => "jpg|jpeg|png|gif|tif|tiff|bmp", movie_extensions => "mpg|mpeg|avi|mov|ogm|wmv|mp4|3gp", # add all files, not only images and movies (-A) add_all_files => 0, # add subdirectories to entry list (-S) add_subdirs => 0, # exclude/include excludes => [], # sort criteria sort_criteria => "name", # Sections # section directories section_dirs => [], # do we add a text slide to entitle sections entitle_sections => 0, # do we separate sections in the gallery separate_sections => 0, # do we create sections for all subdirectories recursive_sections => 0, # Recursion # add links between subgalleries link_subgalleries => 0, # generate header and footer for link to parent gallery parent_gallery_link => 0, # Various # codeset to be set in HTML headers (--codeset) codeset => langinfo (CODESET ()), # language to be used for generated text in HTML pages (--lang) # default is actually useless since we set it before reading the defaults language => "", # user-added directories where templates might be found template_dirs => [], # commands to generate thumbnails and scaled images scaled_create_command => "convert -scale x ", thumbnail_create_command => "convert -scale x ", # force thumbnails and scaled images regeneration force_image_regeneration => 0, # makes everything world-readable (--www) www_access_rights => 0, # extension of generate webpages (--php) www_extension => "html", } ; # merge given options _into_ defaults merge_opts ($default_opts, $current_opts) ; return $default_opts ; } ###################################################################### # Create usage now to use defaults values sub die_usage { my $self = shift ; my $usage = << "END_OF_USAGE" ; This is llgal $self->{version}, the image slide show generator. Syntax: llgal [-option -option ...] Behavior Options: llgal generates a gallery, except with one of the following options: --clean remove all generated files --cleanall remove all generated and user modified files --gc generate or update the captions file --gt [] give templates to the directory -h, --help display this brief help -v, --verbose display notice messages -V, --version show version Additional Behavior Options: The behavior might also be modified with the following options, either when generating a gallery or not: --config pass an additional configuration files -d operate in directory (current directory) -f force thumbnail and scaled slide regeneration --gencfg generate the configuration file --option pass an additional option as in configuration files -R run recursively in subdirectories Selecting files: -A add all non-image non-video files to the list of slides --exclude exclude matching files --include include matching files that were excluded -P add a section with images in subdirectory --Pall add sections and images from all subdirectories --Ps separate sections in the index with a line and a title -S add subdirectories to the list of slides Layout Options: -a write image sizes under thumbnails on index page --ad like -a, but write only the image dimensions --as like -a, but write only the file size --asu change file size unit (kB) --cc [] use image comments as captions --cf use file names as captions --ct [] use image timestamps as captions --codeset change the codeset in HTML pages --exif [] show exif tags on each slide --fe show a film effect in the index of thumbnails -i name of the main thumbnail index file (index) -k use the image captions for the HTML slide titles -L list links outside of the table --lang change the locale --li use images for links in slides --lt use thumbnail preview for links in slides -n use image file names for the HTML slide files --nc omit the image count from the captions --nf omit the link from slides' scaled images to full unscaled -p cellpadding value of thumbnail index tables (3) --parent-gal add links to the parent gallery --php use php extension for generated webpages --Rl add links between subgalleries -s make no HTML slides, link thumbnails to images --sort sort files with criteria --templates use templates in --title title of the index of the gallery (Index of pictures) --sx limit image width in slides to pixels --sy limit image height in slides to pixels --tx limit thumbnail width to pixels (113) --ty limit thumbnail height to pixels (75) -u write captions under thumbnails on index page --uc use a CSS file that is already available on the web --ui use filmtile and link images that are already available on the web -w rows in thumbnail index are at most images wide (5) --www make all llgal files world-readable --wx rows in thumbnail index are at most pixels wide Default values are given in parentheses (where applicable). Author: Brice Goglin Homepage: http://bgoglin.free.fr/llgal Report bugs to: END_OF_USAGE die $usage ; } ###################################################################### # do not show usage when dying from inside Getoptions my $no_usage_on_getoptions_error = 0 ; ###################################################################### # parse options in config files # forward declaration sub parse_custom_config_file ; # option parsing global variables my $recursive_included_configuration_file = 0 ; my $current_configuration_file = undef ; # in case of option parsing error sub process_option_error { my $error = shift ; $no_usage_on_getoptions_error = 1 ; if (defined $current_configuration_file) { my $file = $current_configuration_file ; $current_configuration_file = undef ; # reset here since we won't be able to reset anywhere else die "Line #$. of $file:\n $error.\n" ; } else { die "$error.\n" ; } } # process one option line sub process_option { my $self = shift ; my $opts = shift ; my $messages = $self->{messages} ; my $line = shift ; chomp $line ; if ($line =~ m/^([^ ]+)\s*=.+$/) { my $optname = $1 ; my $type = $normal_opts_type->{$optname} ; if (defined $type) { # use the options type to choose parsing if ($type == $OPT_IS_NUMERIC) { # any match is fine if ($line =~ m/^[^ ]+\s*=\s*(\d+)$/) { $opts->{$optname} = $1 ; } else { process_option_error "Configuration option <$optname> value must be numeric (in <$line>)" ; } } elsif ($type == $OPT_IS_STRING) { # value must be quoted if ($line =~ m/^[^ ]+\s*=\s*"(.*)"$/) { $opts->{$optname} = $1 ; } else { process_option_error "Configuration option <$optname> value must be a string (in <$line>)" ; } } elsif ($type == $OPT_IS_NONEMPTY_STRING) { # value must be quoted and non-empty if ($line =~ m/^[^ ]+\s*=\s*"(.+)"$/) { $opts->{$optname} = $1 ; } else { process_option_error "Configuration option <$optname> value must be a non-empty string (in <$line>)" ; } } } elsif ($special_opts_with_input->{$optname}) { # not a normal option, must be special if ($line =~ m/^local_llgal_dir\s*=\s*"(.*)"$/) { # the local llgal directory name may only be changed # during early configuration if ($self->{early_configuration}) { $self->{local_llgal_dir} = $1 ; } elsif ($1 ne $self->{local_llgal_dir}) { $messages->warning ("Ignoring changes to the name of the local llgal directory outside of") ; $messages->warning ("system- and user-wide configuration files.") ; } } elsif ($line =~ m/^exclude\s*=\s*"(.+)"$/) { my $entry = () ; $entry->{excluded} = 1 ; $entry->{filter} = $1 ; push (@{$opts->{excludes}}, $entry) ; } elsif ($line =~ m/^exclude\s*=\s*"(.+)"$/) { my $entry = () ; $entry->{excluded} = 0 ; $entry->{filter} = $1 ; push (@{$opts->{excludes}}, $entry) ; } elsif ($line =~ m/^additional_configuration_file\s*=\s*"(.+)"$/) { my $file = $1 ; if ($recursive_included_configuration_file++ >= 10) { $no_usage_on_getoptions_error = 1 ; die "Not opening '$file' since too much configuration files were recursively included, loop detected ?\n" ; } my $saved_current_configuration_file = $current_configuration_file ; parse_custom_config_file $self, $opts, $file ; $current_configuration_file = $saved_current_configuration_file ; $recursive_included_configuration_file-- ; } elsif ($line =~ m/^additional_template_dir\s*=\s*"(.+)"$/) { push (@{$opts->{template_dirs}}, $1) ; } elsif ($line =~ m/^show_exif_tags\s*=\s*"(.*)"$/) { push (@{$opts->{show_exif_tags}}, split (/,/, $1)); } elsif ($line =~ m/^section_dir\s*=\s*"(.+)"$/) { push (@{$opts->{section_dirs}}, $1) ; } elsif ($line =~ m/^verbose\s*=\s*(\d+)$/) { $messages->{verbose} = $1 ; } else { process_option_error "Unrecognized configuration option line <$line>" ; } } else { process_option_error "Unknown configuration option <$optname>" ; } } else { process_option_error "Configuration must be given = (was $line)" ; } return $opts ; } sub parse_generic_config_file { my $self = shift ; my $messages = $self->{messages} ; my $opts = {} ; my $file = shift ; # TODO: remove this one day (maybe on march 14th 2006, since it will be 6 month ?) # warn on obsolete file my $oldconffile = $file ; $oldconffile =~ s@$self->{local_llgal_dir}/llgalrc$@.llgalrc@ ; $oldconffile =~ s@llgal/llgalrc$@llgalrc@ ; $messages->warning ("Obsolete configuration file $oldconffile skipped, should be moved to $file.") if -e $oldconffile ; # generic configuration files may not exist if (open CONF, $file) { $current_configuration_file = $file ; while () { process_option $self, $opts, $_ if (/^[^#]/ and !/^(\s*)$/) ; } $current_configuration_file = undef ; close CONF ; } return $opts ; } sub parse_custom_config_file { my $self = shift ; my $opts = shift ; my $file = shift ; my $messages = $self->{messages} ; # don't use a capitalized file handle since it would be shared across recursive calls if (open my $conf, $file) { $messages->notice ("Reading additional configuration file '$file'...\n"); $current_configuration_file = $file ; while (<$conf>) { process_option $self, $opts, $_ if (/^[^#]/ and !/^(\s*)$/) ; } $current_configuration_file = undef ; close $conf ; } else { # custom configuration files have to exist $no_usage_on_getoptions_error = 1 ; die "Failed to open additional configuration file '$file' ($!).\n" ; } } ###################################################################### # process command-line arguments (overriding defaults above) sub parse_cmdline_options { my $self = shift ; my $opts = {} ; if (!GetOptions( # behaviors 'clean' => \$self->{clean_asked}, 'cleanall' => \$self->{cleanall_asked}, 'gc' => \$self->{generate_captions}, 'gt:s' => sub { shift ; my $value = shift ; $value = "local" if !$value ; $self->{give_templates} = $value ; }, 'v|verbose' => \$self->{messages}->{verbose}, 'h|help' => \$self->{help_asked}, 'V|version' => \$self->{version_asked}, 'f' => \$opts->{force_image_regeneration}, 'gencfg=s' => \$self->{generate_config}, 'config=s' => sub { shift ; parse_custom_config_file $self, $opts, shift ; }, 'R' => \$opts->{recursive}, # layout 'A' => \$opts->{add_all_files}, 'a' => sub { $opts->{show_dimensions} = $opts->{show_size} = 1 ; }, 'ad' => \$opts->{show_dimensions}, 'as' => \$opts->{show_size}, 'asu=s' => \$opts->{show_size_unit}, 'cc:s' => sub { shift ; my $value = shift ; if ($value eq "") { $opts->{make_caption_from_image_comment} = "std,exif" ; } elsif ($value eq "0") { $opts->{make_caption_from_image_comment} = "" ; } else { $opts->{make_caption_from_image_comment} = $value ; } }, 'cf' => \$opts->{make_caption_from_filename}, 'ct:s' => sub { shift ; my $value = shift ; $opts->{make_caption_from_image_timestamp} = 1 ; if ($value ne "") { $opts->{timestamp_format_in_caption} = $value ; } }, 'ctf=s' => \$opts->{timestamp_format_in_caption}, 'codeset=s' => \$opts->{codeset}, 'exif:s' => sub { shift ; my $value = shift ; if ($value eq "") { $opts->{show_all_exif_tags} = 1 ; } else { push (@{$opts->{show_exif_tags}}, split (/,/, $value)) ; } }, 'fe' => \$opts->{show_film_effect}, 'i=s' => \$opts->{index_filename}, 'k' => \$opts->{make_slide_title_from_caption}, 'L' => \$opts->{list_links}, 'lang=s' => \$opts->{language}, 'li' => sub { $opts->{index_link_image} = 1 ; $opts->{prev_slide_link_image} = 1 ; $opts->{next_slide_link_image} = 1 ; }, 'lt' => sub { $opts->{prev_slide_link_preview} = 1 ; $opts->{next_slide_link_preview} = 1 ; }, 'n' => \$opts->{make_slide_filename_from_filename}, 'nc' => sub { $opts->{slide_counter_format} = "" ; }, 'nf' => sub { $opts->{slide_link_to_full_image} = 0 ; }, 'option=s' => sub { shift ; process_option $self, $opts, shift ; }, 'P=s' => \@{$opts->{section_dirs}}, 'Pall' => \$opts->{recursive_sections}, 'Ps' => sub { $opts->{entitle_sections} = 1 ; $opts->{separate_sections} = 1 ; }, 'p=i' => \$opts->{index_cellpadding}, 'php' => sub { $opts->{www_extension} = "php" ; }, 'Rl' => \$opts->{link_subgalleries}, 'S' => \$opts->{add_subdirs}, 's' => \$opts->{make_no_slides}, 'sort=s' => \$opts->{sort_criteria}, 'templates=s' => \@{$opts->{template_dirs}}, 'title=s' => \$opts->{index_title}, 'sx=i' => \$opts->{slide_width_max}, 'sy=i' => \$opts->{slide_height_max}, 'tx=i' => \$opts->{thumbnail_width_max}, 'ty=i' => \$opts->{thumbnail_height_max}, 'u' => \$opts->{show_caption_under_thumbnails}, 'uc=s' => \$opts->{css_location}, 'ui=s' => sub { shift ; my $url = shift ; $opts->{filmtile_location} = $url ; $opts->{index_link_image_location} = $url ; $opts->{prev_slide_link_image_location} = $url ; $opts->{next_slide_link_image_location} = $url ; }, 'w=i' => \$opts->{thumbnails_per_row}, 'www' => \$opts->{www_access_rights}, 'wx=i' => \$opts->{pixels_per_row}, 'exclude=s' => sub { shift ; my $entry = () ; $entry->{filter} = shift ; $entry->{excluded} = 1 ; push @{$opts->{excludes}}, $entry ; }, 'include=s' => sub { shift ; my $entry = () ; $entry->{filter} = shift ; $entry->{excluded} = 0 ; push @{$opts->{excludes}}, $entry ; }, 'parent-gal' => \$opts->{parent_gallery_link}, )) { # there has been an error during command line parsing if ($no_usage_on_getoptions_error) { # the error has already been displayed exit -1 ; } else { die_usage ($self) ; } } return $opts ; } ###################################################################### # check and defaults # check whether an argument is an integer sub is_integer { my $s = shift ; return $s eq int($s) ; } # various common checks and definitions sub prepare_common_variables { my $self = shift ; my $opts = shift ; # check a few string that have to be non-empty and may need to be single file without path die "Please give a non-empty directory name without path as a local llgal directory\n" if $self->{local_llgal_dir} eq "" or $self->{local_llgal_dir} =~ m@/@ ; } # various checks and definitions to process the captions sub prepare_captions_variables { my $self = shift ; my $opts = shift ; prepare_common_variables $self, $opts ; # check a few string that have to be non-empty and may need to be single file without path die "Please give a non-empty filename without path as a caption filename\n" if $opts->{captions_filename} eq "" or $opts->{captions_filename} =~ m@/@ ; die "Please give a non-empty caption removal line\n" if $opts->{captions_removal_line} eq "" ; } # various check and definitions to create the gallery sub prepare_gallery_variables { my $self = shift ; my $opts = shift ; my $messages = $self->{messages} ; prepare_captions_variables $self, $opts ; # check a few string that have to be non-empty and may need to be single file without path die "Please give a non-empty filename without path as a CSS filename\n" if $opts->{css_filename} eq "" or $opts->{css_filename} =~ m@/@ ; die "Please give a non-empty filename without path as a film tile filename\n" if $opts->{filmtile_filename} eq "" or $opts->{filmtile_filename} =~ m@/@ ; die "Please give a non-empty filename without path as a index link image filename\n" if $opts->{index_link_image_filename} eq "" or $opts->{index_link_image_filename} =~ m@/@ ; die "Please give a non-empty filename without path as a previous slide link image filename\n" if $opts->{prev_slide_link_image_filename} eq "" or $opts->{prev_slide_link_image_filename} =~ m@/@ ; die "Please give a non-empty filename without path as a next slide link image filename\n" if $opts->{next_slide_link_image_filename} eq "" or $opts->{next_slide_link_image_filename} =~ m@/@ ; die "Please give a non-empty filename without path as a index template filename\n" if $opts->{indextemplate_filename} eq "" or $opts->{indextemplate_filename} =~ m@/@ ; die "Please give a non-empty filename without path as a slide template filename\n" if $opts->{slidetemplate_filename} eq "" or $opts->{slidetemplate_filename} =~ m@/@ ; die "Please give a non-empty string without path as a slide filename prefix\n" if $opts->{scaled_image_filenameprefix} eq "" or $opts->{scaled_image_filenameprefix} =~ m@/@ ; die "Please give a non-empty string without path as a thumbnail filename prefix\n" if $opts->{thumbnail_image_filenameprefix} eq "" or $opts->{thumbnail_image_filenameprefix} =~ m@/@ ; die "Please give a non-empty filename without path as a index filename\n" if $opts->{index_filename} eq "" or $opts->{index_filename} =~ m@/@ ; die "Please give a non-empty string without path as a user-given scaled image prefix\n" if $opts->{user_scaled_image_filenameprefix} eq "" or $opts->{user_scaled_image_filenameprefix} =~ m@/@ ; die "Please give a non-empty string without path as a user-given thumbnail image prefix\n" if $opts->{user_thumbnail_image_filenameprefix} eq "" or $opts->{user_thumbnail_image_filenameprefix} =~ m@/@ ; # css location if ($opts->{css_location} =~ m@^(.*/)$@) { $opts->{css_location} .= $opts->{css_filename} ; } # images location if ($opts->{filmtile_location} =~ m@^(.*)/$@) { $opts->{filmtile_location} .= $opts->{filmtile_filename} ; } if ($opts->{index_link_image_location} =~ m@^(.*/)$@) { $opts->{index_link_image_location} .= $opts->{index_link_image_filename} ; } if ($opts->{prev_slide_link_image_location} =~ m@^(.*/)$@) { $opts->{prev_slide_link_image_location} .= $opts->{prev_slide_link_image_filename} ; } if ($opts->{next_slide_link_image_location} =~ m@^(.*/)$@) { $opts->{next_slide_link_image_location} .= $opts->{next_slide_link_image_filename} ; } # cannot have --sx/sy and -s die "Please choose between --sx/--sy and -s\n" if ($opts->{slide_height_max} or $opts->{slide_width_max}) and $opts->{make_no_slides} ; # thumbnail_width_max must be > 0 or 0 for unlimited die "Please give an integer value for thumbnail width max\n" unless is_integer ($opts->{thumbnail_width_max}) ; if ($opts->{thumbnail_width_max} < 0) { $messages->notice ("Thumbnail width max value < 0, restoring to default (". ($thumbnail_width_max_default?$thumbnail_width_max_default:"unlimited") .")\n") ; $opts->{thumbnail_width_max} = $thumbnail_width_max_default ; } die "Please give a positive thumbnail width max value (or 0 for unlimited)\n" unless $opts->{thumbnail_width_max} >= 0 ; # thumbnail_height_max must be > 0 die "Please give an integer value for thumbnail height max\n" unless is_integer ($opts->{thumbnail_height_max}) ; if ($opts->{thumbnail_height_max} < 0) { $messages->notice ("Thumbnail height max value < 0, restoring to default ($thumbnail_height_max_default)\n") ; $opts->{thumbnail_height_max} = $thumbnail_height_max_default ; } die "Please give a positive thumbnail height max value\n" unless $opts->{thumbnail_height_max} > 0 ; # thumbnails_per_row must be > 0 or 0 for unlimited die "Please give an integer value for thumbnails per row\n" unless is_integer ($opts->{thumbnails_per_row}) ; if ($opts->{thumbnails_per_row} < 0) { $messages->notice ("Thumbnails per row value < 0, restoring to default (". ($thumbnails_per_row_default?$thumbnails_per_row_default:"unlimited") .")\n") ; $opts->{thumbnails_per_row} = $thumbnails_per_row_default ; } die "Please give a positive thumbnails per row value (or 0 for unlimited)\n" unless $opts->{thumbnails_per_row} >= 0 ; # pixels_per_row must be > 0 or 0 for unlimited die "Please give an integer value for pixels per row\n" unless is_integer ($opts->{pixels_per_row}) ; if ($opts->{pixels_per_row} < 0) { $messages->notice ("Pixels per row value < 0, restoring to default (". ($pixels_per_row_default?$pixels_per_row_default:"unlimited") .")\n") ; $opts->{pixels_per_row} = $pixels_per_row_default ; } die "Please give a positive pixels per row value (or 0 for unlimited)\n" unless $opts->{pixels_per_row} >= 0 ; # index_cellpadding must be >= 0 die "Please give an integer value for index cellpadding\n" unless is_integer ($opts->{index_cellpadding}) ; if ($opts->{index_cellpadding} < 0) { $messages->notice ("Index cellpadding value < 0, restoring to default ($index_cellpadding_default)\n") ; $opts->{index_cellpadding} = $index_cellpadding_default ; } die "Please give a positive or null index cellpadding value\n" unless $opts->{index_cellpadding} >= 0 ; # text_slide_width must be > 0 die "Please give an integer value for text slide width\n" unless is_integer ($opts->{text_slide_width}) ; if ($opts->{text_slide_width} < 0) { $messages->notice ("Text slide width value < 0, restoring to default ($text_slide_width_default)\n") ; $opts->{text_slide_width} = $text_slide_width_default ; } die "Please give a positive text slide width value\n" unless $opts->{text_slide_width} > 0 ; # text_slide_height must be > 0 die "Please give an integer value for text slide height\n" unless is_integer ($opts->{text_slide_height}) ; if ($opts->{text_slide_height} < 0) { $messages->notice ("Text slide height value < 0, restoring to default ($text_slide_height_default)\n") ; $opts->{text_slide_height} = $text_slide_height_default ; } die "Please give a positive text slide height value\n" unless $opts->{text_slide_height} > 0 ; # slide_width_max must be > 0, 0 for unlimited die "Please give an integer value for slide width max\n" unless is_integer ($opts->{slide_width_max}) ; if ($opts->{slide_width_max} < 0) { $messages->notice ("Slide width max value < 0, restoring to default (". ($slide_width_max_default?$slide_width_max_default:"unlimited") .")\n") ; $opts->{slide_width_max} = $slide_width_max_default ; } die "Please give a positive slide width max value (or 0 for unlimited)\n" unless $opts->{slide_width_max} >= 0 ; # slide_height_max must be > 0, 0 for unlimited die "Please give an integer value for slide height max\n" unless is_integer ($opts->{slide_height_max}) ; if ($opts->{slide_height_max} < 0) { $messages->notice ("Slide height max value < 0, restoring to default (". ($slide_height_max_default?$slide_height_max_default:"unlimited") .")\n") ; $opts->{slide_height_max} = $slide_height_max_default ; } die "Please give a positive slide height max value (or 0 for unlimited)\n" unless $opts->{slide_height_max} >= 0 ; # either pixels or thumbnails per row must be limited die "Please limit pixels or thumbnails per row\n" unless $opts->{pixels_per_row} > 0 or $opts->{thumbnails_per_row} > 0 ; # adapt text slide width and height in case of --sx/sy if ($opts->{slide_height_max} > 0) { $opts->{text_slide_width} = $opts->{text_slide_width} / $opts->{text_slide_height} * $opts->{slide_height_max} ; $opts->{text_slide_height} = $opts->{slide_height_max} ; } if ($opts->{slide_width_max} > 0 and $opts->{text_slide_width} > $opts->{slide_width_max}) { $opts->{text_slide_height} = $opts->{text_slide_height} / $opts->{text_slide_width} * $opts->{slide_width_max} ; $opts->{text_slide_width} = $opts->{slide_width_max} ; } # thumbnail default size (for text and link slide especially) if ($opts->{thumbnail_width_max} > 0) { ($opts->{default_thumb_xdim}, $opts->{default_thumb_ydim}) = ($opts->{thumbnail_width_max}, $opts->{thumbnail_height_max}) ; } else { ($opts->{default_thumb_xdim}, $opts->{default_thumb_ydim}) = ($opts->{thumbnail_height_max} * 4/3, $opts->{thumbnail_height_max}) ; } # convert options for thumbnails my $thumb_MAXH = $opts->{thumbnail_height_max} ; my $thumb_MAXW = $opts->{thumbnail_width_max} > 0 ? $opts->{thumbnail_width_max} : "" ; $opts->{thumbnail_create_command} =~ s//$thumb_MAXH/g ; $opts->{thumbnail_create_command} =~ s//$thumb_MAXW/g ; # convert options for slides my $scaled_MAXH = $opts->{slide_height_max} > 0 ? $opts->{slide_height_max} : "" ; my $scaled_MAXW = $opts->{slide_width_max} > 0 ? $opts->{slide_width_max} : "" ; $opts->{scaled_create_command} =~ s//$scaled_MAXH/g ; $opts->{scaled_create_command} =~ s//$scaled_MAXW/g ; } ####################################################################### # If --gencfg was invoked, generate a configuration file sub generate_config { my $self = shift ; my $file = shift ; my $opts = shift ; my $messages = $self->{messages} ; $messages->print ("Generating config file '$file'.\n") ; if (-e "$file") { my $old_file = "$file.save.". (strftime('%Y-%m-%d_%H:%M:%S' ,localtime)) ; $messages->warning ("Renaming old configuration file '$file' as '$old_file'") ; rename "$file", "$old_file" ; } open NEWCFG, ">$file" or die "Cannot open $file ($!).\n" ; print NEWCFG "# This is a llgal configuration file.\n" ; print NEWCFG "# It was automatically generated on ". (scalar localtime) .".\n" ; print NEWCFG "# You may modify and reuse it as you want.\n" ; print NEWCFG "\n" ; for my $optname (sort (keys %{$normal_opts_type}, keys %{$special_opts_with_output}, keys %{$special_nonopts_with_output})) { if (defined $special_nonopts_with_output->{$optname}) { if ($optname eq "local_llgal_dir") { print NEWCFG "local_llgal_dir = \"$self->{local_llgal_dir}\"\n" ; } elsif ($optname eq "verbose") { print NEWCFG "verbose = $messages->{verbose}\n" ; } else { die "Unknown non-options $optname to output.\n" ; } } elsif (defined $special_opts_with_output->{$optname}) { next if not defined $opts->{$optname} ; # special options that need special output if ($optname eq "show_exif_tags") { print NEWCFG "show_exif_tags = \"". (join (",", @{$opts->{show_exif_tags}})) ."\"\n" ; } elsif ($optname eq "template_dirs") { if (@{$opts->{template_dirs}}) { map { print NEWCFG "additional_template_dir = \"$_\"\n" ; } @{$opts->{template_dirs}} ; } } elsif ($optname eq "excludes") { if (@{$opts->{excludes}}) { map { print NEWCFG ($_->{excluded} ? "exclude" : "include"). " = \"". $_->{filter} ."\"\n" ; } @{$opts->{excludes}} ; } } elsif ($optname eq "section_dirs") { if (@{$opts->{section_dirs}}) { map { print NEWCFG "section_dir = \"$_\"\n" ; } @{$opts->{section_dirs}} ; } } else { die "Unknown special internal option $optname to output.\n" ; } } else { next if not defined $opts->{$optname} ; # normal options my $type = $normal_opts_type->{$optname} ; if (defined $type) { if ($type == $OPT_IS_NUMERIC) { print NEWCFG "$optname = $opts->{$optname}\n" ; } elsif ($type == $OPT_IS_STRING or $type == $OPT_IS_NONEMPTY_STRING) { print NEWCFG "$optname = \"$opts->{$optname}\"\n" ; } else { die "Unknown normal option type $type.\n" ; } } else { die "Unknown ge option $optname to output.\n" ; } } } print NEWCFG "\n" ; close NEWCFG ; } 1 ; llgal-llgal-0.13.19/lib/Llgal/Messages.pm000066400000000000000000000041351314312235400177600ustar00rootroot00000000000000package Llgal::Messages ; use strict ; # messaging context sub new { my $self = {} ; bless $self ; $self->{indent} = "" ; $self->{percentage_total} = 0 ; $self->{delayed_warning} = 0 ; $self->{pending_warnings} = "" ; $self->{verbose} = 0 ; return $self ; } sub copy { my $self = shift ; my $new_self = { indent => $self->{indent}, percentage_total => $self->{percentage_total}, percentage_in_progress => $self->{percentage_in_progress}, delayed_warning => $self->{delayed_warning}, pending_warnings => $self->{pending_warnings}, verbose => $self->{verbose}, } ; bless $new_self ; return $new_self ; } # indented printing sub print { my $self = shift ; print $self->{indent} ; print @_ ; } sub indent { my $self = shift ; $self->{indent} .= " " ; } # notice (verbose mode only) sub notice { my $self = shift ; print @_ if $self->{verbose} ; } # Warnings are shown after each step of processing to avoid # breaking precentage progressions and so my $warning_prefix = "!! " ; sub warning { my $self = shift ; while (@_) { my $line = shift ; chomp $line ; if ($self->{delayed_warning}) { $self->{pending_warnings} .= $warning_prefix.$line."\n" ; } else { print $warning_prefix.$line."\n" ; } } } sub delay_warnings { my $self = shift ; $self->{delayed_warning} = 1 ; } sub show_delayed_warnings { my $self = shift ; print $self->{pending_warnings} ; $self->{pending_warnings} = "" ; $self->{delayed_warning} = 0 ; } # percentage printing sub init_percentage { my $self = shift ; $self->{delayed_warning} = 1 ; $self->{percentage_total} = shift ; print " 0.00%" ; } sub update_percentage { my $self = shift ; my $i = shift ; my $val = $i*100/$self->{percentage_total} ; printf "\b\b\b\b\b\b\b\b% 7.2f%%", $val ; } sub end_percentage { my $self = shift ; printf "\b\b\b\b\b\b\b\b% 7.2f%%\n", 100 ; $self->show_delayed_warnings () ; } sub abort_percentage { my $self = shift ; print "\n" ; $self->show_delayed_warnings () ; } 1 ; llgal-llgal-0.13.19/lib/Llgal/Templates.pm000066400000000000000000000110661314312235400201500ustar00rootroot00000000000000package Llgal::Templates ; use strict ; use File::Copy ; use Llgal::Utils ; # copy a file sub copy_file { my $self = shift ; my $messages = $self->{messages} ; my $filename = shift ; my $srcdir = shift ; my $destdir = shift ; unlink "$destdir/$filename" ; copy "$srcdir/$filename", "$destdir/$filename" or die "Failed to get a copy of '$filename' ($!).\n" ; } # find path to the template file in generic directories sub find_generic_template_file { my $self = shift ; my $opts = shift ; my $filename = shift ; my $check = shift ; foreach my $dir (@{$opts->{template_dirs}}) { return $dir if -e "$dir/$filename" ; } return $self->{user_share_dir} if -e "$self->{user_share_dir}/$filename" ; die "File '$self->{llgal_share_dir}/$filename' does not exist.\nPlease install llgal properly.\n" unless -e "$self->{llgal_share_dir}/$filename" or !$check ; return $self->{llgal_share_dir} ; } # find path to the template, using the local one if it exists sub find_template_file { my $self = shift ; my $opts = shift ; my $filename = shift ; my $check = shift ; return "$self->{destination_dir}$self->{local_llgal_dir}" if -e "$self->{destination_dir}$self->{local_llgal_dir}/$filename" ; return find_generic_template_file $self, $opts, $filename, $check ; } # get a template file from generic directories and save it to local directory sub get_template_file { my $self = shift ; my $opts = shift ; my $filename = shift ; my $messages = $self->{messages} ; if (-e "$self->{destination_dir}$self->{local_llgal_dir}/$filename") { $messages->print ("Found $filename in $self->{destination_dir}$self->{local_llgal_dir}/, using it.\n") ; } else { my $srcdir = find_generic_template_file $self, $opts, $filename, 1 ; $messages->print ("No $filename in $self->{destination_dir}$self->{local_llgal_dir}/, getting a copy from $srcdir\n") ; copy_file $self, $filename, $srcdir, "$self->{destination_dir}$self->{local_llgal_dir}" ; } } # Give templates to the given directory sub give_templates { my $self = shift ; my $opts = shift ; my $destdir = shift ; my $messages = $self->{messages} ; if ( ! -e $destdir ) { $messages->print ("Creating template directory $destdir...\n") ; mkdir $destdir or die "Failed to create $destdir ($!)" ; } foreach my $filename ( $opts->{css_filename}, $opts->{filmtile_filename}, $opts->{index_link_image_filename}, $opts->{prev_slide_link_image_filename}, $opts->{next_slide_link_image_filename}, $opts->{indextemplate_filename}, $opts->{slidetemplate_filename} ) { if ( -e "$destdir/$filename" ) { $messages->print ("$filename already exists in $destdir.\n") ; } else { my $srcdir = find_generic_template_file $self, $opts, $filename, 1 ; $messages->print ("$filename does not exist in $destdir, getting a copy from $srcdir...\n") ; copy_file $self, $filename, $srcdir, $destdir ; } } } # Get llgal files sub get_llgal_files { my $self = shift ; my $opts = shift ; my $messages = $self->{messages} ; # Get the film tile for the index if ($opts->{show_film_effect}) { if ($opts->{filmtile_location}) { $messages->print ("Using the film tile that is available on $opts->{filmtile_location}.\n") ; } else { get_template_file $self, $opts, $opts->{filmtile_filename} ; } } # Get link images if ($opts->{index_link_image}) { if ($opts->{index_link_image_location}) { $messages->print ("Using the index link image that is available on $opts->{index_link_image_location}.\n") ; } else { get_template_file $self, $opts, $opts->{index_link_image_filename} ; } } if ($opts->{prev_slide_link_image} and ! $opts->{prev_slide_link_preview}) { if ($opts->{prev_slide_link_image_location}) { $messages->print ("Using the prev slide link image that is available on $opts->{prev_slide_link_image_location}.\n") ; } else { get_template_file $self, $opts, $opts->{prev_slide_link_image_filename} ; } } if ($opts->{next_slide_link_image} and ! $opts->{next_slide_link_preview}) { if ($opts->{next_slide_link_image_location}) { $messages->print ("Using the next slide link image that is available on $opts->{next_slide_link_image_location}.\n") ; } else { get_template_file $self, $opts, $opts->{next_slide_link_image_filename} ; } } # Get the css if ($opts->{css_location}) { $messages->print ("Using the CSS that is available on $opts->{css_location}.\n") ; } else { get_template_file $self, $opts, $opts->{css_filename} ; } } 1 ; llgal-llgal-0.13.19/lib/Llgal/Utils.pm000066400000000000000000000015111314312235400173040ustar00rootroot00000000000000package Llgal::Utils ; use strict ; # system routine which: # - takes a description followed by cmdline arguments # - returns a table composed of the status followed by STDERR and STDOUT lines sub system_with_output { my $descr = shift ; pipe (my $pipe_out, my $pipe_in) ; my $pid = fork() ; if ($pid < 0) { close $pipe_in ; close $pipe_out ; return ( -1, "Fork failed while trying to $descr\n" ) ; } elsif ($pid > 0) { close $pipe_in ; waitpid ($pid, 0) ; my $status = $? >> 8 ; $status = -1 if $status == 255 ; my @lines = <$pipe_out> ; close $pipe_out ; return ( $status , @lines ) ; } else { close $pipe_out ; open STDERR, ">&", $pipe_in ; open STDOUT, ">&", $pipe_in ; { exec @_ } ; print $pipe_in "Exec of $_[0] failed while trying to $descr\n" ; close $pipe_in ; exit -1 ; } } 1; llgal-llgal-0.13.19/lib/MANIFEST000066400000000000000000000001311314312235400157410ustar00rootroot00000000000000MANIFEST Makefile.PL Llgal/Config.pm Llgal/Messages.pm Llgal/Templates.pm Llgal/Utils.pm llgal-llgal-0.13.19/lib/Makefile.PL.in000066400000000000000000000001301314312235400171660ustar00rootroot00000000000000use ExtUtils::MakeMaker; WriteMakefile ( NAME => 'Llgal', VERSION => "@VERSION@", ); llgal-llgal-0.13.19/llgal.1000066400000000000000000000726661314312235400152450ustar00rootroot00000000000000.\" Process this file with .\" groff -man -Tascii foo.1 .\" .TH LLGAL 1 "NOVEMBER 2006" .SH NAME llgal \- On-line gallery generator .SH SYNOPSIS .B llgal .I [-option1 -option2 ...] .SH DESCRIPTION .B llgal is a quick and easy program for placing your images and movies online with just one command-line. It generates a pretty good-looking set of static HTML slides even with its default settings. To try it out just run .B llgal in a directory with .BR "jpg" ", " "png" ", " "mpg" ", etc" files and check the output in a web browser. You can adjust the appearance of the image gallery with the many options listed below or (if you know a bit of HTML) by modifying the .I llgal.css files in the .I .llgal/ subdirectory that appeared in your image directory, or by defining .IR "indextemplate.html" " or " "slidetemplate.html" " files." llgal also checks for the existence of a .I $HOME/.llgal/ directory where users can store their own templates, overriding the site-wide .IR "/usr/share/llgal" "." (See .B FILES for details). The HTML webpages are generated from the templates by replacing several fields (See .BR TEMPLATES ). The layout might be configured through the list of options that are given in .BR "LAYOUT" "." llgal uses all images and videos it finds in the current directory. See .B SELECTING FILES to include directories or other files and excludes some filenames. The index includes thumbnails that llgal generates from original images. It is possible to provide custom thumbnails by placing them in the .I .llgal/ directory with the .I mythumb_ prefix. Custom thumbnails for movies have to be suffixed with an image-type extension. For instance, to enforce the thumbnail for image .IR image.jpg " and movie " movie.avi , thumbnails may be named .IR mythumb_image.jpg " and " mythumb_movie.avi.jpg . The slide pages may include a scaled image in the .B --sx or .B --sy option is passed. Similarly, it is also possible to define custom scaled images with the .I myscaled_ prefix to appear in the slides. Note that all command line options (except those from .BR "BEHAVIOR OPTIONS" ), and even more, might be stored in a configuration file to help generation of multiple galleries with the same layout. See .B CONFIGURATION for details. .SH BEHAVIOR OPTIONS By default, llgal generates a gallery. If one of the following option is passed, it will process it and exit immediately. .TP .B --clean Remove all files that llgal may have created earlier and that user did not modify since. .TP .B --cleanall Remove all files that llgal may have created earlier. This includes thumbnails, scaled down slides, all HTML files, captions file, film effect picture, indextemplate and slidetemplate and the style-sheet file. .TP .B --gc Generate slide captions in .I .llgal/captions file that you may edit. The format of this file is very simple. .RB "See " CAPTIONS " for details." These captions may then be modified by the user. The file will be automatically used next time .B llgal is invoked. .B --gc might also be used to update the .I captions file when new files were added to the working directory. .TP .BI --gt " []" Copy template files to the directory. The special value .I local might be used for the local .I .llgal/ directory, while .I user might be used for the user template directory .IR $HOME/.llgal/ . Any other directory is acceptable. llgal will create the target directory if it does not exist. The argument is optional. Its default value is .BR local . See .B FILES for details about template files. .TP .B -h, --help Display brief help. .TP .B -V, --version Display llgal version. .SH ADDITIONAL BEHAVIOR OPTIONS llgal behavior may be modified with the following options, either when generating a gallery or not. .TP .BI --config " " Read the file .I file as a configuration. See .B CONFIGURATION for details. Note that .B --config may be used several times on the same command line. The corresponding configuration file option is .IR additional_configuration_file . .TP .BI -d " " Operate in directory .I when generating the HTML files, thumbnails and scaled images. The default is the current directory. .TP .B -f Force thumbnail regeneration. Also forces medium-slide regeneration if .BR --sx " or " --sy is given. Otherwise llgal will not regenerate these files if they already exist, and you may end up with stale copies. Definitely use .B -f between two runs where you've changed the value of .BR --tx ", " --ty ", " --sx " or " --sy "." The corresponding configuration file option is .IR force_image_regeneration . .TP .BI --gencfg " " Output configuration in .I file for future reutilization through .BR --config "." If .B local is passed as .IR file ", then the local" .B .llgal/llgalrc file is created in each gallery that is processed (in case of recursion). See .B CONFIGURATION for details. .TP .BI --option " 'variable = value'" Configure using a configuration file option. See .B CONFIGURATION for details. Note that .B --option may be used several times on the same command line. .TP .B -R Enable recursive mode. llgal will be run inside subdirectories. This option might be used either to generate galleries in all subdirectories, or their captions files, or to clean recursively, etc. The corresponding configuration file option is .IR recursive . When generating a gallery, this option implies .B -S that means llgal will use all existing subdirectories in no captions file is defined. If a captions file is defined, only the .B DIR: entries will be entered recursively. See .B CAPTIONS for details abour Note that recursive behavior does only use the contents of the captions file to choose which subgalleries to enter when generating the gallery or the captions file. All other behaviors, including recursive cleaning ( .B -R used together with .B --clean or .BR --cleanall ), will .B not check whether a subdirectory is in the captions file. All not-dot-beginning subdirectories will be cleaned. .TP .B -v, --verbose Display notice messages. The corresponding configuration file option is .IR verbose . .SH SELECTING FILES .TP .B -A All files in the current directory will get a slides, except .html or dot-beginning files. Files are matched as images or movies first, and then reverted as simple files instead. The corresponding configuration file option is .IR add_all_files . See .B -S for details about adding slides for subdirectories. .TP .BI --exclude " " Exclude files whose name matches .IR . The corresponding configuration file option is .IR exclude . .TP .BI --include " " Include files whose name matches .I and where previously excluded. The corresponding configuration file option is .IR include . .TP .BI -P " " Use photos in the subdirectory instead of the working directory. May be used multiple times to group multiple subdirectories in the same gallery. The path of the subdirectory must be given as a relative path (relative to .BR . " or to the path given to " -d ")." The corresponding configuration file option is .IR section_dir . .TP .B --Pall Use photos in all subdirectories all the working directory as if .B -P was used for all of them. The corresponding configuration file option is .IR recursive_sections . .TP .BI --Ps Add a horizontal line and the subdirectory name as a title at the beginning of each section. The corresponding configuration file options are .IR entitle_sections " and " separate_sections . .TP .B -S Each subdirectory will get a dedicated slide. If a captions file exists, only the subdirectories that it defines will be processed. If no captions file exists, llgal will process all subdirectories but those whose name begins with a dot. The corresponding configuration file option is .IR add_subdirs . Contrary to .B -R this option will not make llgal run recursively in subdirectories. .B -S does only define the list of subdirectories that appear in the current gallery. .SH LAYOUT OPTIONS .TP .B -a Write image dimensions and sizes under each thumbnail on the index page, and under each slide if .BR --sx " or " --sy was passed. The corresponding configuration file options are .IR show_dimensions " and " show_size . This only works if the ImageMagick command .B identify is present. .TP .B --ad Like .B -a but write only the image dimensions. The corresponding configuration file option is .IR show_dimensions . .TP .B --as Like .B -a but write only the image sizes. The corresponding configuration file option is .IR show_size . .TP .BI --asu " " Define the unit used to show file sizes. Default is \fB"kB"\fR. The corresponding configuration file option is .IR show_size_unit . .TP .BI --cc " []" Generates .I captions from image comment tag. If no argument is given, llgal first tries the standard comment (for instance JFIF or GIF), then tries Exif comments if the previous one is empty, and then tries Exif image description. The corresponding configuration file option is .IR make_caption_from_image_comment . An argument such as .I std or .I exif or .I exifdesc might be added to force the use of only standard comment, only Exif comment, or only Exif image description. An argument such as .I exif,std will make llgal try Exif comment first. An argument such as .I std+exifdesc will use the combination of standard comment and Exif description. Passing .B --cc without argument is thus equivalent to passing .B --cc .IR std,exif,exifdesc . .TP .B --cf Generates .I captions from file names (strips extension, except for directories). The corresponding configuration file option is .IR make_caption_from_filename . .TP .B --ct " [strftime_format]" Add image timestamp tag to the generated captions, and change its format if the optional argument is given (replaces the old \-\-ctf option). The corresponding configuration file option are .IR make_caption_from_image_timestamp " and " timestamp_format_in_caption . .TP .BI --codeset " codeset" Change the encoding in the header of the generated HTML pages. By default, the encoding is got from the locale configuration. The corresponding configuration file option is .IR codeset . .TP .BI --exif " []" Display a table of EXIF tags under each image slide. The corresponding configuration file options are .IR show_exif_tags " and " show_all_exif_tags . If an argument is given, it contains a comma-separated list of tags. The tag names have to be passed as shown by .BR "exiftool -list" . If no argument is given, all available Exif tags are displayed. The tags are displayed using their description as given by .BR "exiftool -s myimage" . .TP .B --fe Show a film effect in the index of thumbnails. The aspect of this effect may be configured by replacing the tile file that llgal puts in .IR .llgal . The corresponding configuration file option is .IR show_film_effect . .TP .BI -i " " Name of the main thumbnail index file. The default is .BR index , as desirable for most web servers. The corresponding configuration file option is .IR index_filename . The default extension is .B html and might be changed with .B --php or the .I www_extension configuration option. .TP .B -k Use the image captions for the HTML slide titles. The default behavior is to use the image names. The corresponding configuration file option is .IR make_slide_title_from_caption . .TP .B -L Do not create thumbnails for text and links (including video, file and url), but list them as a text line between thumbnail rows in the main gallery index. Might be used when the directory only contains subgalleries and thus does not need any thumbnail. The corresponding configuration file option is .IR list_links . .TP .BI --lang " locale" Change the locale used to translate the text that is automatically generated in the HTML pages. The corresponding configuration file option is .IR language . Note that the .B LANGUAGE environment variable might prevent this option from working if set. .TP .B --li Replace link labels in slides (usually .BR Index ", " Prev " and " Next ) with images (usually .IR index.png ", " prev.png " and " next.png ). The corresponding configuration file options are .IR index_link_image ", " prev_slide_link_image " and " next_slide_link_image . .TP .B --lt Replace link labels in slides (usually .BR Prev " and " Next ) with a thumbnail to preview previous/next slide. The corresponding configuration file options are .IR prev_slide_link_preview " and " next_slide_link_preview . If passed together with .BR --li , thumbnail preview is used for links to previous/next slide while the image is for the link to the index is kept. .TP .B -n Use the image file names for the HTML slide files. Otherwise the default behavior is to simply name your slides .IR slide_1.html ", " slide_2.html ", " and so on. The corresponding configuration file option is .IR make_slide_filename_from_filename . .TP .B --nc Omit the image count from the captions. The corresponding configuration file option is .IR slide_counter_format . .TP .B --nf Omit the link from scaled images in slides to full unscaled images. The corresponding configuration file option is .IR slide_link_to_full_image . .TP .BI -p " " The cellpadding value of the thumbnail index tables. The default is .BR 3 . The corresponding configuration file option is .IR index_cellpadding . .TP .B --php Change the default extension of generated webpages from .I html to .IR php . The corresponding configuration file option is .IR www_extension . Note that template names are not modified and keep their .I html extension even if they contain some PHP code. Note that llgal will only remove existing webpages corresponding to this extension when generating a new gallery or cleaning. .TP .B --parent-gal Add links to the parent directory. The corresponding configuration file option is .IR parent_gallery_link . This option is used internally for recursive galleries, and thus not documented in .BR --help . These links are stored as a header and a footer for the index. The text in the links might be changed through the .B parent_gallery_link_text configuration option. .TP .B --Rl Add links between subgalleries. The corresponding configuration file option is .IR link_subgalleries . .TP .B -s For the simplest setup, omit all HTML slides. Clicking the thumbnails on the main page will just take users to the plain image files. The corresponding configuration file option is .IR make_no_slides . .TP .BI --sort " [rev]" Change sort criteria when scanning files in the working directory. Default is \fB"name"\fR. Setting to the empty string means .BR none . .BR iname " is case insensitive sort by names." .BR date " means " time . .BR rev " might be added for reverse sort." The corresponding configuration file option is .IR sort_criteria . .TP .BI --sx " " Instead of using the original image in the slides, insert a scaled image whose width is less than .BR " pixels." The corresponding configuration file option is .IR slide_width_max . Useful if your digital camera spits out large images, like 1600x1200. Clicking on the scaled copies in the HTML slides lets users see the full unscaled images. The default is .B 0 (width is unlimited). You must use .B -f to force regeneration of scaled images if you want to change the value of .BR --sx . .TP .BI --sy " " Instead of using the original image in the slides, insert a scaled image whose height is less than .BR " pixels." The corresponding configuration file option is .IR slide_height_max . Useful if your digital camera spits out large images, like 1600x1200. Clicking on the scaled copies in the HTML slides lets users see the full unscaled images. The default is .B 0 (height is unlimited). You must use .B -f to force regeneration of scaled images if you want to change the value of .BR --sy . .TP .BI --templates " " Add a directory to the list of template locations. The corresponding configuration file option is .IR additional_template_dir . .TP .BI --title " " Substitutes the string .I for .B in the index. The default is .BR "Index of Pictures" . It overrides the configuration file option .IR index_title_default . .TP .BI --tx " " Scale thumbnails so that their width is at most .IR " pixels." The default is .BR 113 . The corresponding configuration file option is .IR thumbnail_width_max . If .B 0 is used, the width is unlimited. Changing this value does not affect the maximal height (see .BR --ty ). You must use .B -f to force regeneration of thumbnails if you want to change the value of .BR --tx . .TP .BI --ty " " Scale thumbnails so that their height is at most .IR " pixels." The default is .BR 75 . The corresponding configuration file option is .IR thumbnail_height_max . Changing this value does not affect the maximal width (see .BR --tx ). You must use .B -f to force regeneration of thumbnails if you want to change the value of .BR --ty . .TP .B -u Write image captions under each thumbnail on the index page. If you have a .I captions file, then the captions are read from there. The corresponding configuration file option is .IR show_caption_under_thumbnails . .TP .BI --uc " " Assume the CSS file is available on .I and thus do not use a local one. If ending with a slash, the CSS filename will be appended. The corresponding configuration file option is .IR css_location . .TP .BI --ui " " Assume that the filmtile image and index/prev/next slide link images are available on .I and thus do not use local ones. Their filename will be appended to the given location. Each image location may be also changed independently (See .B CONFIGURATION for the list of configuration options). The corresponding configuration file options are .IR filmtile_location ", " index_link_image_location ", " .IR prev_slide_link_image_location " and " next_slide_link_image_location . .TP .BI -w " " Set the thumbnail rows to be .I images wide in the main index file. Default is .BR 5 . The corresponding configuration file option is .IR thumbnails_per_row . .TP .BI --wx " " Set the thumbnail rows to be .I pixels wide at maximum. The number of thumbnails per row, given in .B -w is reduced if necessary. The corresponding configuration file option is .IR pixels_per_row . Default is to honor .B -w without regard to the resulting row width. .TP .B --www Make all generated files world-readable. The corresponding configuration file option is .IR www_access_rights . .SH CAPTIONS When called with .B --gc llgal generates (or updates if already existing) the .I captions file in the .I .llgal/ subdirectory. When .B --gc is not passed, if the .I captions file exists, llgal will automatically use it to generate slide captions in the gallery. If .I captions does not exist, llgal generates captions on the fly and use them in the gallery. Generating the .I captions file with .B --gc before actually using it makes it possible to modify them (especially to add comments) or change the order of the slides in the gallery .B IMG: ---- .RS defines an image (when omitted, .B IMG: is the default type). .RE .B MVI: ---- ---- .RS defines a movie. .RE .B TXT: ---- .RS defines a text slide. .RE .B LNK: ---- ---- .RS defines a link slide. .RE .B LNKNOSLIDE: ---- .RS defines a direct link to the target, without any slide. .RE .B FIL: ---- ---- .RS defines a link to another file (typically neither an image nor a movie) .RE .B DIR: ---- ---- .RS defines a subdirectory slide. .RE .B BREAK .RS forces a line break in the row of thumbnails .RE .B LINE .RS forces a line break in the row of thumbnails and inserts a horizontal line. .RE .B TITLE: .RS defines the title of the gallery. .RE .B INDEXHEAD: <one header> .RS defines a header (multiple ones are possible). .RE .B INDEXFOOT: <one footer> .RS defines a footer (multiple ones are possible). .RE .B PARENT: <linktext> .RS defines the label of the link to the parent gallery. .RE .B PREV: <linktext> ---- <url> .RS defines the label of the link to the previous gallery located by .IR <url> . .RE .B NEXT: <linktext> ---- <url> .RS defines the label of the link to the next gallery located by .IR <url> . .RE .B REPLACE: <text> ---- <replacement> .RS adds a substitution to be applied to generated HTML pages. .RE .TP Note that you can use whatever HTML syntax in the captions. .RE Line beginning with a .RI # are ignored. When generating a captions file, the .I captions.header file is inserted at the top of the file to detail the syntax. .SH CONFIGURATION Before parsing command line options, llgal reads several configuration files. It starts with .I /etc/llgal/llgalrc then reads .I $HOME/.llgal/llgalrc and finally the .I .llgal/llgalrc file in the gallery directory. Additional configuration files may also be defined with the .B --config option. These will be parsed during command-line parsing, when .B --config is met. In case of recursive generation (with .B -R ) in multiple subdirectories, the system- and user-wide configuration files and those passed to .B --config are taken in account for all galleries. However, only the local .I .llgal/llgalrc file is used for each gallery. Especially, the one in the root gallery directory is only taken in account when generating the root gallery, not when generating those in subdirectories. To use a same specific configuration file for the root gallery and all subgalleries, the .B --config option may be used. All these files may change llgal configuration in the same way command line options do, and even more. All following options may also be used on the command line through .B --option .IR "'variable = value'" . See also the manpage of .I llgalrc or .I /etc/llgal/llgalrc for details about these options and their default values. .SH THUMBNAILS AND SCALED IMAGES GENERATION By default, llgal uses convert to create thumbnails and scaled images (the ones that appear in the slides when .IR --sx " or " --sy was passed). The command lines used to generate those images from your original images are defined by the following configuration options: .RS .I scaled_create_command = "convert --scale <MAXW>x<MAXH> -- <IN> <OUT>" .RE .RS .I thumbnail_create_command = "convert --scale <MAXW>x<MAXH> -- <IN> <OUT>" .RE You may change the value of these options to change the way the generation is done. .BR <IN> " and " <OUT> will be replaced by .B llgal at runtime with the filename of the original and generated target images. .BR <MAXW> " and " <MAXH> will be replaced by the maximal width and length of the generated images. Note that one of them might not be limited (depending on other configuration variable), making it be replaced by an empty string, eventually leading to empty parameters being passed to your program. If your program does not like that, you might want to create a wrapper shell script which will take care of accepting these. Another solution would be to replace .I unlimited with .I limited by a huge value in your configuration and adapt your program to deal with it. .SH TEMPLATES When generation web pages, the following fields will be replaced from the templates by the associated value (computed by llgal). .B <!--TITLE--> .RS The title of the index. .RE .B <!--CSS--> .RS The CSS style-sheet. .RE .B <!--CREDITS--> .RS The credits line given by .I credits_text configuration option. .RE .B <!--VERSION--> .RS The version of the program used to generate the gallery. .RE .B <!--INDEX-FILE--> .RS The filename of the index to used in <a href=""> attributes. May also contain additional attributes to be appended after href. .RE .B <!--INDEX-LINK-TEXT--> .RS The label of the link to the index (might be an image). .RE .B LLGAL-CODESET .RS The character encoding, usually set to iso-8859-1 or utf-8. .RE .B LLGAL-OPTIONS .RS The options that were passed to llgal on the command line to generate the gallery. .RE When generating the index from template .IR indextemplate.html , the following additional fields will also be replaced. .B <!--HEADERS--> .RS The list of headers that are given in the captions file. .RE .B <!--FOOTERS--> .RS The list of footers that are given in the captions file. .RE When generating slides from template .IR slidetemplate.html , the following additional fields will also be replaced. .B <!--SLIDE-TITLE--> .RS The title of the slide. .RE .B <!--THIS-SLIDE-STYLE--> .RS The style of the slide contents (is defined in the CSS style-sheet). .RE .B <!--SLIDE-NUMBER--> .RS The index of the slide, with leading zeros. .RE .B <!--SLIDE-TOTAL--> .RS The amount of slides. .RE .B <!--SLIDE-COUNTER--> .RS The slide counter according to slide_counter_format as in the caption. .RE .B <!--IMAGE-CAPTION--> .RS The caption of the slide. .RE .B <!--EXIF-TABLE--> .RS The table of EXIF tags. .RE .B <!--EXIF-%tag%--> .RS The value of the image EXIF tag %tag%. The tag name %tag% must match the name reported by .BR "exiftool -s myimage" . Note that a single replacement may be performed per template line. .RE .B <!--THIS-SLIDE--> .RS The actual contents of the slide (might be an image). .RE .BR <!--PREV-SLIDE--> " and " <!--NEXT-SLIDE--> .RS The filename of the previous and next slides. .RE .BR <!--NEXT-SLIDE-LINK-TEXT--> " and " <!--PREV-SLIDE-LINK-TEXT--> .RS The label of the link to previous and next slides (might be an image). .RE Additionally, it is possible to define use custom fields in the templates and define their replacement with some .B REPLACE entries in the captions file. See .B CAPTIONS for details. When modifying the templates, beware that the HTML syntax requires double-quotes around filenames, URL, etc. These double-quotes will never be automatically added when replacing these automatic variables. So you must keep double-quotes around variables when needed, for instance: .RS .B <a href="<!--NEXT-SLIDE-->"><!--NEXT-SLIDE-LINK-TEXT--></a> .RE will be changed into .RS .B <a href="slide_04.html">Next slide</a> .RE .SH LANGUAGE The language that llgal uses to generate text in HTML pages is chosen from the localization configuration. If the chosen language is available in llgal translations, it will be used instead of the default english. As usual with .BR gettext , it is possible to override the localisation configuration by changing .BR LANG ", " LC_MESSAGES " or " LANGUAGE environment variables. If the desired language is not available in llgal translations, or if the user wishes to change the text values, he might create an additional configuration file (or modify the system-wide one) to update all configuration options of the .B Text section. The locale configuration might be overridden with the .B --lang option or .B language configuration option. But, the .B LANGUAGE environment variable appears to prevent this from working if set. .SH CHARACTER ENCODING If a filename contains non-ascii characters which are not safely representable in a URL, llgal will escape them using the method RFC 2396 specifies. This may raise problems if the web server has a different notion of character encoding than the machine llgal runs on. See also .I http://www.w3.org/TR/html4/appendix/notes.html#h-B.2 Character encoding is chosen from the locale configuration and set in the HTML headers. It may be overridden by using .B --codeset or the .B codeset configuration option. .SH NOTES Note that all numerical options may be reset to their default value by setting them a negative value. .SH FILES .RE .IR /etc/llgal/llgalrc ", " $HOME/.llgal/llgalrc ", " .llgal/llgalrc .RS System-wide, per-user and local configuration files. See .B CONFIGURATION for details. .RE .I /usr/share/llgal/captions.header .RS Captions syntax description file that is inserted at the top of generated captions file. .RE .I /usr/share/llgal/llgal.css .RS The default style-sheet template. .RE .I /usr/share/llgal/tile.png .RS The tiled image used for the film effect. .RE .I /usr/share/llgal/index.png .RS The link image used for the index. .RE .I /usr/share/llgal/prev.png .RS The link image used for the previous slide. .RE .I /usr/share/llgal/next.png .RS The link image used for the next slide. .RE All files are required on the website. llgal will copy them to the local .I .llgal/ file during gallery generation. .RE .I /usr/share/llgal/indextemplate.html .RS The default index template file. .RE .I /usr/share/llgal/slidetemplate.html .RS The default file used to generate slides. .RE These files are not required on the website. But, llgal will use them to generate HTML webpages of the gallery by replacing several fields with text or images. See .B TEMPLATES for details. The user may change all these templates by storing files with the same name in its user template directory .I $HOME/.llgal/ or in the local .I .llgal/ directory. The former defines user-specific templates that will be used each time the user generate a gallery. The later defines gallery-specific templates that will be used for the local gallery. A local template is used by default if it exists. A user template is used if it exists and no local template exists. Finally, system-wide templates are used if no local and user templates override them. It is also possible to add custom template directories (with .BR --templates ) that will be used to get templates before trying in the user and in the system-wide template directories. The option .B --gt might be used to get copies of template files in the local or in the user template directory. .SH EXAMPLES Run .B llgal in a directory with .IR jpg ", " gif ", " png ", " mpg " or " avi files to see what it does. Then play with the options described above and use .B -h if you need a quick listing. .SH BUGS There are always some. If you find any let me know. .SH SEE ALSO .PP .BR llgalrc (5) .SH AUTHOR Brice Goglin ��������������������������������������������������������������������������llgal-llgal-0.13.19/llgal.in������������������������������������������������������������������������0000775�0000000�0000000�00000251277�13143122354�0015513�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/perl -w use strict ; require Llgal::Config ; require Llgal::Messages ; require Llgal::Templates ; require Llgal::Utils ; use FileHandle ; use Image::Size ; use Cwd ; use Locale::gettext ; use POSIX qw (setlocale) ; use URI::Escape ; use Text::ParseWords ; use File::Compare ; Getopt::Long::Configure('noignorecase', 'noautoabbrev', 'bundling') ; STDOUT->autoflush("1") ; # constants and globals my $self = { version => "@VERSION@", llgal_config_dir => "@SYSCONFDIR@/llgal", llgal_share_dir => "@DATADIR@/llgal", user_share_dir => $ENV{HOME}."/.llgal", generic_configuration_filename => "llgalrc", locale_dir => "@LOCALEDIR@", # local llgal directory, may be modified during early configuration local_llgal_dir => ".llgal", # look in current directory "." destination_dir => ".", # no section by default # section_dirs => (), # some variable may only be modified when by system # or user-wide configuration files only early_configuration => 1, # show version version_asked => 0, # displays brief usage message help_asked => 0, # clean up all generated files clean_asked => 0, # clean up all generated and user modified files cleanall_asked => 0, # generate (or update) captions generate_captions => 0, # give templates to the given directory give_templates => undef, # generate a config file generate_config => undef, # level of indentation, warnings, ... messages => Llgal::Messages::new (), } ; # store command-line options to write in the index <head> my $llgal_cmdline = join (" ", @ARGV) ; # parse early command line options Llgal::Config::early_parse_cmdline_options ($self) ; # gettext initialization Llgal::Config::init_llgal_gettext ($self) ; ###################################################################### # various temporary globals my $messages = $self->{messages} ; my $destination_string ; my $local_llgal_url ; my $opts ; my $opts_without_defaults ; ###################################################################### # --clean and --cleanall option sub clean_files { my $cleanall = shift ; my $notdeleted = 0 ; if ($cleanall) { $messages->print ("Cleaning all in $destination_string\n") ; } else { $messages->print ("Cleaning in $destination_string\n") ; } opendir DIR, "$self->{destination_dir}$self->{local_llgal_dir}" or die "Can't open directory $self->{destination_dir}$self->{local_llgal_dir} ($!).\n" ; while ($_ = readdir DIR) { if (/^$opts->{thumbnail_image_filenameprefix}/ or /^$opts->{scaled_image_filenameprefix}/) { unlink "$self->{destination_dir}$self->{local_llgal_dir}/$_" ; } elsif (/^$opts->{filmtile_filename}$/ or /^$opts->{index_link_image_filename}$/ or /^$opts->{prev_slide_link_image_filename}$/ or /^$opts->{next_slide_link_image_filename}$/ or /^$opts->{indextemplate_filename}$/ or /^$opts->{slidetemplate_filename}$/ or /^$opts->{css_filename}$/) { my $original = (Llgal::Templates::find_generic_template_file ($self, $opts, $_, 0))."/".$_ ; my $diff = 0 ; # default is cleanall, which removes everything, as if file were not changed if (!$cleanall) { $diff = compare ("$self->{destination_dir}$self->{local_llgal_dir}/$_", "$original") ; die "Failed to check whether $self->{destination_dir}$self->{local_llgal_dir}/$_ has been modified ($!).\n" if $diff == -1 ; } if ($diff) { $messages->warning ("Preserved $self->{destination_dir}$self->{local_llgal_dir}/$_ since it seems to be modified.") ; $notdeleted++ ; } else { if (!unlink "$self->{destination_dir}$self->{local_llgal_dir}/$_" and ! $!{ENOENT}) { $messages->warning ("Failed to remove file $self->{destination_dir}$self->{local_llgal_dir}/$_ ($!).") ; } } } elsif (/^$opts->{captions_filename}$/) { my $grep = 0 ; # default is cleanall, which removes everything, as if the removal line was here if (!$cleanall) { open CAP, "$self->{destination_dir}$self->{local_llgal_dir}/$_" ; my @lines = <CAP> ; close CAP ; $grep = scalar (grep { $_ =~ $opts->{captions_removal_line} } @lines) ; } if (!$grep) { $messages->warning ("Preserved $self->{destination_dir}$self->{local_llgal_dir}/$_ since it seems to be modified.") ; $notdeleted++ ; } else { if (!unlink "$self->{destination_dir}$self->{local_llgal_dir}/$_" and ! $!{ENOENT}) { $messages->warning ("Failed to remove file $self->{destination_dir}$self->{local_llgal_dir}/$_.") ; } } } else { $notdeleted++ ; } } closedir DIR ; if ($notdeleted <= 2 and $cleanall) { if (!rmdir "$self->{destination_dir}$self->{local_llgal_dir}" and ! $!{ENOENT}) { $messages->warning ("Failed to remove directory $self->{destination_dir}$self->{local_llgal_dir} ($!).") ; } } opendir DIR, $self->{destination_dir} ? $self->{destination_dir} : "./" ; # destination is empty for './' while ($_ = readdir DIR ) { if (/^$opts->{index_filename}\.$opts->{www_extension}$/ or /^$opts->{slide_filenameprefix}.*\.$opts->{www_extension}$/) { unlink "$self->{destination_dir}$_" ; } } closedir DIR ; } ##################################################################### # Main variables # The main gallery is composed of # - @entries (the entry list) # - @headers and @footers sub init_gallery { my $gallery = () ; @{$gallery->{headers}} = () ; @{$gallery->{footers}} = () ; @{$gallery->{entries}} = () ; %{$gallery->{user_fields}} = () ; $gallery->{indextemplate} = undef ; @{$gallery->{slidetemplate_text}} = () ; @{$gallery->{template_exif_tags_list}} = () ; return $gallery ; } # Entries are hashed composed of # - type: see below # - filename (original filename with extension) # - url (url of the filename) # - linktext (an associated text that may be used in a link, www-safe) # - caption (the caption of the slide, www-safe) # - title (title, www-safe) # - no_thumb (1 or undef, means that the entry is listed instead of displayed as a thumbnail) # - no_slide (1 or undef, means that the entry does not appear as any slide at all) # - xdim, ydim, kbytes (details about the image or movie) # - dimstring (string containing dimensions and/or size that were requested) # - slide_filename (name of the HTML slide filename) # - slide_url (url of the HTML slide filename) # - counter_with_zeros (stringified counter used in slide's filename) # - thumb_xdim, thumb_ydim (details about the thumbnail image) # - thumb_dimstring (string containing dimensions) # - thumb_filename (name of the thumbnail image file) # - thumb_url (url of the thumbnail image file) # - scaled_xdim, scaled_ydim, scaled_kbytes (details about the scaled image) # - scaled_dimstring (string containing dimensions and/or size that were requested) # - scaled_filename (name of the scaled image file) # - scaled_url (url of the scaled image file) # - gallery (the whole gallery in the subdirectory pointed by this entry) # types my $TYPE_TEXT = 0 ; my $TYPE_LINK = 1 ; my $TYPE_IMAGE = 2 ; my $TYPE_MOVIE = 3 ; my $TYPE_FILE = 4 ; my $TYPE_DIR = 5 ; my $TYPE_LINE = 6 ; my $TYPE_BREAK = 7 ; my $TYPE_LINKNOSLIDE = 8 ; # only used when calling create_nofile_entry, which changes it into $TYPE_LINK with no_slide set ################################################################################### # checking files sub check_file { my $filename = shift ; if (! -e $filename) { $messages->warning ("Cannot find file '$filename', skipping it.") ; return -1 ; } my $excluded = 0 ; for(my $i = 0; $i < @{$opts->{excludes}}; $i++) { my $entry = @{$opts->{excludes}}[$i] ; if ($filename =~ m@^(.*/)*$entry->{filter}$@) { $excluded = $entry->{excluded} } } return -1 if $excluded ; return 0 ; } ################################################################################### # returns a filename that the user provided in the llgal directory # to be used as a thumbnail or scaled image sub find_user_thumbnail { my $entry = shift ; my $type = $entry->{type} ; my $filename = $entry->{filename} ; my $user_thumbnail_filename = "$opts->{user_thumbnail_image_filenameprefix}$opts->{thumbnail_image_filenameprefix}$filename" ; if ($type == $TYPE_IMAGE) { if (-f "$self->{destination_dir}$self->{local_llgal_dir}/$user_thumbnail_filename") { return $user_thumbnail_filename ; } } else { foreach my $ext (split (/\|/, $opts->{image_extensions})) { if (-f "$self->{destination_dir}$self->{local_llgal_dir}/$user_thumbnail_filename.$ext") { return "$user_thumbnail_filename.$ext" ; } } } return "" ; } sub find_user_scaled { my $entry = shift ; my $type = $entry->{type} ; my $filename = $entry->{filename} ; my $user_scaled_filename = "$opts->{user_scaled_image_filenameprefix}$opts->{scaled_image_filenameprefix}$filename" ; if ($type == $TYPE_IMAGE) { if (-f "$self->{destination_dir}$self->{local_llgal_dir}/$user_scaled_filename") { return $user_scaled_filename ; } } else { foreach my $ext (split (/\|/, $opts->{image_extensions})) { if (-f "$self->{destination_dir}$self->{local_llgal_dir}/$user_scaled_filename.$ext") { return "$user_scaled_filename.$ext" ; } } } return "" ; } ################################################################################### # extract caption from image infos # Image comment sub generate_caption_from_image_comment { my $exif_infos = shift ; my @texts = () ; # Loop until a non-empty comment list is found foreach my $types (split (/,/, $opts->{make_caption_from_image_comment})) { # types is a + separated string of types foreach my $type (split (/\+/, $types)) { if ($type =~ m/^std$/i) { # Standard comment such as JFIF or GIF my $comment = $exif_infos->{Comment} ; push (@texts, $comment) if $comment ; } elsif ($type =~ m/^exif$/i) { # Exif comment my $comment = $exif_infos->{UserComment} ; push (@texts, $comment) if $comment ; } elsif ($type =~ m/^exifdesc$/i) { # Exif image description my $comment = $exif_infos->{ImageDescription} ; push (@texts, $comment) if $comment ; } else { $messages->abort_percentage ; die "Unrecognized image comment type '$type'.\n" ; } } return @texts if @texts ; } return () ; } # Image timestamp sub generate_caption_from_image_timestamp { my $exif_infos = shift ; my $imagetime = $exif_infos->{DateTimeOriginal} ; return $imagetime; } # Image infos sub generate_caption_from_image_infos { my $exif_infos = shift ; my @texts = () ; if ($opts->{make_caption_from_image_comment}) { my @comments = generate_caption_from_image_comment $exif_infos ; push (@texts, @comments) ; } if ($opts->{make_caption_from_image_timestamp}) { my $timestamp = generate_caption_from_image_timestamp $exif_infos ; push (@texts, $timestamp) ; } return @texts ; } ################################################################################### # generating safe url sub make_safe_url_nowarn { return join '/', map { uri_escape $_ } (split /\//, shift) ; } sub make_safe_url { my $file = shift ; my $safe = make_safe_url_nowarn ($file) ; $messages->warning ("Non-ascii characters were escaped in filename '$file'.") if $safe ne $file and $file =~ m/[\x80-\xFF]/ ; return $safe ; } ################################################################################### # Generate entries sub create_file_entry { my $entry = () ; my $gallery = shift ; my $type = shift ; my $filename = shift ; my $linktext = shift ; my $caption = shift ; # cache real filename for later my $real_filename = "$self->{destination_dir}$filename" ; # check file return undef if check_file ($real_filename) < 0 ; # set the type $entry->{type} = $type ; # set the filename $entry->{filename} = $filename ; # make a safe url $entry->{url} = make_safe_url ($filename) ; # the link text (will be web-safe after caption file generation) if (not defined $linktext) { $linktext = "" ; if ($type == $TYPE_MOVIE) { $linktext = $opts->{MVI_link_text}.$filename ; } elsif ($type == $TYPE_FILE) { $linktext = $opts->{FIL_link_text}.$filename ; } elsif ($type == $TYPE_DIR) { $linktext = $opts->{DIR_link_text}.$filename ; } $linktext =~ s/&/&/g ; # $linktext =~ s/"/&\#34;/g ; } $entry->{linktext} = $linktext ; if ($type == $TYPE_DIR) { # subgallery specific fields # add index.html so that it works without a web server $entry->{url} = $entry->{url}."/".$opts->{index_filename}.".".$opts->{www_extension} ; # generate a name for links from prev/next gallery my @parts = split /\//, $filename ; $entry->{gallery_name} = pop @parts ; } # for images, we need at least the dimensions (and check their validity) and possibly some Exif info # if some Exif are needed, retrieve dimensions with ExifTool too # if not, just retrieve dimensions with imgsize if ($type == $TYPE_IMAGE) { my ($x,$y) ; # if showing some exif flags, or using some options that require Exif, # use ExifTool for both these and image dimensions validity checking if ($opts->{show_all_exif_tags} or @{$opts->{show_exif_tags}} or @{$gallery->{template_exif_tags_list}} or $opts->{make_caption_from_image_timestamp} or $opts->{make_caption_from_image_comment}) { # only load Image::ExifTool when really required if (not defined $opts->{exiftool}) { # Try to load the module if (not eval { require Image::ExifTool ; }) { $messages->abort_percentage (); die "Perl module Image::ExifTool not found, please install it if you wish to extract tags from images.\n" ; } # ExifTool initialization $opts->{exiftool} = new Image::ExifTool; # accept unknown tags, just in case... $opts->{exiftool}->Options(Unknown => 1) ; # set the GPS coodinate format **HACK** $opts->{exiftool}->Options(CoordFormat => "%.6f") ; # dateFormat should be initialized with whatever the user said to --ct $opts->{exiftool}->Options(DateFormat => $opts->{timestamp_format_in_caption}) ; # initialize the list of tags, empty for all my @exif_tags = () ; if (!$opts->{show_all_exif_tags}) { # use the user provided Exif tags, and add ImageWidth/Height for ourself @exif_tags = @{$gallery->{template_exif_tags_list}} ; @exif_tags = (@exif_tags, 'ImageWidth', 'ImageHeight', @{$opts->{show_exif_tags}}) ; @exif_tags = (@exif_tags, 'DateTimeOriginal') if $opts->{make_caption_from_image_timestamp} ; @exif_tags = (@exif_tags, 'UserComment', 'Comment', 'ImageDescription') if $opts->{make_caption_from_image_comment} ; } @{$opts->{cached_exif_tags_list}} = @exif_tags ; } # do the actual exif tag retrieval my $exif_infos = $opts->{exiftool}->ImageInfo ($real_filename, @{$opts->{cached_exif_tags_list}}) ; $entry->{exif_infos} = $exif_infos ; # get image dimensions $x = $exif_infos->{ImageWidth} ; $y = $exif_infos->{ImageHeight} ; } else { # if not using Exif at all, just retrieve dimensions for ourself ($x,$y) = imgsize ($real_filename) ; } # check dimensions validity if (not defined $x or not defined $y) { $messages->warning ("Bad image file '$filename', cannot retrieve its dimensions, skipping it.") ; return undef ; } $entry->{xdim} = $x ; $entry->{ydim} = $y ; } # the caption (will be web-safe after caption file generation) if (not defined $caption) { my @texts = () ; if ($opts->{make_caption_from_extension}) { push (@texts, $filename) ; } elsif ($opts->{make_caption_from_filename}) { my $basename = $filename ; if ($type != $TYPE_DIR) { # remove the extension $basename =~ s/\.[^\.]+$// ; } push (@texts, $basename) ; } push (@texts, generate_caption_from_image_infos $entry->{exif_infos}) if $type == $TYPE_IMAGE ; $caption = join (' - ', grep {$_} @texts) ; $caption =~ s/&/&/g ; # $caption =~ s/"/&\#34;/g ; } chomp $caption ; $entry->{caption} = $caption ; # title is based on the filename my $title = $filename ; $title =~ s/&/&/g ; # $title =~ s/"/&\#34;/g ; # add caption to the title if asked $title .= ": ". $caption if $opts->{make_slide_title_from_caption} ; $entry->{title} = $title ; # do not generate more if we are only generating captions return $entry ; } sub fill_file_entry { my $entry = shift ; my $type = $entry->{type} ; my $filename = $entry->{filename} ; # cache real filename for later my $real_filename = "$self->{destination_dir}$filename" ; # xdim, ydim, kbytes of the image or movie if ($type == $TYPE_IMAGE) { # initialize here so that we can use it even when scaled are not used $entry->{scaled_xdim} = $entry->{xdim} ; $entry->{scaled_ydim} = $entry->{ydim} ; } if ($type == $TYPE_IMAGE or $type == $TYPE_MOVIE or $type == $TYPE_FILE) { my $kbytes = (-s $real_filename) >> 10 ; $entry->{kbytes} = $kbytes ; # initialize here so that we can use it even when scaled are not used $entry->{scaled_kbytes} = $kbytes ; } # dimstring if ($type == $TYPE_IMAGE) { if ($opts->{show_dimensions} and $opts->{show_size}) { $entry->{dimstring} = "($entry->{xdim}x$entry->{ydim}, $entry->{kbytes}$opts->{show_size_unit})" ; } elsif ($opts->{show_size}) { $entry->{dimstring} = "($entry->{kbytes}$opts->{show_size_unit})" ; } elsif ($opts->{show_dimensions}) { $entry->{dimstring} = "($entry->{xdim}x$entry->{ydim})" ; } else { $entry->{dimstring} = "" ; } } elsif ($type == $TYPE_MOVIE or $type == $TYPE_FILE) { if ($opts->{show_size}) { $entry->{dimstring} = "($entry->{kbytes}$opts->{show_size_unit})" ; } else { $entry->{dimstring} = "" ; } } else { $entry->{dimstring} = "" ; } #################################### # thumbnail, its url and dimensions my $thumb_filename = find_user_thumbnail ($entry) ; if ($thumb_filename) { # there's a user provided thumbnail, just use it # cache real thumb filename for later my $real_thumb_filename = "$self->{destination_dir}$self->{local_llgal_dir}/$thumb_filename" ; $entry->{thumb_filename} = "$self->{local_llgal_dir}/$thumb_filename" ; $entry->{thumb_url} = "$local_llgal_url/". make_safe_url_nowarn ($thumb_filename) ; # thumbnail dimensions my ($tx, $ty) = imgsize ($real_thumb_filename) ; # check thumbnail validity if (not defined $tx or not defined $ty) { $messages->warning ("Bad user-given thumbnail file '$real_thumb_filename', cannot retrieve its dimensions, ignoring it.") ; goto NO_USER_THUMB ; } # resize in the gallery if necessary if ($ty > $opts->{thumbnail_height_max}) { $tx = $tx * ($opts->{thumbnail_height_max} / $ty) ; $ty = $opts->{thumbnail_height_max} ; } if ($opts->{thumbnail_width_max} > 0 and $tx > $opts->{thumbnail_width_max}) { $ty = $ty * ($opts->{thumbnail_width_max} / $tx) ; $tx = $opts->{thumbnail_width_max} ; } # store values ($entry->{thumb_xdim},$entry->{thumb_ydim}) = ($tx, $ty) ; # dimstring if ($opts->{show_dimensions}) { $entry->{thumb_dimstring} = "(${tx}x${ty})" ; } else { $entry->{thumb_dimstring} = "" ; } } elsif ($type == $TYPE_IMAGE) { NO_USER_THUMB: # no user provided thumbnail, generate one # filename and url $thumb_filename = "$opts->{thumbnail_image_filenameprefix}$filename" ; $thumb_filename =~ s@/@$opts->{path_separator_replacement}@g ; $entry->{thumb_filename} = "$self->{local_llgal_dir}/$thumb_filename" ; $entry->{thumb_url} = "$local_llgal_url/". make_safe_url_nowarn ($thumb_filename) ; # cache real thumb filename for later my $real_thumb_filename = "$self->{destination_dir}$entry->{thumb_filename}" ; # if the thumbnail does not exist, or is older than the image, or regeneration is forced if ((! -e $real_thumb_filename) or (-M $real_thumb_filename) > (-M $real_filename) or $opts->{force_image_regeneration}) { my ($status, @output) ; # only scale down, never up. if ($entry->{ydim} <= $opts->{thumbnail_height_max} and ($opts->{thumbnail_width_max} <= 0 or $entry->{xdim} <= $opts->{thumbnail_width_max})) { # the original is not large enough, keep it $entry->{thumb_filename} = $entry->{filename} ; $entry->{thumb_url} = $entry->{url} ; $real_thumb_filename = $real_filename ; } else { # scale down my @cmdline = map { s/<IN>/$real_filename/g ; s/<OUT>/$real_thumb_filename/g ; $_ ; } Text::ParseWords::parse_line('\s+', 0, $opts->{thumbnail_create_command}) ; ($status, @output) = Llgal::Utils::system_with_output ( "create '$filename' thumbnail", @cmdline ) ; if ($status == -1) { $messages->warning (@output) ; $messages->abort_percentage ; die "Failed to create '$real_filename' thumbnail.\n" ; } elsif ($status) { $messages->warning ("Failed to create '$real_filename' thumbnail.") ; $messages->warning (@output) ; return undef ; } } } # thumbnail dimensions my ($tx,$ty) = imgsize ($real_thumb_filename) ; # check thumbnail validity if (not defined $tx or not defined $ty) { $messages->warning ("Bad thumbnail file '$real_thumb_filename', cannot retrieve its dimensions, skipping this entry.") ; return undef ; } # store values ($entry->{thumb_xdim},$entry->{thumb_ydim}) = ($tx,$ty) ; # dimstring if ($opts->{show_dimensions}) { $entry->{thumb_dimstring} = "(${tx}x${ty})" ; } else { $entry->{thumb_dimstring} = "" ; } } else { # default thumbnail dimensions $entry->{thumb_xdim} = $opts->{default_thumb_xdim} ; $entry->{thumb_ydim} = $opts->{default_thumb_ydim} ; # dimstring is empty $entry->{thumb_dimstring} = "" ; } if (!$opts->{make_no_slides}) { ####################################### # scaled image, its url and dimensions my $scaled_filename = find_user_scaled ($entry) ; if ($scaled_filename) { # there's a user provided scaled, just use it # cache real thumb filename for later my $real_scaled_filename = "$self->{destination_dir}$self->{local_llgal_dir}/$scaled_filename" ; $entry->{scaled_filename} = "$self->{local_llgal_dir}/$scaled_filename" ; $entry->{scaled_url} = "$local_llgal_url/". make_safe_url_nowarn ($scaled_filename) ; # scaled image dimensions my ($sx, $sy) = imgsize ($real_scaled_filename) ; my $skbytes = (-s $real_scaled_filename) >> 10 ; # check scaled validity if (not defined $sx or not defined $sy) { $messages->warning ("Bad user-given scaled image file '$real_scaled_filename', cannot retrieve its dimensions, ignoring it.") ; goto NO_USER_SCALED ; } # resize in the gallery if necessary if ($opts->{slide_height_max} > 0 and $sy > $opts->{slide_height_max}) { $sx = $sx * ($opts->{slide_height_max} / $sy) ; $sy = $opts->{slide_height_max} ; } if ($opts->{slide_width_max} > 0 and $sx > $opts->{slide_width_max}) { $sy = $sy * ($opts->{slide_width_max} / $sx) ; $sx = $opts->{slide_width_max} ; } # store values ($entry->{scaled_xdim},$entry->{scaled_ydim}) = ($sx, $sy) ; $entry->{scaled_kbytes} = $skbytes ; # dimstring if ($opts->{show_dimensions} and $opts->{show_size}) { $entry->{scaled_dimstring} = "(${sx}x${sy}, ${skbytes}$opts->{show_size_unit})" ; } elsif ($opts->{show_size}) { $entry->{scaled_dimstring} = "(${skbytes}$opts->{show_size_unit})" ; } elsif ($opts->{show_dimensions}) { $entry->{scaled_dimstring} = "(${sx}x${sy})" ; } else { $entry->{scaled_dimstring} = "" ; } } elsif ($type == $TYPE_IMAGE and ($opts->{slide_width_max} > 0 or $opts->{slide_height_max} > 0)) { NO_USER_SCALED: # no user provided scaled, generate one # filename and url $scaled_filename = "$opts->{scaled_image_filenameprefix}$filename" ; $scaled_filename =~ s@/@$opts->{path_separator_replacement}@g ; $entry->{scaled_filename} = "$self->{local_llgal_dir}/$scaled_filename" ; $entry->{scaled_url} = "$local_llgal_url/". make_safe_url_nowarn ($scaled_filename) ; # cache real thumb filename for later my $real_scaled_filename = "$self->{destination_dir}$entry->{scaled_filename}" ; # if the thumbnail does not exist, or is older than the image, or regeneration is forced if ((! -e $real_scaled_filename) or (-M $real_scaled_filename) > (-M $real_filename) or $opts->{force_image_regeneration}) { my ($status, @output) ; # only scale down, never up. if (($opts->{slide_width_max} <= 0 or $entry->{xdim} <= $opts->{slide_width_max}) and ($opts->{slide_height_max} <= 0 or $entry->{ydim} <= $opts->{slide_height_max})) { # the original is not large enough, keep it $entry->{scaled_filename} = $entry->{filename} ; $entry->{scaled_url} = $entry->{url} ; $real_scaled_filename = $real_filename ; } else { # scale down my @cmdline = map { s/<IN>/$real_filename/g ; s/<OUT>/$real_scaled_filename/g ; $_ ; } Text::ParseWords::parse_line('\s+', 0, $opts->{scaled_create_command}) ; ($status, @output) = Llgal::Utils::system_with_output ( "create '$filename' scaled image", @cmdline ) ; if ($status == -1) { $messages->warning (@output) ; $messages->abort_percentage ; die "Failed to create '$real_filename' scaled image.\n" ; } elsif ($status) { $messages->warning ("Failed to create '$real_filename' scaled image.") ; $messages->warning (@output) ; return undef ; } } } # scaled dimensions my ($sx,$sy) = imgsize ($real_scaled_filename) ; my $skbytes = (-s $real_scaled_filename) >> 10 ; # check scaled validity if (not defined $sx or not defined $sy) { $messages->warning ("Bad scaled image file '$real_scaled_filename', cannot retrieve its dimensions, skipping this entry.") ; return undef ; } # store values ($entry->{scaled_xdim},$entry->{scaled_ydim}) = ($sx,$sy) ; $entry->{scaled_kbytes} = $skbytes ; # dimstring if ($opts->{show_dimensions} and $opts->{show_size}) { $entry->{scaled_dimstring} = "(${sx}x${sy}, ${skbytes}$opts->{show_size_unit})" ; } elsif ($opts->{show_size}) { $entry->{scaled_dimstring} = "(${skbytes}$opts->{show_size_unit})" ; } elsif ($opts->{show_dimensions}) { $entry->{scaled_dimstring} = "(${sx}x${sy})" ; } else { $entry->{scaled_dimstring} = "" ; } } else { $entry->{scaled_dimstring} = $entry->{dimstring} ; } } else { $entry->{scaled_dimstring} = $entry->{dimstring} ; } return $entry ; } sub create_nofile_entry { my $entry = () ; my $type = shift ; my $url = shift ; my $linktext = shift ; my $caption = shift ; # special type case if ($type == $TYPE_LINKNOSLIDE) { $entry->{no_slide} = 1 ; $type = $TYPE_LINK ; } # set the type $entry->{type} = $type ; # row break and horizontal lines need nothing if ($type == $TYPE_LINE or $type == $TYPE_BREAK) { $entry->{no_slide} = 1 ; $entry->{no_thumb} = 1 ; return $entry ; } # make a safe url if (defined $url) { if ($type == $TYPE_LINK) { $entry->{url} = $url ; } else { $entry->{url} = make_safe_url ($url) ; } } # the link text (will be web-safe after caption file generation) $entry->{linktext} = $linktext ; # the caption (will be web-safe after caption file generation) $caption = "" unless defined $caption ; $entry->{caption} = $caption ; # add caption to the title if asked my $title = "" ; $title = $caption if $opts->{make_slide_title_from_caption} ; $entry->{title} = $title ; # do not generate more if we are only generating captions return $entry ; } sub fill_nofile_entry { my $entry = shift ; # dimstring $entry->{dimstring} = "" ; # default thumbnail dimensions $entry->{thumb_xdim} = $opts->{default_thumb_xdim} ; $entry->{thumb_ydim} = $opts->{default_thumb_ydim} ; # dimstring is empty $entry->{thumb_dimstring} = "" ; if (!$opts->{make_no_slides}) { # scaled image dimensions $entry->{scaled_dimstring} = $entry->{dimstring} ; } return $entry ; } # fill entries, everything that's not required for # captions generation, but may be done early sub fill_entries { my $gallery = shift ; my @entries = @{$gallery->{entries}} ; my @final_entries = () ; $messages->print ("Preparing entries: ") ; $messages->init_percentage (scalar @entries) ; my $i = 0 ; for my $entry (@entries) { my $type = $entry->{type} ; my $final_entry ; if ($type == $TYPE_LINE or $type == $TYPE_BREAK) { $final_entry = $entry ; # nothing to do } elsif ($type == $TYPE_TEXT or $type == $TYPE_LINK) { $final_entry = fill_nofile_entry $entry ; } else { $final_entry = fill_file_entry $entry ; } push @final_entries, $final_entry if defined $final_entry ; $messages->update_percentage (($i++)+1) ; } $messages->end_percentage () ; @{$gallery->{entries}} = @final_entries ; } # generate slide number, filename and url only when the order of entries is fixed sub finalize_entries { my $gallery = shift ; my $opts = shift ; my @entries = @{$gallery->{entries}} ; if ($opts->{list_links}) { map { my $type = $_->{type} ; if (!$_->{thumb_filename} and ($type == $TYPE_LINK or $type == $TYPE_DIR or $type == $TYPE_MOVIE or $type == $TYPE_FILE or $type == $TYPE_TEXT)) { $_->{no_thumb} = 1 ; } } @entries ; } # account slides my $nslides = scalar (grep { ! $_->{no_slide} } @entries) ; $gallery->{nslides} = $nslides ; # prepare numbering my $counter_length = length $nslides ; my $prev = undef ; my $first = undef ; my $indix = 0 ; for(my $i=0; $i < @entries; $i++) { my $entry = $entries[$i] ; # entries without a slide are not taken into account next if defined $entry->{no_slide} ; # if making no slides, only subgallery may be linked together next if $opts->{make_no_slides} and $entry->{type} != $TYPE_DIR and $opts->{link_subgalleries} ; # slide counter $indix++; $entry->{counter} = $indix ; my $counter_with_zeros = sprintf "%0${counter_length}d", $indix ; $entry->{counter_with_zeros} = $counter_with_zeros ; my $type = $entry->{type} ; my $filename = $entry->{filename} ; # HTML slide and its url if (!$opts->{make_no_slides} and $type != $TYPE_LINE and $type != $TYPE_BREAK) { my $slide_filename ; if ($opts->{make_slide_filename_from_filename}) { if ($type == $TYPE_TEXT or $type == $TYPE_LINK) { $slide_filename = "$opts->{slide_filenameprefix}$counter_with_zeros.$opts->{www_extension}" ; } elsif ($opts->{make_slide_filename_from_extension} or $type == $TYPE_DIR) { $slide_filename = "$opts->{slide_filenameprefix}$filename.$opts->{www_extension}" ; } else { my @parts = split (/\./, $filename) ; pop @parts ; my $basename = join ('.', @parts) ; $slide_filename = "$opts->{slide_filenameprefix}$basename.$opts->{www_extension}" ; } } else { $slide_filename = "$opts->{slide_filenameprefix}$counter_with_zeros.$opts->{www_extension}" ; } $entry->{slide_filename} = $slide_filename ; $entry->{slide_url} = make_safe_url_nowarn ($slide_filename) ; } # initialize to -1 for no link to prev/next slide $entry->{prev} = -1 ; $entry->{next} = -1 ; # link to previous entry if (defined $prev) { $entry->{prev} = $prev; $entries[$prev]->{next} = $i ; } $prev = $i ; # store first $first = $i unless defined $first ; } if (defined $first and $opts->{link_between_last_and_first}) { # link last to first $entries[$prev]->{next} = $first ; $entries[$first]->{prev} = $prev ; } } ####################################################################### # Generating entry table from files in target directory sub sort_entries { my $path = shift ; if ($opts->{sort_criteria} eq "name") { return sort @_ ; } elsif ($opts->{sort_criteria} eq "revname") { return sort { $b cmp $a } @_ ; } elsif ($opts->{sort_criteria} eq "iname") { return sort { uc($a) cmp uc($b) } @_ ; } elsif ($opts->{sort_criteria} eq "reviname") { return sort { uc($b) cmp uc($a) } @_ ; } elsif ($opts->{sort_criteria} eq "date" or $opts->{sort_criteria} eq "time") { return sort { (-M "$path$a") <=> (-M "$path$b") } @_ ; } elsif ($opts->{sort_criteria} eq "revdate" or $opts->{sort_criteria} eq "revtime") { return sort { (-M "$path$b") <=> (-M "$path$a") } @_ ; } elsif ($opts->{sort_criteria} eq "size") { return sort { (-s "$path$a") <=> (-s "$path$b") } @_ ; } elsif ($opts->{sort_criteria} eq "revsize") { return sort { (-s "$path$b") <=> (-s "$path$a") } @_ ; } elsif ($opts->{sort_criteria} eq "none" or $opts->{sort_criteria} eq "") { return @_ } else { die "Unknown sort criteria '$opts->{sort_criteria}'.\n" ; } } sub get_entries_from_directory { my $gallery = shift; my $dir = shift ; my $subdir = shift ; my $add_subdirs = shift ; my $add_others = shift ; my @entries = () ; my $destdir = "$dir$subdir" ; my $destdir_string = "directory $dir$subdir" ; if (!$destdir) { $destdir = "." ; $destdir_string = "current directory" ; } my $subdir_string = $subdir ; $subdir_string = "." unless $subdir_string ; opendir DIR, $destdir or die "Can't open $destdir_string ($!).\n" ; # get all files, except dot-starting ones and webpages my @filenames = map { ($subdir ? "$subdir/" : "").$_ } (grep ((!/\.$opts->{www_extension}$/i and !/^\./), readdir DIR)) ; closedir DIR ; # sort now so that slide numbering doesn't become wrong later @filenames = sort_entries $dir, @filenames ; $messages->print ("Listing entries in $subdir_string : ") ; $messages->init_percentage (scalar @filenames) ; for(my $i = 0; $i < @filenames; $i++) { my $filename = $filenames[$i] ; chomp $filename ; if (-d "$dir$filename") { # directory if ($add_subdirs) { my $entry = create_file_entry ($gallery, $TYPE_DIR, $filename, undef, undef) ; push @entries, $entry if defined $entry ; } } else { # file my $entry = undef ; if ($filename =~ m/($opts->{image_extensions})$/i) { # image my $entry = create_file_entry ($gallery, $TYPE_IMAGE, $filename, undef, undef) ; goto JUST_A_FILE if not defined $entry ; push @entries, $entry ; } elsif ($filename =~ m/($opts->{movie_extensions})$/i) { # movie my $entry = create_file_entry ($gallery, $TYPE_MOVIE, $filename, undef, undef) ; goto JUST_A_FILE if not defined $entry ; push @entries, $entry ; } else { JUST_A_FILE: if ($add_others) { # not an image, not a movie, just a file my $entry = create_file_entry ($gallery, $TYPE_FILE, $filename, undef, undef) ; push @entries, $entry if defined $entry ; } } } $messages->update_percentage ($i+1) ; } $messages->end_percentage () ; return @entries ; } sub get_subdir_tree { my @processed_dirs = () ; my @remaining_dirs = ("") ; while (@remaining_dirs) { my $current_dir = shift @remaining_dirs ; my $destdir = "$self->{destination_dir}$current_dir" ; my $destdir_string = "directory $destdir" ; if (!$destdir) { $destdir = "." ; $destdir_string = "current directory" ; } # enqueue subdirectories opendir DIR, $destdir or die "Can't open $destdir_string ($!).\n" ; unshift @remaining_dirs, ( sort_entries # base directory for sorting $self->{destination_dir}, # add subdirectories only ( grep { -d "$self->{destination_dir}$_" } ( map { "$current_dir$_/" } # except those starting with a dot ( grep ((!/^\./), ( readdir DIR ) ) ) ) ) ) ; closedir DIR ; # this directory is done push @processed_dirs, $current_dir ; } return @processed_dirs ; } sub get_entries { my $gallery = shift ; my $opts = shift ; my @entries = () ; if ($opts->{recursive_sections} or (defined $opts->{section_dirs} and @{$opts->{section_dirs}})) { my @subdirs ; if ($opts->{recursive_sections}) { @subdirs = get_subdir_tree () ; } else { @subdirs = @{$opts->{section_dirs}} ; } foreach my $subdir (@subdirs) { # remove ending slashes $subdir =~ s@/*$@@g ; # separation line and title push @entries, (create_nofile_entry $TYPE_LINE, undef, undef, undef) if $opts->{separate_sections} ; if ($opts->{entitle_sections}) { my $text = $opts->{section_text}.($subdir ? $subdir : ".") ; push @entries, (create_nofile_entry $TYPE_TEXT, undef, $text, $text) ; } # section entries push @entries, get_entries_from_directory $gallery, $self->{destination_dir}, $subdir, ($opts->{add_subdirs} or $opts->{recursive}), $opts->{add_all_files} ; } } else { @entries = get_entries_from_directory $gallery, $self->{destination_dir}, "", ($opts->{add_subdirs} or $opts->{recursive}), $opts->{add_all_files} ; } return @entries ; } ####################################################################### # Check acces rights and create local subdirectory to place all llgal files sub check_destination { # check destination die "Destination $self->{destination_dir} does not exist.\n" if ! -e $self->{destination_dir} ; die "Destination $self->{destination_dir} is not a directory.\n" if ! -d $self->{destination_dir} ; # cleanup destination # add a final / $self->{destination_dir} .= "/" unless $self->{destination_dir} =~ m@/$@ ; # remove starting ./ $self->{destination_dir} =~ s@^(\./+)+@@ ; # Are we in .llgal ? just check the last part of the path by concatening # pwd and destination_dir even if destination_dir is an absolute path my $path = getcwd."/".$self->{destination_dir} ; if ($path =~ m@/*(?:[^/]+/+)*([^/]+)/+$@) { if ($1 eq $self->{local_llgal_dir}) { $messages->warning ("!! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !!") ; $messages->warning ("Your working directory looks like a .llgal directory. !!") ; $messages->warning ("This might not be what you really want to do. !!") ; $messages->warning ("!! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !!") ; } } # TODO: remove this one day (maybe on march 7th 2006, since it will be 6 month ?) # temporary check, to be removed soon if ($self->{local_llgal_dir} ne ".llgal.files" and -e "$self->{destination_dir}.llgal.files") { $messages->warning ("!! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !!") ; $messages->warning ("llgal now uses '.llgal' instead '.llgal.files'. !!") ; $messages->warning ("You should probably update it. !!") ; $messages->warning ("!! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !!") ; } # create globals to factorize later $local_llgal_url = make_safe_url_nowarn ($self->{local_llgal_dir}) ; } sub setup_destination { # create globals to factorize later $destination_string = ($self->{destination_dir} ? "directory $self->{destination_dir}" : "current directory") ; # Create or check the local llgal directory if (! -e "$self->{destination_dir}$self->{local_llgal_dir}") { mkdir "$self->{destination_dir}$self->{local_llgal_dir}" or die "Failed to create $self->{destination_dir}$self->{local_llgal_dir} directory ($!).\n" ; } die "Local llgal $self->{destination_dir}$self->{local_llgal_dir} is not a directory.\n" if ! -d "$self->{destination_dir}$self->{local_llgal_dir}" ; } ####################################################################### # Generate captions file sub generate_captions_entries { my $gallery = shift ; my $opts = shift ; my @entries = @{$gallery->{entries}} ; $messages->print ("Found ". (scalar @entries) ." entries in $destination_string\n") ; my @captions = () ; # store old values from the captions file, if it exists my $old_title ; my $old_parent_gallery_link = 0 ; my $old_parent_gallery_link_text ; my $old_prev_gallery_link_target ; my $old_prev_gallery_link_text ; my $old_next_gallery_link_target ; my $old_next_gallery_link_text ; if (-e "$self->{destination_dir}$self->{local_llgal_dir}/$opts->{captions_filename}") { $messages->print ("Reading existing captions from $opts->{captions_filename}.\n") ; open (CAP, "$self->{destination_dir}$self->{local_llgal_dir}/$opts->{captions_filename}") or die "Can't open $self->{destination_dir}$self->{local_llgal_dir}/$opts->{captions_filename} for reading ($!).\n" ; @captions = <CAP> ; close CAP ; foreach my $line (@captions) { if ($line =~ m/^TITLE:\s*(.*)\s*$/) { $old_title = $1 ; } elsif ($line =~ m/^PARENT:\s*(.*)\s*$/) { $old_parent_gallery_link = 1 ; $old_parent_gallery_link_text = $1 ; } elsif ($line =~ m/^PREV:\s*(.+)\s+----\s+(.+)\s*/) { $old_prev_gallery_link_target = $2 ; $old_prev_gallery_link_text = $1 ; } elsif ($line =~ m/^NEXT:\s*(.+)\s+----\s+(.+)\s*/) { $old_next_gallery_link_target = $2 ; $old_next_gallery_link_text = $1 ; } } open (CAP, ">>$self->{destination_dir}$self->{local_llgal_dir}/$opts->{captions_filename}") or die "Can't open $self->{destination_dir}$self->{local_llgal_dir}/$opts->{captions_filename} file to append ($!).\n" ; $messages->print ("Appending new captions to $opts->{captions_filename}: ") ; print CAP "\n" ; print CAP "# Appended new captions on ". (scalar localtime) ."\n" ; print CAP "# invoked with $llgal_cmdline\n" ; print CAP "\n" ; } else { # find the captions headers my $headers = (Llgal::Templates::find_template_file ($self, $opts, $opts->{captions_header_filename}, 1)) . "/$opts->{captions_header_filename}" ; $messages->notice ("Using '$headers' as a header for the captions file...\n") ; # copy its content my @captions_header = () ; if (open CAPHEADER, $headers) { @captions_header = <CAPHEADER> ; close CAPHEADER ; } else { $messages->warning ("Failed to open $headers\n") ; } # create the captions file open (CAP, ">$self->{destination_dir}$self->{local_llgal_dir}/$opts->{captions_filename}") or die "Can't create $self->{destination_dir}$self->{local_llgal_dir}/$opts->{captions_filename} file ($!).\n" ; $messages->print ("Creating the $opts->{captions_filename} file: ") ; print CAP "# This is llgal's $opts->{captions_filename} file, first generated on ", scalar localtime, "\n" ; print CAP "# invoked with $llgal_cmdline\n" ; # append the header map { print CAP $_ ; } @captions_header ; # ends with a blank line # append the captions removal line print CAP "\n" ; print CAP "# $opts->{captions_removal_line}\n" ; print CAP "\n" ; } print CAP "TITLE: $opts->{index_title}\n" if defined $opts->{index_title} and (!defined $old_title or $old_title ne $opts->{index_title}) ; print CAP "PARENT: $gallery->{parent_gallery_link_text}\n" if ( defined $gallery->{parent_gallery_link_target} and ( !$old_parent_gallery_link or $old_parent_gallery_link_text ne $gallery->{parent_gallery_link_text} ) ) ; print CAP "PREV: $gallery->{prev_gallery_link_text} ---- $gallery->{prev_gallery_link_target}\n" if ( defined $gallery->{prev_gallery_link_target} and ( !defined $old_prev_gallery_link_target or $old_prev_gallery_link_target ne $gallery->{prev_gallery_link_target} or !defined $old_prev_gallery_link_text or $old_prev_gallery_link_text ne $gallery->{prev_gallery_link_text} ) ) ; print CAP "NEXT: $gallery->{next_gallery_link_text} ---- $gallery->{next_gallery_link_target}\n" if ( defined $gallery->{next_gallery_link_target} and ( !defined $old_next_gallery_link_target or $old_next_gallery_link_target ne $gallery->{next_gallery_link_target} or !defined $old_next_gallery_link_text or $old_next_gallery_link_text ne $gallery->{next_gallery_link_text} ) ) ; print CAP "\n" ; $messages->init_percentage (scalar @entries) ; for (my $i = 0; $i < @entries; $i++) { my $entry = $entries[$i] ; my $type = $entry->{type} ; if ($type == $TYPE_IMAGE) { print CAP "IMG: ". $entry->{filename} ." ---- ". $entry->{caption} ."\n" unless grep { $captions[$_] =~ m/^(\s*IMG:)?\s*\Q$entry->{filename}\E\s+----\s/ } ( 0 .. $#captions ) ; } elsif ($type == $TYPE_MOVIE) { print CAP "MVI: " . $entry->{filename} ." ---- ". $entry->{linktext} ." ---- ". $entry->{caption} ."\n" unless grep { $captions[$_] =~ m/^\s*MVI:\s*\Q$entry->{filename}\E\s+----\s/ } ( 0 .. $#captions ) ; } elsif ($type == $TYPE_FILE) { print CAP "FIL: " . $entry->{filename} ." ---- ". $entry->{linktext} ." ---- ". $entry->{caption} ."\n" unless grep { $captions[$_] =~ m/^\s*FIL:\s*\Q$entry->{filename}\E\s+----\s/ } ( 0 .. $#captions ) ; } elsif ($type == $TYPE_DIR) { print CAP "DIR: " . $entry->{filename} ." ---- ". $entry->{linktext} ." ---- ". $entry->{caption} ."\n" unless grep { $captions[$_] =~ m/^\s*DIR:\s*\Q$entry->{filename}\E\s+----\s/ } ( 0 .. $#captions ) ; } elsif ($type == $TYPE_TEXT) { # TODO: do not insert again ? (in case of --Ps) print CAP "TXT: " . $entry->{linktext} ." ---- ". $entry->{caption} ."\n"; } elsif ($type == $TYPE_LINE) { print CAP "LINE\n" ; } elsif ($type == $TYPE_BREAK) { print CAP "BREAK\n" ; } else { $messages->abort_percentage ; die "Unrecognized entry type '$type'.\n" ; } $messages->update_percentage ($i+1) ; } $messages->end_percentage () ; close CAP ; } ####################################################################### # Read entry list in the captions file sub read_captions_file { my $gallery = shift ; my @entries = () ; my @headers = () ; my @footers = () ; my $user_fields = () ; $messages->print ("Reading entries in the $opts->{captions_filename} file: ") ; open(CAP,"$self->{destination_dir}$self->{local_llgal_dir}/$opts->{captions_filename}") or die "Can't open $self->{destination_dir}$self->{local_llgal_dir}/$opts->{captions_filename} file ($!).\n" ; my $size = (-s CAP) ; $messages->init_percentage ($size) ; my $line ; while (defined ($line = <CAP>)) { chomp $line ; $line =~ s/^\s*// ; $line =~ s/\s\(\s*\)$/$1/ ; # only lines that don't start with # and are not empty if ($line !~ m/^\#/ and $line !~ m/^$/) { if ($line =~ m/^TITLE:\s*(.*)\s*/) { # title $opts->{index_title} = $1 ; } elsif ($line =~ m/^INDEXHEAD:\s*(.*)\s*$/) { # header for the index push @headers, $1 ; } elsif ($line =~ m/^INDEXFOOT:\s*(.*)\s*$/) { # footer for the index push @footers, $1 ; } elsif ($line =~ m/^PARENT:\s*(.*)\s*$/) { # parent gallery link label $gallery->{parent_gallery_link} = 1 ; $gallery->{parent_gallery_link_text} = $1 ; $gallery->{parent_gallery_link_target} = "../$opts->{index_filename}.$opts->{www_extension}" ; } elsif ($line =~ m/^PREV:\s*(.*)\s+----\s+(.*)\s*$/) { # prev gallery link label $gallery->{prev_gallery_link_text} = $1 ; $gallery->{prev_gallery_link_target} = $2 ; } elsif ($line =~ m/^NEXT:\s*(.*)\s+----\s+(.*)\s*$/) { # next gallery link label $gallery->{next_gallery_link_text} = $1 ; $gallery->{next_gallery_link_target} = $2 ; } elsif ($line =~ m/^REPLACE:\s*(.+)\s+----\s+(.*)\s*$/) { # replacing $user_fields->{$1} = $2 ; } else { # that's a slide, create its entry my $entry ; # flexibility: # - the last \s might be omitted when there's no caption # - \s is facultative after TYP: at the beginning if ($line =~ m/^TXT:\s*(.+)\s+----\s*(?:\s(.*))?\s*$/) { # text slide $entry = create_nofile_entry ($TYPE_TEXT, undef, $1, $2) ; } elsif ($line =~ m/^LNK:\s*(.+)\s+----\s+(.+)\s+----\s*(?:\s(.*))?\s*$/) { # link slide $entry = create_nofile_entry ($TYPE_LINK, $1, $2, $3) ; } elsif ($line =~ m/^LNKNOSLIDE:\s*(.+)\s+----\s*(?:\s(.*))?\s*$/) { # direct link without slide $entry = create_nofile_entry ($TYPE_LINKNOSLIDE, $1, $2, undef) ; } elsif ($line =~ m/^DIR:\s*(.+)\s+----\s+(.+)\s+----\s*(?:\s(.*))?\s*$/) { # directory slide $entry = create_file_entry ($gallery, $TYPE_DIR, $1, $2, $3) ; } elsif ($line =~ m/^MVI:\s*(.+)\s+----\s+(.+)\s+----\s*(?:\s(.*))?\s*$/) { # movie slide $entry = create_file_entry ($gallery, $TYPE_MOVIE, $1, $2, $3) ; } elsif ($line =~ m/^FIL:\s*(.+)\s+----\s+(.+)\s+----\s*(?:\s(.*))?\s*$/) { # movie slide $entry = create_file_entry ($gallery, $TYPE_FILE, $1, $2, $3) ; } elsif ($line =~ m/^LINE/) { # horizontal line $entry = create_nofile_entry ($TYPE_LINE, undef, undef, undef) ; } elsif ($line =~ m/^BREAK/) { # thumbnail row break $entry = create_nofile_entry ($TYPE_BREAK, undef, undef, undef) ; } elsif ($line =~ m/^IMG:\s*(.+)\s+----\s*(?:\s(.*))?\s*$/ or $line =~ m/^(.+)\s+----\s*(?:\s(.*))?\s*$/) { # image slide (default) $entry = create_file_entry ($gallery, $TYPE_IMAGE, $1, undef, $2) ; } else { $messages->abort_percentage ; die "Unrecognized line #$. in captions file: \"$line\".\n" ; } # really add this entry push @entries, $entry if defined $entry ; } } $messages->update_percentage (tell CAP) ; } close CAP ; $messages->end_percentage () ; @{$gallery->{entries}} = @entries ; @{$gallery->{headers}} = @headers ; @{$gallery->{footers}} = @footers ; $gallery->{user_fields} = $user_fields ; } ####################################################################### # Links to add in a subgallery # revert a path into .. sub back_path { my $dir = shift ; $dir =~ s@([^/]+)@..@g ; return $dir ; } # store data about how a subgallery will be linked to parent/prev/next sub create_subgallery_family { my $entry = shift ; my $opts = shift ; my $nentries = shift ; my $prev = shift ; my $next = shift ; my $dir = $entry->{filename} ; my $revdir = back_path $dir ; # contents of links in the subgallery my $family = () ; # additional opts to generate the subgallery my $subdir_opts = {} ; # link to the parent gallery $subdir_opts->{parent_gallery_link} = 1 ; if ($opts->{link_subgalleries} and $nentries > 1) { # link to the previous gallery if ($prev->{type} == $TYPE_DIR) { $family->{prev_gallery_link_target} = "$revdir/$prev->{url}" ; $family->{prev_gallery_link_text} = $prev->{gallery_name} ; } # link to the next gallery if ($next->{type} == $TYPE_DIR) { $family->{next_gallery_link_target} = "$revdir/$next->{url}" ; $family->{next_gallery_link_text} = $next->{gallery_name} ; } } return ($subdir_opts, $family) ; } # convert family data from parent to the current gallery sub process_gallery_family { my $gallery = shift ; my $family = shift ; my $opts = shift ; if ($opts->{parent_gallery_link}) { $gallery->{parent_gallery_link_text} = $opts->{parent_gallery_link_text} unless defined $gallery->{parent_gallery_link_text} ; $gallery->{parent_gallery_link_target} = "../$opts->{index_filename}.$opts->{www_extension}" unless defined $gallery->{parent_gallery_link_target} ; } if (defined $family->{prev_gallery_link_text}) { $gallery->{prev_gallery_link_text} = $opts->{prev_gallery_link_text} . $family->{prev_gallery_link_text} unless defined $gallery->{prev_gallery_link_text} ; $gallery->{prev_gallery_link_target} = $family->{prev_gallery_link_target} unless defined $gallery->{prev_gallery_link_target} ; } if (defined $family->{next_gallery_link_text}) { $gallery->{next_gallery_link_text} = $opts->{next_gallery_link_text} . $family->{next_gallery_link_text} unless defined $gallery->{next_gallery_link_text} ; $gallery->{next_gallery_link_target} = $family->{next_gallery_link_target} unless defined $gallery->{next_gallery_link_target} ; } } ####################################################################### # Add recursion header and footer sub add_headers_footers { my $gallery = shift ; my @headers = @{$gallery->{headers}} ; my @footers = @{$gallery->{footers}} ; my $prev_text ; $prev_text = "<a href=\"$gallery->{prev_gallery_link_target}\">$gallery->{prev_gallery_link_text}</a>" if $gallery->{prev_gallery_link_target} ; my $next_text ; $next_text = "<div style=\"text-align: right;\"><a href=\"$gallery->{next_gallery_link_target}\">$gallery->{next_gallery_link_text}</a></div>" if $gallery->{next_gallery_link_target} ; my $parent_text ; $parent_text = "<a href=\"$gallery->{parent_gallery_link_target}\">$gallery->{parent_gallery_link_text}</a>" if $opts->{parent_gallery_link} ; # index, prev, next in headers unshift @headers, $next_text if $next_text ; unshift @headers, $prev_text if $prev_text ; unshift @headers, $parent_text if $parent_text ; # prev, next, index in footers push @footers, $prev_text if $prev_text ; push @footers, $next_text if $next_text ; push @footers, $parent_text if $parent_text ; @{$gallery->{headers}} = @headers ; @{$gallery->{footers}} = @footers ; } ####################################################################### # Precompute common fields to be inserted in the HTML pages sub precompute_common_html_fields { my $gallery = shift ; my @entries = @{$gallery->{entries}} ; my $common_fields = () ; # index title $common_fields->{"<!--TITLE-->"} = (defined $opts->{index_title} ? $opts->{index_title} : $opts->{index_title_default}) ; # index link text $common_fields->{"<!--INDEX-LINK-TEXT-->"} = $opts->{index_link_text} ; if ($opts->{index_link_image}) { if ($opts->{index_link_image_location}) { $common_fields->{"<!--INDEX-LINK-TEXT-->"} = "<img src=\"$opts->{index_link_image_location}\" " ."alt=\"$opts->{index_link_text}\" " ."class=\"image-link\" />" ; } else { $common_fields->{"<!--INDEX-LINK-TEXT-->"} = "<img src=\"$self->{local_llgal_dir}/" . (make_safe_url $opts->{index_link_image_filename}) ."\" " ."alt=\"$opts->{index_link_text}\" class=\"image-link\" />" ; } } # index file (ugly hack to also generate a title attribute right after the href) $common_fields->{"<!--INDEX-FILE-->"} = "$opts->{index_filename}.$opts->{www_extension}\" title=\"$opts->{over_index_link_text}" ; # css $common_fields->{"<!--CSS-->"} = "$self->{local_llgal_dir}/$opts->{css_filename}" ; if ($opts->{css_location}) { $common_fields->{"<!--CSS-->"} = $opts->{css_location} ; } # codeset $common_fields->{"LLGAL-CODESET"} = $opts->{codeset} ; # command line $common_fields->{"LLGAL-OPTIONS"} = $llgal_cmdline ; $common_fields->{"LLGAL-OPTIONS"} =~ s/\"/\'/g ; # credits text $common_fields->{"<!--CREDITS-->"} = $opts->{credits_text} ; # version $common_fields->{"<!--VERSION-->"} = $self->{version} ; $gallery->{common_fields} = $common_fields ; } ####################################################################### # Create the individual slide show files sub generate_slides { my $gallery = shift ; my @entries = @{$gallery->{entries}} ; # remove old webpages opendir DIR, $self->{destination_dir} ? $self->{destination_dir} : "./" ; # destination is empty for './' while ($_ = readdir DIR ) { if (/^$opts->{slide_filenameprefix}.*\.$opts->{www_extension}$/) { unlink "$self->{destination_dir}$_" or die "Failed to remove existing webpage '$_' ($!).\n" ; } } closedir DIR ; # create slides $messages->print ("Creating individual slides: ") ; $messages->init_percentage (scalar @entries) ; for (my $i = 0; $i < @entries; $i++) { my $entry = $entries[$i] ; next if defined $entry->{no_slide} ; if (not open(SW, ">$self->{destination_dir}$entry->{slide_filename}")) { $messages->abort_percentage ; die "Can't create slide file ($!).\n" ; } my $type = $entry->{type} ; ############################## # Precompute all fields first # titles my $SLIDE_TITLE = $entry->{title} ; # this slide style my $THIS_SLIDE_STYLE = "image-slide" ; if (!defined $entry->{scaled_url} and $type != $TYPE_IMAGE) { $THIS_SLIDE_STYLE = "text-slide" ; $THIS_SLIDE_STYLE .= "\" style=\"width: $opts->{text_slide_width}px; height: $opts->{text_slide_height}px;" unless $opts->{slide_dimensions_from_css} ; } # slide contents my $THIS_SLIDE ; if ($type == $TYPE_IMAGE) { # image slide if (defined $entry->{scaled_filename}) { if ($opts->{slide_link_to_full_image}) { # scaled image with link to the real image $THIS_SLIDE = "<a href=\"$entry->{url}\" " ."title=\"$opts->{over_scaled_text}$entry->{title} $entry->{dimstring}\">" ."<img src=\"$entry->{scaled_url}\" " ; $THIS_SLIDE .= "style=\"width: $entry->{scaled_xdim}px; height: $entry->{scaled_ydim}px;\" " unless $opts->{slide_dimensions_from_css} ; $THIS_SLIDE .= "alt=\"$opts->{alt_scaled_text}$entry->{title} $entry->{scaled_dimstring}\" />" ."</a>" ; } else { # scaled image without link to the real image $THIS_SLIDE = "<img src=\"$entry->{scaled_url}\" " ; $THIS_SLIDE .= "style=\"width: $entry->{scaled_xdim}px; height: $entry->{scaled_ydim}px;\" " unless $opts->{slide_dimensions_from_css} ; $THIS_SLIDE .= "alt=\"$opts->{alt_scaled_text}$entry->{title} $entry->{scaled_dimstring}\" />" ; } } else { # real image $THIS_SLIDE = "<img src=\"$entry->{url}\" " ; $THIS_SLIDE .= "style=\"width: $entry->{scaled_xdim}px; height: $entry->{scaled_ydim}px;\" " unless $opts->{slide_dimensions_from_css} ; $THIS_SLIDE .= "alt=\"$opts->{alt_full_text}$entry->{title} $entry->{dimstring}\" " ."title=\"$entry->{title} $entry->{dimstring}\" />" ; } } elsif ($entry->{scaled_url}) { # another type, with a user-given scaled image if ($type == $TYPE_TEXT) { # text with scaled image ? ok... $THIS_SLIDE = "<img src=\"$entry->{scaled_url}\" " ; $THIS_SLIDE .= "style=\"width: $entry->{scaled_xdim}px; height: $entry->{scaled_ydim}px;\" " unless $opts->{slide_dimensions_from_css} ; $THIS_SLIDE .= "title=\"$entry->{title} $entry->{dimstring}\" " ."alt=\"$entry->{linktext} $entry->{scaled_dimstring}\" />" ; } else { # another type with scaled image linking to the target $THIS_SLIDE = "<a href=\"$entry->{url}\" " ."title=\"$entry->{title} $entry->{dimstring}\">" ."<img src=\"$entry->{scaled_url}\" " ; $THIS_SLIDE .= "style=\"width: $entry->{scaled_xdim}px; height: $entry->{scaled_ydim}px;\" " unless $opts->{slide_dimensions_from_css} ; $THIS_SLIDE .= "alt=\"$entry->{linktext} $entry->{scaled_dimstring}\" />" ."</a>" ; } } elsif ($type == $TYPE_TEXT) { # text slide $THIS_SLIDE = $entry->{linktext} ; } else { # link-style slide $THIS_SLIDE = "<a href=\"$entry->{url}\" title=\"$entry->{title} $entry->{dimstring}\">$entry->{linktext}</a>" ; } # slide number, counter and total my $SLIDE_NUMBER = $entry->{counter_with_zeros} ; my $SLIDE_TOTAL = $gallery->{nslides} ; my $SLIDE_COUNTER = $opts->{slide_counter_format} ; $SLIDE_COUNTER =~ s/%n/$entry->{counter}/ ; $SLIDE_COUNTER =~ s/%0n/$SLIDE_NUMBER/ ; $SLIDE_COUNTER =~ s/%t/$SLIDE_TOTAL/ ; # caption my $IMAGE_CAPTION = $entry->{caption} . $SLIDE_COUNTER . "   $entry->{dimstring}" ; # previous slide my $PREV_SLIDE_LINK_TEXT = "" ; my $PREV_SLIDE = "" ; if ($entry->{prev} != -1) { my $prev = $entries[$entry->{prev}] ; if ($opts->{prev_slide_link_preview} and $prev->{thumb_url}) { $PREV_SLIDE_LINK_TEXT = "<img src=\"$prev->{thumb_url}\" " ."style=\"width: $prev->{thumb_xdim}px; height: $prev->{thumb_ydim}px;\" " ."alt=\"$opts->{prev_slide_link_text}\" />" ; } elsif ($opts->{prev_slide_link_image}) { if ($opts->{prev_slide_link_image_location}) { $PREV_SLIDE_LINK_TEXT = "<img src=\"$opts->{prev_slide_link_image_location}\" " ."alt=\"$opts->{prev_slide_link_text}\" class=\"image-link\" />" ; } else { $PREV_SLIDE_LINK_TEXT = "<img src=\"$self->{local_llgal_dir}/". (make_safe_url $opts->{prev_slide_link_image_filename}) ."\" " ."alt=\"$opts->{prev_slide_link_text}\" class=\"image-link\" />" ; } } else { $PREV_SLIDE_LINK_TEXT = $opts->{prev_slide_link_text} ; } $PREV_SLIDE = "$prev->{slide_url}\" title=\"$opts->{over_prev_slide_link_text}$prev->{title}" ; } # next slide my $NEXT_SLIDE_LINK_TEXT = "" ; my $NEXT_SLIDE = "" ; if ($entry->{next} != -1) { my $next = $entries[$entry->{next}] ; if ($opts->{next_slide_link_preview} and $next->{thumb_url}) { $NEXT_SLIDE_LINK_TEXT = "<img src=\"$next->{thumb_url}\" " ."style=\"width: $next->{thumb_xdim}px; height: $next->{thumb_ydim}px;\" " ."alt=\"$opts->{next_slide_link_text}\" />" ; } elsif ($opts->{next_slide_link_image}) { if ($opts->{next_slide_link_image_location}) { $NEXT_SLIDE_LINK_TEXT = "<img src=\"". $opts->{next_slide_link_image_location} ."\" " ."alt=\"$opts->{next_slide_link_text}\" class=\"image-link\" />" ; } else { $NEXT_SLIDE_LINK_TEXT = "<img src=\"$self->{local_llgal_dir}/". (make_safe_url $opts->{next_slide_link_image_filename}) ."\" " ."alt=\"$opts->{next_slide_link_text}\" class=\"image-link\" />" ; } } else { $NEXT_SLIDE_LINK_TEXT = $opts->{next_slide_link_text} ; } $NEXT_SLIDE = "$next->{slide_url}\" title=\"$opts->{over_next_slide_link_text}$next->{title}" ; } # exif information my $EXIF_TABLE = "" ; if ($type == $TYPE_IMAGE and (@{$opts->{show_exif_tags}} or $opts->{show_all_exif_tags})) { my $exif_infos = $entry->{exif_infos} ; foreach my $tag ($opts->{show_all_exif_tags} ? (keys %{$exif_infos}) : @{$opts->{show_exif_tags}}) { my $value = $exif_infos->{$tag} ; my $description = $opts->{exiftool}->GetDescription ($tag) ; $EXIF_TABLE .= "<tr><td class=\"exif-name\">$description</td>" ."<td class=\"exif-value\">$value</td></tr>\n" if defined $value ; } $EXIF_TABLE = "<table class=\"exif\">\n". $EXIF_TABLE ."</table>" ; } ################################# # Replace fields in the template my @slidetemplate_text_copy = @{$gallery->{slidetemplate_text}} ; # don't touch the original template for my $line (@slidetemplate_text_copy) { # user-defined fields my $user_fields = $gallery->{user_fields} ; foreach my $field (keys %{$user_fields}) { $line =~ s/$field/$user_fields->{$field}/g ; } # common fields my $common_fields = $gallery->{common_fields} ; foreach my $field (keys %{$common_fields}) { $line =~ s/$field/$common_fields->{$field}/g ; } # slide specific fields $line =~ s/<!--SLIDE-TITLE-->/$SLIDE_TITLE/g ; $line =~ s/<!--SLIDE-NUMBER-->/$SLIDE_NUMBER/g ; $line =~ s/<!--SLIDE-TOTAL-->/$SLIDE_TOTAL/g ; $line =~ s/<!--SLIDE-COUNTER-->/$SLIDE_COUNTER/g ; $line =~ s/<!--THIS-SLIDE-STYLE-->/$THIS_SLIDE_STYLE/g ; $line =~ s/<!--THIS-SLIDE-->/$THIS_SLIDE/ ; $line =~ s/<!--IMAGE-CAPTION-->/$IMAGE_CAPTION/g ; $line =~ s/<!--PREV-SLIDE-LINK-TEXT-->/$PREV_SLIDE_LINK_TEXT/g ; $line =~ s/<!--PREV-SLIDE-->/$PREV_SLIDE/g ; $line =~ s/<!--NEXT-SLIDE-LINK-TEXT-->/$NEXT_SLIDE_LINK_TEXT/g ; $line =~ s/<!--NEXT-SLIDE-->/$NEXT_SLIDE/g ; $line =~ s/<!--EXIF-TABLE-->/$EXIF_TABLE/ ; # only one replacement per line because earlier template parsing only detected one per line if ($line =~ /<!--EXIF-(.*)-->/) { my $name = $1; # EXIF-TABLE handled earlier, no need to ignore here my $exif_infos = $entry->{exif_infos} ; my $value = $exif_infos->{$name} ; $value = "" unless $value ; $line =~ s/<!--EXIF-$name-->/$value/ ; } # output the line print SW "$line" ; } close SW ; $messages->update_percentage ($i+1) ; } $messages->end_percentage () ; } ####################################################################### # Creating the index file sub generate_index { my $gallery = shift ; my @entries = @{$gallery->{entries}} ; my @headers = @{$gallery->{headers}} ; my @footers = @{$gallery->{footers}} ; my $indextemplate = $gallery->{indextemplate}; # open the template and the destination $messages->print ("Creating the $opts->{index_filename}.$opts->{www_extension} file: ") ; open(IXR, "$indextemplate") or die "Can't open the index template file '$indextemplate' ($!).\n" ; open(IXW, ">$self->{destination_dir}$opts->{index_filename}.$opts->{www_extension}") or die "Can't create main $opts->{index_filename}.$opts->{www_extension} file ($!).\n" ; # headers my $line ; while (defined($line = <IXR>)) { # stop at <!-- ********** --> last if $line =~ m/\*{10}/ ; if ($line =~ m/<!--HEADERS-->/) { foreach my $header (@headers) { print IXW " <div class=\"header\">" . $header . "</div>\n" ; } } else { # user-defined fields my $user_fields = $gallery->{user_fields} ; foreach my $field (keys %{$user_fields}) { $line =~ s/$field/$user_fields->{$field}/g ; } # common fields my $common_fields = $gallery->{common_fields} ; foreach my $field (keys %{$common_fields}) { $line =~ s/$field/$common_fields->{$field}/g ; } print IXW "$line" ; } } print IXW "\n" ; # output thumbnails my $forced_width_warning = 0 ; my $i = 0 ; $messages->init_percentage (scalar @entries) ; while ($i < scalar @entries) { my $entry = $entries[$i] ; my $type = $entry->{type} ; if ($type == $TYPE_LINE or $type == $TYPE_BREAK) { if ($type == $TYPE_LINE) { # output a horizontal line print IXW "<hr class=\"index\" />\n" ; } # next line, next entry $messages->update_percentage ($i+1) ; $i++ ; next ; } if ($entry->{no_thumb}) { # output a line with this text print IXW "<div class=\"header\">" ; if ($type == $TYPE_TEXT) { if ($opts->{make_no_slides}) { print IXW $entry->{linktext} ; } else { print IXW "<a href=\"$entry->{slide_url}\" title=\"$entry->{title} $entry->{dimstring}\">$entry->{linktext}</a>" ; } } else { print IXW "<a href=\"$entry->{url}\" title=\"$entry->{title} $entry->{dimstring}\">$entry->{linktext}</a>" ; } print IXW "</div>\n" ; # next line, next entry $messages->update_percentage ($i+1) ; $i++ ; next ; } # output a row of thumbnail my $width = $entries[$i]->{thumb_xdim} + $opts->{index_cellpadding} ; my $num = 1 ; # figure out how many entries to put on this row while ($i + $num < @entries) { # stop if this is listed instead of having a slide last if defined $entries[$i+$num]->{no_thumb} ; # stop if there's too much thumbnail on this row last if $opts->{thumbnails_per_row} and $num + 1 > $opts->{thumbnails_per_row} ; # stop if these thumbnail are too large my $box_width = $entries[$i+$num]->{thumb_xdim} ; $box_width = $opts->{thumbnail_width_max} if $opts->{thumbnail_width_max} ; last if $opts->{pixels_per_row} and $width + $box_width + $opts->{index_cellpadding} > $opts->{pixels_per_row} ; # compute the new num and width $width += $box_width + $opts->{index_cellpadding} ; $num++ ; } # check whether a single thumbnail was already too large if ($opts->{pixels_per_row} > 0 and $width > $opts->{pixels_per_row}) { $forced_width_warning++ ; } # Table header if ($opts->{show_film_effect}) { print IXW "<table class=\"index with-tile\" style=\"border-spacing: ", $opts->{index_cellpadding}, "px 0px;\">\n" ; } else { print IXW "<table class=\"index\" style=\"border-spacing: ", $opts->{index_cellpadding}, "px 0px;\">\n" ; } # Row header # include the image to force the height of the line. we could do it in the css but IE css support sucks a lot print IXW " <tr><td class=\"tiled\" colspan=\"". ($num+2) ."\">" ."<img src=\"$self->{local_llgal_dir}/$opts->{filmtile_filename}\" alt=\"$opts->{alt_film_tile_text}\" />" ."</td></tr>\n" if $opts->{show_film_effect} ; print IXW " <tr>\n" ; print IXW " <td class=\"thumb\"> </td>\n" if $opts->{show_film_effect} ; # Actual row of thumbnails for (my $j = 0; $j < $num; $j++) { my $entry = $entries[$i+$j] ; my $type = $entry->{type} ; my $title ; my $linktext ; my $thumb_width = $entry->{thumb_xdim} ; my $thumb_height = $entry->{thumb_ydim} ; my $box_width = $thumb_width; my $box_height = $thumb_height; # if a thumbnail width max is defined, force the box to its width $box_width = $opts->{thumbnail_width_max} if $opts->{thumbnail_width_max} ; if ($type == $TYPE_IMAGE) { $linktext = "$opts->{alt_thumbnail_text}$entry->{title}" ; $title = "$opts->{over_thumbnail_text}$entry->{title}" ; } else { $title = $entry->{title} ; $linktext = $entry->{linktext} ; } my $link = $entry->{url} ; # if making slide and not pointing to target, the thumbnail points to the slide if (!$opts->{make_no_slides} and !$entry->{no_slide} and ( ($type == $TYPE_IMAGE) or ($type == $TYPE_MOVIE and !$opts->{MVI_link_to_target}) or ($type == $TYPE_FILE and !$opts->{FIL_link_to_target}) or ($type == $TYPE_LINK and !$opts->{LNK_link_to_target}) or ($type == $TYPE_DIR and !$opts->{DIR_link_to_target}) or ($type == $TYPE_TEXT) ) ) { $link = $entry->{slide_url} ; } if ($entry->{thumb_url}) { # either IMG, or with a user-given thumbnail print IXW " <td class=\"thumb\" "; print IXW "style=\"width: ${box_width}px; height: ${box_height}px;\" " unless $opts->{thumbnails_dimensions_from_css} ; print IXW ">\n" ; if ($type == $TYPE_TEXT and $opts->{make_no_slides}) { # thumbnail without any link print IXW " <img src=\"$entry->{thumb_url}\" " ."title=\"$title $entry->{scaled_dimstring}\" "; print IXW "style=\"width: ${thumb_width}px; height: ${thumb_height}px;\" " unless $opts->{thumbnails_dimensions_from_css} ; print IXW "alt=\"$linktext $entry->{thumb_dimstring}\" />\n" ; } else { # thumbnail linking to the slide print IXW " <a href=\"$link\" " ."title=\"$title $entry->{scaled_dimstring}\">\n" ; print IXW " <img src=\"$entry->{thumb_url}\" "; print IXW "style=\"width: ${thumb_width}px; height: ${thumb_height}px;\" " unless $opts->{thumbnails_dimensions_from_css} ; print IXW "alt=\"$linktext $entry->{thumb_dimstring}\" />\n" ; print IXW " </a>" ; } print IXW " </td>\n" ; } else { # not IMG, without thumbnail print IXW " <td class=\"text-thumb\" "; print IXW "style=\"width: ${box_width}px; height: ${box_height}px;\" " unless $opts->{thumbnails_dimensions_from_css} ; print IXW ">\n"; if ($type == $TYPE_TEXT and $opts->{make_no_slides}) { # thumbnail with basic text and that's it print IXW " $entry->{linktext}\n" ; } else { # thumbnail directly linking to the target print IXW " <a href=\"$link\" title=\"$title $entry->{dimstring}\">$entry->{linktext}</a>\n" ; } print IXW " </td>\n" ; } $messages->update_percentage ($i+$j+1) ; } # Row footer print IXW " <td class=\"thumb\"> </td>\n" if $opts->{show_film_effect} ; print IXW " </tr>\n" ; print IXW " <tr><td class=\"tiled\" colspan=\"". ($num+2) ."\">" ."<img src=\"$self->{local_llgal_dir}/$opts->{filmtile_filename}\" alt=\"$opts->{alt_film_tile_text}\" />" ."</td></tr>\n" if $opts->{show_film_effect} ; # Dimensions and filesizes if ($opts->{show_dimensions} or $opts->{show_size}) { print IXW " <tr>\n" ; print IXW " <td> </td>\n" if $opts->{show_film_effect} ; for (my $j = 0; $j < $num; $j++) { my $entry = $entries[$i+$j] ; print IXW " <td class=\"thumb-dim\">$entry->{scaled_dimstring}</td>\n" ; } print IXW " <td> </td>\n" if $opts->{show_film_effect} ; print IXW " </tr>\n" ; } # Write image captions under images if option -u is given if ($opts->{show_caption_under_thumbnails}) { print IXW " <tr>\n" ; print IXW "<td> </td>\n" if $opts->{show_film_effect} ; for (my $j = 0; $j < $num; $j++) { my $entry = $entries[$i+$j] ; print IXW " <td class=\"thumb-caption\">$entry->{caption}</td>\n" ; } print IXW " </tr>\n" ; } # Table footer print IXW "</table>\n" ; $i += $num ; } # search next <!-- ********** --> while (defined($line = <IXR>)) { last if $line =~ m/\*{10}/ ; } print IXW "\n"; # footers while (defined ($line = <IXR>)) { if ($line =~ m/<!--FOOTERS-->/) { foreach my $footer (@footers) { print IXW " <div class=\"footer\">" . $footer . "</div>\n" ; } } else { # user-defined fields my $user_fields = $gallery->{user_fields} ; foreach my $field (keys %{$user_fields}) { $line =~ s/$field/$user_fields->{$field}/g ; } # common fields my $common_fields = $gallery->{common_fields} ; foreach my $field (keys %{$common_fields}) { $line =~ s/$field/$common_fields->{$field}/g ; } print IXW "$line" ; } } close IXW ; close IXR ; $messages->end_percentage () ; $messages->warning ("Row width max ($opts->{pixels_per_row}) too low for one single thumbnail. " . "Forced $forced_width_warning time". ($forced_width_warning>1?"s":"") .".") if $forced_width_warning ; } ####################################################################### # If --www was invoked make all files world-readable at the END sub make_readable { my $file = shift ; my @stats = stat $file ; if (not scalar @stats) { $messages->warning ("Failed to get mode of file '$file' ($!).\n") ; } else { my $perm = $stats[2] & 07777 ; if (($perm & 0444) != 0444) { chmod ($perm | 0444, $file) or $messages->warning ("Failed to set readable attributes to file '$file' ($!).\n") ; } } } sub make_readable_and_traversable { my $file = shift ; my @stats = stat $file ; if (not scalar @stats) { $messages->warning ("Failed to get mode of file '$file' ($!).\n") ; } else { my $perm = $stats[2] & 07777 ; if (($perm & 0555) != 0555) { chmod ($perm | 0555, $file) or $messages->warning ("Failed to set readable and executable attributes to file '$file' ($!).\n") ; } } } sub make_www_rights { my $gallery = shift ; my $opts = shift ; my @entries = @{$gallery->{entries}} ; $messages->print ("Making all llgal files world-readable for WWW publishing.\n") ; # index make_readable "$self->{destination_dir}$opts->{index_filename}.$opts->{www_extension}" ; # .llgal make_readable_and_traversable "$self->{destination_dir}$self->{local_llgal_dir}" ; # css make_readable "$self->{destination_dir}$self->{local_llgal_dir}/$opts->{css_filename}" ; # filmtile make_readable "$self->{destination_dir}$self->{local_llgal_dir}/$opts->{filmtile_filename}" if $opts->{show_film_effect} ; # index link image make_readable "$self->{destination_dir}$self->{local_llgal_dir}/$opts->{index_link_image_filename}" if $opts->{index_link_image} ; # prev slide link image make_readable "$self->{destination_dir}$self->{local_llgal_dir}/$opts->{prev_slide_link_image_filename}" if $opts->{prev_slide_link_image} and ! $opts->{prev_slide_link_preview}; # next slide link image make_readable "$self->{destination_dir}$self->{local_llgal_dir}/$opts->{next_slide_link_image_filename}" if $opts->{next_slide_link_image} and ! $opts->{next_slide_link_preview} ; # entries that have a slide foreach my $entry (@entries) { my $type = $entry->{type} ; # target if ($type == $TYPE_DIR) { make_readable_and_traversable "$self->{destination_dir}$entry->{filename}" ; } elsif ($type == $TYPE_IMAGE or $type == $TYPE_MOVIE or $type == $TYPE_FILE) { make_readable "$self->{destination_dir}$entry->{filename}" ; } # slide make_readable "$self->{destination_dir}$entry->{slide_filename}" if ! $opts->{make_no_slides} and ! defined $entry->{no_slide} ; # thumbnail make_readable "$self->{destination_dir}$entry->{thumb_filename}" if ($type == $TYPE_IMAGE or $entry->{thumb_url}) and !defined $entry->{no_thumb} ; # scaled image make_readable "$self->{destination_dir}$entry->{scaled_filename}" if ($type == $TYPE_IMAGE or $entry->{scaled_url}) and ($opts->{slide_width_max} > 0 or $opts->{slide_height_max} > 0) and !$opts->{make_no_slides} ; } } ####################################################################### # Main code # evaluate generic configuration files my $generic_opts = {} ; # system-wide configuration file Llgal::Config::merge_opts ($generic_opts, Llgal::Config::parse_generic_config_file ($self, "$self->{llgal_config_dir}/$self->{generic_configuration_filename}")) ; # user-wide configuration file Llgal::Config::merge_opts ($generic_opts, Llgal::Config::parse_generic_config_file ($self, "$self->{user_share_dir}/$self->{generic_configuration_filename}")) ; # early configuration ends here $self->{early_configuration} = 0 ; # parse cmdline now but DO NOT MERGE now my $cmdline_opts = Llgal::Config::parse_cmdline_options ($self) ; # basic special behaviors may be done here Llgal::Config::die_usage ($self) if $self->{help_asked} ; die "This is llgal version $self->{version}.\n" if $self->{version_asked} ; # the local llgal directory name is now fixed # we may check the destination directory check_destination ; # forward declaration sub main_process ; # recursive call, after saving globals sub subdir_process { my $dir = shift ; my $subdir_opts = shift ; my $subdir_family = shift ; $messages->print ("Entering subdirectory '$dir'...\n") ; # save context my $saved_destination_dir = $self->{destination_dir}; my $saved_destination_string = $destination_string; my $saved_opts = $opts ; my $saved_opts_without_defaults = $opts_without_defaults ; my $saved_messages = $messages->copy () ; $messages->indent () ; # setup new gallery context $self->{destination_dir} .= $dir."/" ; # recursive call my $subgallery = main_process $subdir_opts, $subdir_family ; # restore context $self->{destination_dir} = $saved_destination_dir; $destination_string = $saved_destination_string; $opts = $saved_opts ; $opts_without_defaults = $saved_opts_without_defaults ; $messages = $saved_messages ; $self->{messages} = $messages ; $messages->print ("Leaving subdirectory '$dir'.\n") ; print "\n" ; return $subgallery ; } sub recurse_into_gallery { my $gallery = shift ; my $opts = shift ; # list subdir entries my @entries = @{$gallery->{entries}} ; # process recursively print "\n" if @entries ; for (my $i = 0; $i < @entries; $i++) { my $entry = $entries[$i] ; next if $entry->{type} != $TYPE_DIR ; my $prev = $entries[$entry->{prev}] ; my $next = $entries[$entry->{next}] ; my ($subdir_opts, $subdir_family) = create_subgallery_family $entry, $opts, (scalar @entries), $prev, $next ; my $subgallery = subdir_process $entry->{filename}, $subdir_opts, $subdir_family ; $entry->{gallery} = $subgallery ; } } sub main_process { my $recursive_opts = shift ; my $family = shift ; # setup the destination directory setup_destination ; # add recursive specific opts first, so that they may be locally overridden $opts_without_defaults = Llgal::Config::merge_opts_into ($generic_opts, $recursive_opts) ; # evaluate gallery specific configuration, without modifying $generic_opts Llgal::Config::merge_opts ($opts_without_defaults, Llgal::Config::parse_generic_config_file ($self, "$self->{destination_dir}$self->{local_llgal_dir}/$self->{generic_configuration_filename}")) ; # DO NOT MOVE THIS LINE BEFORE CONFIG FILE PARSING # parse command line options Llgal::Config::merge_opts ($opts_without_defaults, $cmdline_opts) ; # set the locale before getting the defaults if (defined $opts_without_defaults->{language}) { $messages->warning ("The LANGUAGE environment variable ($ENV{LANGUAGE}) overrides your language configuration ($opts_without_defaults->{language}).") if exists $ENV{LANGUAGE} and $ENV{LANGUAGE} ; setlocale (LC_ALL, $opts_without_defaults->{language}) ; } # set defaults values for all uninitialized values $opts = Llgal::Config::add_defaults ($opts_without_defaults) ; # restore the current locale setlocale (LC_ALL, "") ; if ($self->{clean_asked} or $self->{cleanall_asked} or $self->{give_templates}) { # complex special behaviors that need full configuration, and recurse in all subdirectories if ($self->{clean_asked} or $self->{cleanall_asked}) { # clean my $cleanall = shift ; $messages->delay_warnings () ; clean_files $self->{cleanall_asked} ; $messages->show_delayed_warnings () ; } elsif ($self->{give_templates}) { # give templates my $destdir = $self->{give_templates} ; $destdir = $self->{local_llgal_dir} if $destdir eq "local" ; $destdir = $self->{user_share_dir} if $destdir eq "user" ; Llgal::Templates::give_templates ($self, $opts, $destdir) ; $messages->print ("You may now edit templates in $destdir and generate new galleries.\n") ; $messages->print ("You may also remove any template that you do not want to modify.\n") ; } # recursive in ALL subdirectories if ($opts->{recursive}) { # list subdirs opendir DIR, $self->{destination_dir} ? $self->{destination_dir} : "./" ; # destination is empty for './' my @dir_entries = () ; while (my $dir = readdir DIR) { push @dir_entries, $dir if $dir =~ m/^[^.]/ and -d "$self->{destination_dir}$dir" ; } closedir DIR ; # process recursively print "\n" if @dir_entries ; map { subdir_process $_, {} } @dir_entries ; } } elsif ($self->{generate_captions}) { # generate captions and recurse in entries only Llgal::Config::prepare_captions_variables ($self, $opts) ; my $gallery = init_gallery () ; my @entries = get_entries $gallery, $opts ; @{$gallery->{entries}} = @entries ; finalize_entries $gallery, $opts ; process_gallery_family $gallery, $family, $opts ; generate_captions_entries $gallery, $opts ; $messages->print ("Now edit the $self->{destination_dir}$self->{local_llgal_dir}/$opts->{captions_filename} file to your liking and run llgal!\n") ; recurse_into_gallery $gallery, $opts if $opts->{recursive} ; } else { # main gallery creation and recurse in entries only Llgal::Config::prepare_gallery_variables ($self, $opts) ; my $gallery = init_gallery () ; # find the indextemplate $gallery->{indextemplate} = (Llgal::Templates::find_template_file ($self, $opts, $opts->{indextemplate_filename}, 1)) . "/$opts->{indextemplate_filename}" ; $messages->print ("Using '".$gallery->{indextemplate}."' as HTML index template.\n") ; if (!$opts->{make_no_slides}) { # find the slidetemplate my $slidetemplate = (Llgal::Templates::find_template_file ($self, $opts, $opts->{slidetemplate_filename}, 1)) . "/$opts->{slidetemplate_filename}" ; $messages->print ("Using '$slidetemplate' as HTML slide template.\n") ; # keep the slidetemplate in memory instead of always reopening it open(SR,"$slidetemplate") or die "Can't open the slide template file '$slidetemplate' ($!).\n" ; @{$gallery->{slidetemplate_text}} = <SR> ; close SR ; # list Exif tags needed by the template. # only one pattern per line is detected, other are ignored. foreach my $line (@{$gallery->{slidetemplate_text}}) { if ($line =~ /<!--EXIF-(.*)-->/) { if ($1 ne "TABLE") { # TABLE is llgal-reserved, unused in EXIF push (@{$gallery->{template_exif_tags_list}}, $1); } } } } if (-e "$self->{destination_dir}$self->{local_llgal_dir}/$opts->{captions_filename}") { # generate the gallery using the caption file read_captions_file $gallery ; fill_entries $gallery ; $messages->print ("Found ". (scalar @{$gallery->{entries}}) ." entries in the captions file.\n") ; } else { # generate the gallery from scratch @{$gallery->{entries}} = get_entries $gallery, $opts ; fill_entries $gallery ; $messages->print ("Found ". (scalar @{$gallery->{entries}}) ." entries in $destination_string\n") ; } finalize_entries $gallery, $opts ; process_gallery_family $gallery, $family, $opts ; add_headers_footers $gallery ; precompute_common_html_fields $gallery ; if ($opts->{make_no_slides}) { $messages->print ("Linking thumbnails directly to image files... Making no html slides.\n") ; } else { generate_slides $gallery ; } generate_index $gallery ; Llgal::Templates::get_llgal_files ($self, $opts) ; $messages->delay_warnings () ; make_www_rights $gallery, $opts if $opts->{www_access_rights} ; $messages->show_delayed_warnings () ; # generate a local config for this gallery if (defined $self->{generate_config} and $self->{generate_config} eq "local") { Llgal::Config::generate_config ($self, "$self->{destination_dir}$self->{local_llgal_dir}/$self->{generic_configuration_filename}", $opts_without_defaults) ; } recurse_into_gallery $gallery, $opts if $opts->{recursive} ; return $gallery ; } } # generate main gallery my $root_gallery = main_process {}, {} ; # only generate a config once if (defined $self->{generate_config} and not $self->{generate_config} eq "local") { Llgal::Config::generate_config ($self, $self->{generate_config}, $opts_without_defaults) ; } # Indent style for emacs # Local Variables: # perl-indent-level: 4 # tab-width: 8 # indent-tabs-mode: t # End: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������llgal-llgal-0.13.19/llgalrc.5�����������������������������������������������������������������������0000664�0000000�0000000�00000042264�13143122354�0015565�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" Process this file with .\" groff -man -Tascii foo.1 .\" .TH llgalrc 5 "NOVEMBER 2006" .SH NAME llgalrc \- Configuration file for llgal .SH Names of generic llgal files: .I captions_header_filename = \fI"filename" .RS Name of the captions header file that is inserted at the beginning of generated captions files. Default is .BR captions.header . .RE .I css_filename = \fI"filename" .RS Name of the CSS file. Default is \fBllgal.css\fR. .RE .I filmtile_filename = \fI"filename" .RS Name of the film tile image. Default is \fBtile.png\fR. Note that it must match the one that is used in the CSS file. .RE .I index_link_image_filename = \fI"filename" .RS Change image name for link to the index. Default is \fBindex.png\fR. .RE .I next_slide_link_image_filename = \fI"filename" .RS Change image name for link to the next slide. Default is \fBnext.png\fR. .RE .I previous_slide_link_image_filename = \fI"filename" .RS Change image name for link to the previous slide. Default is \fBprev.png\fR. .RE .I indextemplate_filename = \fI"filename" .RS Name of the HTML index template. Default is \fBindextemplate.html\fR. .RE .I slidetemplate_filename = \fI"filename" .RS Name of the HTML slide template. Default is \fBslidetemplate.html\fR. .RE .SH Location of llgal files if available on the web .I css_location = \fI"url" .RS The location of the CSS on the web instead of a local one .RB [ "--uc <url>" ]. If ending with a slash, .I css_filename will be appended. .RE .I filmtile_location = \fI"url" .RS The location of the filmtile image on the web instead of a local one .RB [ "--ui <url>" ]. If ending with a slash, .I filmtile_filename will be appended. .RE .I index_link_image_location = \fI"url" .RS The location of the index link image on the web instead of a local one .RB [ "--ui <url>" ]. If ending with a slash, .I index_link_image_filename will be appended. .RE .I prev_slide_link_image_location = \fI"url" .RS The location of the prev slide link image on the web instead of a local one .RB [ "--ui <url>" ]. If ending with a slash, .I prev_slide_link_image_filename will be appended. .RE .I next_slide_link_image_location = \fI"url" .RS The location of the next slide link image on the web instead of a local one .RB [ "--ui <url>" ]. If ending with a slash, .I next_slide_link_image_filename will be appended. .RE .SH Location and name of generated files: .I local_llgal_dir = \fI"subdirectory name" .RS The name of the subdirectory where llgal generated files will be stored. This option is only available in system- and user-wide configuration files. Default is .BR .llgal/ . .RE .I index_filename = \fI"filename" .RS Name of the generated index file .RB [ "-i <s>" ]. Default is .BR index . .RE .I slide_filenameprefix = \fI"filename prefix" .RS Prefix of generated HTML slide filenames. Default is \fB"slide_"\fR. Note that this prefix is used to decide what HTML to delete when .B --clean is passed. Setting this option to an empty string will make llgal remove .I all HTML files. .RE .I scaled_image_filenameprefix = \fI"filename prefix" .RS Prefix used to determine slide-image filenames from original images (in case of .BR --sx " or " --sy ). Default is \fB"scaled_"\fR. .RE .I thumbnail_image_filenameprefix = \fI"filename prefix" .RS Prefix used to determine thumbnail filenames from original images. Default is \fB"thumb_"\fR. .RE .I captions_filename = \fI"filename" .RS Name of the caption file that will be generated when llgal is called with .BR --gc , or will be automatically used if it exists to generate slide captions. Default is \fB"captions"\fR. .RE .I user_scaled_image_filenameprefix = \fI"filename prefix" .RS Additional prefix of user-provided scaled images. Default is \fBmy\fR. .RE .I user_thumbnail_image_filenameprefix = \fI"filename prefix" .RS Additional prefix of user-provided thumbnails. Default is \fBmy\fR. .RE .I path_separator_replacement = \fI"char" .RS Character to use to replace / in the thumbnail/scaled of subdir images. Default is \fB@\fR. .RE .SH Index: .I index_cellpadding = <pixels> .RS Cellpadding in the index table .RB [ "-p <n>" ]. Default is .BR 3 . .RE .I list_links = <0/1> .RS Display links and text as regular text instead of thumbnails in the main gallery thumbnail index .RB [ -L ]. Default is .BR 0 " (" disabled ). .RE .I pixels_per_row = <pixels> .RS Pixels per row of thumbnails in index .RB [ "-wx <n>" ]. Default is .BR 0 " (" unlimited ). .RE .I thumbnails_per_row = <pixels> .RS Thumbnails per row in index .RB [ "-w <n>" ]. Default is .BR 5 . .RE .I thumbnails_dimensions_from_css = <0/1> .RS Do not output any absolute thumbnails size in HTML code and assume the CSS style sheet will take care of it (in table.index [td.thumb [img]]). Default is .BR 0 " (" disabled ). .RE .I thumbnail_height_max = <pixels> .RS Maximal height of thumbnails .RB [ "--ty <n>" ]. Default is .BR 75 . Changing this value does not affect the maximal width (see .IR thumbnail_width_max ). .RE .I thumbnail_width_max = <pixels> .RS Maximal width of thumbnails .RB [ "--tx <n> "]. If .B 0 is used, the width is unlimited. If not .BR 0 , all thumbnails are padded to the given width. Default is .BR 113 . Changing this value does not affect the maximal height (see .IR thumbnail_height_max ). .RE .I show_caption_under_thumbnails = <0/1> .RS Write captions under thumbnails .RB [ -u ]. Default is .BR 0 " (" disabled ). .RE .I show_film_effect = <0/1> .RS Show film effect .RB [ --fe ]. Default is .BR 0 " (" disabled ). .RE .I MVI_link_to_target = <0/1> .RS Make movie thumbnails links point to the movie instead of the corresponding slide. Default is .BR 1 " (" "link to the movie" ")." .RE .I FIL_link_to_target = <0/1> .RS Make file thumbnails links point to the file instead of the corresponding slide. Default is .BR 1 " (" "link to the file" ")." .RE .I DIR_link_to_target = <0/1> .RS Make directory thumbnails links point to the movie instead of the corresponding slide. Default is .BR 1 " (" "link to the directory" ")." .RE .I LNK_link_to_target = <0/1> .RS Make link thumbnails point to the link instead of the corresponding slide. It is similar to using .I LNKNOSLIDE: entries instead of .IR LNK: . Default is .BR 1 " (" "link to the link target" ")." .RE .SH Slides: .I make_no_slides = <0/1> .RS Make no slides .RB [ -s ]. Default is .BR 0 " (" "make slides" ). .RE .I make_slide_filename_from_filename = <0/1> .RS Use filenames as slide filenames .RB [ -n ]. Default is .BR 0 " (" disabled ). .RE .I make_slide_filename_from_extension = <0/1> .RS Also use extension in slide filename when generated from filename. Default is .BR 0 " (" disabled ). .RE .I slide_dimensions_from_css = <0/1> .RS Do not output any absolute image size in the HTML code and assume the CSS style sheet will take care of it (in table.slide td.image-slide img). Default is .BR 0 " (" disabled ). .RE .I slide_width_max = <pixels> .RS Maximal width of slides .RB [ "--sx <n>" ]. Default is .BR 0 " (" unlimited ). .RE .I slide_height_max = <pixels> .RS Maximal height of slides .RB [ "--sy <n>" ]. Default is .BR 0 " (" unlimited ). .RE .I text_slide_width = <pixels> .RS Default width of text slides. Default is .BR 400 . .RE .I text_slide_height = <pixels> .RS Default height of text slides. Default is .BR 300 . .RE .I index_link_image = <0/1> .RS Use an image instead of a text label for the link to the index .RB [ --li ]. Default is .BR 0 " (" disabled ). .RE .I prev_slide_link_image = <0/1> .RS Use an image instead of a text label for the link to the previous slide .RB [ --li ]. Default is .BR 0 " (" disabled ). .RE .I next_slide_link_image = <0/1> .RS Use an image instead of a text label for the link to the next slide .RB [ --li ]. Default is .BR 0 " (" disabled ). .RE .I prev_slide_link_preview = <0/1> .RS Use a thumbnail preview instead of a text label for the link to the previous slide .RB [ --lt ]. Default is .BR 0 " (" disabled ). .RE .I next_slide_link_preview = <0/1> .RS Use a thumbnail preview instead of a text label for the link to the next slide .RB [ --lt ]. Default is .BR 0 " (" disabled ). .RE .I link_between_last_and_first = <0/1> .RS Generate links between last and first slides or galleries. Default is .BR 1 " (" enabled ). .RE .I make_slide_title_from_caption = <0/1> .RS Generate slide titles from captions .RB [ -k ]. Default is .BR 0 " (" disabled ). .RE .I show_exif_tags = <tag1,tag2,...> .RS Display a table of EXIF tags under each image slide .RB [ --exif ]. The tags are given with their name in .B exiftool -list and separated with a comma. .RE .I show_all_exif_tags = <0/1> .RS Display a table of all available EXIF tags under each image slide .RB [ --exif ]. .RE .I slide_link_to_full_image = <0/1> .RS Link scaled image in slides to full unscaled images .RB [ --nf ]. Default is .BR 1 " (" enabled ). .RE .SH Captions: .I captions_removal_line = \fI"string" .RS This line will be added to the caption file llgal will generate when called with .BR --gc . If the user doesn't want llgal to remove this caption file when called with .BR --clean , he just needs to remove this line from the file. Default is \fB"REMOVE THIS LINE IF LLGAL SHOULD NOT REMOVE THIS FILE"\fR. .RE .I make_caption_from_filename = <0/1> .RS Generate captions from filenames. The extension is removed, except for directories. .RB [ --cf ]. Default is .BR 0 " (" disabled ). .RE .I make_caption_from_extension = <0/1> .RS Generate captions from filenames with their extension. .BR 0 " (" disabled ). .RE .I make_caption_from_image_comment = ",-separated strings of +-separated strings" .RS Generate captions from image comment tag .RB [ --cc ]. Default is \fB""\fR .RB ( disabled ). .RE .I make_caption_from_image_timestamp = <0/1> .RS Add image timestamp to generated captions .RB [ --ct ]. Default is .BR 0 " (" disabled ). .RE .I show_dimensions = <0/1> .RS Show image dimensions .RB [ -a ", " -ad ]. Default is .BR 0 " (" disabled ). .RE .I show_size = <0/1> .RS Show file sizes .RB [ -a ", " -as ]. Default is .BR 0 " (" disabled ). .RE .I slide_counter_format = \fI"format" .RS Change the format of the counter on the slides. \fB%n\fR is replaced with the slide number, \fB%0n\fR gets leading zeros, and \fB%t\fR is replaced with the number of slides. Default is \fB"   (%0n/%t)"\fR. Slide counter may be disabled by setting to an empty string .RB [ --nc ]. .RE .SH Text: .I index_title_default = \fI"string" .RS Default title of the gallery. May be overridden with [\-\-title <s>] or TITLE: in the captions file. Default is \fB"Index of pictures"\fR. .RE .I parent_gallery_link_text = \fI"string" .RS Label of the link to the parent directory. Default is \fB"Back to parent gallery"\fR. .RE .I prev_gallery_link_text = \fI"string" .RS Label of the link to the previous gallery. Default is \fB"Previous gallery "\fR. .RE .I next_gallery_link_text = \fI"string" .RS Label of the link to the next gallery. Default is \fB"Next gallery "\fR. .RE .I index_link_text = \fI"string" .RS Label of the link from a slide to the index. Default is \fB"Index"\fR. .RE .I prev_slide_link_text = \fI"string" .RS Label of the link from a slide to the prev one. Default is \fB"Prev>>"\fR. .RE .I next_slide_link_text = \fI"string" .RS Label of the link from a slide to the next one. Default is \fB"Next>>"\fR. .RE .I MVI_link_text = \fI"string" .RS Text prefixing the filename when generating link text for movies without a captions file. Default is \fB"Open movie "\fR. .RE .I FIL_link_text = \fI"string" .RS Text prefixing the filename when generating link text for files without a captions file. Default is \fB"Download file "\fR. .RE .I DIR_link_text = \fI"string" .RS Text prefixing the filename when generating link text for directories without a captions file. Default is \fB"Open subgallery "\fR. .RE .I alt_full_text = \fI"string" .RS Text shown as an image alternative for full-size images in slides. Default is \fB""\fR. .RE .I alt_scaled_text = \fI"string" .RS Text shown as an image alternative for scaled images in slides. Default is \fB"Scaled image "\fR. .RE .I alt_thumbnail_text = \fI"string" .RS Text shown as an image alternative for thumbnails in the index. Default is \fB"Thumbnail "\fR. .RE .I alt_film_tile_text = \fI"string" .RS Text shown as an image alternative for the film tile in the index. Default is \fB"Film Tile"\fR. .RE .I over_scaled_text = \fI"string" .RS Text shown when the mouse pointer is over a scaled image in a slide. Default is \fB"Click to see full size "\fR. .RE .I over_thumbnail_text = \fI"string" .RS Text shown when the mouse pointer is over a thumbnail. Default is \fB"Click to enlarge "\fR. .RE .I over_index_link_text = \fI"string" .RS Text shown when the mouse pointer is over a link from a slide to the index. Default is \fB"Return to the index"\fR. .RE .I over_prev_slide_link_text = \fI"string" .RS Text shown when the mouse pointer is over a link from a slide to the previous one. Default is \fB"Previous slide "\fR. .RE .I over_next_slide_link_text = \fI"string" .RS Text shown when the mouse pointer is over a link from a slide to the next one. Default is \fB"Next slide "\fR. .RE .I show_size_unit = \fI"string" .RS Unit to be used when printing sizes .RB [ "--asu <s>" ] Default is \fB"kB"\fR. .RE .I timestamp_format_in_caption = "timestamp format" .RS Change the strftime format used when generating captions from image date .RB [ "--ct <s>" ]. Default is \fB"%Y-%m-%d %H:%M:%S"\fR. .RE .I credits_text = \fI"string" .RS Credits text at the bottom of the index Default is \fB"created with <a href="http://bgoglin.free.fr/llgal">llgal</a>"\fR. .RE .SH What files to insert in the gallery: .I image_extensions = \fI"|-separated strings" .RS Extensions that are matched when searching images Default is \fB"jpg|jpeg|png|gif|tif|tiff|bmp"\fR. .RE .I movie_extensions = \fI"|-separated strings" .RS Extensions that are matched when searching movies Default is \fB"mpg|mpeg|avi|mov|ogm|wmv"\fR. .RE .I add_all_files = <0/1> .RS Add all files to the list of entries, not only images and movies .RB [ -A ]. Default is .BR 0 " (" disabled ). .RE .I add_subdirs = <0/1> .RS Add subdirectories to the list of entries .RB [ -S ]. Default is .BR 0 " (" disabled ). .RE .I exclude = \fI"string" .RS Exclude files whose name matches .RB [ "--exclude <s>" ]. This option may be used several times. Dot beginning files and html files are excluded by default. .RE .I include = \fI"string" .RS Include files whose name matches and were previously excluded .RB [ "--include <s>" ]. This option may be used several times. The order of includes and excludes is respected. .RE .I sort_criteria = \fI"string" .RS Sort criteria when scanning files in the working directory. Default is \fB"name"\fR. .RE .SH Sections: .I section_dir = \fI"subdir" .RS Include subdirectory contents in the gallery .RB [ "-P <subdir>" ]. This option may be used several times. Subdirectory path must be given relatively to the working directory. Default is to use the content of the working directory. .RE .I recursive_sections = <0/1> .RS Add all subdirectories to the list of sections .RB [--Pall]. Default is .BR 0 " (" disabled ). .RE .I entitle_sections = <0/1> .RS Add the subdirectory name as a title at the beginning each section .RB [ --Ps ]. Default is .BR 0 " (" disabled ). .RE .I separate_sections = <0/1> .RS Add a horizontal line at the beginning of each section in the index .RB [ --Ps ]. Default is .BR 0 " (" disabled ). .RE .SH Recursion: .I recursive = <0/1> .RS Run recursively in subdirectories .RB [ -R ]. Default is .BR 0 " (" disabled ). .RE .I link_subgalleries = <0/1> .RS Add links between subgalleries .RB [ --Rl ]. Default is .BR 0 " (" disabled ). .RE .I parent_gallery_link = <0/1> .RS Add links to the parent directory .RB [ --parent ]. Default is .BR 0 " (" disabled ). .RE .SH Various: .I additional_configuration_file = \fI"filename" .RS Additional configuration file that is parsed immediately (before processing the following lines) .RB [ "--config <s>" ]. This option may be used several times. .RE .I additional_template_dir = \fI"path" .RS Additional template directories .RB [ --templates ]. This option may be used multiple times. .RE .I codeset = \fI"codeset" .RS Codeset to be set in HTML headers .RB [ "--codeset <s>" ]. .RE .I language = \fI"locale" .RS Language to be used for generated text in HTML pages .RB [ "--lang <s>" ]. If set, the .B LANGUAGE environment variable might prevent this option from working. .RE .I scaled_create_command = \fI"string" .RS Command to use to create scaled images for slides. Default is \fB"convert \-\-scale <MAXW>x<MAXH> \-\- <IN> <OUT>"\fR. See .B THUMBNAILS AND SCALED IMAGES GENERATION for details. .RE .I thumbnail_create_command = \fI"string" .RS Command to use to create thumbnails for the index. Default is \fB"convert \-\-scale <MAXW>x<MAXH> \-\- <IN> <OUT>"\fR. See .B THUMBNAILS AND SCALED IMAGES GENERATION for details. .RE .I force_image_regeneration = <0/1> .RS Force regeneration of thumbnails and scaled images .RB [ -f ]. Default is .BR 0 " (" disabled ). .RE .I verbose = <0/1> .RS Print notice messages .RB [ -v ]. Default is .BR 0 " (" disabled ). .RE .I www_access_rights = <0/1> .RS Make all generated files world readable .RB [ --www ]. Default is .BR 0 " (" disabled ). .RE .I www_extension = \fI"string" .RS Extension of generated webpages .RB [ --php ]. Default is \fB"html"\fR. .RE .SH SEE ALSO .PP .BR llgal (1) The .I llgalrc template file provided within the documentation directory. .SH AUTHOR Brice Goglin ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������llgal-llgal-0.13.19/po/�����������������������������������������������������������������������������0000775�0000000�0000000�00000000000�13143122354�0014465�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������llgal-llgal-0.13.19/po/Makefile���������������������������������������������������������������������0000664�0000000�0000000�00000002153�13143122354�0016126�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������.PHONY: all update clean install uninstall # To change the locales that are generated, you have to pass # something like LOCALES="fr de" on the command line # locales that are supported SUPPORTED_PO_FILES = $(wildcard *.po) SUPPORTED_LOCALES = $(patsubst %.po,%,$(SUPPORTED_PO_FILES)) # by default, build all supported locales LOCALES = $(SUPPORTED_LOCALES) # locales that actually have to be built/installed # (needed to drop the unsupported/duplicated ones that the user requests) BUILT_LOCALES = $(sort $(filter $(SUPPORTED_LOCALES),$(LOCALES))) BUILT_MO_FILES = $(patsubst %,%.mo,$(BUILT_LOCALES)) all: update update:: $(BUILT_MO_FILES) $(BUILT_MO_FILES): %.mo: %.po msgfmt $< -o $@ clean:: $(RM) $(BUILT_MO_FILES) install:: for lang in $(BUILT_LOCALES) ; do \ install -d -m 0755 $(LOCALEDIR)/$${lang}/LC_MESSAGES/ ; \ install -m 0644 $${lang}.mo $(LOCALEDIR)/$${lang}/LC_MESSAGES/llgal.mo ; \ done uninstall:: for lang in $(BUILT_LOCALES) ; do \ rm $(LOCALEDIR)/$${lang}/LC_MESSAGES/llgal.mo ; \ rmdir $(LOCALEDIR)/$${lang}/LC_MESSAGES/ ; \ rmdir $(LOCALEDIR)/$${lang}/ ; \ done rmdir $(LOCALEDIR)/ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������llgal-llgal-0.13.19/po/de.po������������������������������������������������������������������������0000664�0000000�0000000�00000004235�13143122354�0015421�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������msgid "" msgstr "" "Project-Id-Version: llgal\n" "Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Transfer-Encoding: 8-bit\n" domain "llgal" msgid "index_title|Index of pictures" msgstr "index_title|Bildindex" msgid "parent_gallery_link_text|Back to parent gallery" msgstr "parent_gallery_link_text|Zurück zur übergeordneten Galerie" msgid "prev_gallery_link_text|Previous gallery " msgstr "prev_gallery_link_text|Vorherige Galerie " msgid "next_gallery_link_text|Next gallery " msgstr "next_gallery_link_text|Nächste Galerie " msgid "index_link_text|Index" msgstr "index_link_text|Index" msgid "prev_slide_link_text|<<Prev" msgstr "prev_slide_link_text|<<Zurück" msgid "next_slide_link_text|Next>>" msgstr "next_slide_link_text|Weiter>>" msgid "section_text|Section " msgstr "section_text|Abschnitt " msgid "MVI_link_text|Open movie " msgstr "MVI_link_text|Film öffnen " msgid "FIL_link_text|Download file " msgstr "FIL_link_text|Datei herunter laden " msgid "DIR_link_text|Open subgallery " msgstr "DIR_link_text|Untergalerie öffnen " msgid "alt_full_text|" msgstr "alt_full_text|" msgid "alt_scaled_text|Scaled image " msgstr "alt_scaled_text|Skaliertes Bild " msgid "alt_thumbnail_text|Thumbnail " msgstr "alt_thumbnail_text|Vorschaubild " msgid "alt_film_tile_text|Film Tile" msgstr "alt_film_tile_text|Filmtitel" msgid "over_scaled_text|Click to see full size " msgstr "over_scaled_text|Klicken für Originalgröße " msgid "over_thumbnail_text|Click to enlarge " msgstr "over_thumbnail_text|Klicken zum Vergrößern " msgid "over_index_link_text|Return to the index" msgstr "over_index_link_text|Zurück zum Index" msgid "over_prev_slide_link_text|Previous slide " msgstr "over_prev_slide_link_text|Vorheriges Bild " msgid "over_next_slide_link_text|Next slide " msgstr "over_next_slide_link_text|Nächstes Bild " msgid "show_size_unit|kB" msgstr "show_size_unit|kB" msgid "timestamp_format_in_caption|%y-%m-%d %H:%M:%S" msgstr "timestamp_format_in_caption|%d.%m.%Y %H:%M:%S" msgid "credits_text|created with <a href=\"http://bgoglin.free.fr/llgal\">llgal</a>" msgstr "credits_text|Erstellt mit <a href=\"http://bgoglin.free.fr/llgal\">llgal</a>" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������llgal-llgal-0.13.19/po/en.po������������������������������������������������������������������������0000664�0000000�0000000�00000004164�13143122354�0015434�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������msgid "" msgstr "" "Project-Id-Version: llgal\n" "Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Transfer-Encoding: 8-bit\n" domain "llgal" msgid "index_title|Index of pictures" msgstr "index_title|Index of pictures" msgid "parent_gallery_link_text|Back to parent gallery" msgstr "parent_gallery_link_text|Back to parent gallery" msgid "prev_gallery_link_text|Previous gallery " msgstr "prev_gallery_link_text|Previous gallery " msgid "next_gallery_link_text|Next gallery " msgstr "next_gallery_link_text|Next gallery " msgid "index_link_text|Index" msgstr "index_link_text|Index" msgid "prev_slide_link_text|<<Prev" msgstr "prev_slide_link_text|<<Prev" msgid "next_slide_link_text|Next>>" msgstr "next_slide_link_text|Next>>" msgid "section_text|Section " msgstr "section_text|Section " msgid "MVI_link_text|Open movie " msgstr "MVI_link_text|Open movie " msgid "FIL_link_text|Download file " msgstr "FIL_link_text|Download file " msgid "DIR_link_text|Open subgallery " msgstr "DIR_link_text|Open subgallery " msgid "alt_full_text|" msgstr "alt_full_text|" msgid "alt_scaled_text|Scaled image " msgstr "alt_scaled_text|Scaled image " msgid "alt_thumbnail_text|Thumbnail " msgstr "alt_thumbnail_text|Thumbnail " msgid "alt_film_tile_text|Film Tile" msgstr "alt_film_tile_text|Film Tile" msgid "over_scaled_text|Click to see full size " msgstr "over_scaled_text|Click to see full size " msgid "over_thumbnail_text|Click to enlarge " msgstr "over_thumbnail_text|Click to enlarge " msgid "over_index_link_text|Return to the index" msgstr "over_index_link_text|Return to the index" msgid "over_prev_slide_link_text|Previous slide " msgstr "over_prev_slide_link_text|Previous slide " msgid "over_next_slide_link_text|Next slide " msgstr "over_next_slide_link_text|Next slide " msgid "show_size_unit|kB" msgstr "show_size_unit|kB" msgid "timestamp_format_in_caption|%y-%m-%d %H:%M:%S" msgstr "timestamp_format_in_caption|%y-%m-%d %H:%M:%S" msgid "credits_text|created with <a href=\"http://bgoglin.free.fr/llgal\">llgal</a>" msgstr "credits_text|created with <a href=\"http://bgoglin.free.fr/llgal\">llgal</a>" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������llgal-llgal-0.13.19/po/fr.po������������������������������������������������������������������������0000664�0000000�0000000�00000004303�13143122354�0015434�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������msgid "" msgstr "" "Project-Id-Version: llgal\n" "Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Transfer-Encoding: 8-bit\n" domain "llgal" msgid "index_title|Index of pictures" msgstr "index_title|Index des images" msgid "parent_gallery_link_text|Back to parent gallery" msgstr "parent_gallery_link_text|Retour à la galerie supérieure" msgid "prev_gallery_link_text|Previous gallery " msgstr "prev_gallery_link_text|Galerie précédente " msgid "next_gallery_link_text|Next gallery " msgstr "next_gallery_link_text|Galerie suivante " msgid "index_link_text|Index" msgstr "index_link_text|Index" msgid "prev_slide_link_text|<<Prev" msgstr "prev_slide_link_text|<<Précédent" msgid "next_slide_link_text|Next>>" msgstr "next_slide_link_text|Suivant>>" msgid "section_text|Section " msgstr "section_text|Section " msgid "MVI_link_text|Open movie " msgstr "MVI_link_text|Ouvrir le film " msgid "FIL_link_text|Download file " msgstr "FIL_link_text|Télécharger le fichier " msgid "DIR_link_text|Open subgallery " msgstr "DIR_link_text|Ouvrir la sous-galerie " msgid "alt_full_text|" msgstr "alt_full_text|" msgid "alt_scaled_text|Scaled image " msgstr "alt_scaled_text|Diapositive " msgid "alt_thumbnail_text|Thumbnail " msgstr "alt_thumbnail_text|Vignette " msgid "alt_film_tile_text|Film Tile" msgstr "alt_film_tile_text|Pellicule de film" msgid "over_scaled_text|Click to see full size " msgstr "over_scaled_text|Cliquer pour voir en taille originale " msgid "over_thumbnail_text|Click to enlarge " msgstr "over_thumbnail_text|Cliquer pour agrandir " msgid "over_index_link_text|Return to the index" msgstr "over_index_link_text|Retour à l'index" msgid "over_prev_slide_link_text|Previous slide " msgstr "over_prev_slide_link_text|Diapositive précédente " msgid "over_next_slide_link_text|Next slide " msgstr "over_next_slide_link_text|Diapositive suivante " msgid "show_size_unit|kB" msgstr "show_size_unit|ko" msgid "timestamp_format_in_caption|%y-%m-%d %H:%M:%S" msgstr "timestamp_format_in_caption|%Y/%m/%d %H:%M:%S" msgid "credits_text|created with <a href=\"http://bgoglin.free.fr/llgal\">llgal</a>" msgstr "credits_text|crée avec <a href=\"http://bgoglin.free.fr/llgal\">llgal</a>" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������llgal-llgal-0.13.19/po/it.po������������������������������������������������������������������������0000664�0000000�0000000�00000004332�13143122354�0015443�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������msgid "" msgstr "" "Project-Id-Version: llgal\n" "Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Transfer-Encoding: 8-bit\n" domain "llgal" msgid "index_title|Index of pictures" msgstr "index_title|Indice delle foto" msgid "parent_gallery_link_text|Back to parent gallery" msgstr "parent_gallery_link_text|Ritorna alla galleria superiore" msgid "prev_gallery_link_text|Previous gallery " msgstr "prev_gallery_link_text|Galleria precedente: " msgid "next_gallery_link_text|Next gallery " msgstr "next_gallery_link_text|Galleria successiva: " msgid "index_link_text|Index" msgstr "index_link_text|Indice" msgid "prev_slide_link_text|<<Prev" msgstr "prev_slide_link_text|<<Precedente" msgid "next_slide_link_text|Next>>" msgstr "next_slide_link_text|Successiva>>" msgid "section_text|Section " msgstr "section_text|Sezione " msgid "MVI_link_text|Open movie " msgstr "MVI_link_text|Apri filmato " msgid "FIL_link_text|Download file " msgstr "FIL_link_text|Scarica file " msgid "DIR_link_text|Open subgallery " msgstr "DIR_link_text|Apri sottogalleria " msgid "alt_full_text|" msgstr "alt_full_text|" msgid "alt_scaled_text|Scaled image " msgstr "alt_scaled_text|Diapositiva " msgid "alt_thumbnail_text|Thumbnail " msgstr "alt_thumbnail_text|Miniatura " msgid "alt_film_tile_text|Film Tile" msgstr "alt_film_tile_text|Porzione di video" msgid "over_scaled_text|Click to see full size " msgstr "over_scaled_text|Clicca qui per vederla nella dimensione originale " msgid "over_thumbnail_text|Click to enlarge " msgstr "over_thumbnail_text|Clicca qui per ingrandire " msgid "over_index_link_text|Return to the index" msgstr "over_index_link_text|Ritorna all'indice" msgid "over_prev_slide_link_text|Previous slide " msgstr "over_prev_slide_link_text|Diapositiva precedente " msgid "over_next_slide_link_text|Next slide " msgstr "over_next_slide_link_text|Diapositiva successiva " msgid "show_size_unit|kB" msgstr "show_size_unit|kB" msgid "timestamp_format_in_caption|%y-%m-%d %H:%M:%S" msgstr "timestamp_format_in_caption|%d-%m-%y %H:%M:%S" msgid "credits_text|created with <a href=\"http://bgoglin.free.fr/llgal\">llgal</a>" msgstr "credits_text|realizzato con <a href=\"http://bgoglin.free.fr/llgal\">llgal</a>" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������