pax_global_header00006660000000000000000000000064147256150140014517gustar00rootroot0000000000000052 comment=7a849610e867810c6db9ec35a47b97b959e1b508 htmldoc-1.9.20/000077500000000000000000000000001472561501400132425ustar00rootroot00000000000000htmldoc-1.9.20/.imgbotconfig000066400000000000000000000000501472561501400157050ustar00rootroot00000000000000{ "ignoredFiles": [ "testsuite/*" ] } htmldoc-1.9.20/CHANGES.md000066400000000000000000000360161472561501400146420ustar00rootroot00000000000000# Changes in HTMLDOC v1.9.20 - Fixed a regression that caused spaces to disappear between some words (Issue #533) - Fixed resolution of relative links within a document (Issue #534) # Changes in HTMLDOC v1.9.19 - Security: Fixed an issue with the `file_basename` implementation (Issue #532) - Added support for 'file' method in links (Issue #512) - Updated HTML and header/footer code to use a string pool to simplify memory management and fix potential double-free bugs. - Updated configure script to look for zlib with pkg-config (Issue #519) - Updated markdown support code to mmd. - Fixed hyperlinks to subfolders (Issue #525) - Fixed export of UTF-8 HTML (Issue #526) - Fixed handling of whitespace-only nodes (Issue #528) - Fixed handling of tabs in PRE nodes (Issue #529) - Fixed case sensitivity of link targets (Issue #530) # Changes in HTMLDOC v1.9.18 - Fixed table rendering when there are missing `` (Issue #494) - Fixed support for links of the form "filename.html#anchor" in PDF output (Issue #514) - Fixed `--header1` support for web page output (Issue #515) - Fixed markdown emphasized, strong, and struck-through text (Issue 517) # Changes in HTMLDOC v1.9.17 - Added new `--pre-indent` option to control indentation of pre-formatted text (Issue #505) - Now link to CUPS library instead of embedding its HTTP code. - Updated PostScript and PDF date/time information to use UTC (Issue #490) - Fixed multiple conversions of UTF-8 HTML files from the GUI (Issue #496) - Fixed a compile bug on Solaris (Issue #498) - Fixed a markdown parsing bug (Issue #503) - Fixed a relative URL handling bug (Issue #507) - Fixed a crash bug with bad title images (Issue #510) - Fixed some minor CodeQL warnings. # Changes in HTMLDOC v1.9.16 - Added support for `$DATE(format)` and `$TIME(format)` header/footer strings (Issue #472) - Fixed a potential image overflow bug with JPEG and PNG images (Issue #471) - Fixed potential heap overflow bugs with pages (Issue #477, Issue #478, Issue #480, Issue #482, Issue #483) - Fixed potential use-after-free in blocks (Issue #484) - Updated the GNU TLS HTTPS support code to use a faster connection shutdown mode (Issue #487) - Fixed some minor Coverity warnings. - Updated the GUI interface for current display fonts. # Changes in HTMLDOC v1.9.15 - Fixed a potential heap overflow bug with GIF images (Issue #461) - Fixed a potential double-free bug with PNG images (Issue #462) - Fixed a potential stack overflow bug with GIF images (Issue #463) - Fixed a potential heap underflow bug with empty attributes (Issue #464) - Fixed a potential stack overflow bug with BMP images (Issue #466) - Fixed a potential heap overflow bug with the table-of-contents (Issue #467) - Fixed a potential heap overflow bug with headings (Issue #468) - Fixed a potential stack overflow bug with GIF images (Issue #470) # Changes in HTMLDOC v1.9.14 - BMP image support is now deprecated and will be removed in a future release of HTMLDOC. - Fixed a potential stack overflow bug with GIF images. - Fixed the PDF creation date (Issue #455) - Fixed a potential stack overflow bug with BMP images (Issue #456) - Fixed a compile issue when libpng was not available (Issue #458) # Changes in HTMLDOC v1.9.13 - Now install a 32x32 icon for Linux (Issue #432) - Fixed an issue with large values for roman numerals and letters in headings (Issue #433) - Fixed a crash bug when a HTML comment contains an invalid nul character (Issue #439) - Fixed a crash bug with bogus BMP images (Issue #444) - Fixed a potential heap overflow bug with bogus GIF images (Issue #451) - Fixed a potential stack overflow bug with bogus BMP images (Issue #453) # Changes in HTMLDOC v1.9.12 - Fixed a crash bug with "data:" URIs and EPUB output (Issue #410) - Fixed crash bugs for books (Issue #412, Issue #414) - Fixed a number-up crash bug (Issue #413) - Fixed JPEG error handling (Issue #415) - Fixed crash bugs with bogus table attributes (Issue #416, Issue #417) - Fixed a crash bug with malformed URIs (Issue #418) - Fixed a crash bug with malformed GIF files (Issue #423) - Fixed a crash bug with empty titles (Issue #425) - Fixed crash bugs with bogus text (Issue #426, Issue #429, Issue #430, Issue #431) - Fixed some issues reported by Coverity. - Removed the bundled libjpeg, libpng, and zlib. # Changes in HTMLDOC v1.9.11 - Added high-resolution desktop icons for Linux. - Updated the internal HTTP library to fix truncation of redirection URLs (Issue #396) - Fixed a regression in the handling of character entities for UTF-8 input (Issue #401) - The `--numbered` option did not work when the table-of-contents was disabled (Issue #405) # Changes in HTMLDOC v1.9.10 - Updated local zlib to v1.2.11. - Updated local libpng to v1.6.37. - Fixed packaging issues on macOS and Windows (Issue #377, Issue #386) - Now ignore sRGB profile errors in PNG files (Issue #390) - The GUI would crash when saving (Issue #391) - Page comments are now allowed in `pre` text (Issue #394) # Changes in HTMLDOC v1.9.9 - Fixed a redirection issue - some sites (incorrectly) provide an incomplete Location: URL in the HTTP response. - Fixed https: support on newer versions of Windows (Issue #378) - Fixed a problem with remote URLs containing spaces (Issue #379) - Fixed a UTF-8 processing bug for Markdown files (Issue #383) - Added support for `` (Issue #385) # Changes in HTMLDOC v1.9.8 - Added support for a `HTMLDOC.filename` META keyword that controls the filename reported in CGI mode; the default remains "htmldoc.pdf" (Issue #367) - Fixed a paragraph formatting issue with large inline images (Issue #369) - Fixed a buffer underflow issue (Issue #370) - Fixed PDF page numbers (Issue #371) - Added support for a new `L` header/footer format (`$LETTERHEAD`), which inserts a letterhead image at its full size (Issue #372, Issue #373, Issue #375) - Updated the build documentation (Issue #374) # Changes in HTMLDOC v1.9.7 - Refactored the PRE rendering code to work around compiler optimization bugs (Issue #349) - Added support for links with targets (Issue #351) - Fixed a table rowspan + valign bug (Issue #360) # Changes in HTMLDOC v1.9.6 - Added support for data URIs (Issue #340) - HTMLDOC no longer includes a PDF table of contents when converting a single web page (Issue #344) - Updated the markdown support with external links, additional inline markup, and hard line breaks. - Links in markdown text no longer render with a leading space as part of the link (Issue #346) - Fixed a buffer underflow bug discovered by AddressSanitizer. - Fixed a bug in UTF-8 support (Issue #348) - PDF output now includes the base language of the input document(s) (Issue #350) - Optimized the loading of font widths (Issue #354) - Optimized PDF page resources (Issue #356) - Optimized the base memory used for font widths (Issue #357) - Added proper `­` support (Issue #361) - Title files can now be markdown. # Changes in HTMLDOC v1.9.5 - The GUI did not support EPUB output. - Empty markdown table cells were not rendered in PDF or PostScript output. - The automatically-generated title page now supports both "docnumber" and "version" metadata. - Added support for dc:subject and dc:language metadata in EPUB output from the HTML keywords and lang values. - Added support for the subject and language metadata in markdown input. - Fixed a buffer underflow bug (Issue #338) - `htmldoc --help` now reports whether HTTPS URLs are supported (Issue #339) - Fixed an issue with HTML title pages and EPUB output. # Changes in HTMLDOC v1.9.4 - Inline fixed-width text is no longer reduced in size automatically (Issue #309) - Optimized initialization of font width data (Issue #334) # Changes in HTMLDOC v1.9.3 - Fixed formatting bugs with aligned images (Issue #322, Issue #324) - Fixed support for three digit "#RGB" color values (Issue #323) - Fixed character set support for markdown metadata. - Updated libpng to v1.6.34 (Issue #326) - The makefiles did not use the CPPFLAGS value (Issue #328) # Changes in HTMLDOC v1.9.2 - Added Markdown table support. - Fixed parsing of TBODY, TFOOT, and THEAD elements in HTML files. # Changes in HTMLDOC v1.9.1 - Fixed monospace font size issue (Issue #309) - Added support for reproducible builds (Issue #310) - Added limited support for the HTML 4.0 SPAN element (Issue #311) - Added (extremely limited) UTF-8 support for input files (Issue #314) - Fixed buffer underflow for (invalid) short HTML comments (Issue #316) - Now indent PRE text, by popular request. - EPUB output now makes sure that `` is written as ``. - Now support both NAME and ID for table-of-contents targets. # Changes in HTMLDOC v1.9 - Added support for repeating a single header row for tables that span multiple pages (Issue #16) - Added support for embedding the current filename/URL in the header or footer (Issue #50) - Added EPUB support (Issue #301) - Added Markdown support (Issue #302) - Fixed a regression in header/footer image scaling (Issue #303) - Documentation updates (Issue #305) - Compiler fixes (Issue #304, Issue #306) - Fixed a bug when running HTMLDOC as a macOS application. - Updated the bundled libpng to v1.6.29. # Changes in HTMLDOC v1.8.30 - Updated documentation to reflect new project page on Github. - Dropped old CDE and IRIX desktop integration files. - Cleaned up the GUI and adopted new default text editors for Linux and macOS. - PAGE BREAK comments at the end of a file in web page mode would lose the first page (Issue #251) - Fixed the scaling of header/footer images to limit them to the height of the header or footer (Issue #273) - Fixed an issue with the top-level makefile not exiting with an error as needed (Issue #282) - Fixed a URL referencing bug when the same hostname but a different port was used (Issue #290) - Fixed build issue on macOS (Issue #291) - Fixed handling of indexed+alpha PNG images (Issue #295) # Changes in HTMLDOC v1.8.29 - Updated local PNG library to version 1.6.20. - Updated local JPEG library to version 9b. - Dropped support for OpenSSL. - Added configure script support for libjpeg-turbo. - Updated HTTP code to latest CUPS/ippsample sources. - Duplex PDF output incorrectly forced an even number of pages - The table of contents showed the wrong page numbers after headings containing the "_HD_OMIT_TOC" attribute. - Fixed reported build issues - The configure script's --enable-local* options did not work. # Changes in HTMLDOC v1.8.28 - Updated local zlib to version 1.2.8. - Updated local PNG library to version 1.6.8. - Updated local JPEG library to version 9. - Updated default PDF version to 1.4. - SECURITY: Fixed three buffer overflow issues when reading AFM files and parsing page sizes. - Fixed incompatibility with Fortify's version of strcpy, which does not work properly with variable-length arrays - Fixed compilation against PNG library 1.5 or later - Fixed documentation errors - Marked Zapf-Dingbats as a standard font - Fixed GPL license text in GUI - Fixed a table formatting problem when a column has multiple colspan values - Fixed parsing of HTML comments - Fixed potential out-of-bounds read in table-of-contents rendering code - Fixed handling of image URLs with ampersands in them - Fixed top/bottom margins for logo and header/footer images - Fixed image alignment bug - Fixed X11 build problem # Changes in HTMLDOC v1.8.27 - Fixed a crash bug that appeared when more than 10 blank pages were present in a document - Color changes were not reflected in PRE text - Remote URLs did not always work on older operating systems - Image filenames using % escapes were not decoded properly. - Rows using BGCOLOR that spanned across multiple pages did not render properly - Rows no longer start on a new page due to a cell with both HEIGHT and ROWSPAN specified - CMYK JPEG images caused HTMLDOC to crash - Table cell width calculations didn't always account for the proper minimum width - Images were not copied when generating indexed HTML output to a directory - Changing the bottom margin resulted in text that was formatted below the bottom margin. - The Monospace-Oblique font was not embedded properly in PDF files. # Changes in HTMLDOC v1.8.26 - Outline and keyword strings in PDF files are now stored as Unicode - The Flate compression code could get in an infinite loop if it ran out of memory - Book files saved from the GUI did not handle filenames with spaces - Fixed and re-enabled the ASCII85Device filter support in PostScript Level 2/3 output - Character entities in the first word of a file were not rendered properly - Fixed-size table columns were incorrectly resized when a table width was also specified and there was extra space to distribute - Text could "walk" up or down when in-line images were used - Row backgrounds incorrectly replaced cell backgrounds when the first cell in a row used ROWSPAN - HTMLDOC did not correctly parse FONT FACE attributes - Images in Level 2/3 PostScript output did not work on some printers - The GUI did not use the first page header # Changes in HTMLDOC v1.8.25 - Added "--overflow" and "--no-overflow" command-line options to show or hide the content-too-large errors; the default is "--no-overflow". - Added "--header1" command-line option and "HEADER1" page comments to set the page header for the first page of each chapter. - Added "timing" and "remotebytes" debug data generation. - Added DejaVu font collection to better support Cyrillic and Greek text; the new fonts are available under the generic names "monospace", "sans", and "serif". - Added "--referer" command-line option and corresponding CGI-mode support to pass Referer: information in HTTP requests - On Windows, HTMLDOC now logs CGI mode errors to a file called "htmldoc.log" in the Windows temporary directory. - HTMLDOC no longer uses Base-85 encoding for image data when producing Level 2 and 3 PostScript output. It appears that many printers and PostScript interpreters cannot properly decode this data when the original image data is not a multiple of 8 bits. - HTMLDOC now renders STRONG elements in boldface instead of bold-italic to match the W3C recommendations. - HTMLDOC now automatically inserts a TR element before a TD or TH element as needed to improve web site compatibility; this also triggers a HTML error in --strict mode. - "$HFIMAGEn" didn't work in a header/footer string. - HTMLDOC could crash when rendering a table. - Book files were not used in CGI mode - Cookies were not sent in HTTP requests - Table cells were not aligned properly when the ROWSPAN attribute was set to 1 - HTMLDOC crashed when rendering unresolved hyperlinks in aligned images - Documented the HTMLDOC_NOCGI environment variable - HTMLDOC sometimes crashed when rendering tables with background colors - HTMLDOC would crash when writing encrypted strings longer than 1024 bytes - HTMLDOC didn't set the data directory when running in CGI mode on Windows. - HTMLDOC could crash when loading the Symbol.afm file - HTMLDOC did not always honor HEIGHT attributes in table rows. - Tables with a mix of colspan and rowspan sometimes caused cells to be moved vertically outside the cell. htmldoc-1.9.20/CODE_OF_CONDUCT.md000066400000000000000000000007471472561501400160510ustar00rootroot00000000000000Code of Conduct =============== My goal is to provide quality open source software that everyone can use. While I may not be able to address every request or accept every contribution to this project, I will do my best to develop and maintain it for the common good. As part of the open source community, I expect everyone to: - Be friendly and patient. - Be respectful, even if we disagree. - Be honest. - Be accepting of all people. - Fully explain your concerns, issues, or ideas. htmldoc-1.9.20/CONTRIBUTING.md000066400000000000000000000004271472561501400154760ustar00rootroot00000000000000Contributing to HTMLDOC ======================= HTMLDOC is developed and distributed as open source software under the GNU General Public License Version 2. Contributions should be submitted as pull requests on the Github site: http://github.com/michaelrsweet/pappl/pulls htmldoc-1.9.20/COPYING000066400000000000000000000432541472561501400143050ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The 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 Lesser 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 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) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year 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 Lesser General Public License instead of this License. htmldoc-1.9.20/INSTALL.md000066400000000000000000000043131472561501400146730ustar00rootroot00000000000000How to Install HTMLDOC from Source ================================== To compile HTMLDOC you'll need C and C++ compilers (clang and gcc are fine) along with the following libraries: - FLTK 1.1.x or higher for GUI support - CUPS 2.2 or higher for HTTP/HTTPS support - libjpeg (7 or higher) or libjpeg-turbo for JPEG support - libpng 1.6 or higher for PNG support - zlib 1.1 or higher Windows ------- Visual Studio + Advanced Installer solutions are included in the "vcnet" directory. The Visual Studio solution uses NuGet packages for all of the dependent libraries, and the current version of Advanced Installer is required to build the installer (MSI) target. We highly recommend building and installing the HTMLDOC MSI target, as it takes care of registering the installation location with Windows. If you want to install the software by hand, create a directory for the software and copy the HTMLDOC executable, the "fonts" directory, the "data" directory, and the "doc" directory to it so that it looks like this: C:\Install\Dir\ htmldoc.exe data\ ... data files ... doc\ ... doc files ... fonts\ ... fonts files ... Then create the following registry entries with REGEDIT: HKEY_LOCAL_MACHINE\Software\HTMLDOC\doc = C:\install\dir\doc HKEY_LOCAL_MACHINE\Software\HTMLDOC\data = C:\install\dir Linux, macOS, and Other UNIX Platforms -------------------------------------- To compile the software under UNIX you first need to run the "configure" script in the source directory. Usually this is just: ./configure Then run "make" to build the software and generate the documentation: make Finally, run "make install" (typically as root) to install the software: sudo make install Ubuntu and Debian Notes ----------------------- You should install the following packages: sudo apt-get install build-essential autoconf libfltk1.3-dev \ libcups2-dev libjpeg-dev libpng-dev pkg-config zlib1g-dev CentOS, Fedora, and RHEL Notes ------------------------------ Install the following packages to get full functionality: sudo dnf install autoconf fltk-devel cups-devel libjpeg-devel \ libpng-devel pkgconfig zlib-devel htmldoc-1.9.20/Makedefs.in000066400000000000000000000033421472561501400153130ustar00rootroot00000000000000# # Makefile definitions for HTMLDOC, an HTML document processing program. # # Copyright © 2011-2023 by Michael R Sweet. # Copyright © 1997-2010 by Easy Software Products. # # This program is free software. Distribution and use rights are outlined in # the file "COPYING". # # # Programs... # AR = @AR@ AWK = @AWK@ CC = @CC@ CXX = @CXX@ CHMOD = @CHMOD@ CP = @CP@ INSTALL = @INSTALL@ LN = /bin/ln -sf MKDIR = @MKDIR@ -p POST = @POST@ RANLIB = @RANLIB@ RM = @RM@ -f SHELL = /bin/sh # The extension to use for executables... EXEEXT = @EXEEXT@ # # Installation programs... # INSTALL_BIN = $(INSTALL) -c -m 555 @INSTALL_STRIP@ INSTALL_DATA = $(INSTALL) -c -m 444 INSTALL_DIR = $(INSTALL) -d INSTALL_MAN = $(INSTALL) -c -m 444 # # Directories... # BUILDROOT = $(DSTROOT)$(RPM_BUILD_ROOT)$(DESTDIR) bindir = @bindir@ datadir = @datadir@ datarootdir = @datarootdir@ exec_prefix = @exec_prefix@ includedir = @includedir@ infodir = @infodir@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ prefix = @prefix@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ top_srcdir = @top_srcdir@ # # Program options... # # OPTIM defines the common compiler optimization/debugging options. # ARFLAGS = @ARFLAGS@ CFLAGS = -I.. @CFLAGS@ @LARGEFILE@ $(OPTIM) $(WARNINGS) CPPFLAGS = @CPPFLAGS@ CXXFLAGS = -I.. @CXXFLAGS@ @LARGEFILE@ $(OPTIM) $(WARNINGS) LDFLAGS = @LDFLAGS@ $(OPTIM) LIBS = @LIBS@ OPTIM = @OPTIM@ WARNINGS = @WARNINGS@ # # Rules... # .SILENT: .SUFFIXES: .a .c .cxx .h .o .c.o: echo Compiling $<... $(CC) $(CPPFLAGS) $(CFLAGS) -c $< .cxx.o: echo Compiling $<... $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< htmldoc-1.9.20/Makefile.in000066400000000000000000000036541472561501400153170ustar00rootroot00000000000000# # Makefile for HTMLDOC, an HTML document processing program. # # Copyright © 2011-2021 by Michael R Sweet. # Copyright © 1997-2010 by Easy Software Products. # # This program is free software. Distribution and use rights are outlined in # the file "COPYING". # # # Include common definitions... # include Makedefs # # Subdirectories... # DIRS = htmldoc doc INSTALLDIRS = fonts data desktop doc htmldoc # # Make all targets... # all: for dir in $(DIRS); do\ echo Making all in $$dir...;\ (cd $$dir; $(MAKE) -$(MAKEFLAGS)) || exit 1;\ done # # Remove object and target files... # clean: for dir in $(DIRS); do\ echo Cleaning in $$dir...;\ (cd $$dir; $(MAKE) -$(MAKEFLAGS) clean) || exit 1;\ done # # Clean everything # distclean: clean $(RM) -r autom4te*.cache $(RM) config.h $(RM) config.log $(RM) config.status $(RM) desktop/htmldoc.dt $(RM) desktop/htmldoc.plist $(RM) Makedefs $(RM) Makefile # # Install object and target files... # install: $(MAKE) all for dir in $(INSTALLDIRS); do\ echo Installing in $$dir...;\ (cd $$dir; $(MAKE) -$(MAKEFLAGS) install) || exit 1;\ done # # Sign the HTMLDOC application bundle and make a disk image... Set the # CODESIGN_IDENTITY, APPLEID, and TEAMID environment variables from the Apple # developer pages. # VERSION = @SVERSION@ dmg: echo Signing HTMLDOC application bundle codesign -f -s "$(CODESIGN_IDENTITY)" --timestamp -o runtime htmldoc/htmldoc.app echo Creating archive for notarization rm -f htmldoc/htmldoc.zip ditto -c -k --keepParent htmldoc/htmldoc.app htmldoc/htmldoc.zip echo Notarizing application xcrun notarytool submit htmldoc/htmldoc.zip \ --apple-id "$${APPLEID}" \ --keychain-profile "AC_$${TEAMID}" \ --team-id "$${TEAMID}" \ --wait xcrun stapler staple htmldoc/htmldoc.app echo Making disk image rm -f ~/Desktop/htmldoc-$(VERSION)-macos.dmg dmgbuild -s dmgbuild.py "HTMLDOC $(VERSION)" ~/Desktop/htmldoc-$(VERSION)-macos.dmg htmldoc-1.9.20/README.md000066400000000000000000000125141472561501400145240ustar00rootroot00000000000000HTMLDOC - HTML Conversion Software ================================== ![Version](https://img.shields.io/github/v/release/michaelrsweet/htmldoc?include_prereleases) ![GPL-2.0](https://img.shields.io/github/license/michaelrsweet/htmldoc) [![Build](https://github.com/michaelrsweet/pdfio/workflows/Build/badge.svg)](https://github.com/michaelrsweet/htmldoc/actions/workflows/build.yml) [![Coverity Scan Status](https://img.shields.io/coverity/scan/22389.svg)](https://scan.coverity.com/projects/michaelrsweet-htmldoc) HTMLDOC is a program that reads HTML and Markdown source files or web pages and generates corresponding EPUB, HTML, PostScript, or PDF files with an optional table of contents. HTMLDOC was developed in the 1990's as a documentation generator for my previous company, and has since seen a lot of usage as a report generator embedded in web servers. However, it does not support many things in "the modern web", such as: - Cascading Style Sheets (CSS): While I have experimented with adding CSS support to HTMLDOC, proper CSS support is non-trivial especially for paged output (which is not well supported by CSS) - Encryption: HTMLDOC currently supports the older (and very insecure) PDF 1.4 (128-bit RC4) encryption. I have looked at supporting AES (128/256-bit) encryption, however it is not widely supported and there are incompatible changes in PDF 2.0, so it is unlikely to be added to HTMLDOC. - Forms: HTML forms and PDF forms are very different things. While I have had many requests to add support for PDF forms over the years, I have not found a satisfactory way to do so. - Tables: HTMLDOC supports HTML 3.2 tables with basic support for TBODY and THEAD. - Unicode: While HTMLDOC does support UTF-8 for "Western" languages, there is absolutely no support for languages that require dynamic rewriting or right-to-left text formatting. Basically this means you can't use HTMLDOC to format Arabic, Chinese, Hebrew, Japanese, or other languages that are not based on latin-based alphabets that read left-to-right. - Emoji: The fonts bundled with HTMLDOC do not include Unicode Emoji characters. Resources --------- The following HTMLDOC resources are available online: - Official web site and online documentation: https://www.msweet.org/htmldoc - Issue tracker and questions: https://github.com/michaelrsweet/htmldoc/issues Using HTMLDOC ------------- Note: Complete documentation for HTMLDOC is available in the "doc" subdirectory. The following provides basic information on using HTMLDOC at the command-line and does not discuss the GUI or web server functionality. HTMLDOC accepts a list of HTML and/or Markdown "source" files and will generate EPUB, HTML, PostScript, or PDF output via command-line options. A summary of command-line options can be shown with the "--help" option: htmldoc --help HTMLDOC normally expects "structured" documents, with chapters, etc. Chapters begin with a H1 markup and continue to the end of the listed HTML files or the next H1 markup, whichever comes first. To convert unstructured documents such as web pages, use the "--webpage" option to HTMLDOC: htmldoc --webpage ... To generate a Level 2 PostScript file you might use: htmldoc -f outfile.ps chapter1.html ... chapterN.html Similarly you can generate an EPUB or PDF file of the same source files using: htmldoc -f outfile.epub chapter1.html ... chapterN.html htmldoc -f outfile.pdf chapter1.html ... chapterN.html Finally, to generate HTML files for viewing (with a linked table-of-contents) do the following: htmldoc -t html -d outdir chapter1.html ... chapterN.html or: htmldoc -t html -f outfile.html chapter1.html ... chapterN.html A complete description of all command-line options and HTML guidelines can be found in the software users manual in the "doc" directory. Credits ------- Many thanks to Leonard Rosenthol for providing the original changes to support a macOS (9) version of HTMLDOC. The original table VALIGN and "HALF PAGE" code was contributed by D. Richard Hipp. The original multiple header/footer image code was contributed by Lynn Pye. The RC4 encryption code is from librc4 1.1 by the folks at Carnegie Mellon University. The MD5 hash code is from L. Peter Deutsch at Aladdin Enterprises (creators of Ghostscript, among other things). Legal Stuff ----------- HTMLDOC is copyright © 1997-2024 by Michael R Sweet. This program is free software. Distribution and use rights are outlined in the file "COPYING". HTMLDOC includes code to encrypt PDF document files using the RC4 algorithm with up to a 128-bit key. While this software and code may be freely used and exported under current US laws, other countries may restrict your use and possession of this code and software. The Adobe Portable Document Format is Copyright 1985-2005 by Adobe Systems Incorporated. Adobe, FrameMaker, and PostScript are registered trademarks of Adobe Systems, Incorporated. The Graphics Interchange Format is the copyright and GIF is the service mark property of CompuServe Incorporated. Linux is a registered trademark of Linus Torvalds. macOS is a registered trademark of Apple Inc. Microsoft and Windows are registered trademarks of Microsoft Corporation. UNIX is a registered trademark of the X/Open Company, Ltd. This software is based in part on the work of the Independent JPEG Group and FLTK project. htmldoc-1.9.20/SECURITY.md000066400000000000000000000122511472561501400150340ustar00rootroot00000000000000Security Policy =============== This file describes how security issues are reported and handled, and what the expectations are for security issues reported to this project. Responsible Disclosure ---------------------- With *responsible disclosure*, a security issue (and its fix) is disclosed only after a mutually-agreed period of time (the "embargo date"). The issue and fix are shared amongst and reviewed by the key stakeholders (Linux distributions, OS vendors, etc.) and the CERT/CC. Fixes are released to the public on the agreed-upon date. > Responsible disclosure applies only to production releases. A security > vulnerability that only affects unreleased code can be fixed immediately > without coordination. Vendors *should not* package and release unstable > snapshots, beta releases, or release candidates of this software. Supported Versions ------------------ All production releases of this software are subject to this security policy. A production release is tagged and given a semantic version number of the form: MAJOR.MINOR.PATCH where "MAJOR" is an integer starting at 1 and "MINOR" and "PATCH" are integers starting at 0. A feature release has a "PATCH" value of 0, for example: 1.0.0 1.1.0 2.0.0 Beta releases and release candidates are *not* prodution releases and use semantic version numbers of the form: MAJOR.MINORbNUMBER MAJOR.MINORrcNUMBER where "MAJOR" and "MINOR" identify the new feature release version number and "NUMBER" identifies a beta or release candidate number starting at 1, for example: 1.0b1 1.0b2 1.0rc1 Reporting a Vulnerability ------------------------- Report all security issues to the Github security advisory page at: https://github.com/michaelrsweet/htmldoc/security Expect a response within 5 business days. Any proposed embargo date should be at least 30 days and no more than 90 days in the future. PGP Public Key -------------- The following PGP public key can be used for signing security messages. ``` -----BEGIN PGP PUBLIC KEY BLOCK----- Comment: GPGTools - https://gpgtools.org mQINBF6L0RgBEAC8FTqc/1Al+pWW+ULE0OB2qdbiA2NBjEm0X0WhvpjkqihS1Oih ij3fzFxKJ+DgutQyDb4QFD8tCFL0f0rtNL1Iz8TtiAJjvlhL4kG5cdq5HYEchO10 qFeZ1DqvnHXB4pbKouEQ7Q/FqB1PG+m6y2q1ntgW+VPKm/nFUWBCmhTQicY3FOEG q9r90enc8vhQGOX4p01KR0+izI/g+97pWgMMj5N4zHuXV/GrPhlVgo3Wn1OfEuX4 9vmv7GX4G17Me3E3LOo0c6fmPHJsrRG5oifLpvEJXVZW/RhJR3/pKMPSI5gW8Sal lKAkNeV7aZG3U0DCiIVL6E4FrqXP4PPj1KBixtxOHqzQW8EJwuqbszNN3vp9w6jM GvGtl8w5Qrw/BwnGC6Dmw+Qv04p9JRY2lygzZYcKuwZbLzBdC2CYy7P2shoKiymX ARv+i+bUl6OmtDe2aYaqRkNDgJkpuVInBlMHwOyLP6fN2o7ETXQZ+0a1vQsgjmD+ Mngkc44HRnzsIJ3Ga4WwW8ggnAwUzJ/DgJFYOSbRUF/djBT4/EFoU+/kjXRqq8/d c8HjZtz2L27njmMw68/bYmY1TliLp50PXGzJA/KeY90stwKtTI0ufwAyi9i9BaYq cGbdq5jnfSNMDdKW2kLCNTQeUWSSytMTsdU0Av3Jrv5KQF8x5GaXcpCOTwARAQAB tExNaWNoYWVsIFN3ZWV0IChzZWN1cml0eUBtc3dlZXQub3JnKSAoU2VjdXJpdHkg UEdQIEtleSkgPHNlY3VyaXR5QG1zd2VldC5vcmc+iQJUBBMBCgA+FiEEOElfSXYU h91AF0sBpZiItz2feQIFAl6L0RgCGwMFCQeGH4AFCwkIBwMFFQoJCAsFFgIDAQAC HgECF4AACgkQpZiItz2feQIhjhAAqZHuQJkPBsAKUvJtPiyunpR6JENTUIDxnVXG nue+Zev+B7PzQ7C4CAx7vXwuWTt/BXoyQFKRUrm+YGiBTvLYQ8fPqudDnycSaf/A n01Ushdlhyg1wmCBGHTgt29IkEZphNj6BebRd675RTOSD5y14jrqUb+gxRNuNDa5 ZiZBlBE4A8TV6nvlCyLP5oXyTvKQRFCh4dEiL5ZvpoxnhNvJpSe1ohL8iJ9aeAd5 JdakOKi8MmidRPYC5IldXwduW7VC7dtqSiPqT5aSN0GJ8nIhSpn/ZkOEAPHAtxxa 0VgjltXwUDktu74MUUghdg2vC1df2Z+PqHLsGEqOmxoBIJYXroIqSEpO3Ma7hz0r Xg1AWHMR/xxiLXLxgaZRvTp7AlaNjbqww8JDG8g+nDIeGsgIwWN/6uPczledvDQa HtlMfN97i+rt6sCu13UMZHpBKOGg7eAGRhgpOwpUqmlW1b+ojRHGkmZ8oJSE7sFT gzSGNkmfVgA1ILl0mi8OBVZ4jlUg6EgVsiPlzolH92iscK7g50PdjzpQe0m3gmcL dpOmSL8Fti05dPfamJzIvJd28kMZ6yMnACKj9rq/VpfgYBLK8dbNUjEOQ2oq7PyR Ye/LE1OmAJwfZQkyQNI8yAFXoRJ8u3/bRb3SPvGGWquGBDKHv2K1XiCW65uyLe5B RNJWmme5Ag0EXovRGAEQAJZMFeIMt/ocLskrp89ZyBTTiavFKn9+QW7C2Mb36A73 J2g9vRFBSRizb+t8lSzP/T1GbKS0cEmfEpQppWImTbOMV6ZgxrM0IUy1Yd7Kyc0K oNMZvykRYwVMzxB5hiQ88kCLfqTNCveIvu1xcB9pWkf+cuDmGCxA3I+yc3Eh/SOP urDsHObt7fyEmJpSxCXlMFHRCuWyGXhMNvhR186t9mANW0PyxKJ8efr+2Vhm1+pA Vk9JESac/lREvx9PVFmlPdqgqRkQ0TQB5+ROo9Wy77cxQr5+rvSZZff630I1YgZf Ph6xOV1/q6vJ3RBNA2nPSTjPeeWQ7pTn7PZGJwCjIUjhMbO+EJVKUJNOAEg033mG tLfbFUYdhA/dRgFuKz90loCMfsnf3e4o/TFydSHUuwBUtOWkL1BBWEbk95M/Zr00 w5fD9knas1u5Lc4ogXzTFPnvJ6hM1RAFJEd+FYzJZIvzwrIx4Ag1DOKViVBpeLTu HWj+xckEgvxEBglplALzfSIJ0CLQSNL8iMFbzCnPeUoQfPkqu37KHrB9syAA06Tb qw1Ax0qBqKInGIgBd0w6dFLF3s04xVcPAXWyJ0w4I7h2bs+aD6YwwK6xxCtXxtN5 Q1LQM8s3tKNXER3mZ8zfwgwjsdLVwhXhysFi6Dlkvk/Vrbn1QDfJnzq+F9LsGRGb ABEBAAGJAjwEGAEKACYWIQQ4SV9JdhSH3UAXSwGlmIi3PZ95AgUCXovRGAIbDAUJ B4YfgAAKCRClmIi3PZ95AhDZD/40fShzDS/smZZL0oXN4GgZ62FrXWBdLjontkXo d8hDh1wJZwqsLVbtO2Gu0CPeH9GclQ3bYsR19sGMM4FDgjMu57O/TU6GZl2Ywcjh ayhRTHyAq/BKZn71AM0N7LS8MdNTaLbTbzEu5oGbAmOVv5f0SUnQoGxbeF8ih5bo hR3ZcORujWMgnymL3+cerNyIDQAtfMAUTfpVcwem4CvquA9Wjtur8YN1t+N7I3o2 eMTNSyNUL9Yx3NxbyJ0yrrMvASo+ZVRaPW5+ET9Iqd68ILSY04Gnar3URJssggX8 +cuyEbP9bAG8qYqcr2aSC2dW84mL/RnZGR//1dfS0Ugk6Osj0LSF5i+mz0CbIjYQ PKgLlgpycuGZBC5kG3RWWfanM0HxPDx10a7vEWA1A5Q+csx4yi3CW/giC1zAdhUO cJ1l4Uj/oxpGeLN7BnT/2NzU/px2fpbaG+xU4HlwjzFM2cIOUIohHFhdvFZbFIIA mePqTBnEB3HtXYRTgMoYDXLWhlOXjyVnMR45WDfvEA3KqbAz6sNMtaOJ6rHBWnR1 1YbpvDWUeaGSLXBoGyo3RgTrN9jON8lE/oUxFobnEdfZGD+uwIniylc5rw3+VkBU +QGZDfgPgxjSmKsWq1cK6rNfBacGYrdyqf90VemEsvR8r0Ump0RPzBMlAAq0Xkup WkiKlA== =0GzT -----END PGP PUBLIC KEY BLOCK----- ``` htmldoc-1.9.20/SNAPCRAFT.md000066400000000000000000000004771472561501400151150ustar00rootroot00000000000000# Building HTMLDOC Snaps Support for building HTMLDOC as a "snap" package can be found in the "snap" directory. In fact, every push to the Github repository triggers builds through the Snapcraft buildbot, and the resulting snaps can be installed using the "--edge" option, e.g.: sudo snap install --edge htmldoc htmldoc-1.9.20/cgi-bin/000077500000000000000000000000001472561501400145525ustar00rootroot00000000000000htmldoc-1.9.20/cgi-bin/htmldoc.java000066400000000000000000000055231472561501400170540ustar00rootroot00000000000000// // "$Id$" // // Java interface to HTMLDOC. // // Copyright 2011 by Michael R Sweet // Copyright 2001 by Easy Software Products. // // This program is free software. Distribution and use rights are outlined in // the file "COPYING.txt". // class htmldoc { // Convert named file to PDF on stdout... public static int topdf(String filename)// I - Name of file to convert { String command; // Command string Process process; // Process for HTMLDOC Runtime runtime; // Local runtime object java.io.InputStream input; // Output from HTMLDOC byte buffer []; // Buffer for output data int bytes; // Number of bytes // First tell the client that we will be sending PDF... System.out.print("Content-type: application/pdf\n\n"); // Construct the command string command = "htmldoc --quiet --jpeg --webpage -t pdf --left 36 " + "--header .t. --footer .1. " + filename; // Run the process and wait for it to complete... runtime = Runtime.getRuntime(); try { // Create a new HTMLDOC process... process = runtime.exec(command); // Get stdout from the process and a buffer for the data... input = process.getInputStream(); buffer = new byte[8192]; // Read output from HTMLDOC until we have it all... while ((bytes = input.read(buffer)) > 0) System.out.write(buffer, 0, bytes); // Return the exit status from HTMLDOC... return (process.waitFor()); } catch (Exception e) { // An error occurred - send it to stderr for the web server... System.err.print(e.toString() + " caught while running:\n\n"); System.err.print(" " + command + "\n"); return (1); } } // Main entry for htmldoc class public static void main(String[] args)// I - Command-line args { String server_name, // SERVER_NAME env var server_port, // SERVER_PORT env var path_info, // PATH_INFO env var query_string, // QUERY_STRING env var filename; // File to convert if ((server_name = System.getProperty("SERVER_NAME")) != null && (server_port = System.getProperty("SERVER_PORT")) != null && (path_info = System.getProperty("PATH_INFO")) != null) { // Construct a URL for the resource specified... filename = "http://" + server_name + ":" + server_port + path_info; if ((query_string = System.getProperty("QUERY_STRING")) != null) { filename = filename + "?" + query_string; } } else if (args.length == 1) { // Pull the filename from the command-line... filename = args[0]; } else { // Error - no args or env variables! System.err.print("Usage: htmldoc.class filename\n"); return; } // Convert the file to PDF and send to the web client... topdf(filename); } } // // End of "$Id$". // htmldoc-1.9.20/cgi-bin/topdf000066400000000000000000000010131472561501400156040ustar00rootroot00000000000000#!/bin/sh # # Sample "portal" script to convert the named HTML file to PDF on-the-fly. # # Usage: http://www.domain.com/path/topdf/path/filename.html # # # The "options" variable contains any options you want to pass to HTMLDOC. # options="-t pdf --quiet --jpeg --webpage --header .t. --footer .1." # # Tell the browser to expect a PDF file... # echo "Content-Type: application/pdf" echo "" # # Run HTMLDOC to generate the PDF file... # htmldoc $options http://${SERVER_NAME}:${SERVER_PORT}${PATH_INFO}?$QUERY_STRING htmldoc-1.9.20/cgi-bin/topdf.c000066400000000000000000000010161472561501400160300ustar00rootroot00000000000000#include #include /* topdf() - convert a HTML file to PDF */ FILE *topdf(const char *filename) /* HTML file to convert */ { char command[1024]; /* Command to execute */ puts("Content-Type: application/pdf\n"); sprintf(command, "htmldoc -t pdf --webpage %s", filename); return (popen(command, "w")); } /* topdf2() - pipe HTML output to HTMLDOC for conversion to PDF */ FILE *topdf2(void) { puts("Content-Type: application/pdf\n"); return (popen("htmldoc -t pdf --webpage -", "w")); } htmldoc-1.9.20/cgi-bin/topdf.php000066400000000000000000000030101472561501400163710ustar00rootroot00000000000000Bad URL\n" ."

Bad URL

\n", ."

The URL $url is bad.

\n" ."\n"); } else { topdf($url); } ?> htmldoc-1.9.20/cgi-bin/topdf.pl000066400000000000000000000005571472561501400162320ustar00rootroot00000000000000sub topdf(filename); sub topdf { # Get the filename argument... my $filename = shift; # Make stdout unbuffered... select(STDOUT); $| = 1; # Write the content type to the client... print "Content-Type: application/pdf\n\n"; # Run HTMLDOC to provide the PDF file to the user... system "htmldoc -t pdf --quiet --webpage $filename"; } htmldoc-1.9.20/config.guess000077500000000000000000001412021472561501400155620ustar00rootroot00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2022 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale timestamp='2022-05-25' # This file 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 3 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, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # # Please send patches to . # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2022 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi # Just in case it came from the environment. GUESS= # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. tmp= # shellcheck disable=SC2172 trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 set_cc_for_build() { # prevent multiple calls if $tmp is already set test "$tmp" && return 0 : "${TMPDIR=/tmp}" # shellcheck disable=SC2039,SC3028 { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } dummy=$tmp/dummy case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in ,,) echo "int x;" > "$dummy.c" for driver in cc gcc c89 c99 ; do if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD=$driver break fi done if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac } # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case $UNAME_SYSTEM in Linux|GNU|GNU/*) LIBC=unknown set_cc_for_build cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu #else #include /* First heuristic to detect musl libc. */ #ifdef __DEFINED_va_list LIBC=musl #endif #endif EOF cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` eval "$cc_set_libc" # Second heuristic to detect musl libc. if [ "$LIBC" = unknown ] && command -v ldd >/dev/null && ldd --version 2>&1 | grep -q ^musl; then LIBC=musl fi # If the system lacks a compiler, then just pick glibc. # We could probably try harder. if [ "$LIBC" = unknown ]; then LIBC=gnu fi ;; esac # Note: order is significant - the case branches are not exclusive. case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ echo unknown)` case $UNAME_MACHINE_ARCH in aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-unknown ;; *) machine=$UNAME_MACHINE_ARCH-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case $UNAME_MACHINE_ARCH in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case $UNAME_MACHINE_ARCH in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case $UNAME_VERSION in Debian*) release='-gnu' ;; *) release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. GUESS=$machine-${os}${release}${abi-} ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE ;; *:SecBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE ;; *:MidnightBSD:*:*) GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE ;; *:ekkoBSD:*:*) GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE ;; *:SolidBSD:*:*) GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE ;; *:OS108:*:*) GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE ;; macppc:MirBSD:*:*) GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE ;; *:MirBSD:*:*) GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE ;; *:Sortix:*:*) GUESS=$UNAME_MACHINE-unknown-sortix ;; *:Twizzler:*:*) GUESS=$UNAME_MACHINE-unknown-twizzler ;; *:Redox:*:*) GUESS=$UNAME_MACHINE-unknown-redox ;; mips:OSF1:*.*) GUESS=mips-dec-osf1 ;; alpha:OSF1:*:*) # Reset EXIT trap before exiting to avoid spurious non-zero exit code. trap '' 0 case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case $ALPHA_CPU_TYPE in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` GUESS=$UNAME_MACHINE-dec-osf$OSF_REL ;; Amiga*:UNIX_System_V:4.0:*) GUESS=m68k-unknown-sysv4 ;; *:[Aa]miga[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-amigaos ;; *:[Mm]orph[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-morphos ;; *:OS/390:*:*) GUESS=i370-ibm-openedition ;; *:z/VM:*:*) GUESS=s390-ibm-zvmoe ;; *:OS400:*:*) GUESS=powerpc-ibm-os400 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) GUESS=arm-acorn-riscix$UNAME_RELEASE ;; arm*:riscos:*:*|arm*:RISCOS:*:*) GUESS=arm-unknown-riscos ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) GUESS=hppa1.1-hitachi-hiuxmpp ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. case `(/bin/universe) 2>/dev/null` in att) GUESS=pyramid-pyramid-sysv3 ;; *) GUESS=pyramid-pyramid-bsd ;; esac ;; NILE*:*:*:dcosx) GUESS=pyramid-pyramid-svr4 ;; DRS?6000:unix:4.0:6*) GUESS=sparc-icl-nx6 ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) GUESS=sparc-icl-nx7 ;; esac ;; s390x:SunOS:*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL ;; sun4H:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-hal-solaris2$SUN_REL ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris2$SUN_REL ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) GUESS=i386-pc-auroraux$UNAME_RELEASE ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$SUN_ARCH-pc-solaris2$SUN_REL ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris3$SUN_REL ;; sun4*:SunOS:*:*) case `/usr/bin/arch -k` in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` GUESS=sparc-sun-sunos$SUN_REL ;; sun3*:SunOS:*:*) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case `/bin/arch` in sun3) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun4) GUESS=sparc-sun-sunos$UNAME_RELEASE ;; esac ;; aushp:SunOS:*:*) GUESS=sparc-auspex-sunos$UNAME_RELEASE ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) GUESS=m68k-milan-mint$UNAME_RELEASE ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) GUESS=m68k-hades-mint$UNAME_RELEASE ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) GUESS=m68k-unknown-mint$UNAME_RELEASE ;; m68k:machten:*:*) GUESS=m68k-apple-machten$UNAME_RELEASE ;; powerpc:machten:*:*) GUESS=powerpc-apple-machten$UNAME_RELEASE ;; RISC*:Mach:*:*) GUESS=mips-dec-mach_bsd4.3 ;; RISC*:ULTRIX:*:*) GUESS=mips-dec-ultrix$UNAME_RELEASE ;; VAX*:ULTRIX*:*:*) GUESS=vax-dec-ultrix$UNAME_RELEASE ;; 2020:CLIX:*:* | 2430:CLIX:*:*) GUESS=clipper-intergraph-clix$UNAME_RELEASE ;; mips:*:*:UMIPS | mips:*:*:RISCos) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } GUESS=mips-mips-riscos$UNAME_RELEASE ;; Motorola:PowerMAX_OS:*:*) GUESS=powerpc-motorola-powermax ;; Motorola:*:4.3:PL8-*) GUESS=powerpc-harris-powermax ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) GUESS=powerpc-harris-powermax ;; Night_Hawk:Power_UNIX:*:*) GUESS=powerpc-harris-powerunix ;; m88k:CX/UX:7*:*) GUESS=m88k-harris-cxux7 ;; m88k:*:4*:R4*) GUESS=m88k-motorola-sysv4 ;; m88k:*:3*:R3*) GUESS=m88k-motorola-sysv3 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ test "$TARGET_BINARY_INTERFACE"x = x then GUESS=m88k-dg-dgux$UNAME_RELEASE else GUESS=m88k-dg-dguxbcs$UNAME_RELEASE fi else GUESS=i586-dg-dgux$UNAME_RELEASE fi ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) GUESS=m88k-dolphin-sysv3 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 GUESS=m88k-motorola-sysv3 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) GUESS=m88k-tektronix-sysv3 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) GUESS=m68k-tektronix-bsd ;; *:IRIX*:*:*) IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` GUESS=mips-sgi-irix$IRIX_REL ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) GUESS=i386-ibm-aix ;; ia64:AIX:*:*) if test -x /usr/bin/oslevel ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then GUESS=$SYSTEM_NAME else GUESS=rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then GUESS=rs6000-ibm-aix3.2.4 else GUESS=rs6000-ibm-aix3.2 fi ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if test -x /usr/bin/lslpp ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$IBM_ARCH-ibm-aix$IBM_REV ;; *:AIX:*:*) GUESS=rs6000-ibm-aix ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) GUESS=romp-ibm-bsd4.4 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) GUESS=rs6000-bull-bosx ;; DPX/2?00:B.O.S.:*:*) GUESS=m68k-bull-sysv3 ;; 9000/[34]??:4.3bsd:1.*:*) GUESS=m68k-hp-bsd ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) GUESS=m68k-hp-bsd4.4 ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` case $UNAME_MACHINE in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if test -x /usr/bin/getconf; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case $sc_cpu_version in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case $sc_kernel_bits in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if test "$HP_ARCH" = ""; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if test "$HP_ARCH" = hppa2.0w then set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi GUESS=$HP_ARCH-hp-hpux$HPUX_REV ;; ia64:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` GUESS=ia64-hp-hpux$HPUX_REV ;; 3050*:HI-UX:*:*) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } GUESS=unknown-hitachi-hiuxwe2 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) GUESS=hppa1.1-hp-bsd ;; 9000/8??:4.3bsd:*:*) GUESS=hppa1.0-hp-bsd ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) GUESS=hppa1.0-hp-mpeix ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) GUESS=hppa1.1-hp-osf ;; hp8??:OSF1:*:*) GUESS=hppa1.0-hp-osf ;; i*86:OSF1:*:*) if test -x /usr/sbin/sysversion ; then GUESS=$UNAME_MACHINE-unknown-osf1mk else GUESS=$UNAME_MACHINE-unknown-osf1 fi ;; parisc*:Lites*:*:*) GUESS=hppa1.1-hp-lites ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) GUESS=c1-convex-bsd ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) GUESS=c34-convex-bsd ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) GUESS=c38-convex-bsd ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) GUESS=c4-convex-bsd ;; CRAY*Y-MP:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=ymp-cray-unicos$CRAY_REL ;; CRAY*[A-Z]90:*:*:*) echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=t90-cray-unicos$CRAY_REL ;; CRAY*T3E:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=alphaev5-cray-unicosmk$CRAY_REL ;; CRAY*SV1:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=sv1-cray-unicos$CRAY_REL ;; *:UNICOS/mp:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=craynv-cray-unicosmp$CRAY_REL ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE ;; sparc*:BSD/OS:*:*) GUESS=sparc-unknown-bsdi$UNAME_RELEASE ;; *:BSD/OS:*:*) GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE ;; arm:FreeBSD:*:*) UNAME_PROCESSOR=`uname -p` set_cc_for_build if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi else FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf fi ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL ;; i*:CYGWIN*:*) GUESS=$UNAME_MACHINE-pc-cygwin ;; *:MINGW64*:*) GUESS=$UNAME_MACHINE-pc-mingw64 ;; *:MINGW*:*) GUESS=$UNAME_MACHINE-pc-mingw32 ;; *:MSYS*:*) GUESS=$UNAME_MACHINE-pc-msys ;; i*:PW*:*) GUESS=$UNAME_MACHINE-pc-pw32 ;; *:SerenityOS:*:*) GUESS=$UNAME_MACHINE-pc-serenity ;; *:Interix*:*) case $UNAME_MACHINE in x86) GUESS=i586-pc-interix$UNAME_RELEASE ;; authenticamd | genuineintel | EM64T) GUESS=x86_64-unknown-interix$UNAME_RELEASE ;; IA64) GUESS=ia64-unknown-interix$UNAME_RELEASE ;; esac ;; i*:UWIN*:*) GUESS=$UNAME_MACHINE-pc-uwin ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) GUESS=x86_64-pc-cygwin ;; prep*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=powerpcle-unknown-solaris2$SUN_REL ;; *:GNU:*:*) # the GNU system GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL ;; *:GNU/*:*:*) # other systems with GNU libc and userland GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC ;; *:Minix:*:*) GUESS=$UNAME_MACHINE-unknown-minix ;; aarch64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arm*:Linux:*:*) set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then GUESS=$UNAME_MACHINE-unknown-linux-$LIBC else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi else GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf fi fi ;; avr32*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; cris:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; crisv32:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; e2k:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; frv:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; hexagon:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:Linux:*:*) GUESS=$UNAME_MACHINE-pc-linux-$LIBC ;; ia64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m32r*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m68*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; mips:Linux:*:* | mips64:Linux:*:*) set_cc_for_build IS_GLIBC=0 test x"${LIBC}" = xgnu && IS_GLIBC=1 sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef mips #undef mipsel #undef mips64 #undef mips64el #if ${IS_GLIBC} && defined(_ABI64) LIBCABI=gnuabi64 #else #if ${IS_GLIBC} && defined(_ABIN32) LIBCABI=gnuabin32 #else LIBCABI=${LIBC} #endif #endif #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa64r6 #else #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa32r6 #else #if defined(__mips64) CPU=mips64 #else CPU=mips #endif #endif #endif #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) MIPS_ENDIAN= #else MIPS_ENDIAN= #endif #endif EOF cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` eval "$cc_set_vars" test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; openrisc*:Linux:*:*) GUESS=or1k-unknown-linux-$LIBC ;; or32:Linux:*:* | or1k*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; padre:Linux:*:*) GUESS=sparc-unknown-linux-$LIBC ;; parisc64:Linux:*:* | hppa64:Linux:*:*) GUESS=hppa64-unknown-linux-$LIBC ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; *) GUESS=hppa-unknown-linux-$LIBC ;; esac ;; ppc64:Linux:*:*) GUESS=powerpc64-unknown-linux-$LIBC ;; ppc:Linux:*:*) GUESS=powerpc-unknown-linux-$LIBC ;; ppc64le:Linux:*:*) GUESS=powerpc64le-unknown-linux-$LIBC ;; ppcle:Linux:*:*) GUESS=powerpcle-unknown-linux-$LIBC ;; riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; s390:Linux:*:* | s390x:Linux:*:*) GUESS=$UNAME_MACHINE-ibm-linux-$LIBC ;; sh64*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sh*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sparc:Linux:*:* | sparc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; tile*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; vax:Linux:*:*) GUESS=$UNAME_MACHINE-dec-linux-$LIBC ;; x86_64:Linux:*:*) set_cc_for_build CPU=$UNAME_MACHINE LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then ABI=64 sed 's/^ //' << EOF > "$dummy.c" #ifdef __i386__ ABI=x86 #else #ifdef __ILP32__ ABI=x32 #endif #endif EOF cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` eval "$cc_set_abi" case $ABI in x86) CPU=i686 ;; x32) LIBCABI=${LIBC}x32 ;; esac fi GUESS=$CPU-pc-linux-$LIBCABI ;; xtensa*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. GUESS=i386-sequent-sysv4 ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. GUESS=$UNAME_MACHINE-pc-os2-emx ;; i*86:XTS-300:*:STOP) GUESS=$UNAME_MACHINE-unknown-stop ;; i*86:atheos:*:*) GUESS=$UNAME_MACHINE-unknown-atheos ;; i*86:syllable:*:*) GUESS=$UNAME_MACHINE-pc-syllable ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) GUESS=i386-unknown-lynxos$UNAME_RELEASE ;; i*86:*DOS:*:*) GUESS=$UNAME_MACHINE-pc-msdosdjgpp ;; i*86:*:4.*:*) UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL fi ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv32 fi ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. GUESS=i586-pc-msdosdjgpp ;; Intel:Mach:3*:*) GUESS=i386-pc-mach3 ;; paragon:*:*:*) GUESS=i860-intel-osf1 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 fi ;; mini*:CTIX:SYS*5:*) # "miniframe" GUESS=m68010-convergent-sysv ;; mc68k:UNIX:SYSTEM5:3.51m) GUESS=m68k-convergent-sysv ;; M680?0:D-NIX:5.3:*) GUESS=m68k-diab-dnix ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) GUESS=m68k-unknown-lynxos$UNAME_RELEASE ;; mc68030:UNIX_System_V:4.*:*) GUESS=m68k-atari-sysv4 ;; TSUNAMI:LynxOS:2.*:*) GUESS=sparc-unknown-lynxos$UNAME_RELEASE ;; rs6000:LynxOS:2.*:*) GUESS=rs6000-unknown-lynxos$UNAME_RELEASE ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) GUESS=powerpc-unknown-lynxos$UNAME_RELEASE ;; SM[BE]S:UNIX_SV:*:*) GUESS=mips-dde-sysv$UNAME_RELEASE ;; RM*:ReliantUNIX-*:*:*) GUESS=mips-sni-sysv4 ;; RM*:SINIX-*:*:*) GUESS=mips-sni-sysv4 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` GUESS=$UNAME_MACHINE-sni-sysv4 else GUESS=ns32k-sni-sysv fi ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says GUESS=i586-unisys-sysv4 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm GUESS=hppa1.1-stratus-sysv4 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. GUESS=i860-stratus-sysv4 ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. GUESS=$UNAME_MACHINE-stratus-vos ;; *:VOS:*:*) # From Paul.Green@stratus.com. GUESS=hppa1.1-stratus-vos ;; mc68*:A/UX:*:*) GUESS=m68k-apple-aux$UNAME_RELEASE ;; news*:NEWS-OS:6*:*) GUESS=mips-sony-newsos6 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if test -d /usr/nec; then GUESS=mips-nec-sysv$UNAME_RELEASE else GUESS=mips-unknown-sysv$UNAME_RELEASE fi ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. GUESS=powerpc-be-beos ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. GUESS=powerpc-apple-beos ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. GUESS=i586-pc-beos ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. GUESS=i586-pc-haiku ;; ppc:Haiku:*:*) # Haiku running on Apple PowerPC GUESS=powerpc-apple-haiku ;; *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat) GUESS=$UNAME_MACHINE-unknown-haiku ;; SX-4:SUPER-UX:*:*) GUESS=sx4-nec-superux$UNAME_RELEASE ;; SX-5:SUPER-UX:*:*) GUESS=sx5-nec-superux$UNAME_RELEASE ;; SX-6:SUPER-UX:*:*) GUESS=sx6-nec-superux$UNAME_RELEASE ;; SX-7:SUPER-UX:*:*) GUESS=sx7-nec-superux$UNAME_RELEASE ;; SX-8:SUPER-UX:*:*) GUESS=sx8-nec-superux$UNAME_RELEASE ;; SX-8R:SUPER-UX:*:*) GUESS=sx8r-nec-superux$UNAME_RELEASE ;; SX-ACE:SUPER-UX:*:*) GUESS=sxace-nec-superux$UNAME_RELEASE ;; Power*:Rhapsody:*:*) GUESS=powerpc-apple-rhapsody$UNAME_RELEASE ;; *:Rhapsody:*:*) GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE ;; arm64:Darwin:*:*) GUESS=aarch64-apple-darwin$UNAME_RELEASE ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac if command -v xcode-select > /dev/null 2> /dev/null && \ ! xcode-select --print-path > /dev/null 2> /dev/null ; then # Avoid executing cc if there is no toolchain installed as # cc will be a stub that puts up a graphical alert # prompting the user to install developer tools. CC_FOR_BUILD=no_compiler_found else set_cc_for_build fi if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_PPC >/dev/null then UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then # uname -m returns i386 or x86_64 UNAME_PROCESSOR=$UNAME_MACHINE fi GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE ;; *:QNX:*:4*) GUESS=i386-pc-qnx ;; NEO-*:NONSTOP_KERNEL:*:*) GUESS=neo-tandem-nsk$UNAME_RELEASE ;; NSE-*:NONSTOP_KERNEL:*:*) GUESS=nse-tandem-nsk$UNAME_RELEASE ;; NSR-*:NONSTOP_KERNEL:*:*) GUESS=nsr-tandem-nsk$UNAME_RELEASE ;; NSV-*:NONSTOP_KERNEL:*:*) GUESS=nsv-tandem-nsk$UNAME_RELEASE ;; NSX-*:NONSTOP_KERNEL:*:*) GUESS=nsx-tandem-nsk$UNAME_RELEASE ;; *:NonStop-UX:*:*) GUESS=mips-compaq-nonstopux ;; BS2000:POSIX*:*:*) GUESS=bs2000-siemens-sysv ;; DS/*:UNIX_System_V:*:*) GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "${cputype-}" = 386; then UNAME_MACHINE=i386 elif test "x${cputype-}" != x; then UNAME_MACHINE=$cputype fi GUESS=$UNAME_MACHINE-unknown-plan9 ;; *:TOPS-10:*:*) GUESS=pdp10-unknown-tops10 ;; *:TENEX:*:*) GUESS=pdp10-unknown-tenex ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) GUESS=pdp10-dec-tops20 ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) GUESS=pdp10-xkl-tops20 ;; *:TOPS-20:*:*) GUESS=pdp10-unknown-tops20 ;; *:ITS:*:*) GUESS=pdp10-unknown-its ;; SEI:*:*:SEIUX) GUESS=mips-sei-seiux$UNAME_RELEASE ;; *:DragonFly:*:*) DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case $UNAME_MACHINE in A*) GUESS=alpha-dec-vms ;; I*) GUESS=ia64-dec-vms ;; V*) GUESS=vax-dec-vms ;; esac ;; *:XENIX:*:SysV) GUESS=i386-pc-xenix ;; i*86:skyos:*:*) SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL ;; i*86:rdos:*:*) GUESS=$UNAME_MACHINE-pc-rdos ;; i*86:Fiwix:*:*) GUESS=$UNAME_MACHINE-pc-fiwix ;; *:AROS:*:*) GUESS=$UNAME_MACHINE-unknown-aros ;; x86_64:VMkernel:*:*) GUESS=$UNAME_MACHINE-unknown-esx ;; amd64:Isilon\ OneFS:*:*) GUESS=x86_64-unknown-onefs ;; *:Unleashed:*:*) GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; esac # Do we have a guess based on uname results? if test "x$GUESS" != x; then echo "$GUESS" exit fi # No uname command or uname output not recognized. set_cc_for_build cat > "$dummy.c" < #include #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #include #if defined(_SIZE_T_) || defined(SIGLOST) #include #endif #endif #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) #if !defined (ultrix) #include #if defined (BSD) #if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); #else #if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); #else printf ("vax-dec-bsd\n"); exit (0); #endif #endif #else printf ("vax-dec-bsd\n"); exit (0); #endif #else #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname un; uname (&un); printf ("vax-dec-ultrix%s\n", un.release); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname *un; uname (&un); printf ("mips-dec-ultrix%s\n", un.release); exit (0); #else printf ("mips-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } echo "$0: unable to guess system type" >&2 case $UNAME_MACHINE:$UNAME_SYSTEM in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 <&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" UNAME_SYSTEM = "$UNAME_SYSTEM" UNAME_VERSION = "$UNAME_VERSION" EOF fi exit 1 # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: htmldoc-1.9.20/config.h.in000066400000000000000000000033611472561501400152700ustar00rootroot00000000000000/* * Configuration file for HTMLDOC. * * Copyright © 2011-2024 by Michael R Sweet. * Copyright © 1997-2010 by Easy Software Products. All rights reserved. * * This program is free software. Distribution and use rights are outlined in * the file "COPYING". */ /* * What is the version number for this software? */ #define SVERSION "" /* * Limits for the output "engines"... */ #define MAX_CHAPTERS 1000 /* Maximum number of chapters or files */ #define MAX_COLUMNS 200 /* Maximum number of columns in a table */ #define MAX_HF_IMAGES 10 /* Maximum number of header/footer images */ /* * Memory allocation units for other stuff... */ #define ALLOC_FILES 10 /* Temporary/image files */ #define ALLOC_HEADINGS 50 /* Headings */ #define ALLOC_LINKS 100 /* Web links */ #define ALLOC_OBJECTS 100 /* PDF objects */ #define ALLOC_PAGES 10 /* PS/PDF pages */ #define ALLOC_ROWS 20 /* Table rows */ /* * Locations of files... */ #define DOCUMENTATION "/usr/share/doc/htmldoc" #define HTML_DATA "/usr/share/htmldoc" /* * Do we have the FLTK library? */ #undef HAVE_LIBFLTK /* * Do we have the JPEG library? */ #undef HAVE_LIBJPEG /* * Do we have the PNG library? */ #undef HAVE_LIBPNG /* * Do we have the Xpm library? */ #undef HAVE_LIBXPM /* * Do we need to use ? */ #undef HAVE_STRINGS_H /* * Do we have the header file? */ #undef HAVE_LOCALE_H /* * Do we have some of the "standard" string functions? */ #undef HAVE_STRDUP #undef HAVE_STRCASECMP #undef HAVE_STRNCASECMP #undef HAVE_STRLCAT #undef HAVE_STRLCPY /* * How about snprintf() and vsnprintf()? */ #undef HAVE_SNPRINTF #undef HAVE_VSNPRINTF /* * Does the "tm" structure contain the "tm_gmtoff" member? */ #undef HAVE_TM_GMTOFF htmldoc-1.9.20/config.sub000077500000000000000000001051161472561501400152310ustar00rootroot00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2022 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale timestamp='2022-01-03' # This file 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 3 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, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2022 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) # First pass through any local machine types. echo "$1" exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Split fields of configuration type # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read field1 field2 field3 field4 <&2 exit 1 ;; *-*-*-*) basic_machine=$field1-$field2 basic_os=$field3-$field4 ;; *-*-*) # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two # parts maybe_os=$field2-$field3 case $maybe_os in nto-qnx* | linux-* | uclinux-uclibc* \ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ | storm-chaos* | os2-emx* | rtmk-nova*) basic_machine=$field1 basic_os=$maybe_os ;; android-linux) basic_machine=$field1-unknown basic_os=linux-android ;; *) basic_machine=$field1-$field2 basic_os=$field3 ;; esac ;; *-*) # A lone config we happen to match not fitting any pattern case $field1-$field2 in decstation-3100) basic_machine=mips-dec basic_os= ;; *-*) # Second component is usually, but not always the OS case $field2 in # Prevent following clause from handling this valid os sun*os*) basic_machine=$field1 basic_os=$field2 ;; zephyr*) basic_machine=$field1-unknown basic_os=$field2 ;; # Manufacturers dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ | unicom* | ibm* | next | hp | isi* | apollo | altos* \ | convergent* | ncr* | news | 32* | 3600* | 3100* \ | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ | ultra | tti* | harris | dolphin | highlevel | gould \ | cbm | ns | masscomp | apple | axis | knuth | cray \ | microblaze* | sim | cisco \ | oki | wec | wrs | winbond) basic_machine=$field1-$field2 basic_os= ;; *) basic_machine=$field1 basic_os=$field2 ;; esac ;; esac ;; *) # Convert single-component short-hands not valid as part of # multi-component configurations. case $field1 in 386bsd) basic_machine=i386-pc basic_os=bsd ;; a29khif) basic_machine=a29k-amd basic_os=udi ;; adobe68k) basic_machine=m68010-adobe basic_os=scout ;; alliant) basic_machine=fx80-alliant basic_os= ;; altos | altos3068) basic_machine=m68k-altos basic_os= ;; am29k) basic_machine=a29k-none basic_os=bsd ;; amdahl) basic_machine=580-amdahl basic_os=sysv ;; amiga) basic_machine=m68k-unknown basic_os= ;; amigaos | amigados) basic_machine=m68k-unknown basic_os=amigaos ;; amigaunix | amix) basic_machine=m68k-unknown basic_os=sysv4 ;; apollo68) basic_machine=m68k-apollo basic_os=sysv ;; apollo68bsd) basic_machine=m68k-apollo basic_os=bsd ;; aros) basic_machine=i386-pc basic_os=aros ;; aux) basic_machine=m68k-apple basic_os=aux ;; balance) basic_machine=ns32k-sequent basic_os=dynix ;; blackfin) basic_machine=bfin-unknown basic_os=linux ;; cegcc) basic_machine=arm-unknown basic_os=cegcc ;; convex-c1) basic_machine=c1-convex basic_os=bsd ;; convex-c2) basic_machine=c2-convex basic_os=bsd ;; convex-c32) basic_machine=c32-convex basic_os=bsd ;; convex-c34) basic_machine=c34-convex basic_os=bsd ;; convex-c38) basic_machine=c38-convex basic_os=bsd ;; cray) basic_machine=j90-cray basic_os=unicos ;; crds | unos) basic_machine=m68k-crds basic_os= ;; da30) basic_machine=m68k-da30 basic_os= ;; decstation | pmax | pmin | dec3100 | decstatn) basic_machine=mips-dec basic_os= ;; delta88) basic_machine=m88k-motorola basic_os=sysv3 ;; dicos) basic_machine=i686-pc basic_os=dicos ;; djgpp) basic_machine=i586-pc basic_os=msdosdjgpp ;; ebmon29k) basic_machine=a29k-amd basic_os=ebmon ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson basic_os=ose ;; gmicro) basic_machine=tron-gmicro basic_os=sysv ;; go32) basic_machine=i386-pc basic_os=go32 ;; h8300hms) basic_machine=h8300-hitachi basic_os=hms ;; h8300xray) basic_machine=h8300-hitachi basic_os=xray ;; h8500hms) basic_machine=h8500-hitachi basic_os=hms ;; harris) basic_machine=m88k-harris basic_os=sysv3 ;; hp300 | hp300hpux) basic_machine=m68k-hp basic_os=hpux ;; hp300bsd) basic_machine=m68k-hp basic_os=bsd ;; hppaosf) basic_machine=hppa1.1-hp basic_os=osf ;; hppro) basic_machine=hppa1.1-hp basic_os=proelf ;; i386mach) basic_machine=i386-mach basic_os=mach ;; isi68 | isi) basic_machine=m68k-isi basic_os=sysv ;; m68knommu) basic_machine=m68k-unknown basic_os=linux ;; magnum | m3230) basic_machine=mips-mips basic_os=sysv ;; merlin) basic_machine=ns32k-utek basic_os=sysv ;; mingw64) basic_machine=x86_64-pc basic_os=mingw64 ;; mingw32) basic_machine=i686-pc basic_os=mingw32 ;; mingw32ce) basic_machine=arm-unknown basic_os=mingw32ce ;; monitor) basic_machine=m68k-rom68k basic_os=coff ;; morphos) basic_machine=powerpc-unknown basic_os=morphos ;; moxiebox) basic_machine=moxie-unknown basic_os=moxiebox ;; msdos) basic_machine=i386-pc basic_os=msdos ;; msys) basic_machine=i686-pc basic_os=msys ;; mvs) basic_machine=i370-ibm basic_os=mvs ;; nacl) basic_machine=le32-unknown basic_os=nacl ;; ncr3000) basic_machine=i486-ncr basic_os=sysv4 ;; netbsd386) basic_machine=i386-pc basic_os=netbsd ;; netwinder) basic_machine=armv4l-rebel basic_os=linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony basic_os=newsos ;; news1000) basic_machine=m68030-sony basic_os=newsos ;; necv70) basic_machine=v70-nec basic_os=sysv ;; nh3000) basic_machine=m68k-harris basic_os=cxux ;; nh[45]000) basic_machine=m88k-harris basic_os=cxux ;; nindy960) basic_machine=i960-intel basic_os=nindy ;; mon960) basic_machine=i960-intel basic_os=mon960 ;; nonstopux) basic_machine=mips-compaq basic_os=nonstopux ;; os400) basic_machine=powerpc-ibm basic_os=os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson basic_os=ose ;; os68k) basic_machine=m68k-none basic_os=os68k ;; paragon) basic_machine=i860-intel basic_os=osf ;; parisc) basic_machine=hppa-unknown basic_os=linux ;; psp) basic_machine=mipsallegrexel-sony basic_os=psp ;; pw32) basic_machine=i586-unknown basic_os=pw32 ;; rdos | rdos64) basic_machine=x86_64-pc basic_os=rdos ;; rdos32) basic_machine=i386-pc basic_os=rdos ;; rom68k) basic_machine=m68k-rom68k basic_os=coff ;; sa29200) basic_machine=a29k-amd basic_os=udi ;; sei) basic_machine=mips-sei basic_os=seiux ;; sequent) basic_machine=i386-sequent basic_os= ;; sps7) basic_machine=m68k-bull basic_os=sysv2 ;; st2000) basic_machine=m68k-tandem basic_os= ;; stratus) basic_machine=i860-stratus basic_os=sysv4 ;; sun2) basic_machine=m68000-sun basic_os= ;; sun2os3) basic_machine=m68000-sun basic_os=sunos3 ;; sun2os4) basic_machine=m68000-sun basic_os=sunos4 ;; sun3) basic_machine=m68k-sun basic_os= ;; sun3os3) basic_machine=m68k-sun basic_os=sunos3 ;; sun3os4) basic_machine=m68k-sun basic_os=sunos4 ;; sun4) basic_machine=sparc-sun basic_os= ;; sun4os3) basic_machine=sparc-sun basic_os=sunos3 ;; sun4os4) basic_machine=sparc-sun basic_os=sunos4 ;; sun4sol2) basic_machine=sparc-sun basic_os=solaris2 ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun basic_os= ;; sv1) basic_machine=sv1-cray basic_os=unicos ;; symmetry) basic_machine=i386-sequent basic_os=dynix ;; t3e) basic_machine=alphaev5-cray basic_os=unicos ;; t90) basic_machine=t90-cray basic_os=unicos ;; toad1) basic_machine=pdp10-xkl basic_os=tops20 ;; tpf) basic_machine=s390x-ibm basic_os=tpf ;; udi29k) basic_machine=a29k-amd basic_os=udi ;; ultra3) basic_machine=a29k-nyu basic_os=sym1 ;; v810 | necv810) basic_machine=v810-nec basic_os=none ;; vaxv) basic_machine=vax-dec basic_os=sysv ;; vms) basic_machine=vax-dec basic_os=vms ;; vsta) basic_machine=i386-pc basic_os=vsta ;; vxworks960) basic_machine=i960-wrs basic_os=vxworks ;; vxworks68) basic_machine=m68k-wrs basic_os=vxworks ;; vxworks29k) basic_machine=a29k-wrs basic_os=vxworks ;; xbox) basic_machine=i686-pc basic_os=mingw32 ;; ymp) basic_machine=ymp-cray basic_os=unicos ;; *) basic_machine=$1 basic_os= ;; esac ;; esac # Decode 1-component or ad-hoc basic machines case $basic_machine in # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) cpu=hppa1.1 vendor=winbond ;; op50n) cpu=hppa1.1 vendor=oki ;; op60c) cpu=hppa1.1 vendor=oki ;; ibm*) cpu=i370 vendor=ibm ;; orion105) cpu=clipper vendor=highlevel ;; mac | mpw | mac-mpw) cpu=m68k vendor=apple ;; pmac | pmac-mpw) cpu=powerpc vendor=apple ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) cpu=m68000 vendor=att ;; 3b*) cpu=we32k vendor=att ;; bluegene*) cpu=powerpc vendor=ibm basic_os=cnk ;; decsystem10* | dec10*) cpu=pdp10 vendor=dec basic_os=tops10 ;; decsystem20* | dec20*) cpu=pdp10 vendor=dec basic_os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) cpu=m68k vendor=motorola ;; dpx2*) cpu=m68k vendor=bull basic_os=sysv3 ;; encore | umax | mmax) cpu=ns32k vendor=encore ;; elxsi) cpu=elxsi vendor=elxsi basic_os=${basic_os:-bsd} ;; fx2800) cpu=i860 vendor=alliant ;; genix) cpu=ns32k vendor=ns ;; h3050r* | hiux*) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) cpu=m68000 vendor=hp ;; hp9k3[2-9][0-9]) cpu=m68k vendor=hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) cpu=hppa1.1 vendor=hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; i*86v32) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv32 ;; i*86v4*) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv4 ;; i*86v) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv ;; i*86sol2) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=solaris2 ;; j90 | j90-cray) cpu=j90 vendor=cray basic_os=${basic_os:-unicos} ;; iris | iris4d) cpu=mips vendor=sgi case $basic_os in irix*) ;; *) basic_os=irix4 ;; esac ;; miniframe) cpu=m68000 vendor=convergent ;; *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) cpu=m68k vendor=atari basic_os=mint ;; news-3600 | risc-news) cpu=mips vendor=sony basic_os=newsos ;; next | m*-next) cpu=m68k vendor=next case $basic_os in openstep*) ;; nextstep*) ;; ns2*) basic_os=nextstep2 ;; *) basic_os=nextstep3 ;; esac ;; np1) cpu=np1 vendor=gould ;; op50n-* | op60c-*) cpu=hppa1.1 vendor=oki basic_os=proelf ;; pa-hitachi) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; pbd) cpu=sparc vendor=tti ;; pbb) cpu=m68k vendor=tti ;; pc532) cpu=ns32k vendor=pc532 ;; pn) cpu=pn vendor=gould ;; power) cpu=power vendor=ibm ;; ps2) cpu=i386 vendor=ibm ;; rm[46]00) cpu=mips vendor=siemens ;; rtpc | rtpc-*) cpu=romp vendor=ibm ;; sde) cpu=mipsisa32 vendor=sde basic_os=${basic_os:-elf} ;; simso-wrs) cpu=sparclite vendor=wrs basic_os=vxworks ;; tower | tower-32) cpu=m68k vendor=ncr ;; vpp*|vx|vx-*) cpu=f301 vendor=fujitsu ;; w65) cpu=w65 vendor=wdc ;; w89k-*) cpu=hppa1.1 vendor=winbond basic_os=proelf ;; none) cpu=none vendor=none ;; leon|leon[3-9]) cpu=sparc vendor=$basic_machine ;; leon-*|leon[3-9]-*) cpu=sparc vendor=`echo "$basic_machine" | sed 's/-.*//'` ;; *-*) # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read cpu vendor <&2 exit 1 ;; esac ;; esac # Here we canonicalize certain aliases for manufacturers. case $vendor in digital*) vendor=dec ;; commodore*) vendor=cbm ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if test x$basic_os != x then # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just # set os. case $basic_os in gnu/linux*) kernel=linux os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` ;; os2-emx) kernel=os2 os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` ;; nto-qnx*) kernel=nto os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` ;; *-*) # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read kernel os <&2 exit 1 ;; esac # As a final step for OS-related things, validate the OS-kernel combination # (given a valid OS), if there is a kernel. case $kernel-$os in linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ | linux-musl* | linux-relibc* | linux-uclibc* ) ;; uclinux-uclibc* ) ;; -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) # These are just libc implementations, not actual OSes, and thus # require a kernel. echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 exit 1 ;; kfreebsd*-gnu* | kopensolaris*-gnu*) ;; vxworks-simlinux | vxworks-simwindows | vxworks-spe) ;; nto-qnx*) ;; os2-emx) ;; *-eabi* | *-gnueabi*) ;; -*) # Blank kernel with real OS is always fine. ;; *-*) echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 exit 1 ;; esac # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. case $vendor in unknown) case $cpu-$os in *-riscix*) vendor=acorn ;; *-sunos*) vendor=sun ;; *-cnk* | *-aix*) vendor=ibm ;; *-beos*) vendor=be ;; *-hpux*) vendor=hp ;; *-mpeix*) vendor=hp ;; *-hiux*) vendor=hitachi ;; *-unos*) vendor=crds ;; *-dgux*) vendor=dg ;; *-luna*) vendor=omron ;; *-genix*) vendor=ns ;; *-clix*) vendor=intergraph ;; *-mvs* | *-opened*) vendor=ibm ;; *-os400*) vendor=ibm ;; s390-* | s390x-*) vendor=ibm ;; *-ptx*) vendor=sequent ;; *-tpf*) vendor=ibm ;; *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; *-aux*) vendor=apple ;; *-hms*) vendor=hitachi ;; *-mpw* | *-macos*) vendor=apple ;; *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) vendor=atari ;; *-vos*) vendor=stratus ;; esac ;; esac echo "$cpu-$vendor-${kernel:+$kernel-}$os" exit # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: htmldoc-1.9.20/configure000077500000000000000000005666261472561501400151760ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.71 for HTMLDOC 1.9.20. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, # Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="as_nop=: if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else \$as_nop case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ) then : else \$as_nop exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 blah=\$(echo \$(echo blah)) test x\"\$blah\" = xblah || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" if (eval "$as_required") 2>/dev/null then : as_have_required=yes else $as_nop as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null then : else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$as_shell as_have_required=yes if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null then : break 2 fi fi done;; esac as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop if { test -f "$SHELL" || test -f "$SHELL.exe"; } && as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$SHELL as_have_required=yes fi fi if test "x$CONFIG_SHELL" != x then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno then : printf "%s\n" "$0: This script requires a shell more modern than all" printf "%s\n" "$0: the shells that I found on your system." if test ${ZSH_VERSION+y} ; then printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." else printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and $0: https://github.com/michaelrsweet/htmldoc/issues about $0: your system, including any error possibly output before $0: this message. Then install a modern shell, or manually $0: run the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='HTMLDOC' PACKAGE_TARNAME='htmldoc' PACKAGE_VERSION='1.9.20' PACKAGE_STRING='HTMLDOC 1.9.20' PACKAGE_BUGREPORT='https://github.com/michaelrsweet/htmldoc/issues' PACKAGE_URL='https://www.msweet.org/htmldoc' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_STDIO_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_header_c_list= ac_subst_vars='LTLIBOBJS LIBOBJS WARNINGS POST CUPSCONFIG LARGEFILE ARFLAGS PKGCONFIG RM MKDIR INSTALL FLTKCONFIG CP AR RANLIB CPP ac_ct_CXX CXXFLAGS CXX OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC AWK OPTIM INSTALL_STRIP host_os host_vendor host_cpu host build_os build_vendor build_cpu build SVERSION target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_debug with_gui enable_largefile enable_maintainer enable_sanitizer ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CXX CXXFLAGS CCC CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures HTMLDOC 1.9.20 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/htmldoc] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of HTMLDOC 1.9.20:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-debug turn on debugging, default=no --disable-largefile omit support for large files --enable-maintainer turn on maintainer mode, default=no --enable-sanitizer build with AddressSanitizer Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --without-gui do not compile the GUI version of HTMLDOC, default=yes Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CXX C++ compiler command CXXFLAGS C++ compiler flags CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . HTMLDOC home page: . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for configure.gnu first; this name is used for a wrapper for # Metaconfig's "Configure" on case-insensitive file systems. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF HTMLDOC configure 1.9.20 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. */ #include #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main (void) { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func ac_configure_args_raw= for ac_arg do case $ac_arg in *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append ac_configure_args_raw " '$ac_arg'" done case $ac_configure_args_raw in *$as_nl*) ac_safe_unquote= ;; *) ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. ac_unsafe_a="$ac_unsafe_z#~" ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; esac cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by HTMLDOC $as_me 1.9.20, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac printf "%s\n" "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Sanitize IFS. IFS=" "" $as_nl" # Save into config.log some information that might help in debugging. { echo printf "%s\n" "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo printf "%s\n" "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then printf "%s\n" "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then printf "%s\n" "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && printf "%s\n" "$as_me: caught signal $ac_signal" printf "%s\n" "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h printf "%s\n" "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then ac_site_files="$CONFIG_SITE" elif test "x$prefix" != xNONE; then ac_site_files="$prefix/share/config.site $prefix/etc/config.site" else ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi for ac_site_file in $ac_site_files do case $ac_site_file in #( */*) : ;; #( *) : ac_site_file=./$ac_site_file ;; esac if test -f "$ac_site_file" && test -r "$ac_site_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 printf "%s\n" "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 printf "%s\n" "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Test code for whether the C compiler supports C89 (global declarations) ac_c_conftest_c89_globals=' /* Does the compiler advertise C89 conformance? Do not test the value of __STDC__, because some compilers set it to 0 while being otherwise adequately conformant. */ #if !defined __STDC__ # error "Compiler does not advertise C89 conformance" #endif #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ struct buf { int x; }; struct buf * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not \xHH hex character constants. These do not provoke an error unfortunately, instead are silently treated as an "x". The following induces an error, until -std is added to get proper ANSI mode. Curiously \x00 != x always comes out true, for an array size at least. It is necessary to write \x00 == 0 to get something that is true only with -std. */ int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) '\''x'\'' int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), int, int);' # Test code for whether the C compiler supports C89 (body of main). ac_c_conftest_c89_main=' ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); ' # Test code for whether the C compiler supports C99 (global declarations) ac_c_conftest_c99_globals=' // Does the compiler advertise C99 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L # error "Compiler does not advertise C99 conformance" #endif #include extern int puts (const char *); extern int printf (const char *, ...); extern int dprintf (int, const char *, ...); extern void *malloc (size_t); // Check varargs macros. These examples are taken from C99 6.10.3.5. // dprintf is used instead of fprintf to avoid needing to declare // FILE and stderr. #define debug(...) dprintf (2, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK #error "your preprocessor is broken" #endif #if BIG_OK #else #error "your preprocessor is broken" #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) continue; return 0; } // Check varargs and va_copy. static bool test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str = ""; int number = 0; float fnumber = 0; while (*format) { switch (*format++) { case '\''s'\'': // string str = va_arg (args_copy, const char *); break; case '\''d'\'': // int number = va_arg (args_copy, int); break; case '\''f'\'': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); return *str && number && fnumber; } ' # Test code for whether the C compiler supports C99 (body of main). ac_c_conftest_c99_main=' // Check bool. _Bool success = false; success |= (argc != 0); // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[0] = argv[0][0]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' || dynamic_array[ni.number - 1] != 543); ' # Test code for whether the C compiler supports C11 (global declarations) ac_c_conftest_c11_globals=' // Does the compiler advertise C11 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L # error "Compiler does not advertise C11 conformance" #endif // Check _Alignas. char _Alignas (double) aligned_as_double; char _Alignas (0) no_special_alignment; extern char aligned_as_int; char _Alignas (0) _Alignas (int) aligned_as_int; // Check _Alignof. enum { int_alignment = _Alignof (int), int_array_alignment = _Alignof (int[100]), char_alignment = _Alignof (char) }; _Static_assert (0 < -_Alignof (int), "_Alignof is signed"); // Check _Noreturn. int _Noreturn does_not_return (void) { for (;;) continue; } // Check _Static_assert. struct test_static_assert { int x; _Static_assert (sizeof (int) <= sizeof (long int), "_Static_assert does not work in struct"); long int y; }; // Check UTF-8 literals. #define u8 syntax error! char const utf8_literal[] = u8"happens to be ASCII" "another string"; // Check duplicate typedefs. typedef long *long_ptr; typedef long int *long_ptr; typedef long_ptr long_ptr; // Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. struct anonymous { union { struct { int i; int j; }; struct { int k; long int l; } w; }; int m; } v1; ' # Test code for whether the C compiler supports C11 (body of main). ac_c_conftest_c11_main=' _Static_assert ((offsetof (struct anonymous, i) == offsetof (struct anonymous, w.k)), "Anonymous union alignment botch"); v1.i = 2; v1.w.k = 5; ok |= v1.i != 5; ' # Test code for whether the C compiler supports C11 (complete). ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} ${ac_c_conftest_c11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} ${ac_c_conftest_c11_main} return ok; } " # Test code for whether the C compiler supports C99 (complete). ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} return ok; } " # Test code for whether the C compiler supports C89 (complete). ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} return ok; } " # Test code for whether the C++ compiler supports C++98 (global declarations) ac_cxx_conftest_cxx98_globals=' // Does the compiler advertise C++98 conformance? #if !defined __cplusplus || __cplusplus < 199711L # error "Compiler does not advertise C++98 conformance" #endif // These inclusions are to reject old compilers that // lack the unsuffixed header files. #include #include // and are *not* freestanding headers in C++98. extern void assert (int); namespace std { extern int strcmp (const char *, const char *); } // Namespaces, exceptions, and templates were all added after "C++ 2.0". using std::exception; using std::strcmp; namespace { void test_exception_syntax() { try { throw "test"; } catch (const char *s) { // Extra parentheses suppress a warning when building autoconf itself, // due to lint rules shared with more typical C programs. assert (!(strcmp) (s, "test")); } } template struct test_template { T const val; explicit test_template(T t) : val(t) {} template T add(U u) { return static_cast(u) + val; } }; } // anonymous namespace ' # Test code for whether the C++ compiler supports C++98 (body of main) ac_cxx_conftest_cxx98_main=' assert (argc); assert (! argv[0]); { test_exception_syntax (); test_template tt (2.0); assert (tt.add (4) == 6.0); assert (true && !false); } ' # Test code for whether the C++ compiler supports C++11 (global declarations) ac_cxx_conftest_cxx11_globals=' // Does the compiler advertise C++ 2011 conformance? #if !defined __cplusplus || __cplusplus < 201103L # error "Compiler does not advertise C++11 conformance" #endif namespace cxx11test { constexpr int get_val() { return 20; } struct testinit { int i; double d; }; class delegate { public: delegate(int n) : n(n) {} delegate(): delegate(2354) {} virtual int getval() { return this->n; }; protected: int n; }; class overridden : public delegate { public: overridden(int n): delegate(n) {} virtual int getval() override final { return this->n * 2; } }; class nocopy { public: nocopy(int i): i(i) {} nocopy() = default; nocopy(const nocopy&) = delete; nocopy & operator=(const nocopy&) = delete; private: int i; }; // for testing lambda expressions template Ret eval(Fn f, Ret v) { return f(v); } // for testing variadic templates and trailing return types template auto sum(V first) -> V { return first; } template auto sum(V first, Args... rest) -> V { return first + sum(rest...); } } ' # Test code for whether the C++ compiler supports C++11 (body of main) ac_cxx_conftest_cxx11_main=' { // Test auto and decltype auto a1 = 6538; auto a2 = 48573953.4; auto a3 = "String literal"; int total = 0; for (auto i = a3; *i; ++i) { total += *i; } decltype(a2) a4 = 34895.034; } { // Test constexpr short sa[cxx11test::get_val()] = { 0 }; } { // Test initializer lists cxx11test::testinit il = { 4323, 435234.23544 }; } { // Test range-based for int array[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; for (auto &x : array) { x += 23; } } { // Test lambda expressions using cxx11test::eval; assert (eval ([](int x) { return x*2; }, 21) == 42); double d = 2.0; assert (eval ([&](double x) { return d += x; }, 3.0) == 5.0); assert (d == 5.0); assert (eval ([=](double x) mutable { return d += x; }, 4.0) == 9.0); assert (d == 5.0); } { // Test use of variadic templates using cxx11test::sum; auto a = sum(1); auto b = sum(1, 2); auto c = sum(1.0, 2.0, 3.0); } { // Test constructor delegation cxx11test::delegate d1; cxx11test::delegate d2(); cxx11test::delegate d3(45); } { // Test override and final cxx11test::overridden o1(55464); } { // Test nullptr char *c = nullptr; } { // Test template brackets test_template<::test_template> v(test_template(12)); } { // Unicode literals char const *utf8 = u8"UTF-8 string \u2500"; char16_t const *utf16 = u"UTF-8 string \u2500"; char32_t const *utf32 = U"UTF-32 string \u2500"; } ' # Test code for whether the C compiler supports C++11 (complete). ac_cxx_conftest_cxx11_program="${ac_cxx_conftest_cxx98_globals} ${ac_cxx_conftest_cxx11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_cxx_conftest_cxx98_main} ${ac_cxx_conftest_cxx11_main} return ok; } " # Test code for whether the C compiler supports C++98 (complete). ac_cxx_conftest_cxx98_program="${ac_cxx_conftest_cxx98_globals} int main (int argc, char **argv) { int ok = 0; ${ac_cxx_conftest_cxx98_main} return ok; } " as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" # Auxiliary files required by this configure script. ac_aux_files="config.guess config.sub" # Locations in which to look for auxiliary files. ac_aux_dir_candidates="${srcdir}${PATH_SEPARATOR}${srcdir}/..${PATH_SEPARATOR}${srcdir}/../.." # Search for a directory containing all of the required auxiliary files, # $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. # If we don't find one directory that contains all the files we need, # we report the set of missing files from the *first* directory in # $ac_aux_dir_candidates and give up. ac_missing_aux_files="" ac_first_candidate=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in $ac_aux_dir_candidates do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 ac_aux_dir_found=yes ac_install_sh= for ac_aux in $ac_aux_files do # As a special case, if "install-sh" is required, that requirement # can be satisfied by any of "install-sh", "install.sh", or "shtool", # and $ac_install_sh is set appropriately for whichever one is found. if test x"$ac_aux" = x"install-sh" then if test -f "${as_dir}install-sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 ac_install_sh="${as_dir}install-sh -c" elif test -f "${as_dir}install.sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 ac_install_sh="${as_dir}install.sh -c" elif test -f "${as_dir}shtool"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 ac_install_sh="${as_dir}shtool install -c" else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} install-sh" else break fi fi else if test -f "${as_dir}${ac_aux}"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" else break fi fi fi done if test "$ac_aux_dir_found" = yes; then ac_aux_dir="$as_dir" break fi ac_first_candidate=false as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. if test -f "${ac_aux_dir}config.guess"; then ac_config_guess="$SHELL ${ac_aux_dir}config.guess" fi if test -f "${ac_aux_dir}config.sub"; then ac_config_sub="$SHELL ${ac_aux_dir}config.sub" fi if test -f "$ac_aux_dir/configure"; then ac_configure="$SHELL ${ac_aux_dir}configure" fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" SVERSION="1.9.20" printf "%s\n" "#define SVERSION \"$SVERSION\"" >>confdefs.h printf "%s\n" "#define HTMLDOC_DOES_NOT_USE_AUTOHEADER_OR_AUTOMAKE 1" >>confdefs.h # Make sure we can run config.sub. $SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 printf %s "checking build system type... " >&6; } if test ${ac_cv_build+y} then : printf %s "(cached) " >&6 else $as_nop ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 printf "%s\n" "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 printf %s "checking host system type... " >&6; } if test ${ac_cv_host+y} then : printf %s "(cached) " >&6 else $as_nop if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5 fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 printf "%s\n" "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac host_os_name=`echo $host_os | sed -e '1,$s/[0-9.]*$//g'` host_os_version=`echo $host_os | sed -e '1,$s/^[^0-9.]*//g' | awk -F. '{print $1 $2}'` # Linux often does not yield an OS version we can use... if test "x$host_os_version" = x then : host_os_version="0" fi INSTALL_STRIP="-s" OPTIM="${OPTIM:=}" CFLAGS="${CFLAGS:=}" CPPFLAGS="${CPPFLAGS:=}" CXXFLAGS="${CXXFLAGS:=}" LDFLAGS="${LDFLAGS:=}" # Check whether --enable-debug was given. if test ${enable_debug+y} then : enableval=$enable_debug; if eval "test x$enable_debug = xyes" then : INSTALL_STRIP="" OPTIM="-g " fi fi # Check whether --with-gui was given. if test ${with_gui+y} then : withval=$with_gui; fi for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AWK+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 printf "%s\n" "$AWK" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AWK" && break done ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then for ac_prog in clang cc gcc do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in clang cc gcc do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion -version; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 printf %s "checking whether the C compiler works... " >&6; } ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else $as_nop ac_file='' fi if test -z "$ac_file" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 printf %s "checking for C compiler default output file name... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 printf "%s\n" "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 printf %s "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 printf "%s\n" "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 printf %s "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 printf "%s\n" "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 printf %s "checking for suffix of object files... " >&6; } if test ${ac_cv_objext+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 printf "%s\n" "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 printf %s "checking whether the compiler supports GNU C... " >&6; } if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 printf %s "checking whether $CC accepts -g... " >&6; } if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 printf "%s\n" "$ac_cv_prog_cc_g" >&6; } if test $ac_test_CFLAGS; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi ac_prog_cc_stdc=no if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 printf %s "checking for $CC option to enable C11 features... " >&6; } if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c11_program _ACEOF for ac_arg in '' -std=gnu11 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } CC="$CC $ac_cv_prog_cc_c11" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 ac_prog_cc_stdc=c11 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 printf %s "checking for $CC option to enable C99 features... " >&6; } if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c99_program _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } CC="$CC $ac_cv_prog_cc_c99" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 ac_prog_cc_stdc=c99 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 printf %s "checking for $CC option to enable C89 features... " >&6; } if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c89_program _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } CC="$CC $ac_cv_prog_cc_c89" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 ac_prog_cc_stdc=c89 fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in clang++ c++ g++ do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CXX+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 printf "%s\n" "$CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in clang++ c++ g++ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CXX+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 printf "%s\n" "$ac_ct_CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C++" >&5 printf %s "checking whether the compiler supports GNU C++... " >&6; } if test ${ac_cv_cxx_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+y} ac_save_CXXFLAGS=$CXXFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 printf %s "checking whether $CXX accepts -g... " >&6; } if test ${ac_cv_prog_cxx_g+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_g=yes else $as_nop CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : else $as_nop ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 printf "%s\n" "$ac_cv_prog_cxx_g" >&6; } if test $ac_test_CXXFLAGS; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_prog_cxx_stdcxx=no if test x$ac_prog_cxx_stdcxx = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5 printf %s "checking for $CXX option to enable C++11 features... " >&6; } if test ${ac_cv_prog_cxx_11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cxx_11=no ac_save_CXX=$CXX cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_cxx_conftest_cxx11_program _ACEOF for ac_arg in '' -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x -qlanglvl=extended0x -AA do CXX="$ac_save_CXX $ac_arg" if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_cxx11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cxx_cxx11" != "xno" && break done rm -f conftest.$ac_ext CXX=$ac_save_CXX fi if test "x$ac_cv_prog_cxx_cxx11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cxx_cxx11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5 printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; } CXX="$CXX $ac_cv_prog_cxx_cxx11" fi ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 ac_prog_cxx_stdcxx=cxx11 fi fi if test x$ac_prog_cxx_stdcxx = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5 printf %s "checking for $CXX option to enable C++98 features... " >&6; } if test ${ac_cv_prog_cxx_98+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cxx_98=no ac_save_CXX=$CXX cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_cxx_conftest_cxx98_program _ACEOF for ac_arg in '' -std=gnu++98 -std=c++98 -qlanglvl=extended -AA do CXX="$ac_save_CXX $ac_arg" if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_cxx98=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cxx_cxx98" != "xno" && break done rm -f conftest.$ac_ext CXX=$ac_save_CXX fi if test "x$ac_cv_prog_cxx_cxx98" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cxx_cxx98" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5 printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; } CXX="$CXX $ac_cv_prog_cxx_cxx98" fi ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98 ac_prog_cxx_stdcxx=cxx98 fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 printf %s "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test ${ac_cv_prog_CPP+y} then : printf %s "(cached) " >&6 else $as_nop # Double quotes because $CC needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 printf "%s\n" "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_RANLIB+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 printf "%s\n" "$RANLIB" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_RANLIB+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 printf "%s\n" "$ac_ct_RANLIB" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_AR+y} then : printf %s "(cached) " >&6 else $as_nop case $AR in [\\/]* | ?:[\\/]*) ac_cv_path_AR="$AR" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_AR="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi AR=$ac_cv_path_AR if test -n "$AR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 printf "%s\n" "$AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi # Extract the first word of "cp", so it can be a program name with args. set dummy cp; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_CP+y} then : printf %s "(cached) " >&6 else $as_nop case $CP in [\\/]* | ?:[\\/]*) ac_cv_path_CP="$CP" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_CP="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi CP=$ac_cv_path_CP if test -n "$CP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CP" >&5 printf "%s\n" "$CP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi # Extract the first word of "fltk-config", so it can be a program name with args. set dummy fltk-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_FLTKCONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $FLTKCONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_FLTKCONFIG="$FLTKCONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_FLTKCONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi FLTKCONFIG=$ac_cv_path_FLTKCONFIG if test -n "$FLTKCONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $FLTKCONFIG" >&5 printf "%s\n" "$FLTKCONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for install-sh script" >&5 printf %s "checking for install-sh script... " >&6; } INSTALL="`pwd`/install-sh" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: using $INSTALL" >&5 printf "%s\n" "using $INSTALL" >&6; } # Extract the first word of "mkdir", so it can be a program name with args. set dummy mkdir; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_MKDIR+y} then : printf %s "(cached) " >&6 else $as_nop case $MKDIR in [\\/]* | ?:[\\/]*) ac_cv_path_MKDIR="$MKDIR" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_MKDIR="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi MKDIR=$ac_cv_path_MKDIR if test -n "$MKDIR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR" >&5 printf "%s\n" "$MKDIR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi # Extract the first word of "rm", so it can be a program name with args. set dummy rm; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_RM+y} then : printf %s "(cached) " >&6 else $as_nop case $RM in [\\/]* | ?:[\\/]*) ac_cv_path_RM="$RM" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_RM="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi RM=$ac_cv_path_RM if test -n "$RM"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RM" >&5 printf "%s\n" "$RM" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_PKGCONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $PKGCONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKGCONFIG="$PKGCONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_PKGCONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKGCONFIG=$ac_cv_path_PKGCONFIG if test -n "$PKGCONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKGCONFIG" >&5 printf "%s\n" "$PKGCONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_path_PKGCONFIG"; then ac_pt_PKGCONFIG=$PKGCONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_ac_pt_PKGCONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $ac_pt_PKGCONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKGCONFIG="$ac_pt_PKGCONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKGCONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKGCONFIG=$ac_cv_path_ac_pt_PKGCONFIG if test -n "$ac_pt_PKGCONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKGCONFIG" >&5 printf "%s\n" "$ac_pt_PKGCONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_pt_PKGCONFIG" = x; then PKGCONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKGCONFIG=$ac_pt_PKGCONFIG fi else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi if test x$PKGCONFIG = x then : as_fn_error $? "pkg-config is required for library checks." "$LINENO" 5 fi if test "$ac_cv_prog_ranlib" = ":" then : ARFLAGS="crs" else $as_nop ARFLAGS="cr" fi ac_header= ac_cache= for ac_item in $ac_header_c_list do if test $ac_cache; then ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then printf "%s\n" "#define $ac_item 1" >> confdefs.h fi ac_header= ac_cache= elif test $ac_header; then ac_cache=$ac_item else ac_header=$ac_item fi done if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes then : printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "strings.h" "ac_cv_header_strings_h" "$ac_includes_default" if test "x$ac_cv_header_strings_h" = xyes then : printf "%s\n" "#define HAVE_STRINGS_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "locale.h" "ac_cv_header_locale_h" "$ac_includes_default" if test "x$ac_cv_header_locale_h" = xyes then : printf "%s\n" "#define HAVE_LOCALE_H 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "strdup" "ac_cv_func_strdup" if test "x$ac_cv_func_strdup" = xyes then : printf "%s\n" "#define HAVE_STRDUP 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "strcasecmp" "ac_cv_func_strcasecmp" if test "x$ac_cv_func_strcasecmp" = xyes then : printf "%s\n" "#define HAVE_STRCASECMP 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "strncasecmp" "ac_cv_func_strncasecmp" if test "x$ac_cv_func_strncasecmp" = xyes then : printf "%s\n" "#define HAVE_STRNCASECMP 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat" if test "x$ac_cv_func_strlcat" = xyes then : printf "%s\n" "#define HAVE_STRLCAT 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy" if test "x$ac_cv_func_strlcpy" = xyes then : printf "%s\n" "#define HAVE_STRLCPY 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "snprintf" "ac_cv_func_snprintf" if test "x$ac_cv_func_snprintf" = xyes then : printf "%s\n" "#define HAVE_SNPRINTF 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf" if test "x$ac_cv_func_vsnprintf" = xyes then : printf "%s\n" "#define HAVE_VSNPRINTF 1" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tm_gmtoff member in tm structure" >&5 printf %s "checking for tm_gmtoff member in tm structure... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { struct tm t; int o = t.tm_gmtoff; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } printf "%s\n" "#define HAVE_TM_GMTOFF 1" >>confdefs.h else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext LDFLAGS="${LDFLAGS:=}" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pow in -lm" >&5 printf %s "checking for pow in -lm... " >&6; } if test ${ac_cv_lib_m_pow+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char pow (); int main (void) { return pow (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_m_pow=yes else $as_nop ac_cv_lib_m_pow=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_pow" >&5 printf "%s\n" "$ac_cv_lib_m_pow" >&6; } if test "x$ac_cv_lib_m_pow" = xyes then : printf "%s\n" "#define HAVE_LIBM 1" >>confdefs.h LIBS="-lm $LIBS" fi # Check whether --enable-largefile was given. if test ${enable_largefile+y} then : enableval=$enable_largefile; fi if test "$enable_largefile" != no; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 printf %s "checking for special C compiler options needed for large files... " >&6; } if test ${ac_cv_sys_largefile_CC+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_sys_largefile_CC=no if test "$GCC" != yes; then ac_save_CC=$CC while :; do # IRIX 6.2 and later do not support large files by default, # so use the C compiler's -n32 option if that helps. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : break fi rm -f core conftest.err conftest.$ac_objext conftest.beam CC="$CC -n32" if ac_fn_c_try_compile "$LINENO" then : ac_cv_sys_largefile_CC=' -n32'; break fi rm -f core conftest.err conftest.$ac_objext conftest.beam break done CC=$ac_save_CC rm -f conftest.$ac_ext fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 printf "%s\n" "$ac_cv_sys_largefile_CC" >&6; } if test "$ac_cv_sys_largefile_CC" != no; then CC=$CC$ac_cv_sys_largefile_CC fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 printf %s "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } if test ${ac_cv_sys_file_offset_bits+y} then : printf %s "(cached) " >&6 else $as_nop while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_sys_file_offset_bits=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _FILE_OFFSET_BITS 64 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_sys_file_offset_bits=64; break fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_sys_file_offset_bits=unknown break done fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 printf "%s\n" "$ac_cv_sys_file_offset_bits" >&6; } case $ac_cv_sys_file_offset_bits in #( no | unknown) ;; *) printf "%s\n" "#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits" >>confdefs.h ;; esac rm -rf conftest* if test $ac_cv_sys_file_offset_bits = unknown; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 printf %s "checking for _LARGE_FILES value needed for large files... " >&6; } if test ${ac_cv_sys_large_files+y} then : printf %s "(cached) " >&6 else $as_nop while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_sys_large_files=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _LARGE_FILES 1 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_sys_large_files=1; break fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_sys_large_files=unknown break done fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 printf "%s\n" "$ac_cv_sys_large_files" >&6; } case $ac_cv_sys_large_files in #( no | unknown) ;; *) printf "%s\n" "#define _LARGE_FILES $ac_cv_sys_large_files" >>confdefs.h ;; esac rm -rf conftest* fi fi LARGEFILE="" if test x$enable_largefile != xno then : LARGEFILE="-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE" if test x$ac_cv_sys_largefiles = x1 then : LARGEFILE="$LARGEFILE -D_LARGE_FILES" fi if test x$ac_cv_sys_file_offset_bits = x64 then : LARGEFILE="$LARGEFILE -D_FILE_OFFSET_BITS=64" fi fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cups-config", so it can be a program name with args. set dummy ${ac_tool_prefix}cups-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_CUPSCONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $CUPSCONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_CUPSCONFIG="$CUPSCONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_CUPSCONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi CUPSCONFIG=$ac_cv_path_CUPSCONFIG if test -n "$CUPSCONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CUPSCONFIG" >&5 printf "%s\n" "$CUPSCONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_path_CUPSCONFIG"; then ac_pt_CUPSCONFIG=$CUPSCONFIG # Extract the first word of "cups-config", so it can be a program name with args. set dummy cups-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_ac_pt_CUPSCONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $ac_pt_CUPSCONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_CUPSCONFIG="$ac_pt_CUPSCONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_CUPSCONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_CUPSCONFIG=$ac_cv_path_ac_pt_CUPSCONFIG if test -n "$ac_pt_CUPSCONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CUPSCONFIG" >&5 printf "%s\n" "$ac_pt_CUPSCONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_pt_CUPSCONFIG" = x; then CUPSCONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CUPSCONFIG=$ac_pt_CUPSCONFIG fi else CUPSCONFIG="$ac_cv_path_CUPSCONFIG" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for CUPS library v2.2 or higher" >&5 printf %s "checking for CUPS library v2.2 or higher... " >&6; } if $PKGCONFIG --exists cups then : CUPS_VERSION="$($PKGCONFIG --modversion cups)" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes, v$CUPS_VERSION" >&5 printf "%s\n" "yes, v$CUPS_VERSION" >&6; } CPPFLAGS="$CPPFLAGS $($PKGCONFIG --cflags cups)" LIBS="$LIBS $($PKGCONFIG --libs cups)" elif test "x$CUPSCONFIG" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } as_fn_error $? "Sorry, this software requires libcups-dev." "$LINENO" 5 else $as_nop CUPS_VERSION="$($CUPSCONFIG --api-version)" case "$CUPS_VERSION" in #( 1.* | 2.0 | 2.1) : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } as_fn_error $? "Sorry, you need CUPS 2.2.0 or higher." "$LINENO" 5 ;; #( *) : ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes, v$CUPS_VERSION" >&5 printf "%s\n" "yes, v$CUPS_VERSION" >&6; } CPPFLAGS="$CPPFLAGS $($CUPSCONFIG --cflags)" LDFLAGS="$LDFLAGS $($CUPSCONFIG --ldflags)" LIBS="$LIBS $($CUPSCONFIG --libs)" fi have_fltk=no POST=: if test "x$with_gui" != xno then : if test "x$FLTKCONFIG" != x then : have_fltk=yes CPPFLAGS="$CPPFLAGS $($FLTKCONFIG --use-images --cflags)" LIBS="$LIBS $($FLTKCONFIG --use-images --ldflags)" printf "%s\n" "#define HAVE_LIBFLTK 1" >>confdefs.h printf "%s\n" "#define HAVE_LIBJPEG 1" >>confdefs.h printf "%s\n" "#define HAVE_LIBPNG 1" >>confdefs.h POST="$FLTKCONFIG --post" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for XpmCreatePixmapFromData in -lXpm" >&5 printf %s "checking for XpmCreatePixmapFromData in -lXpm... " >&6; } if test ${ac_cv_lib_Xpm_XpmCreatePixmapFromData+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lXpm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char XpmCreatePixmapFromData (); int main (void) { return XpmCreatePixmapFromData (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_Xpm_XpmCreatePixmapFromData=yes else $as_nop ac_cv_lib_Xpm_XpmCreatePixmapFromData=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xpm_XpmCreatePixmapFromData" >&5 printf "%s\n" "$ac_cv_lib_Xpm_XpmCreatePixmapFromData" >&6; } if test "x$ac_cv_lib_Xpm_XpmCreatePixmapFromData" = xyes then : printf "%s\n" "#define HAVE_LIBXPM 1" >>confdefs.h LIBS="-lXpm $LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for XCreateBitmapFromData in -lX11" >&5 printf %s "checking for XCreateBitmapFromData in -lX11... " >&6; } if test ${ac_cv_lib_X11_XCreateBitmapFromData+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lX11 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char XCreateBitmapFromData (); int main (void) { return XCreateBitmapFromData (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_X11_XCreateBitmapFromData=yes else $as_nop ac_cv_lib_X11_XCreateBitmapFromData=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_X11_XCreateBitmapFromData" >&5 printf "%s\n" "$ac_cv_lib_X11_XCreateBitmapFromData" >&6; } if test "x$ac_cv_lib_X11_XCreateBitmapFromData" = xyes then : printf "%s\n" "#define HAVE_LIBX11 1" >>confdefs.h LIBS="-lX11 $LIBS" fi else $as_nop if test "x$with_gui" = xyes then : as_fn_error $? "FLTK not available." "$LINENO" 5 else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: FLTK not available so no GUI will be built." >&5 printf "%s\n" "$as_me: WARNING: FLTK not available so no GUI will be built." >&2;} fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libjpeg" >&5 printf %s "checking for libjpeg... " >&6; } if $PKGCONFIG --exists libjpeg then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; }; printf "%s\n" "#define HAVE_LIBJPEG 1" >>confdefs.h CPPFLAGS="$CPPFLAGS $($PKGCONFIG --cflags libjpeg)" LIBS="$LIBS $($PKGCONFIG --libs libjpeg)" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; }; fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zlib" >&5 printf %s "checking for zlib... " >&6; } if $PKGCONFIG --exists zlib then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; }; CPPFLAGS="$CPPFLAGS $($PKGCONFIG --cflags zlib)" LIBS="$($PKGCONFIG --libs zlib) $LIBS" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no pkg-config definition" >&5 printf "%s\n" "no pkg-config definition" >&6; }; ac_fn_c_check_header_compile "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" if test "x$ac_cv_header_zlib_h" = xyes then : fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gzgets in -lz" >&5 printf %s "checking for gzgets in -lz... " >&6; } if test ${ac_cv_lib_z_gzgets+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char gzgets (); int main (void) { return gzgets (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_z_gzgets=yes else $as_nop ac_cv_lib_z_gzgets=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzgets" >&5 printf "%s\n" "$ac_cv_lib_z_gzgets" >&6; } if test "x$ac_cv_lib_z_gzgets" = xyes then : LIBS="$LIBS -lz" else $as_nop as_fn_error $? "HTMLDOC requires zlib." "$LINENO" 5 fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libpng-1.6.x" >&5 printf %s "checking for libpng-1.6.x... " >&6; } if $PKGCONFIG --exists libpng16 then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; }; printf "%s\n" "#define HAVE_LIBPNG 1" >>confdefs.h CPPFLAGS="$CPPFLAGS $($PKGCONFIG --cflags libpng16)" LIBS="$($PKGCONFIG --libs libpng16) $LIBS" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; }; fi if test "$prefix" = "NONE" then : prefix="/usr/local" fi if test "$exec_prefix" = "NONE" then : exec_prefix="$prefix" fi if test "$bindir" = "\${exec_prefix}/bin" then : bindir="$exec_prefix/bin" fi if test "$datarootdir" = "\${prefix}/share" then : if test "$prefix" = "/" then : datarootdir="/usr/share" else $as_nop datarootdir="$prefix/share" fi fi if test "$datadir" = "\${prefix}/share" then : if test "$prefix" = "/" then : datadir="/usr/share" else $as_nop datadir="$prefix/share" fi elif test "$datadir" = "\${datarootdir}" then : datadir="$datarootdir" fi printf "%s\n" "#define DOCUMENTATION \"$datadir/doc/htmldoc\"" >>confdefs.h printf "%s\n" "#define HTML_DATA \"$datadir/htmldoc\"" >>confdefs.h # Check whether --enable-maintainer was given. if test ${enable_maintainer+y} then : enableval=$enable_maintainer; fi # Check whether --enable-sanitizer was given. if test ${enable_sanitizer+y} then : enableval=$enable_sanitizer; fi WARNINGS="" if test -n "$GXX" then : if test x$enable_sanitizer = xyes then : # Use -fsanitize=address with debugging... OPTIM="$OPTIM -g -fsanitize=address" else $as_nop # Otherwise use the Fortify enhancements to catch any unbounded # string operations... CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=3" CXXFLAGS="$CXXFLAGS -D_FORTIFY_SOURCE=3" fi if test -z "$OPTIM" then : OPTIM="-Os -g" fi WARNINGS="-Wall -Wunused" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu for warning in char-subscripts deprecated-declarations format-truncation format-y2k switch unused-result; do { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Wno-$warning" >&5 printf %s "checking whether compiler supports -Wno-$warning... " >&6; } OLDCXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS -Wno-$warning -Werror" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } WARNINGS="$WARNINGS -Wno-$warning" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CXXFLAGS="$OLDCXXFLAGS" done ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test x$enable_maintainer = xyes then : WARNINGS="$WARNINGS -Werror" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether GCC supports -fno-rtti" >&5 printf %s "checking whether GCC supports -fno-rtti... " >&6; } OLDCFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fno-rtti" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : CXXFLAGS="$CXXFLAGS -fno-rtti" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS="$OLDCFLAGS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether GCC supports -fno-exceptions" >&5 printf %s "checking whether GCC supports -fno-exceptions... " >&6; } OLDCFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fno-exceptions" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : CXXFLAGS="$CXXFLAGS -fno-exceptions" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS="$OLDCFLAGS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for OS-specific compiler options" >&5 printf %s "checking for OS-specific compiler options... " >&6; } case "$host_os_name" in #( linux*) : # Make sure we get the full set of 64-bit Linux APIs from the headers... CPPFLAGS="$CPPFLAGS -D__USE_MISC -D_GNU_SOURCE" # Mark read-only sections as relocatable to random addresses... LDFLAGS="$LDFLAGS -Wl,-z,relro,-z,now" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: -D__USE_MISC -D_GNU_SOURCE -Wl,-z,relro,-z,now" >&5 printf "%s\n" "-D__USE_MISC -D_GNU_SOURCE -Wl,-z,relro,-z,now" >&6; } ;; #( darwin*) : # When not building for debug, target macOS 11 or later, "universal" # binaries when possible... if echo "$CPPFLAGS $CFLAGS $LDFLAGS $OPTIM" | grep -q "\\-arch " then : # Don't add architecture/min-version flags if they are already present { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 printf "%s\n" "none" >&6; } elif echo "$CPPFLAGS $CFLAGS $LDFLAGS $OPTIM" | grep -q "\\-mmacosx-version-" then : # Don't add architecture/min-version flags if they are already present { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 printf "%s\n" "none" >&6; } elif test "$host_os_version" -ge 200 -a x$enable_debug != xyes then : # macOS 11.0 and higher support the Apple Silicon (arm64) CPUs OPTIM="$OPTIM -mmacosx-version-min=11.0 -arch x86_64 -arch arm64" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: -mmacosx-version-min=11.0 -arch x86_64 -arch arm64" >&5 printf "%s\n" "-mmacosx-version-min=11.0 -arch x86_64 -arch arm64" >&6; } else $as_nop # Don't add architecture/min-version flags if debug enabled { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 printf "%s\n" "none" >&6; } fi ;; #( *) : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 printf "%s\n" "none" >&6; } ;; #( *) : ;; esac fi if test "x$with_gui" != xno then : if test "x$FLTKCONFIG" != x then : OPTIM="`$FLTKCONFIG --cflags` $OPTIM" fi fi ac_config_files="$ac_config_files Makedefs Makefile desktop/htmldoc.plist" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 printf "%s\n" "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by HTMLDOC $as_me 1.9.20, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to . HTMLDOC home page: ." _ACEOF ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ HTMLDOC config.status 1.9.20 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" Copyright (C) 2021 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) printf "%s\n" "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) printf "%s\n" "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) printf "%s\n" "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX printf "%s\n" "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "Makedefs") CONFIG_FILES="$CONFIG_FILES Makedefs" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "desktop/htmldoc.plist") CONFIG_FILES="$CONFIG_FILES desktop/htmldoc.plist" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 printf "%s\n" "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`printf "%s\n" "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 printf "%s\n" "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using CFLAGS=$CFLAGS" >&5 printf "%s\n" "$as_me: Using CFLAGS=$CFLAGS" >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using CPPFLAGS=$CPPFLAGS" >&5 printf "%s\n" "$as_me: Using CPPFLAGS=$CPPFLAGS" >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using CXXFLAGS=$CXXFLAGS" >&5 printf "%s\n" "$as_me: Using CXXFLAGS=$CXXFLAGS" >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using LDFLAGS=$LDFLAGS" >&5 printf "%s\n" "$as_me: Using LDFLAGS=$LDFLAGS" >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using LIBS=$LIBS" >&5 printf "%s\n" "$as_me: Using LIBS=$LIBS" >&6;} htmldoc-1.9.20/configure.ac000066400000000000000000000260561472561501400155410ustar00rootroot00000000000000dnl dnl Configuration script for HTMLDOC, an HTML document processing program. dnl dnl Copyright © 2011-2024 by Michael R Sweet. dnl Copyright © 1997-2010 by Easy Software Products. dnl dnl This program is free software. Distribution and use rights are outlined in dnl the file "COPYING". dnl dnl *********************************************************************** dnl dnl Note: Using autoheader or automake on this project will break the HTMLDOC dnl build system. Use "autoconf -f" to regenerate the configure script if dnl you make changes to this file. dnl dnl *********************************************************************** dnl We need at least autoconf 2.69 for the AS_HELP_STRING macro... AC_PREREQ([2.69]) AC_INIT([HTMLDOC], [1.9.20], [https://github.com/michaelrsweet/htmldoc/issues], [htmldoc], [https://www.msweet.org/htmldoc]) AC_CONFIG_HEADERS([config.h]) dnl De])ne the version number... SVERSION="AC_PACKAGE_VERSION" AC_SUBST(SVERSION) AC_DEFINE_UNQUOTED(SVERSION, "$SVERSION") dnl GNU autoheader, automake, etc. will break the build system, this macro dnl causes the autoheader utility to fail... AC_DEFINE([HTMLDOC_DOES_NOT_USE_AUTOHEADER_OR_AUTOMAKE]) dnl Get the operating system and version number... dnl Get the build and host platforms and split the host_os value AC_CANONICAL_BUILD AC_CANONICAL_HOST [host_os_name=`echo $host_os | sed -e '1,$s/[0-9.]*$//g'`] [host_os_version=`echo $host_os | sed -e '1,$s/^[^0-9.]*//g' | awk -F. '{print $1 $2}'`] # Linux often does not yield an OS version we can use... AS_IF([test "x$host_os_version" = x], [ host_os_version="0" ]) dnl Clear the debugging options unless the user asks for them... INSTALL_STRIP="-s" AC_SUBST(INSTALL_STRIP) OPTIM="${OPTIM:=}" AC_SUBST(OPTIM) CFLAGS="${CFLAGS:=}" CPPFLAGS="${CPPFLAGS:=}" CXXFLAGS="${CXXFLAGS:=}" LDFLAGS="${LDFLAGS:=}" AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], [turn on debugging, default=no]), [ AS_IF([eval "test x$enable_debug = xyes"], [ INSTALL_STRIP="" OPTIM="-g " ]) ]) AC_ARG_WITH(gui, AS_HELP_STRING([--without-gui], [do not compile the GUI version of HTMLDOC, default=yes])) dnl Checks for programs... AC_PROG_AWK AC_PROG_CC(clang cc gcc) AC_PROG_CXX(clang++ c++ g++) AC_PROG_CPP AC_PROG_RANLIB AC_PATH_PROG(AR,ar) AC_PATH_PROG(CP,cp) AC_PATH_PROG(FLTKCONFIG,fltk-config) AC_MSG_CHECKING(for install-sh script) INSTALL="`pwd`/install-sh" AC_SUBST(INSTALL) AC_MSG_RESULT(using $INSTALL) AC_PATH_PROG(MKDIR,mkdir) AC_PATH_PROG(RM,rm) AC_PATH_TOOL(PKGCONFIG, pkg-config) AS_IF([test x$PKGCONFIG = x], [ AC_MSG_ERROR([pkg-config is required for library checks.]) ]) dnl See whether we need a .exe extension on executables... AC_EXEEXT dnl Figure out the correct "ar" command flags... AS_IF([test "$ac_cv_prog_ranlib" = ":"], [ ARFLAGS="crs" ], [ ARFLAGS="cr" ]) AC_SUBST(ARFLAGS) dnl Checks for header files. AC_CHECK_HEADER(strings.h, AC_DEFINE(HAVE_STRINGS_H)) AC_CHECK_HEADER(locale.h, AC_DEFINE(HAVE_LOCALE_H)) dnl Checks for string functions. AC_CHECK_FUNCS(strdup strcasecmp strncasecmp strlcat strlcpy snprintf vsnprintf) dnl See whether the tm structure has the tm_gmtoff member... AC_MSG_CHECKING([for tm_gmtoff member in tm structure]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ struct tm t; int o = t.tm_gmtoff; ]])], [ AC_MSG_RESULT([yes]) AC_DEFINE(HAVE_TM_GMTOFF) ], [ AC_MSG_RESULT([no]) ]) dnl Check for libraries... LDFLAGS="${LDFLAGS:=}" AC_SUBST(LDFLAGS) dnl Math functions... AC_CHECK_LIB([m], [pow]) dnl Check for largefile support... AC_SYS_LARGEFILE LARGEFILE="" AS_IF([test x$enable_largefile != xno], [ LARGEFILE="-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE" AS_IF([test x$ac_cv_sys_largefiles = x1], [ LARGEFILE="$LARGEFILE -D_LARGE_FILES" ]) AS_IF([test x$ac_cv_sys_file_offset_bits = x64], [ LARGEFILE="$LARGEFILE -D_FILE_OFFSET_BITS=64" ]) ]) AC_SUBST(LARGEFILE) dnl Check for CUPS libraries... AC_PATH_TOOL([CUPSCONFIG], [cups-config]) AC_MSG_CHECKING([for CUPS library v2.2 or higher]) AS_IF([$PKGCONFIG --exists cups], [ CUPS_VERSION="$($PKGCONFIG --modversion cups)" AC_MSG_RESULT([yes, v$CUPS_VERSION]) CPPFLAGS="$CPPFLAGS $($PKGCONFIG --cflags cups)" LIBS="$LIBS $($PKGCONFIG --libs cups)" ], [test "x$CUPSCONFIG" = x], [ AC_MSG_RESULT(no) AC_MSG_ERROR([Sorry, this software requires libcups-dev.]) ], [ CUPS_VERSION="$($CUPSCONFIG --api-version)" AS_CASE(["$CUPS_VERSION"], [1.* | 2.0 | 2.1], [ AC_MSG_RESULT(no) AC_MSG_ERROR([Sorry, you need CUPS 2.2.0 or higher.]) ]) AC_MSG_RESULT([yes, v$CUPS_VERSION]) CPPFLAGS="$CPPFLAGS $($CUPSCONFIG --cflags)" LDFLAGS="$LDFLAGS $($CUPSCONFIG --ldflags)" LIBS="$LIBS $($CUPSCONFIG --libs)" ]) dnl Check for GUI libraries... have_fltk=no POST=: AS_IF([test "x$with_gui" != xno], [ AS_IF([test "x$FLTKCONFIG" != x], [ have_fltk=yes CPPFLAGS="$CPPFLAGS $($FLTKCONFIG --use-images --cflags)" LIBS="$LIBS $($FLTKCONFIG --use-images --ldflags)" AC_DEFINE([HAVE_LIBFLTK], [1], [Do we have the FLTK library?]) AC_DEFINE([HAVE_LIBJPEG], 1, [Have JPEG library?]) AC_DEFINE([HAVE_LIBPNG], 1, [Have PNG library?]) POST="$FLTKCONFIG --post" AC_CHECK_LIB(Xpm,XpmCreatePixmapFromData) AC_CHECK_LIB(X11,XCreateBitmapFromData) ], [ AS_IF([test "x$with_gui" = xyes], [ AC_MSG_ERROR([FLTK not available.]) ], [ AC_MSG_WARN([FLTK not available so no GUI will be built.]) ]) ]) ]) AC_SUBST(POST) dnl Check for image libraries... AC_MSG_CHECKING([for libjpeg]) AS_IF([$PKGCONFIG --exists libjpeg], [ AC_MSG_RESULT([yes]); AC_DEFINE([HAVE_LIBJPEG], 1, [Have JPEG library?]) CPPFLAGS="$CPPFLAGS $($PKGCONFIG --cflags libjpeg)" LIBS="$LIBS $($PKGCONFIG --libs libjpeg)" ], [ AC_MSG_RESULT([no]); ]) AC_MSG_CHECKING([for zlib]) AS_IF([$PKGCONFIG --exists zlib], [ AC_MSG_RESULT([yes]); CPPFLAGS="$CPPFLAGS $($PKGCONFIG --cflags zlib)" LIBS="$($PKGCONFIG --libs zlib) $LIBS" ], [ AC_MSG_RESULT([no pkg-config definition]); AC_CHECK_HEADER([zlib.h]) AC_CHECK_LIB([z], [gzgets], [ LIBS="$LIBS -lz" ], [ AC_MSG_ERROR([HTMLDOC requires zlib.]) ]) ]) AC_MSG_CHECKING([for libpng-1.6.x]) AS_IF([$PKGCONFIG --exists libpng16], [ AC_MSG_RESULT([yes]); AC_DEFINE([HAVE_LIBPNG], 1, [Have PNG library?]) CPPFLAGS="$CPPFLAGS $($PKGCONFIG --cflags libpng16)" LIBS="$($PKGCONFIG --libs libpng16) $LIBS" ], [ AC_MSG_RESULT([no]); ]) dnl Directories for config.h... AS_IF([test "$prefix" = "NONE"], [ prefix="/usr/local" ]) AS_IF([test "$exec_prefix" = "NONE"], [ exec_prefix="$prefix" ]) AS_IF([test "$bindir" = "\${exec_prefix}/bin"], [ bindir="$exec_prefix/bin" ]) AS_IF([test "$datarootdir" = "\${prefix}/share"], [ AS_IF([test "$prefix" = "/"], [ datarootdir="/usr/share" ], [ datarootdir="$prefix/share" ]) ]) AS_IF([test "$datadir" = "\${prefix}/share"], [ AS_IF([test "$prefix" = "/"], [ datadir="/usr/share" ], [ datadir="$prefix/share" ]) ], [test "$datadir" = "\${datarootdir}"], [ datadir="$datarootdir" ]) AC_DEFINE_UNQUOTED(DOCUMENTATION, "$datadir/doc/htmldoc") AC_DEFINE_UNQUOTED(HTML_DATA, "$datadir/htmldoc") dnl Update compiler options... AC_ARG_ENABLE(maintainer, AS_HELP_STRING([--enable-maintainer], [turn on maintainer mode, default=no])) AC_ARG_ENABLE(sanitizer, AS_HELP_STRING([--enable-sanitizer], [build with AddressSanitizer])) WARNINGS="" AC_SUBST(WARNINGS) AS_IF([test -n "$GXX"], [ AS_IF([test x$enable_sanitizer = xyes], [ # Use -fsanitize=address with debugging... OPTIM="$OPTIM -g -fsanitize=address" ], [ # Otherwise use the Fortify enhancements to catch any unbounded # string operations... CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=3" CXXFLAGS="$CXXFLAGS -D_FORTIFY_SOURCE=3" ]) dnl Set optimization flags... AS_IF([test -z "$OPTIM"], [ OPTIM="-Os -g" ]) dnl Show all standard warnings + unused variables when compiling... WARNINGS="-Wall -Wunused" dnl Drop some not-useful/unreliable warnings... AC_LANG_PUSH(C++) for warning in char-subscripts deprecated-declarations format-truncation format-y2k switch unused-result; do AC_MSG_CHECKING([whether compiler supports -Wno-$warning]) OLDCXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS -Wno-$warning -Werror" AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [ AC_MSG_RESULT([yes]) WARNINGS="$WARNINGS -Wno-$warning" ], [ AC_MSG_RESULT([no]) ]) CXXFLAGS="$OLDCXXFLAGS" done AC_LANG_POP() dnl Maintainer mode enables -Werror... AS_IF([test x$enable_maintainer = xyes], [ WARNINGS="$WARNINGS -Werror" ]) dnl See whether GCC supports -fno-rtti... AC_MSG_CHECKING([whether GCC supports -fno-rtti]) OLDCFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fno-rtti" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [ CXXFLAGS="$CXXFLAGS -fno-rtti" AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) ]) CFLAGS="$OLDCFLAGS" dnl See whether GCC supports -fno-exceptions... AC_MSG_CHECKING([whether GCC supports -fno-exceptions]) OLDCFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fno-exceptions" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [ CXXFLAGS="$CXXFLAGS -fno-exceptions" AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) ]) CFLAGS="$OLDCFLAGS" dnl OS-specific options... AC_MSG_CHECKING([for OS-specific compiler options]) AS_CASE(["$host_os_name"], [linux*], [ # Make sure we get the full set of 64-bit Linux APIs from the headers... CPPFLAGS="$CPPFLAGS -D__USE_MISC -D_GNU_SOURCE" # Mark read-only sections as relocatable to random addresses... LDFLAGS="$LDFLAGS -Wl,-z,relro,-z,now" AC_MSG_RESULT([-D__USE_MISC -D_GNU_SOURCE -Wl,-z,relro,-z,now]) ], [darwin*], [ # When not building for debug, target macOS 11 or later, "universal" # binaries when possible... AS_IF([echo "$CPPFLAGS $CFLAGS $LDFLAGS $OPTIM" | grep -q "\\-arch "], [ # Don't add architecture/min-version flags if they are already present AC_MSG_RESULT([none]) ], [echo "$CPPFLAGS $CFLAGS $LDFLAGS $OPTIM" | grep -q "\\-mmacosx-version-"], [ # Don't add architecture/min-version flags if they are already present AC_MSG_RESULT([none]) ], [test "$host_os_version" -ge 200 -a x$enable_debug != xyes], [ # macOS 11.0 and higher support the Apple Silicon (arm64) CPUs OPTIM="$OPTIM -mmacosx-version-min=11.0 -arch x86_64 -arch arm64" AC_MSG_RESULT([-mmacosx-version-min=11.0 -arch x86_64 -arch arm64]) ], [ # Don't add architecture/min-version flags if debug enabled AC_MSG_RESULT([none]) ]) ], [*], [ AC_MSG_RESULT([none]) ]) ]) AS_IF([test "x$with_gui" != xno], [ AS_IF([test "x$FLTKCONFIG" != x], [ OPTIM="`$FLTKCONFIG --cflags` $OPTIM" ]) ]) dnl Generate the top-level Makefile and Makedefs file... AC_CONFIG_FILES([Makedefs Makefile desktop/htmldoc.plist]) AC_OUTPUT AC_MSG_NOTICE([Using CFLAGS=$CFLAGS]) AC_MSG_NOTICE([Using CPPFLAGS=$CPPFLAGS]) AC_MSG_NOTICE([Using CXXFLAGS=$CXXFLAGS]) AC_MSG_NOTICE([Using LDFLAGS=$LDFLAGS]) AC_MSG_NOTICE([Using LIBS=$LIBS]) htmldoc-1.9.20/data/000077500000000000000000000000001472561501400141535ustar00rootroot00000000000000htmldoc-1.9.20/data/Makefile000066400000000000000000000015371472561501400156210ustar00rootroot00000000000000# # Makefile for HTMLDOC data files. # # Copyright 2011-2017 by Michael R Sweet. # Copyright 1997-2010 by Easy Software Products. # # This program is free software. Distribution and use rights are outlined in # the file "COPYING". # # # Include common definitions... # include ../Makedefs # # Character set/glyph files... # FILES = cp-1250 cp-1251 cp-1252 cp-1253 cp-1254 cp-1255 \ cp-1256 cp-1257 cp-1258 cp-874 \ iso-8859-1 iso-8859-14 iso-8859-15 iso-8859-2 iso-8859-3 \ iso-8859-4 iso-8859-5 iso-8859-6 iso-8859-7 iso-8859-8 \ iso-8859-9 \ koi8-r prolog.ps psglyphs # # Make everything... # all: # # Install everything... # install: $(INSTALL_DIR) $(BUILDROOT)$(datadir)/htmldoc/data for file in $(FILES); do \ $(INSTALL_DATA) $$file $(BUILDROOT)$(datadir)/htmldoc/data; \ done # # Clean out object and library files... # clean: htmldoc-1.9.20/data/cp-1250000066400000000000000000000033301472561501400150640ustar00rootroot0000000000000020 0020 21 0021 22 0022 23 0023 24 0024 25 0025 26 0026 27 0027 28 0028 29 0029 2A 002A 2B 002B 2C 002C 2D 002D 2E 002E 2F 002F 30 0030 31 0031 32 0032 33 0033 34 0034 35 0035 36 0036 37 0037 38 0038 39 0039 3A 003A 3B 003B 3C 003C 3D 003D 3E 003E 3F 003F 40 0040 41 0041 42 0042 43 0043 44 0044 45 0045 46 0046 47 0047 48 0048 49 0049 4A 004A 4B 004B 4C 004C 4D 004D 4E 004E 4F 004F 50 0050 51 0051 52 0052 53 0053 54 0054 55 0055 56 0056 57 0057 58 0058 59 0059 5A 005A 5B 005B 5C 005C 5D 005D 5E 005E 5F 005F 60 0060 61 0061 62 0062 63 0063 64 0064 65 0065 66 0066 67 0067 68 0068 69 0069 6A 006A 6B 006B 6C 006C 6D 006D 6E 006E 6F 006F 70 0070 71 0071 72 0072 73 0073 74 0074 75 0075 76 0076 77 0077 78 0078 79 0079 7A 007A 7B 007B 7C 007C 7D 007D 7E 007E 7F 007F 80 20AC 82 201A 84 201E 85 2026 86 2020 87 2021 89 2030 8A 0160 8B 2039 8C 015A 8D 0164 8E 017D 8F 0179 91 2018 92 2019 93 201C 94 201D 95 2022 96 2013 97 2014 99 2122 9A 0161 9B 203A 9C 015B 9D 0165 9E 017E 9F 017A A0 00A0 A1 02C7 A2 02D8 A3 0141 A4 00A4 A5 0104 A6 00A6 A7 00A7 A8 00A8 A9 00A9 AA 015E AB 00AB AC 00AC AD 00AD AE 00AE AF 017B B0 00B0 B1 00B1 B2 02DB B3 0142 B4 00B4 B5 00B5 B6 00B6 B7 00B7 B8 00B8 B9 0105 BA 015F BB 00BB BC 013D BD 02DD BE 013E BF 017C C0 0154 C1 00C1 C2 00C2 C3 0102 C4 00C4 C5 0139 C6 0106 C7 00C7 C8 010C C9 00C9 CA 0118 CB 00CB CC 011A CD 00CD CE 00CE CF 010E D0 0110 D1 0143 D2 0147 D3 00D3 D4 00D4 D5 0150 D6 00D6 D7 00D7 D8 0158 D9 016E DA 00DA DB 0170 DC 00DC DD 00DD DE 0162 DF 00DF E0 0155 E1 00E1 E2 00E2 E3 0103 E4 00E4 E5 013A E6 0107 E7 00E7 E8 010D E9 00E9 EA 0119 EB 00EB EC 011B ED 00ED EE 00EE EF 010F F0 0111 F1 0144 F2 0148 F3 00F3 F4 00F4 F5 0151 F6 00F6 F7 00F7 F8 0159 F9 016F FA 00FA FB 0171 FC 00FC FD 00FD FE 0163 FF 02D9 htmldoc-1.9.20/data/cp-1251000066400000000000000000000033701472561501400150710ustar00rootroot0000000000000020 0020 21 0021 22 0022 23 0023 24 0024 25 0025 26 0026 27 0027 28 0028 29 0029 2A 002A 2B 002B 2C 002C 2D 002D 2E 002E 2F 002F 30 0030 31 0031 32 0032 33 0033 34 0034 35 0035 36 0036 37 0037 38 0038 39 0039 3A 003A 3B 003B 3C 003C 3D 003D 3E 003E 3F 003F 40 0040 41 0041 42 0042 43 0043 44 0044 45 0045 46 0046 47 0047 48 0048 49 0049 4A 004A 4B 004B 4C 004C 4D 004D 4E 004E 4F 004F 50 0050 51 0051 52 0052 53 0053 54 0054 55 0055 56 0056 57 0057 58 0058 59 0059 5A 005A 5B 005B 5C 005C 5D 005D 5E 005E 5F 005F 60 0060 61 0061 62 0062 63 0063 64 0064 65 0065 66 0066 67 0067 68 0068 69 0069 6A 006A 6B 006B 6C 006C 6D 006D 6E 006E 6F 006F 70 0070 71 0071 72 0072 73 0073 74 0074 75 0075 76 0076 77 0077 78 0078 79 0079 7A 007A 7B 007B 7C 007C 7D 007D 7E 007E 7F 007F 80 0402 81 0403 82 201A 83 0453 84 201E 85 2026 86 2020 87 2021 88 20AC 89 2030 8A 0409 8B 2039 8C 040A 8D 040C 8E 040B 8F 040F 90 0452 91 2018 92 2019 93 201C 94 201D 95 2022 96 2013 97 2014 99 2122 9A 0459 9B 203A 9C 045A 9D 045C 9E 045B 9F 045F A0 00A0 A1 040E A2 045E A3 0408 A4 00A4 A5 0490 A6 00A6 A7 00A7 A8 0401 A9 00A9 AA 0404 AB 00AB AC 00AC AD 00AD AE 00AE AF 0407 B0 00B0 B1 00B1 B2 0406 B3 0456 B4 0491 B5 00B5 B6 00B6 B7 00B7 B8 0451 B9 2116 BA 0454 BB 00BB BC 0458 BD 0405 BE 0455 BF 0457 C0 0410 C1 0411 C2 0412 C3 0413 C4 0414 C5 0415 C6 0416 C7 0417 C8 0418 C9 0419 CA 041A CB 041B CC 041C CD 041D CE 041E CF 041F D0 0420 D1 0421 D2 0422 D3 0423 D4 0424 D5 0425 D6 0426 D7 0427 D8 0428 D9 0429 DA 042A DB 042B DC 042C DD 042D DE 042E DF 042F E0 0430 E1 0431 E2 0432 E3 0433 E4 0434 E5 0435 E6 0436 E7 0437 E8 0438 E9 0439 EA 043A EB 043B EC 043C ED 043D EE 043E EF 043F F0 0440 F1 0441 F2 0442 F3 0443 F4 0444 F5 0445 F6 0446 F7 0447 F8 0448 F9 0449 FA 044A FB 044B FC 044C FD 044D FE 044E FF 044F htmldoc-1.9.20/data/cp-1252000066400000000000000000000033301472561501400150660ustar00rootroot0000000000000020 0020 21 0021 22 0022 23 0023 24 0024 25 0025 26 0026 27 0027 28 0028 29 0029 2A 002A 2B 002B 2C 002C 2D 002D 2E 002E 2F 002F 30 0030 31 0031 32 0032 33 0033 34 0034 35 0035 36 0036 37 0037 38 0038 39 0039 3A 003A 3B 003B 3C 003C 3D 003D 3E 003E 3F 003F 40 0040 41 0041 42 0042 43 0043 44 0044 45 0045 46 0046 47 0047 48 0048 49 0049 4A 004A 4B 004B 4C 004C 4D 004D 4E 004E 4F 004F 50 0050 51 0051 52 0052 53 0053 54 0054 55 0055 56 0056 57 0057 58 0058 59 0059 5A 005A 5B 005B 5C 005C 5D 005D 5E 005E 5F 005F 60 0060 61 0061 62 0062 63 0063 64 0064 65 0065 66 0066 67 0067 68 0068 69 0069 6A 006A 6B 006B 6C 006C 6D 006D 6E 006E 6F 006F 70 0070 71 0071 72 0072 73 0073 74 0074 75 0075 76 0076 77 0077 78 0078 79 0079 7A 007A 7B 007B 7C 007C 7D 007D 7E 007E 7F 007F 80 20AC 82 201A 83 0192 84 201E 85 2026 86 2020 87 2021 88 02C6 89 2030 8A 0160 8B 2039 8C 0152 8E 017D 91 2018 92 2019 93 201C 94 201D 95 2022 96 2013 97 2014 98 02DC 99 2122 9A 0161 9B 203A 9C 0153 9E 017E 9F 0178 A0 00A0 A1 00A1 A2 00A2 A3 00A3 A4 00A4 A5 00A5 A6 00A6 A7 00A7 A8 00A8 A9 00A9 AA 00AA AB 00AB AC 00AC AD 00AD AE 00AE AF 00AF B0 00B0 B1 00B1 B2 00B2 B3 00B3 B4 00B4 B5 00B5 B6 00B6 B7 00B7 B8 00B8 B9 00B9 BA 00BA BB 00BB BC 00BC BD 00BD BE 00BE BF 00BF C0 00C0 C1 00C1 C2 00C2 C3 00C3 C4 00C4 C5 00C5 C6 00C6 C7 00C7 C8 00C8 C9 00C9 CA 00CA CB 00CB CC 00CC CD 00CD CE 00CE CF 00CF D0 00D0 D1 00D1 D2 00D2 D3 00D3 D4 00D4 D5 00D5 D6 00D6 D7 00D7 D8 00D8 D9 00D9 DA 00DA DB 00DB DC 00DC DD 00DD DE 00DE DF 00DF E0 00E0 E1 00E1 E2 00E2 E3 00E3 E4 00E4 E5 00E5 E6 00E6 E7 00E7 E8 00E8 E9 00E9 EA 00EA EB 00EB EC 00EC ED 00ED EE 00EE EF 00EF F0 00F0 F1 00F1 F2 00F2 F3 00F3 F4 00F4 F5 00F5 F6 00F6 F7 00F7 F8 00F8 F9 00F9 FA 00FA FB 00FB FC 00FC FD 00FD FE 00FE FF 00FF htmldoc-1.9.20/data/cp-1253000066400000000000000000000031701472561501400150710ustar00rootroot0000000000000020 0020 21 0021 22 0022 23 0023 24 0024 25 0025 26 0026 27 0027 28 0028 29 0029 2A 002A 2B 002B 2C 002C 2D 002D 2E 002E 2F 002F 30 0030 31 0031 32 0032 33 0033 34 0034 35 0035 36 0036 37 0037 38 0038 39 0039 3A 003A 3B 003B 3C 003C 3D 003D 3E 003E 3F 003F 40 0040 41 0041 42 0042 43 0043 44 0044 45 0045 46 0046 47 0047 48 0048 49 0049 4A 004A 4B 004B 4C 004C 4D 004D 4E 004E 4F 004F 50 0050 51 0051 52 0052 53 0053 54 0054 55 0055 56 0056 57 0057 58 0058 59 0059 5A 005A 5B 005B 5C 005C 5D 005D 5E 005E 5F 005F 60 0060 61 0061 62 0062 63 0063 64 0064 65 0065 66 0066 67 0067 68 0068 69 0069 6A 006A 6B 006B 6C 006C 6D 006D 6E 006E 6F 006F 70 0070 71 0071 72 0072 73 0073 74 0074 75 0075 76 0076 77 0077 78 0078 79 0079 7A 007A 7B 007B 7C 007C 7D 007D 7E 007E 7F 007F 80 20AC 82 201A 83 0192 84 201E 85 2026 86 2020 87 2021 89 2030 8B 2039 91 2018 92 2019 93 201C 94 201D 95 2022 96 2013 97 2014 99 2122 9B 203A A0 00A0 A1 0385 A2 0386 A3 00A3 A4 00A4 A5 00A5 A6 00A6 A7 00A7 A8 00A8 A9 00A9 AB 00AB AC 00AC AD 00AD AE 00AE AF 2015 B0 00B0 B1 00B1 B2 00B2 B3 00B3 B4 0384 B5 00B5 B6 00B6 B7 00B7 B8 0388 B9 0389 BA 038A BB 00BB BC 038C BD 00BD BE 038E BF 038F C0 0390 C1 0391 C2 0392 C3 0393 C4 0394 C5 0395 C6 0396 C7 0397 C8 0398 C9 0399 CA 039A CB 039B CC 039C CD 039D CE 039E CF 039F D0 03A0 D1 03A1 D3 03A3 D4 03A4 D5 03A5 D6 03A6 D7 03A7 D8 03A8 D9 03A9 DA 03AA DB 03AB DC 03AC DD 03AD DE 03AE DF 03AF E0 03B0 E1 03B1 E2 03B2 E3 03B3 E4 03B4 E5 03B5 E6 03B6 E7 03B7 E8 03B8 E9 03B9 EA 03BA EB 03BB EC 03BC ED 03BD EE 03BE EF 03BF F0 03C0 F1 03C1 F2 03C2 F3 03C3 F4 03C4 F5 03C5 F6 03C6 F7 03C7 F8 03C8 F9 03C9 FA 03CA FB 03CB FC 03CC FD 03CD FE 03CE htmldoc-1.9.20/data/cp-1254000066400000000000000000000033101472561501400150660ustar00rootroot0000000000000020 0020 21 0021 22 0022 23 0023 24 0024 25 0025 26 0026 27 0027 28 0028 29 0029 2A 002A 2B 002B 2C 002C 2D 002D 2E 002E 2F 002F 30 0030 31 0031 32 0032 33 0033 34 0034 35 0035 36 0036 37 0037 38 0038 39 0039 3A 003A 3B 003B 3C 003C 3D 003D 3E 003E 3F 003F 40 0040 41 0041 42 0042 43 0043 44 0044 45 0045 46 0046 47 0047 48 0048 49 0049 4A 004A 4B 004B 4C 004C 4D 004D 4E 004E 4F 004F 50 0050 51 0051 52 0052 53 0053 54 0054 55 0055 56 0056 57 0057 58 0058 59 0059 5A 005A 5B 005B 5C 005C 5D 005D 5E 005E 5F 005F 60 0060 61 0061 62 0062 63 0063 64 0064 65 0065 66 0066 67 0067 68 0068 69 0069 6A 006A 6B 006B 6C 006C 6D 006D 6E 006E 6F 006F 70 0070 71 0071 72 0072 73 0073 74 0074 75 0075 76 0076 77 0077 78 0078 79 0079 7A 007A 7B 007B 7C 007C 7D 007D 7E 007E 7F 007F 80 20AC 82 201A 83 0192 84 201E 85 2026 86 2020 87 2021 88 02C6 89 2030 8A 0160 8B 2039 8C 0152 91 2018 92 2019 93 201C 94 201D 95 2022 96 2013 97 2014 98 02DC 99 2122 9A 0161 9B 203A 9C 0153 9F 0178 A0 00A0 A1 00A1 A2 00A2 A3 00A3 A4 00A4 A5 00A5 A6 00A6 A7 00A7 A8 00A8 A9 00A9 AA 00AA AB 00AB AC 00AC AD 00AD AE 00AE AF 00AF B0 00B0 B1 00B1 B2 00B2 B3 00B3 B4 00B4 B5 00B5 B6 00B6 B7 00B7 B8 00B8 B9 00B9 BA 00BA BB 00BB BC 00BC BD 00BD BE 00BE BF 00BF C0 00C0 C1 00C1 C2 00C2 C3 00C3 C4 00C4 C5 00C5 C6 00C6 C7 00C7 C8 00C8 C9 00C9 CA 00CA CB 00CB CC 00CC CD 00CD CE 00CE CF 00CF D0 011E D1 00D1 D2 00D2 D3 00D3 D4 00D4 D5 00D5 D6 00D6 D7 00D7 D8 00D8 D9 00D9 DA 00DA DB 00DB DC 00DC DD 0130 DE 015E DF 00DF E0 00E0 E1 00E1 E2 00E2 E3 00E3 E4 00E4 E5 00E5 E6 00E6 E7 00E7 E8 00E8 E9 00E9 EA 00EA EB 00EB EC 00EC ED 00ED EE 00EE EF 00EF F0 011F F1 00F1 F2 00F2 F3 00F3 F4 00F4 F5 00F5 F6 00F6 F7 00F7 F8 00F8 F9 00F9 FA 00FA FB 00FB FC 00FC FD 0131 FE 015F FF 00FF htmldoc-1.9.20/data/cp-1255000066400000000000000000000031101472561501400150650ustar00rootroot0000000000000020 0020 21 0021 22 0022 23 0023 24 0024 25 0025 26 0026 27 0027 28 0028 29 0029 2A 002A 2B 002B 2C 002C 2D 002D 2E 002E 2F 002F 30 0030 31 0031 32 0032 33 0033 34 0034 35 0035 36 0036 37 0037 38 0038 39 0039 3A 003A 3B 003B 3C 003C 3D 003D 3E 003E 3F 003F 40 0040 41 0041 42 0042 43 0043 44 0044 45 0045 46 0046 47 0047 48 0048 49 0049 4A 004A 4B 004B 4C 004C 4D 004D 4E 004E 4F 004F 50 0050 51 0051 52 0052 53 0053 54 0054 55 0055 56 0056 57 0057 58 0058 59 0059 5A 005A 5B 005B 5C 005C 5D 005D 5E 005E 5F 005F 60 0060 61 0061 62 0062 63 0063 64 0064 65 0065 66 0066 67 0067 68 0068 69 0069 6A 006A 6B 006B 6C 006C 6D 006D 6E 006E 6F 006F 70 0070 71 0071 72 0072 73 0073 74 0074 75 0075 76 0076 77 0077 78 0078 79 0079 7A 007A 7B 007B 7C 007C 7D 007D 7E 007E 7F 007F 80 20AC 82 201A 83 0192 84 201E 85 2026 86 2020 87 2021 88 02C6 89 2030 8B 2039 91 2018 92 2019 93 201C 94 201D 95 2022 96 2013 97 2014 98 02DC 99 2122 9B 203A A0 00A0 A1 00A1 A2 00A2 A3 00A3 A4 20AA A5 00A5 A6 00A6 A7 00A7 A8 00A8 A9 00A9 AA 00D7 AB 00AB AC 00AC AD 00AD AE 00AE AF 00AF B0 00B0 B1 00B1 B2 00B2 B3 00B3 B4 00B4 B5 00B5 B6 00B6 B7 00B7 B8 00B8 B9 00B9 BA 00F7 BB 00BB BC 00BC BD 00BD BE 00BE BF 00BF C0 05B0 C1 05B1 C2 05B2 C3 05B3 C4 05B4 C5 05B5 C6 05B6 C7 05B7 C8 05B8 C9 05B9 CB 05BB CC 05BC CD 05BD CE 05BE CF 05BF D0 05C0 D1 05C1 D2 05C2 D3 05C3 D4 05F0 D5 05F1 D6 05F2 D7 05F3 D8 05F4 E0 05D0 E1 05D1 E2 05D2 E3 05D3 E4 05D4 E5 05D5 E6 05D6 E7 05D7 E8 05D8 E9 05D9 EA 05DA EB 05DB EC 05DC ED 05DD EE 05DE EF 05DF F0 05E0 F1 05E1 F2 05E2 F3 05E3 F4 05E4 F5 05E5 F6 05E6 F7 05E7 F8 05E8 F9 05E9 FA 05EA FD 200E FE 200F htmldoc-1.9.20/data/cp-1256000066400000000000000000000034001472561501400150700ustar00rootroot0000000000000020 0020 21 0021 22 0022 23 0023 24 0024 25 0025 26 0026 27 0027 28 0028 29 0029 2A 002A 2B 002B 2C 002C 2D 002D 2E 002E 2F 002F 30 0030 31 0031 32 0032 33 0033 34 0034 35 0035 36 0036 37 0037 38 0038 39 0039 3A 003A 3B 003B 3C 003C 3D 003D 3E 003E 3F 003F 40 0040 41 0041 42 0042 43 0043 44 0044 45 0045 46 0046 47 0047 48 0048 49 0049 4A 004A 4B 004B 4C 004C 4D 004D 4E 004E 4F 004F 50 0050 51 0051 52 0052 53 0053 54 0054 55 0055 56 0056 57 0057 58 0058 59 0059 5A 005A 5B 005B 5C 005C 5D 005D 5E 005E 5F 005F 60 0060 61 0061 62 0062 63 0063 64 0064 65 0065 66 0066 67 0067 68 0068 69 0069 6A 006A 6B 006B 6C 006C 6D 006D 6E 006E 6F 006F 70 0070 71 0071 72 0072 73 0073 74 0074 75 0075 76 0076 77 0077 78 0078 79 0079 7A 007A 7B 007B 7C 007C 7D 007D 7E 007E 7F 007F 80 20AC 81 067E 82 201A 83 0192 84 201E 85 2026 86 2020 87 2021 88 02C6 89 2030 8A 0679 8B 2039 8C 0152 8D 0686 8E 0698 8F 0688 90 06AF 91 2018 92 2019 93 201C 94 201D 95 2022 96 2013 97 2014 98 06A9 99 2122 9A 0691 9B 203A 9C 0153 9D 200C 9E 200D 9F 06BA A0 00A0 A1 060C A2 00A2 A3 00A3 A4 00A4 A5 00A5 A6 00A6 A7 00A7 A8 00A8 A9 00A9 AA 06BE AB 00AB AC 00AC AD 00AD AE 00AE AF 00AF B0 00B0 B1 00B1 B2 00B2 B3 00B3 B4 00B4 B5 00B5 B6 00B6 B7 00B7 B8 00B8 B9 00B9 BA 061B BB 00BB BC 00BC BD 00BD BE 00BE BF 061F C0 06C1 C1 0621 C2 0622 C3 0623 C4 0624 C5 0625 C6 0626 C7 0627 C8 0628 C9 0629 CA 062A CB 062B CC 062C CD 062D CE 062E CF 062F D0 0630 D1 0631 D2 0632 D3 0633 D4 0634 D5 0635 D6 0636 D7 00D7 D8 0637 D9 0638 DA 0639 DB 063A DC 0640 DD 0641 DE 0642 DF 0643 E0 00E0 E1 0644 E2 00E2 E3 0645 E4 0646 E5 0647 E6 0648 E7 00E7 E8 00E8 E9 00E9 EA 00EA EB 00EB EC 0649 ED 064A EE 00EE EF 00EF F0 064B F1 064C F2 064D F3 064E F4 00F4 F5 064F F6 0650 F7 00F7 F8 0651 F9 00F9 FA 0652 FB 00FB FC 00FC FD 200E FE 200F FF 06D2 htmldoc-1.9.20/data/cp-1257000066400000000000000000000032401472561501400150730ustar00rootroot0000000000000020 0020 21 0021 22 0022 23 0023 24 0024 25 0025 26 0026 27 0027 28 0028 29 0029 2A 002A 2B 002B 2C 002C 2D 002D 2E 002E 2F 002F 30 0030 31 0031 32 0032 33 0033 34 0034 35 0035 36 0036 37 0037 38 0038 39 0039 3A 003A 3B 003B 3C 003C 3D 003D 3E 003E 3F 003F 40 0040 41 0041 42 0042 43 0043 44 0044 45 0045 46 0046 47 0047 48 0048 49 0049 4A 004A 4B 004B 4C 004C 4D 004D 4E 004E 4F 004F 50 0050 51 0051 52 0052 53 0053 54 0054 55 0055 56 0056 57 0057 58 0058 59 0059 5A 005A 5B 005B 5C 005C 5D 005D 5E 005E 5F 005F 60 0060 61 0061 62 0062 63 0063 64 0064 65 0065 66 0066 67 0067 68 0068 69 0069 6A 006A 6B 006B 6C 006C 6D 006D 6E 006E 6F 006F 70 0070 71 0071 72 0072 73 0073 74 0074 75 0075 76 0076 77 0077 78 0078 79 0079 7A 007A 7B 007B 7C 007C 7D 007D 7E 007E 7F 007F 80 20AC 82 201A 84 201E 85 2026 86 2020 87 2021 89 2030 8B 2039 8D 00A8 8E 02C7 8F 00B8 91 2018 92 2019 93 201C 94 201D 95 2022 96 2013 97 2014 99 2122 9B 203A 9D 00AF 9E 02DB A0 00A0 A2 00A2 A3 00A3 A4 00A4 A6 00A6 A7 00A7 A8 00D8 A9 00A9 AA 0156 AB 00AB AC 00AC AD 00AD AE 00AE AF 00C6 B0 00B0 B1 00B1 B2 00B2 B3 00B3 B4 00B4 B5 00B5 B6 00B6 B7 00B7 B8 00F8 B9 00B9 BA 0157 BB 00BB BC 00BC BD 00BD BE 00BE BF 00E6 C0 0104 C1 012E C2 0100 C3 0106 C4 00C4 C5 00C5 C6 0118 C7 0112 C8 010C C9 00C9 CA 0179 CB 0116 CC 0122 CD 0136 CE 012A CF 013B D0 0160 D1 0143 D2 0145 D3 00D3 D4 014C D5 00D5 D6 00D6 D7 00D7 D8 0172 D9 0141 DA 015A DB 016A DC 00DC DD 017B DE 017D DF 00DF E0 0105 E1 012F E2 0101 E3 0107 E4 00E4 E5 00E5 E6 0119 E7 0113 E8 010D E9 00E9 EA 017A EB 0117 EC 0123 ED 0137 EE 012B EF 013C F0 0161 F1 0144 F2 0146 F3 00F3 F4 014D F5 00F5 F6 00F6 F7 00F7 F8 0173 F9 0142 FA 015B FB 016B FC 00FC FD 017C FE 017E FF 02D9 htmldoc-1.9.20/data/cp-1258000066400000000000000000000032701472561501400150770ustar00rootroot0000000000000020 0020 21 0021 22 0022 23 0023 24 0024 25 0025 26 0026 27 0027 28 0028 29 0029 2A 002A 2B 002B 2C 002C 2D 002D 2E 002E 2F 002F 30 0030 31 0031 32 0032 33 0033 34 0034 35 0035 36 0036 37 0037 38 0038 39 0039 3A 003A 3B 003B 3C 003C 3D 003D 3E 003E 3F 003F 40 0040 41 0041 42 0042 43 0043 44 0044 45 0045 46 0046 47 0047 48 0048 49 0049 4A 004A 4B 004B 4C 004C 4D 004D 4E 004E 4F 004F 50 0050 51 0051 52 0052 53 0053 54 0054 55 0055 56 0056 57 0057 58 0058 59 0059 5A 005A 5B 005B 5C 005C 5D 005D 5E 005E 5F 005F 60 0060 61 0061 62 0062 63 0063 64 0064 65 0065 66 0066 67 0067 68 0068 69 0069 6A 006A 6B 006B 6C 006C 6D 006D 6E 006E 6F 006F 70 0070 71 0071 72 0072 73 0073 74 0074 75 0075 76 0076 77 0077 78 0078 79 0079 7A 007A 7B 007B 7C 007C 7D 007D 7E 007E 7F 007F 80 20AC 82 201A 83 0192 84 201E 85 2026 86 2020 87 2021 88 02C6 89 2030 8B 2039 8C 0152 91 2018 92 2019 93 201C 94 201D 95 2022 96 2013 97 2014 98 02DC 99 2122 9B 203A 9C 0153 9F 0178 A0 00A0 A1 00A1 A2 00A2 A3 00A3 A4 00A4 A5 00A5 A6 00A6 A7 00A7 A8 00A8 A9 00A9 AA 00AA AB 00AB AC 00AC AD 00AD AE 00AE AF 00AF B0 00B0 B1 00B1 B2 00B2 B3 00B3 B4 00B4 B5 00B5 B6 00B6 B7 00B7 B8 00B8 B9 00B9 BA 00BA BB 00BB BC 00BC BD 00BD BE 00BE BF 00BF C0 00C0 C1 00C1 C2 00C2 C3 0102 C4 00C4 C5 00C5 C6 00C6 C7 00C7 C8 00C8 C9 00C9 CA 00CA CB 00CB CC 0300 CD 00CD CE 00CE CF 00CF D0 0110 D1 00D1 D2 0309 D3 00D3 D4 00D4 D5 01A0 D6 00D6 D7 00D7 D8 00D8 D9 00D9 DA 00DA DB 00DB DC 00DC DD 01AF DE 0303 DF 00DF E0 00E0 E1 00E1 E2 00E2 E3 0103 E4 00E4 E5 00E5 E6 00E6 E7 00E7 E8 00E8 E9 00E9 EA 00EA EB 00EB EC 0301 ED 00ED EE 00EE EF 00EF F0 0111 F1 00F1 F2 0323 F3 00F3 F4 00F4 F5 01A1 F6 00F6 F7 00F7 F8 00F8 F9 00F9 FA 00FA FB 00FB FC 00FC FD 01B0 FE 20AB FF 00FF htmldoc-1.9.20/data/cp-874000066400000000000000000000030101472561501400150120ustar00rootroot0000000000000020 0020 21 0021 22 0022 23 0023 24 0024 25 0025 26 0026 27 0027 28 0028 29 0029 2A 002A 2B 002B 2C 002C 2D 002D 2E 002E 2F 002F 30 0030 31 0031 32 0032 33 0033 34 0034 35 0035 36 0036 37 0037 38 0038 39 0039 3A 003A 3B 003B 3C 003C 3D 003D 3E 003E 3F 003F 40 0040 41 0041 42 0042 43 0043 44 0044 45 0045 46 0046 47 0047 48 0048 49 0049 4A 004A 4B 004B 4C 004C 4D 004D 4E 004E 4F 004F 50 0050 51 0051 52 0052 53 0053 54 0054 55 0055 56 0056 57 0057 58 0058 59 0059 5A 005A 5B 005B 5C 005C 5D 005D 5E 005E 5F 005F 60 0060 61 0061 62 0062 63 0063 64 0064 65 0065 66 0066 67 0067 68 0068 69 0069 6A 006A 6B 006B 6C 006C 6D 006D 6E 006E 6F 006F 70 0070 71 0071 72 0072 73 0073 74 0074 75 0075 76 0076 77 0077 78 0078 79 0079 7A 007A 7B 007B 7C 007C 7D 007D 7E 007E 7F 007F 80 20AC 85 2026 91 2018 92 2019 93 201C 94 201D 95 2022 96 2013 97 2014 A0 00A0 A1 0E01 A2 0E02 A3 0E03 A4 0E04 A5 0E05 A6 0E06 A7 0E07 A8 0E08 A9 0E09 AA 0E0A AB 0E0B AC 0E0C AD 0E0D AE 0E0E AF 0E0F B0 0E10 B1 0E11 B2 0E12 B3 0E13 B4 0E14 B5 0E15 B6 0E16 B7 0E17 B8 0E18 B9 0E19 BA 0E1A BB 0E1B BC 0E1C BD 0E1D BE 0E1E BF 0E1F C0 0E20 C1 0E21 C2 0E22 C3 0E23 C4 0E24 C5 0E25 C6 0E26 C7 0E27 C8 0E28 C9 0E29 CA 0E2A CB 0E2B CC 0E2C CD 0E2D CE 0E2E CF 0E2F D0 0E30 D1 0E31 D2 0E32 D3 0E33 D4 0E34 D5 0E35 D6 0E36 D7 0E37 D8 0E38 D9 0E39 DA 0E3A DF 0E3F E0 0E40 E1 0E41 E2 0E42 E3 0E43 E4 0E44 E5 0E45 E6 0E46 E7 0E47 E8 0E48 E9 0E49 EA 0E4A EB 0E4B EC 0E4C ED 0E4D EE 0E4E EF 0E4F F0 0E50 F1 0E51 F2 0E52 F3 0E53 F4 0E54 F5 0E55 F6 0E56 F7 0E57 F8 0E58 F9 0E59 FA 0E5A FB 0E5B htmldoc-1.9.20/data/iso-8859-1000066400000000000000000000043641472561501400154500ustar00rootroot000000000000000x20 0x0020 0x21 0x0021 0x22 0x0022 0x23 0x0023 0x24 0x0024 0x25 0x0025 0x26 0x0026 0x27 0x0027 0x28 0x0028 0x29 0x0029 0x2a 0x002a 0x2b 0x002b 0x2c 0x002c 0x2d 0x002d 0x2e 0x002e 0x2f 0x002f 0x30 0x0030 0x31 0x0031 0x32 0x0032 0x33 0x0033 0x34 0x0034 0x35 0x0035 0x36 0x0036 0x37 0x0037 0x38 0x0038 0x39 0x0039 0x3a 0x003a 0x3b 0x003b 0x3c 0x003c 0x3d 0x003d 0x3e 0x003e 0x3f 0x003f 0x40 0x0040 0x41 0x0041 0x42 0x0042 0x43 0x0043 0x44 0x0044 0x45 0x0045 0x46 0x0046 0x47 0x0047 0x48 0x0048 0x49 0x0049 0x4a 0x004a 0x4b 0x004b 0x4c 0x004c 0x4d 0x004d 0x4e 0x004e 0x4f 0x004f 0x50 0x0050 0x51 0x0051 0x52 0x0052 0x53 0x0053 0x54 0x0054 0x55 0x0055 0x56 0x0056 0x57 0x0057 0x58 0x0058 0x59 0x0059 0x5a 0x005a 0x5b 0x005b 0x5c 0x005c 0x5d 0x005d 0x5e 0x005e 0x5f 0x005f 0x60 0x0060 0x61 0x0061 0x62 0x0062 0x63 0x0063 0x64 0x0064 0x65 0x0065 0x66 0x0066 0x67 0x0067 0x68 0x0068 0x69 0x0069 0x6a 0x006a 0x6b 0x006b 0x6c 0x006c 0x6d 0x006d 0x6e 0x006e 0x6f 0x006f 0x70 0x0070 0x71 0x0071 0x72 0x0072 0x73 0x0073 0x74 0x0074 0x75 0x0075 0x76 0x0076 0x77 0x0077 0x78 0x0078 0x79 0x0079 0x7a 0x007a 0x7b 0x007b 0x7c 0x007c 0x7d 0x007d 0x7e 0x007e 0xa0 0x00a0 0xa1 0x00a1 0xa2 0x00a2 0xa3 0x00a3 0xa4 0x00a4 0xa5 0x00a5 0xa6 0x00a6 0xa7 0x00a7 0xa8 0x00a8 0xa9 0x00a9 0xaa 0x00aa 0xab 0x00ab 0xac 0x00ac 0xad 0x00ad 0xae 0x00ae 0xaf 0x00af 0xb0 0x00b0 0xb1 0x00b1 0xb2 0x00b2 0xb3 0x00b3 0xb4 0x00b4 0xb5 0x00b5 0xb6 0x00b6 0xb7 0x00b7 0xb8 0x00b8 0xb9 0x00b9 0xba 0x00ba 0xbb 0x00bb 0xbc 0x00bc 0xbd 0x00bd 0xbe 0x00be 0xbf 0x00bf 0xc0 0x00c0 0xc1 0x00c1 0xc2 0x00c2 0xc3 0x00c3 0xc4 0x00c4 0xc5 0x00c5 0xc6 0x00c6 0xc7 0x00c7 0xc8 0x00c8 0xc9 0x00c9 0xca 0x00ca 0xcb 0x00cb 0xcc 0x00cc 0xcd 0x00cd 0xce 0x00ce 0xcf 0x00cf 0xd0 0x00d0 0xd1 0x00d1 0xd2 0x00d2 0xd3 0x00d3 0xd4 0x00d4 0xd5 0x00d5 0xd6 0x00d6 0xd7 0x00d7 0xd8 0x00d8 0xd9 0x00d9 0xda 0x00da 0xdb 0x00db 0xdc 0x00dc 0xdd 0x00dd 0xde 0x00de 0xdf 0x00df 0xe0 0x00e0 0xe1 0x00e1 0xe2 0x00e2 0xe3 0x00e3 0xe4 0x00e4 0xe5 0x00e5 0xe6 0x00e6 0xe7 0x00e7 0xe8 0x00e8 0xe9 0x00e9 0xea 0x00ea 0xeb 0x00eb 0xec 0x00ec 0xed 0x00ed 0xee 0x00ee 0xef 0x00ef 0xf0 0x00f0 0xf1 0x00f1 0xf2 0x00f2 0xf3 0x00f3 0xf4 0x00f4 0xf5 0x00f5 0xf6 0x00f6 0xf7 0x00f7 0xf8 0x00f8 0xf9 0x00f9 0xfa 0x00fa 0xfb 0x00fb 0xfc 0x00fc 0xfd 0x00fd 0xfe 0x00fe 0xff 0x00ff htmldoc-1.9.20/data/iso-8859-14000066400000000000000000000043661472561501400155360ustar00rootroot000000000000000x20 0x0020 0x21 0x0021 0x22 0x0022 0x23 0x0023 0x24 0x0024 0x25 0x0025 0x26 0x0026 0x27 0x0027 0x28 0x0028 0x29 0x0029 0x2a 0x002a 0x2b 0x002b 0x2c 0x002c 0x2d 0x002d 0x2e 0x002e 0x2f 0x002f 0x30 0x0030 0x31 0x0031 0x32 0x0032 0x33 0x0033 0x34 0x0034 0x35 0x0035 0x36 0x0036 0x37 0x0037 0x38 0x0038 0x39 0x0039 0x3a 0x003a 0x3b 0x003b 0x3c 0x003c 0x3d 0x003d 0x3e 0x003e 0x3f 0x003f 0x40 0x0040 0x41 0x0041 0x42 0x0042 0x43 0x0043 0x44 0x0044 0x45 0x0045 0x46 0x0046 0x47 0x0047 0x48 0x0048 0x49 0x0049 0x4a 0x004a 0x4b 0x004b 0x4c 0x004c 0x4d 0x004d 0x4e 0x004e 0x4f 0x004f 0x50 0x0050 0x51 0x0051 0x52 0x0052 0x53 0x0053 0x54 0x0054 0x55 0x0055 0x56 0x0056 0x57 0x0057 0x58 0x0058 0x59 0x0059 0x5a 0x005a 0x5b 0x005b 0x5c 0x005c 0x5d 0x005d 0x5e 0x005e 0x5f 0x005f 0x60 0x0060 0x61 0x0061 0x62 0x0062 0x63 0x0063 0x64 0x0064 0x65 0x0065 0x66 0x0066 0x67 0x0067 0x68 0x0068 0x69 0x0069 0x6a 0x006a 0x6b 0x006b 0x6c 0x006c 0x6d 0x006d 0x6e 0x006e 0x6f 0x006f 0x70 0x0070 0x71 0x0071 0x72 0x0072 0x73 0x0073 0x74 0x0074 0x75 0x0075 0x76 0x0076 0x77 0x0077 0x78 0x0078 0x79 0x0079 0x7a 0x007a 0x7b 0x007b 0x7c 0x007c 0x7d 0x007d 0x7e 0x007e 0xa0 0x00a0 0xa1 0x1e02 0xa2 0x1e03 0xa3 0x00a3 0xa4 0x010a 0xa5 0x010b 0xa6 0x1e0a 0xa7 0x00a7 0xa8 0x1e80 0xa9 0x00a9 0xaa 0x1e82 0xab 0x1e0b 0xac 0x1ef2 0xad 0x00ad 0xae 0x00ae 0xaf 0x0178 0xb0 0x1e1e 0xb1 0x1e1f 0xb2 0x0120 0xb3 0x0121 0xb4 0x1e40 0xb5 0x1e41 0xb6 0x00b6 0xb7 0x1e56 0xb8 0x1e81 0xb9 0x1e57 0xba 0x1e83 0xbb 0x1e60 0xbc 0x1ef3 0xbd 0x1e84 0xbe 0x1e85 0xbf 0x1e61 0xc0 0x00c0 0xc1 0x00c1 0xc2 0x00c2 0xc3 0x00c3 0xc4 0x00c4 0xc5 0x00c5 0xc6 0x00c6 0xc7 0x00c7 0xc8 0x00c8 0xc9 0x00c9 0xca 0x00ca 0xcb 0x00cb 0xcc 0x00cc 0xcd 0x00cd 0xce 0x00ce 0xcf 0x00cf 0xd0 0x0174 0xd1 0x00d1 0xd2 0x00d2 0xd3 0x00d3 0xd4 0x00d4 0xd5 0x00d5 0xd6 0x00d6 0xd7 0x1e6a 0xd8 0x00d8 0xd9 0x00d9 0xda 0x00da 0xdb 0x00db 0xdc 0x00dc 0xdd 0x00dd 0xde 0x0176 0xdf 0x00df 0xe0 0x00e0 0xe1 0x00e1 0xe2 0x00e2 0xe3 0x00e3 0xe4 0x00e4 0xe5 0x00e5 0xe6 0x00e6 0xe7 0x00e7 0xe8 0x00e8 0xe9 0x00e9 0xea 0x00ea 0xeb 0x00eb 0xec 0x00ec 0xed 0x00ed 0xee 0x00ee 0xef 0x00ef 0xf0 0x0175 0xf1 0x00f1 0xf2 0x00f2 0xf3 0x00f3 0xf4 0x00f4 0xf5 0x00f5 0xf6 0x00f6 0xf7 0x1e6b 0xf8 0x00f8 0xf9 0x00f9 0xfa 0x00fa 0xfb 0x00fb 0xfc 0x00fc 0xfd 0x00fd 0xfe 0x0177 0xff 0x00ff htmldoc-1.9.20/data/iso-8859-15000066400000000000000000000043661472561501400155370ustar00rootroot000000000000000x20 0x0020 0x21 0x0021 0x22 0x0022 0x23 0x0023 0x24 0x0024 0x25 0x0025 0x26 0x0026 0x27 0x0027 0x28 0x0028 0x29 0x0029 0x2a 0x002a 0x2b 0x002b 0x2c 0x002c 0x2d 0x002d 0x2e 0x002e 0x2f 0x002f 0x30 0x0030 0x31 0x0031 0x32 0x0032 0x33 0x0033 0x34 0x0034 0x35 0x0035 0x36 0x0036 0x37 0x0037 0x38 0x0038 0x39 0x0039 0x3a 0x003a 0x3b 0x003b 0x3c 0x003c 0x3d 0x003d 0x3e 0x003e 0x3f 0x003f 0x40 0x0040 0x41 0x0041 0x42 0x0042 0x43 0x0043 0x44 0x0044 0x45 0x0045 0x46 0x0046 0x47 0x0047 0x48 0x0048 0x49 0x0049 0x4a 0x004a 0x4b 0x004b 0x4c 0x004c 0x4d 0x004d 0x4e 0x004e 0x4f 0x004f 0x50 0x0050 0x51 0x0051 0x52 0x0052 0x53 0x0053 0x54 0x0054 0x55 0x0055 0x56 0x0056 0x57 0x0057 0x58 0x0058 0x59 0x0059 0x5a 0x005a 0x5b 0x005b 0x5c 0x005c 0x5d 0x005d 0x5e 0x005e 0x5f 0x005f 0x60 0x0060 0x61 0x0061 0x62 0x0062 0x63 0x0063 0x64 0x0064 0x65 0x0065 0x66 0x0066 0x67 0x0067 0x68 0x0068 0x69 0x0069 0x6a 0x006a 0x6b 0x006b 0x6c 0x006c 0x6d 0x006d 0x6e 0x006e 0x6f 0x006f 0x70 0x0070 0x71 0x0071 0x72 0x0072 0x73 0x0073 0x74 0x0074 0x75 0x0075 0x76 0x0076 0x77 0x0077 0x78 0x0078 0x79 0x0079 0x7a 0x007a 0x7b 0x007b 0x7c 0x007c 0x7d 0x007d 0x7e 0x007e 0xa0 0x00a0 0xa1 0x00a1 0xa2 0x00a2 0xa3 0x00a3 0xa4 0x20ac 0xa5 0x00a5 0xa6 0x0160 0xa7 0x00a7 0xa8 0x0161 0xa9 0x00a9 0xaa 0x00aa 0xab 0x00ab 0xac 0x00ac 0xad 0x00ad 0xae 0x00ae 0xaf 0x00af 0xb0 0x00b0 0xb1 0x00b1 0xb2 0x00b2 0xb3 0x00b3 0xb4 0x017d 0xb5 0x00b5 0xb6 0x00b6 0xb7 0x00b7 0xb8 0x017e 0xb9 0x00b9 0xba 0x00ba 0xbb 0x00bb 0xbc 0x0152 0xbd 0x0153 0xbe 0x0178 0xbf 0x00bf 0xc0 0x00c0 0xc1 0x00c1 0xc2 0x00c2 0xc3 0x00c3 0xc4 0x00c4 0xc5 0x00c5 0xc6 0x00c6 0xc7 0x00c7 0xc8 0x00c8 0xc9 0x00c9 0xca 0x00ca 0xcb 0x00cb 0xcc 0x00cc 0xcd 0x00cd 0xce 0x00ce 0xcf 0x00cf 0xd0 0x00d0 0xd1 0x00d1 0xd2 0x00d2 0xd3 0x00d3 0xd4 0x00d4 0xd5 0x00d5 0xd6 0x00d6 0xd7 0x00d7 0xd8 0x00d8 0xd9 0x00d9 0xda 0x00da 0xdb 0x00db 0xdc 0x00dc 0xdd 0x00dd 0xde 0x00de 0xdf 0x00df 0xe0 0x00e0 0xe1 0x00e1 0xe2 0x00e2 0xe3 0x00e3 0xe4 0x00e4 0xe5 0x00e5 0xe6 0x00e6 0xe7 0x00e7 0xe8 0x00e8 0xe9 0x00e9 0xea 0x00ea 0xeb 0x00eb 0xec 0x00ec 0xed 0x00ed 0xee 0x00ee 0xef 0x00ef 0xf0 0x00f0 0xf1 0x00f1 0xf2 0x00f2 0xf3 0x00f3 0xf4 0x00f4 0xf5 0x00f5 0xf6 0x00f6 0xf7 0x00f7 0xf8 0x00f8 0xf9 0x00f9 0xfa 0x00fa 0xfb 0x00fb 0xfc 0x00fc 0xfd 0x00fd 0xfe 0x00fe 0xff 0x00ff htmldoc-1.9.20/data/iso-8859-2000066400000000000000000000043641472561501400154510ustar00rootroot000000000000000x20 0x0020 0x21 0x0021 0x22 0x0022 0x23 0x0023 0x24 0x0024 0x25 0x0025 0x26 0x0026 0x27 0x0027 0x28 0x0028 0x29 0x0029 0x2a 0x002a 0x2b 0x002b 0x2c 0x002c 0x2d 0x002d 0x2e 0x002e 0x2f 0x002f 0x30 0x0030 0x31 0x0031 0x32 0x0032 0x33 0x0033 0x34 0x0034 0x35 0x0035 0x36 0x0036 0x37 0x0037 0x38 0x0038 0x39 0x0039 0x3a 0x003a 0x3b 0x003b 0x3c 0x003c 0x3d 0x003d 0x3e 0x003e 0x3f 0x003f 0x40 0x0040 0x41 0x0041 0x42 0x0042 0x43 0x0043 0x44 0x0044 0x45 0x0045 0x46 0x0046 0x47 0x0047 0x48 0x0048 0x49 0x0049 0x4a 0x004a 0x4b 0x004b 0x4c 0x004c 0x4d 0x004d 0x4e 0x004e 0x4f 0x004f 0x50 0x0050 0x51 0x0051 0x52 0x0052 0x53 0x0053 0x54 0x0054 0x55 0x0055 0x56 0x0056 0x57 0x0057 0x58 0x0058 0x59 0x0059 0x5a 0x005a 0x5b 0x005b 0x5c 0x005c 0x5d 0x005d 0x5e 0x005e 0x5f 0x005f 0x60 0x0060 0x61 0x0061 0x62 0x0062 0x63 0x0063 0x64 0x0064 0x65 0x0065 0x66 0x0066 0x67 0x0067 0x68 0x0068 0x69 0x0069 0x6a 0x006a 0x6b 0x006b 0x6c 0x006c 0x6d 0x006d 0x6e 0x006e 0x6f 0x006f 0x70 0x0070 0x71 0x0071 0x72 0x0072 0x73 0x0073 0x74 0x0074 0x75 0x0075 0x76 0x0076 0x77 0x0077 0x78 0x0078 0x79 0x0079 0x7a 0x007a 0x7b 0x007b 0x7c 0x007c 0x7d 0x007d 0x7e 0x007e 0xa0 0x00a0 0xa1 0x0104 0xa2 0x02d8 0xa3 0x0141 0xa4 0x00a4 0xa5 0x013d 0xa6 0x015a 0xa7 0x00a7 0xa8 0x00a8 0xa9 0x0160 0xaa 0x015e 0xab 0x0164 0xac 0x0179 0xad 0x00ad 0xae 0x017d 0xaf 0x017b 0xb0 0x00b0 0xb1 0x0105 0xb2 0x02db 0xb3 0x0142 0xb4 0x00b4 0xb5 0x013e 0xb6 0x015b 0xb7 0x02c7 0xb8 0x00b8 0xb9 0x0161 0xba 0x015f 0xbb 0x0165 0xbc 0x017a 0xbd 0x02dd 0xbe 0x017e 0xbf 0x017c 0xc0 0x0154 0xc1 0x00c1 0xc2 0x00c2 0xc3 0x0102 0xc4 0x00c4 0xc5 0x0139 0xc6 0x0106 0xc7 0x00c7 0xc8 0x010c 0xc9 0x00c9 0xca 0x0118 0xcb 0x00cb 0xcc 0x011a 0xcd 0x00cd 0xce 0x00ce 0xcf 0x010e 0xd0 0x0110 0xd1 0x0143 0xd2 0x0147 0xd3 0x00d3 0xd4 0x00d4 0xd5 0x0150 0xd6 0x00d6 0xd7 0x00d7 0xd8 0x0158 0xd9 0x016e 0xda 0x00da 0xdb 0x0170 0xdc 0x00dc 0xdd 0x00dd 0xde 0x0162 0xdf 0x00df 0xe0 0x0155 0xe1 0x00e1 0xe2 0x00e2 0xe3 0x0103 0xe4 0x00e4 0xe5 0x013a 0xe6 0x0107 0xe7 0x00e7 0xe8 0x010d 0xe9 0x00e9 0xea 0x0119 0xeb 0x00eb 0xec 0x011b 0xed 0x00ed 0xee 0x00ee 0xef 0x010f 0xf0 0x0111 0xf1 0x0144 0xf2 0x0148 0xf3 0x00f3 0xf4 0x00f4 0xf5 0x0151 0xf6 0x00f6 0xf7 0x00f7 0xf8 0x0159 0xf9 0x016f 0xfa 0x00fa 0xfb 0x0171 0xfc 0x00fc 0xfd 0x00fd 0xfe 0x0163 0xff 0x02d9 htmldoc-1.9.20/data/iso-8859-3000066400000000000000000000042401472561501400154430ustar00rootroot000000000000000x20 0x0020 0x21 0x0021 0x22 0x0022 0x23 0x0023 0x24 0x0024 0x25 0x0025 0x26 0x0026 0x27 0x0027 0x28 0x0028 0x29 0x0029 0x2a 0x002a 0x2b 0x002b 0x2c 0x002c 0x2d 0x002d 0x2e 0x002e 0x2f 0x002f 0x30 0x0030 0x31 0x0031 0x32 0x0032 0x33 0x0033 0x34 0x0034 0x35 0x0035 0x36 0x0036 0x37 0x0037 0x38 0x0038 0x39 0x0039 0x3a 0x003a 0x3b 0x003b 0x3c 0x003c 0x3d 0x003d 0x3e 0x003e 0x3f 0x003f 0x40 0x0040 0x41 0x0041 0x42 0x0042 0x43 0x0043 0x44 0x0044 0x45 0x0045 0x46 0x0046 0x47 0x0047 0x48 0x0048 0x49 0x0049 0x4a 0x004a 0x4b 0x004b 0x4c 0x004c 0x4d 0x004d 0x4e 0x004e 0x4f 0x004f 0x50 0x0050 0x51 0x0051 0x52 0x0052 0x53 0x0053 0x54 0x0054 0x55 0x0055 0x56 0x0056 0x57 0x0057 0x58 0x0058 0x59 0x0059 0x5a 0x005a 0x5b 0x005b 0x5c 0x005c 0x5d 0x005d 0x5e 0x005e 0x5f 0x005f 0x60 0x0060 0x61 0x0061 0x62 0x0062 0x63 0x0063 0x64 0x0064 0x65 0x0065 0x66 0x0066 0x67 0x0067 0x68 0x0068 0x69 0x0069 0x6a 0x006a 0x6b 0x006b 0x6c 0x006c 0x6d 0x006d 0x6e 0x006e 0x6f 0x006f 0x70 0x0070 0x71 0x0071 0x72 0x0072 0x73 0x0073 0x74 0x0074 0x75 0x0075 0x76 0x0076 0x77 0x0077 0x78 0x0078 0x79 0x0079 0x7a 0x007a 0x7b 0x007b 0x7c 0x007c 0x7d 0x007d 0x7e 0x007e 0xa0 0x00a0 0xa1 0x0126 0xa2 0x02d8 0xa3 0x00a3 0xa4 0x00a4 0xa6 0x0124 0xa7 0x00a7 0xa8 0x00a8 0xa9 0x0130 0xaa 0x015e 0xab 0x011e 0xac 0x0134 0xad 0x00ad 0xaf 0x017b 0xb0 0x00b0 0xb1 0x0127 0xb2 0x00b2 0xb3 0x00b3 0xb4 0x00b4 0xb5 0x00b5 0xb6 0x0125 0xb7 0x00b7 0xb8 0x00b8 0xb9 0x0131 0xba 0x015f 0xbb 0x011f 0xbc 0x0135 0xbd 0x00bd 0xbf 0x017c 0xc0 0x00c0 0xc1 0x00c1 0xc2 0x00c2 0xc4 0x00c4 0xc5 0x010a 0xc6 0x0108 0xc7 0x00c7 0xc8 0x00c8 0xc9 0x00c9 0xca 0x00ca 0xcb 0x00cb 0xcc 0x00cc 0xcd 0x00cd 0xce 0x00ce 0xcf 0x00cf 0xd1 0x00d1 0xd2 0x00d2 0xd3 0x00d3 0xd4 0x00d4 0xd5 0x0120 0xd6 0x00d6 0xd7 0x00d7 0xd8 0x011c 0xd9 0x00d9 0xda 0x00da 0xdb 0x00db 0xdc 0x00dc 0xdd 0x016c 0xde 0x015c 0xdf 0x00df 0xe0 0x00e0 0xe1 0x00e1 0xe2 0x00e2 0xe4 0x00e4 0xe5 0x010b 0xe6 0x0109 0xe7 0x00e7 0xe8 0x00e8 0xe9 0x00e9 0xea 0x00ea 0xeb 0x00eb 0xec 0x00ec 0xed 0x00ed 0xee 0x00ee 0xef 0x00ef 0xf1 0x00f1 0xf2 0x00f2 0xf3 0x00f3 0xf4 0x00f4 0xf5 0x0121 0xf6 0x00f6 0xf7 0x00f7 0xf8 0x011d 0xf9 0x00f9 0xfa 0x00fa 0xfb 0x00fb 0xfc 0x00fc 0xfd 0x016d 0xfe 0x015d 0xff 0x02d9 htmldoc-1.9.20/data/iso-8859-4000066400000000000000000000043641472561501400154530ustar00rootroot000000000000000x20 0x0020 0x21 0x0021 0x22 0x0022 0x23 0x0023 0x24 0x0024 0x25 0x0025 0x26 0x0026 0x27 0x0027 0x28 0x0028 0x29 0x0029 0x2a 0x002a 0x2b 0x002b 0x2c 0x002c 0x2d 0x002d 0x2e 0x002e 0x2f 0x002f 0x30 0x0030 0x31 0x0031 0x32 0x0032 0x33 0x0033 0x34 0x0034 0x35 0x0035 0x36 0x0036 0x37 0x0037 0x38 0x0038 0x39 0x0039 0x3a 0x003a 0x3b 0x003b 0x3c 0x003c 0x3d 0x003d 0x3e 0x003e 0x3f 0x003f 0x40 0x0040 0x41 0x0041 0x42 0x0042 0x43 0x0043 0x44 0x0044 0x45 0x0045 0x46 0x0046 0x47 0x0047 0x48 0x0048 0x49 0x0049 0x4a 0x004a 0x4b 0x004b 0x4c 0x004c 0x4d 0x004d 0x4e 0x004e 0x4f 0x004f 0x50 0x0050 0x51 0x0051 0x52 0x0052 0x53 0x0053 0x54 0x0054 0x55 0x0055 0x56 0x0056 0x57 0x0057 0x58 0x0058 0x59 0x0059 0x5a 0x005a 0x5b 0x005b 0x5c 0x005c 0x5d 0x005d 0x5e 0x005e 0x5f 0x005f 0x60 0x0060 0x61 0x0061 0x62 0x0062 0x63 0x0063 0x64 0x0064 0x65 0x0065 0x66 0x0066 0x67 0x0067 0x68 0x0068 0x69 0x0069 0x6a 0x006a 0x6b 0x006b 0x6c 0x006c 0x6d 0x006d 0x6e 0x006e 0x6f 0x006f 0x70 0x0070 0x71 0x0071 0x72 0x0072 0x73 0x0073 0x74 0x0074 0x75 0x0075 0x76 0x0076 0x77 0x0077 0x78 0x0078 0x79 0x0079 0x7a 0x007a 0x7b 0x007b 0x7c 0x007c 0x7d 0x007d 0x7e 0x007e 0xa0 0x00a0 0xa1 0x0104 0xa2 0x0138 0xa3 0x0156 0xa4 0x00a4 0xa5 0x0128 0xa6 0x013b 0xa7 0x00a7 0xa8 0x00a8 0xa9 0x0160 0xaa 0x0112 0xab 0x0122 0xac 0x0166 0xad 0x00ad 0xae 0x017d 0xaf 0x00af 0xb0 0x00b0 0xb1 0x0105 0xb2 0x02db 0xb3 0x0157 0xb4 0x00b4 0xb5 0x0129 0xb6 0x013c 0xb7 0x02c7 0xb8 0x00b8 0xb9 0x0161 0xba 0x0113 0xbb 0x0123 0xbc 0x0167 0xbd 0x014a 0xbe 0x017e 0xbf 0x014b 0xc0 0x0100 0xc1 0x00c1 0xc2 0x00c2 0xc3 0x00c3 0xc4 0x00c4 0xc5 0x00c5 0xc6 0x00c6 0xc7 0x012e 0xc8 0x010c 0xc9 0x00c9 0xca 0x0118 0xcb 0x00cb 0xcc 0x0116 0xcd 0x00cd 0xce 0x00ce 0xcf 0x012a 0xd0 0x0110 0xd1 0x0145 0xd2 0x014c 0xd3 0x0136 0xd4 0x00d4 0xd5 0x00d5 0xd6 0x00d6 0xd7 0x00d7 0xd8 0x00d8 0xd9 0x0172 0xda 0x00da 0xdb 0x00db 0xdc 0x00dc 0xdd 0x0168 0xde 0x016a 0xdf 0x00df 0xe0 0x0101 0xe1 0x00e1 0xe2 0x00e2 0xe3 0x00e3 0xe4 0x00e4 0xe5 0x00e5 0xe6 0x00e6 0xe7 0x012f 0xe8 0x010d 0xe9 0x00e9 0xea 0x0119 0xeb 0x00eb 0xec 0x0117 0xed 0x00ed 0xee 0x00ee 0xef 0x012b 0xf0 0x0111 0xf1 0x0146 0xf2 0x014d 0xf3 0x0137 0xf4 0x00f4 0xf5 0x00f5 0xf6 0x00f6 0xf7 0x00f7 0xf8 0x00f8 0xf9 0x0173 0xfa 0x00fa 0xfb 0x00fb 0xfc 0x00fc 0xfd 0x0169 0xfe 0x016b 0xff 0x02d9 htmldoc-1.9.20/data/iso-8859-5000066400000000000000000000043641472561501400154540ustar00rootroot000000000000000x20 0x0020 0x21 0x0021 0x22 0x0022 0x23 0x0023 0x24 0x0024 0x25 0x0025 0x26 0x0026 0x27 0x0027 0x28 0x0028 0x29 0x0029 0x2a 0x002a 0x2b 0x002b 0x2c 0x002c 0x2d 0x002d 0x2e 0x002e 0x2f 0x002f 0x30 0x0030 0x31 0x0031 0x32 0x0032 0x33 0x0033 0x34 0x0034 0x35 0x0035 0x36 0x0036 0x37 0x0037 0x38 0x0038 0x39 0x0039 0x3a 0x003a 0x3b 0x003b 0x3c 0x003c 0x3d 0x003d 0x3e 0x003e 0x3f 0x003f 0x40 0x0040 0x41 0x0041 0x42 0x0042 0x43 0x0043 0x44 0x0044 0x45 0x0045 0x46 0x0046 0x47 0x0047 0x48 0x0048 0x49 0x0049 0x4a 0x004a 0x4b 0x004b 0x4c 0x004c 0x4d 0x004d 0x4e 0x004e 0x4f 0x004f 0x50 0x0050 0x51 0x0051 0x52 0x0052 0x53 0x0053 0x54 0x0054 0x55 0x0055 0x56 0x0056 0x57 0x0057 0x58 0x0058 0x59 0x0059 0x5a 0x005a 0x5b 0x005b 0x5c 0x005c 0x5d 0x005d 0x5e 0x005e 0x5f 0x005f 0x60 0x0060 0x61 0x0061 0x62 0x0062 0x63 0x0063 0x64 0x0064 0x65 0x0065 0x66 0x0066 0x67 0x0067 0x68 0x0068 0x69 0x0069 0x6a 0x006a 0x6b 0x006b 0x6c 0x006c 0x6d 0x006d 0x6e 0x006e 0x6f 0x006f 0x70 0x0070 0x71 0x0071 0x72 0x0072 0x73 0x0073 0x74 0x0074 0x75 0x0075 0x76 0x0076 0x77 0x0077 0x78 0x0078 0x79 0x0079 0x7a 0x007a 0x7b 0x007b 0x7c 0x007c 0x7d 0x007d 0x7e 0x007e 0xa0 0x00a0 0xa1 0x0401 0xa2 0x0402 0xa3 0x0403 0xa4 0x0404 0xa5 0x0405 0xa6 0x0406 0xa7 0x0407 0xa8 0x0408 0xa9 0x0409 0xaa 0x040a 0xab 0x040b 0xac 0x040c 0xad 0x00ad 0xae 0x040e 0xaf 0x040f 0xb0 0x0410 0xb1 0x0411 0xb2 0x0412 0xb3 0x0413 0xb4 0x0414 0xb5 0x0415 0xb6 0x0416 0xb7 0x0417 0xb8 0x0418 0xb9 0x0419 0xba 0x041a 0xbb 0x041b 0xbc 0x041c 0xbd 0x041d 0xbe 0x041e 0xbf 0x041f 0xc0 0x0420 0xc1 0x0421 0xc2 0x0422 0xc3 0x0423 0xc4 0x0424 0xc5 0x0425 0xc6 0x0426 0xc7 0x0427 0xc8 0x0428 0xc9 0x0429 0xca 0x042a 0xcb 0x042b 0xcc 0x042c 0xcd 0x042d 0xce 0x042e 0xcf 0x042f 0xd0 0x0430 0xd1 0x0431 0xd2 0x0432 0xd3 0x0433 0xd4 0x0434 0xd5 0x0435 0xd6 0x0436 0xd7 0x0437 0xd8 0x0438 0xd9 0x0439 0xda 0x043a 0xdb 0x043b 0xdc 0x043c 0xdd 0x043d 0xde 0x043e 0xdf 0x043f 0xe0 0x0440 0xe1 0x0441 0xe2 0x0442 0xe3 0x0443 0xe4 0x0444 0xe5 0x0445 0xe6 0x0446 0xe7 0x0447 0xe8 0x0448 0xe9 0x0449 0xea 0x044a 0xeb 0x044b 0xec 0x044c 0xed 0x044d 0xee 0x044e 0xef 0x044f 0xf0 0x2116 0xf1 0x0451 0xf2 0x0452 0xf3 0x0453 0xf4 0x0454 0xf5 0x0455 0xf6 0x0456 0xf7 0x0457 0xf8 0x0458 0xf9 0x0459 0xfa 0x045a 0xfb 0x045b 0xfc 0x045c 0xfd 0x00a7 0xfe 0x045e 0xff 0x045f htmldoc-1.9.20/data/iso-8859-6000066400000000000000000000033301472561501400154450ustar00rootroot000000000000000x20 0x0020 0x21 0x0021 0x22 0x0022 0x23 0x0023 0x24 0x0024 0x25 0x0025 0x26 0x0026 0x27 0x0027 0x28 0x0028 0x29 0x0029 0x2a 0x002a 0x2b 0x002b 0x2c 0x002c 0x2d 0x002d 0x2e 0x002e 0x2f 0x002f 0x30 0x0660 0x31 0x0661 0x32 0x0662 0x33 0x0663 0x34 0x0664 0x35 0x0665 0x36 0x0666 0x37 0x0667 0x38 0x0668 0x39 0x0669 0x3a 0x003a 0x3b 0x003b 0x3c 0x003c 0x3d 0x003d 0x3e 0x003e 0x3f 0x003f 0x40 0x0040 0x41 0x0041 0x42 0x0042 0x43 0x0043 0x44 0x0044 0x45 0x0045 0x46 0x0046 0x47 0x0047 0x48 0x0048 0x49 0x0049 0x4a 0x004a 0x4b 0x004b 0x4c 0x004c 0x4d 0x004d 0x4e 0x004e 0x4f 0x004f 0x50 0x0050 0x51 0x0051 0x52 0x0052 0x53 0x0053 0x54 0x0054 0x55 0x0055 0x56 0x0056 0x57 0x0057 0x58 0x0058 0x59 0x0059 0x5a 0x005a 0x5b 0x005b 0x5c 0x005c 0x5d 0x005d 0x5e 0x005e 0x5f 0x005f 0x60 0x0060 0x61 0x0061 0x62 0x0062 0x63 0x0063 0x64 0x0064 0x65 0x0065 0x66 0x0066 0x67 0x0067 0x68 0x0068 0x69 0x0069 0x6a 0x006a 0x6b 0x006b 0x6c 0x006c 0x6d 0x006d 0x6e 0x006e 0x6f 0x006f 0x70 0x0070 0x71 0x0071 0x72 0x0072 0x73 0x0073 0x74 0x0074 0x75 0x0075 0x76 0x0076 0x77 0x0077 0x78 0x0078 0x79 0x0079 0x7a 0x007a 0x7b 0x007b 0x7c 0x007c 0x7d 0x007d 0x7e 0x007e 0xa0 0x00a0 0xa4 0x00a4 0xac 0x060c 0xad 0x00ad 0xbb 0x061b 0xbf 0x061f 0xc1 0x0621 0xc2 0x0622 0xc3 0x0623 0xc4 0x0624 0xc5 0x0625 0xc6 0x0626 0xc7 0x0627 0xc8 0x0628 0xc9 0x0629 0xca 0x062a 0xcb 0x062b 0xcc 0x062c 0xcd 0x062d 0xce 0x062e 0xcf 0x062f 0xd0 0x0630 0xd1 0x0631 0xd2 0x0632 0xd3 0x0633 0xd4 0x0634 0xd5 0x0635 0xd6 0x0636 0xd7 0x0637 0xd8 0x0638 0xd9 0x0639 0xda 0x063a 0xe0 0x0640 0xe1 0x0641 0xe2 0x0642 0xe3 0x0643 0xe4 0x0644 0xe5 0x0645 0xe6 0x0646 0xe7 0x0647 0xe8 0x0648 0xe9 0x0649 0xea 0x064a 0xeb 0x064b 0xec 0x064c 0xed 0x064d 0xee 0x064e 0xef 0x064f 0xf0 0x0650 0xf1 0x0651 0xf2 0x0652 htmldoc-1.9.20/data/iso-8859-7000066400000000000000000000042541472561501400154540ustar00rootroot000000000000000x20 0x0020 0x21 0x0021 0x22 0x0022 0x23 0x0023 0x24 0x0024 0x25 0x0025 0x26 0x0026 0x27 0x0027 0x28 0x0028 0x29 0x0029 0x2a 0x002a 0x2b 0x002b 0x2c 0x002c 0x2d 0x002d 0x2e 0x002e 0x2f 0x002f 0x30 0x0030 0x31 0x0031 0x32 0x0032 0x33 0x0033 0x34 0x0034 0x35 0x0035 0x36 0x0036 0x37 0x0037 0x38 0x0038 0x39 0x0039 0x3a 0x003a 0x3b 0x003b 0x3c 0x003c 0x3d 0x003d 0x3e 0x003e 0x3f 0x003f 0x40 0x0040 0x41 0x0041 0x42 0x0042 0x43 0x0043 0x44 0x0044 0x45 0x0045 0x46 0x0046 0x47 0x0047 0x48 0x0048 0x49 0x0049 0x4a 0x004a 0x4b 0x004b 0x4c 0x004c 0x4d 0x004d 0x4e 0x004e 0x4f 0x004f 0x50 0x0050 0x51 0x0051 0x52 0x0052 0x53 0x0053 0x54 0x0054 0x55 0x0055 0x56 0x0056 0x57 0x0057 0x58 0x0058 0x59 0x0059 0x5a 0x005a 0x5b 0x005b 0x5c 0x005c 0x5d 0x005d 0x5e 0x005e 0x5f 0x005f 0x60 0x0060 0x61 0x0061 0x62 0x0062 0x63 0x0063 0x64 0x0064 0x65 0x0065 0x66 0x0066 0x67 0x0067 0x68 0x0068 0x69 0x0069 0x6a 0x006a 0x6b 0x006b 0x6c 0x006c 0x6d 0x006d 0x6e 0x006e 0x6f 0x006f 0x70 0x0070 0x71 0x0071 0x72 0x0072 0x73 0x0073 0x74 0x0074 0x75 0x0075 0x76 0x0076 0x77 0x0077 0x78 0x0078 0x79 0x0079 0x7a 0x007a 0x7b 0x007b 0x7c 0x007c 0x7d 0x007d 0x7e 0x007e 0xa0 0x00a0 0xa1 0x02bd 0xa2 0x02bc 0xa3 0x00a3 0xa6 0x00a6 0xa7 0x00a7 0xa8 0x00a8 0xa9 0x00a9 0xab 0x00ab 0xac 0x00ac 0xad 0x00ad 0xaf 0x2015 0xb0 0x00b0 0xb1 0x00b1 0xb2 0x00b2 0xb3 0x00b3 0xb4 0x0384 0xb5 0x0385 0xb6 0x0386 0xb7 0x00b7 0xb8 0x0388 0xb9 0x0389 0xba 0x038a 0xbb 0x00bb 0xbc 0x038c 0xbd 0x00bd 0xbe 0x038e 0xbf 0x038f 0xc0 0x0390 0xc1 0x0391 0xc2 0x0392 0xc3 0x0393 0xc4 0x0394 0xc5 0x0395 0xc6 0x0396 0xc7 0x0397 0xc8 0x0398 0xc9 0x0399 0xca 0x039a 0xcb 0x039b 0xcc 0x039c 0xcd 0x039d 0xce 0x039e 0xcf 0x039f 0xd0 0x03a0 0xd1 0x03a1 0xd3 0x03a3 0xd4 0x03a4 0xd5 0x03a5 0xd6 0x03a6 0xd7 0x03a7 0xd8 0x03a8 0xd9 0x03a9 0xda 0x03aa 0xdb 0x03ab 0xdc 0x03ac 0xdd 0x03ad 0xde 0x03ae 0xdf 0x03af 0xe0 0x03b0 0xe1 0x03b1 0xe2 0x03b2 0xe3 0x03b3 0xe4 0x03b4 0xe5 0x03b5 0xe6 0x03b6 0xe7 0x03b7 0xe8 0x03b8 0xe9 0x03b9 0xea 0x03ba 0xeb 0x03bb 0xec 0x03bc 0xed 0x03bd 0xee 0x03be 0xef 0x03bf 0xf0 0x03c0 0xf1 0x03c1 0xf2 0x03c2 0xf3 0x03c3 0xf4 0x03c4 0xf5 0x03c5 0xf6 0x03c6 0xf7 0x03c7 0xf8 0x03c8 0xf9 0x03c9 0xfa 0x03ca 0xfb 0x03cb 0xfc 0x03cc 0xfd 0x03cd 0xfe 0x03ce htmldoc-1.9.20/data/iso-8859-8000066400000000000000000000034541472561501400154560ustar00rootroot000000000000000x20 0x0020 0x21 0x0021 0x22 0x0022 0x23 0x0023 0x24 0x0024 0x25 0x0025 0x26 0x0026 0x27 0x0027 0x28 0x0028 0x29 0x0029 0x2a 0x002a 0x2b 0x002b 0x2c 0x002c 0x2d 0x002d 0x2e 0x002e 0x2f 0x002f 0x30 0x0030 0x31 0x0031 0x32 0x0032 0x33 0x0033 0x34 0x0034 0x35 0x0035 0x36 0x0036 0x37 0x0037 0x38 0x0038 0x39 0x0039 0x3a 0x003a 0x3b 0x003b 0x3c 0x003c 0x3d 0x003d 0x3e 0x003e 0x3f 0x003f 0x40 0x0040 0x41 0x0041 0x42 0x0042 0x43 0x0043 0x44 0x0044 0x45 0x0045 0x46 0x0046 0x47 0x0047 0x48 0x0048 0x49 0x0049 0x4a 0x004a 0x4b 0x004b 0x4c 0x004c 0x4d 0x004d 0x4e 0x004e 0x4f 0x004f 0x50 0x0050 0x51 0x0051 0x52 0x0052 0x53 0x0053 0x54 0x0054 0x55 0x0055 0x56 0x0056 0x57 0x0057 0x58 0x0058 0x59 0x0059 0x5a 0x005a 0x5b 0x005b 0x5c 0x005c 0x5d 0x005d 0x5e 0x005e 0x5f 0x005f 0x60 0x0060 0x61 0x0061 0x62 0x0062 0x63 0x0063 0x64 0x0064 0x65 0x0065 0x66 0x0066 0x67 0x0067 0x68 0x0068 0x69 0x0069 0x6a 0x006a 0x6b 0x006b 0x6c 0x006c 0x6d 0x006d 0x6e 0x006e 0x6f 0x006f 0x70 0x0070 0x71 0x0071 0x72 0x0072 0x73 0x0073 0x74 0x0074 0x75 0x0075 0x76 0x0076 0x77 0x0077 0x78 0x0078 0x79 0x0079 0x7a 0x007a 0x7b 0x007b 0x7c 0x007c 0x7d 0x007d 0x7e 0x007e 0xa0 0x00a0 0xa2 0x00a2 0xa3 0x00a3 0xa4 0x00a4 0xa5 0x00a5 0xa6 0x00a6 0xa7 0x00a7 0xa8 0x00a8 0xa9 0x00a9 0xaa 0x00d7 0xab 0x00ab 0xac 0x00ac 0xad 0x00ad 0xae 0x00ae 0xaf 0x203e 0xb0 0x00b0 0xb1 0x00b1 0xb2 0x00b2 0xb3 0x00b3 0xb4 0x00b4 0xb5 0x00b5 0xb6 0x00b6 0xb7 0x00b7 0xb8 0x00b8 0xb9 0x00b9 0xba 0x00f7 0xbb 0x00bb 0xbc 0x00bc 0xbd 0x00bd 0xbe 0x00be 0xdf 0x2017 0xe0 0x05d0 0xe1 0x05d1 0xe2 0x05d2 0xe3 0x05d3 0xe4 0x05d4 0xe5 0x05d5 0xe6 0x05d6 0xe7 0x05d7 0xe8 0x05d8 0xe9 0x05d9 0xea 0x05da 0xeb 0x05db 0xec 0x05dc 0xed 0x05dd 0xee 0x05de 0xef 0x05df 0xf0 0x05e0 0xf1 0x05e1 0xf2 0x05e2 0xf3 0x05e3 0xf4 0x05e4 0xf5 0x05e5 0xf6 0x05e6 0xf7 0x05e7 0xf8 0x05e8 0xf9 0x05e9 0xfa 0x05ea htmldoc-1.9.20/data/iso-8859-9000066400000000000000000000043701472561501400154550ustar00rootroot000000000000000x20 0x0020 0x21 0x0021 0x22 0x0022 0x23 0x0023 0x24 0x0024 0x25 0x0025 0x26 0x0026 0x27 0x0027 0x28 0x0028 0x29 0x0029 0x2a 0x002a 0x2b 0x002b 0x2c 0x002c 0x2d 0x002d 0x2e 0x002e 0x2f 0x002f 0x30 0x0030 0x31 0x0031 0x32 0x0032 0x33 0x0033 0x34 0x0034 0x35 0x0035 0x36 0x0036 0x37 0x0037 0x38 0x0038 0x39 0x0039 0x3a 0x003a 0x3b 0x003b 0x3c 0x003c 0x3d 0x003d 0x3e 0x003e 0x3f 0x003f 0x40 0x0040 0x41 0x0041 0x42 0x0042 0x43 0x0043 0x44 0x0044 0x45 0x0045 0x46 0x0046 0x47 0x0047 0x48 0x0048 0x49 0x0049 0x4a 0x004a 0x4b 0x004b 0x4c 0x004c 0x4d 0x004d 0x4e 0x004e 0x4f 0x004f 0x50 0x0050 0x51 0x0051 0x52 0x0052 0x53 0x0053 0x54 0x0054 0x55 0x0055 0x56 0x0056 0x57 0x0057 0x58 0x0058 0x59 0x0059 0x5a 0x005a 0x5b 0x005b 0x5c 0x005c 0x5d 0x005d 0x5e 0x005e 0x5f 0x005f 0x60 0x0060 0x61 0x0061 0x62 0x0062 0x63 0x0063 0x64 0x0064 0x65 0x0065 0x66 0x0066 0x67 0x0067 0x68 0x0068 0x69 0x0069 0x6a 0x006a 0x6b 0x006b 0x6c 0x006c 0x6d 0x006d 0x6e 0x006e 0x6f 0x006f 0x70 0x0070 0x71 0x0071 0x72 0x0072 0x73 0x0073 0x74 0x0074 0x75 0x0075 0x76 0x0076 0x77 0x0077 0x78 0x0078 0x79 0x0079 0x7a 0x007a 0x7b 0x007b 0x7c 0x007c 0x7d 0x007d 0x7e 0x007e 0xa0 0x00a0 0xa1 0x00a1 0xa2 0x00a2 0xa3 0x00a3 0xa4 0x00a4 0xa5 0x00a5 0xa6 0x00a6 0xa7 0x00a7 0xa8 0x00a8 0xa9 0x00a9 0xaa 0x00aa 0xab 0x00ab 0xac 0x00ac 0xad 0x00ad 0xae 0x00ae 0xaf 0x00af 0xb0 0x00b0 0xb1 0x00b1 0xb2 0x00b2 0xb3 0x00b3 0xb4 0x00b4 0xb5 0x00b5 0xb6 0x00b6 0xb7 0x00b7 0xb8 0x00b8 0xb9 0x00b9 0xba 0x00ba 0xbb 0x00bb 0xbc 0x00bc 0xbd 0x00bd 0xbe 0x00be 0xbf 0x00bf 0xc0 0x00c0 0xc1 0x00c1 0xc2 0x00c2 0xc3 0x00c3 0xc4 0x00c4 0xc5 0x00c5 0xc6 0x00c6 0xc7 0x00c7 0xc8 0x00c8 0xc9 0x00c9 0xca 0x00ca 0xcb 0x00cb 0xcc 0x00cc 0xcd 0x00cd 0xce 0x00ce 0xcf 0x00cf 0xd0 0x011e 0xd1 0x00d1 0xd2 0x00d2 0xd3 0x00d3 0xd4 0x00d4 0xd5 0x00d5 0xd6 0x00d6 0xd7 0x00d7 0xd8 0x00d8 0xd9 0x00d9 0xda 0x00da 0xdb 0x00db 0xdc 0x00dc 0xdd 0x0130 0xde 0x015e 0xdf 0x00df 0xe0 0x00e0 0xe1 0x00e1 0xe2 0x00e2 0xe3 0x00e3 0xe4 0x00e4 0xe5 0x00e5 0xe6 0x00e6 0xe7 0x00e7 0xe8 0x00e8 0xe9 0x00e9 0xea 0x00ea 0xeb 0x00eb 0xec 0x00ec 0xed 0x00ed 0xee 0x00ee 0xef 0x00ef 0xf0 0x011f 0xf1 0x00f1 0xf2 0x00f2 0xf3 0x00f3 0xf4 0x00f4 0xf5 0x00f5 0xf6 0x00f6 0xf7 0x00f7 0xf8 0x00f8 0xf9 0x00f9 0xfa 0x00fa 0xfb 0x00fb 0xfc 0x00fc 0xfd 0x0131 0xfe 0x015f 0xff 0x00ff htmldoc-1.9.20/data/koi8-r000066400000000000000000000051641472561501400152150ustar00rootroot000000000000000x20 0x0020 0x21 0x0021 0x22 0x0022 0x23 0x0023 0x24 0x0024 0x25 0x0025 0x26 0x0026 0x27 0x0027 0x28 0x0028 0x29 0x0029 0x2a 0x002a 0x2b 0x002b 0x2c 0x002c 0x2d 0x002d 0x2e 0x002e 0x2f 0x002f 0x30 0x0030 0x31 0x0031 0x32 0x0032 0x33 0x0033 0x34 0x0034 0x35 0x0035 0x36 0x0036 0x37 0x0037 0x38 0x0038 0x39 0x0039 0x3a 0x003a 0x3b 0x003b 0x3c 0x003c 0x3d 0x003d 0x3e 0x003e 0x3f 0x003f 0x40 0x0040 0x41 0x0041 0x42 0x0042 0x43 0x0043 0x44 0x0044 0x45 0x0045 0x46 0x0046 0x47 0x0047 0x48 0x0048 0x49 0x0049 0x4a 0x004a 0x4b 0x004b 0x4c 0x004c 0x4d 0x004d 0x4e 0x004e 0x4f 0x004f 0x50 0x0050 0x51 0x0051 0x52 0x0052 0x53 0x0053 0x54 0x0054 0x55 0x0055 0x56 0x0056 0x57 0x0057 0x58 0x0058 0x59 0x0059 0x5a 0x005a 0x5b 0x005b 0x5c 0x005c 0x5d 0x005d 0x5e 0x005e 0x5f 0x005f 0x60 0x0060 0x61 0x0061 0x62 0x0062 0x63 0x0063 0x64 0x0064 0x65 0x0065 0x66 0x0066 0x67 0x0067 0x68 0x0068 0x69 0x0069 0x6a 0x006a 0x6b 0x006b 0x6c 0x006c 0x6d 0x006d 0x6e 0x006e 0x6f 0x006f 0x70 0x0070 0x71 0x0071 0x72 0x0072 0x73 0x0073 0x74 0x0074 0x75 0x0075 0x76 0x0076 0x77 0x0077 0x78 0x0078 0x79 0x0079 0x7a 0x007a 0x7b 0x007b 0x7c 0x007c 0x7d 0x007d 0x7e 0x007e 0x80 0x2500 0x81 0x2502 0x82 0x250C 0x83 0x2510 0x84 0x2514 0x85 0x2518 0x86 0x251C 0x87 0x2524 0x88 0x252C 0x89 0x2534 0x8A 0x253C 0x8B 0x2580 0x8C 0x2584 0x8D 0x2588 0x8E 0x258C 0x8F 0x2590 0x90 0x2591 0x91 0x2592 0x92 0x2593 0x93 0x2320 0x94 0x25A0 0x95 0x2219 0x96 0x221A 0x97 0x2248 0x98 0x2264 0x99 0x2265 0x9A 0x00A0 0x9B 0x2321 0x9C 0x00B0 0x9D 0x00B2 0x9E 0x00B7 0x9F 0x00F7 0xA0 0x2550 0xA1 0x2551 0xA2 0x2552 0xA3 0x0451 0xA4 0x2553 0xA5 0x2554 0xA6 0x2555 0xA7 0x2556 0xA8 0x2557 0xA9 0x2558 0xAA 0x2559 0xAB 0x255A 0xAC 0x255B 0xAD 0x255C 0xAE 0x255D 0xAF 0x255E 0xB0 0x255F 0xB1 0x2560 0xB2 0x2561 0xB3 0x0401 0xB4 0x2562 0xB5 0x2563 0xB6 0x2564 0xB7 0x2565 0xB8 0x2566 0xB9 0x2567 0xBA 0x2568 0xBB 0x2569 0xBC 0x256A 0xBD 0x256B 0xBE 0x256C 0xBF 0x00A9 0xC0 0x044E 0xC1 0x0430 0xC2 0x0431 0xC3 0x0446 0xC4 0x0434 0xC5 0x0435 0xC6 0x0444 0xC7 0x0433 0xC8 0x0445 0xC9 0x0438 0xCA 0x0439 0xCB 0x043A 0xCC 0x043B 0xCD 0x043C 0xCE 0x043D 0xCF 0x043E 0xD0 0x043F 0xD1 0x044F 0xD2 0x0440 0xD3 0x0441 0xD4 0x0442 0xD5 0x0443 0xD6 0x0436 0xD7 0x0432 0xD8 0x044C 0xD9 0x044B 0xDA 0x0437 0xDB 0x0448 0xDC 0x044D 0xDD 0x0449 0xDE 0x0447 0xDF 0x044A 0xE0 0x042E 0xE1 0x0410 0xE2 0x0411 0xE3 0x0426 0xE4 0x0414 0xE5 0x0415 0xE6 0x0424 0xE7 0x0413 0xE8 0x0425 0xE9 0x0418 0xEA 0x0419 0xEB 0x041A 0xEC 0x041B 0xED 0x041C 0xEE 0x041D 0xEF 0x041E 0xF0 0x041F 0xF1 0x042F 0xF2 0x0420 0xF3 0x0421 0xF4 0x0422 0xF5 0x0423 0xF6 0x0416 0xF7 0x0412 0xF8 0x042C 0xF9 0x042B 0xFA 0x0417 0xFB 0x0428 0xFC 0x042D 0xFD 0x0429 0xFE 0x0427 0xFF 0x042A htmldoc-1.9.20/data/prolog.ps000066400000000000000000000173521472561501400160310ustar00rootroot00000000000000%%BeginResource: procset htmldoc-device 1.8 24 % % The following procedures use setpagedevice, which is not supported by % Level 1 PostScript interpreters. For these systems, make setpagedevice % a no-op. % languagelevel 1 eq { /setpagedevice {pop} BD } if % % trayMap % % The trayMap variable defines an array of tray positions that are % used when looking up the "MEDIA POSITION nnn" page comment. The % array should be exactly 8 elements long. Unavailable trays should % be set to -1. % /trayMap [-1 -1 -1 -1 -1 -1 -1 -1] def product (Xerox DocuPrint N4025 PS3) eq { /trayMap [0 1 2 3 4 -1 -1 -1] def } if product (Xerox DocuPrint N2025 PS) eq { /trayMap [0 1 2 3 -1 -1 -1 -1] def } if product (HP LaserJet 5Si/5Si MX PS) eq { /trayMap [3 0 1 4 -1 -1 -1 -1] def } if product (HP LaserJet 2100 Series) eq { /trayMap [3 0 1 -1 -1 -1 -1 -1] def } if product (HP LaserJet 5000 Series) eq { /trayMap [3 0 1 4 -1 -1 -1 -1] def } if product (Xerox Document Centre 220/230) eq { /trayMap [1 2 3 4 -1 5 -1 -1] def } if product (Xerox Document Centre 332/340) eq { /trayMap [1 2 3 4 -1 5 -1 -1] def } if %product (Insert ModelName string here) eq % { /trayMap [-1 -1 -1 -1 -1 -1 -1 -1] def } if % % haveMediaColor % % The haveMediaColor variable defines whether a printer supports the % MediaColor attribute in the page device dictionary. % /haveMediaColor product (Xerox Document Centre 220/230) eq product (Xerox Document Centre 332/340) eq or product (Xerox DocuPrint 100 NPS PS2) eq or product (Xerox DocuPrint 2000 Series 100 EPS) eq or % product (Insert ModelName string here) eq or def % % haveMediaPosition % % The haveMediaPosition variable defines whether a printer supports % the MediaPosition attribute in the page device dictionary. % /haveMediaPosition product (Xerox DocuPrint N2025 PS) eq product (Xerox DocuPrint N4025 PS3) eq or product (Xerox Document Centre 220/230) eq or product (Xerox Document Centre 332/340) eq or product (HP LaserJet 5Si/5Si MX PS) eq or product (HP LaserJet 2100 Series) eq or product (HP LaserJet 5000 Series) eq or % product (Insert ModelName string here) eq or def % % haveMediaType % % The haveMediaType variable defines whether a printer supports % the MediaType attribute in the page device dictionary. % /haveMediaType product (Xerox DocuPrint N2025 PS) eq product (Xerox DocuPrint N4025 PS3) eq or product (Xerox Document Centre 220/230) eq or product (Xerox Document Centre 332/340) eq or product (HP LaserJet 5Si/5Si MX PS) eq or product (HP LaserJet 5000 Series) eq or product (Xerox DocuPrint 100 NPS PS2) eq or product (Xerox DocuPrint 2000 Series 100 EPS) eq or % product (Insert ModelName string here) eq or def % % haveDeferredMediaSelection % % The haveDeferredMediaSelection variable defines whether a printer supports % the DeferredMediaSelection attribute in the page device dictionary. % /haveDeferredMediaSelection product (Xerox DocuPrint N2025 PS) eq product (Xerox DocuPrint N4025 PS3) eq or product (HP LaserJet 5Si/5Si MX PS) eq or % product (Insert ModelName string here) eq or not def % % haveManualFeed % % The haveManualFeed variable defines whether a printer supports % the ManualFeed attribute in the page device dictionary. % /haveManualFeed product (Xerox DocuPrint N2025 PS) eq product (Xerox DocuPrint N4025 PS3) eq or product (HP LaserJet 5Si/5Si MX PS) eq or product (HP LaserJet 2100 Series) eq or product (HP LaserJet 5000 Series) eq or product (Xerox Document Centre 220/230) eq or product (Xerox Document Centre 332/340) eq or % product (Insert ModelName string here) eq or not def % % haveTraySwitch % % The haveTraySwitch variable defines whether a printer supports % the TraySwitch attribute in the page device dictionary. % /haveTraySwitch product (Xerox DocuPrint N2025 PS) eq product (Xerox DocuPrint N4025 PS3) eq or product (Xerox Document Centre 220/230) eq or product (Xerox Document Centre 332/340) eq or % product (Insert ModelName string here) eq or not def % % copies SetCopies - % % Set the number of copies to print. % /SetCopies { % Set the number of copies of each page. For Level 1 printers, use the % #copies variable; otherwise, use the NumCopies attribute in the % page device dictionary... languagelevel 1 eq { /#copies 1 index def } { 2 dict begin /NumCopies 1 index currentdict end setpagedevice } ifelse % Discard the argument on the stack... pop } BD % % duplex tumble SetDuplexMode - % % Set the duplexing mode; "duplex" and "tumble" are boolean values. % /CurrentDuplex false def /CurrentTumble false def /SetDuplexMode { % See if the duplex settings have changed; if not, don't change % them, otherwise some printers will reset their state and you % end up with single-sided output... 1 index CurrentDuplex ne 1 index CurrentTumble ne or { % Build a page device dictionary with the Duplex and Tumble % attributes... 4 dict begin /Duplex 2 index def /Tumble 1 index def currentdict end % Register the new attributes... setpagedevice } if % Save the arguments on the stack... /CurrentTumble exch def /CurrentDuplex exch def } BD % % string SetMediaColor - % % Set the media color for the output. % /CurrentMediaColor () def /SetMediaColor { dup CurrentMediaColor ne { haveMediaType { haveMediaColor { % Build a page device dictionary with the MediaColor attribute set to % the argument... 2 dict begin /MediaColor 1 index def currentdict end } { % Build a page device dictionary with the MediaType attribute set to % "Color"... 2 dict begin /MediaType (Color) def currentdict end } ifelse % Register any new attributes... setpagedevice } if } if % Save the media color on the stack... /CurrentMediaColor exch def } BD % % number SetMediaPosition - % % Set the media position (tray) for the output. % /CurrentMediaPosition -1 def /SetMediaPosition { dup CurrentMediaPosition ne { haveMediaPosition { % Add any tray position offset to the tray number. trayMap exch 1 sub get dup 0 ge { % Build a page device dictionary with the MediaPosition, % DeferredMediaSelection, ManualFeed, and TraySwitch attributes... 8 dict begin /MediaPosition 1 index def haveDeferredMediaSelection { /DeferredMediaSelection true def } if haveTraySwitch { /TraySwitch false def } if haveManualFeed { /ManualFeed false def } if currentdict end % Register the new attributes... setpagedevice } { pop } ifelse } if } if % Save the media position on the stack... /CurrentMediaPosition exch def } BD % % string SetMediaType - % % Set the media type for the output. Use a null string to do auto selection. % /CurrentMediaType () def /SetMediaType { dup CurrentMediaType ne { haveMediaType { % Build a page device dictionary with the MediaType attribute... 2 dict begin /MediaType 1 index def currentdict end % Register the new attribute... setpagedevice } if } if % Save the media type on the stack... /CurrentMediaType exch def } BD % % width height SetPageSize - % % Set the media size for the output. % /CurrentPageWidth 0 def /CurrentPageLength 0 def /SetPageSize { 1 index CurrentPageWidth ne 1 index CurrentPageLength ne or { % Put the arguments in an array... 2 copy 2 array astore % Build a page device dictionary with the PageSize and ImageableArea % attributes... 4 dict begin /PageSize 1 index def /ImageableArea null def currentdict end % Register the new attributes... setpagedevice % Don't need the page size array anymore... pop } if % Save the size on the stack... /CurrentPageLength exch def /CurrentPageWidth exch def } BD %%EndResource htmldoc-1.9.20/data/psglyphs000066400000000000000000000351541472561501400157570ustar00rootroot000000000000000020 space 0021 exclam 0022 quotedbl 0023 numbersign 0024 dollar 0025 percent 0026 ampersand 0027 quotesingle 0028 parenleft 0029 parenright 002a asterisk 002b plus 002c comma 002d hyphen 002e period 002f slash 0030 zero 0031 one 0032 two 0033 three 0034 four 0035 five 0036 six 0037 seven 0038 eight 0039 nine 003a colon 003b semicolon 003c less 003d equal 003e greater 003f question 0040 at 0041 A 0042 B 0043 C 0044 D 0045 E 0046 F 0047 G 0048 H 0049 I 004a J 004b K 004c L 004d M 004e N 004f O 0050 P 0051 Q 0052 R 0053 S 0054 T 0055 U 0056 V 0057 W 0058 X 0059 Y 005a Z 005b bracketleft 005c backslash 005d bracketright 005e asciicircum 005f underscore 0060 grave 0061 a 0062 b 0063 c 0064 d 0065 e 0066 f 0067 g 0068 h 0069 i 006a j 006b k 006c l 006d m 006e n 006f o 0070 p 0071 q 0072 r 0073 s 0074 t 0075 u 0076 v 0077 w 0078 x 0079 y 007a z 007b braceleft 007c bar 007d braceright 007e asciitilde 00a0 space 00a1 exclamdown 00a2 cent 00a3 sterling 00a4 currency 00a5 yen 00a6 brokenbar 00a7 section 00a8 dieresis 00a9 copyright 00aa ordfeminine 00ab guillemotleft 00ac logicalnot 00ad minus 00ae registered 00af macron 00b0 degree 00b1 plusminus 00b2 twosuperior 00b3 threesuperior 00b4 acute 00b5 mu 00b6 paragraph 00b7 periodcentered 00b8 cedilla 00b9 onesuperior 00ba ordmasculine 00bb guillemotright 00bc onequarter 00bd onehalf 00be threequarters 00bf questiondown 00c0 Agrave 00c1 Aacute 00c2 Acircumflex 00c3 Atilde 00c4 Adieresis 00c5 Aring 00c6 AE 00c7 Ccedilla 00c8 Egrave 00c9 Eacute 00ca Ecircumflex 00cb Edieresis 00cc Igrave 00cd Iacute 00ce Icircumflex 00cf Idieresis 00d0 Eth 00d1 Ntilde 00d2 Ograve 00d3 Oacute 00d4 Ocircumflex 00d5 Otilde 00d6 Odieresis 00d7 multiply 00d8 Oslash 00d9 Ugrave 00da Uacute 00db Ucircumflex 00dc Udieresis 00dd Yacute 00de Thorn 00df germandbls 00e0 agrave 00e1 aacute 00e2 acircumflex 00e3 atilde 00e4 adieresis 00e5 aring 00e6 ae 00e7 ccedilla 00e8 egrave 00e9 eacute 00ea ecircumflex 00eb edieresis 00ec igrave 00ed iacute 00ee icircumflex 00ef idieresis 00f0 eth 00f1 ntilde 00f2 ograve 00f3 oacute 00f4 ocircumflex 00f5 otilde 00f6 odieresis 00f7 divide 00f8 oslash 00f9 ugrave 00fa uacute 00fb ucircumflex 00fc udieresis 00fd yacute 00fe thorn 00ff ydieresis 0100 Amacron 0101 amacron 0102 Abreve 0103 abreve 0104 Aogonek 0105 aogonek 0106 Cacute 0107 cacute 0108 Ccircumflex 0109 ccircumflex 010a Cdotaccent 010b cdotaccent 010c Ccaron 010d ccaron 010e Dcaron 010f dcaron 0110 Dcroat 0111 dcroat 0112 Emacron 0113 emacron 0114 Ebreve 0115 ebreve 0116 Edotaccent 0117 edotaccent 0118 Eogonek 0119 eogonek 011a Ecaron 011b ecaron 011c Gcircumflex 011d gcircumflex 011e Gbreve 011f gbreve 0120 Gdotaccent 0121 gdotaccent 0122 Gcommaaccent 0123 gcommaaccent 0124 Hcircumflex 0125 hcircumflex 0126 Hbar 0127 hbar 0128 Itilde 0129 itilde 012a Imacron 012b imacron 012c Ibreve 012d ibreve 012e Iogonek 012f iogonek 0130 Idotaccent 0131 dotlessi 0132 IJ 0133 ij 0134 Jcircumflex 0135 jcircumflex 0136 Kcommaaccent 0137 kcommaaccent 0138 kgreenlandic 0139 Lacute 013a lacute 013b Lcommaaccent 013c lcommaaccent 013d Lcaron 013e lcaron 013f Ldot 0140 ldot 0141 Lslash 0142 lslash 0143 Nacute 0144 nacute 0145 Ncommaaccent 0146 ncommaaccent 0147 Ncaron 0148 ncaron 0149 napostrophe 014a Eng 014b eng 014c Omacron 014d omacron 014e Obreve 014f obreve 0150 Ohungarumlaut 0151 ohungarumlaut 0152 OE 0153 oe 0154 Racute 0155 racute 0156 Rcommaaccent 0157 rcommaaccent 0158 Rcaron 0159 rcaron 015a Sacute 015b sacute 015c Scircumflex 015d scircumflex 015e Scedilla 015f scedilla 0160 Scaron 0161 scaron 0162 Tcommaaccent 0163 tcommaaccent 0164 Tcaron 0165 tcaron 0166 Tbar 0167 tbar 0168 Utilde 0169 utilde 016a Umacron 016b umacron 016c Ubreve 016d ubreve 016e Uring 016f uring 0170 Uhungarumlaut 0171 uhungarumlaut 0172 Uogonek 0173 uogonek 0174 Wcircumflex 0175 wcircumflex 0176 Ycircumflex 0177 ycircumflex 0178 Ydieresis 0179 Zacute 017a zacute 017b Zdotaccent 017c zdotaccent 017d Zcaron 017e zcaron 017f longs 0192 florin 01a0 Ohorn 01a1 ohorn 01af Uhorn 01b0 uhorn 01e6 Gcaron 01e7 gcaron 01fa Aringacute 01fb aringacute 01fc AEacute 01fd aeacute 01fe Oslashacute 01ff oslashacute 0218 Scommaaccent 0219 scommaaccent 021a Tcommaaccent 021b tcommaaccent 02bc afii57929 02bd afii64937 02c6 circumflex 02c7 caron 02c9 macron 02d8 breve 02d9 dotaccent 02da ring 02db ogonek 02dc tilde 02dd hungarumlaut 0300 gravecomb 0301 acutecomb 0303 tildecomb 0309 hookabovecomb 0323 dotbelowcomb 0384 tonos 0385 dieresistonos 0386 Alphatonos 0387 anoteleia 0388 Epsilontonos 0389 Etatonos 038a Iotatonos 038c Omicrontonos 038e Upsilontonos 038f Omegatonos 0390 iotadieresistonos 0391 Alpha 0392 Beta 0393 Gamma 0394 Delta 0395 Epsilon 0396 Zeta 0397 Eta 0398 Theta 0399 Iota 039a Kappa 039b Lambda 039c Mu 039d Nu 039e Xi 039f Omicron 03a0 Pi 03a1 Rho 03a3 Sigma 03a4 Tau 03a5 Upsilon 03a6 Phi 03a7 Chi 03a8 Psi 03a9 Omega 03aa Iotadieresis 03ab Upsilondieresis 03ac alphatonos 03ad epsilontonos 03ae etatonos 03af iotatonos 03b0 upsilondieresistonos 03b1 alpha 03b2 beta 03b3 gamma 03b4 delta 03b5 epsilon 03b6 zeta 03b7 eta 03b8 theta 03b9 iota 03ba kappa 03bb lambda 03bc mu 03bd nu 03be xi 03bf omicron 03c0 pi 03c1 rho 03c2 sigma1 03c3 sigma 03c4 tau 03c5 upsilon 03c6 phi 03c7 chi 03c8 psi 03c9 omega 03ca iotadieresis 03cb upsilondieresis 03cc omicrontonos 03cd upsilontonos 03ce omegatonos 03d1 theta1 03d2 Upsilon1 03d5 phi1 03d6 omega1 0401 afii10023 0402 afii10051 0403 afii10052 0404 afii10053 0405 afii10054 0406 afii10055 0407 afii10056 0408 afii10057 0409 afii10058 040a afii10059 040b afii10060 040c afii10061 040e afii10062 040f afii10145 0410 afii10017 0411 afii10018 0412 afii10019 0413 afii10020 0414 afii10021 0415 afii10022 0416 afii10024 0417 afii10025 0418 afii10026 0419 afii10027 041a afii10028 041b afii10029 041c afii10030 041d afii10031 041e afii10032 041f afii10033 0420 afii10034 0421 afii10035 0422 afii10036 0423 afii10037 0424 afii10038 0425 afii10039 0426 afii10040 0427 afii10041 0428 afii10042 0429 afii10043 042a afii10044 042b afii10045 042c afii10046 042d afii10047 042e afii10048 042f afii10049 0430 afii10065 0431 afii10066 0432 afii10067 0433 afii10068 0434 afii10069 0435 afii10070 0436 afii10072 0437 afii10073 0438 afii10074 0439 afii10075 043a afii10076 043b afii10077 043c afii10078 043d afii10079 043e afii10080 043f afii10081 0440 afii10082 0441 afii10083 0442 afii10084 0443 afii10085 0444 afii10086 0445 afii10087 0446 afii10088 0447 afii10089 0448 afii10090 0449 afii10091 044a afii10092 044b afii10093 044c afii10094 044d afii10095 044e afii10096 044f afii10097 0451 afii10071 0452 afii10099 0453 afii10100 0454 afii10101 0455 afii10102 0456 afii10103 0457 afii10104 0458 afii10105 0459 afii10106 045a afii10107 045b afii10108 045c afii10109 045e afii10110 045f afii10193 0462 afii10146 0463 afii10194 0472 afii10147 0473 afii10195 0474 afii10148 0475 afii10196 0490 afii10050 0491 afii10098 04d9 afii10846 05b0 afii57799 05b1 afii57801 05b2 afii57800 05b3 afii57802 05b4 afii57793 05b5 afii57794 05b6 afii57795 05b7 afii57798 05b8 afii57797 05b9 afii57806 05bb afii57796 05bc afii57807 05bd afii57839 05be afii57645 05bf afii57841 05c0 afii57842 05c1 afii57804 05c2 afii57803 05c3 afii57658 05d0 afii57664 05d1 afii57665 05d2 afii57666 05d3 afii57667 05d4 afii57668 05d5 afii57669 05d6 afii57670 05d7 afii57671 05d8 afii57672 05d9 afii57673 05da afii57674 05db afii57675 05dc afii57676 05dd afii57677 05de afii57678 05df afii57679 05e0 afii57680 05e1 afii57681 05e2 afii57682 05e3 afii57683 05e4 afii57684 05e5 afii57685 05e6 afii57686 05e7 afii57687 05e8 afii57688 05e9 afii57689 05ea afii57690 05f0 afii57716 05f1 afii57717 05f2 afii57718 060c afii57388 061b afii57403 061f afii57407 0621 afii57409 0622 afii57410 0623 afii57411 0624 afii57412 0625 afii57413 0626 afii57414 0627 afii57415 0628 afii57416 0629 afii57417 062a afii57418 062b afii57419 062c afii57420 062d afii57421 062e afii57422 062f afii57423 0630 afii57424 0631 afii57425 0632 afii57426 0633 afii57427 0634 afii57428 0635 afii57429 0636 afii57430 0637 afii57431 0638 afii57432 0639 afii57433 063a afii57434 0640 afii57440 0641 afii57441 0642 afii57442 0643 afii57443 0644 afii57444 0645 afii57445 0646 afii57446 0647 afii57470 0648 afii57448 0649 afii57449 064a afii57450 064b afii57451 064c afii57452 064d afii57453 064e afii57454 064f afii57455 0650 afii57456 0651 afii57457 0652 afii57458 0660 afii57392 0661 afii57393 0662 afii57394 0663 afii57395 0664 afii57396 0665 afii57397 0666 afii57398 0667 afii57399 0668 afii57400 0669 afii57401 066a afii57381 066d afii63167 0679 afii57511 067e afii57506 0686 afii57507 0688 afii57512 0691 afii57513 0698 afii57508 06a4 afii57505 06af afii57509 06ba afii57514 06d2 afii57519 06d5 afii57534 1e80 Wgrave 1e81 wgrave 1e82 Wacute 1e83 wacute 1e84 Wdieresis 1e85 wdieresis 1ef2 Ygrave 1ef3 ygrave 200c afii61664 200d afii301 200e afii299 200f afii300 2012 figuredash 2013 endash 2014 emdash 2015 afii00208 2017 underscoredbl 2018 quoteleft 2019 quoteright 201a quotesinglbase 201b quotereversed 201c quotedblleft 201d quotedblright 201e quotedblbase 2020 dagger 2021 daggerdbl 2022 bullet 2024 onedotenleader 2025 twodotenleader 2026 ellipsis 202c afii61573 202d afii61574 202e afii61575 2030 perthousand 2032 minute 2033 second 2039 guilsinglleft 203a guilsinglright 203c exclamdbl 2044 fraction 2070 zerosuperior 2074 foursuperior 2075 fivesuperior 2076 sixsuperior 2077 sevensuperior 2078 eightsuperior 2079 ninesuperior 207d parenleftsuperior 207e parenrightsuperior 207f nsuperior 2080 zeroinferior 2081 oneinferior 2082 twoinferior 2083 threeinferior 2084 fourinferior 2085 fiveinferior 2086 sixinferior 2087 seveninferior 2088 eightinferior 2089 nineinferior 208d parenleftinferior 208e parenrightinferior 20a1 colonmonetary 20a3 franc 20a4 lira 20a7 peseta 20aa afii57636 20ab dong 20ac Euro 2105 afii61248 2111 Ifraktur 2113 afii61289 2116 afii61352 2118 weierstrass 211c Rfraktur 211e prescription 2122 trademark 2126 Omega 212e estimated 2135 aleph 2153 onethird 2154 twothirds 215b oneeighth 215c threeeighths 215d fiveeighths 215e seveneighths 2190 arrowleft 2191 arrowup 2192 arrowright 2193 arrowdown 2194 arrowboth 2195 arrowupdn 21a8 arrowupdnbse 21b5 carriagereturn 21d0 arrowdblleft 21d1 arrowdblup 21d2 arrowdblright 21d3 arrowdbldown 21d4 arrowdblboth 2200 universal 2202 partialdiff 2203 existential 2205 emptyset 2206 Delta 2207 gradient 2208 element 2209 notelement 220b suchthat 220f product 2211 summation 2212 minus 2215 fraction 2217 asteriskmath 2219 periodcentered 221a radical 221d proportional 221e infinity 221f orthogonal 2220 angle 2227 logicaland 2228 logicalor 2229 intersection 222a union 222b integral 2234 therefore 223c similar 2245 congruent 2248 approxequal 2260 notequal 2261 equivalence 2264 lessequal 2265 greaterequal 2282 propersubset 2283 propersuperset 2284 notsubset 2286 reflexsubset 2287 reflexsuperset 2295 circleplus 2297 circlemultiply 22a5 perpendicular 22c5 dotmath 2302 house 2310 revlogicalnot 2320 integraltp 2321 integralbt 2329 angleleft 232a angleright 2500 SF100000 2502 SF110000 250c SF010000 2510 SF030000 2514 SF020000 2518 SF040000 251c SF080000 2524 SF090000 252c SF060000 2534 SF070000 253c SF050000 2550 SF430000 2551 SF240000 2552 SF510000 2553 SF520000 2554 SF390000 2555 SF220000 2556 SF210000 2557 SF250000 2558 SF500000 2559 SF490000 255a SF380000 255b SF280000 255c SF270000 255d SF260000 255e SF360000 255f SF370000 2560 SF420000 2561 SF190000 2562 SF200000 2563 SF230000 2564 SF470000 2565 SF480000 2566 SF410000 2567 SF450000 2568 SF460000 2569 SF400000 256a SF540000 256b SF530000 256c SF440000 2580 upblock 2584 dnblock 2588 block 258c lfblock 2590 rtblock 2591 ltshade 2592 shade 2593 dkshade 25a0 filledbox 25a1 H22073 25aa H18543 25ab H18551 25ac filledrect 25b2 triagup 25ba triagrt 25bc triagdn 25c4 triaglf 25ca lozenge 25cb circle 25cf H18533 25d8 invbullet 25d9 invcircle 25e6 openbullet 263a smileface 263b invsmileface 263c sun 2640 female 2642 male 2660 spade 2663 club 2665 heart 2666 diamond 266a musicalnote 266b musicalnotedbl f6be dotlessj f6bf LL f6c0 ll f6c1 Scedilla f6c2 scedilla f6c3 commaaccent f6c4 afii10063 f6c5 afii10064 f6c6 afii10192 f6c7 afii10831 f6c8 afii10832 f6c9 Acute f6ca Caron f6cb Dieresis f6cc DieresisAcute f6cd DieresisGrave f6ce Grave f6cf Hungarumlaut f6d0 Macron f6d1 cyrBreve f6d2 cyrFlex f6d3 dblGrave f6d4 cyrbreve f6d5 cyrflex f6d6 dblgrave f6d7 dieresisacute f6d8 dieresisgrave f6d9 copyrightserif f6da registerserif f6db trademarkserif f6dc onefitted f6dd rupiah f6de threequartersemdash f6df centinferior f6e0 centsuperior f6e1 commainferior f6e2 commasuperior f6e3 dollarinferior f6e4 dollarsuperior f6e5 hypheninferior f6e6 hyphensuperior f6e7 periodinferior f6e8 periodsuperior f6e9 asuperior f6ea bsuperior f6eb dsuperior f6ec esuperior f6ed isuperior f6ee lsuperior f6ef msuperior f6f0 osuperior f6f1 rsuperior f6f2 ssuperior f6f3 tsuperior f6f4 Brevesmall f6f5 Caronsmall f6f6 Circumflexsmall f6f7 Dotaccentsmall f6f8 Hungarumlautsmall f6f9 Lslashsmall f6fa OEsmall f6fb Ogoneksmall f6fc Ringsmall f6fd Scaronsmall f6fe Tildesmall f6ff Zcaronsmall f721 exclamsmall f724 dollaroldstyle f726 ampersandsmall f730 zerooldstyle f731 oneoldstyle f732 twooldstyle f733 threeoldstyle f734 fouroldstyle f735 fiveoldstyle f736 sixoldstyle f737 sevenoldstyle f738 eightoldstyle f739 nineoldstyle f73f questionsmall f760 Gravesmall f761 Asmall f762 Bsmall f763 Csmall f764 Dsmall f765 Esmall f766 Fsmall f767 Gsmall f768 Hsmall f769 Ismall f76a Jsmall f76b Ksmall f76c Lsmall f76d Msmall f76e Nsmall f76f Osmall f770 Psmall f771 Qsmall f772 Rsmall f773 Ssmall f774 Tsmall f775 Usmall f776 Vsmall f777 Wsmall f778 Xsmall f779 Ysmall f77a Zsmall f7a1 exclamdownsmall f7a2 centoldstyle f7a8 Dieresissmall f7af Macronsmall f7b4 Acutesmall f7b8 Cedillasmall f7bf questiondownsmall f7e0 Agravesmall f7e1 Aacutesmall f7e2 Acircumflexsmall f7e3 Atildesmall f7e4 Adieresissmall f7e5 Aringsmall f7e6 AEsmall f7e7 Ccedillasmall f7e8 Egravesmall f7e9 Eacutesmall f7ea Ecircumflexsmall f7eb Edieresissmall f7ec Igravesmall f7ed Iacutesmall f7ee Icircumflexsmall f7ef Idieresissmall f7f0 Ethsmall f7f1 Ntildesmall f7f2 Ogravesmall f7f3 Oacutesmall f7f4 Ocircumflexsmall f7f5 Otildesmall f7f6 Odieresissmall f7f8 Oslashsmall f7f9 Ugravesmall f7fa Uacutesmall f7fb Ucircumflexsmall f7fc Udieresissmall f7fd Yacutesmall f7fe Thornsmall f7ff Ydieresissmall f8e5 radicalex f8e6 arrowvertex f8e7 arrowhorizex f8e8 registersans f8e9 copyrightsans f8ea trademarksans f8eb parenlefttp f8ec parenleftex f8ed parenleftbt f8ee bracketlefttp f8ef bracketleftex f8f0 bracketleftbt f8f1 bracelefttp f8f2 braceleftmid f8f3 braceleftbt f8f4 braceex f8f5 integralex f8f6 parenrighttp f8f7 parenrightex f8f8 parenrightbt f8f9 bracketrighttp f8fa bracketrightex f8fb bracketrightbt f8fc bracerighttp f8fd bracerightmid f8fe bracerightbt fb00 ff fb01 fi fb02 fl fb03 ffi fb04 ffl fb1f afii57705 fb2a afii57694 fb2b afii57695 fb35 afii57723 fb4b afii57700 htmldoc-1.9.20/desktop/000077500000000000000000000000001472561501400147135ustar00rootroot00000000000000htmldoc-1.9.20/desktop/Makefile000066400000000000000000000022741472561501400163600ustar00rootroot00000000000000# # Makefile for HTMLDOC desktop files. # # Copyright 2017 by Michael R Sweet. # Copyright 1997-2010 by Easy Software Products. # # This program is free software. Distribution and use rights are outlined in # the file "COPYING". # # # Include common definitions... # include ../Makedefs # # Make everything... # all: # # Install everything... # install: if test `uname` = Linux; then \ $(INSTALL_DIR) $(BUILDROOT)$(datadir)/applications; \ $(INSTALL_DATA) htmldoc.desktop $(BUILDROOT)$(datadir)/applications; \ $(INSTALL_DIR) $(BUILDROOT)$(datadir)/mime/packages; \ $(INSTALL_DATA) htmldoc.xml $(BUILDROOT)$(datadir)/mime/packages; \ $(INSTALL_DIR) $(BUILDROOT)$(datadir)/icons/hicolor/32x32/apps; \ $(INSTALL_DATA) htmldoc-32.png $(BUILDROOT)$(datadir)/icons/hicolor/32x32/apps/htmldoc.png; \ $(INSTALL_DIR) $(BUILDROOT)$(datadir)/icons/hicolor/128x128/apps; \ $(INSTALL_DATA) htmldoc-128.png $(BUILDROOT)$(datadir)/icons/hicolor/128x128/apps/htmldoc.png; \ $(INSTALL_DIR) $(BUILDROOT)$(datadir)/icons/hicolor/256x256/apps; \ $(INSTALL_DATA) htmldoc-256.png $(BUILDROOT)$(datadir)/icons/hicolor/256x256/apps/htmldoc.png; \ fi # # Clean out object and library files... # clean: htmldoc-1.9.20/desktop/htmldoc-128.png000066400000000000000000000053431472561501400173700ustar00rootroot00000000000000PNG  IHDRsRGBiTXtXML:com.adobe.xmp Michael Sweet Copyright 2017 Michael Sweet New Icon yP~PLTE   "()*+/2568<= > B C D E F L N O P S U W X Z [ \ ] _cdfhiqrtuyz| !!"""####$$$$$$%%%%%%&kJetRNS  !"')*+,-.138=@AFGJLMOPQVWY]_aehklnoqstwyz{~X{IDATx[@pj lVԁκJ1p np{[q_ajJJ[}cx.{s SOcOrWi{p2YNWȋ7!@P@{hyEe@Q1 5 9p6<9XXsT G&@?,f8OH+Ql.K?iB?@ù.DSO~+ c}||Vœ(BA7.kyr)#Qn)dnz*_\v3bA+KxVqvC";/%, r.X|;ᷳ 2c;mOh߭iނ[>ї9,DPK)^|b/ȍb;RHQαe$=/pP|ǹy,G^d7f?N!A@@@@@ u:`=z]86h`Vh7qݘ~>k# M\DVhS꧴2EGS^>Ry>&IHBzR}\hSU15&ugK64TS ̆C_e>:ܸe) U{`Z66EÔ-(c}s͚[,-ҼYFƨM<b̉ J9T/֠GH[LBu5j2֮#HjkլCUJTS5t&\cC | IENDB`htmldoc-1.9.20/desktop/htmldoc-256.png000066400000000000000000000125221472561501400173670ustar00rootroot00000000000000PNG  IHDR\rfsRGBiTXtXML:com.adobe.xmp Michael Sweet Copyright 2017 Michael Sweet New Icon yP~(IDATx{\Ugݝ}vw>xZ-Д XlK)oZ(Ђ!D#&E A0 (Z #ã>xpwۙݹ3|ni;s~DpWqxxHx[˻շoR___jc*M|g2RW.O6yn0@N<4*C^߱x 0&V ]@p2k68xPP^T&QM4vPt`SʸPUJ:_mM(*7+{%O~  7\VL ÿ@, ˋ!p{h|X2{htXqH y$ t@8m344@,yF-uT+T= xd@2;Q@x_q )Z)0h2aQeVN_#,Qb[3Q@' ;3 ?Ѡ^U=F9z8𒳕Ќ@ItKQ'7'2'ACxpsɬ7@ Y\IgiH/yVL5 X?h7=4$Qە`@nmKVsVB] 5rKm{@P1h@RB^lmS`. 5s[{[h@,3^ģf7i@V 4 ,Pg+PG@Y `r8@ @  @ @ @ @ @ PBYNCwQ?PhNWUq?Ywp @  @@@ :jkOH?ѓHjBwL_"}N"@1 =tp O.`"@Q}NjG"@ {@G@XV@.<}+ (F@P"@>GOW@vAw%ҟl@Q`Y}"Y7'+vF3>݀ 6[F#Pg{Ta>'ȏ$߱6"@ oLK9 ̲~M["F"xTEzZ9$LH_j n"_.k-omNюX@aMfQ'T}ߝMTMOhLU"(?Dl L@*7],9f~Q"(D|7sJUbz2Pй6cyp_A߲mX ?Wkm&_}!Ua7KS鎪x$PlFs6Joa3y"u `|4XP77g6 m9';‹(!"zȦVP&xrċ6EcnYRGGC`=\nPʯ`:3D1'SЉ[)W txUM}vcV^j@7X, n߉6 o#ߜ]{7w| a_hf+q+$"9*?h/{;3SUe qdNי}MދdfZ_ܭ8DoUr+\Z5U>ہݰm =-7Dp뎶Ɗ'Oϓ@nzќ >``( h#E,3gNTp_3˟ݔY'mC[ɿҖ9S3cD}2s\z{L4_pP zE;hxա&{´" (΀[8w?{gh~!(H7]<rEI^̀ {ݻ%QOWWK)>:LP8nA[? /wt?]"(SpZH}ҺL*;$Gn91 _bvlf/s O܏Kn9N+Z2{*O#1 z(~YdSas[2(\]m=r.(_nˬDۆlEF-yo?\/nEJ-y@P"JmK)-D+WqZKC1ۖ3@zk @B    @@@ @@ @   @ @ @@ @ @Ј,whD/yx !hH/yaX`tpjV10l0;.MUsg ̗aV}<n@Ix@\L.SFU<4 pUm\5ǻEe^Y\lK#܉"}]6Gnq 7( 1oSNY -Q\c?R*>L4D$eڤp*j|J_|Mϋ%e@П_>EبLUFWf)Csel2*EG@0EؤZ8 B"Xai2j|=6qhH+A?ެ}딅 AeSj M,N"SuX'K-U1X qܴ)2w|#}ӳǻەVeb2R6/IENDB`htmldoc-1.9.20/desktop/htmldoc-32.png000066400000000000000000000026771472561501400173110ustar00rootroot00000000000000PNG  IHDR(p sRGBiTXtXML:com.adobe.xmp Michael Sweet Copyright 2017 Michael Sweet New Icon yP~PLTE     #'(,.013345799 ;= C C D E H K P P S U V [\]_beefiinpqrryz  !"###$#%$%%OtRNSV#IDAT(c`F<3## vy/')FFY O-,|Vչʌ:Qά|(!yn$75iPFUuAPIDzXI:(Vɪ+ҙQT'3__$[_(4ƪ(ȩ^S + 0R/,Kjفg)M@I7$F~9הh Michael Sweet Copyright 2017 Michael Sweet New Icon yP~5IDATX WOA}wC>(& K , QX[kP((h:!ĘA@Q4'{;~xb[%owg7ﷳ3;>!jyCBϮTI`@gx}O*]g]$R>f^,!ZM@-{@487:uy߫Ep)\so&sZMTr?{-@hRv S| mCr'0u |!%pOy bB6HsB\x>9 OY;';Maf|遹 Kߦ6맜pJk ȎMיj /l.d#iYtsbmN6lf2NyFYtɝp]&8Ȕ G}fY=" ;ۥsvЗWXc$Zl=,hZUqHuN@H1BVHise%" _/?(j:爷D7c?IENDB`ic12PNG  IHDR@@iqsRGB pHYs%%IR$iTXtXML:com.adobe.xmp Michael Sweet Copyright 2017 Michael Sweet New Icon yP~YIDATx_UefYd)bPZQPI=DA!SHX> AQPA=C/eAT&DEQ ޵Uk\vwwuν;rsg99gΙ5+`Q#/:eLg][pn4k+LvQchReY-6aNA η(Hg+PJ~ y̯4|/ &E.g8R,H.E"*̝9 &ڜ aLjsqC t̛<3t.X;W.<ܝ;W.<ܝ6̖#E%37ͮ\2qw{̦*C&Zy {4Isew5֥xт1u)5;\.C7GUZ =s>.&@wL\ur'a*! S _?Klp¬'nW(yħxD#w؄zM}f3;Me?CDzfdG'Hw5soA}Aj=V|rOflFu3̞fqcf-á]-6۽ग_c54;xȳH$"mfO3;F^l=D\D) [DQ(TXNL&w488b%}V"}//X;Xv[v}ߌ ^∙el`W6 ӭЏ *#^|LґM_Y&>\[zJ熫Q5͞ F4W!yQ(RE2_;r,xsGCQ 4lÒϗKhcVw>Zg5a8O"<㖚-}fs^Pe"UrxщxƮH"ry9x!QeB%6HPzR9!mIѥN(YRsbSk ZkI[3Vx }` l&u&ݲвiR h-L-k&u, zm:q|._g5{Lx ꇖ7BNd<&Zhڊb#@ s@@+;v_ Q)[bm򷥰jϣ}( 6wW5hWxC["ڋ*n#V bHD84k8݈n@Kh?c}+&\ DAT3ܐLN5lH 0щ< *H L8yTD* Sd̓"5_̓r̓̓̓̓̓ &&&&&&&& && &&&& &$ &&& &$ &&& &$ &&& &$ &$ &&&$ &"&&%&$ & &&%&$ & &&$&$ & &#&"&$ &%& &$ &$& &% &#& & &$ && &!& %&"&% &#& && &&$&% %&$&&&"$&&&#&"&#&& &%  & &&&$ %&&& &"$&&& & !&&& &%  &&&& &$&&&&&&&&&&&&t8mk@ VəV !!,,"" ))ee   !! ''**,,................................................................................................................................................................................,,**'OO' !@@!  8kk8 .MM."@aa@"1OzzO1"=YY="+F__F+ 1JassaJ1  3J_nɈn_J3 1FYhq~ʧ~qhYF1 +=O]hotwyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{zzywtoh]O=+  "1@MW_ehkllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllkhe_WM@1" ".8AGLOPQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQPOLGA8." !'*-........................................................................................-*'! ic08PNG  IHDR\rfsRGB pHYs  iTXtXML:com.adobe.xmp Michael Sweet Copyright 2017 Michael Sweet New Icon yP~cIDATx -U}ʪ@"J )4Ĕ -,$"!E!F!e*!((A)P (""Yþ/73.3wzgt߾}}}2) @ @ @ @4 jQAbzc$JYccq*~*Ń9KseUT/S 6/7*.S\I1i6 *١1 (U<5\x(R AG_Zq JEVwST0 L X;PI&o{6UnmAr@qX+`.mŦUlm@#߃UDOj䋙Yu& y-~ƒ*H@uh[cv k{w')H@ Xl\ \# =~$@Uk6 ܵ +;  k6Nv gY]C`_[t}/.rh2kڍ^@z>3/kl~BF>@&`ZalW:8NV` x֮5l-w{iM0" Ȏ= Fi. ` XE{{~ ȏk ;зfGT`I@~b`RNv$@ ?nRGD^,V8Dߙ}3 ȏ@&/ޙb0 C]N(u~OS@BǞ/b%Oߏ|@ +E5>RNY&+t eCyT b:@nB1 +0!7 r/r%e!2dh0 9>ŸVz&)^Yx8}jFpTKZa!:oWz)ۖҔDiYJoV\xJ++| _#h jq$$@Izo+׊F0#Ciu @;.NwܓfϪWwoJ Rz\RUjS` U~!SHimUL,C83WG#CcGPs\B?NJ $2R<kvܡBUiK\-v69 ~Ii[5Oʹ,`jOSz וRG{`Pv;}[bA\At$FsѼY<8=*4ںq8kڎW[y:ZRt9L.A3ހjV镊Hu ߗ)* B; v"sv_3R=ڽjpg|?ni4iU{dd4S PّWV?W,I.΅U4,NޫӺ^uOH`?g}>œN mEq^uTc0 R̛["\0v:} ####ho**DuA}裚pGZkd12]bG4X7 6ݦ#:mZ YX5ME殛*h?qsc wK^uHm0;_ݯӘH骊n&@.Ո衑7,Mk  <=Ն.SØ|nrWz> 3%C"iNSrrPκ{)})bJ6l.Ⱦv4t2yOT# ]M %ϪݥvGL|m(ڲw(E:{jH冲gPtݛ}/l R ͻǼi g ~]5/6R֤:uSSqڑ!|#gtO@lR7{h W_JPP"/OY| Sc)sN>==e:ׯ:ojgJ&!].5yK p(O]u.ԑ6(_h|z@ѥʚئ/C."TeɍwDR?rޣ Sje$?EGc$5tw괏8y94}{$#t{Ǖ_N59 Nir,:fu)qтoT_Pw.{/h_vM hꧏbCU?}7kqry7^:Px(r!LhDw.ӻuI24$o_1Ǒږn ` t.am%5\=A<_?+F9k}Sw? [u=W#:nDS?GKu<\b׆>cq\mJEa3 ?|FX)z*FgHwv?k~(]kH3' l%$Q+ڱ{^j ^I#glj@<"dU],%T˓A +@VBZ@<"dU],%T˓A +@VBZ, |gZ :%YI/J)H@n&'V_M~ȽUDZ" b@+C @0W>E@@ `-| 6Z\m-&):0ZLhqSt`ʧhh1 ŕO! b@+C @0W>E@@ `-| 6Z\m-&):0ZLhqSt`ʧhh1 ŕO! b@+C @0W>E@@ `-| 6Z\m-&):0ZLhqSt`ʧhh1 ŕO! b-C!3);<3-&0v1Z C gSjw*X?3-&`Z}S/̰onL`yuj;2+/L!,r3钮\,r `ܵ +:cSMH@& NHXܕ@ , `Q̠hEqǍ  k6[ԴKZ#cLʧ) l7q@@,酱Xb h>Ek6k-5R4X(ȕ/ech0+oۘ4XNz0?PQ h.kZ BEh^<|_^45jZ0Oe E\s34i^=6;]p&;HlY?4iZ[k8 T=0o0⇚yV5k  `S(W, ; {֢5٩S鮴jגw:bu{*P AsClO(6 ~FEQ4?{$@`n\Za[??p z @y "@7[+H> GhvbgS^v}T3tG@b0Oź zA)#p6K~#7r$W^ 4L 6/MY8Y P!;o)|W+x0f,^FeK;*P jX+|#6/u_4z|#żag+Hܪ_T:} _댤A{!i, 3]+<.L/_T~/v;/Mj~{B؋4e6SpZ $LAbBU>}G#nQ؝c!rosÝKw A ܭW*,;>pi瀟!d꣩(Xou>݀+pMk+QRw^' 86WNtC 0,{f60>w7t?e)?.v>^7LF`XKa3Q,PfM)l">]pR: "`#E§)),j&-#zį#GrOML i¢ιE] MahvBށr%|h&_MŦC#Z6b,M[Bv$ S h}m0}L tj8``y@ˢG<1MĩdZm3 M$F< }-~GӈCmGYBٝۊbvĠĩ!|C eG gxA{[3Rxgb{Z6z44諑ۏL!D!|[0O-8{+N1Ol7zf.Av=-zgX"4;n,'A !TO#B!8NL۩,$?IENDB`ic13PNG  IHDR\rfsRGB pHYs%%IR$iTXtXML:com.adobe.xmp Michael Sweet Copyright 2017 Michael Sweet New Icon yP~cIDATx -U}ʪ@"J )4Ĕ -,$"!E!F!e*!((A)P (""Yþ/73.3wzgt߾}}}2) @ @ @ @4 jQAbzc$JYccq*~*Ń9KseUT/S 6/7*.S\I1i6 *١1 (U<5\x(R AG_Zq JEVwST0 L X;PI&o{6UnmAr@qX+`.mŦUlm@#߃UDOj䋙Yu& y-~ƒ*H@uh[cv k{w')H@ Xl\ \# =~$@Uk6 ܵ +;  k6Nv gY]C`_[t}/.rh2kڍ^@z>3/kl~BF>@&`ZalW:8NV` x֮5l-w{iM0" Ȏ= Fi. ` XE{{~ ȏk ;зfGT`I@~b`RNv$@ ?nRGD^,V8Dߙ}3 ȏ@&/ޙb0 C]N(u~OS@BǞ/b%Oߏ|@ +E5>RNY&+t eCyT b:@nB1 +0!7 r/r%e!2dh0 9>ŸVz&)^Yx8}jFpTKZa!:oWz)ۖҔDiYJoV\xJ++| _#h jq$$@Izo+׊F0#Ciu @;.NwܓfϪWwoJ Rz\RUjS` U~!SHimUL,C83WG#CcGPs\B?NJ $2R<kvܡBUiK\-v69 ~Ii[5Oʹ,`jOSz וRG{`Pv;}[bA\At$FsѼY<8=*4ںq8kڎW[y:ZRt9L.A3ހjV镊Hu ߗ)* B; v"sv_3R=ڽjpg|?ni4iU{dd4S PّWV?W,I.΅U4,NޫӺ^uOH`?g}>œN mEq^uTc0 R̛["\0v:} ####ho**DuA}裚pGZkd12]bG4X7 6ݦ#:mZ YX5ME殛*h?qsc wK^uHm0;_ݯӘH骊n&@.Ո衑7,Mk  <=Ն.SØ|nrWz> 3%C"iNSrrPκ{)})bJ6l.Ⱦv4t2yOT# ]M %ϪݥvGL|m(ڲw(E:{jH冲gPtݛ}/l R ͻǼi g ~]5/6R֤:uSSqڑ!|#gtO@lR7{h W_JPP"/OY| Sc)sN>==e:ׯ:ojgJ&!].5yK p(O]u.ԑ6(_h|z@ѥʚئ/C."TeɍwDR?rޣ Sje$?EGc$5tw괏8y94}{$#t{Ǖ_N59 Nir,:fu)qтoT_Pw.{/h_vM hꧏbCU?}7kqry7^:Px(r!LhDw.ӻuI24$o_1Ǒږn ` t.am%5\=A<_?+F9k}Sw? [u=W#:nDS?GKu<\b׆>cq\mJEa3 ?|FX)z*FgHwv?k~(]kH3' l%$Q+ڱ{^j ^I#glj@<"dU],%T˓A +@VBZ@<"dU],%T˓A +@VBZ, |gZ :%YI/J)H@n&'V_M~ȽUDZ" b@+C @0W>E@@ `-| 6Z\m-&):0ZLhqSt`ʧhh1 ŕO! b@+C @0W>E@@ `-| 6Z\m-&):0ZLhqSt`ʧhh1 ŕO! b@+C @0W>E@@ `-| 6Z\m-&):0ZLhqSt`ʧhh1 ŕO! b-C!3);<3-&0v1Z C gSjw*X?3-&`Z}S/̰onL`yuj;2+/L!,r3钮\,r `ܵ +:cSMH@& NHXܕ@ , `Q̠hEqǍ  k6[ԴKZ#cLʧ) l7q@@,酱Xb h>Ek6k-5R4X(ȕ/ech0+oۘ4XNz0?PQ h.kZ BEh^<|_^45jZ0Oe E\s34i^=6;]p&;HlY?4iZ[k8 T=0o0⇚yV5k  `S(W, ; {֢5٩S鮴jגw:bu{*P AsClO(6 ~FEQ4?{$@`n\Za[??p z @y "@7[+H> GhvbgS^v}T3tG@b0Oź zA)#p6K~#7r$W^ 4L 6/MY8Y P!;o)|W+x0f,^FeK;*P jX+|#6/u_4z|#żag+Hܪ_T:} _댤A{!i, 3]+<.L/_T~/v;/Mj~{B؋4e6SpZ $LAbBU>}G#nQ؝c!rosÝKw A ܭW*,;>pi瀟!d꣩(Xou>݀+pMk+QRw^' 86WNtC 0,{f60>w7t?e)?.v>^7LF`XKa3Q,PfM)l">]pR: "`#E§)),j&-#zį#GrOML i¢ιE] MahvBށr%|h&_MŦC#Z6b,M[Bv$ S h}m0}L tj8``y@ˢG<1MĩdZm3 M$F< }-~GӈCmGYBٝۊbvĠĩ!|C eG gxA{[3Rxgb{Z6z44諑ۏL!D!|[0O-8{+N1Ol7zf.Av=-zgX"4;n,'A !TO#B!8NL۩,$?IENDB`ic09KOPNG  IHDRxsRGB pHYs  iTXtXML:com.adobe.xmp Michael Sweet Copyright 2017 Michael Sweet New Icon yP~@IDATx 5UYDPQK볲,Scj$䡲jH,MSUji'xߗUwgϞ=kߺ{5kϬ=kT @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ :,8XɎذ _v']en'#@@*-.jU+e[e[6싊/O<~X d˜G !pvΒy+V>e?aQ@+KVgdݰ(E2aUG~Qv@).<:`a2;7_쩲e@8_ oUK ,s/usey 0-O0|앲/ll4@~}2_'@"/}<X33SvEFB@U wD(";8_,5~{>@AtȖLDQ`Q!+C 0WAB'|R:D!}k>!@3knoġϮ:4{d3P/0Bw= @5\koXZ8 6{=qlD @@'q 49kFL\pv[ +@ &ko3 iok;dX  X{C6ȺF9Q 0G M:qjF Ee/!@脀7kqsT;6œ8 9 '  Nd r6bdgl-@@YZuza;8 am-> @芀wgئa@}].K& y;}:Ƨ7 {@Z%` >6V;$!Xh2&u @O ~N^-axG!rGm ̃ T,L@JZ'04{dAF^#+K@B t8bWC[ϩ}sX= : tG`&G^nv8hȋ byɀ @`ZbnRk8n4X68D-[=mv _÷TOMUuUKc9sKe5~ > ]WUoUA`Fh{;?tQU=Xf,Pr?3אٺ˫(]z׫Bp.`Da{3~֕*>@>@ .Ԅg]YU^KtWUՕZ.!qik5G;j88B=k% _][>} U#p\SU~&nN@L@c;YU~6%dG=~_`Ձ4|#@ ;U?SӜݙ9{kvhTU[7J2|.WYL@ TGkحUVM\6#}gг>B9%L>@@\@k̉WO4%v% :H>0 n\Km҈D=CeG8P&`HXk @$pԁ bxmz5z0ƎojGpɵ6γc`37lŻa)>KFzoOP}Yzue] ;oXb|8|KsT8JTud~zUӠ5ļLǗy(0L/I?A ?W6^MGA?B4U?[?RIE:m2v$J@u;rWU2(+$7osBp =aa>0ķxϭUz%* N |E~Oѓ7@zAϥ=?X5#7g`$"\zGIO[ %'"o\ĥzwFp2ҥ s|oԟ:_%Z|?Oeߖ#pc|%pr>o⾟i"'h-UuĿE@49ZU%{X/ X4pH=ƹCpv@2]Fi?>@X-;zEU`{5!;ovz !G K :G|FvoC?~9ϋ#c:! (Q}h]x^?ԗ+ƉyE9g#c?*<`fUªzU^>4T&@?;\{4xA1U?t 'Ev*@!?hx ,_(1[/4&-;`jdn?X?@yH'jayUu%=Cۂ0֓?#@3+$'x'p-N@jm8="h}]#u ΁=(i 0g{IMwU}XUUǫ9xνCuK.ܫ@]uUuO ˽L(e4V5"{ۗ5}˛}@]~o{ '$]o.FZ]a/}uw hh4goh$_].SuWzTI f%KclXtOX8яk{q ^y@UU|W{`z]@weQY\77sxUf-aGKI?hxߓ_~{R$0AG|Rw`⡺hvFNۥܟۣ^)X<}t*DiT ~IOI5j<2`lixgV":~+͚/ׯ<*:S&st[ d'ߩuÙO?Fwy>QXvKPN4kL$c8c:¯>I'؞i*<f5úx^TUSlf"߯Qͼ'ً';쩺X) =Oz&`]^:B'./7psfEVu.԰}zQfARi6z/5O:nލI7zl#{[1:BI]so%/^UكY@Oi/"  Ӹ_%V1&(]V}*9``|4\z [dSl@k.ZN:@uo]O{.ו,5r}/)n8ooe3[p~U#SK t+_y?mG?&YY{Ɖ:ۿ-:9Y,?٬٬%+ N?RC/هo%MJ 9P%ggoY_'?vkUܥΟ 8s;8T/0]KzL>|hU}w,ptc\="I(ۙWg[U[jHK]=?`?Tڍ0Jy~uu۪.jXV%7,ң4AwJ]&Cua͵Hg\6%ixWtNtTgjG? vws/zJ ~Loj,<]߬*M @?G]N`IFcz? ~~(TZ V}Ec'^>\҂ ˃"ɞ+pzNg?*󎨪h/EctY׬?2Ŀ?K_2u½$on o>g;= &˾]fbM; ~ I', ?a)+j:aSZʞ/>OXC?Wقr2%?\t'F oe=o͓Y!]m|yK\/G9*^  8zׯ?7 StY#:+Q98, 5 Ioۺ7|_MZ~z(_OخCxtx ~(ү CtۓΔZpnwo{j~˟;\|WitίH3߶{^Orά74Mnfܗk}t4wE wiR5koפYѬ/IOx oӵ`:^^ۗ}̓.kx8@_ :{uSN]Mr_@!i 5i~-G`0s?!W5L\wZ;@AnhiMD/I~%}g~-]UU5w.OYg 0=tx~? O%C,p ;IZ7h[-qg@`GsE^O{F y玌9,s7kk8}{ҳեV|kx}߾kxG!Qtkɺ,p H\ӻٽU&pV֪y-a}q =}Op˯KCB=w:I1]yGpfF<l[t=/Oϰ'Gp=_+Q=?%~x%:,_Rݦ{& @Ԛ56i(+*8Wj]#ve@ Z8 6BsRC#>_y!@5Z:HcM\yCghC  LNi jm=}vGަx zn\ |@к:qjNF9rPsѐܰ*( ,5ϱ<h|;!;gBӱm͜-ˆ< @dֵɶ`t!+k0%(=Dˑ$;r.e@@>bgAq,@Tdvp9/s>׷=O~Sv6 "XYAY,,!ۅg`jW9kCKZIb;ÂΗ#C N |̣Aoo "Uf9C,8:"rVy 8G +2 <[8ϱr@]NV.2,xʏ㻼./#mC'聒@ X-W,!? `/o-dur<("ϱ/ xH >2 @`o?Ao <Bcֳkbq#\u^?@3ev @]~[,}[;bp#?g~p\PHG\>/:A:R'e(CI @`n,ʟ]Eq#1PC[+Ƕbzzڇ+lo@s#N٧de!!!,:z]:3%BFܢ,y9s=eoP' #p' ?Β5YC;.9!vB#nQ]˃ZA:oN#%ewqǀ  @`j$|[z~CCC#&}>ʊ:wNgZ,9#IDATuжVMި2w#Ic`w 0Zg~;> 1qn" X?Mb嶂n>3v30??yb(儹z{m @A'_ذmCx#$qnG^xp*G9Vv{"9Ex' ?8/@8s8ˇʎ#;PU@+@z\WeʲF: 8cw8q,e䲣Z)|QA#wAq^g' ꮷk7c02?ry@X~d˶,Ϋ-;3up,mr.eG&/bRq;; !'qy!dG sGlו-ڐcr|'''Cy6mE  XCH-vҶkdW;-?1!C#΂yhB , j Ю;kQ62|rze娣-8M9yNGv@3Ѫ;+3!G1 tK.ZD:A:5%%{vr٢(?hKNs]:串qu"6Lj'guBGZMi/GD1 GQrwqhNhJCW"8z:֋m^E=-j;hv#Y cXg@q"@G3A@Dg6ܖA:!:r#R7HSB[,N ub[ǡ[96MZ"w8蜀3(:o,/bX9ϡ @]l^v:ӱ\X8reFv:BNG^o4hDCr[#xՅ Michael Sweet Copyright 2017 Michael Sweet New Icon yP~@IDATx 5UYDPQK볲,Scj$䡲jH,MSUji'xߗUwgϞ=kߺ{5kϬ=kT @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ :,8XɎذ _v']en'#@@*-.jU+e[e[6싊/O<~X d˜G !pvΒy+V>e?aQ@+KVgdݰ(E2aUG~Qv@).<:`a2;7_쩲e@8_ oUK ,s/usey 0-O0|앲/ll4@~}2_'@"/}<X33SvEFB@U wD(";8_,5~{>@AtȖLDQ`Q!+C 0WAB'|R:D!}k>!@3knoġϮ:4{d3P/0Bw= @5\koXZ8 6{=qlD @@'q 49kFL\pv[ +@ &ko3 iok;dX  X{C6ȺF9Q 0G M:qjF Ee/!@脀7kqsT;6œ8 9 '  Nd r6bdgl-@@YZuza;8 am-> @芀wgئa@}].K& y;}:Ƨ7 {@Z%` >6V;$!Xh2&u @O ~N^-axG!rGm ̃ T,L@JZ'04{dAF^#+K@B t8bWC[ϩ}sX= : tG`&G^nv8hȋ byɀ @`ZbnRk8n4X68D-[=mv _÷TOMUuUKc9sKe5~ > ]WUoUA`Fh{;?tQU=Xf,Pr?3אٺ˫(]z׫Bp.`Da{3~֕*>@>@ .Ԅg]YU^KtWUՕZ.!qik5G;j88B=k% _][>} U#p\SU~&nN@L@c;YU~6%dG=~_`Ձ4|#@ ;U?SӜݙ9{kvhTU[7J2|.WYL@ TGkحUVM\6#}gг>B9%L>@@\@k̉WO4%v% :H>0 n\Km҈D=CeG8P&`HXk @$pԁ bxmz5z0ƎojGpɵ6γc`37lŻa)>KFzoOP}Yzue] ;oXb|8|KsT8JTud~zUӠ5ļLǗy(0L/I?A ?W6^MGA?B4U?[?RIE:m2v$J@u;rWU2(+$7osBp =aa>0ķxϭUz%* N |E~Oѓ7@zAϥ=?X5#7g`$"\zGIO[ %'"o\ĥzwFp2ҥ s|oԟ:_%Z|?Oeߖ#pc|%pr>o⾟i"'h-UuĿE@49ZU%{X/ X4pH=ƹCpv@2]Fi?>@X-;zEU`{5!;ovz !G K :G|FvoC?~9ϋ#c:! (Q}h]x^?ԗ+ƉyE9g#c?*<`fUªzU^>4T&@?;\{4xA1U?t 'Ev*@!?hx ,_(1[/4&-;`jdn?X?@yH'jayUu%=Cۂ0֓?#@3+$'x'p-N@jm8="h}]#u ΁=(i 0g{IMwU}XUUǫ9xνCuK.ܫ@]uUuO ˽L(e4V5"{ۗ5}˛}@]~o{ '$]o.FZ]a/}uw hh4goh$_].SuWzTI f%KclXtOX8яk{q ^y@UU|W{`z]@weQY\77sxUf-aGKI?hxߓ_~{R$0AG|Rw`⡺hvFNۥܟۣ^)X<}t*DiT ~IOI5j<2`lixgV":~+͚/ׯ<*:S&st[ d'ߩuÙO?Fwy>QXvKPN4kL$c8c:¯>I'؞i*<f5úx^TUSlf"߯Qͼ'ً';쩺X) =Oz&`]^:B'./7psfEVu.԰}zQfARi6z/5O:nލI7zl#{[1:BI]so%/^UكY@Oi/"  Ӹ_%V1&(]V}*9``|4\z [dSl@k.ZN:@uo]O{.ו,5r}/)n8ooe3[p~U#SK t+_y?mG?&YY{Ɖ:ۿ-:9Y,?٬٬%+ N?RC/هo%MJ 9P%ggoY_'?vkUܥΟ 8s;8T/0]KzL>|hU}w,ptc\="I(ۙWg[U[jHK]=?`?Tڍ0Jy~uu۪.jXV%7,ң4AwJ]&Cua͵Hg\6%ixWtNtTgjG? vws/zJ ~Loj,<]߬*M @?G]N`IFcz? ~~(TZ V}Ec'^>\҂ ˃"ɞ+pzNg?*󎨪h/EctY׬?2Ŀ?K_2u½$on o>g;= &˾]fbM; ~ I', ?a)+j:aSZʞ/>OXC?Wقr2%?\t'F oe=o͓Y!]m|yK\/G9*^  8zׯ?7 StY#:+Q98, 5 Ioۺ7|_MZ~z(_OخCxtx ~(ү CtۓΔZpnwo{j~˟;\|WitίH3߶{^Orά74Mnfܗk}t4wE wiR5koפYѬ/IOx oӵ`:^^ۗ}̓.kx8@_ :{uSN]Mr_@!i 5i~-G`0s?!W5L\wZ;@AnhiMD/I~%}g~-]UU5w.OYg 0=tx~? O%C,p ;IZ7h[-qg@`GsE^O{F y玌9,s7kk8}{ҳեV|kx}߾kxG!Qtkɺ,p H\ӻٽU&pV֪y-a}q =}Op˯KCB=w:I1]yGpfF<l[t=/Oϰ'Gp=_+Q=?%~x%:,_Rݦ{& @Ԛ56i(+*8Wj]#ve@ Z8 6BsRC#>_y!@5Z:HcM\yCghC  LNi jm=}vGަx zn\ |@к:qjNF9rPsѐܰ*( ,5ϱ<h|;!;gBӱm͜-ˆ< @dֵɶ`t!+k0%(=Dˑ$;r.e@@>bgAq,@Tdvp9/s>׷=O~Sv6 "XYAY,,!ۅg`jW9kCKZIb;ÂΗ#C N |̣Aoo "Uf9C,8:"rVy 8G +2 <[8ϱr@]NV.2,xʏ㻼./#mC'聒@ X-W,!? `/o-dur<("ϱ/ xH >2 @`o?Ao <Bcֳkbq#\u^?@3ev @]~[,}[;bp#?g~p\PHG\>/:A:R'e(CI @`n,ʟ]Eq#1PC[+Ƕbzzڇ+lo@s#N٧de!!!,:z]:3%BFܢ,y9s=eoP' #p' ?Β5YC;.9!vB#nQ]˃ZA:oN#%ewqǀ  @`j$|[z~CCC#&}>ʊ:wNgZ,9#IDATuжVMި2w#Ic`w 0Zg~;> 1qn" X?Mb嶂n>3v30??yb(儹z{m @A'_ذmCx#$qnG^xp*G9Vv{"9Ex' ?8/@8s8ˇʎ#;PU@+@z\WeʲF: 8cw8q,e䲣Z)|QA#wAq^g' ꮷk7c02?ry@X~d˶,Ϋ-;3up,mr.eG&/bRq;; !'qy!dG sGlו-ڐcr|'''Cy6mE  XCH-vҶkdW;-?1!C#΂yhB , j Ю;kQ62|rze娣-8M9yNGv@3Ѫ;+3!G1 tK.ZD:A:5%%{vr٢(?hKNs]:串qu"6Lj'guBGZMi/GD1 GQrwqhNhJCW"8z:֋m^E=-j;hv#Y cXg@q"@G3A@Dg6ܖA:!:r#R7HSB[,N ub[ǡ[96MZ"w8蜀3(:o,/bX9ϡ @]l^v:ӱ\X8reFv:BNG^o4hDCr[#xՅ Michael Sweet Copyright 2017 Michael Sweet New Icon yP~@IDATx mGY H2ɔޛAQdADmlEۿwVp[  bDAAmT `̐@0SIu> {X{[SY^꭛sN}VR$ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @lO:;Y \7| m#"7uf}|"_osY׏m @@/_~6g6s]*/u>;9?Y"+]uw?]7 [$#$P%Fl;#/jMC#Pt @,KࢸG~Q isعSz.ˤv ?9?!D @e |*n @\ନ_~fF'[sUvDw~4ɶs0já @8$_6=&u'Tf%0Du{$v}%s_"@ @h0&O|vL8N~ѯg}7G~kdcI @>Rϔ}L/iG{8Lkg @ @]OФIX&p̴o)0);6>'-"K @ 6OXֹA<6O؎r;p{n @إs 88p=8f+`Vc;v{wG @>U5wcW S6d?'/G>>D @{ȾշE>!_Fm,vJ>[o@j0&NiF~eM] @ w%5Wms;Ӥ}G:oۙm~D>OA @8?.#Eێ~ۛ{a#?;_uIq"W%K @O ^9bjl^㹯d vWs3Gd~  @ @`Aȹ|=)uЎ uKk}(qqڏY#@ @ <0wjGBg'm.S%@TzA,M"@ @ Eo t(z-}/kv+:u="6:v @ @r>}d$v2KԮO}]Jn\I @8'gG듶sڧ^vku=wꉖ @ 0:e-pm]r֕Mo7\=][; @ @`M.z<*?n֧muvZ@׆oOu% @/}e.Ӱ7θˊܬذv]eE0_Y"@ @x9xOᯣuٗc{쿵f:::u=,# @+,<4FյLu=OoY"@ @(gE>P;߬G`X=iyb|<;= @ D4mqu{-3i*1WݞY|-Ok>o @GQE4_k=ܮWvP;Qqq_,  @ ~˾_' ugno]eTaIwFGO} @ V6"qSI}z)P6Vݞ}όz% @]~KSI}%P6Rn^cɖ @ ЍDMύO5ܬuy5J.ZJ Pe~#_o+ @ go#rٮ5۹Z֎_ewD5WB @= \o#׎ZV[jǾC]?6N|Ed*fI @~o}+}v=uvgno]C.+&H @9!վduYOn^b`]'-s_oQ @ @25oF^+4B זOZ7, @ @^ω\eiءUvӵ]os.K#D @ۑ|ON{N:FV}^s @ @XN|>&9v]G\Ys9\9#8 @8@o#vߨkyTfXƺ.s7wD>ep- @ @`+}"*0P;e^_G\WjG?zl;uGJZa @ @`n̯|m[6C*յiWesFjUZ[#@ @e |1n3Hper}TvGU´e\֜"M;E @ @nD΀@ks=So7c}v+Qݮ_29cD @ plv::V&},TԼ-W]o>w}9 @ثgDnhuĿ.}>4kG?zvs;ˑuA"@ @d3myú=\&a})=h @ @&}sN돶}֬{RS[$n>,Kp=k"K @ @`_&s4n-l}LN~V\os <=s~H"@ @sfvs޹Rۇ꼥[͛2ׇ9oY"@ @".|E>#58'H?s"+?$ @ @9 䄀$vy Жr\#Y"@ @| P@]e]텦H/3N~eݗۓO~T @ @`;>jWˑۙr~"dj_s9-'= @ Ї@/DͱyҞXfv׎,OF^fk,  @ @/OZuJrv[rY7n[e9s;w|v,$ @ P`DOe;_G,lݗ I١Sj;xz8I @ @`'}Wa27H23ywGF1$ @T Q{D>9G':?\G@vǒjǿ.\u. Ŕ @ d4Z)R2-=ea$'E~_F @ @|EK#'СK} `O @b u;Y @B W>kۇLuv]_j7nU+pYrzV% @ 0DA'ͱzɀ?E?0P>Nj&@ @e d_5:\˗3M2>inA @v#}yIr򜹧$jQ3i2W\y_lks_,$ @ 0*|ω\_|:@<.7h;N>⃋(|  @ @vϚ}ףoIcsMsAޣ] ۙs׍Dud @UQE\:_9> pg=T;Q;yc:#@ @1 d5~mβ=Ly|niZZu}2zK @ 0rf_vZ?j s\Sp^v]l'5G~E @ @>S"!r}NXSg=4pϻu\ @f%}f?m}޺羹yR{Vv]~ @ 0RN}ع=-mulg.6 Rs9 9 "K @ @`U>ȟku=vu;3KٞgGuYH @ Jٗ}pڿmYܮk̗OڮlY"K @ @`Oq۾o-i< ma֋X @ @>mm׳*i;tpuVsvV4ˑ۹sD @ @* d6m_gvה4nx}ZRu_=i" @ @`Eo;˪ \4+0YLmz4@pXкV]{ϴv.F @'}>oY\op=Y&VZxgY<_u,  @ @`;֫>r{<9;ڞUtZBc"xD @A gnOJO:f @Xf_wRݗU۹)gfTu}2_=gZ3#@ @ȾnrR߸Ҷ]SSʛ*M*LW+2" @X'<udžw=v@ϩ;n> @ @ lh}#йo&iO 6,T=˭rNpö  @ @ d_h}筪[ꜩT/G'97$@ @k"}_Udžw=@޴VW 5<' B @ n_ʾo/}㶮v=g d!jw @ @`2p~qOe:{vK.}*  @ @ 싺d߸'g0}u9<~].\u]n'@ @+.pbV^e$*P Lrޞ[sB @&:q]vuU-@.S-d]NڗǎyP"@ @k(}q۹.7fjArXwmݖ#>* @ @Q d7}a@t}x粮 vn< @ @l@V'*}xݿ,ÂdT r/>v=_?7u@{IiuK Z'@ @k(}./S=ߺ^ Sm=0TM @&0| v[ڧnz}ZIh v|>H @+"0 ƹ_fTZzn˛ԃ @ @`MnjuVw]l@u]yu{,  @ @ ʾqX]ϯ۹Qi6on7-Z5 @ /޹ަv=/iċ4;kaj!2Ot,]U @ _]eMu}ұzή Bjp_n j  @ @`@7κN7vߎg,D]evWRE"@ @u @ַzl}NvyZzl@$@ @u>:׾t=ky-wh/8u-p^# Z @ @`},c/x]6Mߞ3u}ﶠyv{ZS  @X3a+U'_u}'ܠ=.0u]N @ @k zVejn-mCI`M'l/i׵ @~>sǏ=@ޤ-H]esr["@ @ l]ٓ^m!PzNk @@Y\s&}}{ luX]˶ǭ @ @u2ڮձṇm40F}u;z޸ c @@eV73Mڷqsv=r}zZŧko+N @Q`R?x'j2:n.6yݮK @(0okuf8ZAsgVzAK @ 0biI}WcI۹l+ @ @`ھqgn^m_{|&x 3yo['@ @(0\v <.hz~e]꺎 @ @uhq=m}W&{ niypu @ N>pݮuv={ Lv ~ @ j omurnϷN @]`/}亜Kw8ZO7( @/=< @ضO_  Г@@O+ 0޶Q2k+p7\j8Brcs3 p@#'pW2$s@ ,I@`InK'Z[]  @`'#@ `'j%@`9*;FJ\@ O`A v= GzǿWWأ@}-qܷ߉s  @m p8-v- k:$@ Ԏcr?bI._@=]@ P{Ȏ= (؆Pr G8!v;GA% 0/Y%Ї@f"pf_&.Bv%9veCzՙjo9Q 9G@]ICydy&@ |p)su%& n->f vX)O@ "+PI`oFu! @`>5_=1G@|]  q@IDATZ)/9Ԏ_;:svI $ 9G@m H@`D(-?wu-~ @`v7ck(9 {.M%P<ՀqXb݅(E(Xn5GRM ,C@`I`x_nGF,ߊ9FHF`3t)cȎŵWF󳹌E@ (@X5iH yǿOrsJ9_ssvaxGKօ4@B݄Ff/?{ӣ]S_,yr٥<#G ]Zʾ99!?gw·s@kG$06؅Gpɑ*G.)<#SPl_xiK KyU3w/ ' E@`,-v!7X[cr?]#9#P9ʑ)'|:7~s\{|=75#vz~̚;Fr鴃#P9% @r|e){+y)_y "0wb7 0W8 s;WˑTqʑ'%).to|+=5jOI)D @#)"AʑQʑ7}ztػ1]ֳ>Vʥ{G=2*1G@Q&04"&7;gT4n$划D'pIti8sWU+q dzۓ@O+#v;so!ʑų8ws7 @"''\T{vξoS] ͇G@>Ӯ#B92#D9R#F@~S}ƫ]y]ծ7r>s lW@`R#0G6#s1#B92#D!?8=A/0׆@c|"@ `.N`[brd/;:1nzf/G^刐D} 3[#|'Jo?8m lʉf'vNR::9y]|Du|Ts.-^4sY ̅E l[@`TN$wn 9#:w>Xcc'Gz$ 0MGc^KJcbӨfo0S!(9(9n h;> -GhHsc&Gn$ 0+Bc^)Oʮ3I@ `}f' 0;KW"Pt1#29{sxBsqD^{Rr<346) g极nN.L>Y-$w2r\6GX^w=gcLaە  @`3?kh?\| j< @t%rDY'{9" @ \@/~_=5 Wsk<07[C@vV ($FPr$%GT#+9" @ \O08`)sxu~ېJp* ` >^ʕrK3 ̅EH@`SU.wã]!G>^HcD$GF$ ЋY+/xY+R4} |@^hj f)y߈q7/#9#(&F*pIti87N9~#+jRH ;g;owug:LlGN#9! @WēqϏ{OC `..+hw5;+Hӣß#9‘# 0Y ]G+rod=#uYJ|ǀ/-/D)~쏬qַ8\l.9r_.3Nj,s=s~H]zcszavR`##xht?ז83F*sY)'>=֧ԤnbGoVnTqW4stơ0@vzR4٨uRt~)=+ @@q§|gG=F?cLՀ_:sŷÜ5XFURڎ" V?#R# @ \h̯r Q6/0SXhBAf!? ׸p> Зx"`.4ѻ,3GRvZ9# 'C<D,W g\^ʝ-yW.EI1_)~ϴj 5?#`.6_Oy|uy|.miv=_9fgJQ ;yGs$ GN'{9R  @)pYv|Ͼx2,g3t9 ץw/vCNdF!#9"p Jv @2{a pǃ<.{UYeJ `Y]J9o!:cHF?#ϊKc$@"@o}UssKy)E@@/+Y@`τ.0 G4~F3g_"@T7}:D0 z'K*͞x8:{ ؓ|xxjgD?#HD&ĠEAO N~[ yk͈}F3K @xm? E ߖ[88C#`p5#/H}>柑K @\gD87l@{5`6-m19i_MG1:񔏔?^O|\ę@:zϋ9NL."F&3"~烥|˅dd]"@E*c>K|s8X@`Ơ.G 2dl̷a @4~zv|#ҾӖ^؍n|X?#"~ZD"e7 @` >Q+WM>^v. s3 p@F3RgE:# @_&R~~)obI6K /ڈPg:# @l\Wb]"@`wc>E@ *r"& @ \'_R\wAxVy R^tR.U{y)UKo @ >:>A)DD x`un%QB]Q32O @`ODg(cGF@GPؖ]_~~fpެnWMJ*;9cFϚ @Z <8^+|U<ޟ>+?W-/y~c5gk_Z1x-9/5SBA]zInYZCcbO%bxx5EW|c pۯZVރɹ_?} x29R[@R | 5^1Wk>eqU1S-.]Qi9пEzijKhxE)ϋo5g%]Z G%s^_48\ͷƓ/;/챲#@#~Gt &oZz^cƈb_"0ovk.pQgW]sngܼJymKyDH @/rˍɂ_zk=Pgw?RLX]dSf+/ψtf~<=^x 1ylyc=3߈<(˷$ @`eo9IZ{b|==x [iG3^[HK}L?btSJ*FF"@VK '9)?BK=11rۤ #/@c;9>~2<1F ~r)9n'4&nN_ L_w΁x<Vds?vE&K?~b|/ 8h;211poJF+GhFOS=5.fO-|Vu &I3 fpCXs;kx:K+aޥ'b@WbZ" V0OG5uuu|ZfvÈ_ 5CsߌyΈ o 7$@%/ypMO4Rt~)'cMmw߻ ]aD#?f {b  |q=U1S]TFQX-/vRR^߰V'-Wc,&>'ߓrg* 0SNg"b҈-"Y__)xu쓖+pBx=KJ*FqwXWqrωN_xLDI\ xhZT}xs|'k;ƻO(}~)\sG>+& @: ArRƓqx<?=fCoh<$ Pѹ|ťQ$:h[?lەMJp 0 Cp:qU+`)_^>"XR \?Q_㩀{~vubd|^g~3~)/{n>F'-nx>E_'.J8O,ڝF&_Orss?/xktR[r)H@(E! @`k1W/y=~wDŽ~Igń:w1 x`L,KbRb?8M+px*J朘ED䎟8$ 0M{T<ϯ'ڤq|1v^?/˘J"@ i ~䒍ymkqv0e<x&PZr=U DasR41P.G(X1*OFqK֘F@~ÓoRʻ*572Q t x-" sښ4CmP q4RJ+j@>i?#9a`>KwW;'^ xQm$ 0KG~'fI;k3(f9$ x`#xW]1ýx*>Vʥf?g7038Kyc<J\f7C+Z,uӮ9q n)=/& O(ɨ,|aKbf؎@VOh}} vz'b&&⩿s~_'֣b sJ|n~hPbګc4{S/w=/?1 8JB4}Z<1_I|kIxtS>AE9wцy;GpZ֎9%_/^-@K{W|Dq' y|che @:WvsR{eKeꋥ'7&;I"@`⡋v7\Q1Oq :B?_%xցR<2gWB"~zƕ_wF֥?TOj9bX~eD3?F+kRMe[|SIbDoGhq$X@>5DJP"J h%B*5*B!%'-6 Ђ 6 !~m~W:;kkҸxsKy^{~䞑 "`{ |`Ocslo=ɧ7MJv9ݳmsrQN7~玤үȝC|b|\p7:'\}@ {/n>-c=/| 3rA @{$/xlʷK#Xnc?QAl㋃~ַ{o @xb|﷎/}ب }o.WN >'$P>V3_3>.ҥ @;.?;~n t6xwBgF  @ |l|G~/^p[ po o|n1 @#Eo_E *`r#@L|v/y|K۽|B\MMw_8~>QW!@C t8 }O/ %}||Ol7>G^1~)ש\< Ӌſ9~zN?xGGO}_ ɿ7Gp$X%@)w_[?|/>ExߣScGg7NQ xT^@+7t| ( @`C7@;;FBG!; @i?3q?csvgے|܄n߄$@\rrJhwOz /O( @ c|_[/Ɵ{CBp @ w'vnq w}?c[!@Sy G/?Rp|O_O~2 @F>16_:tO'nYxq ~c2>F1Q(O੸v_9~}M=A 8'8 /REJEJ6 _X-E#>:|DC s07!PNQ˪_OI7q5^" 1Uܴ$@N zn^eKeK__d{cQcg?<ύ/ jTDm&@6-<wo {n]-\U+=ޟ_Hiv ~Iowǯ ( @P7/}o_@ #m SwoFk>c{m @όc?D!@]OT~4Osc4~*/񩱗JVp6#``3ڍ s>珍_ZMAM {l1_77浾7f7M`63 ~'>Ovq|Oot ׍D޺ͱN9f = |@$@`{ӹ?c{{nGln lY?s;ow}O+ p{>4~Wa~sU}kpmND]xrǷ@xW}{tBG}|k}7/}CޗBlx# @`AP_h` X2Dxbׯyn# <(;#@^5QU=_?'9e @ |bl}3>>Q'nSs܈c:>Vӥo+}svy{ 8* |po/zcW/z/: @1_-E#۹ ~>TD_/}i/{n3k{lIc?>[qJkp͠NG6^kߵ7W&pE?f?? ={# ÏlQ@ŧ 88 @ @pBå @ @c 8 @ @pBå @ @c 8 @ @pBå @ @c 8 @ @pBå @ @c 8 @ @pBå @ @c 8 @ @pBå @ @c 8 @ @pBå @ @c 8 @ @pBå @ @c 8 @ @pBå @ @c 8 @ @pBå @ @c 8 @ @pBå @ @c 8 @ @pBå @ @c 8 @ @pBå @ @c 8 @ @pBå @ @c 8 @ @pBå @ @c 8 @ @pBå @ @c 8 @ @pBå @ @c 8 @ @pBå @ @c 8 @ @pBå @ @c |ҁ'us̓~J?;B @_7Q?z?V׏W]Zv^*qW @ @;.`?`G @J @؀ _7 @70G @'!``<ģp @ @x7'<_g&@ @'!p)l$ @ @3 @ @71<  @Is_8ғuZ @ |``h @ @(p)|wɺ' @ n< ?n6 @ @NT[ooڽ>6"# @ @kr߹yR<s7(ġj @I׽p݊ @"p՜95]0XB @nOf:w"r  @Ax+p j: @N] 9or޵Qmo>T  @!u's[sGpȍ՚ǎzNN @c%͋zu8.8 ;9 @xu^҇۵~u?X @Bl$׭[?kvf /_|]k3W1>( @ @ TNĨr]#>KC7.BY?~54_c>Х  @ @6 TN|;i\28ϯZe^d~+s5n :" @6Ɂ'^~nkkG[⡯c @Ie+ܺ5Veil{]MKNbJڙY  @ @["Pl~u_[ۿ@.tE\?R @ @-u}<4q1}nԋeK_<4W/O @NTrߦdƖڥ5nY˺y]f2  @ @rٞ&Mo!kkfN/ڽ_#k27>@N/"\hg}YWc]_w @ @ܵrؔvkJAױ/8Yjױ폏+j@!@ @',qm.u_&eil^ C^vu!vjN!@ @&PkrdށM{-k8?h4.*/WӞchtD @ pbV2|ozuUglŁ@Nυ~|R~& @ @*gM>[J>ۙO^U6`e>1/_'y2'  @ @TZ9Uroƪs?}*Nx ĚObcڥ5?U  @8!U+gl;9n-ssW.ױP//.e?'pN. @ @rY[^*Kcg3gͺ>vumsѹĚ_c?8ʼH @nXrU/g>V*5Veil!{ \L||b}ȚuB @nPrQ^R]SkS*س/ sEvƲ.5XsT'Q @ @ TnZ9jY{{_nuuKUx{z?{U7M3~.mq @ @Q TN\6Ӯ=^@.<si+. @ @0I+7ECrz~+>t ^_>6C?>jE @^/B @<@嘕kV:砗a/:.sX<aa6N/$튗I1ϧޱta @ @%*3f=7M{iҮ˫u)+ȅ2 L?k*Vbڽ>k>27B @.-P9g喕c&L|ǬI\W;$gҚt Eqxuy[+/- @ p&P9e=MYqCn.Kc pEd!틵>؟cw @ p%_2j˞sM3v\_j5rcw0|/p^~Oc1emhZc  @8DrVnjhYcK{[s+֩v5>~Q6&vLĬ{ @ @`?4jOc>严D?ee4?lYH;2mױ6H|{  @'Pc'kuRx{*ױ0_@~iŠf>8:n^[-`B @*gq'K{9uMv_k xnh-vY\>_>WsT @, TXO^o9iel-RY_Z{u|@^~J~wy.kz|icz;5F* @ @ ?3U{|2 f}U\c?t9@]XOOs՞sQxϮB @<G$sv?'^Køڕ(_wY&:^>6G}rT @-PG\q-sC9WCXR^kOԅ/]hOs\O15>2z͏qZ @N\~z}֯Kg/QqR>w7ꢒ{'?$ G  @ p'~g&9:{2?{?sv^b1t)P*}l6꒓|cծc+@_Z]u{gքB @^;o$'s{Nc|zyeQ˱6+Z;d}mu|ht~}?3քB @VwǕϣp'!>g9GOk,8ꯕ}sk\8(6"OR49f59S Qk  @ @V xwO'1O2ݓױT$sK7Үxr Jκ>jzK8[F P  @n@%ouNDdi^JUjZ7vAj.&gMsތ'^4u9'Ԩ~d @@}G/{B??O)+{.> vik.vsڹ]QoD/  @NX>QWb;IR\Jgs-^^7q\T{ڣGP7QuJޯv2Һ>kJ~/՟  @NP_%ФNxډ1dq%\ţGP7QIu9% O̱'f<{{s9O_wv6G~usggR$@ @?WvOv~?'K:6T?I!q,ZZ@LOoU!@ @x˸¿d?q)IcI{(~j'xcƫ$GPﷸoM\syx^#}lL&g" @nL5p휄Wbd|s_X>ukU}_sKem|inb.6IuO36x9ZWe>l쿙Q폟M/ @}ͥ-gډ9%x{}u;I~kKZy*f<1cW|˨O'FC* @ p|Jlԟ5v9M:>~zucRkSz;cG7P7;78's?$v)._'%4 F}֨  @O}ۨړx'Vݓ{⾔g~\ΗKj:jW+zn4Rsigf2XbU~*ߙQ;/  @ qο7j}O|-̉}_[;os=O;q +_l$7Ǫk|c9Wcz?ymΗs%fGF/|U!@ @ǩ~d$Ib%_ϥ{PűruI{z~og>UƫeނY[7ɱ8jF=OU!@ @ T@%= yo)|sv %c5Om`&ļsڥ~U\=QW>& @㈿7jJ&N"3V1}I6~&$xjͼr|_>6j/FU @ @`]Z߱{vJ>1ĚR~ըiQ @{~p_cA* vOӮ<{~_m}οq])GOmn'M?&u}l^7ʄH @ TBQΨs]JXc=Ob~bWk36>^)P=N;q km>}v߷?ԬKk[G}ݨ3g @ @`Ko7[?Q{"]Rj+\%'~žq9Z5q9h9 B sډKHk^4_fn/~lz;k,/kn_8 @@G}٨;R]IwOXNk}QsC81=H9 H\1펔>W'}MEuڥ{,u訟7)=q9  @Z# ?=ꏎQ+ғl]qXk}f{[N&Zٓ{vjG\˚WL5Y[v_3ب$u߹ƴB @\գַI|ծ?xQ?c52V1c}sK6vju=M;q "SڬK~yv_WFQ?wԵcJ!@ @I T[yZTI"=ǞX{nIĿs?>XcKqnWF)nHO|N\7ĵs̯׭{;w^Wo?2u^? @@5lmz<{bv+IO? {_K3s}:.6lu&vĥ[k]s1:!_ԗbԷbGe5 @ prWFQ4'NbK69o^\ZRUz'S((<־s?r|s}Ț>ǪfX:E{~5۸< @ ԗO~y|X%ٽ~ONRI9g^+_[sCROz"{vjǝjyncG`FPCSx  @@%?7j%o>_%IrogJOҽ'uixQҟ9~5XKx7 'i'hM+|-=.s/]zZyר ٣zX @ @R$jԟQ+7X%s;cs2^z=~j\b]gsKqL?pկRkOܶ L5}si?^Z4v׮y2jz@}_էB @O_5ꏍVRq>=V{&sMrܮΟiϯ~]{ƫl{&ni+UC{v R=׬~XtTs׵|_:5̀ @ p)hͣV\eNz{jtϱ^zKk2c{k~{LbJ?R m)ZvZw8'8Xsjel~߯onp~iO6Ĩ:B @%Dq67ZSv_s5 uݓvOk> }ogl-iX^8ު]Rz;c'+M_N\+᮱$|-q_K>kz2~Ӟ:K{)fQ x)* @l[+WD6Ǫ=J3t'Kr_si6ޏϚk]c{u'{vK팝d~i/5 uI{\H_Ҟ<~UL~s{r~i/>VS Ѯ{Q @m$)=M{)j9^Jg.\sk~UI&O?P޶2_sKz]J{v%^5Oq}Mr}{3G}FT @c'F}~~ʟfǹ]:'sԟ$6b͵zgL'5W%~O2V2y|8_uN%KI|[J:z9ss瘱ŚRRPQ B @D~k;G}v%%_}k5 uͧ]Z}qn_ԟ3.U[U6]|8_9&^s_>ԯ9wM~:[jX:JYu9j6>~! @k~oGL_cIdG2''+kg~pR\KƓ|9^ƗXroMUSߊxqnWj%ݽd=i9FOU?~i/q}|RisFQ?}?|~ԮuuB @`ITַWF?0~gZzIoYjgj/3iW$3!~]=$w7KbXZ{Hǹ]I{;IRLº/ޮטk[%ֳ|s~I[+֎1N @`kk{?v{]J3VZky]ﯽf]w{;cc|>]R ](s~bcoy~XҞcxk1k_=/r;/z  @Ux/3ܮZBz\%skc}.;/GutiX*ṷ.weœxуZZwľکΥ~c}|e2q2[K @. uX/3Vu)XǗIuk%}vk[署2dzѧӿ.mae5Kseo,5Yvd}Y8~kΑ-9  @lM#/z?튇J&d2X컖qjZ<}j>[@=9O}hyS+v9Ǽf[:_q[:~>G_zL;Xc7  @lA/z?CcߗX/%Y$\^Vvi-lou@?̯Ŭ_7|8uL{;s},k2Vk,gMsye42׏f|Y @nҿu3~b/X利XkҞc%},!1Ixb~>9GO+cǹ=wR*u̝*'bՓbױmFykM՚ks%c6j=~Ե_1ĺ:oŹ\<7ק/u{k&s}^:n^O @.\[jgl)jc+X_5O_kױ}.Zk>c|櫬ų٧ӿnéړ/zl\u|k_c׺ޟկuX״xb]cuRcs;z^rv?~mq @7-pk^:~vz_|"s[5q)c]~|W?yb[@=z=y++ƪsTvjJZ7oXQԥUkXg<95םSsYSJi}Ur|kD!@ p[Һy\{-Xogn)XOK c2vӞ:KbZs}7e利\Үc{7T\*W/md.K}k.Z5s},}U|sYTuK#@ pJoCykϧQ!kҮ8Y25ZO\RK^~-lԃO{agJrZj_Tk\10~#cvb3~`>:6%X_̯ws8 @eU5~ډuNyi|uZ%>X*9ܾ79g,1 @]`,v*k/W~>vs{_cQr3cJ{)XJ zy=ᬱgZ Y|uJ+Z{~v>=~u|:>^*u\Ĺ_q @yN,jRXձ|R;c=X+ @ P\O{)]jYRcNc{Rƪd3~o5is}N^ pJYOǬ[&t~̀]:. }%9ӮKULqǧ/jWיؼF @]e>WCk$}m=ks>v'k_ןvs{_c([\oVJ}o`r:&ZKzs'x3$gn_s>kXΛ56N @m߯ybO\KcuK3̱x1UOsL[7@OLk,A2Ǫ]o:jIvԮ똚K;~3Xs}>C8ܮ~zccX @#P?VY:w[jgl)jZ+kܞu[|!_םvs{_c+i/>Vf v|ל3/ROT;wQ9dE0O @Q TzQYZ>$֚.bOuyv~~KUJ xmPotRci?xaz#9R\:&vo-\G֤K_wWɺ>W픜+u @NY`_4\qN{?ˬu/&v1}[ab:'ϱz;.~>V2vO{)ԯk* @n!I缦qnW?N\Jb:Ks_^}U$ @OK{)XO)&Y\利Xk^}^EhJss2kc  @[2 luIDATv}|$YKͱ7tͱSK)jʂjeahvve<~vu^'~=vܯ~6 @ c'}^ؾ=kzu~Vnj~Ԛޮu}o%>Xsiϱ'|u}Ue~_*9ܾ7׵aM @R`_Rzn4}U;5ǧ?ǵ|ޮ]_Zӯc3/jԹ $[-Lfk85Z4~X?>7_^2/snk  @\Vಉ>R>~uO?'-_5kbU2$ @.v*~֭9y-s{OTJ/5F @%x}H5}]s,(Iq=3i]sU\%$\ZXǖ5#!PZ}nkJ޾rc @ Cҥ5}lRge~ZAK?Ҿc.XfNSV;h}ܮ~J-} @]H;[_jgl_>Xv|y,\W=2&( :eKXuڴ+ksYsH\;f}Mu}sk'@ py>$5^_4XK5VRƪcF.dtK?^"튽>5kck\bKKk/ @KlgvƖbK7Wמ5},~4-cWl]ÖlO{)j?dM|}c5WlxEY' @8ey~ˣ}U%sdǹ_q!$ZwKX}Hk繹_RckKX{6rߌglg⾹N @mHRtZcoTksse~_sծ9wik?!.yvv=:U>voA[Қ>}M?GFȴ6PIENDB`htmldoc-1.9.20/desktop/htmldoc.ico000066400000000000000000011163231472561501400170500ustar00rootroot00000000000000(6h^ h .   $$f($$X v,$$ 6@@h VL@@(V@@ (Blh((Lv (# +>Lt +( fD3"( f3f3̙f3ff̙fff3ff33,3f3/333,,f(3("f"3""f3̙̀f̀3fffff3ff3̀3̀3f3333 fw3̷̷ef3̙̙̙f̙3̙̙T̙˙f'3fff{ff3fef33(3f3333{{f3fffff3fff{ffff3f)ff̙ffff3fffffffffff3ffff3f3f3ff3f33f3ffffff3ff3 33f333333 3f333 33̙33 f3333f3 f3f3ff33f3f3333333f33333333I33f3G33h3f3f3̙f3fffff3ff333f3333̙f3wUD"wUD"ffffwUfD"f333wwwUUU3DDD"""33߳ޏݏ۳Gkߏݏk(  b*0I F e \ l) 0$H \ ~) h  < D \ () k$ W g(( @fD3"( @f3f3̙f3ff̙fff3ff33,3f3/333,,f(3("f"3""f3̙̀f̀3fffff3ff3̀3̀3f3333 fw3̷̷ef3̙̙̙f̙3̙̙T̙˙f'3fff{ff3fef33(3f3333{{f3fffff3fff{ffff3f)ff̙ffff3fffffffffff3ffff3f3f3ff3f33f3ffffff3ff3 33f333333 3f333 33̙33 f3333f3 f3f3ff33f3f3333333f33333333I33f3G33h3f3f3̙f3fffff3ff333f3333̙f3wUD"wUD"ffffwUfD"f333wwwUUU3DDD"""33####G###k###kG#G########k##k###k#k##( @ OjqrrrrrrrrrrrrrrrrrrrrqjO{h~  ^ [ 5 L ^ [ b$   P h ^ [  <  n { s [+  X  V [3+ 4 [ Y Y  [0  ! 3 d ^ [  ! 3 Q ^ [ h!  V R GGFF($HfD3"񙙙<8>($Hf3f3̙f3ff̙fff3ff33,3f3/333,,f(3("f"3""f3̙̀f̀3fffff3ff3̀3̀3f3333 fw3̷̷ef3̙̙̙f̙3̙̙T̙˙f'3fff{ff3fef33(3f3333{{f3fffff3fff{ffff3f)ff̙ffff3fffffffffff3ffff3f3f3ff3f33f3ffffff3ff3 33f333333 3f333 33̙33 f3333f3 f3f3ff33f3f3333333f33333333I33f3G33h3f3f3̙f3fffff3ff333f3333̙f3wUD"wUD"ffffwUfD"f333wwwUUU3DDD"""33##G##G##G#؏###Gk#G##kkk#G#k#G#######Gk###G׏k###G#׏ߏ##G##G<8>($H >aorrrrrrrrrrrrrrrrrrrrrrrroa>Z`DJ  S : B S : H !  S :  d 8 y S :4    L  S    j   J S m Z    \  S L  m    S :  m   _ S :  m  S :     <8>(@fD3"񙙑񙙑񙙑?(@f3f3̙f3ff̙fff3ff33,3f3/333,,f(3("f"3""f3̙̀f̀3fffff3ff3̀3̀3f3333 fw3̷̷ef3̙̙̙f̙3̙̙T̙˙f'3fff{ff3fef33(3f3333{{f3fffff3fff{ffff3f)ff̙ffff3fffffffffff3ffff3f3f3ff3f33f3ffffff3ff3 33f333333 3f333 33̙33 f3333f3 f3f3ff33f3f3333333f33333333I33f3G33h3f3f3̙f3fffff3ff333f3333̙f3wUD"wUD"ffffwUfD"f333wwwUUU3DDD"""33#####G#####G#####G######G#k########G#######k#####G####؏k####؏#####G##########޳##GG####ڳ################Gk###k###G#############G######؏###GGGGGGG###G###k########Gk####k########G####k########G###k######G#k#####G#####GGGGGG?(@  -@MUXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYXUM@-  #?XhqvxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxvqhX?"  #EccE# ?fh? -[]- ??j##%%&&&&&&&&&&&&&&&&&&&&&&&&&&&&& && &&) "&&B%  X,&&  ^%  X F&& } ' b&&/  k #  && F  A ? : : : : : :  W+&& }.&&  T  n o&&7 f  !&&7 y %  !&&6   !&&6%  X !&&6%  X  &&6 * && &&  &&&&&&&&&&&&&&&&&&&&&%%## RR LL?(fD3"񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙????(f3f3̙f3ff̙fff3ff33,3f3/333,,f(3("f"3""f3̙̀f̀3fffff3ff3̀3̀3f3333 fw3̷̷ef3̙̙̙f̙3̙̙T̙˙f'3fff{ff3fef33(3f3333{{f3fffff3fff{ffff3f)ff̙ffff3fffffffffff3ffff3f3f3ff3f33f3ffffff3ff3 33f333333 3f333 33̙33 f3333f3 f3f3ff33f3f3333333f33333333I33f3G33h3f3f3̙f3fffff3ff333f3333̙f3wUD"wUD"ffffwUfD"f333wwwUUU3DDD"""33#################################################################k############################G#G#################G####k###################G######k######################G########؏####################################################################ڳ#################################G#################################؏G##########G################################k#############G##########G########؏############################k#########G##################################k#######G#######؏#########################################################################################k############################G#################ڳ############################################################G##############################؏#############k##################׳#############k##############################G##########################G######################G##################G##############G####################################################kkkkkkkkkkkkk????(  !'*-........................................................................................-*'! ".8AGLOPQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQPOLGA8." "1@MW_ehkllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllkhe_WM@1"  +=O]hotwyzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{zzywtoh]O=+ 1FYhq~~qhYF1 3J_nn_J3  1JassaJ1 +F__F+"=YY="1OzzO1"@aa@".MM. 8kk8  !@@! 'OO'**,,........................................................... l  .. l  .. l  .. l  .. l  ..( L l  ] .. A P l   |..  ] P l  /.. | P l  I... P l   e..HD l   .. d } l   E 4..  O  l     O ..4( l    R m..  O ] l  *#.. `3 l                _ .. j l 5  P..J l   P.. m l 2 P.. :  l B ..> % l   T ..>4 l  e ..>D l   y ..= U  l   ..= g l  - ..=5 l    ..= P l   .. < P l   .. < P l   .. < P l   .. < P l   ..  l  .. l  .. l  .. l  ..G  z n...............................................,,**'' !!   ee)) "",,!! VV ????PNG  IHDR\rfiCCPkCGColorSpaceGenericRGB8U]hU>sg#$Sl4t? % V46nI6"dΘ83OEP|1Ŀ (>/ % (>P苦;3ie|{g蹪X-2s=+WQ+]L6O w[C{_F qb Uvz?Zb1@/zcs>~if,ӈUSjF 1_Mjbuݠpamhmçϙ>a\+5%QKFkm}ۖ?ޚD\!~6,-7SثŜvķ5Z;[rmS5{yDyH}r9|-ăFAJjI.[/]mK 7KRDrYQO-Q||6 (0 MXd(@h2_f<:”_δ*d>e\c?~,7?& ك^2Iq2"y@g|U\ wIDATx{U<$JX+yZ.U"(bFE]ZTcZK#Ѕ,XLR`x l%2{g}wO;}s~uNID@D@D@D@D@D@D@D@D@D@D@D@D@D@D ]9؆@,E,Fx5bTIB%0 y2c$׈G@Z-8 5>rD7BI:(*_ ښisP!ZD b3G|jB4@@}a v!A% qb PdC 1gl}JEʵ.Pwg#~;Yz&,K݄xM+:D@ g"AXOj|L̤WHebPȎ>Aܗjgj&|@@ w#@L :BIDW,DAh< _AIH`w5LcL6@eE@R`Oc?M9Ix" Pd9$#ЎCF lC$2$Go? (@P$I6}`oJ" !@MRfM@3ǎ/o@(؜"^Bv:S9e_l6Qjnbzi}|%)>3kDu{z f$~@PFU]1>Vz\WvBID Uj֮ Z`a?%VY3sŖ2f2t@8Y; Z \F) E(CXl**Xw Њ!"g,kmeopi@ PԮ LKY-1#,j4OD ]jZ?fQID 8ԮA|T@g kD@#@R j=:b%P~p!4c.BID <ԮZEW¼@ID <v#{&zyLf@8jU(7_\V4S\/P;0R>/!]-ݪB~Ͻ+0Oa?x>+fuc4ܙOΙ{ Mʘ1TFWuB0?hQw:xIi];yxHI.ao+A|#)yL3BY ]_92⾏u6;N{@ޟwbOFp~1+Ylqi?ߊ#1wPnʅHgoNso#>cx!h3pFǸNc?8,ijQƖ2#꧱ηfvg/nƍDft#Qjԍ@̀{+~Gu\atZf)G`.E} #h.,_ {{o$o;F{ZAqxwq4l aX:7G6=#ϯ ^[_gh7@C/Ex~D[RX]=l.xfN}ՕO0;^@] |X^#Kt..]ߎy|: 񕐦bUp?U%WR3|N+n o8QQ\l~| ˮX7w vͅ1n g08|j>'kb*T׽ٞ$X n1z[s~yNͷ,^x㸣/4Va`+qG&k}),C^=㶎㹒7W~Ft^אZ6)`ϧxḣ|G/y?67Bp X 4-'7ڔ򺯯D@ :/q_xz/e*ZfVu=)bMxcRi܉]^$2{N||wH,~ a_ؗpu0_Ӄ_f$ߦa7ϭ3JNhKOC}ݷ}W ᆑp 3y;}56+?ڳ6|G$(]񧛰}3@3p ^Yp $`t.%nŋF뽫q)Sqp@.av䱫 ]mihzh=0vy[.WQ#-G7X*N=H|5إx~d^wxpY>!췷)_t P]ǻށ'pL6=1n8NzU\G83p1C#h>{3yYʬPA6 0n8R2qD,?yNvfs WW&_֭X0|*8=ۍрh | CJU#Ma)~ D R=_9@0Gp\=yۧR88;oG kў+UT2ß ;x9.i/| Jt31TO@PRy\Z8X5Ne]n~ N/4/ǒ&Kan7SkkC} vڻD7|,<+'J'(rp܅_KwZe <cM>|1?~^`+wc>t8a#I> rtK#JɗkMάn u^(-(G E n2WduhM@wv"P .- n_Nţ"7@ډ@]48?^wPD ?@+D֠$! HBKyE 22T$dIh)DF@Y:" -"kPUG$"@d @2$W"# AUHB@@dd5#IR^ UuD @Z+D֠$! HBKyE 22T$dIh)DF@Y:" -"kPUG$"@d @2$W"# AUHB@@dd5#IR^ UuD @Z+D֠$! HBKyE 22T$dIh)DF@Y:" -"kPUG$"@d @2$W"# AUHB@@dd5#IR^ UuD @Z+D֠$! HBKyE 2@1::")jxSh"mvGEN!P ` ^ZDFڥkjP^ٚ@D m\]52yTD (['ִ\ p4CD ԮmeȂ'(B׮@Ŧޟr asEI38< |~Q$"jk50W ZF+h[[*"Ԭצ)@~fZ&*M3nF(fl"5kM'eo+Y>:l֦UM7Sf6{;J" %@R[x |dx_̤$"[(J͚~LSX+wL<6Q+pSʆ[J" #@mRԪ6Ԩ`Z<ϏM[m$i:5 )UR~AQ}"5YSS1g EG!J" C¾ ?.5MPPfϘy#D@f?AP>&@E/̔P{/M%oCHo`ⷣ?Oqze=S^4 u%x_Q.~G@T,M3{7B=#Oj^wjz\fMi_pLD@2$@}݅#|]rSQ`*#> PՌ "A!D@!@q߈~8џvOӨz=.-gN- }!^<7 xpm$~.M#xj`r<3r܎BID ^j>Nk_k{Z3s `ݕ:-%h@bow.0s9nṿQ[k)_q7x} D@]7!x?j&~~=M"DEmjMs} ȻE@N?˘ 0^8A@v%Ep܌&G#O?P&s~7[pmMLF@؆-fBDFtR]IrE:љGrxAQS7様} SRǏ6SEoƍc)f 0qZ@Q ioM3&|_77s&~aR*/ۗrZ^ O4<f&zbK4S_/v)r3=YecH%~K`&*VBX3fL7[&@ J0Ni\&|غ3J/p>7X/QOFyb@6et©#?MbM<3n |Lfb6rUίU(?6ة@df_IHDm3pj0S 7Mu߃ɓ 7y\38 NPL'@M ;0`yb@4nS ؂F`B/2N- ƓTHm3rj)EmGtNel6♥V ˩/j~[^)cg% S ێ_Ou5TIENDB`(@fD3"񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙟񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙟񙙙񙙙񙙙񙙙񙙙񙙙񙙙񙙙????????(@f3f3̙f3ff̙fff3ff33,3f3/333,,f(3("f"3""f3̙̀f̀3fffff3ff3̀3̀3f3333 fw3̷̷ef3̙̙̙f̙3̙̙T̙˙f'3fff{ff3fef33(3f3333{{f3fffff3fff{ffff3f)ff̙ffff3fffffffffff3ffff3f3f3ff3f33f3ffffff3ff3 33f333333 3f333 33̙33 f3333f3 f3f3ff33f3f3333333f33333333I33f3G33h3f3f3̙f3fffff3ff333f3333̙f3wUD"wUD"ffffwUfD"f333wwwUUU3DDD"""33###################################################################################################################################################G##########################k################################################################؏#######################################G############################################ڳ##############k##################G##############Gk##############؏##################k#############؏################################G#############G###############################k##############ڳ############################################Gk#########################################################G###############################k############k#########################################################؏######################################################ٳ########################################################G###############################################G##########################################################kG###########׏####################################k############kG###########################################################kG############k##############################kG############ڳ##################G############kG##########################################kG############G##############################kG############؏###############################kG##########################################kG######################################kG##################################k##############################k##########################k######################k##################k##########################################################################################????????(@  $),/1222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221/,)$  &.6<BFIJLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLJIFB<6.&  (3=FNUZ]`bccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccb`]ZUNF=3( %1>JT]diloqrssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssrqolid]TJ>1% *9GT_hnsvxyz{{||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||{{zyxvsnh_TG9*  ->N\gouzzuog\N>- .@R`lttl`R@.-@Sbn~~nbS@- *>RboobR>*  $9N`oo`N9$ 1G\oo\G1 (>ThhT>( 3J__J3&=UU=& .FffF. 6NN6$<dd<$)BB) ,GG,  /mm/  11  11  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  2 N1!2  2 N1!2  2 N1!2  2 N1!2  2 N1!2  2 N1!2  2  N1!,] 2  24 N1!> |2  2  N N1!>.2  2 k N1!>H2  2"  N1!> d2  2 :  N1!> 2  2  U N1!> 42  2 s  N1!! O 2  2( m N1!, l2  2 AB N1! b#2  2  ] | N1!8  :2  2 { O  N1! p W 2  2. ( N1!D t2  2 \ N! 2  2>3 N!  Q2  2> i N!)2  2> : N!  ]2  2= J N! o2  2B \  N!  !2  2 A n N!&  !2  2 A  N!5  !2  2 A % N%G! E !2  2 A4 N1!  W !2  2 AD N1! i !2  2 A V  N1! |  2  2 A g N1!   2  2 A N1!>  2  2 @ N1!>  2  2 @ N1!>  2  2 @ N1!> 2  2 @ N1!> 2  2 ? N1!> 2  2 ? N1! <2  2 N1!2  2 N1!2  2 N1!2  2 N1!2  2 N1!2  2-                   2  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  22  11  11  //  ,, ))$$   FF  ""SS OO5ww4????????htmldoc-1.9.20/desktop/htmldoc.info000066400000000000000000000000111472561501400172120ustar00rootroot00000000000000HTDChtdc htmldoc-1.9.20/desktop/htmldoc.opacity000066400000000000000000000432631472561501400177470ustar00rootroot00000000000000bplist0056X$versionX$objectsY$archiverT$topgbnopqrvw~VI $'*-45<=IJKLMNVZ^bcipz /5678adgltw}6FGHIJKLPTX\]^_cfghijkpv  %&8HIJKLMNRVZ^_`dghixy   (89:;<=>BFLMNRSTX[\]stuvwxyz{@}~M:9!&*.U$null0  !"#$%&'()*+,-./0123456789:;9<=>>@AB::CDEFGH:IJKLMN>PQRSIMUVWXYB[\>^>BY@9WpolySidWpixDTypSbmPUresUnTsecCUcolSpUoBgImSparVnPaStrWactLaysUsnShsWpenTTypSmodTzoomTallRVsavStDTmetaVspiDecVgenNamUorTypVpixRadTfrasUimSizUbgColVnPaFilV$classVactTraVsavPrDTtarsVcurFraSenVVlineThVautoBTUshLayXrectCRadUresiMTcurRWspiSegsTtrasWfilSensUmainCVtraTrgVcurObjVguiLinTvarsVlasModWpolyStaUbgTyp lc,#@@ #@T #? f< #@ - ,#@I}b,cd"eimWNS.keysZNS.objectsfghjkl \kMDItemTitle^kMDItemAuthors_kMDItemCopyrightXNew Icond"sut ]Michael Sweetxyz{Z$classnameX$classesWNSArray|}WNSArrayXNSObject_Copyright 2017 Michael Sweetxy_NSMutableDictionary}\NSDictionaryd"uX  "SresSdel#?xy\PCResolution}\PCResolutionXPCObject"#?"#?"#?"I"#@"#@"V"#?d"uR "ATlaysUanimTUlAcLs#?cd"mfghjl d"ut d"u>Z "@:R:@MTisShUblendSnamWmaskTypTopacSfilWmaskLayUedMskSvis=.#@Y/ ">BUalConTobjs,-cd"m !"#$    %'()*+ #?#?"V&xy_PCBitmapContext}_PCBitmapContextZPCDrawableXPCObject"#?&"&""#?&"I&"&d"+u xy./]PCNormalLayer0123}]PCNormalLayerWPCLayerZPCDrawableXPCObject]Shadow Effect"678:;TfilNTatts<01_PCShadowEffectFiltercd">Cm?@AB2345DEFD67;6 [inputOffsetZinputColorZinputAngleYinputBlur#@OPQ"RSTUUNSRGB\NSColorSpace_NSCustomColorSpaceJ0 0 0 0.58:W"XYTNSID9xy[\\NSColorSpace]}\NSColorSpacexy_`WNSColora}WNSColor#VxydeXPCFilterfgh}XPCFilterZPCDrawableXPCObjectxyjk]PCFilterLayerlmno}]PCFilterLayerWPCLayerZPCDrawableXPCObject"::@rsMuw@RB? C-E">}B>@,-cd"mA "sV?&Scd"mD "V>&d"uF " @@MM@M@TrectTstrYSisIXstrTBndsTstrXSshXTantiSflVVattStrSshYUalPixSangSflHG # YH> X_5{{4.0850515463917532, 33.996134020618555}, {120, 80}}"XNSString\NSAttributesIWJScd"ŤKLMNĀOPRUVVNSKern_NSParagraphStyleVNSFontWNSColor">ZNSTabStops[NSAlignmentQxy_NSMutableParagraphStyle}_NSParagraphStyle"[VNSSizeXNSfFlagsVNSNameST]OpenSans-BoldxyVNSFont}VNSFontOP"SUF1 0 0:xy}xy_NSAttributedString}_NSAttributedStringP"9UWNSWhiteD1 0:xy\PCTextVector}\PCTextVector_PCRectBasedVectorXPCVectorZPCDrawableXPCObject"::@M@R^[ _-a">BZ\,-cd"m ] "V[&ZBackgroundcd"m` "VZ&d"ub  "!"#@M&M@))*+M@UdimLKWfilPropVcornRXVcornRYUstroscf g #@0{Z cd"02m1d3e ]cornerRadiusX]cornerRadiusY_{{4, 4}, {120, 120}}9:;<=>"?@ABCDEFGHIJKLMN@PQ:RS:TUVW>Y[\:]^S_MVrelLP2SblHWgradAngUradGCTfilTWrelRadCVfilPosSaEqStypXrelLinP1VfilColVrelLP1UfilImVothColXrelLinP2SgEqUfilGrSrEqXgradStopUpgNumSbEqt#@Vpqzyshribuwvjx OP"bSUF0 0 0:OP"eSUL0.6 0.6 0.6:d"hkijknomno">&<sValtColSlocScolglmP"u9UB1:xyxy^PCGradientStopz{|}^PCGradientStopZPCDrawableXPCObjectmno">&Ysgimxy^NSMutableArray}WNSArrayV{0, 0}V{0, 0}V{0, 0}V{0, 0}V{0, 0}V{0, 0}Q0QtW100 - tS100xy_PCDrawVectorProperties}_PCDrawVectorPropertiesZPCDrawableXPCObjectd"k|o9:<;=>"?@ABEDFGHIoJKLM@P::T>:M\I:\]S_TcapSSposUinvisSwidUdashSy~b w}vxP"9UB0:OP"SUL0.4 0.4 0.4:d"komno">\s|}mmno">s|~mV{0, 0}V{0, 0}V{0, 0}V{0, 0}V{0, 0}V{0, 0}d"uO xy_PCStrokeVectorProperties}_PCStrokeVectorProperties_PCDrawVectorPropertiesZPCDrawableXPCObjectxy\PCRectVector}\PCRectVector\PCPathVector_PCRectBasedVectorXPCVectorZPCDrawableXPCObjectd"u> xyWPCFrame}WPCFrame_PCMetadataObjectZPCDrawableXPCObjectd"uˀ߀ "A @M>>: >M@@BYauSizCropVnewFacUapIn1TpathTapIDUcropRUapIn2UisRelUisColTcropVvarVal ,_{{0, 0}, {0, 0}}\htmldoc.icns"A !"#$MR'()*>,-.M0134UcodeSUprColVprShTiSfraVcodePlVcodeFrUcodeFTsnShVexPropTpropUgenCHUgrTypVanLooCVprLinCUcodeL   cd"7>m89:;<=?@<BCDl V{JFIF}U{GIF}_"kCGImageDestinationBackgroundColorU{PNG}V{TIFF}_*kCGImageDestinationLossyCompressionQualitycd"MNm cd"QRm cd"UVm cd"YZm #?^com.apple.icns]public.foldercd"`am OP"dSUL0.5 0 0 0.5:SiosUcocoaUtouchVMyViewVUIViewxylm_PCBitmapPropertiesno}_PCBitmapPropertiesXPCObjectxyqrYPCFactorystu}YPCFactoryZPCDrawableXPCObject"A @@>z>: >M@@B ,_htmldoc-128.png"A !"$MR'(*>M014  cd"m<l V{JFIF}U{GIF}_"kCGImageDestinationBackgroundColorU{PNG}V{TIFF}_*kCGImageDestinationLossyCompressionQualitycd"m cd"m cd"m cd"m #?Zpublic.pngcd"m OP"SUL0.5 0 0 0.5:VMyViewVUIView"A @@>>:>M@MB  ,_{{8, 8}, {113, 113}}^htmldoc-32.png"A !"$MR(*>M01( ɀǀ Ȁcd"m<€ÀlĀŀƀ cd"m cd"m cd"m cd"  m #?cd"m OP"SUL0.5 0 0 0.5:SmacVNSView"A @M>>: >M@@#B ̀ ̀,[htmldoc.ico"A !"'$MR'(,*>/01M0154 ݀ۀ΀ ˀ܀cd"9@m:;<=>?πЀрҀӀԦAB<DEFՀրl׀؀ـ V{JFIF}U{GIF}_"kCGImageDestinationBackgroundColorU{PNG}V{TIFF}_*kCGImageDestinationLossyCompressionQualitycd"OPm cd"STm cd"WXm cd"[\m #?_com.microsoft.icocd"abm OP"eSUL0.5 0 0 0.5:VMyViewVUIView"A @@>m>: >M@@vB ,_htmldoc-160.png"A !"z$MR'(*>M014 ‸ ߀cd"m<l V{JFIF}U{GIF}_"kCGImageDestinationBackgroundColorU{PNG}V{TIFF}_*kCGImageDestinationLossyCompressionQualitycd"m cd"m cd"m cd"m #?cd"m OP"SUL0.5 0 0 0.5:VMyViewVUIView"A @@>>: >M@@B󀨀 ,_htmldoc-256.png"A !"$MR'(*>M14  cd"m<l V{JFIF}U{GIF}_"kCGImageDestinationBackgroundColorU{PNG}V{TIFF}_*kCGImageDestinationLossyCompressionQualitycd"m cd"m cd"m cd"m #?]public.foldercd"m OP" SUL0.5 0 0 0.5:VMyViewVUIViewd"koZ{128, 128}P"9UE0.75:_CICheckerboardGenerator"A !">$MR*> !M01% Ɂ  cd")0m*+,-./  <23456l _"kCGImageDestinationBackgroundColorV{JFIF}U{GIF}V{TIFF}U{PNG}_*kCGImageDestinationLossyCompressionQualitycd"?@m cd"CDm cd"GImHJ [Compressioncd"OPm #?_com.likethought.opacity.opacitycd"UVm OP"YSUJ1 0 0 0.5:Vquartz_MyDrawingFunctioncd"^hm_`abcdefg !"#$%&'iiklinoii(()*(+,(( _framePickerVisibleZhideRulers[windowFrame_layerViewDimension]hideVariablesZexpansionsYprintInfo]toolbarHidden_editFrameMetadata_{{4, 254}, {626, 523}}#@i`cd"m "\NSAttributes;-cd"m./012345677896:: _NSHorizontallyCentered]NSRightMargin\NSLeftMargin_NSHorizonalPagination_NSVerticalPagination_NSVerticallyCentered[NSTopMargin^NSBottomMargin "B"Bxy[NSPrintInfo}[NSPrintInfocd"m=>?@ABCDJNS=W _"com.likethought.opacity.preview.ui_(com.likethought.opacity.preview.elementsWfactory_#com.likethought.opacity.preview.web_&com.likethought.opacity.preview.cursorTtype_&com.likethought.opacity.preview.iphonecd"mǁEBF<ˀl9G Ucolor[resolutionsd"kHI#$o#?#?cd"m܁KLMii((6 VstatusWtoolbarTdockcd"mOPQR WaddressUimage_#http://likethought.com/opacity/web/_,http://likethought.com/opacity/web/image.pngcd"mŁTBUEELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Kmexy+,]NSMutableData+-}VNSDataxy/0WPCImage1234}WPCImage_PCMetadataObjectZPCDrawableXPCObject_NSKeyedArchiver7Troot"+5:? &*/4;@GNT[`flsz  (*-/8;DFILMPRUWY[\_hjlnpy{}  +4<AIRqz&/@BKMO`bkmo&)+-FKQWY[]fhjw~         ! * , . / 0 E K P R T V X Z g t v x z | ~    " / 1 3 @ B K M Z \ ^ k m o x y {   % ' ) + - 6 8 : < > @ L W b l u    ) 2 ; D O X a o z         ) + - 1 > A C F H J W Y [ d g i k    FS\ikmos!4ELU\^`bpy '4HQ\e  !#,/13zfmqy   !(*7DFOTVXZovz~ '.5<CJLNVZc|5:>DHNPQSUWY[]_acdfhjlnpr !&(*,5P[v !#,4?GZenw  "$%'()+-@M   !#0=?ACEGIVXZ\^`bdkq,:GHIKXegkqw~ABCEGIKMOPRSTVXj !'LRY  XYZ\^`bdfgijkmo "$&(*79;=?ACERSTVcdegtuvx     ,{}~    H U V W Y f g h j w x y { !#!$!%!'!)!+!-!/!1!2!4!5!6!8!:!L!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"" "."4";"h"u"v"w"y""""""""""""""""""""""#/#0#1#3#5#7#9#;#=#>#@#A#B#D#F#X###########################$$$$$ $ $$$$@$F$M$z$$$$$$$$$$$$$$$$$$$$$$$%%% %%%%%'%4%:%<%V%%%%%%%%%%%%%%%%%%%%%%%%%%&&& & &&&&&=&D&J&Q&W&&&&&&&&&&&&&&&&&&&&&&' ''''')'4'6'='Q'^'q't'w'z'}''''''''''''''''''''( (( (.(B(C(\(e(r(s(t(v(((((((((((((((((((((((() ))')?)V)m)y))))))))))))))))))))**** * **4*_*g********+++ + ++++$+-+6+9+<+>+@+B+K+T+a+h+k+n+q+x+{+~++++++++++++++++,,,,5,8,;,>,A,J,L,O,Q,S,U,^,g,t,,,,,,,,,,,,,,,,,,,,,,,,,,,-------"-(-*---/-8-@9999999999999:::9:htmldoc-1.9.20/desktop/htmldoc.plist.in000066400000000000000000000027521472561501400200350ustar00rootroot00000000000000 CFBundleInfoDictionaryVersion 6.0 CFBundleExecutable htmldoc CFBundleIdentifier org.msweet.htmldoc CFBundleVersion @SVERSION@ CFBundleDevelopmentRegion English NSHumanReadableCopyright Copyright 1997-2024 by Michael R Sweet CFAppleHelpAnchor help CFBundleName HTMLDOC CFBundlePackageType APPL CFBundleSignature HTDC CFBundleIconFile htmldoc.icns CFBundleShortVersionString @SVERSION@ CFBundleGetInfoString @SVERSION@, Copyright Michael R Sweet 1997-2024 CFBundleDocumentTypes CFBundleTypeExtensions book CFBundleTypeIconFile htmldoc.icns CFBundleTypeName HTMLDOC Book File CFBundleTypeOSTypes htdc CFBundleTypeRole Editor htmldoc-1.9.20/desktop/htmldoc.xbm000066400000000000000000000015761472561501400170660ustar00rootroot00000000000000#define htmldoc_width 32 #define htmldoc_height 32 static unsigned char htmldoc_bits[] = { 0xf0, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x1f, 0xfc, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xe3, 0xff, 0xff, 0xc4, 0x23, 0xff, 0x3f, 0xc4, 0x23, 0xfc, 0x0f, 0xc7, 0xe3, 0xf0, 0xc7, 0x07, 0xe0, 0xe3, 0xc7, 0x07, 0xe0, 0xe3, 0x0f, 0x07, 0xe0, 0xf0, 0x3f, 0xc4, 0x23, 0xfc, 0xff, 0xc4, 0x23, 0xff, 0xff, 0xc7, 0xe3, 0xff, 0xff, 0xc7, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0x3f, 0xf8, 0xff, 0xff, 0x1f, 0xf0, 0xff, 0xff, 0x0f }; htmldoc-1.9.20/desktop/htmldoc.xcf000066400000000000000000000025211472561501400170470ustar00rootroot00000000000000gimp xcf file BBBgimp-image-grid(style solid) (fgcolor (color-rgba 0.000000 0.000000 0.000000 1.000000)) (bgcolor (color-rgba 1.000000 1.000000 1.000000 1.000000)) (xspacing 10.000000) (yspacing 10.000000) (spacing-unit inches) (xoffset 0.000000) (yoffset 0.000000) (offset-unit inches) gamma0.45455000000000001 htmldoc-32.png     h | Uq  " " = 1  U&&&&&&&&&&& &&&5&&&&&&;  UK4p;  htmldoc-1.9.20/desktop/htmldoc.xml000066400000000000000000000005631472561501400170730ustar00rootroot00000000000000 HTMLDOC Book File htmldoc-1.9.20/desktop/htmldoc.xpm000066400000000000000000000027011472561501400170730ustar00rootroot00000000000000/* XPM */ static const char * const htmldoc_xpm[] = { "32 32 17 1", " c None", ". c #000000", "+ c #0F0F0F", "@ c #FF0000", "# c #FF2600", "$ c #221A18", "% c #110200", "& c #040000", "* c #010000", "= c #030000", "- c #0D0200", "; c #220400", "> c #0D0100", ", c #3D3534", "' c #1C0300", ") c #030303", "! c #070707", " ........................ ", " ................+......... ", " ............................ ", " .............................. ", "................................", "................................", ".......................+........", "................................", "................................", "................................", "...........@@@....@@@...........", "........@@.@##....##@.@@........", "......@@@@.@##....##@.@@@@......", "....@@@@...@##....##@...@@@@....", "...@@@..$..@##@@@@##@.....@@@...", "...@@@%&*..@#####@##@...=-@@@...", "....@@@@;>.@##@@@@##@.,'@@@@.*..", "......@@@@.@##....##@.@@@@..*...", "........@@.@##....@#@.@@........", "...........@##....@#@...........", ".........+.@@@....@@@...........", "................................", ".......++..............)........", "....+++.................).......", "..++.....................++)....", "++..........................+!..", "..............................+.", "................................", " .............................. ", " ............................ ", " .......................... ", " ........................ "}; htmldoc-1.9.20/dmgbuild.png000066400000000000000000000257321472561501400155500ustar00rootroot00000000000000PNG  IHDR09iCCPkCGColorSpaceGenericRGB8U]hU>sg#$Sl4t? % V46nI6"dΘ83OEP|1Ŀ (>/ % (>P苦;3ie|{g蹪X-2s=+WQ+]L6O w[C{_F qb Uvz?Zb1@/zcs>~if,ӈUSjF 1_Mjbuݠpamhmçϙ>a\+5%QKFkm}ۖ?ޚD\!~6,-7SثŜvķ5Z;[rmS5{yDyH}r9|-ăFAJjI.[/]mK 7KRDrYQO-Q||6 (0 MXd(@h2_f<:”_δ*d>e\c?~,7?& ك^2Iq2"y@g|U\ pHYs%%IR$iTXtXML:com.adobe.xmp Michael Sweet Copyright 2018 Michael Sweet New Image ;Q$IDATxydU'[, PUʦ 32 `Ȯa ؂3 Ҋ PȀ-"l*"% 4Vl˨|q^^թ'T],9WY( [elUJ@VY( [elUJ@VY( [elUJ@VY( [elUJ@VY( [elUJ@VY( [elUJ@VY( [elUJ@VY( [elUJ@VY( [elUJ@VY( [elUJ@VY( [elUJ@VY( [elUJ@VY(F% /ȘBFD dL#2QSˆ()`D@Ɣ/"J@ c% 1ȘED dL"2hQS()XD@Ɣ+"J@ c% 1ȘBED dL"2HQS()PD@Ɣ'"J@ c% 1H,GHG`B L EH,&o.DG6HO&P_~it3&7摔x+?],Z]D4]US'-S*} R^vJL;eȄ57Sk/~}̪T-Zs~*_H˿Smk+AF_J.IQ*^+ڹ`a6H)84% 0F]PgɔBCS8λH%mk w,ޚyھW:릿/g]MRԮ5J<zV5iX&etܮ)L`'xoϸ(vJwQq#LDxS“Nc^3#JGߗdnnUgF,pc]F^?3ZP0mbSFAFC](;ca?7\W,qF:nq.ns??yv[k[7.2y4q(Hd+VFʗ\X/PO6602.~2%V*~o`{am*V~6{vUYCxz>MO46Lzj䴹+>od 8+Z՗k%;Ewz5zܙ žR]*)TpŹKqzt>b)*QJFɵ%0,toOyFs72+ZFT+~.O/(Py" Q]_;.>EqCr1뼆gZ?k%ʖsv]Z++s>Q Ϡk^}IŴjvoq*۹?{X y@C +֯_ҽYrI909fU>hXF&l.7S0Z֭dM:nL7jE!ig *ŋ<];GvhlV](;6b2rD]60FMToRceeёDZq/#^FeQyZu[Cvw~oTk4DJyzM_Cxzyly=xx/q/,c ,6JFiT$ųc𢡊:V?j8lm_{L;v_/p1]s;aAv~h FP ԸB'b@vcZ c^Ϊ W>ϝzimࣵgP]{[{<ھ7;vnn)՗5 6@~sk=Jj^; FXףzDZO8 @ظnZ樆k8yҢxG:˳m8_}j}>aqic okh , }]FU;8VT1n`6ʌXtaQLsj]J5S%TLxϧ9aquHp/Jy>W,Em]K}sq~#CFk RV}ݾ@U+ls9 K*E/AW su|G};Ẏ)/>KyYF;Of ~XF&Tca`s£=vZ)(aZq\WOϳ{!9OsWVZVaTB#QFλ{:gR/{6| k1e}?>WptK~6s9&ݶnñj8V,Xu8TbpAKv9g]> XkR [XZٵ|#=zb\׼./tG4>od @0Ƶ"2Qd@CA7훦sTG54,+Q mg1! =z(]Ϯ#,&e*vq,~#QPciL Uuʕ8#8J15c$)1ȃ %P& }\51uڵb;y'm֎*F}:"h^q==i[ȼDZLD?XH ryn1Zj~ʰs*PJ_K.-)U.+']6FMUS3F4ebјS:s 8H9`P!UϢ[Ǿȳ0$_Lh(L/V]T$?`P%ӴSSwsQGRnL]F},PRTH~PQ()ND@Ɣ'"? c 1%Ș"EDdL"2PQS()VD@Ɣ+"? c 1%ȘEDdL"2pQS()^D@Ɣ/"? c 1%Ș"FDdL#2QR@Ɣ1dLS@Ɣ1dLS@Ɣ1dLS@Ɣ1dLS@Ɣ1dLS@Ɣ1dLS@Ɣ1dLS@Ɣ1dLS@Ɣ1dLS@Ɣ1dLS@Ɣ1dLS@Ɣ1dLS@Nr (EDBA " @Ș@D1%( cJQ@Ɣ")DDS2 dL " @Ș@D1%( cJQ@Ɣ")DDS2 dL " @Ș@D1%( cJY3eʔrmm-oy{" @P>lЇ>䞈*[nQPqV^yr-ho.l~x;,L#8 +0mf{]s1G?qz>뮻5E&O<<[n>l7߼zNZnvaV|V[mU.úw&M*Yg=8ꨣ=أ\s5{[U|>qڴi̙3*w |q/x[_O~.7ؿ/ (|(.Vu駗;':& Yfu/Bkz]wݵnnh{iulk:ε:s\>Q+oA;3K/'EY}iʇz\s5]kjRC%#x=4{mC}?>?y{:_#!' Ѧ{~vPAZꫯo1LJUSwq^=J!w{9 A :k}o& hxN]8Ds6>:s_5bSN)/VYc{k{;;h Q^UG|Y-;.m><bkg̘Q]tQ;F([lq{g_joz;lͰ_\_Zx̌ǽاSOmK/?x58?Wu]kߖsxlE9.b>O?t{G sۗ_~~wkQ E+SO=z=4նx\ѰF\O}%]Vqq1Z>FYK.gA/c߱>y\~ַ9/ulcz׾V#3{V}=s,m)@81"O:;g\pAǶ?Obuy䑍Eڦn:Z7Eo혢Ӛ=:^xb^$J{5:|*# ,c=Q] 4_LK)qE («:Csw󶷽m`>88F٦ckVǾw[WGJ1/nbytl+#w}w>mQ(#F|́}bX1ŶH~?O;{{я~beܱ=W g5hQp qJlULSr[/#'tR㊻aٍUledL%y3xJ+4px>awe]>^΍E:±\}~|;cg>rkln#HE Ol*V,Ƣ,7s̎cT)S_h?w~ܺv7woxGZ sJ{J;qlaCӔǺ};_qX=7p"#)])@8MEXȽ(#EV}[W]u~pE[J+ ŢsT⪭zjUV86{Ǣx;4W {H&QodM)@>sX`#FUGvmM_}y~g}q?_|fX ]Ģ 1"Hu~ 1=w]wm-K-K @P.Wsz?輳fSjۢj6O&M8_L~3gN{ z8gLp K.7~v h "/Vg=í{[7|e-/袎 H{5w^ǹ->E 1bjnVtڢ裏nrZV4BkeOӃ;[+X7h~quZyꫯ.󟷦>)natd{vYfntx8iFUzꩃ+ћQBFٴ(@w}r-7묳Π}o!1p9Fם}]W%wܱ52o(M`H[.=ЎVXay =\>{oa| ,})@Ql,b'\]1oۃ9#Ҫga뮻Yy1vƌƊ1*.Vƭk<]c5Z TŴ=3}b?ov=W,L ?C(g HTMLDOC Users Manual

Chapter 1 - Introduction

This document describes how to use the HTMLDOC software. HTMLDOC reads HTML and Markdown source files or web pages and generates corresponding EPUB, HTML, PostScript, or PDF files with an optional table of contents. HTMLDOC can be used as a standalone application, in a batch document processing environment, or as a web-based report generation application.

HTMLDOC is open source software under the terms of version 2 of the GNU General Public License. No restrictions are placed upon the output produced by HTMLDOC.

History

Like many programs, I developed HTMLDOC in response to a need my company had for generating high-quality documentation in printed and electronic forms. For a while I used FrameMaker® and a package from sgi that generated "compiled" Standard Generalized Markup Language ("SGML") files that could be used by the Electronic Book Technologies ("EBT") documentation products; EBT was bought by INSO who was bought by StellentTM who apparently has dropped the whole product line. When sgi stopped supporting these tools I turned to INSO, but the cost of their tools was prohibitive to my small business.

In the end I decided to write my own program to generate the documentation. HTML seemed to be the source format of choice since WYSIWYG HTML editors are widely (and freely) available and at worst you can use a plain text editor. I needed HTML output for documentation on my web server, PDF for customers to read and/or print from their computers, and PostScript for printing needs.

The result of my efforts is the HTMLDOC software which runs on Linux®, macOS®, Microsoft® Windows®, and most UNIX® operating systems. Among other things, this software users manual is produced using HTMLDOC.

HTMLDOC used to be available under a commercial end-user license agreement from my former company, Easy Software Products. While that company is no longer in business, I continue to maintain HTMLDOC in my spare time.

Organization of This Manual

This manual is organized into tutorial and reference chapters and appendices:

Encryption Support

HTMLDOC includes code to encrypt PDF document files using the RC4 algorithm with up to a 128-bit key. While this software and code may be freely used and exported under current US laws, other countries may restrict your use and possession of this code and software.

Legal Stuff

HTMLDOC is copyright © 1997-2024 by Michael R Sweet. See Appendix A - License Agreement for the terms of use. This software is based in part on the work of the Independent JPEG Group and FLTK project.

htmldoc-1.9.20/doc/2-using.html000066400000000000000000000514521472561501400161700ustar00rootroot00000000000000

Chapter 2 - Using HTMLDOC

This chapter describes the basics of how to use HTMLDOC to convert HTML and Markdown files into PostScript and PDF files.

Note: HTMLDOC currently does not support HTML 4.0 features such as stylesheets or the STYLE element. For more information, please consult Chapter 4 - HTML Reference.

Using the HTMLDOC GUI

After opening the HTMLDOC application, the HTMLDOC window will appear with the Input tab selected. Click on the Web Page radio button to specify that you will be converting a web page file. Then choose a file for conversion by clicking on the Add Files... button.

Now that you've chosen a file to be converted, click on the Output tab to set the output file and format. Finally, click on the Generate button at the bottom of the HTMLDOC window to convert the HTML file.

Generating Books

While HTMLDOC can convert web pages into PostScript and PDF files, its real strength is generating EPUB, indexed HTML, PostScript, or PDF books. HTMLDOC uses heading elements to delineate chapters and headings in a book. The H1 element is used for chapters:

<HTML>
<HEAD>
    <TITLE>The Little Computer that Could</TITLE>
</HEAD>
<BODY>
<H1>Chapter 1 - The Little Computer is Born</H1>
...
<H1>Chapter 2 - Little Computer's First Task</H1>
...
</BODY>
</HTML>

Sub-headings are marked using the H2 through H6 elements.

Note: When using book mode, HTMLDOC starts rendering with the first H1 element. Any text, images, tables, and other viewable elements that precede the first H1 element are silently ignored. Because of this, make sure you have an H1 element in your HTML file, otherwise HTMLDOC will not convert anything.

Start by clicking on the Book radio button to specify you'll be converting one or more files into a book. Then add one or more HTML or Markdown files by clicking on the Add Files... button.

HTMLDOC will automatically create a title page for you unless you specify a Title File/Image. When the title file is HTML or Markdown, the contents are formatted to produce title page(s). When the title file is an image, the image is centered on the title page with automatically generate content based on the title and other metadata.

After providing all of the input files, click on the Output tab to select the output format and file. Finally, click on the Generate button to generate the book.

Using the HTMLDOC Command

To convert a single web page type:

htmldoc --webpage -f output.pdf filename.html ENTER

htmldoc is the name of the software.

The --webpage option specifies unstructured files with page breaks between each file.

The -f option specifies the output file name (output.pdf). In this example it is a PDF file.

Filename.html is the name of the file that you want to be converted.

To convert more than one web page with page breaks between each file, list each of the files on the end:

htmldoc --webpage -f output.pdf file1.html file2.html ENTER

We've been using HTML files, but you can also use URLs. For example:

htmldoc --webpage -f output.pdf http://slashdot.org/ ENTER

Generating Books

Type one of the following commands to generate a book from one or more files:

htmldoc --book -f output.html file1.html file2.html ENTER
htmldoc --book -f output.pdf file1.html file2.html ENTER
htmldoc --book -f output.ps file1.html file2.html ENTER

The --book option specifies that the input files are structured with headings.

The -f option specifies the output filename.

File1.html and file2.html are the files you want to convert.

HTMLDOC will build a table of contents for the book using the heading elements (H1, H2, etc.) in your input files. It will also add a title page using the document TITLE text and other META information you supply in your files. See Chapter 4 - HTML Reference for more information on the META variables that are supported.

Note: When using book mode, HTMLDOC starts rendering with the first H1 element. Any text, images, tables, and other viewable elements that precede the first H1 element are silently ignored. Because of this, make sure you have an H1 element in your HTML file, otherwise HTMLDOC will not convert anything.

Setting the Title File

The --titlefile option sets the HTML, Markdown, or image file to use on the title page:

htmldoc --titlefile filename.bmp ... ENTER
htmldoc --titlefile filename.gif ... ENTER
htmldoc --titlefile filename.jpg ... ENTER
htmldoc --titlefile filename.png ... ENTER
htmldoc --titlefile filename.html ... ENTER

HTMLDOC supports GIF, JPEG, and PNG images, as well as generic HTML or Markdown text you supply for the title page(s).

Using HTMLDOC on a Web Server

HTMLDOC can be used in a variety of ways to generate formatted reports on a web server. The most common way is to use HTMLDOC as a CGI program with your web server to provide PDF-formatted output of a web page. Examples are provided for Microsoft IIS and the Apache web servers.

HTMLDOC can also be called from your own server-side scripts and programs. Examples are provided for PHP and Java.

Warning: Passing information directly from the web browser to HTMLDOC can potentially expose your system to security risks. Always be sure to "sanitize" any input from the web browser so that filenames, URLs, and options passed to HTMLDOC are not acted on by the shell program or other processes. Filenames with spaces must usually be enclosed with quotes.

CGI Mode

HTMLDOC supports operation as a CGI program. You can copy or symlink the htmldoc (all but Windows) or htmldoc.exe (Windows) executable to your web server's cgi-bin directory and then use it to produce PDF versions of your web pages.

The CGI converts a page on your local server to PDF and sends it to the client's web browser. For example, to convert a page called superproducts.html at the following URL:

http://servername/superproducts.html

and if you installed HTMLDOC in your server's cgi-bin directory, you would direct your clients to the following URL:

http://servername/cgi-bin/htmldoc/superproducts.html

The boldface portion represents the location of the HTMLDOC executable on the web server. You simply place that path before the page you want to convert.

Form data using the GET method can be passed at the end of the URL, for example:

http://servername/cgi-bin/htmldoc/superproducts.html?name=value

Server-Side Preferences

When run as a CGI program, HTMLDOC will try to read a book file to set any preferences for the conversion to PDF. For the superproducts.html file described previously, HTMLDOC will look at the following URLs for a book file:

http://servername/superproducts.html.book
http://servername/.book
http://servername/cgi-bin/.book

The first book file that is found will be used.

Configuring HTMLDOC with Apache

The Apache web server is easily configured to use HTMLDOC. The simplest way is to copy or symlink the htmldoc executable to the configured cgi-bin directory. For example, if your Apache installation is configured to look for CGI programs in the /var/www/cgi-bin directory, the default for Apache on Red Hat Linux, then the command to install HTMLDOC on your web server would be:

ln -s /usr/bin/htmldoc /var/www/cgi-bin ENTER

If you are using Apache 2.0.30 or higher, you will also need to enable PATH_INFO support by adding the following line to your httpd.conf file:

AcceptPathInfo On

Apache also allows you to associate CGI programs with a specific extension. If you add the following line to your httpd.conf file:

AddHandler cgi-script .cgi

and enable CGI execution with the Options directive for a directory:

Options +ExecCGI

then you can copy or symlink the htmldoc executable to an alternate location. For example, if you have a web directory called /var/www/htdocs/products, you can install HTMLDOC in this directory with the following command:

ln -s /usr/bin/htmldoc /var/www/htdocs/products/htmldoc.cgi ENTER

Configuring HTMLDOC with Microsoft IIS

The IIS web server is configured to run CGI programs by either modifying the permissions of an existing directory or by creating a new virtual directory that allows for execution of programs. Start by running the Internet Services Manager program:

  1. Click on Start
  2. Click on Settings
  3. Click on Control Panel
  4. Double-click on Administrative Tools
  5. Double-click on Internet Services Manager

After the Internet Services Manager window appears, perform the following steps to add a virtual folder for HTMLDOC:

  1. Click on your server in the list to show the default web site service in the list
  2. Choose New->Virtual Directory from the Action menu
  3. Click Next when the Virtual Directory Creation Wizard window appears
  4. Enter the name htmldoc in the Alias field and click Next
  5. Enter the HTMLDOC program folder in the Directory field and click Next
  6. Check the Execute (such as ISAPI applications or CGI) box and click Next
  7. Click Finish to dismiss the wizard
  8. Click on Web Service Extensions
  9. Click Add a new Web Service Extension
  10. Enter the name "HTMLDOC" when the Web Service Extension window appears
  11. Click Add... and choose the htmldoc.exe file from the program folder, typically C:\Program Files\msweet.org\HTMLDOC
  12. Check the Set extension status to Allowed box
  13. Click OK to add the extension and dismiss the window

Finally, double-click the My Computer icon on the desktop or start the Windows Explorer. When the explorer window appears, perform the following steps to provide write access to the Windows temporary folder:

  1. Open the windows temporary file folder, typically C:\WINDOWS\TEMP
  2. Choose Properties from the File menu
  3. Click on the Security tab
  4. Click Add..., enter the username for the web server, typically "SERVER\IUSR_SERVER" where "SERVER" is the name you gave your server, and click OK
  5. Click on the username you just added in the list
  6. Check the Read and Write permissions
  7. Click OK to save the changes

Once configured, the htmldoc.exe program will be available in the web server directory. For example, for a virtual directory called cgi-bin, the PDF converted URL for the superproducts.html page would be as follows:

http://servername/cgi-bin/htmldoc.exe/superproducts.html

The boldface portion represents the location of the HTMLDOC program on the web server.

Using HTMLDOC From Server-Side Scripts and Programs

To make this work the CGI script or program must send the appropriate HTTP attributes, the required empty line to signify the beginning of the document, and then execute the HTMLDOC program to generate the HTML, PostScript, or PDF file as needed. Since HTMLDOC looks for CGI environment variables when it is run, you must also set the HTMLDOC_NOCGI environment variable to a value of 1 before running HTMLDOC from your CGI script or program.

Another way to generate PDF files from your reports is to use HTMLDOC as a "portal" application. When used as a portal, HTMLDOC automatically retrieves the named document or report from your server and passes a PDF version to the web browser. See the next sections for more information.

Calling HTMLDOC from a Shell Script

Shell scripts are probably the easiest to work with, but are normally limited to GET type requests. Here is a script called topdf that acts as a portal, converting the named file to PDF:

#!/bin/sh
#
# Sample "portal" script to convert the named HTML file to PDF on-the-fly.
#
# Usage: http://www.example.com/path/topdf/path/filename.html
#

#
# Tell HTMLDOC not to run in CGI mode...
#

HTMLDOC_NOCGI=1; export HTMLDOC_NOCGI

#
# The "options" variable contains any options you want to pass to HTMLDOC.
#

options='-t pdf --webpage --header ... --footer ..."

#
# Tell the browser to expect a PDF file...
#

echo "Content-Type: application/pdf"
echo ""

#
# Run HTMLDOC to generate the PDF file...
#

htmldoc $options http://${SERVER_NAME}:${SERVER_PORT}$PATH_INFO

Users of this CGI would reference the URL "http://www.example.com/topdf.cgi/index.html" to generate a PDF file of the site's home page.

The options variable in the script can be set to use any supported command-line option for HTMLDOC; for a complete list see Chapter 3 - Command-Line Reference.

Calling HTMLDOC from Perl

Perl scripts offer the ability to generate more complex reports, pull data from databases, etc. The easiest way to interface Perl scripts with HTMLDOC is to write a report to a temporary file and then execute HTMLDOC to generate the PDF file.

Here is a simple Perl subroutine that can be used to write a PDF report to the HTTP client:

sub topdf {
    # Get the filename argument...
    my $filename = shift;

    # Make stdout unbuffered...
    select(STDOUT); $| = 1;

    # Tell HTMLDOC not to run in CGI mode...
    $ENV{HTMLDOC_NOCGI} = 1;

    # Write the content type to the client...
    print "Content-Type: application/pdf\n\n";

    # Run HTMLDOC to provide the PDF file to the user...
    system "htmldoc -t pdf --quiet --webpage $filename";
}

Calling HTMLDOC from PHP

PHP provides a passthru() function that can be used to run HTMLDOC. This combined with the header() function can be used to provide on-the-fly reports in PDF format.

Here is a simple PHP function that can be used to convert a HTML report to PDF and send it to the HTTP client:

function topdf($filename, $options = "") {
    # Tell HTMLDOC not to run in CGI mode...
    putenv("HTMLDOC_NOCGI=1");

    # Write the content type to the client...
    header("Content-Type: application/pdf");
    flush();

    # Run HTMLDOC to provide the PDF file to the user...
    passthru("htmldoc -t pdf --quiet --jpeg --webpage $options " . escapeshellarg($filename));
}

The function accepts a filename and an optional "options" string for specifying the header, footer, fonts, etc.

To make a "portal" script, add the following code to complete the example:

global $SERVER_NAME;
global $SERVER_PORT;
global $PATH_INFO;
global $QUERY_STRING;

if ($QUERY_STRING != "") {
    $url = "http://${SERVER_NAME}:${SERVER_PORT}${PATH_INFO}?${QUERY_STRING}";
} else {
    $url = "http://${SERVER_NAME}:${SERVER_PORT}$PATH_INFO";
}

topdf($url);

Calling HTMLDOC from C

C programs offer the best flexibility and easily supports on-the-fly report generation without the need for temporary files.

Here are some simple C functions that can be used to generate a PDF report to the HTTP client from a temporary file or pipe:

#include <stdio.h>
#include <stdlib.h>


/* topdf() - convert a HTML file to PDF */
FILE *topdf(const char *filename)       /* I - HTML file to convert */
{
  char	command[1024];			/* Command to execute */


 /*
  * Tell HTMLDOC not to run in CGI mode...
  */

  putenv("HTMLDOC_NOCGI=1");

 /*
  * Write the content type to the client...
  */

  puts("Content-Type: application/pdf\n");

 /*
  * Run HTMLDOC to provide the PDF file to the user...
  */

  sprintf(command, "htmldoc --quiet -t pdf --webpage %s", filename);

  return (popen(command, "w"));
}


/* topdf2() - pipe HTML output to HTMLDOC for conversion to PDF */
FILE *topdf2(void)
{
 /*
  * Tell HTMLDOC not to run in CGI mode...
  */

  putenv("HTMLDOC_NOCGI=1");

 /*
  * Write the content type to the client...
  */

  puts("Content-Type: application/pdf\n");

 /*
  * Open a pipe to HTMLDOC...
  */

  return (popen("htmldoc --quiet -t pdf --webpage -", "w"));
}

Calling HTMLDOC from Java

Java programs are a portable way to add PDF support to your web server. Here is a class called htmldoc that acts as a portal, converting the named file to PDF. It can also be called by your Java servlets to process an HTML file and send the result to the client in PDF format:

class htmldoc
{
  // Convert named file to PDF on stdout...
  public static int topdf(String filename)// I - Name of file to convert
  {
    String              command;          // Command string
    Process             process;          // Process for HTMLDOC
    Runtime             runtime;          // Local runtime object
    java.io.InputStream input;            // Output from HTMLDOC
    byte                buffer [];        // Buffer for output data
    int                 bytes;            // Number of bytes


    // First tell the client that we will be sending PDF...
    System.out.print("Content-type: application/pdf\n\n");

    // Construct the command string
    command = "htmldoc --quiet --jpeg --webpage -t pdf --left 36 " +
              "--header .t. --footer .1. " + filename;

    // Run the process and wait for it to complete...
    runtime = Runtime.getRuntime();

    try
    {
      // Create a new HTMLDOC process...
      process = runtime.exec(command);

      // Get stdout from the process and a buffer for the data...
      input  = process.getInputStream();
      buffer = new byte[8192];

      // Read output from HTMLDOC until we have it all...
      while ((bytes = input.read(buffer)) > 0)
        System.out.write(buffer, 0, bytes);

      // Return the exit status from HTMLDOC...
      return (process.waitFor());
    }
    catch (Exception e)
    {
      // An error occurred - send it to stderr for the web server...
      System.err.print(e.toString() + " caught while running:\n\n");
      System.err.print("    " + command + "\n");
      return (1);
    }
  }

  // Main entry for htmldoc class
  public static void main(String[] args)// I - Command-line args
  {
    String server_name,                 // SERVER_NAME env var
           server_port,                 // SERVER_PORT env var
           path_info,                   // PATH_INFO env var
           query_string,                // QUERY_STRING env var
           filename;                    // File to convert


    if ((server_name = System.getProperty("SERVER_NAME")) != null &&
        (server_port = System.getProperty("SERVER_PORT")) != null &&
        (path_info = System.getProperty("PATH_INFO")) != null)
    {
      // Construct a URL for the resource specified...
      filename = "http://" + server_name + ":" + server_port + path_info;

      if ((query_string = System.getProperty("QUERY_STRING")) != null)
      {
        filename = filename + "?" + query_string;
      }
    }
    else if (args.length == 1)
    {
      // Pull the filename from the command-line...
      filename = args[0];
    }
    else
    {
      // Error - no args or env variables!
      System.err.print("Usage: htmldoc.class filename\n");
      return;
    }

    // Convert the file to PDF and send to the web client...
    topdf(filename);
  }
}
htmldoc-1.9.20/doc/3-cmdref.html000066400000000000000000001124011472561501400162740ustar00rootroot00000000000000

Chapter 3 - Command-Line Reference

This chapter describes all of the command-line options supported by HTMLDOC.

Basic Usage

The basic command-line usage for HTMLDOC is:

% htmldoc options filename1.html ... filenameN.md ENTER
% htmldoc options filename.book ENTER

The first form converts the named HTML or Markdown files to the specified output format immediately. The second form loads the specified .book file and displays the HTMLDOC window, allowing a user to make changes and/or generate the document interactively.

If no output file or directory is specified, then all output is sent to the standard output file.

On return, HTMLDOC returns an exit code of 0 if it was successful and non-zero if there were errors.

Options

The following command-line options are recognized by HTMLDOC.

-d directory

The -d option specifies an output directory for the document files.

This option is not compatible with the EPUB or PDF output formats.

-f filename

The -f option specifies an output file for the document.

-t format

The -t option specifies the output format for the document and can be one of the following:

FormatDescription
epubGenerate an EPUB file.
htmlGenerate one or more indexed HTML files.
htmlsepGenerate separate HTML files for each heading in the table-of-contents.
pdfGenerate a PDF file (default version - 1.4).
pdf11Generate a PDF 1.1 file for Acrobat Reader 2.0 and later.
pdf12Generate a PDF 1.2 file for Acrobat Reader 3.0 and later.
pdf13Generate a PDF 1.3 file for Acrobat Reader 4.0 and later.
pdf14Generate a PDF 1.4 file for Acrobat Reader 5.0 and later.
psGenerate one or more PostScript files (default level - 2).
ps1Generate one or more Level 1 PostScript files.
ps2Generate one or more Level 2 PostScript files.
ps3Generate one or more Level 3 PostScript files.

-v

The -v option specifies that progress information should be sent/displayed to the standard error file.

--batch filename.book

The --batch option specifies a book file that you would like to generate without the GUI popping up. This option can be combined with other options to generate the same book in different formats and sizes:

% htmldoc --batch filename.book -f filename.ps ENTER
% htmldoc --batch filename.book -f filename.pdf ENTER

--bodycolor color

The --bodycolor option specifies the background color for all pages in the document. The color can be specified by a standard HTML color name or as a 6-digit hexadecimal number of the form #RRGGBB.

--bodyfont typeface

The --bodyfont option specifies the default text font used for text in the document body. The typeface parameter can be one of the following:

typefaceActual Font
ArialHelvetica
CourierCourier
HelveticaHelvetica
MonospaceDejaVu Sans Mono
SansDevaVu Sans
SerifDejaVu Serif
TimesTimes

--bodyimage filename

The --bodyimage option specifies the background image for all pages in the document. The supported formats are GIF, JPEG, and PNG.

--book

The --book option specifies that the input files comprise a book with chapters and headings.

--bottom margin

The --bottom option specifies the bottom margin. The default units are points (1 point = 1/72nd inch); the suffixes "in", "cm", and "mm" specify inches, centimeters, and millimeters, respectively.

This option is only available when generating PostScript or PDF files.

--browserwidth pixels

The --browserwidth option specifies the browser width in pixels. The browser width is used to scale images and pixel measurements when generating PostScript and PDF files. It does not affect the font size of text.

The default browser width is 680 pixels which corresponds roughly to a 96 DPI display. Please note that your images and table sizes are equal to or smaller than the browser width, or your output will overlap or truncate in places.

--charset charset

The --charset option specifies the 8-bit character set encoding to use for the entire document. HTMLDOC comes with the following character set files:

charsetCharacter Set
cp-874Windows code page 874
cp-1250Windows code page 1250
cp-1251Windows code page 1251
cp-1252Windows code page 1252
cp-1253Windows code page 1253
cp-1254Windows code page 1254
cp-1255Windows code page 1255
cp-1256Windows code page 1256
cp-1257Windows code page 1257
cp-1258Windows code page 1258
iso-8859-1ISO-8859-1
iso-8859-2ISO-8859-2
iso-8859-3ISO-8859-3
iso-8859-4ISO-8859-4
iso-8859-5ISO-8859-5
iso-8859-6ISO-8859-6
iso-8859-7ISO-8859-7
iso-8859-8ISO-8859-8
iso-8859-9ISO-8859-9
iso-8859-14ISO-8859-14
iso-8859-15ISO-8859-15
koi8-rKOI8-R
utf-8UTF-8
Note: UTF-8 support is limited to the first 128 Unicode characters found in the input.

--color

The --color option specifies that color output is desired.

This option is only available when generating PostScript or PDF files.

--compression[=level]

The --compression option specifies that Flate compression should be performed on the output file(s). The optional level parameter is a number from 1 (fastest and least amount of compression) to 9 (slowest and most amount of compression).

This option is only available when generating PDF or Level 3 PostScript files.

--continuous

The --continuous option specifies that the input files comprise a web page (or site) and that no title page or table-of-contents should be generated. Unlike the --webpage option described later in this chapter, page breaks are not inserted between each input file.

This option is only available when generating PostScript or PDF files.

--cookies 'name=\"value with space\"; name=value'

The --cookies option specifies one or more HTTP cookies that should be sent when converting remote URLs. Each cookie must be separated from the others by a semicolon and a space, and values containing whitespace or the semicolon must be placed inside double-quotes. When specifying multiple cookies, the entire cookie string must be surrounded by single quotes in order for the string to be processed correctly.

--datadir directory

The --datadir option specifies the location of data files used by HTMLDOC.

--duplex

The --duplex option specifies that the output should be formatted for two sided printing.

This option is only available when generating PostScript or PDF files. Use the --pscommands option to generate PostScript duplex mode commands.

--effectduration seconds

The --effectduration option specifies the duration of a page transition effect in seconds.

This option is only available when generating PDF files.

--embedfonts

The --embedfonts option specifies that fonts should be embedded in PostScript and PDF output. This is especially useful when generating documents in character sets other than ISO-8859-1.

--encryption

The --encryption option enables encryption and security features for PDF output.

This option is only available when generating PDF files.

--firstpage page

The --firstpage option specifies the first page that will be displayed in a PDF file. The page parameter can be one of the following:

pageDescription
p1The first page of the document.
tocThe first page of the table-of-contents.
c1The first page of chapter 1.

This option is only available when generating PDF files.

--fontsize size

The --fontsize option specifies the base font size for the entire document in points (1 point = 1/72nd inch).

--fontspacing spacing

The --fontspacing option specifies the line spacing for the entire document as a multiplier of the base font size. A spacing value of 1 makes each line of text the same height as the font.

--footer lcr

The --footer option specifies the contents of the page footer. The lcr parameter is a three-character string representing the left, center, and right footer fields. Each character can be one of the following:

lcrDescription
.A period indicates that the field should be blank.
:A colon indicates that the field should contain the current and total number of pages in the chapter (n/N).
/A slash indicates that the field should contain the current and total number of pages (n/N).
1The number 1 indicates that the field should contain the current page number in decimal format (1, 2, 3, ...)
aA lowercase "a" indicates that the field should contain the current page number using lowercase letters.
AAn uppercase "A" indicates that the field should contain the current page number using UPPERCASE letters.
cA lowercase "c" indicates that the field should contain the current chapter title.
CAn uppercase "C" indicates that the field should contain the current chapter page number.
dA lowercase "d" indicates that the field should contain the current date.
DAn uppercase "D" indicates that the field should contain the current date and time.
hAn "h" indicates that the field should contain the current heading.
iA lowercase "i" indicates that the field should contain the current page number in lowercase roman numerals (i, ii, iii, ...)
IAn uppercase "I" indicates that the field should contain the current page number in uppercase roman numerals (I, II, III, ...)
lA lowercase "l" indicates that the field should contain the logo image.
lAn uppercase "L" indicates that the field should contain the logo image as a letterhead (shown at full size).
tA lowercase "t" indicates that the field should contain the document title.
TAn uppercase "T" indicates that the field should contain the current time.
uA lowercase "u" indicates that the field should contain the current filename or URL.

Setting the footer to "..." disables the footer entirely.

--format format

The --format option specifies the output format for the document and can be one of the following:

FormatDescription
epubGenerate an EPUB file.
htmlGenerate one or more indexed HTML files.
htmlsepGenerate separate HTML files for each heading in the table-of-contents.
pdfGenerate a PDF file (default version - 1.4).
pdf11Generate a PDF 1.1 file for Acrobat Reader 2.0 and later.
pdf12Generate a PDF 1.2 file for Acrobat Reader 3.0 and later.
pdf13Generate a PDF 1.3 file for Acrobat Reader 4.0 and later.
pdf14Generate a PDF 1.4 file for Acrobat Reader 5.0 and later.
psGenerate one or more PostScript files (default level - 2).
ps1Generate one or more Level 1 PostScript files.
ps2Generate one or more Level 2 PostScript files.
ps3Generate one or more Level 3 PostScript files.

--gray

The --gray option specifies that grayscale output is desired.

This option is only available when generating PostScript or PDF files.

--header lcr

The --header option specifies the contents of the page header. The lcr parameter is a three-character string representing the left, center, and right header fields. See the --footer option for the list of formatting characters.

Setting the header to "..." disables the header entirely.

--header1 lcr

The --header1 option specifies the contents of the page header for the first body/chapter page. The lcr parameter is a three-character string representing the left, center, and right header fields. See the --footer option for the list of formatting characters.

Setting the header to "..." disables the first page header entirely.

--headfootfont font

The --headfootfont option specifies the font that is used for the header and footer text. The font parameter can be one of the following:

  • Courier
  • Courier-Bold
  • Courier-Oblique
  • Courier-BoldOblique
  • Helvetica
  • Helvetica-Bold
  • Helvetica-Oblique
  • Helvetica-BoldOblique
  • Monospace
  • Monospace-Bold
  • Monospace-Oblique
  • Monospace-BoldOblique
  • Sans
  • Sans-Bold
  • Sans-Oblique
  • Sans-BoldOblique
  • Serif
  • Serif-Roman
  • Serif-Bold
  • Serif-Italic
  • Serif-BoldItalic
  • Times
  • Times-Roman
  • Times-Bold
  • Times-Italic
  • Times-BoldItalic

This option is only available when generating PostScript or PDF files.

--headfootsize size

The --headfootsize option sets the size of the header and footer text in points (1 point = 1/72nd inch).

This option is only available when generating PostScript or PDF files.

--headingfont typeface

The --headingfont options sets the typeface that is used for headings in the document. The typeface parameter can be one of the following:

typefaceActual Font
ArialHelvetica
CourierCourier
HelveticaHelvetica
MonospaceDejaVu Sans Mono
SansDevaVu Sans
SerifDejaVu Serif
TimesTimes

--help

The --help option displays all of the available options to the standard output file.

--helpdir directory

The --helpdir option specifies the location of the on-line help files.

--hfimageN filename

The --hfimageN option specifies an image to use in the header and/or footer, where N is a number from 1 to 10. The supported formats are GIF, JPEG, and PNG.

--jpeg[=quality]

The --jpeg option enables JPEG compression of continuous-tone images. The optional quality parameter specifies the output quality from 0 (worst) to 100 (best).

This option is only available when generating PDF or Level 2 and Level 3 PostScript files.

--landscape

The --landscape option specifies that the output should be in landscape orientation (long edge on top).

This option is only available when generating PostScript or PDF files.

--left margin

The --left option specifies the left margin. The default units are points (1 point = 1/72nd inch); the suffixes "in", "cm", and "mm" specify inches, centimeters, and millimeters, respectively.

This option is only available when generating PostScript or PDF files.

--letterhead filename

The --letterhead option specifies the letterhead image for the page headers and footers for PostScript and PDF files. The supported formats are GIF, JPEG, and PNG.

Note: You need to use the --header and/or --footer options with the L parameter or use the corresponding HTML page comments to display the logo image in the header or footer.

--linkcolor color

The --linkcolor option specifies the color of links in EPUB, HTML. and PDF output. The color can be specified by name or as a 6-digit hexadecimal number of the form #RRGGBB.

--links

The --links option specifies that PDF output should contain hyperlinks.

--linkstyle style

The --linkstyle option specifies the style of links in EPUB, HTML, and PDF output. The style can be "plain" for no decoration or "underline" to underline links.

--logoimage filename

The --logoimage option specifies the logo image for the HTML navigation bar and page headers and footers for PostScript and PDF files. The supported formats are GIF, JPEG, and PNG.

Note: You need to use the --header and/or --footer options with the l parameter or use the corresponding HTML page comments to display the logo image in the header or footer.

--no-compression

The --no-compression option specifies that Flate compression should not be performed on the output files.

--no-duplex

The --no-duplex option specifies that the output should be formatted for one sided printing.

This option is only available when generating PostScript or PDF files. Use the --pscommands option to generate PostScript duplex mode commands.

--no-embedfonts

The --no-embedfonts option specifies that fonts should not be embedded in PostScript and PDF output.

--no-encryption

The --no-encryption option specifies that no encryption/security features should be enabled in PDF output.

This option is only available when generating PDF files.

--no-jpeg

The --no-jpeg option specifies that JPEG compression should not be performed on large images.

--no-links

The --no-links option specifies that PDF output should not contain hyperlinks.

--no-localfiles

The --no-localfiles option disables access to local files on the system. This option should be used when providing remote document conversion services.

--no-numbered

The --no-numbered option specifies that headings should not be numbered.

--no-pscommands

The --no-pscommands option specifies that PostScript device commands should not be written to the output files.

--no-strict

The --no-strict option turns off strict HTML conformance checking.

--no-title

The --no-title option specifies that the title page should not be generated.

--no-toc

The --no-toc option specifies that the table-of-contents pages should not be generated.

--no-xrxcomments

The --no-xrxcomments option specifies that Xerox PostScript job comments should not be written to the output files.

This option is only available when generating PostScript files.

--numbered

The --numbered option specifies that headings should be numbered.

--nup pages

The --nup option sets the number of pages that are placed on each output page. Valid values for the pages parameter are 1, 2, 4, 6, 9, and 16.

--outdir directory

The --outdir option specifies an output directory for the document files.

This option is not compatible with the PDF output format.

--outfile filename

The --outfile option specifies an output file for the document.

--owner-password password

The --owner-password option specifies the owner password for a PDF file. If not specified or the empty string (""), a random password is generated.

This option is only available when generating PDF files.

--pageduration seconds

The --pageduration option specifies the number of seconds that each page will be displayed in the document.

This option is only available when generating PDF files.

--pageeffect effect

The --pageeffect option specifies the page effect to use in PDF files. The effect parameter can be one of the following:

effectDescription
noneNo effect is generated.
biBox Inward
boBox Outward
dDissolve
gdGlitter Down
gdrGlitter Down and Right
grGlitter Right
hbHorizontal Blinds
hsiHorizontal Sweet Inward
hsoHorizontal Sweep Outward
vbVertical Blinds
vsiVertical Sweep Inward
vsoVertical Sweep Outward
wdWipe Down
wlWipe Left
wrWipe Right
wuWipe Up

This option is only available when generating PDF files.

--pagelayout layout

The --pagelayout option specifies the initial page layout in the PDF viewer. The layout parameter can be one of the following:

layoutDescription
singleA single page is displayed.
oneA single column is displayed.
twoleftTwo columns are displayed with the first page on the left.
tworightTwo columns are displayed with the first page on the right.

This option is only available when generating PDF files.

--pagemode mode

The --pagemode option specifies the initial viewing mode in the PDF viewer. The mode parameter can be one of the following:

modeDescription
documentThe document pages are displayed in a normal window.
outlineThe document outline and pages are displayed.
fullscreenThe document pages are displayed on the entire screen in "slideshow" mode.

This option is only available when generating PDF files.

--path dir1;dir2;dir3;...;dirN

The --path option specifies a search path for files that are loaded by HTMLDOC. It is usually used to get images that use absolute server paths to load.

Directories are separated by the semicolon (;) so that drive letters and URLs can be specified. Quotes around the directory parameter are optional. They are usually used when the directory string contains spaces.

--path "dir1;dir2;dir3;...;dirN"

--permissions permission[,permission,...]

The --permissions option specifies the document permissions. The available permission parameters are listed below:

PermissionDescription
allAll permissions
annotateUser can annotate document
copyUser can copy text and images from document
modifyUser can modify document
printUser can print document
no-annotateUser cannot annotate document
no-copyUser cannot copy text and images from document
no-modifyUser cannot modify document
no-printUser cannot print document
noneNo permissions

The --encryption option must be used in conjunction with the --permissions parameter.

--permissions no-print --encryption

Multiple options can be specified by separating them with commas:

--permissions no-print,no-copy --encryption

This option is only available when generating PDF files.

--portrait

The --portrait option specifies that the output should be in portrait orientation (short edge on top).

This option is only available when generating PostScript or PDF files.

--pdf-indent margin

The --pdf-indent option specifies the indentation for pre-formatted content. The default units are points (1 point = 1/72nd inch); the suffixes "in", "cm", and "mm" specify inches, centimeters, and millimeters, respectively.

--pscommands

The --pscommands option specifies that PostScript device commands should be written to the output files.

This option is only available when generating Level 2 and Level 3 PostScript files.

--quiet

The --quiet option prevents error messages from being sent to stderr.

--referer url

The --referer option sets the URL that is passed in the Referer: field of HTTP requests.

--right margin

The --right option specifies the right margin. The default units are points (1 point = 1/72nd inch); the suffixes "in", "cm", and "mm" specify inches, centimeters, and millimeters, respectively.

This option is only available when generating PostScript or PDF files.

--size size

The --size option specifies the page size. The size parameter can be one of the following standard sizes:

sizeDescription
Letter8.5x11in (216x279mm)
A48.27x11.69in (210x297mm)
Universal8.27x11in (210x279mm)

Custom sizes are specified by the page width and length separated by the letter "x" to select a custom page size. Append the letters "in" for inches, "mm" for millimeters, or "cm" for centimeters.

This option is only available when generating PostScript or PDF files. Use the --pscommands option to generate PostScript page size commands.

--strict

The --strict option turns on strict HTML conformance checking. When enabled, HTML elements that are improperly nested and dangling close elements will produce error messages.

--textcolor color

The --textcolor option specifies the default text color for all pages in the document. The color can be specified by a standard HTML color name or as a 6-digit hexadecimal number of the form #RRGGBB.

--textfont typeface

The --textfont options sets the typeface that is used for text in the document. The typeface parameter can be one of the following:

typefaceActual Font
ArialHelvetica
CourierCourier
HelveticaHelvetica
MonospaceDejaVu Sans Mono
SansDevaVu Sans
SerifDejaVu Serif
TimesTimes

--title

The --title option specifies that a title page should be generated.

--titlefile filename

The --titlefile option specifies a HTML or Markdown file to use for the title page.

--titleimage filename

The --titleimage option specifies the title image for the title page. The supported formats are GIF, JPEG, and PNG.

--tocfooter lcr

The --tocfooter option specifies the contents of the table-of-contents footer. The lcr parameter is a three-character string representing the left, center, and right footer fields. See the --footer option for the list of formatting characters.

Setting the TOC footer to "..." disables the TOC footer entirely.

--tocheader lcr

The --tocheader option specifies the contents of the table-of-contents header. The lcr parameter is a three-character string representing the left, center, and right header fields. See the --footer option for the list of formatting characters.

Setting the TOC header to "..." disables the TOC header entirely.

--toclevels levels

The --toclevels options specifies the number of heading levels to include in the table-of-contents pages. The levels parameter is a number from 1 to 6.

--toctitle string

The --toctitle options specifies the string to display at the top of the table-of-contents; the default string is "Table of Contents".

--top margin

The --top option specifies the top margin. The default units are points (1 point = 1/72nd inch); the suffixes "in", "cm", and "mm" specify inches, centimeters, and millimeters, respectively.

This option is only available when generating PostScript or PDF files.

--user-password password

The --user-password option specifies the user password for a PDF file. If not specified or the empty string (""), no password will be required to view the document.

This option is only available when generating PDF files.

--verbose

The --verbose option specifies that progress information should be sent/displayed to the standard error file.

--version

The --version option displays the HTMLDOC version number.

--webpage

The --webpage option specifies that the input files comprise a web page (or site) and that no title page or table-of-contents should be generated. HTMLDOC will insert a page break between each input file.

This option is only available when generating PostScript or PDF files.

--xrxcomments

The --xrxcomments option specifies that Xerox PostScript job comments should be written to the output files.

This option is only available when generating PostScript files.

Environment Variables

HTMLDOC looks for several environment variables which can override the default directories, display additional debugging information, and disable CGI mode.

HTMLDOC_DATA

This environment variable specifies the location of HTMLDOC's data and fonts directories, normally /usr/share/htmldoc or C:\Program Files\HTMLDOC.

HTMLDOC_DEBUG

This environment variable enables debugging information that is sent to stderr. The value is a list of keywords separated by spaces:

keywordInformation Shown
linksShows all of the links in a document
memoryShows memory usage statistics
remotebytesShows the number of bytes that were transferred via HTTP
tablePuts a box around each table, row, and cell
tempfilesShows the temporary files that were created, and preserves them for debugging
timingShows the load and render times
allAll of the above

HTMLDOC_HELP

This environment variable specifies the location of HTMLDOC's documentation directory, normally /usr/share/doc/htmldoc or C:\Program Files\HTMLDOC\doc.

HTMLDOC_NOCGI

This environment variable, when set (the value doesn't matter), disables CGI mode. It is most useful for using HTMLDOC on a web server from a scripting language or invocation from a program.

Messages

HTMLDOC sends error and status messages to stderr unless the --quiet option is provided on the command-line. Applications can capture these messages to relay errors or statistics to the user.

BYTES: Message

The BYTES: message specifies the number of bytes that were written to an output file. If the output is directed at a directory then multiple BYTES: messages will be sent.

DEBUG: Messages

The DEBUG: messages contain debugging information based on the value of the HTMLDOC_DEBUG environment variable. Normally, no DEBUG: messages are sent by HTMLDOC.

ERRnnn: Messages

The ERRnnn: messages specify an error condition. Error numbers 1 to 14 map to the following errors:

  1. No files were found or loadable.
  2. No pages were generated.
  3. The document contains too many files or chapters.
  4. HTMLDOC ran out of memory.
  5. The specified file could not be found.
  6. The comment contains a bad HTMLDOC formatting command.
  7. The image file is not in a known format.
  8. HTMLDOC was unable to remove a temporary file.
  9. HTMLDOC had an unspecified internal error.
  10. HTMLDOC encountered a networking error when retrieving a file via a URL.
  11. HTMLDOC was unable to read a file.
  12. HTMLDOC was unable to write a file.
  13. A HTML error was found in a source file.
  14. A table, image, or text fragment was too large to fit in the space provided.
  15. A hyperlink in the source files was unresolved.
  16. A header/footer string in the document contains a bad $ command.

Error numbers 100 to 505 correspond directly to a HTTP status code.

INFO: Messages

The INFO: messages contain general information that is logged when HTMLDOC is running in CGI mode or when you use the --verbose option.

PAGES: Message

The PAGES: message specifies the number of pages that were written to an output file. If the output is directed at a directory then multiple PAGES: messages will be sent. No PAGES: messages are sent when generating HTML or EPUB output.

REMOTEBYTES: Message

The REMOTEBYTES: message specifies the number of bytes that were transferred using HTTP. This message is only displayed if the HTMLDOC_DEBUG environment variable has the keyword remotebytes or all.

TIMING: Message

The TIMING: message specifies the load, render, and total time in seconds for the current command. This message is only displayed if the HTMLDOC_DEBUG environment variable has the keyword timing or all.

htmldoc-1.9.20/doc/4-htmlref.html000066400000000000000000000604661472561501400165130ustar00rootroot00000000000000

Chapter 4 - HTML Reference

This chapter defines all of the HTML elements and attributes that are recognized and supported by HTMLDOC.

General Usage

There are two types of HTML files - structured documents using headings (H1, H2, etc.) which HTMLDOC calls "books", and unstructured documents that do not use headings which HTMLDOC calls "web pages".

A very common mistake is to try converting a web page using:

htmldoc -f filename.pdf filename.html

which will likely produce a PDF file with no pages. To convert web page files you must use the --webpage option at the command-line or choose Web Page in the input tab of the GUI.

Note: HTMLDOC does not support HTML 4.0 elements, attributes, stylesheets, or scripting.

Elements

The following HTML elements are recognized by HTMLDOC:

ElementVersionSupported?Notes
!DOCTYPE3.0YesDTD is ignored
A1.0YesSee Below
ACRONYM2.0YesNo font change
ADDRESS2.0Yes 
AREA2.0No 
B1.0Yes 
BASE2.0No 
BASEFONT1.0No 
BIG2.0Yes 
BLINK2.0No 
BLOCKQUOTE2.0Yes 
BODY1.0Yes 
BR2.0Yes 
CAPTION2.0Yes 
CENTER2.0Yes 
CITE2.0YesItalic/Oblique
CODE2.0YesCourier
DD2.0Yes 
DEL2.0YesStrikethrough
DFN2.0YesHelvetica
DIR2.0Yes 
DIV3.2Yes 
DL2.0Yes 
DT2.0YesItalic/Oblique
EM2.0YesItalic/Oblique
EMBED2.0YesHTML Only
FONT2.0YesSee Below
FORM2.0No 
FRAME3.2No 
FRAMESET3.2No 
H11.0YesBoldface, See Below
H21.0YesBoldface, See Below
H31.0YesBoldface, See Below
H41.0YesBoldface, See Below
H51.0YesBoldface, See Below
H61.0YesBoldface, See Below
HEAD1.0Yes 
HR1.0Yes 
HTML1.0Yes 
I1.0Yes 
IMG1.0YesSee Below
INPUT2.0No 
INS2.0YesUnderline
ISINDEX2.0No 
KBD2.0YesCourier Bold
LI2.0Yes 
LINK2.0No 
MAP2.0No 
MENU2.0Yes 
META2.0YesSee Below
MULTICOLN3.0No 
NOBR1.0No 
NOFRAMES3.2No 
OL2.0Yes 
OPTION2.0No 
P1.0Yes 
PRE1.0Yes 
S2.0YesStrikethrough
SAMP2.0YesCourier
SCRIPT2.0No 
SELECT2.0No 
SMALL2.0Yes 
SPACERN3.0Yes 
STRIKE2.0Yes 
STRONG2.0YesBoldface Italic/Oblique
SUB2.0YesReduced Fontsize
SUP2.0YesReduced Fontsize
TABLE2.0YesSee Below
TD2.0Yes 
TEXTAREA2.0No 
TH2.0YesBoldface Center
TITLE2.0Yes 
TR2.0Yes 
TT2.0YesCourier
U1.0Yes 
UL2.0Yes 
VAR2.0YesHelvetica Oblique
WBR1.0No 

Comments

HTMLDOC supports many special HTML comments to initiate page breaks, set the header and footer text, and control the current media options:

<!-- FOOTER LEFT "foo" -->
Sets the left footer text; the test is applied to the current page if empty, or the next page otherwise.
<!-- FOOTER CENTER "foo" -->
Sets the center footer text; the test is applied to the current page if empty, or the next page otherwise.
<!-- FOOTER RIGHT "foo" -->
Sets the right footer text; the test is applied to the current page if empty, or the next page otherwise.
<!-- HALF PAGE -->
Break to the next half page.
<!-- HEADER LEFT "foo" -->
Sets the left header text; the test is applied to the current page if empty, or the next page otherwise.
<!-- HEADER CENTER "foo" -->
Sets the center header text; the test is applied to the current page if empty, or the next page otherwise.
<!-- HEADER RIGHT "foo" -->
Sets the right header text; the test is applied to the current page if empty, or the next page otherwise.
<!-- MEDIA BOTTOM nnn -->
Sets the bottom margin of the page. The "nnn" string can be any standard measurement value, e.g. 0.5in, 36, 12mm, etc. Breaks to a new page if the current page is already marked.
<!-- MEDIA COLOR "foo" -->
Sets the media color attribute for the page. The "foo" string is any color name that is supported by the printer, e.g. "Blue", "White", etc. Breaks to a new page or sheet if the current page is already marked.
<!-- MEDIA DUPLEX NO -->
Chooses single-sided printing for the page; breaks to a new page or sheet if the current page is already marked.
<!-- MEDIA DUPLEX YES -->
Chooses double-sided printing for the page; breaks to a new sheet if the current page is already marked.
<!-- MEDIA LANDSCAPE NO -->
Chooses portrait orientation for the page; breaks to a new page if the current page is already marked.
<!-- MEDIA LANDSCAPE YES -->
Chooses landscape orientation for the page; breaks to a new page if the current page is already marked.
<!-- MEDIA LEFT nnn -->
Sets the left margin of the page. The "nnn" string can be any standard measurement value, e.g. 0.5in, 36, 12mm, etc. Breaks to a new page if the current page is already marked.
<!-- MEDIA POSITION nnn -->
Sets the media position attribute (input tray) for the page. The "nnn" string is an integer that usually specifies the tray number. Breaks to a new page or sheet if the current page is already marked.
<!-- MEDIA RIGHT nnn -->
Sets the right margin of the page. The "nnn" string can be any standard measurement value, e.g. 0.5in, 36, 12mm, etc. Breaks to a new page if the current page is already marked.
<!-- MEDIA SIZE foo -->
Sets the media size to the specified size. The "foo" string can be "Letter", "Legal", "Universal", or "A4" for standard sizes or "WIDTHxHEIGHTunits" for custom sizes, e.g. "8.5x11in"; breaks to a new page or sheet if the current page is already marked.
<!-- MEDIA TOP nnn -->
Sets the top margin of the page. The "nnn" string can be any standard measurement value, e.g. 0.5in, 36, 12mm, etc. Breaks to a new page if the current page is already marked.
<!-- MEDIA TYPE "foo" -->
Sets the media type attribute for the page. The "foo" string is any type name that is supported by the printer, e.g. "Plain", "Glossy", etc. Breaks to a new page or sheet if the current page is already marked.
<!-- NEED length -->
Break if there is less than length units left on the current page. The length value defaults to lines of text but can be suffixed by in, mm, or cm to convert from the corresponding units.
<!-- NEW PAGE -->
Break to the next page.
<!-- NEW SHEET -->
Break to the next sheet.
<!-- NUMBER-UP nn -->
Sets the number of pages that are placed on each output page. Valid values are 1, 2, 4, 6, 9, and 16.
<!-- PAGE BREAK -->
Break to the next page.

Header/Footer Strings

The HEADER and FOOTER comments allow you to set an arbitrary string of text for the left, center, and right headers and footers. Each string consists of plain text; special values or strings can be inserted using the dollar sign ($):

$$
Inserts a single dollar sign in the header.
$CHAPTER
Inserts the current chapter heading.
$CHAPTERPAGE
$CHAPTERPAGE(format)
Inserts the current page number within a chapter or file. When a format is specified, uses that numeric format (1 = decimal, i = lowercase roman numerals, I = uppercase roman numerals, a = lowercase ascii, A = uppercase ascii) for the page numbers.
$CHAPTERPAGES
$CHAPTERPAGES(format)
Inserts the total page count within a chapter or file. When a format is specified, uses that numeric format (1 = decimal, i = lowercase roman numerals, I = uppercase roman numerals, a = lowercase ascii, A = uppercase ascii) for the page count.
$DATE
$DATE(format)
Inserts the current date. See Date/Time Formats for details on the format string. When no format is supplied, the default date format for the current locale is used.
$HEADING
Inserts the current heading.
$HFIMAGE1
$HFIMAGE2
$HFIMAGE3
$HFIMAGE4
$HFIMAGE5
$HFIMAGE6
$HFIMAGE7
$HFIMAGE8
$HFIMAGE9
$HFIMAGE10
Inserts the specified header/footer image; all other text in the string will be ignored.
$LETTERHEAD
Inserts the logo image as a letterhead with no down-scaling; all other text in the string will be ignored.
$LOGOIMAGE
Inserts the logo image; all other text in the string will be ignored.
$PAGE
$PAGE(format)
Inserts the current page number. When a format is specified, uses that numeric format (1 = decimal, i = lowercase roman numerals, I = uppercase roman numerals, a = lowercase ascii, A = uppercase ascii) for the page numbers.
$PAGES
$PAGES(format)
Inserts the total page count. When a format is specified, uses that numeric format (1 = decimal, i = lowercase roman numerals, I = uppercase roman numerals, a = lowercase ascii, A = uppercase ascii) for the page count.
$TIME
$TIME(format)
Inserts the current time. See Date/Time Formats for details on the format string. When no format is supplied, the default time format for the current locale is used.
$TITLE
Inserts the document title.
$URL
Inserts the document filename or URL.

Date/Time Formats

The $DATE and $TIME header/footer strings support an optional format string in parenthesis. Letters represent date/time values while other characters are inserted verbatim. The following letters are supported:

LetterDescription
AFull weekday name
aAbbreviated weekday name
BFull month name
bAbbreviated month name
CCentury (CC)
cDefault date and time format
dDay of the month ("01" to "31")
eDay of the month (" 1" to "31")
FYYYY-MM-DD
HHours for 24-hour clock ("00" to "23")
IHours for 12-hour clock ("01" to "12")
jDay of the year ("001" to "366")
kHours for 24-hour clock (" 0" to "23")
lHours for 12-hour clock (" 1" to "12")
MMinutes ("00" to "59")
mMonth number ("01" to "12")
p"am" or "pm"
RHours and minutes ("HH:MM")
rHours, minutes, seconds, and am/pm ("HH:MM:SS am/pm")
SSeconds ("00" to "60")
THours, minutes, and seconds ("HH:MM:SS")
XDefault time format
xDefault date format
YYear with century (CCYY)
yYear without century (YY)
ZTime zone name
zTime zone offset from UTC

FONT Attributes

Limited typeface specification is currently supported to ensure portability across platforms and for older PostScript printers:

Requested FontActual Font
ArialHelvetica
CourierCourier
DingbatsDingbats
HelveticaHelvetica
MonospaceDejaVu Sans Mono
SansDejaVu Sans
SerifDejaVu Serif
SymbolSymbol
TimesTimes

All other unrecognized typefaces are silently ignored.

Headings

Currently HTMLDOC supports a maximum of 1000 chapters (H1 headings). This limit can be increased by changing the MAX_CHAPTERS constant in the config.h file included with the source code.

All chapters start with a top-level heading (H1) markup. Any headings within a chapter must be of a lower level (H2 to H15). Each chapter starts a new page or the next odd-numbered page if duplexing is selected.

Note: Heading levels 7 to 15 are not standard HTML and will not likely be recognized by most web browsers.

The headings you use within a chapter must start at level 2 (H2). If you skip levels the heading will be shown under the last level that was known. For example, if you use the following hierarchy of headings:

<H1>Chapter Heading</H1>
...
<H2>Section Heading 1</H2>
...
<H2>Section Heading 2</H2>
...
<H3>Sub-Section Heading 1</H3>
...
<H4>Sub-Sub-Section Heading 1</H4>
...
<H4>Sub-Sub-Section Heading 2</H4>
...
<H3>Sub-Section Heading 2</H3>
...
<H2>Section Heading 3</H2>
...
<H4>Sub-Sub-Section Heading 3</H4>
...
the table-of-contents that is generated will show:
  • Chapter Heading
    • Section Heading 1
    • Section Heading 2
      • Sub-Section Heading 1
        • Sub-Sub-Section Heading 1
        • Sub-Sub-Section Heading 2
      • Sub-Section Heading 2
        • Sub-Sub-Section Heading 3
    • Section Heading 3

Numbered Headings

When the numbered headings option is enabled, HTMLDOC recognizes the following additional attributes for all heading elements:
VALUE="#"
Specifies the starting value for this heading level (default is "1" for all new levels).
TYPE="1"
Specifies that decimal numbers should be generated for this heading level.
TYPE="a"
Specifies that lowercase letters should be generated for this heading level.
TYPE="A"
Specifies that uppercase letters should be generated for this heading level.
TYPE="i"
Specifies that lowercase roman numerals should be generated for this heading level.
TYPE="I"
Specifies that uppercase roman numerals should be generated for this heading level.

Images

HTMLDOC supports loading of GIF, JPEG, and PNG image files. BMP image support is deprecated and will be removed in a future version of HTMLDOC. EPS and other types of image files are not supported at this time.

Links

External URL and internal (#target and filename.html) links are fully supported for HTML and PDF output.

When generating PDF files, local PDF file links will be converted to external file links for the PDF viewer instead of URL links. That is, you can directly link to another local PDF file from your HTML document with:

<A HREF="filename.pdf">...</A>

META Attributes

HTMLDOC supports the following META attributes for the title page and document information:

<META NAME="AUTHOR" CONTENT="..."
Specifies the document author.
<META NAME="COPYRIGHT" CONTENT="..."
Specifies the document copyright.
<META NAME="DOCNUMBER" CONTENT="..."
Specifies the document number.
<META NAME="GENERATOR" CONTENT="..."
Specifies the application that generated the HTML file.
<META NAME="HTMLDOC.filename" CONTENT="..."
Specifies the filename that is reported in CGI mode.
<META NAME="KEYWORDS" CONTENT="..."
Specifies document search keywords.
<META NAME="SUBJECT" CONTENT="..."
Specifies document subject.

Tables

Currently HTMLDOC supports a maximum of 200 columns within a single table. This limit can be increased by changing the MAX_COLUMNS constant in the config.h file included with the source code.

HTMLDOC does not support HTML 4.0 table elements or attributes, such as TBODY, THEAD, TFOOT, or RULES.

htmldoc-1.9.20/doc/5-mdref.html000066400000000000000000000133771472561501400161470ustar00rootroot00000000000000

Chapter 5 - Markdown Reference

This chapter describes the markdown syntax that is recognized and supported by HTMLDOC.

General Syntax

Markdown is a simple plain-text format that uses formatting conventions that are commonly used in email and other text-based communications. Markdown is used by most of the major blogging, web site, and project hosting platforms and is supported by many standalone text editors.

HTMLDOC supports the CommonMark version of markdown syntax with the following exceptions:

  • Metadata as used by Jekyll and other web markdown solutions can be placed at the beginning of the file;
  • "@" links can be used which resolve to headings within the file;
  • Tables can be embedded using the "|" separator;
  • Embedded HTML markup and entities are explicitly not supported or allowed;
  • Tabs are silently expanded to the markdown standard of four spaces since HTML uses eight spaces per tab; and
  • Some pathological nested link and inline style features supported by CommonMark (******Really Strong Text******) are not supported by mmd.
Note: HTMLDOC does not support embedded HTML in markdown documents because the version of HTML (or XHTML) cannot be reliably determined, making support of certain character entities and language elements problematic.

Metadata Syntax

Metadata is specified at the top of a markdown file between two lines containing three hyphens, for example:

---
title: My Great Novel
author: John Doe
copyright: Copyright © 2018 by John Doe
version: 1.0
language: en-US
subject: Fiction
---

# Preamble

...

HTMLDOC supports the "author", "copyright", "language", "subject", "title", and "version" metadata and silently ignores everything else.

Link Targets and @ Links

CommonMark defines no standard for how implementations generate anchors or identifiers for headings in a markdown file - this makes hyperlinking to a named section within a document basically impossible. Jekyll and other markdown implementations allow the special link "@" to be used, which HTMLDOC supports:

See [Screwing in a Light Bulb](@) for instructions on installing a
light bulb.

...

# Screwing in a Light Bulb

...

To reference a markdown heading from a HTML file, convert the heading to lowercase, replace spaces with the hyphen ("-"), and remove any special characters. Thus, a HTML file would reference the previous heading using the following HTML:

<a href="#screwing-in-a-light-bulb"> ... </a>

Table Syntax

CommonMark does not define a syntax for plain-text tables, instead relying on embedded HTML which HTMLDOC does not support. Both Github and Jekyll support a common markdown extension for plain text tables that uses the vertical pipe ("|") character to specify column separations. The first line contains the table header, the second line is a horizontal separator, and the remaining lines contain the table body. For example:

| Heading 1 | Heading 2 | Heading 3 |
| --------- | --------- | --------- |
| Cell 1,1  | Cell 1,2  | Cell 1,3  |
| Cell 2,1  | Cell 2,2  | Cell 2,3  |
| Cell 3,1  | Cell 3,2  | Cell 3,3  |

will produce:

Heading 1Heading 2Heading 3
Cell 1,1Cell 1,2Cell 1,3
Cell 2,1Cell 2,2Cell 2,3
Cell 3,1Cell 3,2Cell 3,3

The outer pipes can be omitted, for example:

Heading 1 | Heading 2 | Heading 3
--------- | --------- | ---------
Cell 1,1  | Cell 1,2  | Cell 1,3
Cell 2,1  | Cell 2,2  | Cell 2,3
Cell 3,1  | Cell 3,2  | Cell 3,3

While table headings are always centered, you can control the alignment of the body cells by using the colon (":") character in the separator line. Put a leading colon to specify left alignment (the default), a trailing colon for right alignment, or both to specify centering. For example:

Left Alignment | Center Alignment | Right Alignment
:------------- | :--------------: | --------------:
Cell 1,1       |     Cell 1,2     |               1
Cell 2,1       |     Cell 2,2     |              12
Cell 3,1       |     Cell 3,2     |             123

will produce:

Left AlignmentCenter AlignmentRight Alignment
Cell 1,1Cell 1,21
Cell 2,1Cell 2,212
Cell 3,1Cell 3,2123

Table columns do not need to be padded so that they line up - the following (less readable) example is perfectly valid:

Left Alignment|Center Alignment|Right Alignment
:--|:--:|--:
Cell 1,1|Cell 1,2|1
Cell 2,1|Cell 2,2|12
Cell 3,1|Cell 3,2|123
htmldoc-1.9.20/doc/Makefile000066400000000000000000000041671472561501400154570ustar00rootroot00000000000000# # Makefile for HTMLDOC documentation files. # # Copyright © 2011-2024 by Michael R Sweet. # Copyright © 1997-2010 by Easy Software Products. # # This program is free software. Distribution and use rights are outlined in # the file "COPYING". # # # Include common definitions... # include ../Makedefs # # Documentation files... # SOURCES = 1-intro.html \ 2-using.html \ 3-cmdref.html \ 4-htmlref.html \ 5-mdref.html \ a-license.html \ b-book.html DOCUMENTS = htmldoc.epub htmldoc.html htmldoc.pdf htmldoc.ps DOCFILES = help.html htmldoc.pdf HTMLDOC = ../htmldoc/htmldoc$(EXEEXT) --datadir .. --strict # # Make everything... # all: $(DOCUMENTS) # # Install everything... # install: $(DOCUMENTS) $(INSTALL_DIR) $(BUILDROOT)$(datadir)/doc/htmldoc; for file in $(DOCFILES); do \ $(INSTALL_DATA) $$file $(BUILDROOT)$(datadir)/doc/htmldoc; \ done $(INSTALL_DIR) $(BUILDROOT)$(mandir)/man1; $(INSTALL_MAN) htmldoc.man $(BUILDROOT)$(mandir)/man1/htmldoc.1 # # Clean out document files... # clean: $(RM) $(DOCUMENTS) # # htmldoc program (dummy rule) # ../htmldoc/htmldoc$(EXEEXT): echo Rebuilding documentation... # # htmldoc.d (directory) # .PHONY: htmldoc.d htmldoc.d: $(SOURCES) ../htmldoc/htmldoc$(EXEEXT) echo Formatting htmldoc.d... if test -d htmldoc.d; then \ $(RM) -r htmldoc.d; \ fi $(MKDIR) htmldoc.d $(VALGRIND) $(HTMLDOC) --batch htmldoc.book --strict -t htmlsep -d htmldoc.d # # htmldoc.epub # htmldoc.epub: $(SOURCES) ../htmldoc/htmldoc$(EXEEXT) echo Formatting htmldoc.epub... $(VALGRIND) $(HTMLDOC) --batch htmldoc.book --strict --titleimage htmldoc-cover.png -f htmldoc.epub # # htmldoc.html # htmldoc.html: $(SOURCES) ../htmldoc/htmldoc$(EXEEXT) echo Formatting htmldoc.html... $(VALGRIND) $(HTMLDOC) --batch htmldoc.book --strict -f htmldoc.html # # htmldoc.pdf # htmldoc.pdf: $(SOURCES) ../htmldoc/htmldoc$(EXEEXT) echo Formatting htmldoc.pdf... $(VALGRIND) $(HTMLDOC) --batch htmldoc.book --strict -f htmldoc.pdf # # htmldoc.ps # htmldoc.ps: $(SOURCES) ../htmldoc/htmldoc$(EXEEXT) echo Formatting htmldoc.ps... $(VALGRIND) $(HTMLDOC) --batch htmldoc.book --strict -f htmldoc.ps htmldoc-1.9.20/doc/a-license.html000066400000000000000000000430701472561501400165410ustar00rootroot00000000000000

Appendix A - License Agreement

GNU GENERAL PUBLIC LICENSE

Version 2, June 1991

Copyright 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 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

  1. 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.

  2. 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.

  3. 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:
    1. You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
    2. 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.
    3. 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.

  4. 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:
    1. 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,
    2. 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,
    3. 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.

  5. 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.
  6. 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.
  7. 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.
  8. 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.

  9. 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.
  10. 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.

  11. 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

  1. 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.
  2. 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

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.

one line to give the program's name and an idea of what it does.
Copyright (C) yyyy  name of author

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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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) year 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.

signature of Ty Coon, 1 April 1989
Ty Coon, President of Vice
htmldoc-1.9.20/doc/b-book.html000066400000000000000000000037231472561501400160530ustar00rootroot00000000000000

Appendix B - Book File Format

This appendix describes the HTMLDOC .book file format.

Introduction

The HTMLDOC .book file format is a simple text format that provides the command-line options and files that are part of the document. These files can be used from the GUI interface or from the command-line using the --batch option:

htmldoc filename.book
htmldoc --batch filename.book

The first form will load the book and display the GUI interface, if configured. Windows users should use ghtmldoc.exe executable to show the GUI and htmldoc.exe for the batch mode:

ghtmldoc.exe filename.book
htmldoc.exe --batch filename.book

The Header

Each .book file starts with a line reading:

#HTMLDOC 1.9

The version number (1.9) is optional.

The Options

Following the header is a line containing the options for the book. You can use any valid command-line option on this line:

-f htmldoc.pdf --titleimage htmldoc.png --duplex --compression=9 --jpeg=90

Long option lines can be broken using a trailing backslash (\) on the end of each continuation line:

-f htmldoc.pdf --titleimage htmldoc.png --duplex \
--compression=9 --jpeg=90

The Files

Following the options are a list of files or URLs to include in the document:

1-intro.html
2-using.html
3-cmdref.html
4-htmlref.html
5-mdref.html
a-license.html
b-book.html

Putting It All Together

The following is the complete book file needed to generate this documentation:

#HTMLDOC 1.9
-f htmldoc.pdf --titleimage htmldoc.png --duplex --compression=9 --jpeg=90
1-intro.html
2-using.html
3-cmdref.html
4-htmlref.html
5-mdref.html
a-license.html
b-book.html
htmldoc-1.9.20/doc/help.html000066400000000000000000000472721472561501400156410ustar00rootroot00000000000000 HTMLDOC On-Line Help

HTMLDOC On-Line Help


Contents

Loading and Saving Books

HTMLDOC stores the HTML files, settings, and options you have chosen in .BOOK files. The buttons on the bottom of the HTMLDOC window allow you manage these files and generate formatted documents.
Button Description
Help Displays this on-line help.
New Creates a new .BOOK file.
Open... Opens an existing .BOOK file.
Save Saves the current .BOOK file to disk.
Save As... Saves the current .BOOK file to disk using the name you specify.
Generate Generates the current .BOOK file into a HTML, PDF, or PostScript file.
Close Exits HTMLDOC.

Contents | Loading and Saving Books

The Input Tab

The input tab lists all of the source files that are used to generate the document. You can also specify the type of document (book or web page) and the title and logo images.

Setting the Document Type

Normally HTMLDOC generates indexed documents from your structured source files. To convert a single unstructured document (or "web page") click on the Continuous or Web Page radio buttons. The Web Page type inserts page breaks between each file or URL, while the Continuous type does not.

Structured HTML files use heading elements (H1, H2, etc.) to delineate chapters and headings within a document.

Adding Input Files

Click on the Add File(s)... button to add one or more HTML or Markdown files to your .BOOK file.

Adding URLs

Click on the Add URL(s)... button to add one or more URLs to your .BOOK file.

Deleting Input Files

Highlight the file(s) in the input file list and then click on the Delete button to remove one or more source files from your document. The files are removed from your document but are not deleted from disk.

Editing Input Files

Highlight the file(s) in the input file list and then click on the Edit... button to edit one or more source files in your document. By default this starts the gedit editor under Linux, the bbedit editor under macOS, and the Notepad editor under Windows.

The editor can be changed in the Options Tab.

Reordering Input Files

Highlight the file(s) in the input file list and then click on the Move Up or Move Down buttons to change the order of the input files.

Selecting a Letterhead Image

The letterhead image can be shown in the header or footer of pages in the PostScript and PDF output files. Click on the Browse button to select a letterhead image file using the file chooser.

Selecting a Logo Image

The logo image can be shown in the header or footer of pages in the PostScript and PDF output files. Click on the Browse button to select a logo image file using the file chooser.

Selecting a Title File or Image

The title file or image is used for the title page. Click on the Browse button to select a title file using the file chooser.


Contents | Loading and Saving Books

The Output Tab

The output tab specifies where your document will be generated, the output format, and some of the output options.

Selecting File or Directory Generation

HTMLDOC can generate a single EPUB, HTML, PDF, or PostScript file, or a series of files to a directory when generating HTML or PostScript output.

Click on the File radio button to select single file output. Click on the Directory radio button to generate multiple files to a directory.

Selecting an Output File or Directory

The output file is the EPUB, HTML, PostScript, or PDF file you wish to generate from your source files. Click on the Browse button to select an output file using the file chooser.

Selecting the Output Format

Click on the corresponding Output Type radio button to select an output format. You can select the PostScript language level in the PS Tab and the PDF version in the PDF Tab.

Selecting Grayscale Output

When generating PostScript or PDF files you can choose to convert all images to grayscale. This is necessary for many Level 1 printers that do not support color images and can reduce the size of output files considerably.

Click in the Grayscale check box to enable or disable grayscale output.

Title Page

The title page is the first page in your generated file. Click in the Title Page check box to turn the title page on or off.

JPEG Big Images

JPEG compression is a great way to reduce the size of large photographic or continuous-tone images. It is supported when generating PDF, PostScript Level 2, and PostScript Level 3 output. HTMLDOC uses JPEG compression when the output image cannot be reduced to 256 colors or less.

Click in the JPEG Big Images check box to enable or disable JPEG compression.

JPEG Quality

Drag the JPEG Quality slider to change the JPEG quality setting. The JPEG quality setting determines the relative quality of the compressed image. Since JPEG is a lossy compression algorithm, higher compression generally yields lower quality. Typically a quality of 75 or higher provides excellent image quality with a high amount of compression.

Compression

PDF 1.2, PDF 1.3, PDF 1.4, and Level 3 PostScript files can be compressed using Flate (a.k.a. ZIP) compression to substantially reduce the size of files. Drag the Compression slider to set the amount of compression to use.

Unlike JPEG, the Flate algorithm is lossless and will not cause any loss of visual quality at any level of compression.


Contents | Loading and Saving Books

The Page Tab

The page tab defines the page header, footer, size, and margins for PostScript and PDF output.

Page Size

The page size option is only available for PostScript and PDF output. HTMLDOC supports the following standard page size names:

  • A3 - 11.69x16.54in (297x420mm)
  • A4 - 8.27x11.69in (210x297mm)
  • Legal - 8.5x14in (216x356mm)
  • Letter - 8.5x11in (216x279mm)
  • Tabloid - 11x17in (279x432mm)
  • Universal - 8.27x11in (210x279mm)

Click on the Page Size arrow button to select a standard page size. You can specify a custom page size by double-clicking on the page size text and entering the page width and length separated by the letter "x". Append the letters "in" for inches, "mm" for millimeters, or "cm" for centimeters.

Note: This option does not set the page size on the printer. It only generates pages using the specified size. See the PS Tab to enable printer commands for PostScript printers.

2-Sided

Click in the 2-Sided check box to select double-sided (duplexed) output.

Note: This option does not select duplexing on the printer. It only generates pages with the left/right margins swapped on even numbered pages and forces all chapters (and the table-of-contents) to start on an odd-numbered page. See the PS Tab to enable printer commands for PostScript printers.

Landscape

Click in the Landscape check box to select landscape output.

Page Margins

The left, right, top, and bottom margins can be changed by clicking in the appropriate text field and entering a new margin. Append the letters "in" for inches, "mm" for millimeters, or "cm" for centimeters.

Header and Footer

Select the desired text from each of the option buttons to customize the header and footer for the document/body pages. The left option buttons set the text that is left-justified, the middle buttons set the text that is centered, and the right buttons set the text that is right-justified.

The left and right header and footer are swapped automatically when generating duplexed output.

Number Up

The Number Up chooser selects the number of document pages that will appear on each output page. Click on the chooser to select a different number of pages.


Contents | Loading and Saving Books

The Table-Of-Contents Tab

The table-of-contents tab defines the number of levels in the table-of-contents and the page header and footer that are used when generating PostScript and PDF files.

Customizing the Table of Contents

To change the number of header levels listed in the table of contents, or to turn off table-of-contents generation entirely, click on Table of Contents chooser and select the number of levels desired.

Numbering Table of Contents Headings

To number the headings in your document, click on the Numbered Headings toggle button.

Customizing the Header and Footer

To customize the header and footer for the table-of-contents pages, select the desired text from each of the option buttons. The leftmost option buttons set the text that is left-justified, while the middle buttons set the text that is centered and the right buttons set the text that is right-justified.

Title

Enter the desired title for the table-of-contents in the Title field.

Contents | Loading and Saving Books

The Colors Tab

The colors tab specifies the colors and background image that should be used for the document.

Body Color

The Body Color field specifies the default background color. It can be a standard HTML color name or a hexadecimal RGB color of the form #RRGGBB. Click on the Lookup... button to pick the color graphically.

Body Image

The Body Image field specifies the default background image. Click on the Browse... button to pick the background image using the file chooser.

Text Color

The Text Color field specifies the default text color. It can be a standard HTML color name or a hexadecimal RGB color of the form #RRGGBB. Click on the Lookup... button to pick the color graphically.

Link Color

The Link Color field specifies the default link color. It can be a standard HTML color name or a hexadecimal RGB color of the form #RRGGBB. Click on the Lookup... button to pick the color graphically.

Link Style

The Link Style chooser specifies the default link decoration.

Contents | Loading and Saving Books

The Fonts Tab

The fonts tab contains all of the document font options. The default options roughly correspond to those used by most browsers.

Base Font Size

Click on the left arrow buttons to decrease the font size and the right arrow buttons to increase the font size.

The font size value is in points (there are 72 points per inch).

Line Spacing

Click on the left arrow buttons to decrease the line spacing and the right arrow buttons to increase the line spacing.

Body Typeface

The body typeface is the font used for paragraphs and most other text in a document. Click on the Body Typeface option button to change the body typeface.

Heading Typeface

The heading typeface is the font used for headings. Click on the Heading Typeface option button to change the typeface used for headings.

Header/Footer Size

Click on the left arrow buttons to decrease the heading and footer font size and the right arrow buttons to increase the font size. The font size value is in points (there are 72 points per inch).

Header/Footer Font

The header/footer font is the font used for headers at the top of the page and footers at the bottom of the page. Click on the Header/Footer Font option button to change the header/footer font.

Character Set

Click on the Character Set option button to change the encoding of text in the document.

Options

The Embed Fonts check box controls whether or not fonts are embedded in PostScript and PDF output.


Contents | Loading and Saving Books

The PS Tab

The PS tab contains settings specific to PostScript output.

Language Level

Select the appropriate language level by clicking on the corresponding radio button. Level 1 output is the most portable, however most PostScript printers manufactured in the last 6 years support Level 2. Level 3 output supports Flate compression, however very few printers support Level 3 PostScript at this time.

Send Printer Commands

Click in the Send Printer Commands check box to enable to disable printer commands in the PostScript output files. Printer commands are not supported for PostScript Level 1 output.

Include Xerox Job Comments

The Include Xerox Job Comments check box controls whether or not the output files contain Xerox job comments. Click in the check box to enable or disable the job comments.

Job comments are available with all levels of PostScript output.


Contents | Loading and Saving Books

The PDF Tab

The PDF tab contains settings specific to PDF output.

PDF Version

The PDF Version radio buttons control what version of PDF is generated. PDF 1.4 is the most commonly supported version. Click on the corresponding radio button to set the version.

Page Mode

The Page Mode option button controls the initial viewing mode for the document. Click on the option button to set the page mode.

The Document page mode displays only the document pages. The Outline page mode displays the table-of-contents outline as well as the document pages. The Full-Screen page mode displays the document pages on the whole screen; this mode is used primarily for presentations.

Page Layout

The Page Layout option button controls the initial layout of document pages on the screen. Click on the option button to set the page layout.

The Single page layout displays a single page at a time. The One Column page layout displays a single column of pages at a time. The Two Column Left and Two Column Right page layouts display two columns of pages at a time; the first page is displayed in the left or right column as selected.

First Page

The First Page option button controls the initial page that is displayed. Click on the option button to choose the first page.

Page Effect

The Page Effect option button controls the page effect that is displayed in Full-Screen mode. Click on the option button to select a page effect.

Page Duration

The Page Duration slider controls the number of seconds that each page will be visible in Full-Screen mode. Drag the slider to adjust the number of seconds.

Effect Duration

The Effect Duration slider controls the number of seconds that the page effect will last when changing pages. Drag the slider to adjust the number of seconds.

Options

The Include Links check box controls whether or not hyperlinks are included in PDF output.


Contents | Loading and Saving Books

The Security Tab

The security tab allows you to enable PDF document encryption and security features.

Encryption

The Encryption buttons control whether or not encryption is performed on the PDF file. Encrypted documents can be password protected and also provide user permissions.

Permissions

The Permissions buttons control what operations are allowed by the PDF viewer.

Owner Password

The Owner Password field contains the document owner password, a string that is used by Adobe Acrobat to control who can change document permissions, etc.

If this field is left blank, a random 32-character password is generated so that no one can change the document using the Adobe tools.

User Password

The User Password field contains the document user password, a string that is used by Adobe Acrobat to restrict viewing permissions on the file.

If this field is left blank, any user may view the document without entering a password.


Contents | Loading and Saving Books

The Options Tab

The options tab contains the current HTML editor and allows you to save the current settings as defaults.

HTML Editor

Type in the program name in the HTML Editor field or click on the Browse... button to change the HTML editor that is used. The "%s" is required and is replaced by the file to edit.

Browser Width

Drag the Browser Width slider to specify the width of the browser in pixels that is used to scale images and other pixel measurements to the printable page width. You can adjust this value to more closely match the formatting on the screen.

The default browser width is 680 pixels which corresponds roughly to a 96 DPI display. The browser width is only used when generating PostScript or PDF files.

Search Path

Enter a list of directories in the Search Path field to specify a search path for files that are loaded by HTMLDOC. This is usually used to get images that use absolute server paths to load.

Directories are separated by the semicolon (;) so that drive letters and URLs can be specified.

HTTP Proxy URL

Enter the URL for the HTTP proxy in the HTTP proxy URL field to specify a proxy host for all HTTP requests.

Tooltips

Check the Tooltips button to enable tooltips on GUI controls.

Strict HTML

Check the Strict HTML button to enable strict HTML conformance checking in HTMLDOC.

Save Options and Defaults

Click on the Save Options and Defaults button to save the current HTML editor, page, table-of-contents, color, font, PDF, and PostScript options. Default options are used for new documents and when generating documents from the command-line. htmldoc-1.9.20/doc/htmldoc-cover.opacity000066400000000000000000000372671472561501400201660ustar00rootroot00000000000000bplist00X$versionX$objectsY$archiverT$topbnopqrvw~ '-ABICDEFJNQUX\_bcjkwxyz{|"#)*6789V:@DKLPSUY]eou  !:=@EJOPQRSTUZajq{@!./347AGOPQUYZ`aeiv|}~>NOPQRSTX\`defgknopqrsx~:,M?12345678BCDKLMWXYZbcdefrst9uvU$null0  !"#$%&'()*+,-./0123456789:;9<=>>@AB::CDEFGH:IJKLMN>PQRSIMUVWXYB[\]B>B9@9WpolySidWpixDTypSbmPUresUnTsecCUcolSpUoBgImSparVnPaStrWactLaysUsnShsWpenTTypSmodTzoomTallRVsavStDTmetaVspiDecVgenNamUorTypVpixRadTfrasUimSizUbgColVnPaFilV$classVactTraVsavPrDTtarsVcurFraSenVVlineThVautoBTUshLayXrectCRadUresiMTcurRWspiSegsTtrasWfilSensUmainCVtraTrgVcurObjVguiLinTvarsVlasModWpolyStaUbgTyp/C "#@@ D#@T.#?,- b *#- "#@I+""cd"eimWNS.keysZNS.objectsfghjkl \kMDItemTitle^kMDItemAuthors_kMDItemCopyrightXNew Icond"sut ]Michael Sweetxyz{Z$classnameX$classesWNSArray|}WNSArrayXNSObject_Copyright 2017 Michael Sweetxy_NSMutableDictionary}\NSDictionaryd"uX  "SresSdel#?xy\PCResolution}\PCResolutionXPCObject"#?"I"#@"#@"#@#"#?d"uR "ATlaysUanimTUlAcLs#?  cd"mfghjl d"ut d"uրހ "M::@M@RSexpUblendWmaskTypUedMskSnamWmaskLaySvisTisShTopac $ %#@Y">BUalConTobjs"#cd"m! #@ia-#@#"#@ia- xy_PCBitmapContext}_PCBitmapContextZPCDrawableXPCObject" #@# d" u xy]PCNormalLayer}]PCNormalLayerWPCLayerZPCDrawableXPCObjectTLogod"u&Iv "@:":#$@MSfilH9:' ">*B&("#cd".7m/0123456)*+,-./089:;<=>?12345678 #@ia-#?#?#@##@ "$H'#@ia- "$L'#? "$I' "$S'#? "$' "$Z'#@# "$E' "$' ]Shadow Effect"defhiTfilNTattsG&;<_PCShadowEffectFiltercd"lqmmnop=>?@rstrABFA [inputOffsetZinputColorZinputAngleYinputBlur#@}~"=UNSRGB\NSColorSpace_NSCustomColorSpaceJ0 0 0 0.5CE"TNSIDDxy\NSColorSpace}\NSColorSpacexyWNSColor}WNSColor#VxyXPCFilter}XPCFilterZPCDrawableXPCObjectxy]PCFilterLayer}]PCFilterLayerWPCLayerZPCDrawableXPCObject"::@M@VJ W#a">BIK"#cd"m61350+L-M/NOPQRSTU #?#@##@ia-"J "IJ "J#? "J "J#@# "EJ "J#@ia- Scd"m316XY-Z+0[\]^_` #@##@ia-#?"I#@# "I#@ia- "I "I#? "II "I d"ub      " @@MVM@VM V@TrectTstrYSisIXstrTBndsTstrXSshXTantiSflVVattStrSshYUalPixSangSflHc udI t_{{10, 83}, {120, 80}}$"%&'(XNSString\NSAttributesesfScd"+05,-./ghij1234klnqrVNSKern_NSParagraphStyleVNSFontWNSColor;"<>>?ZNSTabStops[NSAlignmentmxyAB_NSMutableParagraphStyleAC}_NSParagraphStyleEFG"[HIJVNSSizeXNSfFlagsVNSNameop]OpenSans-BoldxyMNVNSFontO}VNSFont}~"QF1 0 0ExyT}xyVW_NSAttributedStringX}_NSAttributedStringZ~"[9WNSWhiteD1 0Exy^_\PCTextVector`abcd}\PCTextVector_PCRectBasedVectorXPCVectorZPCDrawableXPCObject"::@ghMjl@~w #">rBvx"#cd"vzmw5yy/z{|}{|} #@ia-#@#"hw#@ia- "hEw "hw#@# ZBackgroundcd"m #@ia-#@#"v#@ia- "v#@# d"u   "@MVM@VMV@UdimLKWfilPropVcornRXVcornRYUstros #@0v cd"m ]cornerRadiusX]cornerRadiusY_&{{10, 53.650000000000006}, {120, 120}}"@::?>:MVrelLP2SblHWgradAngUradGCTfilTWrelRadCVfilPosSaEqStypXrelLinP1VfilColVrelLP1UfilImVothColXrelLinP2SgEqUfilGrSrEqXgradStopUpgNumSbEq#@V }~"F0 0 0E}~"L0.6 0.6 0.6Ed"񀎀">V<ValtColSlocScolZ~"9B1Exy^PCGradientStop}^PCGradientStopZPCDrawableXPCObject">xy  ^NSMutableArray  }WNSArrayV{0, 0}V{0, 0}V{0, 0}V{0, 0}V{0, 0}V{0, 0}Q0QtW100 - tS100xy_PCDrawVectorProperties}_PCDrawVectorPropertiesZPCDrawableXPCObjectd"""#$%&?'@):*+:?->/0:M3I:\79TcapSSposUinvisSwidUdashS Z~";9B0E}~">L0.4 0.4 0.4Ed"ABC">V\">0V{0, 0}V{0, 0}V{0, 0}V{0, 0}V{0, 0}V{0, 0}d"Vu51/k xy[\_PCStrokeVectorProperties]^_`}_PCStrokeVectorProperties_PCDrawVectorPropertiesZPCDrawableXPCObjectxybc\PCRectVectordefghi}\PCRectVector\PCPathVector_PCRectBasedVectorXPCVectorZPCDrawableXPCObjectxykl]PCFolderLayermnop}]PCFolderLayerWPCLayerZPCDrawableXPCObject"M::@tuMw@R  ">~B"#cd"m #@#"u#@# WLayer 1d"uƀ "@::@MH ">B"#cd"m #@#"#@# _Inner Glow Effect"defG_PCInnerGlowEffectFiltercd"m€Āŀ ZinputColor_inputHideOriginalYinputSize}~"?F1 1 0ÀE"D#@"::@M@ˀ ̀#">BƀȀ"#cd"mۀɡ݀ʀ #@#"#@# TTextcd"m͡΀ #@#"#@# d"uЀـ      " @@MVM@VMV@ uҀ _{{0, 25}, {140, 30}}$"%'ӀsWHTMLDOCcd" 5,-./ghij1kՀր׀r;"<>>?mEFG"HIJ#@1op}~"F1 1 1EZ~"9D1 0E     " "@@MVM@)VM,V@ uۀ _{{0, 5}, {140, 30}}$"%0'܀s\Users ManualZ~"59D1 0E"::@9:M<>@R #">DBހ"#cd"HKmIJLM #@ia-#@#":S#@ia- ":W#@# ZBackgroundcd"[]m\^ #@#"c#@# d"fug   "jk@MnVM@VVrVMV@  cd"wymxz ]cornerRadiusX]cornerRadiusY_#{{0, 0}, {140, 187.30000000000001}}"@::>g:M }~"F0 0 1E}~"J0.5 0.5 1Ed"">nV4q">n}~"N1 0.67 0.6755E">n#@Uh'}~"M1 0.34 0.351EV{0, 0}V{0, 0}_{70, -93.649999999999991}_{50, -49.999999999999986}_+{2.8421709430404014e-14, 93.65000000000002}_,{2.0301221021717149e-14, 50.000000000000007}W100 - td"""#$%&?@:+:?>g:MI:\ҁ    }~"L0.4 0.4 0.4Ed"ف">V\">V{0, 0}V{0, 0}V{0, 0}V{0, 0}V{0, 0}V{0, 0}d"u51/k d"u xyWPCFrame}WPCFrame_PCMetadataObjectZPCDrawableXPCObjectd"u "  @@>>:>M@@BYauSizCropVnewFacUapIn1TpathTapIDUcropRUapIn2UisRelUisColTcropVvarVal) "_!{{6, 29.650000000000006}, {0, 0}}_htmldoc-cover.png !""#$%&'()*+,MR/012>456M89;<XUcodeSUprColVprShTiSfraVcodePlVcodeFrUcodeFTsnShVexPropTpropUgenCHUgrTypVanLooCVprLinCUcodeL' #$&(!  "%cd"?Fm@ABCDEGH<JKL V{JFIF}U{GIF}_"kCGImageDestinationBackgroundColorU{PNG}V{TIFF}_*kCGImageDestinationLossyCompressionQualitycd"UVm cd"YZm cd"]^m cd"abm #?Zpublic.png]public.foldercd"him }~"lL0.5 0 0 0.5ESiosUcocoaUtouchVMyViewVUIViewxytu_PCBitmapPropertiesvw}_PCBitmapPropertiesXPCObjectxyyzYPCFactory{|}}YPCFactoryZPCDrawableXPCObjectd"򠀒Yselection_{140, 187.30000000000001}Z~"9E0.75E_CICheckerboardGenerator !""#$%&'()*>,MR2>M89 ABC(?0>  @Bcd"m123456<789<= _"kCGImageDestinationBackgroundColorV{JFIF}U{GIF}V{TIFF}U{PNG}_*kCGImageDestinationLossyCompressionQualitycd"m cd"m cd"m:; [Compressioncd"m #?_com.likethought.opacity.opacitycd"m }~"J1 0 0 0.5ESmacVquartz_MyDrawingFunctioncd"mفEFGHIJKLMĀāNOāPTĀĀ _framePickerVisibleZhideRulers[windowFrame_layerViewDimension]hideVariablesZexpansionsYprintInfo]toolbarHidden_editFrameMetadata_{{35, 38}, {958, 839}}#@i`cd"mQRSS "\NSAttributesaUcd"mVWXYZ[\]   S^^_QS`` _NSHorizontallyCentered]NSRightMargin\NSLeftMargin_NSHorizonalPagination_NSVerticalPagination_NSVerticallyCentered[NSTopMargin^NSBottomMargin"B"Bxy[NSPrintInfo}[NSPrintInfocd" (m!"#$%&'cdefghi)*,-!/jptyc _"com.likethought.opacity.preview.ui_(com.likethought.opacity.preview.elementsWfactory_#com.likethought.opacity.preview.web_&com.likethought.opacity.preview.cursorTtype_&com.likethought.opacity.preview.iphonecd"9=m:&<khl<@Qm Ucolor[resolutionsd"EFG16no+0#?#?cd"NRmOPQqrsĀĀĀ VstatusWtoolbarTdockcd"[^m\]uv_`wx WaddressUimage_#http://likethought.com/opacity/web/_,http://likethought.com/opacity/web/image.pngcd"glmh&j:zh{kmno<|}~ XhotspotXXhotspotY#@#@=ffffhcd"wmx:z{|}~&kh<QQ UrectXUrectHUrectWUrectYTleftStop#@4#@F#@ixyWPCImage}WPCImage_PCMetadataObjectZPCDrawableXPCObject_NSKeyedArchiverTroot"+5:?Y_"*26<AGMQX`fnrw|#*18=DLRTVY[]_abegpruw &9BKNPR`it}   &*.09;=FSZgp#%'0357PU[acegpsv     % * + , . 0 1 3 5 6 ? A V \ a c e g i k x }       % & ( 1 ? J X ` k t y         - / 1 3 5 7 9 ; = ? H Q Z c l y {       & 7 < A C E G I ` m v x z | ~     " + 8 = J S [ ` h q z &')+,.0235JLNPRTaprtvxz|~,.0=?HJN[hjlnprt ')+479;'02468ACEGIKRelt  ',3@GIRW`uz =>@BCEGIJLacegikx   )68ACPR[]fikm &O "+1578ACEGIKMOQSUWY[]_`mtv(=?ACEN]dlsz  2468:AHOV]dmrtvx!.BKV_hv  "+8:CEMV[]_a !#=JQSUW^`bdfq!.1368:CPR[]bortwy{  !.024<IRTVXZcegikmz|~ 4ACEGTafh    ! # , . 9 F I K N P R [ h j s u ~ !!!9!!!!!!!!!!!!!!!!!!!!!!!!!!!""""""""!"#"8":"<">"@"M"\"^"s"u"w""""""""""##D#L#U#X#[#]####################$ $$$"$'$*$-$/$D$F$I$K$M$b$d$g$j$l$s$z$$$$$$$$$$$$$$$$$$$%%%%%%U%_%f%l%q%v%|%%%%%%%%%%%%%%%%%%%%%&<&B&H&O&S&Z&a&g&l&s&x&~&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&'' '''''''"'('M'S'Z''''''''''''''''''''''''( (((($(*(1(8(A(V(](r({(((((((((((((())e)g)h)j)m)p)s)v)x){)~)))))))))))))))))))))))*** ***G*T*U*V*X*e*f*g*i*v*y*|*******************+++%+8+;+>+A+D+G+J+M+P+S+f+h+j+m+p+r+u+x+z+|+~++++++++,,,&,3,8,;,>,C,F,I,K,L,U,b,e,h,u,,,,,,,,,,,,,,,,,,,,,,--,-C-O-^-c-h-q-}--------------------. .5.=.c...............// //////!/*/7/>/A/D/G/N/P/R/T/V/]/e/j/w/|///////////00 00000 0#0&0(0*030<0E0N0[0l0o0r0u0x0{0~000000000000000000000000111#1.171I1N1S1Uhtmldoc-1.9.20/doc/htmldoc-cover.png000066400000000000000000016267131472561501400173030ustar00rootroot00000000000000PNG  IHDRxQ"Ug iCCPICC Profile8U]hU>sg#$Sl4t? % V46nI6"dΘ83OEP|1Ŀ (>/ % (>P苦;3ie|{g蹪X-2s=+WQ+]L6O w[C{_F qb Uvz?Zb1@/zcs>~if,ӈUSjF 1_Mjbuݠpamhmçϙ>a\+5%QKFkm}ۖ?ޚD\!~6,-7SثŜvķ5Z;[rmS5{yDyH}r9|-ăFAJjI.[/]mK 7KRDrYQO-Q||6 (0 MXd(@h2_f<:”_δ*d>e\c?~,7?& ك^2Iq2"y@g|UP`oiTXtXML:com.adobe.xmp Michael Sweet Copyright 2017 Michael Sweet New Icon yP~&IDATx][b%7#da@UN\G% "22d!2 :???!>"3Ϩ~B= =Mڸߍ.x|捿>>n@ퟫ?3/ ʊ,4 ~TSK&.iϥ=0|wK.~ L^}GYHxO3Y۳}_}E^6{2 Ϳ5"M_œj-m[?zn^ZŧX 4@{>:<,jދۿ~,filx/O Nm7K7 g b%2 ymWs(Y?.ׯևq' MOCcr,;¾ociFޖhx"i/׏ g妝]߁?uI_O.Ƿk~s7?#{7sj~jOF18ՉٽLƀ?"nQ6~eֻsxbaN'_XlcdQu>P~Y bpG4S ~G?R\nܭ???7ςtgXri`P>G,|$&ߢQ~Bx[|9.3r'TL^ ;Ny%2'2VJ-ڟީQO5MxpRX2LmgfaOLqIHzsnm3`F9fvYgw{y273=O!Ԟ̤@sf7_+Tƀ>3TxMx_eέ~żq?V,͇tڞp3WJ \x#|HG>eL= _pE-aނG ۝9%e_z.(?q1~Wro-H̩ϑ@ &>u^!^w@3r?gJ"pQ,*j.F֞X~~R@Z;/Ry)= 1׀po`OK丗ma"1#<Ͷ@aڴ;???&:\)-N%6-"X=y} %[#@!_^TG(kI}~keWru*w3C+1~ONj50|x? CECT<ѥ/ װF7N:Aa։ŷa=\'z].o߮GDˑ-qwBۥNKyk]ʍCnk 1` e$zx3ڠڷJ#EJ }V0E( 5Csُ~Y'~hY2e3_YwT:Q\|ʊ,zhq\%!fUO/@f -xbaolT'ܝ倈Nw U|Jݞ|vR$D]m#|@^#wzU3Xo 5 y+ꍂ96QVfݲd~FgLsLv"I7Tʕ1ۓ{5bꤖ',/'f/z4kò%24ӎhvQR4SǮA;mhnNbn_*Ӯܣ/Q~uj ag$=v_}ǹ A%FY~m=ӄmu$O>+D|5vy~u:|Uf*m???Ŝlĉ]VE84u&#Zk YO;d枴-׈;0D|[hϰ[^x%7[YLixh~'LI+Ht977"I x(*0 yؿ` Jh狏gw1CEc Hg T6uRL;$f)lyp 2 z{dP3>391)=%h)T}~kK|c<VIg}Ż{ex| 3>bxT 4%!?k2'7aqBKe?4895)f`ų1Wov=4jێ>0w/#c'%34,u׻Zlz5޿_Mrڑ_~2dYKሥK4ҽ=䤨?{}岹Hj(???kB#5tEFV6ŇA3e?_iKd3P# 7nO<{$a H [%ab :8{S~,]="cNn0$1;>'??|Zj:(~PCktIatٶ:KO4b~1\h&et5@k{)%rL;;/~-;-`yK?' y&+A(%&al%"N״gkBFݸb^~T9}yT?Eۂ6? T~oFk]J%>??? SsauG*i"Sc4wߎAsPFYJ^qO&&frSCTؼ苅A2x٪V5So쩎@vUo_$F1b M "9*i"K2@M<Ӳrzt\W\ڎ/tvm烩: t90 Aaa~E!gV ҭ-n\[b֬_+K]4ۿ@U!zA#n׹=!s[~綋Bz´ߡqCemڟ2 8Ji9???>mbm``H].$1biF$n?D5|-Ip۟4)_LKcuL+Frm3be24i< ?y0}_ =w<0]7$Ó~rC>Hker$z&nXf/ ˃ˏg^L뭓}j?^5g~;X EC+e|a _ʦu.HGg%?>ߡc Za???#^%=d9N ^1Gk h`|= ow`x ΁!cgo_N;r6τ#:+\ Ooy+E!kЬ_zx76ٛ~BD3<^ rWfM`>m$e+tJE *.lLNSgo(J8ܺ~1(PDk00Sc?9P|~>kOWGk,c_o=Е:#x˛q5[|Kl>JB#v_؞px{߾ox<'K|e<@z4~ɇxh^`??ؓkxcOh ]4~\\=]`߅;p~4 s>=A_3PI(SEZT^A9I9?????􄊧 }N53r-). F =>GFc3!c 2f-2pAi{c3\(r&R@S ."]?# OibktBy! s7g1HOtiox޾m(`}Oo$ yi(_Ҍ(?_I^T+)|H#Cd L R'm0Q!2t90`=hs >{PЧk9Xt:.w {^bowrzyAE&\LsJw9?+QaO86t ]_ǼTItJ͓ʯ(7_j~O_*Xh"Yr BzbW^ ^V{:|hGWE|4|)5_ReX xsw!sܿ~_΃/tac Ai =\MQ ti֥AT|&[&PNO) &YO<A!,xQ4@o-zh% et zZP(D+)x2+(!7p }, 1̒lMҍ quĎ oJ%)4H_ .O/#>dP,@o6iCW)bhɏ{.|ҪVDpL;s[ykOb'9ԋ &%|_B);Q KVqQ/}jCLRx#Xo%”a"b~՘B%P\nK<d0H0x d v3:^v<#;jQ4~xS\BtO;eyO Mѵ&=T/ ##~ |{4i.Ǘro7/Z:n6q>7Gm> CozҸ~s`^Y=?!EIy9}"%>F%=6ahݏz7L4t#oi?%SSvF@VcGZǓ^IkWDglrh$???o}EV4ц4Wߞ. Htd =&{{` uUȕki1%p1H| 7\46c(F~%&Wl]rkڿIO)=@[p+Tz![ MtLN)Vp-(xdj,O뗤mg<[.ʈ~YCzBz 1=ErHˏ_bk)'ez~Waݏɱ$ҬڿVqYe#F}"LmQs0}'!獯 0cV!r3ؤJћ6QWI k&BڣOx @:pֈS!b "oh|{SVO>\6FVER?E!9b3Qc42z[F^0q7AQ `Myx~!ޣ^x.8 _0xia= x Tsrp']%e>T}a,޿l(,˙ώu3mx&8DĎNo \ɜ(2}({;~o1U k@ V~Wշ }Q$.iÛ2"n5&c5xx|RG[ !S(l_*S% sMJ_It_<9RAK0dcp{D0e8x$zkE Bʼn#ň-}|$e=>9lG:] ESLI~F)єU4ihY\l)k{%V5LEjI*|WNgpnJkh:*oK"?L"-NbųyC!j$|pX&R%T.kq0`6|DoRª \DXPWYu O v>n^kĸE%"z_ KEJ:j1RzrI2LX;2nI:}=1zz-wlOW4닚72~&?Ęa|#J|tNk]}gS/ nW9fev}, !-'?~fJY~*O3[F?~ad6Ξ6i:}{‡ᔱSI|ʶEj.*/*7-(q3 ."壊?7r?t=^Gg&NrspFYۍmajOܐ ]eJrR|a'|z+7ChfHr.F#ppSl!kHd6 bG18+ w( 1Ѯp^+2dr3]k^=m(5*uDsMxjW;[&׼l)uٿ".0?~0-G~tOGj9@Kt}_{`th[Z _)^ njpO:XY`*URNU=WʜB3>=!U*VЌV.tH'$c%=]բL)ѳ1Ad["ABIqKGzU3 "|Lz*8+rN6 -[~>lhn<6œ6ߨ>Cm A3->?%жlٷ' S/0CU*~< Mχg<_9G[Mkr0hpתD_;] b}K-; Ugy̢L_*ݫ6R;|qG4(ļ3}\y_1hBb*q=NUSsh\SScȤ'_z ^vrHBe6- <2}/9[M0(Vlb!Tnt cc_+<{Kv`}ȳi?dF_hPⱱ0RTOs@B:[>n=F5f%!+è0hDH_ÅЭ!Ru"b_"z0/O-MS糎Wݿ ʐ O^o/Ct OLj _IMDs8WaHuTL|4<'i.13 B D`ࠥS~)>0g 䓐Ħ?+}.N!re5P7,E{>%ӷ2^i3?]wV 'f>ǣƴ~cc߇$x {B0~Uڟ/D_.ʊnoyGֆkL7E%tcCUK gB㋟<7U3Fq$e MկGQWR:M"_l$D+ry^cp)ip`/b6Ӟ?;HNiBSš[;&بOhA!:Sl0Z@8P[J?d44 ;bV0rFrVJ#Bwiw#a|->liJ._Q o ՙk;,d f 0z7l#|<ߗl37|g3Ud~~Ud o+rAy~ X3~?i,YiUf~'fn>Ĵ?x?g}Dֈzܠ|C4<}" AɃmo(AWL. C#9?W>θ O#Ơ gvƾ=&h1u^权rO ï&Vh1WP`ڏs8S'~|HSyjA 4N.5:\>L`݄\?~-d8v>y}*pnt{'P|:_<~xvD2~6^̘ؒ BM~?{0u>iM1_t{!<8%yͿ˴g#pq9kBjV͘_QҒ>ao,Fh -->7Dp7<4E2gK=tO)[[RwD/d#$l8?4UL "9DP~ ZIctc#Ŀ OsM(i_Bu(P &F >QQ!;@qyq0Ȣ!6kUj8KSl\P5(\o*KOUr!D5'|dI%LcGHM>!=q""h4vx󧱾o#H+W];Urwkfif?'W]/P=.z$ * g.&f)qCPsoᷩbtG>?$X! |wa|ѐD@Zk6{(G߱x1gI_d"'۶p -foPQg(L#6G(#я\6 H(-kN?n&2y4 wѦB_О& 8[7 ]q$旘ohZr*')9d4{+NA궠fף<#~->hFXaQ[$i>ڇ&r02]f~i/쇝Gd~z*~s6ypxn?=Z>xY`ioO Ag=0Y %g5Mx?p!HHba?rp~(at( {YDgVB-TԺai?H͡+t),"b4YK8??3FK; K\Gk5DM㇈r_`>ڇ_“}ȱ b`=x|i^o/\qQۯ1C*0p/Hϟ *`^>-cHU}3?ݽu}1 ^wkG0yB}:nc Ez(Sn L+ؙeOFCRsR iLv0!ъisa~ +Fav*m⹥77>M03/b<#*w=E/.|.{vz2d wm.*a`E&mOʊ->PJlϿT# Lg QU%/=bۣWHZT]Lk惽 dAG=HldOx x vXɈqڨ! Vj!4~}>\rifIwHW`}B-bA?}&LLd7Au}Yj]ҭdiz*yѷS3x|7L51/n VY0ӯ_?:ɞ{2>HDu+'{Iڼ@`2&2'1 ~?7um;4*wN܏"mlT!gj`[r-E*] BxUZ匏 ^+oIKG.+Yq{t~'ztFV&KUֺO7VFOp]?/ j'E¶=%rJ`ujV-0%*+'?sTd *oA=*JSK9E8)J=I^g^c<+3wD[֕\̄r[ҁwX֡.FVoI "bRj=_]Djm}ue,VCd?aqWj1 L.TQXIvweu+GRъ%gk T֧6٫^1:3$KC[JFۏ Ƀ???qk{ ߲XIzOW $ jzlr: )i݄077p7Ɍ)8m,cgsptkO'-~(iIQ2Z S7Yx.|ȇwB XY =f[P!`.+.iVqs {K~W >wvxD+{^oj Y /O/;Q BW){9)0px걵Ϲ_ /e$|Sx|;|n!k%BL 2\"p'm]&,(p?ߏ?awYw:[!gA /9meqF:㩊 DP#K-=[NpetzQ^9B?ݕI(_c(r918OuբKZ`nzܷ7Gcۓ}5#ٞx%Qo10J^ae2ece'S1yr_LZԟWEnY 98ȅUJ5Ts(PIp#R 'F`MZ2 9k4nH=P8!EG@DY ?Iuš@kgZ<NG&j.fMoʒ'hlE5+s“Dbݾ=5v'0{j{6!|S?#BZe4hRIAv^7At l8R(q,0Zh g+h7jqMPL9[7f8IV]o6Eɠ2 zIw`NDaU4EFcDݕtUH /T`U #^OXQɆѬ_zrŒOR]HIe= (^$~VWk-gcINL@O~ J|ܿP1 @o(VE/avԉVB( h\ccy#9 9&VcaVN)v&`Q=]$'z84NԱsn*k${+q*{MR$K;!Baǫqm5_.c~`WJKqY'Q 'o5_k価88߆57ߍo\NW`&2B8yRT+y!K-ߣ%hDw+# |V6zqѢZ#Us$(%@UqYM% B1Zp!WI9zU'4I j,Y |'?ӭ_O}:ᶣ4kľֳ CQRcTѓ&;tkߨP h@ Fʜ)|1>G{_{o!8=mu7!!>c¯!uoFמBٚij* un*xa>xArG`./7D:Q'N hrShC[s# y3!vGHO/㋧,u{?~ï/=v{ԀʸR]*KVdTċ ]o&\ Ft*P'/l)S>3#jvǻ?õ::Kjݑ"WBOx>|*&n$p˰omIm: kq bMTF~ɐ(AdD))`_L^[cs쟶r_ )Qc;H͟tJz>kS$eG دD֏+b8٫Tf[K~>c[?ݙ/[a"8Hy y|'SS$о2g (w^Uc@U-ڠop_`OtC~^Jh/sgq8&lզ㝎Ñ{dljkI 0]_W_kGūXU*6޻7+xs%8y5]ͦ͋њ+<zCJMJ[văǷ_ش〵n/ƃ3)bε~ѧz?~HmƗ"CAa9R\r:S׍z Zz@9KV9Bۏ{J Rܟ?8ۜ,t?ۢJwY(^:VG|?8\5B7H/WRHlMIz K#VT|HEI *nt~Gzɯ*i<tMEgM R"\FWojx]х^7]*qn3Y-ܴ?T:n?}bMF& c,F& +M:oҘϤӖ.^o{o+ffmY |Eb #Rm|8fn>dn>`*|=qV,p9fYF;X͑jtZ =Tvz#Fk>,۞ k% f^fWٚl#ُvAy!H0[1j2]}ֶ|.CMʀ!4e4NjaqB 8 %Z9! AR'( TzO~?/F{;.@|>o @& 8KT g0>0PJtJ*P"rzQ[(2;Z#S(L;|p X\# gA` Vֱng9 G>*}(rv AVjڗ ?E! O4M8=C}Ll_KVzhCƧw~iDɲ]M+: Dף+fCN޸O3Y"]/եo{:JA+rBgVE-Rx"ʚ]WCXW5>_xK@HT< SR)X"gU$E# ȫCe0O9)E^=uFklwNF_e>=2wUP#i̢u}[Vc6|JMJV!L,#").nIZ6n$]6|56OMg~{ݿt+׻6x[;:Ë*HҞHΒGw#B0a{ا%CH9ѭM0Nq=66PV)\RQ' ^ھލ̊8..~?gڟ/f#w>$MV#wfz- 84=sT9 ޓ~wbAc B^]gUl׽k^M4Ts[YA{3SGx4$9 pL $lRl~'[qwr;ۓPK9D$' h׻^!FI:$>T} Sllv'Rf~~| k/9&+1g(m"Sqc.BZAs nǥOt"}pU&j[eI֢ TYW: S{"QB2Aڜd<=(J})fJrN~>U݇eD"[(н/Smɵ=ړ.JۓUA,cڡ];|w;?y) d+·#ﲼW:z6$%Qf^eh83nf6JaM&0Df{BvfnBmQzzeb1n|nk$'{B9o} 2s}i?)!-fktQF1B[L UMrV${)d]3Bcq@R#Uh?x_J^ |O<۩(%X(???߃ >(*QJS]'qZ9ˣ xM^Bd̍Z:UPek܏k,9)U+5WsRBJ!]CqKd~;^f~&.u~SH=ufYC:%(dm <&*>Sg|0KR#Ye~FOR0=[J)[{u\B0M.Zv%eDe!Baƍc2dOe/ Rx|ݿCa6h ]|_~q~=A4ZJ- A9D>}mjͬ2=9Bۏ~1 aE%[(|:?O?{jGҠ.zOs^]2)GU0"}`jm&LFctEt4!e"&0?4%*ه9!*'ٯM`ǹCz|՞d0Ho2&} ́TT٥hAo_Qj RU$Bw~`tr2:׼-aZY'ThlB$SMp"d#@_0{ݹEA '[VT886MxQ3m~ DSnņߢ^]r5#mRdz u["Dd 퉦g4H/i ] L!a"Hr`sU'4Cת0uo6kc95[`T/_jXސ$s1&3vAKSYIi&-Xf|k`)VxpL:ՈUa0ml\0m?9lQz~nIjE/HĊ߭w EKUrC|yƒz>_99}eOP>@j@FimuЇ C8\p)Da[_?JH>$NoC̡?PG +VQ9;Ź''GUoFdJ_ŇG$-$sS<\h/a ƫCi b&l惯.awJ %ߞ8"7||PEit77r|Ivnސ*t?6w__q:RZoO~^1!OzR}e= s0E~s{*n>DE΋obe+%1ٛW1lV%bYRtWQBՂ (I͉ص?:>hb4O-DUܞ-@ ߟUcޟzG*ѐ???Vw Eβ[ c ~QfC~\]{$Hsۇs{Cظr܈~ME:.|4ȭI?7f>R]s*a Wz`ht<ɚ3}æDͷ'$|>g:[s | v]n옺?xUBۏ8*bzQzԳ}o+$S |7ln.XBMeB"BDn* M|/g?wk|fk*j?8`;rJb?I!h"Bf2O0q+&Kez|Tvٶ32Ax}W=|X$EѢ$Հ#eh :tě;|tƎH4V77iGFI#B:?r xïkYQEK:sT.7i>3i23G}9㿃' lIvw"̀OIw ?JE23ٷa? |` 8tN,Øߵ!,g'Oh8~ וdFT7$z'ڟq2z% u%*L{="/NI{8JV4]s]cDYAZ]z:XL!'b`?̂w,؊{o<vƒN%W:!/@$PW陦H?=z,1Kx'Lת1-/t4*DQ5/">;qt|&X8J!ocHUm?d25J#|@_ z~*ÔCCś̟g $yPXQ$ %ϟ^)$~NYO{IpV^բtn!,x Z_=rs[hO3R$8|Ww M;<0d oEx:!AXo.du][|W7~ fg[E!dјDv@X*dY 'l`A%ghŃ=·׬!dn]H  Ӗư~@|k7@Sf?B'z?J2w- %$0?h7d}ۯ!zV,fFBߟ\?G_$_OلZe,"j!BPWUyoC7pڙdvEMaG :s2 c5M O:G?kѪ>1:c{%[RS Dh l?T! zOQRf֯Wf?p#t iV{ͿftۇQR[ =1/1!fso׻ޮwi@su>΃ўl7o7y[#`}f+[1g4=Lȗɍ1mndmoT{\9k -<}7]. *fQ\M]5?M^{΍//\Z2>0BO_o*ZT.w5퇑iˤiUHDulKԗa:uHq'61'WF`-?{ڋ% ͼ}Z|o-X,BO0뷞KrڟˠfH1V+٫xA9@`۟/cЭ} e ԸUch(~B))h´_F_m?m)dX<BtQ}V"CRZA~c)HHx}Gn)U3l> XI0?/FXKSC˲1IJ7 lYi~!k(9`52l|&[4=&Mn!(njx5&KpY9Jb?9^~NA}ʼibb;@d2~ca8‚/b III=Ea. > VF@0<8>E =į+J񖰐/SS߿B"jٞ~?҈זEm LI3dv e1ذ¬ӟ0+ٶC_`3:_͘HF; n*6jRI)㨪o0rd"Nl O'_ٕUH%bu9J"u> z%ݎ ?|ڟхbzda/k"9'\q躉OTŇq al^bRpHU`ǸBل9V}~ $H-G|peưڇq&ۇ QN0ΘC"ȎwGm?IIQJΖӴ_J'ә}Ou>P]n"(9Dn@k۔?A( *W{0 fD䖸ԞnL?g;5%賽{mK0ϏƂ#Eէ>=??u~CrLVMh%"k xԳBY}ZKse9y |Uȫy ۧ|}>?kEѥE< ZA@r[VEp Pr6ntyd+>tzQ7YNv)]򣤇\obD d@+۟(.k=v'E !"a|t3M/P퉹W03(V4`){"*EbO]tZE_&ٲ*Ɨ}+JƞoE v IN4ٿrؿ+z`<.!_Alvڿ$=~f Ah~Uw5h~4& 2 UdyzvDsy'IQB]H?E&u7:\I$8??=>EH{J3s.Kbvƣ⨬Qȶxchn%UAy$vM ]fAoc`6IڷO* sFb+N.65Ϸ)g oS!6xBs+i! ړu2kݲ'r;Ё}eimJٵGFVQE 9BXjaFN6FYD/3̜2J>.-u?{kL8Ť=4|66ړ^oʹ0*m(bi-_iPG'qL>1$?Ӿ>e;Wzڕ6*u|@W)˄N˩z?)W)O OХ #JpJc?gY??B?c۟DZ*ʒg*u鋌??)VvɄ}FC4@; X;gy o0`t\RLkq9rsA^?G0jԷBMPI"||en1x-GJNјcݍ$(] s秪0lCoj@W\*;UaowP~kC2JbE%Cpa-X [YI%ɥ@m<@ >C%aXjWRL-S#472V?h.+NE_,C*?}ut&_h?g+f?&H}b%whx?#}ôXۆ>As~ҟ9gJQdkbMx̙ҵ hl8 ($ 0{r_qmsnm{\Ԉ gPm d/Z.gs:U|ǘ@KJGbu[ya#qii롵AON2i> $E?/S9% ܯG߇$nRrRl~ ' !l%:c=E_gseݏlc^\`rXtBFR0{-CWw=^͹f Gn#vdAHiQ#>®S0aCa&ZϘԟ?V^lԖ@y Tr]sKNh>&f =Go^bD(?S嗢G8[2~cצMv'3@ѯ<95F ľH0!4[a$#GPǰYضo'v Y0Ѭ~^=w~aH_9>(TIdEdsXA 9ۇ7x9@K>Q ̇m{2I!`l Ϧ?Fs78[( =p)7,R KD b R="ؗq/a@{}̇^xt@E^JӴt &MOZϲ~Ԯ/UBOo/h:Dnsthm|lQ]Z1hm7u#8 _ S|L$d Q/[g7OG,ϧcv_xa;?0ִI=i|~(rwC< *z]0(/tz1N$;an{޼s?ߖs}a~[>K[oZh@?ΏG_c _3b(|_`{IY!K3}߅ Γ\KV XB쎤cSS60՗/NHVh&A0yxzP-Kc{xHdy|i*kt.AI%X(Hu3` +9ʊA /I5̖d+P GxE:!؇zt5%S|{׆2-}?XxZH4wUUQqd#}xk&7bȓzK WD]z#'9CהB'zEǠVPIp M 1-{FWUEF۟M/{>?R&x!Xp?ec2!yP 6ZdTx=?P };aGFI! ވdCPh>ݣ r=~^WLLjY/ƋbS1[+aޞܿzxy!VAP!keRބ`*E{Ϯ[%Uf{B$K1xihJ"i;7v 4R%V*{>%z\__YI Jd{L]hp7i/LW 6=0/n @~g'\T_Uһ=>'FvޟoT1L?ǧ)zwM?\ twx#*;N(DGM3͝Z˺R(~Yo߹gm#A}_[/ԞQo0VOo/Kr~kVD|Om/'G*J ^Ms=J[s%nZ∇4jĤѺVRh^_G?֎1ΝpTZQEe$V *{Rr5={l}x)LSoՏ\Cå `Tx#1/f`MȽtޣ'镜 Z/E7|[`^$heZv=ʕ7LCnƒpݷ'[;ٝd),:/3*í ݿwfRknBټ7Wx. %BX1WؿںL{Y=r0!yE&&zIOi?dGS~DJ~K g>guO a7MJTJWþ?Y6B3П3.F̙[)tr (Tš^C"opVJXlbIѭ%P]eۍSs_(]\.3QnAGڗO՗0??}h͎gc4ܫx`Mǒ__H=AUMlNe0;^S*)|C9:īi_WN*za+n5l>_*>F| F{PJjM, ycxzBpEiCnU#…#SN). e|K[0_jnW55ͦgwl*zیM>dL|N! /҉aSZtFɫ{m,l]ۻ>4OI$pH)RA EBTphQrTK !"P);8v`6>kݽ3u~o]aF{?giff~1ί5ݢw5VH8[0 #@0Bi^*B$^Bz>?>xé%ׯ. 3h U=a [ڳЈ{{nlX?#5d)$*iУ??7U*߹֢ޱ8t&o'&I- ׫}Lx 8&;W@ g|Fu;ci[YIł/tickYA!0۲"Zx4OcfՈVw0pF^D :fH}[6L:me0.#G4#WqO9Dm! GN3j[B7qV^Pwܸ`h1[檊H~n n9~3yjk:7(_׋3bV6G'*G6o!WJ%` F!_Gh77v `k;\#u+)$8!swlyPzD/E"mAteȊ\bj'fİ{ƭieܽ}[4LlKZY~>D3{a (GGGnK`qbL<y0] 1eJwk#nsoPʈ}%$ BH;/ʧ%h h; 'O (Ȯ7ԞTs(J-ySV <_ֲ*^RUqG'cAc%Wnx>!l2Wa ,ZX'yqt5 ֥rRYPX0sf9 %cc*̷'=1ُv[ӺOH2??M$/`OֽӏzO ENl֏kFzQ7Q7!+}tP";,ĮrΐE!ǝ9Cq ='Hq$ +Z}-$>H~\m}Fuanj齘?eW}?߯G3>( ho=.x$grg"΀X05^z -/xfvQ×9sq )`Ԫ9^=%OShc+,w}>'MO9 m'AԨ^oGT'(wyg:>7앮( D1},]W= =![uP=//bjOL@z|s?zxw8M׊:RA|MF&25TPYHz<d~S6^y%8\Eʸ?CsAJ3+EeV_W1z~:#{FoϸisH{}k=ڞ=ͯFFFGG6FS<[F|fc)T")e]e}PVF*jDSwkrPˀ!?x(g47 ~篤>e!R<~\Ϯ7T,٣A]A22Fw$K{#Je=x^~A?p:tv_1v<֣iGj.׷+3 a>+Z;~~9oͮk&.$l_&?$昐9Fx?? I|zFÞJR~!!Dz-Q[/,-9-CA;pgw{:,õ =aNe {ZcOBadO`xB;UXXT{GGP@2bMdz= ^؏'{=բѷ̌P$fmTk+YSٚOtF> )f\ܢl1ҟp3i矓lP)E !"  rRDcn0:z B;['[W_rxUB¯j.@X Ji+֣#i<3J"'i W8z,dEуbW*_a Å!=+諢z{p=]ogOIv=6g 6FGGH ^wIR7~vFеbp{[V7KCX75hCw~Gٚ[[I>f>NkLJ1xxjzK@4=,"Ôp' {ڞӔ=}왓1k{:3 iƼ&{:ٳB:jKp/{FGGefѷ|Cu)nӹAOktKL83~(>-LTd5wkw4PX3j$c_>vWT5Rb_uY%/ q~`@BHoBTtl4?!' QQK[OL'KEx5a-֣2 _t~ 䬲~w$(I~hn)kW/Vn>rSՂGXߕ}~ܑ3dUH}F-a'h@I]{-p9< Dҝ]w;`'4mO q8!wӪ=s NH~|PҞWi&|]sGGGs2 /?ӉEC_?#ܻS@;G]|D)] ҷ>|@A@,%r}¥"C| p@Ͽ~D~mfzpZޯnyDMsد.ϖV;c7`2X;RmϷϣ|J{Zdtp|oAge \=B9{Z>m56KmG)~P`>g+5pҘ dC\m~F@W p {/.0m=iO@$z&b{gXH,+ 3'lY QeS,8rGG驏Uf%;"зe9~х>EGCq ,w_w[F4^[BxŘZʟ8Jɫy ;߀$$gjHu-':}P?ZTu/sK(#k6BAFDŪ9fk4vLi҄--V utfV?3_ij^JeF~Ԥp7f<2(E/ #"J_1r؂I,¨XlY;pSbJ HԚeO̞\G"k{ LuZ{hXF v)`V\@+dFG~wd2竃uuΕil߃!"+}F5eh3<mA6+~ g­v֙ ҞQ@ ftf`ȦN[-s }H_cut i|~4pe^:H*H3ϟ~糫v~Z@_F'(\+e5ևF+Su|)7xpp5UwY[WB?2;6jSRx4X$4YG'λaF~|Co0'62 \t {jOMnw9{()($]3$N\`>#{b>sFs`OwW7lC:"fGGi/>*gI& RDqW) ' (C`T}>.]Mu@Wգz|{χܯCMQN.чȅ7o28K})u~/a+Rk BǞL~Y:x_F# ҰN+;vq2f5R|>'.Cj8]^Q)t6W,Miu~UO7]vɛRi:HUX}hbq] 0%חΞNyFѵIo'nؓʅL%IL6]۠3D`ZQ! Eû~~*Cް5#s@c]bMШ9aF@"5Bc&_'dkW3 I4TƷXDXmLḬwKdG"k4z%oJ߫~翚DBN;YcZLaЁ.kYqh&t& b9#D` yBX{ `)V@m;穾uzOW 2'2\֜w<8$T/|+ jy12f)ʞQ''mAyBadC/@Ƣӏ왙/?'ҞVYqɞآ'xY= I `{ -A'D3Ý s H܍"TM(Hs>WȈ( ӭ>?鈑vC,%9ܐVVG&xH+&wz jC*H7 |f=3Jvԫ55#"]wA$<_U odHbu[A40!& I~A$Ԇ&PI?]x,~.>hC&e!vWܷi?Yb%|Lw?|<vkW^Z{FsG0X}~~aWp3ߗ;̈́t`>6ZQ/(5nj'5<|04K8r1v>?'N`劫HբyHw !'-5{߯Ω"QН)~M ~]wpԜ_V)r8 S/gpn?}3  Xb(_DM9t%5‘LdE|Ajy}"ۓž*_X:A K=`thO/]*ݰD(2{֞WWT訔_SM?lYzߢPBzɋzͭ.C1GYP;^t+_7iʤk_I-*ďzU'G(GˆZ'sΝ%g6rR?M Q?n&Q"/`e]ہvAR@TOJx/m>(V tüS"/`6/vQVE:n ZA|ˆƫGj9n%)fCaIFO!Ӟ0ٯtR0|eWw(±/Ẇ\IM`@5_o?v']e<(͆&P -yzt~˪@yġ7X+!WٸqC9礫75_l)!%xL>kr{jj(*ȞWH@R6Y d9v.Y~ b)\缢W+" ]3 K|αsZy+8uL I#imX}ޤփ8,_4kNlڛ-D` } 8Pm/beQ%MՉ_"1C{dI¼Iy>l2J"HX|(IGŠ>WACl}-srt}@nGU`/7 Sf+%*`/ڰf`4)vt*!IYw%`҂4icwXIX-Up&{Ƒ=CqvS" =Rʜ9~=$C-Eͤ=1gܙ=w+E)efQ+10X?)/(L6p+WrH |o5"]zxI}ٹ nNNWv}bAfC/Yу=Wk }bAn30 fmGPJs@;d,J~OBnvQ?H[kY>v0~Nfr1)P f?K]xN nYv狵כ%:yt_*Kk=Ove% Dv*z(m) i)„Mw|qGE-|Ih xݯATp[{Ξ=CLB1`&{'cxb{CYkϝFf2FGd0.wrw|ra^=-=B52Tϯ9n<&&xܞ ؞VCgP=]bO_wnT,ё-K A*aɕ@h [8UuD0.YĨߋ6H?N[?m:+ ҽwfʴŒQ!( $%B%x\@0[(Mew$w"o)7\fl-6D{qW5Ai9hP@X X?hь_B[fz]~C%_uU\}5 `f|.k}`]!IZF~1[ŎRb{̟X6CJEQ?*i;_h;[?;f!jp=VS9a(ΞC`^y ܅ߞ_ 7vV>X(0g@@y0ҧpzx(hp=L\`>yG jbՠNk׎#Ԍ\nE#D"n&/?<_I *NpM*>C*= !Rn21@1Cixj"hBj t+{ wfOml {ZcOv>^t惴ݑ=ݮjK[/{FGhtTJ}ӹbX^k4BQ9O# 8?J& O1h64@SAPCh+}ܓQ# Vn:N_ׂ2ZE\ |6 0B 7Nb>7!q%F4gD3s0Ypu-q[}x~##Lß (0_d~L ]N0Vx&5Atq8ۭ-c;F\i^ K{,Prw 2ƃ|iT}]W{dA5Ũb +1<7`` Bq~nfW]az!Bt!nr\gL,.fYBK}뿯]dM>6χNG^~K}'/χ#y8>!O~Mv8>y>{/ٯz41|kЛg5\og/{Vt~s_me݀~F;+̇[SzC='kz{G!x7]Q#N`Ńg:sH"?5o2!m( $'3О91 Zl3A.g!{Bu~fG9?MSD{ׯuWb )̡jI2?$QbQIWb:P5Am&%TESo$J$%h1Dww:]qH/ǮJb&&a.#;AƢK#HA;hG~g&}#xkIP)2jg;HZDF^!+P8 /}}C{ByэIE,Ba;~ӟ. bx"J+T02l_@䄳4⥣Afw˞. {ZoO ́4vGΞdIaOnfbaOh e:?q}a<c#rX7q 9M}ݍ( 6kv4Ih9Qqr|ᜤtCu$e{ˈOr}봶^qptz|y|TfNu!~un[G7{1W9zȖRx~$|~d5 9~ygt> 萓s~T)ukizo8yD8H {|Z2^,-LCgq=_b! ʞzdOSgrtaO#{o- ) jiO;͈]_rHbC]Ue)W՜v.<*A˥1].ӯ?گf<]Iӯ&a`޸=qjNHI}m]esoNtvZ<$DM\(w\lo/?"뛚*<ۍb% \~+\m̎tq=C1~[e?yS[aC43AihOϗá~H =%!we?`4UdDדzwty{F_m(ht|쉃\2{}L٥~˿B6|HOҞp4n>yUM ˤSTFGS}12 aQeQP\=#wz=2lx_b=B"Ywo'氳vWm2`Hi.^a%]H7F/˒#.EKh1:E Ԋ ݷam΅cyS*؎LtDlX^K̊'m5`F5*8({7jy]ޡoX_[}ßևɬtY!ޗyB:LÊ9IJ"Qt- ~gmѫ%AOAPmOcpu ^z㷔168ݗeExmk{FkO0boO?]bϸ؞R惲g95Y?\)3={gQ %jeQѿM:!bIP[5%ݧ0Le0X A >0~ɯF u_ ru(GnS<^ڥl}<]/?5m(:CE4X]05x_\xY7*#\?Ժ 3ӤyM9(<PH~a~~{~I mFca-{P .b)R-^NBCDu_,V.'IB{n5|=ݎ.kC4{œzK{xlv|?tU9yUP|ߎ}Ε P`-AŐ'N[U߲GVKkUBeDeXFrϏ i▴Q1d ) 5 HpəBv4(&z[1;zpr\AC%4{G|ёWǶبmVs&fZٞQ> PX;P*c~bP#ٙ$Go[ _)z;pFN?eƹڲ&}=Z}Z #yHh WƉ71?2+,6Uu,O% 0J䎪@=vGDX e烧0t|zg*/idhSiڞ8~gޝB36xۊA'>?6A!YC@:P1a\Kא6B{/M#{[D\ybSWA? 8NpUq?l=i #_>`>tJ|ޞ_cG_h~Psf mϕ)Q'j5YCqcsη) _[əDP.A]Smb0CqW ?G`h S`Ȋ Α-Oh8/O ,3h>Gg܁i0zS<}}s_[ɚyZ;qR vujH/Ǔ v?1nq:=rak!-rj2zHو4hIojSh>}7g/bՌ<"n>Dv;|[7ydz~FPetQ$vi0 ]ZExx0nlMƯ[37,`Og{= ]nODp=o5SӀj[_OSz#{񻉢\ʽokOYiv%h9iQ+U*#IOE v{`~uhPӀbJod_2-<mu~`r\O){Mf[) *ڥ[}Kw~ܫd'3 7܀`{}: ?0 ~~Zr}\`@\^ '>kAk߾)O:\֬ZKMY~BM- j>(گ`8lt+CKIw[]|`< W/WpsDr7S?\∗EI4TL,AȽ+klޙKB4s$kb?)hm/tگ$ڞv=WL!=2{ڞ} EI z^zL`:?=*w=_>^s?&,qmP^0# يv/yaWlO7.-dO?gmV;Ҟgx =N}C\bOrĆ mO~>P(^pn??+$P@+IZW&sLNr$Q ֆ. O릳C $_I.K%ܑaJtC-^/h$|}6; Z?G&o[;~ +,(B(. ͛ba>b>1~wLa^^7`z<뽛 o/;[Ϭ^N=uo痚nX47&{4ezx~?Qmq/0VhjpBwyWsxY*e9JQ"gw/5{p\ $ ʾٌ'i+Xv="{0<{JPt ??9Ut0-V?f[ǚK*<8_9n1G/2 7Bko."v-'<sLd*dQA o!bn4ou1jړzG[;Ϩ?w`hzG4*oo&+dQ&D2P;nj o ^[yzPKfV$޹3#CNtkbԫ/T'N !v1 ucO'g{. \#3]'=Ύ,`{\VۓlOi۳ž.>B?}7ackm5}L){|S2! "AӖr}>?o[}Z,5顚o?l/JUE~Lt@0G 6J_6=p97~~D K6cí_{Ю~~lߏƿjÅ{3k"z=6kz2K48| 3n~,{6V XܒZl`OBOQ 'c olNt(IhU=Оvk{cwY=q>Tt)" } {3.z83z{4Xسq?/'N–!nHG8Tzs8D <9)⟻\Xi(QO}(xt^,q]'K VT~h'i.l 5'w og;ބp s% lEUYO)y L&@7qQԈQ[[ e9I_|; ub LEdw&.~ҀV[w@L尣 }k:_/`c98{:]lY\'ҙ] Tߎuh#6RM(;Ss8/=87:t&`(.Ix ;ĉz?w!Wh!$~^fnxlO"mOE]=b{gY4~ p>vdXi~ZcO8=!\M4 V'[|B_(z;~47sƶlv:UvY8DjoZwzIfbK^QX F/g~n,-5ᣪCPavH7@.%󭎟]jB[3BhE ]r[CcB)" Ɵ;blk}ZRF|s+qL*2^6BgzS!w 9T'wQd@Vhx~|_1\AWEߊ (it:yts戃6EE𒸎}zw'RHܗ/w؟x J؞QS{Z}EtiOuggO/8F=^\%f ?Z`Ue+| W[;חرBhvjHn)ZoYc N~}ʙP6Iobo~xG^`,k}@ٍZ>@{n"aIZd,;x za#7 TkpCϠU㮨'diײk)@7}~i>X-T F%:kc~-pѳZoϻU[_}Sb[nmE8\G<VF=h}կ\_4z+X=y`+XM'=As13{Omy<n9?_U]Yb0Xv2?Oif6tea[@2UP ԏ o+{Di} Y )2Gksk (ZvUyjQFC;R3lؚ(+C̨-Zj v[ZЗ!3]J1ے\49<9@"a y{O( t^[%Ku{K3bnN0fms^ Fg3'Nq.0 /+P|hI=or>\fO=_V'4|8=H]!yF4teGr2)_{:POPϣ1 ^s̠VʎPA.6ʎ^_fڣ@{^S0E[B1,"jqey2ݷ̨cz{Fƨ7C}z2eZ(&]"`)}Nwwekrne*Qy zcAm\$C#Jp=7ktc 4R,X],x$`!Kn>.CN< |Ka ߅]Ű@,q,seee.%:_m+?׽[S`OWw9 wSχ[seJ{c\:{6㿪bq+~~y4+ϘT@CK,#^Zep^f\\Ԉrn[Z?H{M)}٤}"䯟rb1e*Vu~t=̇۽/cH~1 pPdqa$7^:oO zO8hE~SRWrLn!K _M[^~7:wqHVSn52 f1 Aν-XW`BǃYx]VYQCykGyŦ =>h텻_9/ Z Uo`O?CoiB#"=}mOJ)Ξ N {>8۳{8>/3ڞؒ ;͇*)0/?Tӿǖ:UiK'v9'ʝ$,O"5nA\j}KN˨憎[ex|&A \mV6L=8m] : Zu?g2(A܉F=WgP!Чtyj_dBD($B ecvv)d\n[_y`4 ,%K׭2zLQh"`AYWdQ 5'nsF4:m(wI74wVJ_b1BUcpSΗS5yW9 Ts9d LuC8?Р83mSGM`JWX/g\bOYV9AiY^p)"Fiv=2{|XO-{}=-.gjO>Y:Uv[Q?TSCkέ $ %\–ߐَ7xU\-g7摾cѯh=WEWg&!Kw|,Ą!^qF t@B'P?'wt#-? aP?X?;>o~H^ sԗ!W^;m6_ihƣ@qp cOtu/ϯ -;&Zu^Yu#^rᤕ>:HTۘ1AJ.Dў}bK /퉜5$=%E3.'(؞vhO9=Ӕ=q>(mOC lo-󡟟v=h~Z3?mfnoϰ+A?.jIe'> 0c}z}3`)}7cͩB>[иJ LKcȽ h]h158]ວ(iq4OhOwoo&糧8T}~v~w[qfsԇ IAԬeyJTRPan e4Yh YC*.$^;OtB?ZK#o֯=+; }3_ne\8MyڴD3S栫s h;t}}!? VY)z '0y^.S2ƞ7ՎѺ8SY`O@/dO(=Xf>ܩ=7=ݩmriϲp8B7|(yF)]s7b_>>|G//~>O~?ߧ~m{d޶cH'n{qճ| >Yѳ{ɽ^Y}޳soI~X+nµ郂]=v_Q2,`S{ #k'{{_ծ=>4thW{4nkς9ݎfK/W_W<2ߪc!Lg-t\xxZ6y4%g pG!{p|:(ɏ==^ npiG]}~?||_9_//zѯ} u=~.[T- X x ߮:랚زj'xoƟ-uocOŲ5d2?wUgz['~ozhΏC{}җΗ?! aQYd^:;RK~# RR;D.0@A$ T>T?c{f<PCCѿK|S{ۿo##########w,_~^5/}o< y:H+1d3ZAy E_뛄pUj/`cj.'Gdehoqѿ~O?ݕ緽ů/?gd3(4Ÿ?/`ʍV<_s1⶿c{ O*{ABF6Fol>7U?ַ<8񅑑X/}+?^g<=joEefa- `53tHï21QgJvG4F4X95~Оբ2=sWr=~dGCXSGbdG]G/|>8,Ͼ瞯}_y^gM6ְB[JG&w,D&_S_ _/ʻɸvL-ȝj|aeCڈ[ڳ@ FlFcd~߷uzGFFFFFFFFF>{C_~ٗ>-[lZ+hs.}Eg=%ekX3thĵ==eL@\}>`WFr||x}|ddddddddd %n[>~}{fk0;b%@ u (tG;O7c{㷦\B<Ϟ+늑G*}{ddddddddd .g/{v#& V_&6 KRh3uYM`YCGy<'@Dv|)ӎ`o~q=imj1? ޴ adddddddddI%W?ݧDj A[<Yk IDY1єF-yi#{Ѕū^RH?M# (¾??{l##########OjO+e/Dph[,[Pd?_ `*cda0c.)ٸ̞S`ىTm,ȞD7V~l?CxfGy+O~/o @O7yiзDݗH/@N5 #ڠCwjaKgFy=hH6TI?m/Ƿ|dvᑑ|g}/#_Eϼ{}ϱ @%A$Y8=hv9Y74 DM E0EsH=ӀdaaOU; RđO:n#m_WЇfy=9~/ \Z6k q!T!8K^}D$V \~yoiO~a3A"E){ST?bc-U?CկB_+_WHh9np %?1_8 ,/ |]k .O,:5}Rt f97"=癣6-?5#_[̷vdddddddddi++į ݑz"{+'_M#0A*y{w\/bO22㿥=wÞ PFbZϾ}|w-|˾|/ K_tL4Frv҃PTVܽ4Ht"HG02`aoiO@7׽=O ;ENF!"cɿ|wC<2YyuW>+gw3rpfyDuWg^D0yA?$ O$S kG_W: J' aG_OmzCGFFFFFFFFFF{ү ڣ€k?>: 2ή;g,oܱBx T@Aϰ=Ody L'>s1I~-̾92222222222r(_ʯz ]'`B<|CH&ecٖ}Qx R)1 j=94ɈjXR?bc?{}#6ȅr/s_>{@&xOivĻQY<ݣ¡(կ:3nݻ6LLul>Dz<<p4@SpğW?_؏~⑇#;۶?&tz@|R뱗D&bH^t`Pn;9,P yi N84 lO'{)a.ٙD\یgX?" ^pafov6'=o<&4\!/{Ja@cHTV]`x_CP!_vާUrVa;1I=P,bۮG}g&02222222222򄒷cuT=qW@STS#Dmpr8[j%>ApGENaD.97phqb^8Cy=ϱkyb(#SX5G3Q&wGt3o'gy={#w];;q ^^SSgz z\a!D ьQqW=#iKd|zyߕYwɃDe11Ne#'71oFFFFFFFFFFFFEz۟=mD;A ~U0JT"SgL`i?8;lgtkGXcpQGJ=W +/~ۨ?ОW ;G3j-ZPӕO|WoٶFFFFFFFFFFFM~+Mx_Ss-eS9SNeDscO~x)? 8e]> EA;gLd @ e?Rݔ3}{׻fyɯ{ ^|n 7+)#F/Ͱ\PZ$/9/G߅$D<a{$Kw=-%nJ'*b08qn0q*[C 5)CM_ueyɏ/;>k/73 L ß2Ngg(eQ9)v&HQiDcD24B`-t )RHcڈ" ž 9&lbG1֏g̉"m{>١FFFFFFFFFFFO~Gwݱm{@;d?b/H^WG"UID*Ls [bxB#3BDC l`OuٞjɞWD`=#ߔ$#_|o M###########O^77~nHk ?;V4w8זLhKLKYE`fD &J"#4z5cnvS:qFqxo@=F׏'6q^_K'fWyGzk~^_oXOTl[J{UǪ5D,b9S?`qry #?=`fveº:2Dg ٯP19h|aGM.'P񊨬RGǟ~ 78W^x:)3=;3YvB4Z_XV4Fnyu'kvio_2<{m)'E`Ԕ3-BO= >!aw/ƭ#K?"YUii,L5 Cá=OڿF)|?wIq8z;E0~2(|2zM3S_h< ;Y1c1wQF('>߀588l8^#3f8/*ze?rI"M@M |3yD$ KacjV c?oc1c?,l0}^ZgJ/RICX=K o_z3Aۿ "%RbDֿ9"/᰷^CǙ7?]@'>M1c1߼O=NcH@֣}0u;b1c1ǟǟ{,KCQ8"\.P2q0m提g|Z?`Ϊ @'3eAV ɒ/!iC_`G8\OUUC"mE}s?O_c1cYgk/ 2zųR)QR5PxĴQ>L^?&U  hUC,!g_CJAmOP3r$SROWܻ".Jߐ ?zpJoK/'Dc1c̍Ҁ}wd˙;F] PŔ RS*cddC2e 2fQǐRBeŊ-bc`_1 BHRhz{MCe;}""{c1cÇǏg=5- |JB.ʟh@\hLI|֏ƄQH|XQrA~dekg Qc'\nã!?$#y m(nw1c1ͳo7diuDcfAHd DO(JjCN.g%KLLݐ/xZCX=֤މ'#ӎ/~S3/1c1/_ӟ7zѝh0\feLU\e`8+I3r2"s!$e?z"R$gw "2'LxߡIl p&YF"O_~+_c1#N<hLx>4) z0ˆq$ 8r62Ő$?`&9P.K="H7I݌Hry^"uFrcs p<+^|?c3a1c1G_g_9CqLQ avcYX=b1`Lj%y 8Z&MOsO.i,|tphIgW>ϋ"ЬOXDD!Q ?_y-a1c1?(ܿ7 CVU~wdZgE }rAjShHa|cu\sSo{/gsg#$k3p!K?ERf\h0#D#؄apO__B|7/"Gg?/_c1c_>0!Oׁ>6! c!@"0 y)+#Ҟc<=Q*(4x/4/)2ߵ佁e?]0c1Ƙկ׷Ȝnw_Qsw`w\2,h6r| 粇$ԉgS"85cc1caxO|=BtW3rþaX;`ُҕ@ (P cXHm= )`FTlaHng7 7iXDxFpZBq c1c~x?grLOpi0KS@u[4DOu^g975Bb/yKSJ!I̋M( H^ΣdAp3&Pюg ~'?c1cQO_{E  g~QtOO-A hD ,Qq7|ŕ@?Lxe3 C zK%R l GM߯ٝ aU8{~y+`1c1?Z~K_z^q\>ѭF }G=vRg 8FqȥXBA$>Zr:2,͗$Is(Sӯ0\4tkC5~CCcŗxc1c̏> z-qKhm덙9\@C@4`_( smb&D !ǝR$ԧl! A)^ՄNmC/UA Q' Mjޛ!`318'oc1~U$2mPU@){(EhC-$.w'@H%4ejX$ y3-s8"ղ(^)3~#5ڽ?'c1c̏?YY3d\ NUmXS*/zETo(qtRof֞@9rx!1Q?(6z/ANX֏3_=1c1lG@;{#'h1aθqy,j'`ZMћ0ε$G`ɂj}R$ჭ+)n􃑲4JD$Bc|RI]^( 9UqvNL/<~Sc1c̏=/pγ(Fq8O!r$2ý(?*];T(o|R} jL];с8$bB L&\/_ͳ9^q3O@P )0 x ǧ5F*Mx-q>,/c1||3j"fnG_/>Xd՛t{ #tF:C[bg 6 e?PA %;8^T#٘^h mbY񠵳?{_{n1c1O_٣%hr= ǰ0HN ,\(H(&'k~bhbHUa=IC{!tB8z*KE*Rg(BM?WOw(cG#CV1!g~W_y-ɍ1c1ϓWo~?(qkGi32AH6dv@'.fmdY)@,ˆ*bGg'Ȳq gJG(`::D΍#~H90h_7^z>c1c̟??;C4@| 妳p4׃+׷> ̨"(LͪWZŐK<{J Sqg;p$mlO D5tEx _|c1~+ϞM Tus=l8nb  NTQz ֛dKE;rO8ALɪ,!lьMhBP>9P]җ~~mc1c7{1 fgAyˀGe>w=paV3n"JQL^_N5%HЃ"4adSɽ^>"J la8'Z瓟c1cb;_v42du!PϏt %GLa Lb[lEI ԌL݂F$@d0ċuPsch~-no=5g~3yO믴1c1o zAF.b MRSI_L2PmjP2CZҏ7 N5,'xb1(Wf{KDHt MPz(_#1c1|_𨮁Uԣ䬨M zT`@Gm`hvyX VI5_('(0e`( \'" T[_OEm98[>_c1c> |w>=<yxCRrC LyG*=HX qor~A$fB.7??]q8;lC8nq= @"COcmCa8&G?o1c1|xo|QY4BZC6~.&LŘ9!UDMc&?@ށQ =(o]`G=<A?7s[,S^[DFɠۆ`xx Nkc1;gH2WF ǝ 6=P[ P͠ϛ!֌6 @yWgb1z,s3 Uqx=Y#".4t0?|wc1c>lo~G]ׂՏh="4u?"+pJp_CRƊ}M@`7uX||?*pD 2?oh_>̿p[f_Ͽ l1c16^x_:`ˑH }tׂ}`ވάS]˃ !"fh%T> I U6K1 6d\H<%W+>mA:M(9k8srx ^c1cpO (EwA%8;CvFGcBfmgF̖~#ZR $$ٟ" zQXM\ͧe}u8+{0I ]z G ?7_z_]c1cpw/ EnIg A~|JAz86}h4_"@C Pc,F5V3)r&t,uЙ?xA'*<٢hKZcyZ?@4 ~75c1Ƙ3{9΁c.>1j):ȕ>d,}<%A'(/oOP?~>BBńr`{f[""pj9?g4bׁwpUuGLehz4D췞7/1c1|LJKtDd,DP(?4J,A"6)w׿@n0z߁D(OHA'!= 3dH WCgzOC79#]#Φ4>ng0c1Ƙ{9$Z"ͽ׍ yY)j@S2~ *Q ܠ.(L{,h NB ['s 8s1=*#:yXφv^~ c1ċ_{?zw&F̩9,s3oRv4Du,op4@SUYm#ո?26HA]ܳ]s<<A"6Pq4@UBa y45oj1c1~"y]"cwmIQH&ڡZ|= {s'C30$5a QG#>-l$IJDz}P*|l(C&냚FjiHQ%sl* 1c1|@/|]Ke^IHvIOQ[$bQ"ɂFH0$?e-  ;P[VCY;)kOzv0-4gЦg=x6c1<9 GZA 4`)W_qqdÈMӫ13 SOP #q# ۈT"`IQ~ K ma*T6 17սF{+C9B^}m91c1ȫ|{;5BorWsYqbS^kZCf$40{ qdk8em!JŭfEk2pRvc\OKG`D]4f{Bd28dc :[iF~峟7c1c>K/_1+G*7APGkDI""h& !"5('H^(8 v(&0 -C' ]D&Lzzf8Z`0R'}_Kc1cW^ycCDjz$C ?^#F!Ɛ3!Ĭ= >z<]B.g/TO.nβ7Jh?2‘8ѐHQ8#t ~/5}_z-1c1{cz!sOd#d3HH|ԛ_א$Bvh5٘Y: g#8>@=>OwclcZQO||wl&&?W$xߥO!H}fЌJb9NU\vqh i8D"> c1c^|a 65JpJN9.aMQS t )~P˄>X) cc8*Ezjk?zYx dH-SNɩo.lR(0\9;!sP{?]CJ?" Pl.%_iP ӈ4\TD!Ʌ~%'"I2`D򯬮WEivId AٜP֣堍Dཇk_Wc1c~{|rvz(VlFS0޶ёI?z=B*1RL\jDP%ig"d(]>Gei^ɢ~{`y:7tƉSj|S:܄1c1<-o?vC]e8=Ϻ<$#!)jP<P$z<ӱdqB\BxѸ!5,3I^49"i`L\,[_ŕꏠI9>BzH;8~*nSkFlEk 4c1ƘzU ;GaFD"ܽŬPr! R HZQ6;CpΗ^0闠 HcIͰ5;yC^ϺE08l]v ✚8p&\gé6Q[_`1c1Op\&o:wn@dYƙ%@FE1$LF]p=M=~ar$dGT#g}Ah!τUOZ_:o3Cf"$pi*0K11=k@|嗿c1cw޻{"Y6=~.A1tY{*1eJ(8KI]S;Js?!c 9Ezy9J)5rnAH'ΠJ~29fEF@4>Hr::m9q~ Ts2 c1T[Ӽ/#~M# !Yϊ'Jp8j=^g1Nwͅ6.q AQfQ*@UI#g%QFw 4m{]44s3e}vC)=l9M?)]?~_?c1cy ^=+Z~ 3]@Qk5,FSCJ  1wxg36C.}3?"25B"|MLTAdwqu?qv4&bv1z0bF -vu3Ł^?$3&b9PU$[Zk>/~c1׿qklKg=ZURˌ/#0| G8hF#)#''p(3DHa\]UqȐ^,9ƒ/R5:F6&EecpNokL -1c1~k_|M N6*8Ē3)Y+[W,x]mm rCCW"#".Zd%3}C BRtƸQ+F\>h &?("F4v4އ>c1cg|, %2wYBF! k8?bQ-2gKH$!\ɿ`"䖿Kz .JDa0rt6b˴EGX%"%!~AUTpB>A 钹 1~l81kfo@+y<8*1I4EQALЦ,&bWr%Ϩ AHfP|fs{qs3Zk c1cr> 6'f8`@6}!>egG/AEPteտ9' R$xV/1Z|2fEF :Y}1 Rj!,`Gqe?A e=/gC6y|O믜1c1<|魷*1NYa }*AWsVb_R9̣cbw q;ss$9<$k3ϴϋ."| JV݁]S&,SӅ).lGDGBehIg%?z++g1c1O7ݻw }xpFW"lD fUARA6Y˙jChE遘2`4A`zU^M;ҕ*ZHڞq>4ˢa^}X,eIQ8s+t)Jrk`eXA~毜1c1<<;F \dwG}a5}L*!=D1%3a'0PsG6SHq]×І:gV3 `Cq FTбkSоai!"G99#'oc1s |w}4 ճY jU6Gj[Q7H:EɿL5wؕq2/eD<l%G qhGyZ/T n疌) l׏ヌ7Ln8}q\S 1lFĤ}e3c1Ƙy<'& 2@f" 2w<2?A3aܚdP̓<1Ls!7@|.K=R7BF.SX?ƍ:OH2^BbYrw`A"jgc_c1cnyk8 {U(F GuY2kxH&5535 f!MIuRTgN5@ ȣ!A A,=-h1@r,C/X1jր 0N1hPоc1c ;G G "{ӎ"#A[fzrN;!Zd Ѥ,b 5@T󅤙0DMƥ D,ۮI%͛(kGT˺ڹ @ȐE _ x܀@f"+;f1c1kr~h2Q"psT 4{J@rԹi^\jy( 0*Lm୆^|!qW B^/) ,Α3`(5bH< #> @,l]@khХ -1c1x޽&qgF6Yr63+vlr%ȍ:>ߩP Ia8LG)i#!^$u{86SzV5m zGVeKN\LSay,4c1c {02 1 s͒|"kFɏHj tPL' @m jR:#jv)o􂼑!j.Dt94nP]_6RAC_UA69=OGH$ͩNLJ;h|53c1Ƙ;!1f%i{$%Uv5c9pxJ~YZw cv@m l9|JT[Nܓ&&ri[He@BZl |- c0($,Fz x4<=6Ӄ@5 c1s[B{|ĈI pAu/dht`ybKAFޘ;F;,FR$hIXLP CYb&DY )l+8b9@sg܌Аokf1c1 @%fbhUv/;h*!@R_ -dRDɒ!YQߵ~7_E9bOr1&JWy1c1c5^y- FF-P* l#@A,2uM^Nj$(ښl!\=JE'jRuf޽~^67fХBst1( M gJ6g}@kc qv4U c1s{&D6 =-}=`s"$rK@=F:L"*r4X .ۅ5t:gO:54BcZ,1vYeIjXXu&bȰD d!"`c1s{Bqs:}/z!jOADm^臨q1cPкzh=^J(DDJ ?ew h}ɌgJQ}l9̟@OQՋ wi1c17k34PҶ4JYs:!w֚YybBC0OQ/Qv!:B)W-qD]?Lr|,Ciqج/ #i*c8w!N{ f1c1[lZBr퉑_^&GP:2ʐYc=4@3saWƤtz/6;H ak SPu=h:׋C[?8^f%z=1c1!jdO6,OrYT׿<Ԧa#`3B!NbNM( Ue3Dz}#@6 *335K|(dR0`1c17ۏ 2~|-l@F&Pr"3ɔUOch܅ GGzV%9IWpJq(AkgOz\=)~Tm%mh%Fqts~\GoUTaN>.4}"F 8pP"Y@ɩ Ǩ p G,!Jѯظ葿`c1sk8$F r uf [~QAH PVCNǒR`KHmIk):ELLLlG_ȍcHDbh"W2Z9n@2Fezd[㯱KGfrnCH Ӹ Ec41c1<0+m9Wv3d?>Ǧ.URN iarq)RT߃X͠/f$J& {?P[Yzmm8"\8/~[Id7tG1c1mKeČeHq.kRKd]$rYGPi:1 < #),1 y|k̤bIHY(keJe B&Đ8rJq@;7ݰ_0c1c5rXqqÚmf= ` bJ XzR 5T9.,ΎAyY^հ ,[zVKS9nϣ_,WU1@1Srz3:1G21c1ܤ@ѓ5,GVX#V)g͜s41Sߔe9335OPmD,M #$D!" U]ڀP (#ETi8&x!71c1f9 WP9rDH1٤/u{7C !w9˲1 *.Kl ^fEXݧW2&HPFe}TM@i- 2GKHGO}Dk"Xg0c1Ƙ[%gf!k8) WD H/hϸP;J! EJKyeCG)4AͤG֗[H^ۏ>9lFPe+(9`n؜c1c4L FȈ#RQM"etA+<rscB7gBRDNG@'j$>z<"T5 H5XbHZ' %m28gg91`P mi1c13Dw2HM$:Y lΌ]bi5$:X0\z gl'NJ%[\ цCOPbj 3L, ^`tʼ$ @Ri1c15YN!{|! Y ٹn{bKrR@J"die^|r5>R="X(- YhyE%\ -C"c-9?"I/8EF ~Tϻ繎\|WI&Xz B:yQ(S+(M|V1c1~-ҍʇq##i0y*p˟\hS?Ћnnj@P@Αb@Ѓ+( Fd~2.RȘ@+!@ Q2hu!L hP~)CPcc bO1jz1c1ƘЫ 0'G^؅*&y=K=43TXձ8b/01-.s`$C&EqH_v}PDpCD$л0>J3;ЗmF60z:1c1XqTՒiF<#\7&ظhHtwÀʠױVhB8pDH񯮧uv}SE#LJҠGDuc1cJ swL`7 Ƥ))a6 T੊֑"1t! (1'R)FuAԘb]T/\Ye=vC* %jPZB ]x>UHKu^jC9~hdjV)פc1c1789G|D%.;fQe/ki "7@Dlg9+5 sDLH&=Dhyvщ!Ȑ;jkHF,UEA}u"J.O^2rii Л,(75c1cr3PSC:8C*FÔ7fݻ-D9V3a;~PB.F[jZ\^D>!eArFs=DmOb lyir/m"FY~1c16 zy x \bD0b3Pֳ@nQ8\0n M(u8H5ul+r'K%r=A S' L^$4#i1c172dX,q$/vl0# ?(Ԃwv(, I̳Hqd ̾9_;,=P!Wb)E69*C G@9@? 0K/'K-`xIfL(#R1c1ܮh8j˨ׂSp)ֺ6}RfiRR|L]I"bXyB X*!>`ɥ@U^1rR¿ҡ@.O ic1c]js΂~jNI"1PBrtVC.DiH3s=eOMDi(a4qU472:u3DHfJ ?ȥ@}G\_B΢&`pbUC g3Hc1c]GyhY(5R Yk,(@LLdlo'9&tWY*U$3mAZ&g4%sDbW[8âhdfr^-P;UKIXD 1c1CUs!|? E%F\7&O39D!SZcn"i籠Ń>Ն*:p#Hn>ŵ4vqLM\ )dgc1cnn 0j(S1#=pֿ) }mpĜǴi8'ž*%)zqc42P 0yu* IULC%}ahv[\Y?g"P~U4=Fc1cn9%r~ֱvW@lϔJ,3ec&|톐@,^0{ \zփvkBX<#} UԐ`1c13԰(E;YABއqS\'Zʭ-~烖 sτ6Aʠ R KFln=#Iad0m O@'- x͘1c1Ƙ[a.~#cb hm&qFhteRDb-$+Iyu q+ME,m^ jȧ0Lة`ldiJFl:~JC4~< Ϳ w\c1c$YA 1g8Q=r4(\lpaHt}Xlfe3E:Zˡ܊*Fpy6 f 2l4sP=c1c5Pl 4Tb15\AeHʳUu(FX[TE%^"˼z臈qHPC|b|,E>XowȺzvIdzѕ> \/1c1*ɥޫ1CdPJh_wM9'6ܶZh;LVRKaX>I}ܽ>vNhfyvEc1cm ZX&=1#ZZ&՛)lɵx͠ M,D}y޼V_yשIA>suN#XsL 9N}%'v 'sz ҼjaORc1cn ฉ}d .9aV0~M'EiR@<4Ѡ;JBKNWЗS+2%B!O`D0MGW55ˎz=cXk0c1+2ø gsֿ4\={n,ZWnH@  EhB!B V,Y(n$pCףXHޱ< jbŹm:]o1c1Z GQJ(r(O̗pE6v!   Io@qt{|-vgd!P%=EaPFDku(Ieic1cY"3l0דcBPGM.2grRss2R,3r߄mPށ!fp/1c1Ƙhm-roރ(-ҼϔzPU/C_P 8Kb"͐mp̤ d|D2""UJG@$ .,) uH".XmŵKVk9nj0c1ƘVz?>P2H ŭ,hT-sg"r& c?c{n?BH2.SPuWEZ]]:Ű=v}VX~p71c1)~>ҁ&Q"thUy><F|*4-,>ج+rG>d_$dͨ})w7c1s*C\32>ĖL 9~YrFW&*d^eTe$a;ᄈ"A:=qGwv, >UΈ5c1cM2A#!s!A^ y0f] M` ԁY6"tx`2%Q}gΎgBh6$k\z6zSQ͹xѶ C9D75c1cJĨPRFbs@o@-GCudqjf\qiH=Z#wqg8 y+J Fۭ e^'m>hb1c1釒FzeIdIJIGw?DE`1c1uP z#pagb;ʐ7Ԑ\ʅ`n8wksȐ@ϼL+Rҏ<ɭKkV"">s*l%B65{6\Qb1c1 ؄GDJ}8/l2__|aDP4F+ qWgPp (B.Z_Se`V~!=a=QLxIuc1c J 6AfY{bv.$#\ 3bk'we>LG8753yxǚUq(] q@8*%}ՠaUF8:-cmL c1c1 CaKv\pO8p9G:?2$qF# Q:x'F$0"502؂񃭏+ n c1ce p#gۂVc(6 %{b@vWr{?!JPa<9&&ƥ]#`bՠa8dnMڥ1c1+pKR }=1(8t9. +ŀ5_s""DP$ZH?w@̦g/Lĺ~U7f>y}y2 %nl#Y?q(c5+a1c1O2A2eAR$(RYjmB.u15-Fe Df:2[#@S@3ňasEb@HI[ͅDZ `IlP8u2c1ƘۖH-Y4 aо7(6N _lX P%Kbԑ@ ^uR5B%?5^YOJDiT;kS32c1cep<aOeI`}HiYޝ{S0L+)@dD8.ΈR Dms(뷢W= ww1p36G* NAc1c)zûܥF 8Ӱ( \0nSpBI̠XM2 >rV#J,rgWȈ}ǿ!v=u룮7c1s shk 2 x8"> )&X:O^{!p9{[ɂDfNĮֆ"62Էh<=@o1c1IqB2 Mտ`IP9. -jA eH a$ \\/v4 ޏ5tخM$6D_߱X)Wwh1c16un"!W3 ! W@> 8B`dmNz>dDyn{pߚӄ;d'/ w?76PGoX4'c1c14ch;AMh^`&kW!{RBrQh)4zך|}Wbtvu?>h]bc1cn_ƽ1AH} DHK}'՜'-oƄb lyo<9^xutCgfI.@Ś AZ;m4Xa0c1C̊=//RNSƬx } Aыb&0 ly4I~~vRϳ_fDDŽb vg~|Jir?/w(4c1ƘԦ-7kKIo8C.q, PCܼaUʆswc'9R'"P|N79JP3sg(P Wf7mi1c1fHd]#Xb [A(sɢSnlְ85HFJA>7cȐ1c1ƘQ 7Y&X->ׂ3t0 9,s)} QʍtP*$+l rU1~c dȹ_J w: GHИJPEeJ,ic1cMKOW'G@FtI%jt ׼/egp CPSdX#!\Qؙk*Hn쯩~]>b6an1c1ƘKKJVSv6YOsgMb8p& b=S , A,oWֳgDFDO^ YACdzx5c1cqx8Xu0\HdƨsO+X:(tlXNV #ȳX 8XA¾eP?X=4WboN㻙c1c)3Z9_j`vw#@-k!D.ym! H5N!.DN] Vb MH>>vY>~iJD6fD `c1ci8!ɆajY#$hlvB$@:EXmDQL'DOr.Y*1*4JJc9;ȍ{̒je}gTqAX3y 1V1c1f!@ b18X'2ĀY?Wt \v˔n?cc/tL9N}ಛngr]Yim!b0#rWEdV{sA>{BQAKӰZ*^B[ P:Rz05cE̳ɓP[n Y>ò0kV,s*:) B].i_XQQ 20oxom·Dd=&O1́ x"Hơ5e#6R#jPLW:4QC1) 2/% DŽ`OOi)VC\_ I03"T"i]jTچΡ7}Qg ,g󩴧o 5 zt1.@DX C?8:İ]G.dUf~(i:Z)Y6.m#YSb7# ^S$1EA%g{*6m*$+{z %d^V~%Red4[PJ V>ˋl4ۈ~9è"6" rۥ ?x:7F2 Kk7#a3b DhUۦKK]A(KȰ*{/2Neђ#ʚ/VĜquR2L|Cq0 a ozQ!dt;iK%گ&sg+>zC)kFWܐ雙 됁v@d/GddԷ3#uV~J# QQo-?{+)Ba _>}>+guXD6 <4ڨwVmuVkfaAzf+uB;ǻ>]qp\U}mRН|Yy} #O7n { %a㊺ 8HpEpf,H+Uy\ry_ׇe?rlq^_# !d- <1)>^&xob3_V~O߿[Znѡy ˮ"!y3bAΎ? ]鎒>4QA-W#z?K:2Me:RT/CTòp:2f SLsjkСGMq8>ȉaAg.;B"$*/T%tjR8pֶ//eWIBܮ7šzX_HjԕаLsh*˘ pv%B]AJ%bD˦<_f4_aB{98I k_0vϏ>1ig/ݮW5&`Jz<쵰.=?0B&_3,S&8RD)0P;g"LY{::̾QoZQ P脭<e(UL- \kcB[ŧmA5_X]j; QhLv(l*: B8sq,b=sǡׇ ?]=TOy>̜ ^DۋVd:h 4], p[mq`k WGC{W]#pْj+i#-r-s%1 ]${DַD?/$f:1К˥ m;vij{mc'MAr\h`x r8Joȣe~8zU݂!e};E Mx]*iC&Y/1{.RkĜKX.|7Eh3"Kt|@v}ʊ^Im S}yu}kˏ;qc,;訐0Ίn9kyw"{"@h+[< he-1%Q[]*Mc%Ӄ1^`QқK$U6,gAc@ɕ?#eƍnphgm}5&Ry\/j)JsZ2"˽:k'1CQr 0Ǻ5P2=z~ 'ǃe yP^5[jjwtn##vD13"c܎GrVV)zK { "'e4,SKO{AzkUsL'_P/ՙf>X]&䞞>GEDn,l?S. NK8z{'B5C4T7 DTTF7}ZF+veϋf#d`d`&:Hާ މfjV{CԳL2σ)5SB;u$qؽĴ<\m= wrK/X-y~ m[", iŐVҡѪ#*m?*zKqxYXEkމeƊ9R-ÖY2Q-c\y޹^e(2dZ5zv9~ m'lt[öVWaXm3 CR*w2kw:TP_}  MОr]X+F>ǥחH?/ !ɸK~hS/wbܐ: tp'HHW/J$s'I^]bh kjڿPjr)񿭗_7D1 Rc=fm\"DPI6=x®7 /iO]hq9r$[fQc?K=ϣ%bXFKx=>ċ᳾hr̵]vB2(!S:q)I߁;IC %5!qՔRg脖! z8z_#?"A/Z%d\t4YaSCrW/e;1Sjhђ7g>=9Yv+;AΈ}71r8B<%Q k8է{"."Gk@]OI\/<ۡK$qcQ35hg ?뵵]^W)v% 1u~k-B͓f\d@g{su"=Z{6 MU@񌾝# V%*H_c}^{od $cz':7Q~}4Jfj>. L}8 qcjX$;翟6Y%I|"M(B+>B !̜wk3{rGe122cuܾv(CB*%0ܩ1FExZbD2jP¨6Q'#b6V;YrֳvpqjXreiGe>f#hٟ^m[De3JI=*T`lm'|&"*q>Am Q=4>S 㩋A=!,~_zy k8C( wlڝ~&).6}!䱺!K.aC;H"$9џ:eDBΗ:sVe4Xк^,$^ 9zo y}? 5n~ oj߯8f*L:<0_dV >}/bjBW/Wę_w Wn O uJД_wzD3'Ƃ91KHy?$'z5$x]]( Uvʸц#20{!CL?fVWDK'Z:GsNmoMnM uה hM\?r~l_8?62|)o`|ҧc3K6$x_(OCuy/?,]h;\_splsxFr7; xSK񲄁W+ˊ΂\8sJjc"W1"t:a_~:~/Э[QnysJbJ  Me^`] ꏐNmv #2BN)s ݏs8Hș,ZFI:fuQ|RO}$s}SA6Syhؓb^ <[r<%|~;2- VGHݞ׍Ax\kh)TYA|fF>xYrA&_h݈Oۗm,:WlU1m)ph ic > m`|^4 {X4Z[>cC2 hNLH߻}l0eK;Z<@ZAOԂ'I4,R-I<E{BzZ4ʔ2>#@b}`Rwnkd1ĎHīWfĸ;f.fyqi 5ԍS ʹ{ j'Ol5ItP_BNl\4?7ǰ,&;,K:ݞ?jY!~Q7T."ELmcQkq㌨)w@2g AېvUUg!-~Kv۬#B"^v/э*3YicޗyhB1G*4u|ւDg+4 ֐~U9:W؄MI f/Tۋ~r }JB CB6:1,wF,)SЁA]}}w-O=ˇ_FXj^ըk}}_FB01rU O~OjqV7nhS^0/E#lxn\a7}x!gXuM=oo?Gc)C[)1R-jt hS4}iukUkPcB}\+ӛ,2}a &|>}uTF}vqrIXqeOY ѣ(?rm,$SDS&<8&48I+N?LI7Zî^Վ Ĉ>Aw<^oZkthtBmDb|׮b92xCAˏ܎ |X͑0OE˺LkȻ7V(*3-d{ zI%M} ⨲ሾ!%tc5]c <|YcU^3<7<4PAYdˤ#2zB~O\BBfTL12QC-bkxl3lvc4]؉/Qc/dKa{ߚowguVWB Rp529S ǛbvY)eBRD }%KP=bA1SH_9{vESb3 M'RFP E75|V/w0~REFA!JC󲉎90!(|3$۔|LBqݑw6da1{:>hN17,2\{N͞O[Şbs Qs!Ňrw4h Md+cd~gЄFN80%K,dٓ|ݎ+tG}WfPМ#m 5'ZsIy3"u2\%V Vs}dBV[0l׵+ۻcz0H =,icKjian_>P]5' m]/_e /GwLY"T}5ehWHb3'YFZ•R&OliJQmZ^?>pW=Z9Uݘ惰 }Zߌ7վnL@v<{ t)6Hi So88KͰ̴zӞPï](g{Xx~\~S:(Rs,rH25AYBW?Ͽ\_^[ʭC2T)1yؾx5@ތ@'(0_?b>mAwLI+cF8:*8eex@"Ȯߒ.!7?ƼCM׈; |A,䠁UgEPM"knqI%5)GwJ [S!b,, 1/M5K u@ވutUcƲ'n\l 䘒0? 7XjSyq>M C%҃K!v| iK?䀭YCjЃԂ~"o1Pbѻ-Th_fF 0T cӤ ?h(-uZ_~v1- &j۞CU.0# ` MqFq)5Z_#V""^? ّZ7ɽoG᱙Qrp#⾪QչfCKjW w V?B2v%>P=ԭ8VLѕyC&5p;M\&*"J53|>gU=1ZV/\_qƑf ԩ 1MO~,qasL"čWR>Y \GY\I+m+"V/XM\С# o.3rGxFf;ddl9Z*lr:8氘YxĺwI&\= 0"rTC9}yq#rT?wC ouD8wG ^.3FF3^՚׿{z!5T^%T7Wz+ɤypW͑!zY{ Dޝ[~XAjD|G1&6 <5cyFXt}2,554r{`ይ'~gĻLAbZ~y8 =eRG8C@h3ޏi> >N9uKkC""Slm֫LŎ8~tԝOi}8<s4@[}zZ"C:zٚr\hg2"4e! va@%gAIiR182ׯ3\Sc!#FT3`{oW[w|MFi/jz(q~:󐈑auMtS8H! oW\Nnϡ6bW2iTn}. &x,9&r)J#`֛9m`dhtrXᔡNaыZCA!tS2w S +ou̙=~ m}QaD>5oʭĐҎ~$inXya𫧠WeC{_Vo& / %6;ܵpi1ԇמ;X>ᕿ -:gcݩF+Hhqޔ'v͚V/8LITZq2?vª򎀣́|%IJ;HQ5a6 kJb>tL_1)A (%/čb㆚/~cnGoVvHCS h# ^/qa#s:"tXhp5NsbX[_20qc6 j\uvyGsK;,5/pOP}va~5Fu\v=}+qѰ#C@ X ?9:֧Pe"vZYPx@֞6 ؃%WF]Mɴz.h6TΰuH:I K)u 1.\ǯw²0ZC :H!]|?UK,Цct8fn7O>%QgJƊ8oEԳ f7cDPO$Zj3$ 2~_ "z@j7%Jn[ S]w3J6D_ɻK`Dk;I=N,<kZ=u 5.˂=ן). -`b'\h:Nߪ^ř5&1|5Hsӛ)\,zr]>+.,4Nj@.1<0Ԑ[ RLH47U5B^xgg :i-6$Wbi]$޿62Gg蕼[Վ3u翩jEYd4-~L5qj3DH1b*ierSEwXcџ߽ՖBђ/2 u7/}9l};;wSoqmw^\oocmFxDYj)ImcLVn⧰b%^ɗO*vۏCdtɠ?較cxE-ƽaN\F9c9٢>4C=3:D%I߮"Aۀ#V'x߇aVof"N4P8i fSj~>%%Pd^cB 5BQ__%CB:HQ2dX~ C6SC*MzwУZtt du~l^~ԔjN AݭǔTr[ΝiaU!԰K>hS `uA3Mlfm!Mqdkc>-BB$[s< .4^۔a0$(8LD(R{t}Ymt|尟~Cr=y.*JۺW j~e(O~\sZ-E:m[uT2AB9MobNDTZG;rȭlB@[n~p9*1t4XM-X]&W zXΪf krݶ.bdjXTz]&~&v]}}3Deј1X_S}7)h$O#5 T|We]R=]"G3qRQ]9_ߐf5P9R[MqpsY5~p>pcCBo^OxA ]FXUg8zɺ9NL ,JZ-2"uHdW*ylrO5/8h䨝ݯ#([,ōnazR@2_@c enMh3+Ƅǒsi9,GOm7#o%(GSQ{΅ HiO;]PHGCEjV5ޱ"V&4TɑqI;efdM 33*rC iS2?>u9 O<t"{_YQd/~'O-S߉ϳ|P芊aY^|L>߲Bx+Jn;d zѧA%<"O։kt]=ۢNǏ?5C͆P%Go5= VYhl D-ț2qTA UYw^l}3z*Ahm Ṙm|]ĸ7Uvwlacqx}e*Z_ۡN -բNw__2Ov`N@sR! ^P BfC@ H+k ?1z\_QeJG}؋5`G3/BN.(tIJgK kj{]G5D<)&Ҭ"W(FTqa"zO_|{(^b8=s uNmcHfe (_xk8o'Q6Ƒ^7Ww`Sڂ?BCXo5q;4fC{:rLJDkh! mC,zݴcMz8Ayfwu2`vݦ}B@x֐aGW`W#ru/TĭP :; |A+wmȪmW_.,v1rcFb;F(+e943ό1NA0İ@lx` \\ߊ#<ڣ CCC\ q{;p")j,l{WjC$f3U.: 3CAϨvu2qbXH`|~OYZͯ| LT`˭LNc(^7k$bFF/ ^{3"a~qUן~5DqПi]ndT BMyA- Ӛ1 GߌZa̪b24=!?ӥ H6i@. ?B3|' ?F5ZF\ WŮj@k[TMX ǵ^)o}yW%S3Kޔd7ki!u!ΐK4WȔٰPpMMGCnrK-3@M}pO/8DtF /X- Qa3\ 6ﰔOV|f8~ٸPbbarNifU#3C8+О٧ ZTDog}vs+~)6d -qt_2/{eL/Z{.:L̃+R$VF? N~S} s@~[M4YavıTF@HBh_;`[OwIvhC#4¤wAecfBS_y [yjFJ(; W@o?<ճklh"ԍpTb6iF!~F'bdjGwZ'׆{t4{T~ K4Hb`ma3T"OuSs/I<=Ca=RVf9.\qD8y磥4ElwBeKi9˟m:ԄڿǏpplb5.lF 91r{^FH:FY>n ;u!|rU ʝCv.3kW-!\:xTښ꧐ܧ z3Ae M-R ->w ̹@ ?8F{Њf!}͏'eX8j/e{TNE<Ę$'RLLP Itvm͜GX:2d]ns`t?uK*WF+X'Z|jUfP`F`vqAy?>dCeX?zOVG#w@B,` V:)OΉcb/jxPgILOe(3TʐնгFe _'ÿYlG|2O[ۑa (<`#C`5k@*iCvnąEڡ;F-̛^` zy5|DEDYxduiJLItM<{?=oXŅ<噔U{ó'Pff"x,?."=q+.] ڷL8'U] >/*H逊dYPwϲm?RNo ?X<ౘ5 %az1x(FzXgGg^*ai{PQށ:С#dhihf3B2mB5=!*PӠVy~"Nqe=ˏ1†;>kA bp//͐!uͲң"t.-s+{a[wʝXQ'_vQ۷,F ApArx<)1F652GR]2 !͊rJu/&GMA%erO{SGL@uktȤKSUIXM*<*=2cLC}'^Vg.~EY8(,jB K(?%zanj5U;B~Ӝ z&"Ōlm Zi^^YDZb45NX O&Ld zִvhN g1כ#`iY +YKțGDSa-BpjԐ94RCV*{?9$ɞXVHќ{ƜZL٬." vE7mZk?_}Es3ӬNV]ˢRk}3m# 2N&ǹ岍4?"fbV7꤀45"b/hx8<Տ ,Fqj@4` iGk[4:!jЏL~]e*4)i!nohݤCݼ/d{!ZVFҶQG^æ˱̖m$F8Ǽů:j*v{>B5Рeuu3$!DJ(yPڠ0oe 0ʴZ7O;zRSn3{jdx"9zyժ, b 5q=oB"m2""^K-hp$zI-_IáF DẒ̌K,. _$ht{౸g1Sp,*tۀ2bvٗlS=GJ\(sLl mXbKdU$bOug;Tُf%Ze 1NNJ)dr亯ߧNQճ-ˎWؾr%i붖$Nqh.*Hk !İu#%#b_;6_grL!OXC9jj_:p/csm818w}_J8e/ӈeUcD Vna?55 +N,6!7edtOO9&/ êe ӻ-9i2D;los8GŅhVX YŸcM͢; YjGqXqdkmT;QjèO52># 4 UŅ#qMgXgZؚ>0T ;uM=In4uR1dIo> AUUjQqme}(GdZ—L&ܠ<)gLȻ?xګpX7[">-ygZ"^^PaCD8Y+u=Ptpt[mn|YucC5.4ȡ| ZȅIDOX HSVcDrⶫ: 1nPRz]<fZAK820Z|s;TEkGB.!GY0m^q?Rs!:aSȐ sjP;ɵ^2D8| '<=HZWAPO96t?i4'}3AP\Y1޿MяJet5YmbeXq}Ϸ4ct_ uV[G@zBeSCĭ/K824G$VemNq.4tO!r-M"2_^w Nt>(bH˰3Y} '&453.d>VͺѢ1|?"09_׹c S~JӋˮB GD*QI5"EKKnH%4Z1|( ~kj4_?Jc5V=C䵆S1-8ZBLBw?k./ȶO!jl]oJZľe*MC^KYD4AЙj qi ΫXS!9$5Dc´` S>8K s?SXbܘDd_ڎCb2^ V^=f2q22mJC_Cٍ Sa7ڃ@|gk\]~+cv4i3kpyįDL $lÅv[A8Xw42]CJ3*npWx `=FRGM(|isЏz."޿\Um)C@5.&UDNhQ2[9=csь=+̢!rC7GһG_ Seq+ǣiŝ|udĨy+4Q՗4e帜R/#5BITRb,LS%=.`,ڧ:W8JH OW%_[>1$ΠgoVShBig~g92>e #YS;z+.\ JMφ9!4v(5q 2,h3LjF̾uoQ#;r_"5/=1_gXj{-[.h*T;;]`˹?cmf-Bj1 9X":ONČ Q"hU}GHc,״ CY}[@gCFkOS DE`ġnwwweA=ic 0g OhI+b)=)$J+2"FtA -4VK ey!Dbbh GI.P/4UK@/y}εB>=G,{`x9x.ɘ X!7>BycJgC7|DZz45 r 6Hobp9GŲ]P]9k %탩Lψi ?Uo[Ip؁ _S!f3Bzӽv4DxB)۲)gaԹzrQZ.Ǽlv 䱦!AŽeI,5ᚉX %)kjCŅuzqlK{WG?hhx2"ܼIX-W&IdI7@J>(#OD鸮u3ؽ 5?Qݛ;&tڠf? Q{?RLmyH⿙/ֆ}mbY`!ys-^>K|zƥ%tl2c[3vd0?@̫ȷ؋aв*ӷT u&X fX% "(qOSPg7Vp3B|]*xVi9t!XD77?m~\hGH# l Gvv9P6P:F8!=Jec'Ȱ5645<a ~hTw B~U2ov-B V;_/c2%q%miR6 U-laO} &5kPqx2Je/cqhA1N´f4aFȧf_2,[BKrj6)mL[}g-H<! ]RCh8|T G}ѧ L4'B aa[+7)mħYG\FKn5q]e<"DCD3b p5d E;єv^&|k/ٍ9ђ/TVq1QC,fHr1eHpvnfdMA(_W&Y{vZgIK)eK٬,69 L aa3hF]> kgr>ӡ^kSϱ4lBDC/SՎSye_Lnb!A#,/;HN<..dWzYG/ϥCmJbD y,|Bpɦ'Dd:)i ;EskH.:hD3&My_2"Lu,U/Uvpjh} qg}WI/TMᵃ52|8b>jfD=U|% ͣdL &| 6oYa?obG}}ǙvS%s'B5v=)A|,b5n io\omυYpd0gvVioHEz|%/8a8#,S̎](e~.٣fRDGo H()k.E 3 Ly RzSs%U҇!aw[EHEA9b5b\'e)& 9e7q@YlnaH• h qy5<ϛĀ]')U }Iœpgz;OѤF\،le{.Ҷ\ =rj"*+Ԯ) kX{O" ]_B</P%zF4D [Q\]> kC`5ZI=pA> `%f ݴEݶ`jдT-j)#i"#T!ăÂ9g۷k.Gi;9 La =Bb߲ Op%bfEꉛp^Qrlu92nWHwgr\v!@M3C>^#fEV5L4i}5nAym2}_Z\jޕ՘`S7Wl5GEjH~ϟmhNIh…<*3F̄,T> 3g42P̈͌Cf)!ͦ_ q\(#n1hăJ8m%cgXc7hĊH26!YCBix*ӑQ vCfѦ*ξ_(7%Y3' ։А!Ѡ!N@CЁl.I_%s|sqO=kO P$P≸_1bQ=\0ǁ%IMD: oxuDK^m22f7]%c *gtUxBO i ~_36B_ԗVr[Wh8kHR#n)FÚXr9ZGCbb^ΊUY!5r2zf_ˮ m??"jBy  ۿm])Lכw&j|Jo zXYf1o725}W֞bLA(& cAM`Q;`1m|@8mjܠ|%A;O ԉmI`6(׀#X}H@S/ԉ84k"ʘc̾=/ga9|)߁-7cΪ]cb%1@;y5S$/}joDh^S6WW,HC5:>%=*8,*x@!f\IAH 6șbP+΢zx!z=/PtL3c]bcNCnx70 Ƙ}M0FM[S954 DpC(Ħ,{c$~n)ښQ!$4SL(sM)K*l<}9uc[Zb0Ƙ3~r1f_Uo JlİU1O(=|l#,h^%HeACG-xA8gŗA l&|?z ѵ t1.ԒđfZgkԯH$lz1ݙm1ǖ1r1SR*ɶ1^ 8LqNB+PR6cY-Rtԏ @m:QMP닞Ua]1Js)m^So70a`11ӭi aISp~jb)b@(/%Zv"4MnMY?3V4TW=7S׏ӑT({së-1c̞ ?opw9-&.XI7AѪoV煒Q, V-daS{YW( r,l>v=`]ᅖ1l _0씥̬/ O/Jߥ"s'Vd_P&֏+~ I<N1vnȚ<-}.YbZpbmXiW;{V!^SH11bݖ1;BկA A|&.SD ֶ &"/􎝆x6A7ɂB`ʎCW@2#R8dC4B>а`9351 r1f'dB1G!-z CNb\ 2 ܿ~>a]PXS=#GKZ[z`p %Χ( \_/]$ 7(1W[$,1 `9S~# 1&xӣ=Ο _BO1U[ٺ*73I ܱ#IΎͅ- Y&l0#F$t?,&x0%cNWbx%c`9RBϕv}c[?~ YoO-6|TaMVM$1/F\%QII+b89HR 롧OB)4sL)"H]S 9~Nc,1cc̱~sJ:)͔ jB>TЖC-̈́z[JԈ'`#}xˉAGvaew~6> & Q~h&65EҍcnALG5ɖDX ^$W4&zx% y@M GFb|cGqc̑In21f@<1HBuuլ[1ВG)$E i 93ZҿoA4Ka PTH-XRv+:XCy4IIh 4Xb0Ƙc$7r1r-a3lIH#:?rPF2WQۘNXY4+@m$63]K ɳ+HZ^f{N86c>ʤ~iccp ƘSԦ( ^ZP, J&v*I_8Hwlİ9 qh(C]dP/×e$GvKcHz-XN'u/%'U 2l cp+ൖ1 `Y汴O)3~C%"zU'6 L [ћ0,B(ks|%0 >ce(@ JJeR =IMh8 z.N|A7˻}w)|W%AlVbYHbB5HF&Q$YB1b0Xb0cr1fH\vUrD:DN87B5 S[OC / lHgIǁ#/Hz KdHvM)C&+$7a!SkCˤ\s4MuZb0sz\x2`chLJvh <Ђ$Z|Ca_(/fٖc11kmy].n˓#T~ 5VwR &bkcpoQ|*R'Cq.P$ 2L ,v_R$:) 1INb+ q*DApD0_ eYXLJ@ػ`mX]q(F < i. F]1j)5%Pxyc̑%c11W6)HAҼCkڷ]ȕoS$BS$ʄEPHAwZ{V"Eqo%1JHDy AUU!2b0DTۈj=9*kcc̙ 1$;AԴc641%@ihYM`669 2d<'!CI@Ҋ2qAUaVkE8/s.Pc?Žry1D|Z1K qc9r`̡;%Th94eFOm61Q}(hAW)c7ҳċl :""|Qʴ-.ы*:dk#}-fT@uT& d1IbAK cEnw>c)R)oqR( \SЧhR*ۓ^$ + 5Oo +lM4lRB@e$'8P#xc2e"Bw9^2$Kb`J<sh%Yb0c  +HMyPP>|ȼTdԤ;,~1?l[@kΉ#(;X22@X5" SMhU=1w7@Vy%#4czK c$_dCJ(f 5̻12c5'pDj EV(#+b¼c1AnE oT]mJn:( AzjEڿ8T=ZD&lzPWc!$IKq$\bIy.('eA8RZN~ Qޠ0`+,1c9r-7sLwEwWD`-cߏ?1VzRFU$"Awba@91ʘ@Đy\A`~-~zRIj8c9;C%bO1I ϵ`1r1fOY*h@'́=B"x#WzىUS6b?Hڿo^,*`NT9$ ̦ItD](C6AW8mԳz_@O4cc`q%g 5!$bs/KK_XKD. XbuDR0Y/0dID4FI\dGb60YNGX/&Cz1`H o`1 aAhKO_0@B2dʠ vE&b3"Bj2Dvw:~`P"BY=sbTN M>La_1N$AttqHR+J1+6 >c1GWn,7snp+cweb֐WDŽS=!BlThCh`qC%B-؂mB'i ͱ/$K ; "IH=L! 9NhT+ 91Xn0?9n#ۭnZ$/8|JDJun,=B~IR6#(.LPK߆ 7},C>h3DVzqLb/E\'F 9[l,1c9rû-7sXW_٘nO6 fC ՍÏqr{qp^HN 9 HPMq@ PF h# ,91nu&P=j;eMSdbe%"3za ๆRpv)7č,azcv[bc`!8 Ca7Kd. VșրgzgI 8?Ya3,/9WfUx  /l*NN5i)C 56bxT(&u݋Uc,1c1Mnx7X >1 _M _̤ǥmjQIQ|ŖG8Y%?4"P=3yA*73m<[Dj=G{f3Zg ҘK `1/_"7|Ø OAX| cV~n%Q4O ڌC_0d4LC+虍 |ͅzdE$WEIB;∺"Y&Iٱ1Ƙ'7r1;}d^ǐtqKkn:˃K}<@iNI# 72.;󧖝.4`[6Y7`-AV Qk/P N1'R0%cb1.c&K ccI1A!oYeN C!9c0:LJUmD!# q 2BA&m$uYA&ާĴu#{p=-XT6j 1 J _0cKDm[5@h{GPhAy䆞9I9*a5J#ZN+x'$חپ$Mt.sݢ{C83h\)1f;-1c1^n DoY@1*A~ $K˃ b1#L_XcҭE)Nvh }$52'JHD;Q> v dCȎ 74ä/LfEH}gG9m,1 /~ħ`9:x> Ɯ]4ر:П800HClL ?1i 4SS*9\Qč7mP@S :vO!OM!@{b6DFJ1Ɍ?3eYp9|[s,ypPC>=~r1WLwї1gwz[W~)GǺ0?hRZPQ@"6b:k@K&YIB.Q0`3'Y3)C;0^b.xKr;cLDZ| xpM|Ƙcχ?DZr|Lm/,C&/n<2%S:M@73к@f-3HTĈz<2N S||ѐ4;YQc\!'B0r11K wİg|xppm>c!>< p{> '3a `ֱ4šM(ti a9W}R~iMq bCA CDӜۘ@#Cc B%AD :~ʏSoEflcaKb]K {81fˀgnc| \aա|TOc7L kbr% Ƭ8p!MzJTvΠ=mĆz.dJȥ-DM\=m&@4xEQS@Rl#&_xo˜->^c81s? <DZ7r,73TOH[<l)쏔7kT##Ii=1OcR3Ps({ 8@o&f $AC 0١|j99`,1x%~ c8n \<cZn0f~10@1e?B< 8m%d4r>X׈b RAL%cSk <]k)Z 1)B,e$+JևBET+>0{ 9=Ű7$"F 2c. <co@> n_hܕZ9'+u)Kщm/+zB w( Uh8Ŋ-4KDX33 JD}_T#`MLhEa1\U><6pK>cU><8xc䆯qHhx91 g`dɍvj7dͮ?ԿC& $6z jIѢ Җdz9G'.$yĤ~bKt2S;a,1cWa1{ ;߷{#7 j *%HG5HzeCen~J_zB!V2mgGW,i)Q2dZLDul"mQ89BOj7<*,/K 1 |/|x2A7>ݖcSJ7/ИC8]Ĭ=3A/DP=_1NG`S m%MGBP4(JIP!$86ԣ JP&7=ȥĨ˜#+1%"^6Ƙ1pCr1;Jj䣷Ml%!h}r8!-dZL>|p wRY=.snȸmˏS"Tq4dmzr>(-1x%m cn NB;}*)U=$SsD_w(;W\Rr눙R2 Y+^.=!'@=fsh9DJz]>]%Kn1w |DZrïZn0Gjx'6a9@ e_7Cs2_?B]ض0 Z!D?{=&&-L14R>0˭KVSh]l'C8N^gbc( 1`.|DZrO`& в%Ԙi fb_81y<´o6$JAzBhOb 'b8L: T&S6w8$}R# aA21]# H wİ|xp k}sHh<||HI ! `[QMYP:kjgO1-b~U Z V䆘rj7_rHUG@e3)sȺѓEǰm%?¹Y=6sn1Pbx%]/'0ƘCȧn DZr;-7#CKdH2P 15PbB [X{=8MFoyw(AnL9Dl!jmvs[۷Q8EY1Q^`:P"CjlzAWޜ0\bx%=}Àqc!r c[n0XY]R^Ǟr:D?C >^CcL 5JC.#1{v9ͬ^t6ho"cO_lj`EVŅQ9y_bh3OiV/?ӓ1Xbcx#く81hW.Y ?e5VNԆ<191tB2_HRЗJ"FE}L"c?ON4IN7AAlX! -=/ PGzS/V/%ޝ0Nb%c̙bMr1ʐ}Cst7sA&Avܿo /PIYvP'z%.u&-i!K)S}OU4L Hy|QkH/'DL`٨8MLd8bs%߱İ{xc'ޒ`Lm96t9f^38 ]Aj[ιݔZ{VA/Iv%sMShA GeT#̨GԶ!&[aGۈ A1;#u${"OTc,13f1ƾ{*7<9df6m D}̉27zTɣ/=95"fBc|ObX@zๆ=& lQ^ bXGAxڊD_.?"$U4GVtvŘ9ZbUyf1q ? \dahyF=yMdR&eRGs orBL\ڇlDkJT]=`6,9|E=dNjA}`A!Yu2b>?]6PCH9X]) |ĥ81 s ~y笡_D0:Շ9ւTv"`!_v61|YRā6B5:@)w@4N2RE @/1%-]qcY%x.pr95%򙼶4P"$c/QB ub)p403?E F*ۺ'2X!S#0䳦, EQp3K@-AC)~$5nc V>0sz-p!T>ݓ s៓n~;T.1pD~;˚15bez8ޢiP޶6*Y)讑}&%YplDyHDYYAzP"r~y=^0/^!Ocqp/\8v~r9d XkerS$eD`GV;^8S^4Uq"(AٔC5,P4O%S.MHMO]U% N"&Ș)1[-1 \%7>c1;C8v[n>s4ۃP/bAdJ h-} м#C7'T;X ɚU|8:AM, dy C]4R ˃lzITSAok.OIG Д@F[|ǀ_. a1f+s5.̮ Yn0v$@@ xD'l~,#N;&؅c5~9Wrל̐?QscqL 9Gy^^Qd-2T I͜@0!?kzc̞}*7=I8y>*Ne=xYE9gc:cVkH ʡ6D (?Åx.hh%ؔ!%CN" F]x#ScCb8DZc>< p{>c1DZrýwXn0{1-ˤGN^ӵ| ;c?͊2IAHduW0Ӣ6$ 5 }"9gF^r;!EiB_cC"}*[ᮖv~xc!SӀk^`̠ Dqʎh0+_S8|.< }"!7MD̮)'VYIq>| e]"S 1;z{JG4J#D$h 0mKCHs"1Hg98ErkcQJ Gs;b|~ƛbay{FyyŔdX &5{;Yb=<x6Y9`Osy2:Dv,7 xk$bS}VBoOצ] ʵu|bkFcAAR-[nc,}!Fr"T4w6EM$ G,|oųbHdꡔ3 HA(/PE{pk 9YX%ӭ2V19^:+.e D`ːP# N1v*^=ڕTM ARUF<@-9AlM| ~<)2rѩ" JFn6U?!2@ :ΐ؇Cbg토xȾ2z|dpwc9^`)-PC>C%6 r ۠2G c-1'C,RFfTǑFPcVJi3GEϷ3x L+% 7JLBK gK'qc9\p]_8vInxsňI+.ogΥ \5ة`e!S:Vvv2&}GNKhP%NY?Ed*X!LD:CPT׃;tIR4$N#44{g w(.3<0w=1739pwK [>0c |3`.YIcyZ?@pKܿRXQ˜\+e &frCt%([4P52UQ'1s!]S0{ܘ*1 )pcۀX3cN{DZKr Ykk־I/DM:6զmQ%lu;`L`C@x!S0K0P=!Y%drK .ң;;jNL1!7}%33c9#><8 >ǎ冷O`V~SuЃF -@ T BJ^)N-s~,=f{7]ц(gu1b@\t1S͎r~;-5=4jQFbh0pK ǀ_. a1[\ &{Zn0k,B" Py4@#&]F0BVHiQj@hp^1|xpm}.Cs!l)ޚ刔11UѨa!%dۀą^?URWPڷ=)~ Qr;Bc/C,0 /Z<ť͍39Qbc)1Î7pc1{ Eo^Xnx. n'D;fɕ'8i : ?,@peܽ+xa".d5N~)KvM ϬzM?0~OcQn 4Mr}[s TaB=@Dal1fjQ5urp%sz|x2p!p;>c1QyKl,7hl!bX)x80bb0z,?lۿL$D|tp[=aˣ!{'cb;:z7 JFsy:\k ᆿms0r(_pur`5aqc1OOAU> >?B8N6('$H\h  }!KP"! }zInNd}B,owHJ% } QP)Zԇ)l6, 2ղ<1jXfyQ~N;=}C81ƘC 3䆻[n8 ? J\p8}[FLm!R э!&@H!EO:-d0 ~b␼ E325,={/$).Єg>3 qc1 |{g};qIZr3 rR%KdaH`:\D\(oߏ=Py$H\ec dn;'0X͠ʓ%\}()LIHV-K ǜn\xFb1 ^:|;fh6@wUF K&t 5{A;Jz8{kA YT&JN 2{F\^L"xmz&x~vQbxW%c7xc9r\ 4pxO> Op$ՆoMf/ffẐv} ( =9둫ZINorê"! INBgVSŖ@),DN̢fq&&D pJ İ3><+}c̑柁_~xL冻Yn8zCd9"h|d 0TD߬+ Kf CkakYMy˓6t972pZ&/9@/fQbkTc̹^(|E4x# 1<Ù݁81ƘcÿO0:cNs=EИA~,U fUj/~:X'Ihm2/(bJA S̲R"&{|hLͪuۅqCJIkGзX?.İW@>c1Xrupli\QC1h):F3MbX߹_WAِ~|O1QML̬V1$|THމEiQ5GS-gRRPOٜ)j9$lbZVnyc81N[8v 7TiGʐC o!+ [CS0n33c1<*3|h3+1֚?Q'&zCNbRcP<{$M~!,LvXIU>yd҂J75`stHQċjEY/y)UIrȉccw0c̙qՀ0GR 0?BIɅTvJr0E $ojk= T2=h~D <Ў>Jt!cHh-Cj3fPPiqss {}c1|#}HJ )-~m6Nپ rjwA,(~XIj?.%`ڿ{jAZ\3Je =Vvd]q$\{1DF٥8Md3t`G VZ1BC N#qc1f{?n|;%bEq{Z # I0B2)!0U@G@t^gʤLH5\"@$H73#Ly$%RL ԚX-4[H5,k؍NJmbKn ja5 qc1f/[o~9Vh026Aݥ,>GԞ~5e E dqa6ə =Aֿ1lFҊOx.o^=&!B;m$ mhK, 3K<a1ƘW~ _>sd出<j@o?Ra`؋=Njk?Nu"e"BhcI ,%3K$i'!)(6JFNAtc:pI 5Cesa1Ƙ%>0G YS!SV@CK״"14?bp_|ֿGJ.5d9 UL )*ԩt`C\aHC!\wsdBvk|c9+y=8̡Dc9P).f5)g ( ?V@DɜE GdbEZ.mAɟ$c,I- u. ']Xݍb-)MD,2d aqc1)7~{9dľ\n)CJ{ +$cŪwAM )DRY$J#'?Yf b2Iى!1T $Pu9;S~Cy9 0\Tc6  |a1ƘpS|0o& g˨ C{DfPeA}u q׵~D>z|N!Ea3 P0fR 0I.N뗙 [4; |a1Ƙˀ =>sE}hhM Fi ȻAC'e&\LwhbAPT9$f@;Y/uj-'lv`\Y  AsVe[e EX>!YohiA⯁[6c1zՁ_a,u][߳!C>gO@iOSj.((j9DCs/qbk8sXP"CCl*V/?F)qh"6B#Ǎ@D9xc1 .~ 1~9HPV%O1>?fcar+*C\gȡo xehe];͢vБAR'l%%"OIDdwz$lw:?z!f0ӂ&6livg0c!gx*?8́P2&S"$BNƶGľ1@ dANG#p=C=)K=%ٟ$4h@ 7St 6="lu;~H5SB^JC"-mdNYdAg0c!+/nA-1c&!!t `&AV }Z/FB%#5]^sυI)9{Rv"A'㑔;#@;2@HȾSWĤv{o1~[=/c10p#0$ ( o4鷆m-R"[\20hbnW%x~5xnʾGbvExAH Ġ]PC*Ccc9KmTsOOa1ƘU{o=pe9D.C;ِ||bg)~ ^͡{2A/Qɥ$pb56@{,2N <^YI5Нb x+Yt'S2 ǢdOh(㔈=!ddԟ{1c3mWu oү=T5A& %!"!jH=b6{Le%r8/ /Q8/2=+6<1F9y1G_>p#1cv xps=%Z(ÖDPs6R$ж'/SJ~DB Ah:mm#x{?ߚhh Nk/qGM` 6,W͇=P9'Aw6-/!TMcWn5U|"c7 x8pU9zmlcH0b>2 _,hPSS*')H~-5Q_o~/X&4j@(I:ʂ Q8T:O}tÈP`ش@T?K= Ո9|#$R781sRী7 pOUxe19ڿJu,ֳ}WH\eqY:fR/2e31#eَ^b),dea􄋨 *_1LJi,@-PzC4KZ/VŹ0HmtE]DU 7L`_$JPbdOUrŋxyCڐBpDԋcO_:s ہ?o 6c1Bq%o0ǐO'Q;7Ők hfDm%`Q|'A-Ɓ@XV2E!M?|%fx45ДU$u&+!9,Jre"9 4qtc,y7LoȘA7^x>c1Xrpk[_1ǵU\~ e!Tۅ4a.i)^ԯGȑ0V_l* cgFE.s]>籢y|e2v11Ǐ<c96G灋 |9E_전D2: Z Q? J{TBh@]Q꧗4LcHV,dM"e~jN!T/͐Y)l9wɨ yɨ#'b1Q.ÀbVZ>}oA L ~KÛCC;.N%}󚅙1fx j,I%_ m؁[ddPbb!czӁ81Ƙ#ė 9>c*(wgCPZn„8*BhC;01 9?$YPrqY=2uĘl )+]^dDݙIr(ŪgUc+1c3 p 5|Lh2r*ћY,H*@e$d,P2,}eT7J60E'a¬@hȾԡ( OߚtL.I#IXAz4Hޮ9T'¾-o.qc1/;Dˁ?)JŤ}MhLEqD{{y_,C!!SH=S (:GT7 vj Q?&D_ uHA^@6_Hzǵ5GU{ /s|"cZK><␒2"84&d( cϙhׇv+ vF(6Ll!c>J{Zn䜘y `rэ4AK 9ثAeʾJĖ G #\2xryZk8|x4f}'w.?>|ҧpKp/;|O>82C,S :!Y&JBwXBfq!$q㖄o7[8h#v&DBdDvEzQzR&:աE)}G#p9oL=%Kk~n c)x>79f *> W,=w"2KPS62dG顲-rr39$Etq Ք4Hɶ蹣c#xBͿR%Mo&1$01#;q~[}c̾w/nI7{ʿx(?Og{B43bpG;x!1=aD' mu+af9?gR)lV\@L%&D}`axYʻ[ِn \ BrȾy^17|;%}ہx^#!cZ)GѡbjN'w$,c(,J=QhÖD_ ˃ hTf&"(BdIpFi֒ hOcb),1<8\ <c% x=r}"|/u8*}=A4/ >o ,~Y_ ?:tǵI=e??Il& UZ<Pf?D?`pf)cpgNGWfŖId H"ু~xc'7/n \'b1Ɯ) \ <c4 #oُ~9x5 P_jPuK"M28C6PeZTk{,o,!S1S?^d(0&~7n.]iz  ~p>};gqc1w^E>CÁsqOʀdfA?njv{Qh̠Q h/IeB1{65\`2DI&Ȼj=5Q"Iu H5匐3c.8Yd˼z=r86i8.\<!p9g}"W11-.>}M݁C89zȟ[~=xd/G;S]R^-JYMsR*P4lCY5W0$77/RM( 6Cp9U_5,Y1LC$Z䩆c+W c^ {yYݹWILL\9vK[,K) RD8 Nhy  "5"Z8% 2rg"=\gZMOQ>kϳ_c1fQ |+}#H\議ޟ$hJyRb#Jm׸;U_9DC#fb"t%#%lcylTtT%4"WWQ?t5qx73xߨ1cx9Pg?c=p}'ȭˁ u&߈J/~$9CF1>Ĭ!rD6y%l$DÒ{oi}{wЋ] l)U\|%cc`w׻28@;@#FuIm:/@r EJD\zFg0|ˀ8Y^ <:5c.3;z}|'˻?a.`2~cAR75*S&'b1^-S@ȒK-|A3ʩ}#-024O"=x>'oLB/?*w~N0"{r`DptB)c}>8Av7;N1si x"w|#'kw~k_ R!݈c75XvvҿV}P"R3;摼̉he_t+)Vߎ6[\ڨj~Aߠ8Uvm/g'd9a1O xd >}F4H/0\er_ ,XcvPl^惍0?b# G]ݼLz$=@b (Ԓ[,+ōq;i\lpPFߺ|x:w8Y>'W_7b1!/<GC/a>a ~b5IqK^7YF]wCYtnphn6^RsGdAUmB"#fJC| ["sc,lOL1*<`>n~*뀗FN?\{+}cN <x *a]|#'ہ? a>Etl3 #栴:v ұ'2vz+ջVR}sӼ=4PPNdm$gD"JB 1*Rw063/Y(_1w?8Y}gF1Ɯ,^\<Ǿ珀oE#s mo/rNoG',5v%9M9=@ CbOr0dm`; 2;Y\%1FrexP]esƙܒ ˀk6> l' r+KMe3<`.~8._ljs0s'9c |od$B+o~oC|e`ړVPr [ίM^n~ŽV[8/A\( 'Y$"tCqIݍ\YWUhGY{&PȘ;_?x8Z_ljw'o~v|#c.6~*_lj~i9_:ńZq|u(йXou?QOA^h}=Nk#N`r5)K/#/2U^Jj7?:|}@Ř-K~7r@e7b1ÁW y瀧u;mz3 Sѳ HaE;@5$b* =<-1Dɵ졉Tf9:5Q uW22)%!SF=GCyBRau#/_lj󏀧^ qR!C qoq@>Ӿ7Ẃ<qcN|xJ|=w?ucgx8O?a.b5Z4\Poԍ XQ|>fA-:uxC$@G8?0HRG^ j(vށ:|Cm6&334D9Q:Nˁ1*{u\<\R*?l I#Tј71>y5M\ ,9AA6}$QΈK^Y!y=A)L!OF3ry[_~\jx,px2p44ۀ+}#s +I7/x)po\jlNc,}ӨC>TH';"d3"Z"?"U`~m>OCDC. pX%?NX2uo>}!+N&ƚ mLz~fXsU7:N~ _1\|c;WvW)!#:%K9EZJc$C&M)9`8ue?b $k)(q;9tT}=)ǃf.b'51I2KHDnyr?JnthlD`;ԘKpo4Lແ s}#s9p?{_8%<8 < x\6LA u)8-h@ "W ,ͅNة%~N[*Ct~iHZ1`4&l} !SI9Ѧ8E[A%sܐ7Rsy;?8% <E|sI7ox龑SCk_>0#C1{zM/PzyO9qšOR$1mjM/RYgÆ>ŧY 'tu$ 1ovEyuSʯ\! D:_+73|#si_qJ|x!pO+rx}{ dii([(]{^YPG!gc(T0pCh|?W^\цl H}[[%}$@[=+ ˍqz}7 *_1Ɯ_p/?ox4 Gou~֛3a! !=X8/&r*`Ar{(zr~~ $h lftQ=;@bRPHOO:Ou˚ |qJpqڏ_1Ƙ; .!,{%@ OFͲ% \5ֳ܇p=ːAI},Wv~,#9-HA 2Iص` GQ 6QRW9@<40gyWN_gu,y$,xm*ucE?\x(\W:B71RLGM(yd1R{KZM쌘 )k$!k9ͅdN1\*z?sُ$|r<` >p-Pվ3G x<7}#sz;4q,[|抢 vuǢc5)2,Dqܽ^y$zNI !4eS$ՏdlG ,) #'"ULz~ !3*q@2J"W oR_0Ƙ?%j;FN|aVzsS6G.2bͿ$cZm+6Bn,J&}wfiY8fbp@9!Mqyr~4{)W̕G瀧u sL߈1\{n\8=n^7"&߈b֛CEע:Wz,; XtɅ8FjAFd)jK*mL <"h#l Y5E<vBl'CތrMb,j{gou*_p=o:1 |پF95À:a \GؐS\K (mO] yjD{S~a%dJK)^I9\#!"ta߱d5J 㴉(1c9QfR@:rl'c<?=ۀOc 7/8U~8<xQ1HofZ^ܭY4p5krJ bI$I~[q?;rDʾBF;$ /f2v,+'WɅr{RsXpU>8=xr:'1$w x CFN?Yþshfb-Of,?x>WOMClIƀ?d;ObRy v M:fЋd\L%{MfCKo%VS+6NRbpvs~ S 4|Ƙ'E*7/Z7[|#`iE$ŞbhzUs*gf& _>J^(tfte$o*h& #$+$‰Y1s;CBj:CpE,\< xT10 N 2C7y* A^K?EV7( zɎٌ~x-];5XZADdיאk'YcR7@K|If6u7Z&?l+5p xp/ˀ[}#c̕ۀg':P v"r!5@՛C{#p. I0y->S To 'ș0^WqzG9刵 &IhD1JY&t13s?UKb́a5s}c̕~Ø!9E*@]j~4s5v g%u/63 =-4uOhFÜzG:рCi$M O#B%.Ё"'V-0SܐYDhfc~a1\|U7ٌAU֫?@@ѿб_h'fJ%BD2,u8EhLHllrbwYh\1ȺPCRʵȡ!hA .H(ޒ1fχ_1s>'souf@qlT[r } b '-*~-Wbwy! {Xhp `p]Gh~Ջkżi R)[ԈQ=sYaOGW>0c.a/^|7bm !/:?VMJJfEq<^`Ș36buV Ɓ2^KUN JnІ B2U9RDgILUc=3〷:1ƘK | }|Z^[MP-#&$.LؐעŶlA r7O&%#bT3FF;JN 䯎{?i8`GN|/- c̅%ZK1sp=cYq[}|* YZ*yj7M)d'6B1CG::Az``Htu-$h z6s7br&)mY?A P^#yʼ=nTiK|~,z,c9%^|p}|hKeF7ĜȤֿ!pd.$BJ} ZԈ'?aWnLc@ ] &lU\MlS -ցg *!aplik̦vX qx;?)c1椸xp?lEЫ#{THTd?>v7PF1[b s' b߻͝L}{[4A3|t;gkz;cq#RZ7x#St1O0c4> <0?:hh+dmə]"Ck;?\0cn'7/ xpoĘ;8~̚kЇkֿE`Ƕ查}C0B&ڈ}N{ȔLM >!Ә99*sP/c8/h?m wuc1\^J7Ss ZM-{N~D D.U4f3~Km @wsdb:!If(̞,@ə"‰rԨCH|068`c1sJt)n@*kdY+AյDmC_`KD[gDŜhJQD{9(CC%86T9|vy )v9qej1,y`'sjH0 Py- U$\CskD{ ,yv(ddU,BzAhf?`jB=I.~#;Cg 3Wɟ:sQ2y"b n1dqn1slzÌ9%as*Yj pN)u u>@#EtG3b桰K]3R`3!WY )FL% CDyA VCk ,cF\j0p1ƘC}Ssc7:9EFOĔ;j:,Z"x!`S=APY[I+!zHU1^&Bd&Y5Aa7P5dwC/zg;CFP@ 0O+|~ Ɯ*/x1poc̕? a̩-p?b"hK% Aj|LDH )<)o󔁋XP<ҲyToƆBi-r`IˆNwI]o肒Հ@nj (cizເ>0s%j''|#\"pfAĪk2ej'T8J%1# YYSg)iw5ة\V֌H$c,]`v{& )탍ђEjƸc0aK0sEQk0RcKZ^A &P#tyA S; юWv=Y$o 숝,Oըы1 ,p :ZH*V$`2׹ס:JDT F6x"@-T{#4h'bz*lm|LÏrbGiӑ4Ͽ4\>|U7$c1~aeGe?HN a̹zy-; z/]Ӗu`"waez PʲԊV@\lѕJNY.ˆ =12 |a14x 5s}\IvCﰜ6(0W 1淇*V,rxutp&^t^t^M(N2G)CҬINh0F-Gj#0(mvc50.x?dC?O<-w>L۷`eۀg':1Ɯ7/-V߈15S)ĮGb楸9@CL9<:R(9" %a%S "T}1O9^LyIute&c[*놋$bFOObƘˏ c̝gW0JBu9DY79A6ez Z#Os2Ru"< _u ;Ręy{AJO /A>9'x"lcn^|5o%c1~a̕g/#4wR4I%3!i ]$O 9-8?ٌU6Psd,#,P(+-%!/5x‚~`~˷X::=s'ww~cUu*1W$cdr/:E_䗸"~?A\PAq$2 U =ġɏ;3va[NDΥT#j4salT·oN91-sB!4jfMcsp ;}cn'^x J?é :q_OR3qb*{cPlD&O+$%ry=[4mRO.4/AaM uTND(ٖͥLPm\cDn\< xcmSsc7:҄U"uL}&喃EDQZ ~jlzB9Oӫ∝FfK䕊TPAv!Jq GTmZGH93<`Ap+27F1Ƭx#h4cN ?2+v ^ôsR/RLHFv %a:Fr"D)_1q,[}s|%Z}&թz3UWy]1Z8 @U <|s`xpx<6_1b +aD0,X2+UG LL5 ^RA4^({bz`ȭ5 /+ӜnȜL˚:?̱6ԟc{/>1Ƙ+ |azkmĆ."?u"V5,O yP/\{8?:TϦnؖ#. fVfJL ~̘qIyN 3[3 Xtc7O0Ƙ+[poS.Zyށ- iT!=;7CIw&;fK9JI @M`^'߁8"))\ .(ț\WDКt$7fژ_5cOx4F_1\|x6p pൾcL%je6  ^z3 Ø[6+|~V1u@YdFgSŎ9ZJYgAf R"Z"x+UpY$Rv"We$;HG數"d4衁Z  kP,{G$#ZYЌD5ľ꣄M̟H4Ƙ 6I{|s s"^ncnq'7GHaW GUT6PP#fvt?%8/; ^ECJ.EWR&o8C̆ѽ%]bѧ-ČIr@7G=g4cn3 \ <xc.1>< x_1SE(pYC bݓ\^H& 7xr|[pzI s\̍ ھH?ŎܑHg̗TMԱ0X5Ķdu'&~U!/j5 ƘK^ 1Ƙ-c|Ƙ O*b>8h-!KE%C4>/s #  sg( _^-T!g"CfT8V@9LF YJ)[sx-p}s-݁uc I#؁r2C/F{TQ= z(Fh\=A{sHY `[6#lc6j='-ǡ}; Z:ψC (< 4Ƙu3uc̉q=o~>gr~*(zT!# xJi yq8 {E`zIr1P 1so6d"eR~E̦FKED=QDX\;W ]jçwxc4 <8|/f_11J[jh"wRape"H}~qHֿ=pAK&8Zcȝv匪 s0wOpD/ \ ϿȖGTc."&߈1\<g9i}Ƙ-DMe Ԓ$-9~"6mq,c F1M46bZ_GatKBf-FODf TK,R4Vsu" <^Bm7mq1bQUӁ:1?7_cŧ-h2V$BZ2dZ^ah,(* lO/f@z3F#TE5f\bP0d GȞXD{~;mIPcRi^ ԝq lj:c[|s; s'Uz]2 8XT!,և3F1;b12xeAԇOB"(Fr$jY#wI1ᠺLm*"[r>|HbsDM3s$7|7b1+^<"YucN_Բ%FW7$f b?tR0hH&Bm&Y!G Z{~x}~{j dV2HP| _g6#0bUVX͍4Ƙ瀧uc }1Ɯ( lM/' TעǶ<@+͙+A߶A 5g&ED@Bc"A 9UsaHh0&2 J1ޠ0Ɯ4 s53]ucNJLLHd]%)SāK%5K<3cx c9ZZ{Qz/Mt?H$Nq8E&i~/h0Ɯ^sxp/sʬmAH"J⪘ 5 Xoב49R<5e+)є8a!5н|Y5JO #W]rG;,KC0XdFBlF=}̜2H<);aAMc1cݸ%FLϳ$!H];)<6e'6 C?O=zj.KFJߊcTYKhp]+ꌐ@#c1cj҃FZX6y=٭(uj5YRDPC S؂_KBNs;mB zR#횐9B)s@$aToO*5Pw\r.vwu$&8>1c1.0+!Q pj+HIOb8 IGJ{fOdHr+=?;:b^@PJ"=%\Qz:Q` 1wBx;LrtR_@NߥJ$/ !oTRa1c1@y翔>dG9@# %vPp?5`Tr4aly92ƝUs\jhn; z'IQRN)!mZ?{(!c1c޴(I) Z 1ҽ~;M:P44$qZ`x 'vM˱6)Bw%F~@11'k9uq7 V دlXNЈHc1c9d$> D\lm)7۴ÁqM/# s t3D>4ӁL8@Xа uп[*Ĝ*)Q!A{21c1shr6T!4A&)Y!-]:>\6?_P FH Bb8Dqɓ;Vv J.ƔVd #T41c1 :R/g5%!X_l_5;S`==%p9"+PB5RYCRz"FT#$[q]fEzģ~^DODʺ)ݤ4c13Tw}7E: ZCZ}1?3rѦ~Oz~Zq~l fy@ݎQAV 8@>0hD?O%4c1c . V9e H&wl9s6Y6_T9ˁ e!hdOpe6|ǐLB8CC$ dBj*,M|~까 ߫Fznc1cû J581I !RZ45OmsuЇe"H-G@S0c5($sk/@*HnH](f7`ld: O 5DQQf$S.<1c1ƘC%ѿ*no$R&?|LAI&4oU'Ҝ3[IG,sWYK2b < Lh "R4q/IhU)k681c1;c1c9XoGoT`&t=eI!!2V*,6~ӡ +ߩ3ڐQꐋN `$,ͣJݒ~KP#bh1c1ƘK1EFI>O4L 5i}.y; 0pGhcy HUAH{ɤ YcɗR.Ȃryx|V c1c9tb JHCFG)o07ܠ,wpe/X=A?w|) ;0G9M.Џ)R &#Y6K+،_O=?{?4y c1c9T6fK z3;jm"H/,)Z24@; C"U{W'"zH&';4]H1H=4#(eO5F'?a ΐ]c1c1GFWHRO;h'fSZ*șL Ptf0_6:( %;FIb/Lb =4خ,C:Pr el-%0VB[sP1'A.HRB9['+H b( rQ@A_7a\gG <ΐ8t1&rX"Բ ѿC 0Dzʎ _@28s e)c*Rx!G}7g$( @ImЯD]FEJʣrFŜY! ꡔLiiC lc1c u|3 )L 5  @ .~Ю ~r¬ݑVdh^>HYˠu n@Gcj#9J)d6#2g=wHT' X&n+seN9UɅw"R!Ab"R2ϩ̺jc1c̡|:t>8I_(1)>,DgC*5![b bXqBMFC|ЖAM%}#o2; j{$qΑL9Hsϓc1cWrGXҿܱ%Wd.FJ%"I i/~~$S9Z48PPI2zGP5(VpU:|ιAǎGD1c1,&XSJv܊]襕Y$@0HeB:,X~K{ndZFd40[M,ə(A-T1f+VgVSc>U>N1*c]퟉f4=:̚$#BhLCPjD;OQ(e03n;1/P!1!B2lŊ2P~eE3w*-@LP5fd&1c1kIU(hzyAWc&8_;ԇ׏<|;yoޯ]\ 쪥3Ѥ$dP}B}Hd 9jhߔ/q"C9`Kc1cT"!I{_<: 6 eob0N lySdϳNNgb42d1C |֞{3E9t@r8 c1c~M^kҷn Ԁ" D e^4VLO`— Ro(53KRUtrIDHRld JnhqOLE2igؕ󣬗b0c13u1x!EM)} ) k gwQ/_Vhx\xPXr M s!ba(2͒AX>Y? o̵61ݝpV1c1b CDM/&@5-Msn&M 8 S _ȽA_(3qHm/fd(6ί %irlpNBM1c1$#l /hl8p|6\tOfMEI !q@́)sjhnh~$c!@/B6>kI!Nv(1c1`)͸{%1g}JI U@'=%nԿ,&cj%>fB|$^!}@OPgen 0~7h(oj,xz~`zvrܤS^8G1c1i;QģiMoqyR٥sѿQ2)Cz%XEW=>B5uֆ9ѐI.p=^Nْ`_@[T<qH&x"!B4%b9hG+<`1c1NAD ){E̲ZكwѿAgD/W<ß.R$t; %"#ُ:sBHGWTϣ[!m-c1cYS%.7&!UP$ žɐꅔRrǠV 1B"Btei.l[>}#?r&G(pH85c1sq!% ʃ,Q<=rD0D=>Hܭ#.GP܉q!+ANd@X(?mk3"c1cZ $W"B>_.ǰ@\( (O;?Fp˜@`8NG7hX 8SRel!&9$@'3Wc 2\ag/:c1c9d!ĔrI f@kLaY%(e}lUk4+ XCzsIzz GjW3ї}stY@eC5֊<(_ \DR秜g]Kr$[wFUYw{ՊPqwc|!6V64@ћ-[R݇ڨfs o/3f y@V[zK+>`,;(?GE5dQVq*w#$緯8@%G1O{J~aǰόDL-ިxWP?wZ<@$j5ҳ!mV$7-r_pB݄(/g1=2[;pS]߯y~/-e>8) ݏ%LqlI|z"ᢙ dvx3ݣ4h_ejԃ%,M+,/_Uy2Qa1×؈C g"X؆,$e%_]mA>}2Pð<2GShgrdL+Æ2tܓ͊ IUkFDA9]}'B(d;P%;9OUyFk8zO4c9ĿO-|JLx="̃9LxM;iv:?1tf"-"b4MUyQ~U{UPu?Ny5^9 _F&1XCskdƒeO}kFԶ!?)+oa߆n۷n"GY_-+^mX(Y˪kY{IdYq9y##%5pYVS䃉~ R6ch,$:]YFz?vw\h}g3"Q1Q1< w0`ydD2 RD~-dZbks i{+U7qs|=zT%\Fg 8ٰ6ʫs{z|M1b%hsq|]%cԸ`.T=5JTQ C gAվlyiX$j>%V(\jpo*.ICPYRZԆU^ޯA^QA~#Ou=X /ܥgӿWaXh6Agt, otC$FAuX#md>_ڪVڤy -MЄ%a/xŬ<;"-6oK*c) Dz}e#" (j|Qٰ z:^-Oʿqg$ANi6!\ ݒ8=- _PY&S{AyŽ74k$J7Rr ӔOAj oف Zdu[t{!q[b03+eف~kW1@Bβ$?) &%3'bs(d _h.A|`7F mMJVᐦ]dbM%t~ &W|-IbG9U9I!Z5:CNGsF4iRY'&ά&S޸5_bZIrxp'?'e7뫥 f|1f\}nX0>bsTSPɓvG_ 11q$s?("od|r%[;E>PXvnWN#k/x7J$b,zD!ӯ߳#-0dnAyybȆbB2U}!\Ǚh(Sm<%Q.[pj#8"RqD{C҇B*[]IoM[͈w4rF0x&0&-!$O1bOqi|'| ]0eMd ̛9 F*t DCBJA5a+WŮuc"AG k'#C͔bf>?w2,_KmX"Í]8bj, H8 v~֞!UQ hWA m\E{l?ksM5i^QeYaӏac Z{q4SlKi}(ϲ N[* c`VE? P՘bD!%NcnJ(4yJErH7^6OwQ528WP˶2NxY:77S˂͌K"40h>@\KsN}gi e!e; (U;MkBOPCXh +[-ElzY?!C!Nwx(S1,?:Gtog _Y-\K%$Q{"#3(rqmiX4Vkj_tOq |G 7KZmITt^{qS>M 3 ϟ!qsmC2_\$!f܇xg.@-t9Xnsb͟+9kO:͜&wPB>|ˀ@=!TXr1Ȅ8֘h-YwG>~TKAy"C;5y!\Yፘ&Mavܱx5Mp/qC|.sZEk(Ȼp^$w%!wJDM< ǡ""^6BfŇ&NZ]hzf],0 7Aщ/M]1],׿$c$!$jA15r?~Oya+/s؂.UF62Phz<=8neNk l7z 7UG0$DBFh/*{Cm|oP \~ԉʜ m+au>ߞqLZ6V3te<,gczQ?SCQ&:Д|Iey&R&JS;5sF0o||,B4#^2 HqRcTEqBk5f5t&CHԏm2E@zqo %!oOE{ "{Bl)aߖ YOuf!al;9r>?jޱTxDl57N/mI4cQ7GXC(X3C|Ő7 4!~ ЌMv1RW'4@_\~Ar]ɡcԵ&9PFFAJף|JZ:ZBD{p懶9` L4@!#+,}26_jH^~_1˭8sa2z'^>4|0 c{5-XcփUX+F>H&DȘ@Y( mhM9Vyˣ؅Y=vY{;fnWx M_ HGPPQ.`st <5#w8iU2`&&D<ׄ2A- J-?ҧAӡB%En0 2hCJӟPOz|dAR~ A~ϡS|ц̈|5 >UBT-Hpݙ5VFнla0is[2OLc_#!QN{#$۶A\sgxA)Sϓ҈Q l[eEkXc~lDOȣ 5ϵ\>l/ y%qLѼ Q-10ծ Xx &uc-L?ĄOq{튽MOJ8sbjl +%<=% D/{fH/b/*Dc$Wy_R`'bwyCD b8(a2L"G7MLd ݭ&cBG7 -P)R}rQ/klO0yTzX@.:#+83NȂ/ ,~q@~DXj)NY &@r8u ! ?Yb=,p'z%n܁>]GDɨ͉Dv78*1d4\j,8%ѝV_JM[Y߽ߨZA&Rī,>h+Bŭ1 NVV}eLuCNd#t!MI=Q{C^5Vil9 E{ʺ xB}l!֚7Az$dE|8doKKGA3 ɼ^GpCnA1ZgVƯf筄[)f5-tXϳ8LvCmeכkV.ɦL% j+-r.`+ܐxVcRB޲YB]>#ki|q?3͎)'7&"F'|f9%zcP"[8lo&uB2db~_!qb{c}W7MrH,h[ b_%12~cNU 1 ?MoZp J 2>GLlg''mIhÅq=β|m kpc3$uOa _B}3DMށտEUu3M;pn&EzmDkyՕmB;/ڋւ9)|p]F+ׯ~Lb&9%pőx_?2oHaH,s"{ĜH}ftnH)`C}Sye̊yib.< U\C?f10 ;@N@ QӢ q~ \1B䯏f*2DݐQW=10j)vb?X발6=\h/u#-0F S.Cn>J.4_uW89"{ Q= ٯcO-3= '8D3obQ> /%=ZC_LkO/P2pBOLs-;*zF[~BD?,@ah v(Q߰pE)Kɖu9<2$ףf+ Vy+~yaTVxrp;q?}wS{GR_O-4y{=avp wA[~f}~֪% g%!w1k#|[Rh-|A~y8DSu-%2<0SDBmBnhc*N4Ga/_|  sRNamWm.<+- WϪ{x&syPCIb^]PLT] z?ߦJBT,*⃻ Wt$a4Q ', S?篡vh{nOiaΏ?7Fe{) zk5i-#0G ҅vz"=zJ\L1DP#RWR<+;5] r^uZ>x Y0Zô鐞M0 ҼW֯) ߌK+ YQm0!?_u?ExfM͞K'FlrzI^q{%ڱK'3O~f( ZY]<:p^EQNKj;UVzSq=q6~4v\^!]g|D0{b/o6./6Pz2dC鈷PV/qʫt,h[0B- Ln|\9g[DY |נr8wzS朦}4o FĸFxb6`n>LKl["]\kj=Qo3 B!ڋi._}<"OR x6CuauIc@o%Qf71j.>˶"} qeoɨlI؏u>\]HŖ[PB xzXslgÇW>- ]_;Q#d-rR/M=||NZeLĻPsay @fhC a;U>rlO0sy҃=5|TqomO /QxG~,{r{7?j!@۲El)F@цvGx͡ i1f>tR΢Ƚlbf"քȧH4W߶ܱy;mR/ .CU w/T˯o"MQOf8;q֮g% _ִ"73qax'l+<|]x#M[aU {czχ\W}' m]^i/ Pac ݙMћ ؅9 w"㦗ft?ek8؅J> Müg؅ xG0 b2gfn0MVq Qo=mΈ '%T.e?HimMO `f1_Z3–Ob1AZCxf1B@s܂\dqXnb~_io^E\}=. %~1x.Cč\̟x}`xAX|,8fFBLb 0+]jM÷_VByˆ%)@52{;v0:|0"lAn̈x=);SM cSOEZ7#= !nsdm_Nk4>h Qw1gncr0/!)EG]8 ~˽L P2cڏ{Y}A%bhXMM'e\.@VWYQ6ouAtl8(׌Q*!7rX!"<ϙ -rzqpr?P$? H/hhǶ!4zoMY㨆P " )כ31%6G>_5|.BRjg;y~ɘԓ[f;[vGofvUц!}5/9rL|8<N2Lu{bh>=v5!uaէ=JAo-vC[VՌH[s)y >&aH>7x7w֙hS[ mk)毥ն6bk|^KnKPOR[aa#pߓŠe 'gJ\l~ yy&e0~:vΧq+agSOlND4}FɞX_Z?:~b \HBW`P3SK Цf=d+\M_і5Fc,_hG^{i- !^H<cVEq#Z AT?Q`\eii^ TFD<1& "Կ*Nl MKXV3Yzye񾭿ո߹2#>Spw&2nİൟlZA%ڴEjcH~bAH5+]r9x5|>jzL( ^r~=a]+PC9{}&8DO3|~N7IݛiБkH? e0pj?ZESHi "*c_Y\hMgƏ-)d"8CtD[B{4$QcA4 :!SOyA3|;-O1oc+1<Nd}M}ש'ǡ_QOs<]jh-Bq"zTY|q1L 8CJe Md8MlzpZ6DzgoVRZGnA8'IdFUjW*GVZ 6!n w!2/,4YD3ȯA, ϖM7t ]V^:P}VM? eH]P͟M8S]ZIdP= Z6B>|)s^=a-6a1c#Fh~6MY'02s9PJ-OU< QwݤO4x~TBe#VBsVK{B+ΐA/~Y3a6pm?|ףH| >⩐RHR-Asqgᆮ{ mK,bߔq/|? Z$*k-s־ 't[DԸP N9ӡ!95n5<s e0JM/-,jKLx 7u˭vت$J8!T.'DXa׽sa8mǡTÆGmrwBHSڂ+7]<mK#$R70@OFD?#ݧ8ws%NR6as5 mp p=|L7$ޣ[AsN 3td، *V3&V<=t >9:f&8@6Ŭ} m΂$r8 aMd~n VxXo1x ӂ ?jFzDHwhAʺk0|eLp9aRY1-xeg-¢"tLOx-3 ע &R>Z>FU1V@; OwXD6)m?,6 sy?}m&k?zu6Gܧejh;tc_fFugT?2"']t(?uM hym wѮrr"ݨ" (-8{RΙrOA*A ޗB:G_at@yy+nUtSGGN ƢcA8*$Q!Oh HB;xx܄p -؜f d"iFb){޳-ČX#]Bw]&j{d^Ȑx=ƈs1&n%_צ{8K2 5>!;,<>|L+Ov?^[!b\S)5$vZBRఽP sjIt$ThgHވ6_70e B/f9k_-eM w~}o߼WD{Mf+? Tlq -G,i!t3"bO^2lLD<ƽ:|8<D(2Y?>H%ɡd^ &B|ԿPXFu\3xߚgJ4!6^ j%niVoX|3|q.AEH>8Ok+.|.:?n±jL(\[+WZMzq@|A*} B翎ß/LǡXͅEƷc{ cwOEosq:>n,OD!s>@'fP^wơߌAYeppxөYx?xh-po܂4RDY|˔W)5\ml!.S=L6YcG^_F [CV'8:"/`xO4lBnӳa Y$~ί"V4|-5@1d1DD޼# 8+$ZN\ / M{>%q,ePUݪhQ:q]4 v0!P eu[ɡSH&(ӿWL\lA $Bud9Fثm{/ɜ6F1[0lPr~lR&2< Coz5$>w"Lx=*q>+ 1ĹѦxD&~~!?K=Uw+(I$ ڻB KahGOkjLW3fTW$|mͫ4[Wi[ڷb#TyE_/DC)ff.#%X{Z5h]i%G5fKE;G2ЛMƶZտ1K%ray2pکR#- v"w}Æ&챯{fԳΏ1b xJDs<~3'8fêl W\X5'( 1FfaH}w^'41;)3«A۳􍫖 VJrć4|V7,JA3~_G`"*yEnrk@ .7=pB 7^m|TDCr–.~XurvUXEr8, Y#{y 5GVal92Ѯ]i@1ہgXcr-z"GqВa?['@L{h73cg Z]mR AKpCLN_L(l|?R3϶=Q5jB}Ȕ45KV!t#!$!ZʡVWc#݉Sag!GG Xfr;g{#zV3N^Tn,L`)@;`֧DU9Pxn'yN(>޲bSh zMa h=87S#!"ʚ#: ӡ8R,ta7zB0PC믡x:. ~GLYW@.-pcU  V1$~l`}"h"a}Ҁ>#|QmyEVz1YTEj Uby Oq|IN[?|t\<'Lh(@Z0#9 "E/Ƕs$Vx{m4BA$ׇMV|4ď9Mc0tȢL2XBxi{9܆\xB,O[5W{(LKw @hA fUWEL^Dȱj5{Nvmj_^~Kިz yMX7v$B{_fz/ pkAdd"|G-YM-%o?uͅ)?85Ϳh-!ŕV ~ilZ-D߁i$6$hkh4ox.4s!3#3?ggfD/_9vl/{'[62|ᜦejBI(Cİ!ڧ#rKIՌ|jM Kvz3c} ?Z#\ @A]sjO,5eg q}~͛̕[qupEKц-=BXj./=\m4@2MW{ԧ)|COCF1P=j θN4NIj퇤]f"K'Y{\8 ?s 5|1~]=)(!3'6<#Zu >TCDkk9S) _(99tٙYdr5*$a^j\Њ7B:W%Zѧ '/PIv#r[^Mf0 >RV6b/DƁn"OD;R2G~SifSo3̷Bq$+ oNLْmX!-"v=~x<M!G8b br> aDu3=2bֻm S`abpR 2utPW5|!5 L[c C!>)ul!GCx֣E'A.f-c $F+H)5Tblp=ߣ¹3Ӝl32q?Ll_M*w4y .64hM{aU)PY.^UX$q=#K rp4ܣ(5='"?S&_9tro 3.2sQ9;5 bh%j:&D+Aa ;ĚB%EejEeEz:.Q<7BnBFuYI>ÿEfMq*Q-@z ei iG-!2܇_p+*PWss|x>??mf U=O0>(<[>odռk:Ў7̗KtW8ۑ重%Ff b8{]CAcEAŠbV[g7.p8xտiOn|c׿וX2NʹЂ B{tKIlf!)i$dhn='Gg|dBxO7vװg@ [j3e+8LSƞ31zЉyͅ;xjk( ى;qNb&3/݇)ݺ0Qa}hA 'pAn͌6D 6D^TDɅh_gs2k)+0\m8D#DF( ӟ]ԁ&%9t"s1ff?j}8Of3򖋴RN6?)}qENC!b -0~j\"#j|̇$[$ZG[#D54~zsF%SfxF?y_I#[DֆR/[Uw;~: } s9q8 hK= I͋wͣkn*̮gü Cu@J^D 8;֍*Abσg'F!c̨=>=P>_ne#?l[({phODCHZ͵-?O[hG\_Cx&•7P͏OPCy 2n&@<ߵ^_~mQWq'$a6G,#R3ASpC_3] 7<F'L,GRJWY MjBˉqϸ@ t,}_O?z˲vt3a=Dϐ[P#47Ph 3|AOh%N?(J*ZG]jb.}|9wjG#λgta5!sl>8mCW22w'FekԈi(7$ܱ&A? ŋSa/7@[\E/UO\vy^fr,$s^ǰ: ":0 EjҔi%V|jfنY#`:+3cS/{Т"3Mg~0#K=HS>G-1 3Vc[h&MH"Ex8e#`k^Oѿ92&͠'yE-MC)jx|Q)dx>LHWn}6`79sц^XڵͿhj'&|Ҍ߫3}dO0T==[dF?U 8MH0hc%"N؈S!GO!eFJc:0K<8,Wt?~SW<#cM#\]-9qOHvHhGXbe]gڏY ͫ }^ y8E; 5/i2XB9V~g+!&.Bw*-_=?ǫzPݰ91|{bCM<bfWFP7͡A9Z3\"@ӏտϡM˙M8/A$qϯzլv @؈?wo\oE}5z~}l!|"ln< }x?eW|CjHCQd%Ad5N.Zhǃk4VjCh7[kAڊa K9x_~G X2yth=qe7zQ+5aAM܂rEpabش{q|nV'2}),#ů/VZbĢ1d&@F\g3&XQGoE3H22_%`٬nzsli޼Z)p׿ߐJՕe1/^?_ ae]7 fݦ5̙նSbLHC`i=CG>:䏡ɜ 8ֳ%zYl (ܚ"}x_X݇3=3<{ótdIm|޴2 ])LU2t8:kiEϤ=ެS%y<*_\("T &% cּt|"{fz:j:/ڋXz戗'x™mvUfw !/r>*~%k3V ?1Ur2, t:huÇmHT|Կ=0W|Ͽs? ӄHo[8v!ve"PtCc#/tZHZfxe+[J:1skeԿR9 Im 0g^ނT/Kgd}z>!߻Qc zD^68 *3y" 3 z^Fl3z@ ߥ)͜U?5&s|fMpv)Iku`vrWŲ[ӾQ8sf(X;j?Ęvt(IpgI4̭XчUP0[o=4;j: m~Hݪzg4M3ѐR2C eqGn Y9 )c$m"VP!2',nobO `>B IqWǡ,@ʣg%7;3_n̲J 2gQ6qfޭZݩ]j~00p=_Uy{ xT = yqCʧ$NcXMGkz,2O]Vrz(5h7Ճ?AQx]hAz⣊ǾCK wt~4 $tC-+l.@?R5e Iq8\Ape`f/~1RAjl-fOM[%jTȏ`<{ jGCiǐu--tj.'BO0_?^dn‡ e~'d̉bkyBԵuXzKN'Oz<= UyQԀG?SS"̂Hk !VXc$e$3YћUCU_PcĐUV!#G 686}M9'g$nueoUhHaXFUk%{d=M՛ pޏڈh{ sLs ZDHbՕ:j;+S_sK}"u{D) iAHɅFEBG=s{}h؈fup^!$d[?b=P;Ϟz>d:Tǡ8O̅l*0evܡY$0R4r#VI^+Xa>F3+uzC ibP֮|E]>w[xe8bd,P[ d+l { HDK23: # ͤv?QRW\=hP*eӆ\oN6<{k07r2l(C^g\+$:G[>~r6y??rŭi1jv~Ο#N#v/h^!ڍ.;}@c?2ZZGhg[+$;nF4RE7 G:GmHZس 1+~&2܎5FG*0-b$DHF;t |z4WFE^h*g2jsE'HQ~_LqGu`m/b/؇t垵4'4|;09  }Jcl!סŌS7pAH%YwQ~$L\#D4|A 3)v׬q~ ? :R?vw$Q+7$ֱ)"{ǐދ>԰WlƒIqe~ H+PBmmO'OaN@/qGh:珶{^ٷoUϹ//PE2!))(d 8)GeY0 3Iύ N'vH'H$K(&uk_k1Zϡ$J3~k׮Ǫ{`s 5D0؋ +$JB8 'B c2X9>Ov(DAIQf"GmD!) |ӨᶜR"7̻Lŧr4!B!ī\9:8:`7B YiϊJ:{G}tj0HЈβGg],%( OdcS Q'ZD=r~緤l<;IhB!BWgPYɜ˷ؒ{b-ϰrj¶{bMyxIq.lvFaS,Xb0cac S|(q *e wo7Jm̽(HaDf9vB!BrBCksc$괟6 \߷"7'qGUa< #b9Yi`"_HVCl9GTS9<O!B!xEOs:F>z|8"'>} ^(jȋ? E2D.Rx#5.;`9 !)>J^Z3P(y_#g>ccvB!Bj|d6<|P5_(ay&o$6މ\ɾ}RDA%izeKbQQE:6+N!B!+рvݐxbXC{K-1ZF8(3Hs-v]. Ʈ"NŤ]Xo=?r4!B!+(4{=m<0Fgn\ |MBaKbߩ=c $5S悉D&Ŏd4S^Y9BSX, 7$4!B!ī'4|]4Zܙ } M#J+δ$q 3`0̙ᬲ82`q,0) -ߌ E%ǧ7!B!xx`f8×~[j 8v.DnK}rɥLuZ**-.Rf)̛Ss/(]`;,)J'o+s]WW_B!BJçPbؖ-"OpyD.z b(u1__>f~]MF2 RT ]PB؞$" (^bq] V<}sI.rU,\.SB!BJ5|-\("aWt,͌l"`E)aA6/tԥJNV?;A~1a6G،cGA?+v3bf<}?pu?3!B!xu`@Kq"a 6$.\Q%a_)Ğ\ME˅KPa9.p4>1LtH3V:<3f݆yG#r4!B!+GаX؟ov+pdcqEo&TŽ#?0;}H dR?DJry1u'AÔk B!B* W˸hb/ŹM r&2LK(gvBV֚*AU(:\: B!?x:lȔ?`Qb;CŹPL ܱ;nqmoX  B߂ iK/cXQ %8Ty~P!B!xX}k %<'2$ႬpT"K>"˳CQ@##?cKbB-`3ߧX b_vA'B[6W})erwZ:/ kEE\77O !B!p^o֢d?`nxaZą5vaUm1<"Q< `rLݶ`U1PF) 'l4A\JoK 9Px1OM!B!^>yu=Fa bOXV޿*vkklP jg( [2_CrGig 5G 94hDV<<]?R:C&gh(WiWn&B!*&J9CtJ<:E).8pF?Na*m^x tMAOR0C.9M. Gx_XΐD D0y΀״BG䭄!B!x%͛1]"cr\Gt_mcgXk5Ec-:H#$?))14ĭ9PlK%6 B}8!z8W90qs/uff B!puJ bWt.>B}-% |۸#ckK xB 156/0QItq{r'pzF!$D(C pwÃ~Ҏ!B!SNf?|:uT?"*‹&U_tG5Ź`7Dl</:]FwjH͔`)0Dwht;8)r'JG|X1 nbF]?xK!B!WW׭i~shOVge^. 4I\ER[{( .n E=(bd`霞vLx+ũ#[*HpKDK B!t>uu=ЙB6?<sV>x!C ,)vNv[孍Rd|#śi'bQ0ͲaQC[Y-Q#*kŦF0#4l$D'TFB!B6?qs'vEp-ŅI/-ʐ< ck/zą8Mh@X, a }9٭@hFOMD-lrV Jxʘ3 ~;w25!B!w+ZgHG~q0NdZ(##l&f{9Kxs3q1%Ro#)O4!Lل00Ny^'B!_^'kk̀{)a XqLl(X-$P旱yX\ir|?\9İY͗\'`V09 l7(ZXk %\: ӳ'B!\fuKbo%]GL<}va`y(;U@R X JQ _({mD9pm̦y 9(끫 4*@tJ#`%ZMhI/M?F4wãB!ond$X\XkF\EDxZbXϳF-x>Oz؝?@oR,ZϢ$(4̻U%CB?llD pmtEj =Â1+.(A!B!>|0Ȫ2 b?Q<1s~e`vXm [WY$nV5dL-d{V#,bOE9V*O(9~!,R"Eq z xEr B!B?=>q*c'gKY b؎Ecn{Pck$J#8gY(EȽv~SK"#R0C$+Xn]y͢Q½[` S+nڞB!Bބ.1bf=nӰ (~-\$.`K|<15F]Wx:s -  2V /x<4䖈R~_D@[eCyČ gR`,̌_)7| ?>P!B!>PBYdL q\,)4Jg(YD'x"@a/H;^haGs/SB!B|@혢?g1UbXz|V孄Չ b#kMa*[Pv-O 2Yq naUu?belԏ%s!9?BԠGre@5gSB!B_Έ |42꼙mf%l'2v5q»8'ie`Ű$,:%P2 da< #4YD"2nX>?왶'B!57}snj`@| },Bݸw̐m4v~q Eb/]]vŒ<ܧ.@eyc2*hEB+ȡDw/s)#I`p !9 O=;=}AB!Bs77a#na0.C~%ɧo͌,7+jBi؞eÖO;Ɲ3vN~NLH 6YPnNϋEe5N|Biӽiwa33g)B!w~60yƇ4oB<xBX^&NrK?"^3 = Q0Yv{t0cq7.KTeyƓ>hQlQ/Alo밍\} VB!B~X8L w\}c-P{+hfDx"Pl#<TZ:Ͽl]£{iP=(m˷L Ź,lȴpDi͘sZ߇qyD:ka5|QB!B77ws`، cIO}G(.u[Nqa55$b07o(r>hG sFPXci?ƀzKBg>_Ȱ% =LDlx2vavk2B!k}vX~(Y6ѯ-1M-l3?QɎ%l Up4̶PŻ4 WHbK |ONZEieZP.5* pck)R!B!w01 [c<}a9j͘DA@Q?U|݈aff-v1DD?)$c nZj#<sVd䃘; >^J[wqEXlG.=3OT!B!_s}ѫ+ }¾K -WĄuXl FX ^}Az@, j\Tc]&YRnΧ畊XbE g|H,ქTѩ.2U/j|KJ5'B!Wz}8>f~~j: t~ؒ 2lCrQyN `Pw(,#h fvSnK"!gZ0CXGJǼF@&B ǁ0O={|֚JB!3CTx^K js[<"JĘ oհ%|Gd<)߀4"ykQ6Cv ._bKj2F|p70@Dq ͿL\qOLߡ8X/=A!B!7|&DŽِ} F14Ay͑ Jخrܲ~]Pu<=˖0H_0I":Y`"Y$gpDd:滼=P{$F뉏m |HH!B!xyw1W-EX,u_ lV$3n~MQI ,z҈nOPՑo⡑p]eF Ѣ" k  ENæ0;/a/-gpıF/<>U!B!|#W'wbvPXL /8`RRm]X28a,X}"Qz5Y*+`[?,eب| zNbt~wp[8rjU2M]S Dw>$0;VfTq\>?W!B!xKaue'sY?z,3G`!r廿WbU֧fU'|\'f.k.2^B@ ;a Ȋή#Sn8J+yc}>T.F?vwwwB!B2?~}cWC;Y/5! -#5 Hs;n& *z/v1 }`56ri:Y!0aMf,\j 634M5em`{xl q SD '17=v&',Pdc1G#4t8J Gv&,0ffnB!GO&ĮD_HJĘ Iw6Aˉ ebm%!wV[ 5 3"a_n=PmNK@Ki<=a" 19&F5~ì%5!B!{_oX"Fz5tK a BFDHi .l%KĺQ7` /6}.uiJ=!0rrֻx=QQ9z`xCq& !@+ !B!{7Z;ٹp GZ$ Lyz E]oq" ljx"K<0 ޣu9}-WN7AHxB,L)|a>,o*$ַxAFϏ 3c-bwF3t3{X!B!k|zxN]Cc;_\-Я, QB` - nPrʒQL [{*(\i|F/XxQNiHmI)K /2mFl* ʒpDne,a ! A:Cz`;Cg޾A!B!Cڗ–Տku`̵#a^}=rޚB^2/D^`NHE5y$ hYe-\^B9 a&)n+,8br_E<(!0&Ğ  m>F ]HA8&ъqT B!%pECW>/D"У}Rf({ נ=M/H%{MȂNwR EYt 8@ԙ,4EP(mӆ<,2 ECACEXߚŖ2 gB!B=-J" 4ڪ^Ϧ ImZ䧈K|^Tn |{f:_Ew B! ~dcHi1`NChװf1>)lŅ:// \a3w餘k32x?``nI2Gb$rtGMяDTT`X|F uSTȐXF !'U!B!_ 8~&؜>Cڑw n:1dO9$r~-ƄUqsTbAd'@Cbf#q'`\&a9p#|_MAB.؏6Kc)Y F28nc7oB!/KqPF@ GZr }jЕT`_`irdIgxvmn"ߔ}DSej^ >E,T-0  -ӡ`>L MA) = n~k03B!B,>s}ۮM}_Nea~XAXIfV] :b@~疄y@^\A) fnяn- Qf7O/"B!ϙ~|-FDE#Zot\|/.TQR oXy7j(BJ*,?KY ^3lf@XrXl Ģ;3.adu`&\ ͌] >{PƒO W?B!/4B&0VŔݖ6>1̃1c_ 93"n/TezYzڹaT(L h/(vĴր,,Xu rW%-ɔC9kQƻc8tFKoDq6^~:/\!B!"yWg74im 1;2/u )s!@X]0UHxPPӐo@6>esչK e/),yfBZ =ur4,^ڣ6Kbbazr0K!B!kwCG9Dڜ漛u KMH SÒ#..ׄ ?QqQUߎGC [j2HOhpKI3#ԑO*'b<x(pF*p1`)(h66"`g~FUB!B_]݌{A @c]` C|| K l"`<,".,i ],,OLqF*5`-0RОWm$H 0iSq8Տ*<.sQ(RbB~[F ]k2{`Xԍ~kPr|/*C@2F[u%"+Xu3/+QJ(h"h;Ycj'!Te#q.O16ߞ A q[’qEW,~~F" 1 c#2Yri3EldW_IB!BkCxG6'8E,7 nQisbJ_$+l Q%|e(y,8A;)3e6.0މ@5Ӏ]B>%6";٩?ؐzfuup44ڕ8~ZF-J;JSzb~7OB!Bk @k#De-^K,;>rvK>2H6zX'tG"9Xjt($]`9gv.tm#1_`\Pޓ+EAٶj/ҪE}l?&B=c= 9z.osd4>{gZB!B?7t{_;j&1v%Ùw${°ã*̈HB_Cz4=4sCD\`$=A?cҞ- L /̖ʢ/EؒFi!.D)?`?6l p#^UrBvkz0+=>40o./W_#W@!B!|tՇbhCRnI`$5s%m8a|)Ƞ>u.MeԷ`?XV!J}4c7_ߗ(w]{5*$RW `:'<7d`qX,wCNh䴅ތA,Ga0/[~\y2P@_$"7ut;!a,)w,JDSj`f#la7*k->Sd<x'Ɓ?8;/nwm%ȯr͘M l%"K RϼFi0/u B!~NWټ.Ml01v%cF'y4…ɿ`X4 )=yL ;"F#̐B)wNݓ\ QYxzw:Jnr~@O{sD*78"7 ia]B!B?+wӐN>} }^ 0 |w)apF(B;S2{\&5 {o. )1J, 1M 2DNd<>Z鼰fD:*X@ Fϔ?idaTҼg@g:2.7B^y Hլ[o>kM:!B!3>>6ډ(Z.OeaX>Ȁ<8ڪ,)XiB;wL`<@`"j"bs97_ZDžkz2mI F.*<t}%20Ld[QV+ rCbpt[N 5ӻvo-A!B!'Ch cVpkG.cgF)<&cҟ =/, py]K+ ؅9ȳݖ<\]#xqI829@՚kgQĞ$7 ȳ@|MC80(\A(#Y)k> $7tDW<~_WXB!B|Ï]]\$;(ֆ?!r pkkmVZ)[dp\Of_cn^Li2g݁-kӽXvBaɄ@t4OﶪYx,uU{B;nyn3!!_M؞8IYkGEODP LSôW=B!Bs77_C8.0|)cKo#\05tBQ2vqIl7wD .([H]B| |ɢs4b+l> /[ǨqfY,[PŞ0S 5Ɠa a76Ă(5 Rq(J鷟}*Cڛo~Z^!B!|tGAHv3p4}0cZQ0s1Մ@:|&)O.l[N'> ߗ9-nKeϡELdX F %N_%NdGv+ ԋ;*IϷ5?|Tz I9=| [ƼuSC/Vm֦7kmd:X" n|;C !B!e||v w7[s+cjۨ1G-+<"=[+^ۗMmNK |e2 [#sM0LSCx΅tklV$lB) 5B'/}wO "Y S_OCkY#9L[5ko_]oBr!B!ۧ6ۘǐ\65 !₍ga|׸fQ]3%X֍ݽҀ7tZj儥WQ|Lk@R%2[,K%,R#N"ŖKE,X"cHA=Hp%&Unp,P Sp 9 дX3(R!B!vç'NBk3Ϭu;5BrDN;C0$0?T 5b1 νNNF[0] X4PUk`g_]Dw4 mFy:FG r}*6E,RE:p 6qGN/N H 9n| 0(lBŗ3 "B!̗oo|{z7 @~Lgͻ05Pc [s&ak{$(!FSxBޏpD=9 ą2zgF#}~mX(\AAº1A19vvG,L0eQbFJɞ$Q'`%y<"VSZ3Ay`mnY!0 m3g@TŊ_yO!B!8RR h!n3tؒ8.ypyW+F׏ٓ5"K.!=%2P'HâD8]"؈Fט[<6pi²2Tϱ 4Ӌ4a)^.ٛq~󃕅*H1bE]@.LiYsL l@[=è3C"{H07ǯ_!B!᫫_|l]A %ч1>u qV.2#[J<瘃IZ,Y>I.UqzS@K!ؐg@f 6 %DjÌn+#B!xuO\]Uǁ@L9+-SEa5LC\9 -l8=sc^ F [k lKfŋPo\ux4oK"ziꖇ5Hrf^q٬AkZlf!hjElL4Cs C0Gon[o]IkB!B\g?zu5VCo}E[3?_?yNghÿ`0we`@mP>C_"֛}}>Xb~pd(I?Z2md`Y2 #==8xyB,^?_51{.<ުXW13B(%S ;D2T釔|u({6x4}7|$A!BAdϞ}T^Hy80BST~I ֿEyNZ@ A3!#hc Z0o 0҇mBw]%EtsKe}%r 4. y,\:y ME C_a. =4ꊸ/%>B!`ߙ#e} o a$oy"Ƿ33 YD285v2%|Q7(؏`V3v.œ=l6g#`5Q$G*D,uEe cևbʰ<"dA+@ i  4ph"\{%R`kB!B|@9}ccoiؘ> -/Fw!ntc, %p*:s2xJzBef bI \pZ@a‡~Ns[:9wj502wii3ztVGufgŬ5۰vw !wkB!B|2g܌`]PTrUv%-y7?t ]vf~[͛5ռYkE=z!B!{z#rS>>yؚ5B)ғ-$G?9˥t’zt[ύ4ɥS4nY m#Uk ahd i{%K\ ^RdA SYԙ$-{8n~>ف46wڀ!a/6W09?zGi B!B3?zGNW)gE7#{ʼ0? Ih =1}$PH)8w2ˁ khG|`T1_<1ORCiGFCx$,28X _0+#HYo1 6egI`|4>oX[N\rr?ro0N1 }ԵC*1/4WƷ{}7N'$B!x?FkON-SOİw8֧6D7)\hpKiǗ˨y@.A -5=Y*oy~7Q` ʡ֫|3,v ssoh0'vp2fdK`A6V r}a.z|,F%9X[6Da4`(05@9#!VƟJ~w>?t}B!/~tgt ǻib&\)cK &؋:[N^H8͌Ϳ4aGG|_)rf9,&HRȥ<O+NG ZQʥv"6oPl?ECtXc#<076Kr\x/е=j&F lC}Y&F!%G=o~'B!O\_[diں>@Tg1Ok0?0> uӼizjq@ ;C2/=Y[$°@^nd79*q~݉G`11[˱ K Ne)0|!8&@_dKFFC*̹"nOG&UG0f5ΐs=]%B!xjM4.`pd8Nf'p?=nNiv>Х -<uoI=5E[f6 הr(a):8~5V Fc)g.xZ=Ģ}̽ ;ј!KtwZTahH.m'ϘfUwq˱Rނ_n`Ԯs.E?aSSdC?Yٝ<9'j0{wGB!GNy20(yNYD80lHH~?v"OpTm C_@1ob$~#%x˼gxDV2pO[\uYT:ng"m#a'<~Oƺ`:KXk#aى(Iz@=I=?R.v~@q[HXaQ)օ@/5.:$>}ɟ3!B!_:רa|q_Y#82#!с6No<ű޳!`Sb]H2\7/RYú4u~9󅵚F/[Οe~cubLRwh "BH%R $1ɑZ=UC@q,wL+BCt8s8zM0S- k#|w:B=Kt\x~#N炍Єna8ÎGp6ƯJ3 Gc/OW[]w0ϿI3?5눖 7}|7 B! w?yb!5MhCߦTb$2RXK?%fapHt= `hQi&`sv5 %W;$ nHJp/Y_Xv1pa~g?t<Mc8 'I*J 0%ЊȬ}OKKj%s_WEmx7!)_v44t;q chԮh-7'vSὀ'onɇ?['B!SWWO=J#8&0H\hi\2<5[*C8"@ GAGG*,yED;s wK!B!/(^+^/taO82qĎf Ȁ{. "x2B(W'j ϫN4oZXaD0|J;e~ϲ=O,hIHccp[$9`Ɂ X-yK5y&58EXpR0(CJqzgc8wR6.V GO΁s_h}6( yKgo)B!ˇǏN[xp1fؒ8HǮf.Nh׌~q{cHX^H%5i/hJO2<0^W'ysDc;U8phnrbP 1j տ̛uvELo8#K_1_Y*ok̬xEz}ʪc6.x<glDHjXyFB_!c †5 GICñLaGF%u?wَv6l=ny>.`~#frq}S{B!B}nxZUcgavLԍӑp(iHY1A)$2&|j ) 5ܶ/P<hɼ|_d2̧%b̓(ono5F(&FΈb,"lj`94kT!1t8|J 9x݉plG-560 %v3@;o)!%hapcx}\8;ڱR;OA/3wUHB!%+8(`)F$;r )/[}rD >cX*C/0!{Ka"lc.9dp\<E4fc#xc~O =wI4fap+Hͦs[i.\˒36P~V]Z ,FPgtH2'cאF/.6)z1yłkO?v:~ڤB!B\Ov3یfBz-#^4 cB7/]P刱IEeޘ\fGi[cDR`fy^6.剾HO̿Li~'Qv,p@nEȫA`Jl𙦈R_O|Ő<$|Ͱxr )Kޭ#t @ttrw!uuf Ig7?+A!BAWn(`|b`#S!Gt[\:CO6Z-Ef# ?Bْ0hKc$N*&;;6՟p.\L๛4kkww.#pu!bx#:#f4-2``4[{6ͅ|2/BQCe GCm6fby(,q~f 8z+}o>k?ɇoS!B!ի_p;Yz\n8|K$] BЀ{TQ_(-g1`J@t\@}.w02dߏW zB3aǟ\O#$~-NHsHw3툊l Tv27oOB!,9~ǯIbvJX?+ 6 #Ƅ!"*C0bh(1 J<pD? ;M$;G0le YelXӬ^S I*gg ":萞rO AOR˻iJTWZJ.TTX}])caTH~lPuOl>z(zDp{]*xݸq;aq772#p`5758oRQ!Dt-viwε)<@,;_HOȱ eSْG҅y( Hyۅ {i7]|*x|,A|p +$n8 fgٻay=Ua:ώw.sC2/ARKu?wo}_|ߐ B!ZonN!1Dܣm }$:hmOr.CXȿpi2Pi^hQAK{M.Y^unB,7䁶lUa9q)4 /dG ]0I;}(GwFʭA\σ%Ÿ syl8F~DOpB5X kh0kmͲbVXpvcRXJ?57nE1 nvw]$Y^?uGZB!ۭ}s77WYv Z}Gb0.sx%*sM986΋ZJ]5h~MwCȾ5Wtlj/r߰ˮZ{|mE(L= O}A v͕G%{뱫0Bk ng$KO@yÈ<̦qD7͛Gk, nfeE0^ } L6mN CeL؋ GvXZ02w[{ay*ˀ[Yl ʹoБqp9p*7׭ @/#rvo+Wvv,uXD} EHlh$i\R_ z &`K4,HH@əq*PߙYUw.wzwZbL탵Ƕ!I^(-/" +DF#Pm@aGV$ĮW"A~"B$?^xu:^x_ՁyVZk hUԺKeh-@v^%udADYQ!m+Hݨ\¼%x|ď6@IOVQ*`lYoO,;@a4NE#)`s0@#J!)"('APrB#0 Ep~= XMɁ#f-n{v %yr!^755nս_X!b ȴc3NEO|Ͼo~5_:^xu?@oomCaMmk%h @}+ rD)*C;,jLdX_[8T"Nb|n@Q/ 6RT$^Ï@&$x#tpzX h) 6By~g߮E8@Ž(5P5FY 5 ~OsAcj,[?BK*hxY kʟfv* G+ʝ`}?ީ_{Kb /KqC`R*D@tCH& CRwCR :%"8:^xul7V jv X Dh,hDȺH㝖_ [HU4An% Æ5!rդZQ¨J.+އA#BghǛJA(4xi0~W擉ol&~W[XOԝcB@JV ~C]^&QV c#tON'efB-ڋ[IA0TF 'ylD;m哝%5'iR!Yr* w@bV#PI:@\S!#%ZX;__o~w/xu:^xOp.|/ 2&Љ ȹ .Ci6wJDc䒍ФKZN@oiw=, 1L 4pbLn *v]{6$'y :k'S 4He@@ٯ,0%HPMC:I؛}%)1&a@Ago,}^JI6.%"NC+YNþ34JB,@c4_v:Z`Ҏv}/X[$NR;yY5=A]z~/Eqxu:^x㽏ψ'?ϟ+"w\iz]BTLlP$T GmX/L^4ђUrvэ6$) .[ym!N?>ӣ%ؘ XYX}<T8b0() dwhF eLI 8!d4-fzoշ(:]l\`rVi*E)@4RTDhi|z w"C,:6h4b3sJp(* %߿_:^xu:n/ooϙ<֠f:YwEdؠ+5l##(~rVLk82htI#qst`Ji!3<`Eޟ́h:iЌHD@+If!p"X4 +(jRe1$/x #xNN"iW9{~\/[[. yN4EjJc-*Y3;&Xb} ёي~Y^F&` qfTX&Tdh}_~_~|z$:^xuqm÷?|߽}"~h`q'R!Ͱ w26lҏSс<2F& H.'kG{#u 6x).A@&ӻa|5,5^ 5}.Y3`2FCM D^S#Ē+ahw¾5B\vw/GrZY BM"tCа4m %)ˏww~x^xu:^9?}GJ!F^h? Aa-Č@('^ ?nЦJWJdk[+\he@Qbt mFI 1A` s h#6H4ߎt썚 `#|? J8 50Y :33UAƁjKEA0d#8T.5e5MP:\ҾÎSmlydxs?% -Q&Fg8ne`_b RVP ձu:^xuv_ӧ_|zo?}5 )AaON&dDbG`j% dI * ]"p؈>!֕]PcJy eN^@ֱG lLѲdgJJҴB\F\lkE 3 vd,A<ñCZ6z#Y2%o~˗?|e^xu:^i>}oO?{zp&c=&_" ҐuhB@LAh%>,Tl}.@&D(A]P@Pe8*&xKmſvV^DAxSğ337Ke,H$&TU#\$Qrb5 /?~?~?߽u:^x'w.?|O_oT-!nJB*>M&jR "DzDep \:~ >LD,|: S3;tp+& OSk`mсb`oforlǿ|?~T:^xu:@EOh6 ٢{_(R H ze@D (JkhIAdb a#,%UeXfPd [ͦQ Pu+k@dj Q9tC>2o*:ſ V&:OpB~ߞM0*y:{HӫL'a) _.G )Pp |p~$ xZ ^C6p4u`$}_NPkΗt(DVڕ*ԉ#Hgg|G䩍x$/e}}};v߿#G)Y]_yu:^xCQ"g?G9 n!n֝\ϩBDDE^P9!%=IE`}%"C׀.hR>vBi!B2U\Qd,QVmmށ T\?0B ƛ6~wW%F'vZ\Mlm6Ip(kK?U\[Ahi ),spn9LdR Mv?u-t(P9~ 6[oV N{0@K%)`cwh HUp'B8a(cvzfVD]zC :A"TE%柈O2JI$fE6*I.>2]9<O t?%tVbڃnsVoEs>r~x\p'sy۫x}3 <ꣵ dDzu/$X,I1 Pe(TePC$5 Ap ҫ&G'C hsza@#_, };CJB7$W$P4QR R =!S,DL*^OŹIy6plD llQUH&zTokJ=1yueD7XcA3 , ,Z1K84! pGت$F[j Β [q`CܱnК܁CK7a8Y4 O6j +t;_ Cݮ)=,dH ?n8V>xI:Vœ'sɜ|?>,-L[g'$ A;nzUdK$zxL$/!2 2}N[`܄@,^bjw*՝ѪFڢ Y *q_$^2H,2H= 4<vi VEPmhF0xINEU425 $", A$:=o 6GI93Zd@&o\ONTa+%p) @!tt#_l &.E8L" vƒ B$8!vbo}(X27P6J9״]馲 d)8{'Jd@\sD[LVct/$xwI}sWqU<w燏I̹'y9p?d}2;oӏS"lg([W,,C8OR!24.]GQph.׀,n(떼8T!ZҡW'𲋝<@(*&"Y(_iΠ$`2CFw$BBa&Йs0-0nuUxR ^>^*@UH9CGL97K㝣EiqXJ1aC c#n/Ou}Q=A Ms:oMm3i +gkbL|Z*4R{PUy'wUaц<T"l%` ĝhĽ ty*d|5yqygu>z~傞f;xh BVMa@VX_$ Ctkz PJk PD&?e]@<RrBQv`]-e"j Y+q4+҈Z +P0n8{p=Yt OEO@"-w<<30$ _hqQ_ޠi3( ]{ҌK|'I<{k ` D5PJR1qd<N^,)rQQOALj f^=f=R9@'#?} ~fJX`WOϙ=svyaH0?9s+<<Np73N̷c{H˛=7Ԝ!_Zv8@/N_{pt91k B9ʐ/&t\I|Ea;Bc,dzCTRC>YdB/][1  n"dNe[rvEM[/%nzZf e14!DJ0,-D΄.fZɌq/m2Q*HV#^25nyPC"P;J I [j*%*/ JaP؁v:T!;aCuD2gkKzA+8hC'20XrA O9D̓.9qkkHx|e*}w3|?OOv{z&6o~yomY{mts_ '?;l_ "h/d2?Z4d1@Q| jh" 2M* ="+8HU3/pcr$AuYM@ OLb3@ -:M(#i(-h;h0xbxI2gy2iKBp\ IoB*=R KagA~OC-euUUB==ޥB: ;ъӡRBb;[@4a C~]ǽӓ9\-cORz«}sjb׼3`zx^åSϏ~=>ߞg`8r44GrU[H¡&J\Aاt \B--MP%}x VyTU # G=uB!XW(1]1L?bFgp [xR dtϖhHRLf@F^o*OqEmC'I<h3RM/Z DDD;.(X h"@^4Y6s7͡)zZYc0-ِK6.Jd }X/yG Ay8c@43n hZ{yj2;JC<ݞ?twN3^>dx~9_=6OU/kqSܑ_Pyze½k_709{TnCD+ S hYG/ {~*siuPt7Є!fDm9QG~LK"V6ܶ"+s1":%t &+0 FpQL230#Fjdj @E)cQ$?D3NeOx XQ%%X GHuCDEi*Zz&ZDiNB R -` U 0GB?a-/ zHĤx\LTԥcOr@u8 4S:XN'K%=!n"'2lڰCJ(\jm&jXBGdnD̀@{EI r9绚t|EJ7\;:t /U7֮r hYg_8b%Pm}*޴^L&F zHL ۑHm/=7:BQL\s J0ӽSfA?$q){niz?#hrsA9<@-(s 5,'VEġQv8zU--{ z%s %P[Pd#*de;XADA 1H*JM:D~>i$~>`.:Lix<#H47> "<f(i'1 N|9''L/RSAO:L˝ГhAzt<[d󅢶Ɠ etG&ى-ȃxo<0Aƻw_Ȳ}La0| 8zF 23_Dgt|- NN'|+(#C98Dlj|']w 3(IlϏpgěGxv"|f~9_ 'ԩ;::rB܄DؗoV! L 5Qgd:bxx`:5PUogm U|akE=5ǁ^VI 9ڲ +sP'~-H|7<*hF7rAzG]9/de<Ǯ @hǰ D9X*QL tvSmWl3*R5$np0 ꋝRd} }ؙdiq6Jj2E䲾 쟀dm4Fyt?q #+bw%ׇ̈́xr|`anB(s:m;TZJa[ޡ!XJn8j9l:fRkx&T IJy8A22 `2$ %?]6e0Qw # {vw(><6g[ߘ@Hٱxϣ59O1DD.?j֦tJmXtPWjy;t4?-=mjRN//~hZTXB9 N< lYa'߫0?XI1UX Ho8Ekv"eh<ٺƓR 1<|y1R< NoE7ҒI6a4Fq*.@A@=tMᖈndn Y\0w3o H'OK|?< 6?6fۀ3|g xw(QV j}H H =P y!(K$z0p.PY&!%1/Z,lm5"/0}?z;@N@q?#п#[籡 C )CʑxLGCHq]c?@" W$նͮCdìIk0j=Dei#A HIHRC`̅q?/=RJk ⏂ cȨx ̕sÈfKM^$: t͏iēF|tByOd=?SxO5wh#: TyV&I0 ;.P$m=EKF兦X!׃D.P3 =‰ uSUIq2MdNϷ#7>Oы7ir}xZ̢1~-[涣H97a!8^TucsGyjpOg Ĵ JZ5I PФ"G E{} B`JMq6t֥BJb4Ԇ,2`iY+km~|7ȶnf p>j_IWQ-0c x}+?9fd?& 9ص8aioN"w?4ra=Op.͛` J$&"h!J& Z| 5Tl/) M&PLBR1j~eЄ`zG'G$","pa$0N(ݪ61Ϭbo"H<`'+| = T ~@'HPcU F<O/"a~- -p0ι#`' ?'\RN2.fЛV/PBr_ؐ7#'P5#D.p4'Njh@Zؓ[3UJUܞ||B;ſx6F 2 İ<5|W9 l_s6K4݀`D¶&w[!_ {Ϲvۦ~X*>]__^I|9'aԞ#9_2;yG[9QJidZtxȮDd ՊR:JpI!Pex,7;&2&cxsƜ³A6N<,D`0ö*H)|^@ =H򐭛Α-p]{F0! {-(}+hC C/Be,[&yx~#DV%!=IR<퀏g l7D-j*n9r((tM]Ǔ GC ղNA&TH8jڂi4E?AlQ==`  9MV&g|ft2@Nv}kvx᫚Z澑}94皻=*;ΟJdNXu?\p;A?3BE|/|gsn3޵S93phѰ^zd'Dv#1u@#'D$_D\Cuc`$^Sh U!UfAD~]:jCd+$cege`V+1?/(_w_!'VID@˲0t [ހfpڇA 0\{:Aw鼪~qO XAOE ~Ban0 P)hNj3/5l_oK {ny tƗ矽>ߣ:p|~e'>_Sp?0zw6n2Onk:ΐ^m9}*o]2;Hh 1%br sA_ Zq0B aMrgE[MH#qTdXѓO{p[r(g-A/*dHʁhz0k_NO<q5=U mwgopɁ<auxC%\`2h"Zt"zO5|Kϫp*Gs?dɟn9?|+ ms?z3ۭ=Z=Q#Vx߁5V;,6$p5Hp @^CٺWѲ*L7ͣIt`o0^A/TiYw?/ ݡʮ\$+9I=K? a~<~' 'oJh*Ah R %%=5eUő`)bOD+y~8sdE ޴)VrrBoAn7R6.J-zF|^t;NAU-`j Y "k8E$ObxR (O¨w1 <_ o3w5H>Vx[p{Dz?C rJYCb`,VO'@ ;aŜblUEHI??M\`~|=rgo7ښp9[*ǜ%_ F]¤bd8>8 P4KR`` B(8Nԟ4 V%EU"m;I9_3_6~\:~wTĿkyNx94 ^T6WU@ z٬qllcrzO\ӷ v t@zJIK_fO7 4wZB5 Q 5A* |Sj42l+paI2rvf*BڜqC>xa#7F7s%8î}IguG=l}hCG넻3|<Ětkn_z)s~ koIrgC_rB,5JȏH)^V:k_{-+S)YCP~Ae=C d!Rw' jMDgWЃ\`|h*[t='-4L^'(OK_I@uZwqC}5w9-px5៧x]#Z /U:̎Yϋ$qxN4q|S`?`xDs 0ϨE4=L4y:/_(>9z~?i,JD~)Sd 2yHi"XꁘBx0_t C) %LNb KxHфc42HέtP7 ;@ `_aIDO#tAgנl\r Z8"0u O l~d ϰ.<,*it *P`/E( UgdKTy[K_0$(-go[zXO6^_[3뙣r{!Mx$|;@aQΟ.Y<&nUV懇oYǥI|/FZOytO DDc҉j$z;z_$x}TC* MB 'dԌ{*B pZ3+k䟎sAM_-M4`]#pF>A _G7y|'OoV9QǬ~7s`'{H֘02A) L1A4(SE/BDv1ZKe>~$0sUdx] S= s#Yi :B=x?<}bN2?:%xT1F.ÒLNx {f3^MS4NO9o7gf~e̷s^_#7-!{_X_2%x?gVDFg񜝮xp=&A/`8J$JJHV2㟷/RV:! ^\ _' 8SwU{w|ϩE'L3W+qg UNH<N'nҟ:,U_8Г<'R ]Q48O[?3z4x%6 :I?q&F'ϭ/PJ)R`*)/ [GHT77&4eO7x2!'ie,d4AzPhF9rdeި;.k.0a4?g xFz?u8܊c_ڄOy5?<(<xIv}s݈36-%hBDEu5Єyxمb:0&lR{äLϵooK^wǿSkOEo|xA >yd[vk>;c k39>.ˏ>ˏ.੉ I Јv +zCMjJO#.p$2yZG6+ xô Li F ӧS`|+qNOAYhj|fۉx 6% @XG8MAmk[2?!XܖNht'# ijxZ>Ed]'B v.+[xnb?3Ryt[N)7gO% ⼜+3ϺRT?FVyX 0򨫤9<<d\ F8́'nqd>xjl#4[7j..6N9isC *uNdtɆϨ́Od?yxN#<0gij<<'DлgN P '[BO5I9O5^0z`њyr=x͆ +|Њ#k($()=&2_-^fDBr<)uE1ِ5C%AVsб2Yr׳'_H< lĦ/s:wl7MmٌR;#{Rx xF*cȺŜ9#$f{)sz1ɳI uÛx ۭS7!;lk_Eu#QXLp #V`" y69 <#<?F9d]|E<3{^,>y\ 2E#ҩ-ʥg̞^X/pmx:KxDΓivkNO$'1M,ް"oStd\l7JW Æ'@K.m.<|l-}AY1xjOٳ=AutOr<{d;}mkلO%j ZOK"@"gş L ̭UsU%tvt-,3CL=I# ˆI[d1_Hl?#<.71ÁKt*--+8~Bu3 (U.V O dwMA>?"a{'N׌-߬-LgʹS6VT5 zI9އaŽOG@PW]tSi'G 3 nфYdSxKyωe^gS+3"sE4nvMxFr) ' Ix K_?glx|yBYJi&@M+MXhGOIdBk  ˨&Wh倃h{+B\?3e xDH?( Ǟy(/6j`Q2"xMkZ' {jy!{w6`yvQL58z0Gڦ=.-[2 %>^9|֮hG9+bxbd֙m>%hmOREq.b!“/@ClQ!EaX StܚX_Os?q^q h}'?Y지ͩNc'z5RDy<ftx&SxRg~8㬈d w7 ,!袼C5E%j>r.~,Sh;3 }e>*%ɵ6f&: epy CA"6Yijt xBȇ/T?xxS v|[?"N~dzbWsdH,aܦPo);1NaD<œw yHruR35~G{^kF-dkeLteM"aTispO܇gz\<)Ɠl<99v@C< &RoG'Q'DS`)~x*c< KKx0+M'I4jRHx:|%.JvO x:KQPi~0d=w*_0")VPȞ#k! ku^9cTQ=KZjwғx9<޲w)3_"tgxiO=N%f&ו OY+~f|݄ `cLPM5<5\JxZܠb@`sxm}g,#?݅$@~#w7D9A5<}<]s3e yO\H6I80o~鹪>8~Vsb6DoOdm{,Ɨ+q  .XXjLX_zmVDR݊ & ?U]Fxړܮi<UŊw)xjյ$uSZ3H0L_F6gz7(-ߌmJIl?ᩄzuoO"'~O`lZ<)SoN  @$}O3+9L`KOO_fAXf-Gol8ݷ]!gFzV0F`Ȟg2pOx:Axs%Lv/dkLMK&a1"3Cφ?2o)+xA`Ld,:S^Oy_#0d5뇻z) O/?L~8.# gaO~&3x:zȇ嶚vFHFO=pd `&PJ#<]Afggϟnsy|9{S"j+ ed`|g]w*7b_}'ν1|dfvEVI#Wb $X dR3s<1&) !O?LPz|-4< 2FK&$Ot̟SS_CN'H슏fT?c-o 7v!\y<,g*g[* k29P}sڪqS&IqԎϚ'jz(O7vE(y|mWI$4ONj_+M<$OĮASFS 1_ݥw~&ĥ^qЩMS[3!CdLJ0SR$ #҄O+YKJ_hã~IS^.DT)(y XScBj%i"$9]Ԃg'+ﯲҌSxҳ)vE:!'w <_SJ`T_iUS;( 3:YOwO+#_ zX"zǫʍxW{zl162-O|9 և.=@1U_|86oyV aXw:_lĻs<noUmOۉ|G (+]XcBIϕj|19D03 ϵ59b_h7g/_` 9'<" Qs;Т&短#gtK|sl/xOa9h1k ⹫'E,NyJ+/ Bmv)r#' yK[ÈgЇyu*xFwJxS)m>Y9O;_U1^8r)'_H_/e+l~|n$bIjlOIګX3O+WvĈg&d ˇKu+FdyO-O%Vsugz'>$\Ug{:W2ݍ(Dy5Osҫ`YY} v=<ΗNu|,f9maۂ͡jv_'baFaSٔ 3t\x67U@j<_~6<<+ztg^M*G -ۧE}3OWo6cPÉ۪8.vzw+c)znӅns>yL@;nuW+I)^ls冧NܝhI<x"R,p<֏+fy/x'j:)lP+(胤`O5Ok۴yyBB"'?VWɜSڕ!S (x38T'2OkyOEǫb˥GY(oUY5D\Wg}a{O9j |Q}@Yq!AXgsyhN Om6&i֞q'THևil׉pJ,qVaIqM=mhFB4܍[zF+/&x\qtPDS:ʳOE3'?_+Z bW &c)RdXbuPf~U:8_⦬u(-OYIs'@F?WPCc[=80 92}a O}ȓ__xT$D"h)OS+\Qv<%?Qn[RggOSiN$g'Gᩨ>3h#lߦ:0C]ρٌ$K0*JOs0a? ĥ9>6R7Ӕ%iG/|3f߮BΞg'?bp>LM.a>y"5Uw f~r(Zևyz3@ޯgѾU< vOWTZ̭ x`iyN9\{1"R֌ gڗZ'YtytF6q.?/jIҗs֯5a̧dwR6|~_6X>xP-቉6Yit7p?-)/J}UD pVU_UOӡC)Ti?|SK;TEPÂbQc9x TWLy%Z,s#O!uO O|ΥYd?a̳ 2S swrQB퇰I 23Sl2) {2ϰ'=Av8/B~xՇX9Vu%~JSFڣ'}u#~%Iy |ϙ%'&xZbKN[y2ρ>4[S|I|'<%/vM{<̚)vM4OPX扚2:)gݒYV;_g6>2Ox)B|6y6f$m^S$.@_57+^S0SO$k/*^n 9 ׇ\+-OIym4L~2\ʎ6 /)9d2nCdH jlk3+% i[ ow{:O<<{g>w";P'&x*OV:^OhQ[93g aN٨r]>93~X&# =01wjY$L y냿쌪?`a#OgvwaR Ox,TKT.F?}O OW’9~H#Ў#}8s8'xA[>,dd1 -Ƽ ` 7ag_8vMF\R.YwK Ġ婁'y%= ' `<)-OxIc" a-D3, <5Ϝ <_Hy'ap^<$-O"8Ϡ() |MLE4f5NlS)tw]N_xbSS\P&aJk^LqDv5)T]\4jz/cE \AuѬ<@RO*S>e<53 &yS ^Q6mE>4Qz})+<$6F?)O3<|p0OI<`PDe/^*O+lOt<>MA)=Ϲ!釚AsYy9Ƭ %= K$3<*3`+DB6<3 `c*SyS\sg^Iw1j\K}H<ؼ0e} O<5meF9DQL>LD)>8O/"N:Tïzӡa'Vxb'FgSwb+Fԗ 8xJ9oR)"I xb8G'+&V)s0X7,m9{b3*P,=myI|f2 W%Ul1F\vu#)+JK"I!U"qf2GiЗN"V~Ԃ0Q'Vx"/ig:e) LTp9H3R94,y:Lqy67<+`H)L?}l ϯxOSx"U+t<Nx 9L׮M;EDS|A6}kZ+FZ fX;AfA!iHp}s8 A." QMQ+S[B~A'sFfmPچFHA7 Ogx Ocʓ TТc<[i]qW&xJ's<=_+<˂D-{5OIs^<ʄg2e] ɳSx REn^Eyqza}#3ksusؑ4бx|]b6]m6gKPBnJҪv.WT[Bh 6%;O5@-x b+DxKƶaSsl|W<'-foO%4m&\,"dVh6s򗀕61\>_ \ևxqdQyH(?X?癧Kl P48_̦ycW~m')Hd\sv 3C~_7\W\6>V~2feD/q}8O M lk%}94)8jWL5b~'<< FB}Ӹ%rS۪oFZ[amnDZFF̢}%O?T /75Oy26TQ],1TUI'Tum Oj5O,T3m-؈` ٭ҶEpw.sE(K@Z3?)O t_E}T(Oӭ%43حT O C"5O$qTOYD0y;/')Zp5J3HA"+!u[~f賩Նgpz/AyS9`-xBSk}lx~+s w{zDPkz̈M]O:w7g3j9,HHԎg=B;z]zjA˱4{\@Շy9Iڛ㔩y0Hm3r' Ԣ~$CxVOXKޖ,,dFAv>enhCqQ(ʓ)$6%(en-.uSky Z<ìe^]-<y"ϰp! ተEBɔgŪs]W)n.S'xbgH+يSO'&xV@rL?+"E%3<M!L<nye Uml橕 =*NߎS6DǓ>txbgHKxb` <2Oy}"Oo< 1We`%O9*Oa'H2p/fآ.Pb~܏u(/UE\G)H(;MJ?Fl\dž!=O[_jm ~Ex)ADQY቞'RMLgᑌz6>$Ϧ'%/YyKx"TeB6~3䥝ܟvNBng8_:ͳ$XhDBCOW/rx& I.K#)uTӺ@T/<@1S=O=gX]dzT' {GH<OOmx IG&{0ꒈ<xjޜȞGN|TiA梋\IyL4+IC1hR@X(d “x{ѕhͮ@s wyJ29և<>4$o}=U<;}8Dm,S湬O:;O*#l3Wsg# <+O^d_IQ7 QO|Լyڠ5O2<@8zo>ׇ鑄=O[ Ox&{wSUF(ա4K0zؓ)UzVAyjɒ$VD)5=O:1-=Y@*_)L?" 99$}*繤'Kxb'j;1Dj}XXrڪqRz(j9,8'&x&CAu yŀ/ QZQa^lZٵy<5m mxv[{`|O;^> y,u3Hag<]:&xb#OxtOM[Y?I?!5U|1{[y.SΓ}Th1㏕OCyYv3Ң8DS,d>š<1OljyOLg}<}II&T?xvg0ĺFgwyI )(WOK 6y:OijxBIOsl&:?VtBTk?),x^ywĤ.>#.?ՅEVN/k%|".y62OqTgqdc/wI?lymKwI1G w5<:N 4}# 2@s9ZKs[N~^r[QG59O^glНIs^fxm?,4\D?Wm0._觠Yqdzԇ9xfn=# sa =9}>ُrfo1`eoóhCGnw//q#"=:YGo= g'?"~|ٻL{jZo0CzG烇\W:˞o/=q%\}z ?w~E"/?M|Y[#b*LF3gaFܩyuT}"hɞkxm<{0W*?TUWv"a쿤ipu 6䗖./0gx,ST\0HW,O ,' <]_]i^OCf3ϝ N\w2_k-S>Wޑw_}ˤόB}l2S8!y-gx~h 7^?pg\{}tW\,^y<<ݓ<2=& o.ݯo(Μ /q1<{?MƧ/%<"Y^n[އKQl+j\% iS :ZW[^wގW^?g܃k.კ*2||S_|_.\aCe`ϪxaRl\D³?}N'xVrp<."ef\7" X]a?`<AzJdAe}Xݤ~fMs{&.~-/}۟#yfks3YS)ވ)= =뾄c [ Kǧc=g6XZbN5qTp4L?=_٣f!q _쾬$(|<6k8_5Em8H$*dcv0SO6^̸K/|u z<>ls<(}e#lqqHscb|^wnWw*HGn8pX]R{2߶7v2y?ulL _Uf+_fhr*^m/*8VuI}^YeqDp`=OF*ybT& +?}~ij7᯼c%pSx CV]R\JI a {O_y{4n˧ߍ(_Zŷ<|]=/6HgyA]OcsIWi` Tq7_}pC} Gug^gx੔'Yv6uO/QиER&)h~Ԛ.yz]R4$<˲s_@\cp4Ge Sj^IJ*5.+凛/SYI:[IIu OHtz\X19x")@x ~|!uy"(K<ΗZ">>yv3`0"O='^)&"~6p.G[_ Z [;sUӒ>;80b5'vO5C K-OUx&Sfx9ևEFsc")h"'{)O|9V*\濓x^V\MYծ0˄Yh{}h`{/³:2=?7k=Wp4e @w'Ȫe i69̵K> \!UC_߾T6<_a舓=#nХ<]O:"O$Asj4}2O5Hf'Vy?)OQ.~,L<0 3rQHi .Dmu FO9oQo~pw*y Ψ'_+7럛x* bFY] Oݻ|۾U/K>WPT7KE H󩒧$y)Ol;_Z-}hRavF!_K#f@]W* 6O )`a9y)3 flgߍ>ȦujB~xW SQc'ب럯CJ~L@ZRa"ԭXxT[ 7g'/JСVSj!] xAOhEW<řtia(lIϦҕs5.')^&e}rV &8n$O&?ﺩiY?v_ݟUi+N} ;5ytkh61p ,u n8"lϭ|O5|%YV/)@A|-~mx]|ʵW_އ=U|tg  ņ] ?|cq9+zRj@t/OBÉOW7"x2˳ݡW򫏺iJvEJ1SY BDs?X<~"U^< 12!4"2ӞcOVOT$ik18=6)Pexnsj̗| 7\338kڡ :w;Z|Q61ԍoS ؐ}R/yȰ#*Gmx\o?f|ӟk+kM/ZCAO+3nnՃ9K=H߂ ~q|">cKf?﹗AɁ?'\?Qrw].+Bo Ra?;Ծd`]c-^s9<l7#Oj߮;N͊<5 xbgOү7T[ĭTS sDgieBRK%O/qv2SUgx Maa.j1O^S .)# O<'JZL!ʹy=OF"#M3Sܘ;я16p 1'dQU7_8\_қѨ&8SW`U 2,$TҒw,"_Yz={}u^̤wMS|8KGk⼓;܋mq;H S}H^y`4m3\Đ'S5:橉'SKE}XV(ʿe!Ĵ~܌ͅ^AIO>L+fXs?m&OxFRkeϒ}dѢjb?ۿZ|RTT<%+ OlJ?'yrqmY? E mz vX.}GmPH5|͸=aRvnarSaMP /y_>K$4e_ ~]yB6ݟw%h;'? !*!m% -T\@A,5QBLXVퟷ݋y'IܡnSS9^??<#j .Y|KO{J󈥧fhҝYq(K.<l ੼?;72goӘs=zoޑ%0I%m*z_)wݳ[;(QvFlfW]Jg(cq6 ][ 71A{;‰ x//`Էaowÿt]88 {ÃxpݹȐԉhBtՏns==P(QYv;R05_ }"yU,eC19}| '\ OxAho?OCC.X D_kQ_"+o7pwM <4k\qi?tky}@Dٷ|y^ NW̏~ܰBBϘW?G:tm̞I)9sΗ!e][vCwXV2 g)%MOI٩ ('0Ї)gy*q;>ϛ/2S7vOw4v(16MG_XK5|:"~Z#Ͼ#x{F^0ƤsK&vܮpy%.("Ob<{rt'y:}@)vY0Qfya;̏rI1CsG;?_+ cGoj40u:p6FBjIx)+x?h`dUX?`CCz~J?TșѹRHyV%|ۣ4 Q:\sd+>w]¯8>;_g6-GpEpbcۯ~wb)g4W%-ך0X<>C]hpxK68eᾒ4Vyq[9VPZSB',ayʁ!oș{QkṷqMx6)xO$,prxpSQ]ػ>'7E ޏ=\~>z 0և/x)ަ K=$}3M*({yuuOo. `IK,4x~'=Vcď \{Jgv yoߊkB)<\]BQm>P0UGyH?势fka\Yrugps%aga iiY fح+7+dU4<4{? l\y8.o/zHK7{>/ij^MJ?(.fWb$B?2]|AN}&d!Ͻ6x5,p C6)+${Ǔ\Nwp?IOap KwCcxߌϯYG'BIP?h*By6W_&(&|1G?q|dvcoJX\Q~oX~w]<_2Mk&P<#sz' | O?|1|)̇_{Ixbgc^y@Qk)Z?N@w&U ~I?%2aN ` ODڬxZ}<w婽/?ax!}q#KZQـs/!ĺvYcs aXʐkH3`yn'fxj[y* [Qèp!R~S y*ŖY_ !Ϡ(a~qD4feHqyN9K Kˬ{ cMSR?Ŧ|ġU<]SܹDd>|ᖇ/̯-D\ _#ysGLTG9öp|a~yw{sw(o7ҹSߏEO#O ;C໿zZr>rG/.w#$CśQ\E"PRfꀒkiصx9s_sCUDj|2m/ݾ E7Y@Ab|[b|,2u~7eڤ3k՘k9Q&F+óUFF#քS<ԇ6'X @ 'VvٴsO;_ͯ!p_),"Qڻ5,'? g Ο,7ɂ}le ×/ :_z~x"IҌh^I ?{ s+ ~ e|amJ4XW=\3_LFa/Sx x2~~iM~wnݧ.3quW$NDM\DLHrp T~ĶU))mKMѠmrX ج2y) W:JQ<Ɠ+*nѫq?skⶋ 3Áe1?c#Oʇdg<5tbaj=v9'Yzdg~D=ٷ3t OA;r1x:MCWxj3*j_ˬ j4(?~Hq$.WzG@YrvIg ?K :iHRP'W])sZMqI(V'mt}=,cJԙxBx$I =OH]b~ECgL7lխJ--dyxVߑ")>ZupĂT/Io" QFiϡ@ţs5,=N]]5+G?W(G/~ ߊ§w]~?ycy1"O_4Z_=(/E-6_pq02Pקnŏ~]xd+j}؎ O-d$6WLv TxB혿M12E8q~GmbRlRk?DSaͮ,6+.j2HbOz" O̓tPj~4d/hUxbr O/vܕDb86)=<;w[{ #.٨(s8yUNs+VjH^i}r^pypL>\1oR*Xn L ړD+4Nx+Ҍw`ݜ0J)|8-G5sBNM~*yǷ_]#r|9wOax8@Kqz`CV ^iҀB×*xFk4\:|9xSƨL;N_'ټ*F+;#ʝI9\9g\h8Ox NR0sC|q$,T"ZHmQH`["z=aْCQ")bT&HquwWO_gM+x0?|#]oǵ}q0!<% d&I4~[rf_VJJu# mݛBcS ~|Ѷy+"^A@`d,,-sUzjW2t^) ~ԞoI 9)(_q,:3gz=Exb)2g6|d6[eRyg'{<%nIEi. G PRM[Uv>>Sjtmp !S"8Q.l M<$hv!ų*4SCsgS |9 na0./i19\H_ܿ|+xPse|$}~HSL=pJ^䯾jQ xb 4TBfER] ct:U D?2Х>fl6]\ "7:Tv6J@Q3rcN%XKdlGXanUS|4!zHx% >2q:(Ot 03^ВZ~~g\M{z34e<3OxH2ojZ$ć44=*hwOup 3"~OWR[B9!VOqS$,ҐR;_\}:̾S}߯'I <V_OxU!+e#}<'  l!_^*Qr:G"S {iuxyΩ[d,`zhib37NW:c"\"WH|Pbbv:.^/bdPylKmwqUoJq%8}w_\? ?nJHlJ"]~W>/sEE{xk[*qWP_I?|Wll/B9bz6JL69xR‹Gv&f≀Ó5) Oe>0S9^'zx4)cxjx+}8^'#?ItMyƗuw+K& 87~-'0J]U2(E9aڪ Y.& McRմ)XECr^ x #OW }lqcѐ'w \6Zh/`o>=V05g(Ha>'Qi_ <ƳZ33l]W34}^|OLxqo&dq iš=fTOx"D%8*<3^0NKgoĪVlCO4݊AXXAf@`hr|"_c aM9>5=čWHKo}v:eBq$b'3Yb~΃7pD3BtMOqUKu ^q,Ŧ"CkC174eHk/d 7Hl2A#8%6O1{ {RЇm|߹'>Td&6;hG2>a?fhߏn%x(O ߸2vS4lOPPV j邞\%Q,=ሧ֏~ZsAK:?dlzT >x"r4خȠ;Xaɗxjρ E ⅓^V2" ؂;Ih+;aAK%UCIUQc$N5 75G|X|i]44iG^O4Dl$_2NOnjUkSXx*w4礿`PYӹO iI +Ͱ$fkkc6A& }Z kL?ήSq'A85NJ(OGXWAYJOSi֙ g^ AhpBAD<˳8@OR<tth;z <K;>tUw⅗ &xxIVfy=bWaH"~Әg'՞gJq\|f}O'^:ϚwÝv,>qe{A_>r]{yrQ-C0Gt8wOBAs#OG<%1<5mKBO)\";ŋ#Pq%?xB}8@_q<5)i3w6(6e>4<a\>4g`ϰ~'xbU#'CR,k'uXoqfm|5\+WV/|@IP@[&k*/,Șs爥-l&${xr˿qpQCx!7~}3l~EN᧦ffZ4vۤ= ;P Vhsz:8, =~J*MHU7cg<ܳ_W?l8GW¾[~ Jg|rd??‡7<7e|#?߸aՓo=3'lErv ZA >$ |:,ġB#4Gc-V4P<r;(fs4<+,S _![xӆݠ޴GO/i8yo{ѳp2)ϷʜXo=*?^@pE;9 >Oo移h$jY5X2o݉/?%8z"2%[gŷg3Ƶy>4Oy !P<قIyB\5׭)-𔄧g%YI\d3k(_h9kss*L<7ё)kB#=!23$J#F% QMƆQcK|3lKؔ'<0VP%!ݥ0 Pȟ8>HH.=BB̶gCtlJU!3% ?e!̌'+[<ui!zi/33ID%I%IH5#@zu *'==)їLoaRf$3h|x9&vshhY|h:\mVr Y_#+24J9jPHTG,SgPQ:ȁ5OǸ$F^N.?_bg)% r!~9 Hp˱zx5.9w]:a+<`u~ݡ^ڟ .7\|'-@S8?Bg)mrx.O`pOR<"9jbQCQ}IiGK>4cG֖ 2o/۬\C+ akS CILaƓ?-8|tQB>?^ϺR3u3]-W47s\D Os2ȿk'?%bk~{^yB O||z*_|`g@cS0iľȇ&1GN^b@_S?Ldm7 3|yL2]Hђ63|ǦUxJv2L5F׳O, } ]RAgҊd)>L*E"."3)ͤJ}MBãS\S|{  A֟JՇld~5Iȯ"Ebu.S$< 9Rg9d3C-wC8փ>?r Sk<̢ mdl 4b^,?dzȝϓ!ãxgq8s֮]O}?FiWzs k#xOm"ܐ]@RS%oY"8WeG5܌mhl"@OL+8 "ϭq$'[9'6!n :U'[O _?n6S|]E|a~c8?aZIgy!Hے9Gґ`|Hxf`^8d-)%!鼛9xR0xV+ϼxROAm$4t<`kt$z7-?>xa(yE1.k}`ᄔ/VڄQy%>V4p>(kTJ1$C\Š: 'CIϛe+txX?7lgz~˟ϟ |{ɁegIM~f<]RiP U>ՙ7GrX^}nHg֥ G}EwXx" Q\--3i] S0u1EZa OxexjS |xB` 'X 2y ,;?3Px&~jg ϸPɊh(X (XF9i*Y 1LUCcaפҡ,jdX+R3a3rF.է+S7OWēV4hqh)<ը~ ͔./X5~Z0lkZ|Γ(Zݶ7|*BPLRP֜sWg3lq\cj>;a:$X:`31_b@+g #ܔ^zY Xʬe2JO$GAyiSH}=1'6}&cTu?ܱ'OG`9~ Oo XOw߳uYU+ό{XR}s6t-aS!~DQ[G+NΦ$=?ZQW( IJZ Pp1ϐVZ_Up@t}[i34^) xxBت~+fL3)WO_G/gP$Gm byc+b\E%I=ajϜҺ¾:s5a)RI/OS M:.#YbKқ#I6f|R>M.@ٟeQVU^/@^Jr|5dfU|z❯g1J@?W\ITx҆#IV\9C:?r>"A*/NΏh*=]H\jQ`όs!d.jL _X~I|B'@[~޺eES x&53Y!|6Z%5y眾Lu̔ 8 gȇYx|_c`ʁPj)xT3iCMXJK.j3GܜУg3!_3_gO;| |uO~/#P7n\q+ a"qK{lW/Ly4]hh[Jfњ p@DFa<'3$4'<j#ClDSiLhiy3 _wW3K7do=6`xW'_rmgFv=|`){ױ2 elBahMH6$Q =xr )V(y@׃0ΰUb#m wE)<9v&˧a=_|SrER^?|0zTB 7 *DWi[ 3T-*lg{>Diϸ~.K 1*xm&<(B+:qx\|hEszBt E>4V+_rdQI|c5Qt?=nx TP>$<y;OxBwypH@j=eׂZگh/!7:GWdA KݿƝPrI9]\>3$zvgl)Ƈ<=3HaqAӑVC8)MqY1d<+&3 +Gqjxم OWzfxNoxt|]?i SS+<>gpQ'ЃO.;P@L JD% Eކs+)n(UƘD?NRFde>HxB[!ax*p`xxsVךbt5'ftO,Q|c?, }NRf'!L+9 :K233.2Ts'931e%87__X6aD#Pda]Go8p2U4wT}y.YZ#þS'ZxvrS-]4nȲ68x7ٷ~|։Uɲ`:8%S:gFF V769^y|LM*9Bܾ?_ODxbϠ':x*b9wܛtxVR|* )~Yl6vxj$4O2 ?^qc $Yܵf.I +|wAYz% }*^\,I?öE!!Ǵ_OĴS<&sOjIIO{ϼ *ؙVQnO-Wl`2ڍ Rtx<5WzUΞ}ڍ_ޟ`ע:y['.\C“dV>ܘ->_Ҥ2ǁ:+/1!Og%xnsT4}wgOr|=)g~礤?SGy +x\Un W`1.L&?8SRB)9x6c<7Qѵ[D ׅP\>ێAT-ğ4fC N6_t~C`3![",&,ll*3aCbei S Y'9%r'j<%1A|oćrg<5$~avK|`u7݌ 释‚M~<<8ρxr❻D4^v ^O6;G;l;4=r_t:g|E{/!,IT+xP}|Ln|&ϫ)s{k^ [T[hKgN}?*eUO.VSz$ן6hY?̩p5d˦G~:0pGL0l!-Lo2 Z$|+X9HrP/)Զ6iKPQx 5yeoxxW>Nmۜ? %~7NsUi(@Y>;fO`>4ܗ !bm!~ҁL3=01A|BT  S(b 2BaԄ/x>olFE¹&9_4OI'h..sT`[Mb0\Z/~Xe;=qPFxjOUjZpOD~'X4y0<,c n?~mNlDW:`=-kCl2mˤ_TP8u_\LF툟W (U|Hx;R4)cXGp1`x'K3~npIW.!<۴ZmgWJTh/^"3 ȴn9TUӷ_/`)Ν):?aN!Q o L;|R'f`CШJ/9eRr~֐C9E9HzOE9W\+6eXb?־c7DV*έyje↎; Yx"sP>P<l Ϲi!έiAQ_d`&fA ti_VNph3as8T|tp;^/"P| "Dn;~A)B%c%y H^7S %*gKdzd G5tfbO)ֿכ}b s " xPgMew .B.:N՞ y~EqtϛZΓJgV㲑_I&>3ϰߥ@0H/C­-eH6` O5x\ՓaC.T=ڍ\zGʔܼ+l)"fk.W џ%,.%deӎ|ȋo?PTc|29·Ah=1kҭ>8d>t ґKp!2aHxw[z *kf?&;h2Wuxx_@SVPy%8vIkfBSo*$Sqv+cOAF+/)Ry`o4*sUj~z.i,a)5?58@D? [PXD7!MO-Ov=rj< /S:'8VlSJwGa{OnځGĭGmލxq& *~IvFR<]'!:oOʈg/#,<ֈIk6G uw)d:?7cxr:Azϖ}O޽[vER,6hVi|UvZm: NOllϥ;+(A(b-ƌ,"K< x>VgqOxJTxNcUY=h/2O{>h⃲^mVDvU.UX Ug?=$w3_tr._ٿ|r\[?~~Q[ BV#фF"Bz\},FMC41l++N։*S>>[FyN^ex3qۣ@ |(?9u1i_M_+4=?+6DijVO_{y iJ;n6]~bZ;-6;_ E|4U_u|ʇ]C-c-~fR?ߡ%pE8~Ĝ-=<~R?aH kfԿi+A_+>'`T)1tsrR{jOsVdV秒 ί[@a<ɚ 4’AVD^XDUG_SWf7S]>$Ίᇼ눹tiΰ46)) $V[Y2~N5?%)M<,)S3D9}“Hї<'X4!?nLY\qO;,W_M[~wd-dۼ`ILKZ_%^U(/4 %̊5 Sx=2{7aIZ:v'[ 2ٓ4 w x4WբxƠ Ux#af}qAj+%>sxʏgzML톘k W]mxʗp0<?o_gQ_0熈fK!eNU]?$+JJUjq&c^8I1x7NYu\Kĵ- CxJ4x+W#OO)t󊳻3,4'q<BBc'xjXZ4gKd;#Mӿ`7#ﱮ &xH.w)&:Qg9@q/ x~x즉-g^E^_K=~nz k!$o>rMW)mS?l)^u^5x:z^!gX@xo]t;FJcOxL]n4s+> k+{<'IޘR4؋쯆9 @/.A(~ⰅYm~ZώxSO{vn"&IߡOM'<`x OS >ps( (#Wy`ϬP&\D<7QOjT EDΟt" _t19v]>&1 uJZA?#z' 8V4U69ȕ]|'TĤ}wWnkW^|Mيgܺ|%xjy_b?PV0? ѓ1 ,6+-<OovQ<`[ 48Aߎi͊DfS]zsP3.2#2 > x(~n9Ȝ`ҵOgiIۀNYHfjϠ,Sg%9@0gKb L.K>6{ͧb8&-^>DHG_gR0<Beps}[}[n[@,O 9!0w.4=:?_;SSIe2O iOag䃔vwH;<%h *Kg<hX9<iZ)_ԐǴ[$JnXxI_ ɭRfքw7‡cN>hТXS[XBچv] V@ށ'N k s/χ/ dMN'6)cֶWHV$oQY~DOtdXma<5WxJ{8JxI-xq< xZp $x:้)kW F}>?8laj`VIeQ!_Q ;%v8Ke /Є5m<%uT$d°_ ω]H% Sf)5B;Ht󘥑yNQ <$[ORUbzx,gv+Et  OڠNV,gTFC ' y_Rp_yu*Hb or叮\ i#EDA/./( i \0tQtmD5%ʕ6Q9[G7u uWxJVDxdiy^u Ϥ8~|%mo{O"=GRWR/)p KCyJüB`(^}{iM5WkԞWOɊHSR/c4YHAx|<O'O#e-<5wk)?\.җexJOIxڙQl~{I,:2R=q *̪;&3xV]0<-mL١Q$gS +v4T_ =8̟>3'ø7v| &3؟]DR lSXmOJOYOóͪo!IN'`=4uơjQSCĚeߗӫ]} X*<DgÄ$xj )&%3d=%P55TO}gxQCH$l#Bb(>H iO-&Jp6e]SG Qe<1X˥!#3Ss;D ˇxrώ=sm`_K?k<a1z4nes53r:&A/Usǎy%)xc}+p.w>E'Cc Yx6 Vy+'& Vmn?ڣs*zYW;j*+'3p!561x\F^7CVO7iˊ0$>`AEkQ[A}[C&O[p^u[y?[<~v;wg[SgvI# ra+8}b ɼJx6[$G9[w_ fžz4V&R,S}ƕ W5Gs2AQ"Bo:x}<,hjS=:, 2}8BusIZ[O;W악ՅxקɪWJum?TMpD"aGbӘN4SsQyq)k}t:&^f.Dr-xӳ3Ǝ3k@GWn8q K$D%ދ7Xm0쌧05}.[MhbvWXrl h3ğOuFXECO_t3ߋ8ܣ\./^8dsx~BܔJzeώXBJwK_}-g߈V#oW54gA_*f~n[NᵗUtS/n*ip*rt_WŢ2X#J-U5KyxF>3$AdFZqz-O'M-<Ɠk|JO)m~<␷*po>ªZ]*nJpZ rOޛGݞV{kAD%hWkD4v'RjLQ[MLv2ݎCǁV#*ʠT2YLTAQtowq랳ނwU=9|~y~ϞW$\V>? ZJ^׼\R 18\v_TW3(xY=7 AyA9[OwCZj/C'j<7>\&e U\n )ZO9?~g=}y8!%G"zΣWl~nҁϐϼP2GM\7&YΥһy^fYP<^\{YxIp>c"駵yr}Ф9/*V?Oio$3oyj?-Ϙ`-&qu1Oq)ʐB1[zcx*Y|#)P8*֌qJՎ x>=Š*`!˓xj͓(4),&,kq@~M:H-$mEVe4gDzWUgaybm"CaO|t_lc?>޵giy6!lXgoiG DIa9L;xHMwQql&M\"Uj ՟O+׷J!7ڕg8Ʊkaϐ T>QU{wL/L;sˑ3(yگ`z3aR?CԚRBsiܦ))ziO+[hy才NY_a5,Pb9H DY:6%}p8ϡp04A}i?X ǪDUo>1 hWŘr 8H?uFWPjrͳ:3<5yFOMp#3` ӳч )kyƛhs.xbV)mn/ 1 3$A3OFח2] ~ȓ6@OR1Q~G m3'S+3No&׊ 26(|i< ~O^ҝ )厶g,'!MD鋪$*_ J23H|)-~q;OOLkWf596p${uų/䩅~Ŧy@5R٭|:A-8w0Jj2 jJpޯlSv7I~{օ6;jUj:3Xs O> u>(Jo,23S*ۜe< 3Is>OLckŌ58KibcKj(66NbԠV: JƄmB6I66&0I_N4)d3!O1O8c¬'mR>fX2S<ʹ^ % SLԆ'hPu'3w&֖9ꈨ-(=\[ =!1d\I~V?Cr}ezΡ@xҜ `zoɣ։GkN >iMgmx䎧pl„3%g~H>߯e@j_ung)^?ŏ@䯱̃乄aЅއ'T e\5=r2?NO[/ M?Bx k(pS)18(4s/Yobƻx90a$OS&U^Wyn6G'|%uKJ|CI=0+ K'5<^|Ӧ|}6 2H$ e2^q u//p3 !cՇos#ث?O<gPg3<&(-/PoY3W(hO^_'1m՘ pMEܬJhҞ!/̻cմ扚g s^HK=2}5EK<*?)DOēL.(y!?y /♧(1Qu⨊ %T8|3gqovICˀS-x._ O=$3Vf<$tXe\ݬ8cs"_3O!Mnҏq}1eVP䗴ZKّg'䇓|Oյ@yJɓ[}H=G< J_'aeyJ$h}I)LB灙ށ4Ŵ={lCm"l X$>!!kCΧj]GHXH5*!bUol10iO)iuoR (fC1j :g<Ӈ.h `#,?E!v@2 +I"'xnի ȐKU_#Fy=(C&\ s{ w*ǐVXSdNՇ5y9SEjWl[}mWҹ2(GP_djC VB/aX_?ګ/Ň~T#Ig8}tOS3a}Uw~F<}KOg@1>„}inOQ+RʒӋ2ޡ< z M1J=̗ܦ6,O0-gY;}ۂSmq3Yh?\<;zV -7\>Q֍z[Iij_|E膲%oUVi?UͶ{t<>$M(y:K1Q!^ U_o?sE5J?qL?i1xBGy[FNlFyI^zf^g?D\ɣ7pkgp݆,F~~KO)f*+OO8m;x'SZKQjx}`e-ODgtH'<UB!‹߷s:{ˀg@חbw܏\=%L7w?(P/%Y_6cLu LܯňFOAa/չ iS]39`l5p.^dؤ<˩z35uD`^]x⿎Gݷdg⟿]_x^~[sY<ڦ6 gBZGHͰVJ4K7 k% <O}*PR̓^WG, }Te$(MǠMxS'xJ? 5Ϡa(iN7{=!"e ҄BhPQE>Y;K.ǩ7xptӏKc'<1Ñ:SboK0%ݏ2O0 ҆]?T)DU΅>!VAGb |?R|LO< J<hG/}6$r$2oJ.p MZIq\U[[{`GVax,G(wآBqЬ\3;2gl Ԧ~߬>PZbI#b:[:?96 Mfʶ9ϞӇ"yS }C r:is`G؂ W1$II]~%۔ ߯ZƔaoچឧL ܯ ꍄL=9NK#ć8_u {X_}Ԛc|e礆߱S;?ߝԗÞfI#g>{QWvĖG&=Z?nynxp?p sn}6l Soď>,ɧ{xꈧX nnv綨>)K8M O/ yCg/x"{+Y6ර, yV|6֬?3|D݃OvN;O g V98׾r.z:vMAr}ٷ愣ZC0>j avFF3؛jyGBvE-6;%-xjf1I^@:َ6~S"n-))MUFMRbYkOM!O--0)o&c}Иzj PPfahīx8[Y*AZ?Q8:V?A?I#'(ɳ'oaM}P;3']2 # <&>`}i橭wv3k)[(zZ4,4|d (+OƳoħ! ߏ`o%OgԇB?~gxqe=8y?^S7J%^(WUk87'OⶻʟN-~ʅ?x]q2 8ߌ'B4"֗#xMgqp/po٘&Ԋ{e3W\Gt^?>Tx~Yϭl33689ixFdO{xr}`≮)'?*n9"q؄ `u<8l4ҩcn^'Wq=צ4+a#H)<%OMczA{l8 *.lǝƖvU$LY#=O{=#Hm,`d5"\rztEf2}MjO1'j3(ΐx^͙ψH|xڊ,v?sN|8 {V ,}PUMηMy[߄_{έr1L:WރT|px{sL*xM\O O OLPMG.OJX~-WzBO,21;e"GO]Q9ikҺsKSC/Xpcrф\x@Jak==e‡oy<^Vnx*IgWmӸ_-sGOމw➧ H=MP%x݇'vx=x.ᾛ#x)qm]w)9?O 7^O=х>#E.[\bGWo=wލwލ;O/*<y܅#'s wrۆCqcM2T mk >[hynW=,`AT˰dGu0OP'y_ڍTQx451)v4O}*Xt1ݦC/ByW(m oaLfHK$f<0c  2 >Qy!Qf,5Mm`fN 5{++MEB{u_,s<ȿD 5 d Dp>ɒh%8λ/~ie] KoZVM6eı lFf2i5ɖRLγ)C[\AyQ_xMt pXoǨϞŷ>>;XK7Oęc8rfQ 'tg:Oyے3l2aƔ~Õwp1`L9s?U0-κ χ:cNxÒ<uj_b(ӻkqNRxr'x($`;N ]~:٠ ;t?F$Ő5g_Ks ,=OV HY,Owa . u'OAAn2es3= G[պY<x&!Ϡ̢ "qv}LIRdLycL?89E͠'k\~gOt=S㹗yS]/cl&J4U%K%f-8wjKsn"g^n&1bҦ]MC/>1A}:O6$m/>P{.V3cB x@@ c;^=9w?|lˎ 3ᱍ!<,73aA|])Ќ%^qݸv\w; ǎCnF+0&Tb&M33|=LHSb 8`>-~*3O-xx!2j>],<ߴy,ɆVo0iU Lۑȶosn7JJ N;N}Vºmޣ.7LF9I>LZurnRy^'ߞ6wቖ'gZxtnjryy4=o>TM /2ZgS165<}sg0b3Oڞ0'(6^_r~fJ7ʬ;{1g o:xdgup^iGX7a#w2,23יoķc lJPWvWFk= m`,gWBF=`U_?Z9#F,Sbk0[(J)b~f(~. +*OSdtsJM3Mc> T ;}0Ն 6 Į<K gxjC<e<' >Ha'&hngލ'x}80ƕ`#C̢6岓> I CMrfn HjĠyh6bxLUD ˙"O3l)W$6mkXeXS $:GiUKcS~,\Iiq&[w{ow MO fĄUS9}7yoe4>8_ 3I]Q=O<7D7AmBDCw!`>7A{O݄:~o1 %UVo' <mYC-OV;Nk\n(RRޔ:M&TkcQ,eGw&wG~)'Dsͱݛa=V-Д)l'e!O3\Bxo!ԗ">V~kXp^d kw@SP͸]sx -yOf!p'N+\:Ub3+[[Qq5M|,xyx:㉂g)Ex. m[Wu[HP$U"Ϛ3&Ų0Cr^"G?"sd3?  OԂH}y)=cuV-B][_(ηEN#HXQ˲)!Bs8,?)qi΋`jB*$x(4$ޥnyG>  B*u oAi/ؚh0AY!QH{65.0_iG0 6 B; = d^}߉\q~Q?r-4/9oL|0sI{=TkIdt:(ɚYz[xȳ؏TW _ï/ Jhv q`3gP:SBjA'01O~T uھ6!b{#9l%[v?W&}%g$SďmX["uGSсVYqC!C4.&\2>i= .A8OB ٥b"|m¦@xd})y Y?PMqC`18zQ^bFC̰< MR?7oHXX?>XbB^*ևs[;sAi F&3¢yꪌ;f~8&N]=C^ iژIt#)OM4(s{̗5tdX-ke|GsexEV( ^gosn=lsFdjb"y1lɭ6h`l6u6FgB>?H1ԯO{>/RpxjHq¥i*P S{ y灏?g~%Z!}^NH;XS*ڣtymF%}6 uvB.tx<*򠟡l8d}Y;~ g7aEY/wv$YY?c#VcI@T:t ??_HkL:uo*vG]WflD֗P0sGc&e4 + 09%ma._Ӏ?$>=s {-F'NJ[q3"Oa1fVh, >]#௾~v1Lf4,MIg]!OA9mAmrީ)fpz(:UuPV`*zzg&< Z?Cփk؅ _]9y6]!nx +{^0Ss@mP;Fol;5fVRTׅ]'lcWJɯ%†ђ.慹 lNuOE;fxx_`.W7 `@zCT-̛X3t}1iȑϿ .oy~_gy젴_)X@1}y3IA]3gO)y)c^;ϓ{0&XOk8OngS}%l_xiTn'I`QQۯx:C~JeF}Qr"l: J&MS35oPB>^}Pn iZ/x 62OPp<5aO.'癳gD-gV6&y"' g78"7>- wCShy6q4)o @z4T#Jvz+u Z?yzEGO"?ĥ_x3a-W2̛kQCUR3*eIt;${,Ŝ^W&Pal+] 7zxku/!7T~$75nxJ)y>_t@_ALJĠb c@~ob^?= +Ь/0C5X*ŒNh+xդy{.}JBXV+,j[SjJ/gtmʚgo* QP{5^p-ڻ߽jW+vW U쟙ylVzR@+n99$|:|~nvw<űxE9c~c}7e5vfr@⌗a/i+{7[_–b-MMSc%^rϡbi},[x3˯6|Wx%_D<y b:GM %h9*̉RҘ=ڨ* jڎsAa&!1]7Lߠy:6hv.cz^p w1v.+~)O%8SLboR62-.ܹgɃ?c%O7Њ|A0ʴhsv4y~k(d Y_`>12!ܭ/g/wrJ1`x$'b4RZ|^$_-_smOc\'GG5'_Wʵm&h y *H9`mdSjߋ']L|q\Do~?[Ǐފg0'+S$ byF\xMh1~ Teߏ}x~oʠW4W㖏}? ~{)x%U ߮AS8XGaOy*frj3ɾټ婣?B?2ٛ=`nK+nZ;㹍zҹKj``A5/> ?{~sN$/L;ZVF<[+ٯFhBܧ̹4@ARߊHlVE0J={w]7 ^x^2 +iytS \N:OȘ3ٚ %R|3/ţ>Qt_W]Z#T'Ұ?zl"q<5CR VA} Շ7W~{OTU潗axnS xqVrr?&Z4<'J]*~(Bq}j~O(?󪏱 H1vo$gZWd}oHx叚 vf"%) 7"q Zx׺vvn&T~̼0b7 xVr0)OL #ZZ<5S o d0UͱgM E CF?>t7kgv=`;T ϡQW:D;pSp#W„+}{v<8lWv;ɳ9vk9?|hNyU>UrxܹBڻOߜlCDfR?H<~`Pb Br_zxJeU[$-[8YW]IU8 ؆e1NMf4{zgp >pivރ߉N:^Iz"=OZɳӺ f/'.Ѵ#o WyϹONFdg5OIޮҮ)ky*kaZ|Ak:&y0Yʳⶆq-+x "}ݧW?0L7!.Xst Z;)u:0H<^P"[a'|{I,P+p%'ُ§]qXȹruo?W~/|'{3['9 cO{ gpYe4Gȕuo=7|^h^O~f{sVv&b5~/aT9Ӊ4쌥9XX* <.,Ĉӆ5ɃC|<~^ͮkyΝS gOxGX. \wS꬝1_y=YxjDd<ևOч~: !SoSoup\.Lp.\8-8xPAʼn }?n o ~Y_L?YFI{@pp5xeRpre)A YP}gx]x8~c}U<7˗kAUmE7OsF쉧V%a;$P,yYLN&tO84[Igz-I[Zg<ʳLT_z<-Lӗg!OnЇU<>'C3.TgOKxk?ڏcTg[xʈ<^+ ;D YS :9F7h)L?.Q$&w\x#I≤XS}K;ڶ݉;'S&yH{o'zךg<<ڵԅ<#OYSy7(vē<%LH,Z˿x{j}MZ_{I#BSg_lؓ<UU5OυxmCJyr<7E%WY>?S Oa<"?=UIW-U1+KywOF":ˇ8'xX=WR8ԇ$:?L(\{B\_ ME*&`SrEωY&.Ҁ,tD?a2nC:f<_V`<>|y]'ޔV/Ӈrksi:"dVa7,7ڏޑ'8LxkOA5+ٰx_5u<)yQ3.b,^vK+ƛev}̇!Ϭ*xXxNá Pa_0Bٿ^DQ~nP0'**.ج>d^?-xJP9V<7ls?HNDSsr{,Ol,7-Osii!ko?Pcct#H<='y#^jSM[/g띬/(UWF?{> {&}`YLi#1ںy5O禴^YTxK3)Ow]S$DFi>Gx}_цg77@Brԇg
}r`Cx j1Z7=y>TF\YL(چ ]4碮5N&!|Hkb\e h3Plx6P.IuZ l*x.Ї'es~XʳJ^s`䢗L; k5OuoUۈYofyj|]3xv $uI s'}Xx"R ;P?r5VmtQa򰶓?' O;3.s~}I壯-<4҇'ߝgLFaU?Xh%Oӕ@7[_ sbHDcDFzpX~#!ql6$wHy*<Is+TCb2S=-(IAR;xJa~ta%W:3ϐ><a'DS}Co剂0/O,ͣ.sPk~AA\Pu"̝KrY3wyp3H?!OY_G0==e~xb<؞'x}:2B#_5O fjMZeΙ? &SS'݋>I N?Q:.T?*dl<ηAd%O/s;0<Ĉyyn5ϓ2O'x~rI*Hb:`<[Н=n1`'O<\}Ķd@?OH2mvDu5SJsUZIdAЇ< nH yr{Sw)g_lzP6Dyo+kpGzSSO.nK'Xt2M)i[ۯ>)A&EnM}daIGwcG1{YYLE3{y<)}/» ҪoL;h5 ۮȣrȎnU<lz?cDF<;}؁@Zȳy 3 8,~\X園MWY&?<`RݥyAr\|fɽ̂r4M|?Bj rFU|N ̧IW<ɧxIbUf9Nd<H?e~(asa.ēerJDyx2I|}bUS  *O2.ә= s] e70!M)O<5 hyf} J23rG}#d{<ԜUQ-Ϡyjbך'T Gז,gókT]P+xb63[~=cC S؎D/<1!a!OBѾD橭>T<_F O)yJScs<Kg"լg׭9y`%a5Oc5OڤpG*+!mU$h1xB;wvryu8L)O)xJ˓/rLu'@}':|IsstbWJs1S|g[Q' gquyS d%JO'Q! 'xBbn:CԇII?lWn? }$7.= kSK!GQ<wGoNs]S Y3Tyj3Aw}ma89Kfx&hӮ/>pN"L?`bĀ牖gd< YDÓtxeB;S}l׈@ԹuTA/Ly=!L4:5[I^ޏoJ+4954D1BIXZBAtz#ʥ:JRԂgY%<ꃤdfĆ'S9ҎP6ĹaE;>~!i{!Oclvxi8)ľj!d OY_󔤟T1<`{AefjO)VbLyRDͳH#}BY3f1ޮmXL?CS_/N/)CחƳ}f8mJy2txP'jĄ~Jc0NyB5bKUa<+!)S` O7ko$`R< m9z˓˯ ~ڟ+x w'%w`/<<}fv9g5yā2(RcRCȸCxF%s<_/d"٤)rcb\!QQ N 41[9OPxl:&'Iې>h2mRI`d{@;8=O$ R OX7)~jI͉`S<$C$đᆭBLDgR Rb_? yEHMXxB궎}$#0% m-Oه[ydKyb9O)xlyF?9ބ|i4r~,8Y,YɿTy:5y^xj9OSD3e=}P܍ 43TCFI,O5<@3j} y~><7iJ~~T,Ls0SLopeh!$)yxJ[^L2I>hNOisЦӇbCkl/Xg<^> b_ #(MBpO 裗g)BYxwy,tMևC fxt(ʓԭ9P {'˟>0V?<}}-NU< )pȳT`=Oћ LtFrC| hz$b\\+<}jMv͓bw/\M4fiEesT̖ۚjALyGiG`h=nxJ^]}Ӈ VlҸ6 }B Uyixbg`=GOdطG Z}3O;9yW}n'MYgzdOrKfX3kZ<1}.ybg4$xU,OyܽMϵ]rum`EqwCۑ (|I$!BJc#BF!@L@0Xrt1xg_γVպcuZUO^?3x0q>~mscz'ߔ޿ϯ/]'uA@~X eZ-8'ޗ0alz?wmFã;My]<:o8iT & #/v%8k z(:zhxB߀HڬsiMVT+z(0 3Q]n O8R}[sG^rWdi~]˰մ@M=dZ)OωwƫOC^6 B|K%_dƓyFD%LdpB&!]l6{A&_am&Cٴ\lMw}V_J_4Ϭ:1&& 5J ?312տAJ35Uds'l_1|WQ{ByW{L`g6vdgЃ'>/i'}rb'U G thߟqI`_N>ߌ+;YL y>)ٞ}zLH<ĖglxB|q幞S}9Or!w)_(/<WVY }oO=yd=^x׮CӔ{F=O}V3!.ߣ}jOg҃3{;}=$Zށ^ʱi}Z g}ώ'2O_9ϤO5>bKxB?2<"_\ aqm?=3)]5D۫y/@#;ˁ6N/Цz2+9%Ryꉵצ Èឧjy'OzCBS{{#ϙ> WI=R}6Og<:5V6-pZdT..|=Z '=O\'<]s5 (OxZ6^>UH `qSN/1:`onP\(FkQuJ/rńTZɼRbe?Z*r f0طhx}&rd}?=VQoy&c^Y!ӭ&j s[1m)O`"kJXY3x8}Lc}(xV{¯GOZK9O<ިzRQ;iOy4OϏk8vhsH9]vBfr]IRKjfwQY}Hְn2Kq/=@𴎧A@*& Dsy_h%by_6J'=<$Vx3=X^Syc(ֿ<oy~,{6?6A1/c)a#XL2ˇVף-,ұtmy.Ҷ,v'_ 8O1iE5i=Oc sY2~QJ4bݢG0j}B>KߴLe̘Hv'4OGm5Oy'_xZ$Ot-C<}<[whSsEP&Rۊp?']y{(N*I9]pfP6o9IdFIO2˝D|t"-')tOk34L&҂x'OD{DM7xhAy$Ot`9p%MX\So=ϒ1Ay?}$wĀJ*xn#x|' { nR<_7#y#%e'ѥ1rgc!O(j=d$2Oۤj3i-~'FDS^91id^geKm%OXɤO6@nPD$@oԿ퀾'd҄1}'JE(z@HS^I=uQxiB熧o:Eks~_g 9@.N|c-%'"֭αK1R5YzJܜlÖtl!po!Eynͮ>i<-ϭy<<}<%> <ػx+;1gAgWu,rH%xpPy|'<'p@iy~`&^9݄: [i5yO4']TODʙG-mRw1wjAQէvVkaOS|cH-<;'7ѿ~ON[\ '돐{<{t;2@lm0CU?“l³oz%;FG'!|nV[}wo.O+& !m!G~͵ۚovm43'g`V6K<ӥpV2(sPS3_=u-s;`/݁-3Qq4%gVtֵ63 ̮CucpuuJ $H_ xJa<9e M ~Bx4+K0<H/^191dF(ϔ. [}l]s~OW<-&ԱfCu(+z_фdzaޯTJ:I`퐧'O:'h6p=}0>hs}Z; 5R xâMx.$M*4rP^q=L♾<Og/0fRڟ2;/:=xM`a]mېg^;IB#|ĄV)_D ΖOhh⹖>.ߍAb=7ft48Ny"kSt> OL'^-w]/깒C[k `ӚJ4K~Kڳج+,:c~Pv<_:Qnm' kQuP{RLz8,?IUCim;Y2T%1mhV7Nʖǫ_zlm~W {0'/-x" K+-O+sV'<}(˶OT6Y5W {`215<]_&U<: Ӟ':~CV$'<9C䉷t/zxOyx/W'H󜗑evv ^ pMAe>GsU7ȭ ɟ*<;ϼ;jcē׌@qx:g͡>C/=Ox7˧ݸDgfSS{Pk=[y%vV_ 2+1/&*qKv?n[ MFh'Q*0mjY䙃9i6?]X)1\mks`v3)OS->_/ϧ]L<i3J_qқ>.ӣ>K&"9tk^Tɳ6c{=~# N )8G۰yDU%5l-z5&]yg)[xb3x:ӧ\8&z8ȓ/B'0Og OD}Ϳ[dAE!O' (h}D 3Ճ/`hMRSr#y,xZ9ܩֳfOQ&6U IwRi=}HC y '\/$ܣߊ'OƶA*O-)mBD%n>2l?J,U\SE|b:Fz }6"4ONM6YU+OC YO<Ϭ|sy4=~R5J=̳«琥3\1Nxofu!5z'N 'ڃ2xB@<OJ #RI<,Ƚyy/%xڌg`:`<'Վg~?nAcFOmGz#=S,PEӻs\uLeSȎ:&LxaDwxͤd(Dx34[pWYRUOi>܂']<xmiBϐe#i{3$yJpscnƁXγ7.[x'DN“lAFjx|ۿ[*|*d^qiF.5o?Zu)\`-J#`-|dd8c!%^˳phRӐ7]9k|g,*5yφ0Id.rwms*ICHcW=r<ϺڜW|9ny3y9v<1ig)p! S/G3apS<M-YxQ2gҧ`xItU/s&z"}?gIISN@߈>I[Cӵ>}O;pD >mv 0bR%uYlC&Е!zIL߹dz1uγ_:v<>gP)gn8ܱ_Äڱ#3~=@gAဵInݹr?|>CNlIy.@N(V#;zWyz?_zsxk>9yCJ֯57ztg=̯r3\ -6< `_|ݯQgh/!YkE AL0߈ɀ}WaiU(mN-wN5p9BĂ;Q?_{vԐ؟4Y9M+<[z-h!Oԁ6Sr&ɻ5vF_x7  /sP?H-j0MP V{j݆gS7=ϴmzL"ODe=<>jo^+lIzg#z>y,so[8$HӇyDj}?턧MaR3ϹI_ɵɯ}KY4/`_C[ݭKMIH`4O<-\闙>Oyr=;уD'Aykؑװ#ODdUp+<9V˔gXߞ}s1OpA3?m4C¸ڊ'á>+ini<|ALJqY_jTKOy^2P(\^p+&G=Cgb!`!O_<- QbzHMg(OxZ O/o{5$ yruD)IջkH ~/Ϸs-l߷PKyzIF΄ĄȪÛx湕gZq=(Ox.G_k=f9 >.VÀq!mW`;sɿ휧rOj'Γ 0kUbeA_:S#e PܿOLxt>Z j*rr_qj^Gݮ;[#zn?GAړě"6z-_a-[[O硁VngƒuNv a` lBam<1;<9XE9O)O[s^%kf}zܰyi#'>S[x!Ϣϓ*Mx:p-;dƵk yr-pus4q2c {ΐ0g=NL]0οyBigC'|y=Ϳ4gSӇ<1I' G}:X8Y\wR8j6 ivsOGу]ҡ1ҫGo}CyZٖU*噺<WkX%'ϝL"4m쒢XO'<n|}Ft]Wa˓o#OC<-HGq4Km\<ʀ%yZspbeQx ƢO\o3hzt3[z`<6hJ7W-3+4`V?'J.9t=sODayLe_-O<ĉ>ixC6$Dy!,L)=It3a:'=Կ`rx%c8ie?r!\ s=,õT<(ϱ[}B6K"K~r'jd!ϐcrʳ|yĥثҙ=zcPPOhV>7z8z<>ox9ύ{/\_2[fx2}"֪X>`sy*Jl&x)CE.L I>Ot jkG2Ouv6`]/Ӣ+O-<ӊ'2(GSy.w<;>V`/2}aO&'NxOVb4  x nt*%A ϸdςE}֠tO|+zfg<鄴{<XՔC9@YCw0Ӄys;z i;Ks/ǖ;OgMLڟSS'g*a@P`'h텧su˷p]}/UGz9`zPf<߯ub3?xBGDYˁK뵓wcY>Q?WM=Cg̭}rLń4wbaѧ }V{Sg=4EӫDWX,_\#xR8.oĀ']-SU(o&ѭUMӗQٿK;}3؃tѥOFJ/$F- wStw_ן[<ӎbT]t+rk+/' 93t&̴Z5} 2?SXwy,V -^HK:r\ E[՞35S>p}`GYmB:$EO%V4CYg!xziJ?uK9O {5OgU(lʼnOFi(,xBDy:Y<ʀD*k S40. o`a3Id^zi'g҃Aտy'O@I^ KǫO+$+smY{歋uAFyk%C,Fӓ<1Ӧhc}_ ?vǵ]L!f{b}r~ϳr7[<9OE ecg} CNJx53#$VG(2:A<=O5`9Z= 7_e*PViqK;𴺌+Eų͎JI=ŵ\ { MgVhZV& }?}SaӉYYvd៍r7bE%xȿ܇t$DUɯonOq9&Obq[ouMQϗAi}&"ÛxR}c9҂^iE5kgz9nŞ+=ûg2K+XZomyijy`JyCI[_e `C{i#Ŀ t Oh} ^k)? 27ᵜUBa_yCZOcN?s}`Y@GvHs_w'ז't]"{Y0O;ӊ#<\STTW"ߐӃiE<׎El֟REtO >=eHphbJ “KXnT '<~"aX,IQ%jE-O*mC;S'ט=dshzQ#ήX)ms73yECeJ5Du|0|?&<1J~'@Lwz7) '_o1O1;CB/cm/G'w[dMf]=ި9=SLzL0O<}:@CHԿbOnytaLig[珋{#Gy6"Ul6Է' =ӧ } tXJ'.w{8²CJ́BOto9\wTL#R`ߟP;u ;r>h;yC5.n'&S|}?7iWA;#M%NWx:dy cuEp!\ÃasyכO?Ox)\̢O/Q[n6PJ|xD Wh5nܰS5s' :Í#U(sC{aW;_EDɹ>OA5O/~^rR,_fyi~/VrcC.q祇T~F5h7xruى 剎grOO%&lgXB <tzLzErJ|,F\Qr*Bb0[3S2~5RR Cn2?pwγnz0{U!=@X~ϜYV9eWX0&hJLOpHECc'܌'y pM #?yZ?%fLmyk'th=7O+:*w8NλzKxR,4!˅rD{Sv5Y2FȥslC^VϯsAK9H9)j{„g,-,; Eadz+09xNyN34< ]1m9cTe#RN~pU& /<'1O9\ OVV+aU8~͋5ִ4a邧#t'4Ox'dKD1v4Of4f~L隧u<"5F^Չe5.>T}@ BLO//cP'<ޢJyM# h Jpyi8Ƙ2j\$23/ƿr/8~vN ې/FlVO zp8wx|0Βg.e>}f1e%N\2f=8VdzWO}z?|i\u=!O>Q-zhxZ96'>yts'ʑ+>M[3T-V@Ǖ4Q}z/ͳ:#<@Dz` .Dj C ' U{^ϐbSGQUy[YyzY/z}rmyXS^i&\qNAajgfj7ңQw֞sT<ӆU1!u]'/P#@Cl3iAurL:)'㙏{zb7#.qI$墡<9?^յ? zP<(T<}3`$gw9,^ rd_-Ϡvhv8L_{%y:2V3 w<ῳ;;)KMg<=k_NUR^@m3aB`[I췼Vs<ǚmmyPߠ-Bxn xb҃KL%L{oxm=}v/zpmN| !O>)f<nLCVCj!4Crxn.MP(z- QU]ֻ ! >Ep6ػ]kf5/l{TMA41+;Y$LxQ\}V0_tѰSIz}ڨ]f9@V9"j̿eM&<頩jij+e;=ņ'fq(\RS ]փ.׉ҧ{KQsbq>eH1J)OD{xJ\!͹gm5Id7PS_>qF,VTxz/ϴzh83 >Ay@tN y;~xn7?,Pһf4<ɖpPj4+wzJjOփ{, L) *ZY#2: 6 ~yHUb7Õɬr'O49@Î/KӋV0:I\է50Ls@wU0QjPF| CHlx/< zX9JR=KLspߜ2\{= Zj7xY6KI{Lޥ_mXXJ Eõk-")RӡiYXBJ 5b\wqMÆguHgLO9D ?M8:t8*&yxH ЩѺ*QmM3;qH5r15LS#{džIؿ$m5oaYL5x$MA! =փѥl*j֖ kNojó뒨6s˶9&LVH*x;c)8|Ş;O_k9x"6#RqOLqsݳ? }ڄ'BoEv,8 󔪆<O' <)y }"Dɪ_3?pMgAz,87DrT-R:x:oM^(,S_%P@'ybȿO*`%i<Z6i"-ĵ`f1zJ!3=<#<3_*81R6TgFC1aLO'%D5#uȟ/{a$bΛFa$“4 '<*qVۃ'r.* $Me4 DT|'$ζȂVCBjnxlDG3m YĤOa}hSYm, ͜hsMQ2<;$,R̿[|~c\zW/ Lfa#+QM&6 Sr:b<)SԪ*ͧ@>uwڃ;A[o%kfxBFn yAN.3Il<C#<=i{T7́>m0+U!wi'gz Omz)wƦUՋ-q7=$~:tAjڧ\)2T6fnSZʠ7q5?upRC&GIfdϢfXrV$|O26fQ_qD"~ѫcϠ"H+ߧH%9Ic%PX<ݜ.\'"AVi'' |{(3j.0"$xON#<]9 ;ժ\[mA1CdSK{egzKx|5M4E7V+*G\;bT}a}'Ahv3?xͿF2LAj9OPFγ`˱dʾC,.T뎘2߮^`[vhɁn d *b"Z/hZSի 9r]T5:N=@Xo +Q'!CgdY`lDOUM$PȀ4I"(*rgا3_IB4CƓbO ǯ%U&Ο_OJxm(!˾3Y}J ;A4RkOwF'y)ΰҫsL:Hg> rpƠHi0Rj~"<)q_n*iR<ei9_tV/Sb@@(+g JS->!S}?i6抪1b<O""#`OOrLOOG鯷DM&Vz}{h L'\7VCT/SڋXuuf-l@tƓuf%\?bW'4)^ O(jv~LqOFO+/ڃ_l)ƟIdv,r( ?NO )K2ˏ}$ϷC%{XJ/-j`_lW.N*9T1uyt8Mtϟ$3!wIH 4=≮'D~Q3kGb5MED}rܰTCy9<]{L{0 ӱۥLXxIڃ'n\Oxi/y6Bx:<C;<_PAEB }8]"8mZ Ix괚RbUW ˆ]e,<'<ےȌb<{I}Fzl::xFqƊ!!,ò>`dŮYl lďd:_'z/Kmgzx]2s.!haLa$؍'.LΘTۄ@&[TG+oq*>X݇~`cbO͸w OUl Q3s ]#X5UCX1X֏ ]s531mS:-xˣLG+u!mLg5$LUgZT<bڎїMf\(;o {hjB1gB[i|,yAR }s lp~8`9Va0V `E?cY1L籛k;cۧm lZc_o4$o=4k#sxSj~,w4J#vc 'f'-dkO_ۧcVW+ Κ}:!5xBP'JLf"26 .j}`")sGd"#0>VA&=3REXC4ᩝvF5X@݈{7]戲쌙3E8u_ǯ-lXg[0cǃӸ{$~:zfw=I+ H (_Ǭb Ff0d>C1 +`vSxbߞ-z bezz=J;dTw~UgQp8yX5fق 0b(<5{QSQ`O=H;mL3)[>m}&1{O-}sv|a(j@OR$mX9Yh]`/**66Ȼ>ȸ#sxVVLFmDPOxZ3np չ07ZΨ gKU7s~'y`{مYs}o[{k|z%D`r 3 0- Yg/*+g?q8p>-ŷ&ه'%m>e0SY-2Ϝçkh~sO(Tv/;fr Ξ]opQ^A i$^r gКvJcQk@ V=U,1ص g`״ iDCO/N$ǘCIj~[`ļ!˰ߡ9lcq*B|EX| pTKڣj{`&0^!DTLE{%hJ/@P?^}^kan .8!zK>4؆} fǓ8<mj ==vnK/\#`.7fcش u*hj^h\DlY?OPW1|'x_p!Ê:=SSûA[R{$f )ʳ r .†͠mȹ`f8Cz: nyT ;O6tg'xbsg@C n{]|3wIF[/g D0:{iY:``>kx(+`ٍ\~ch}C:aBOVVYj$%^䄓1D ~+pJ IYX& 38`;~鹸{S|vc"yӝŲ&yU3: {QekSq  _ݭSgO4xbޚm:g~2 /!yfΜ=&[d]D2ոV>|gX! rQ f#z\(T{U$댜O-<)\ ԐQ<b"y~"/>t. kbA0~!9nZA=gh*<{0SǻdMEGߗnONЪBeRMU9 /pv,Oe[w?glEks@ (l֤;x.|yOƁA; hWC9lz?0&{b>!bdl׎Bg) R a){j'Ycf >3{pő&O"<ٶzŢh"dGmޝkZW"F`ΠOՔeGK.ۜ3{VFt!Tyq?K şۀgz\{F;/{7}Ong)GO!@M#)m}Z?0LW,k?U|祦"C|H_IS_R3f}.xvGzx2LL?&`6$OZp YTF9iT۱͊K_Y_dM˞ \uפ84$X<ݢɂp`{[V޷2$*M$)S8t59Z%b-s/pYxEg S˻Bj9؇?}^9v! .9x;p||,r~5WәڦȰ%j<]\M'GњMON&>j$R8QtrN7DwR+)Sx48pM)}t0Ba,k%Dh^/Yy>\e4ⴺ?TRȖJY=<#uԅߜ?f 9=>Cr:j(mxun>WVQRj?Jib<)30Gg(V[g:"SkT \Eb o>TmpAJc4%-T!i ip5KqEl]f]߃jv 9\6.ه$$z+j%Hga IyWj:i4gq:RyoN\}~t'gK?-kO;IK:o{׶TQG|_>† QYnIVD>$3xjjvP%+'gا7w&Q{g3W}8x粴8'<{hI9D p5RnW@a5 _7~+*2H8iR62,UsGw<#)12|D t!Y>%|ql_G/߼ȱO˨$- t(~.:e]l83p!>;]B?CN[gZݞ//4<.]B$UwFXW8o6{PEIYySeVJβ^AxKIsK{&ʰ}F'sCHlMhkPMX`fyε`pP SÝxFfք6_/]/(Qdr¬߉LJ/@<UN)n(/e^GHqKq| R67,0Khz;hzE>9QoMOP[)h<{eHg& x/lج(dDEǫtOD@>a1 # ] ,ۼ|ri4 ?BRpQGHV䭞Bf  g](R4gn繑>'為y 9~Exxz,³X6oMJϯdx޻йI|AdXOSQS{pFAg6@KQba==U И-+ M췵64;D2ԍ${_/Έ2ݞxt 5ؾ=YXح?,S}vS+2@f(bFyBN0l Iv2w$-4zu [~ŊC`{HDq5k6b['AF%=)Vs'5ش1J=X= )_x-8~nzαG ݆o^d*_+X4 .8ⴿ3\ngPYzrFн"W'\DZh B-ꜣ &1\\δeIy^jOyzXCX֝8|AK~ova>WoNN޿41r? M <1JYD\{0qfLQ6xMf:FNJ ^U.@Ifm6b< 8~_l*ɏͷ}qP/Y6PvI\~,>]5MaUJTqx9acX>ڥ9Xע u>}u#ίGZ}lnKE5~LI| <3)U(A ޟ_z1: f$^=zyM'xXԊYjgf.V҃UĨobTP_$>*p.JFPX3ZxNzY^:oo\Njs/j{4rǫ[&yD҃:`nquW`4;Xx^/i;8W584;->ݎ?m0yHlc8Q3<Nr?b jzq5]. ~mۋS(D;|u feEa)J{_ajAuD-VV۟ 3UXi^b&'\$1HRX?۳xhO;сްl{{b5ؾN!R-<+U,oIcC٣op|_u;{s(siFB|$S^M sEZsz쉩Zhz2 ~RpjV0ʼF#ye]:*9:md# ](=jy;²O#a4VH~vWO[L]廌d߽oy8r{~ý>V\_:1q/RnYRCIɔ9E\pT{`f-Nt޷fb@͗$27~DRٱHA[c0*7)9rH T jׇtB:xVR.*ꎧF+H+JOU1{9٩jT-dM!޵Kf?gw]Y<@Zv!UdH;Z<tp^pcEشY˪v}J<{cphnGrJ"i!Te=:VB$Db n;_xݖFQ'ϴ12rzl/' ;GFUE4Nqk]`U(V۫O8)WB!xhSq8q w^uӸt  xe^c_TӯARw5hPexJHIkid<ֱv᪋LH,8u^k5]WQbaˬKd0|hL=vLTb|)# z/aݓsoF繥t*ڂ =̣dŨԩHm_( T=ƞ 0{O*.#<4 JBI=@M~8t;}] xHvA12iGxX6M|8y2FIiԕ5I.x'_r,Nl![5QMhШ=nR pLUh1r=yHgjiOGKB.u<<)sA!?;yCx4)캛 鮥!Fչ9|h{vOtmo 'q~CpE=t^T/Soqg׏D9L?6\/1.>\Dd9OMjkG,]wmN$cx/@>P+PST?I~ܶܫU'of?".H !_NHLC2/- >6:'v%6,5893xn}*E๴136Μg9f?bd| -)Xj[w&2ڏavK 3 (E"a/Ϻ77CPafQ@~ߨP$geƷOowfͺZ*Xv[x~ JS@\<吺2 N³'|[g==Hb!<}QmFw^I(ch|:~!;N;X 6Zt"[ڥҥW䑉 lKPZDͷ/&||jW&$^9%=X'O t<[U[(f4Vu>yA2%U%Dfg[Jw5xn'%a40Bv{ԶY|dgгJ["y.x5gT^%ظsza~&x0JZf_DԣF;dDR.d|OE05M|AKLtO18MOՅj$ӣ F y)XIRbxx%Ġ?9AM4 1S\~^jA.!Ss0~WB!^a+|LSV (5gO!pb q`E }{depH{naN_}}'?DY%"2I*Tjdn,sjnrJ<)ye5 Drf {&AdF)zEbxR\E.DUGԕLé<9ӊVX7Lןj՜ȶdlOφaWZo#o.Ѝ.[vTp!E=zTWTF"Wng<:`1&WYߠztHy,C\BMz4} ?5{1PE }DZ#/vEx-ܰgJxdtWDT y`)]H.(j- OK'R[Q aV-!mea.̭;;>ڮd4wۮr^?GZO4j!*B>jx.lI T`禕8hYC4я=55<{ O㑕k Kqr<[%Ewwʓc{ )kUw1M9!3W⠝M * MFZi6in-pH1x%>.eϬEٞc%-w \/Xku[5#1KkOE$ HgH&/ceJϫ!zT:WCn rÍW) S<Yav] ~w!l[Y/Nl WYy$wy`fjS09Mv۲ tO֦1y:N2JA-a%=+h b쓌rP06.k Ѳ| W(u+atەsSmUEKBqH6ɪDc–ոmsxfaFL #X;5XIXš9߉֌ȁK_#RC'#h²{IGfb*3oM% O~( 8`x| Tp!ƓAevn[]9~¢䏬lՕYig1޵z3^,*X86Gp$6IlēxrvNb2[ ܵ8etafNә4~؃=lߩ4zOnDb3y7L1<>IQlXe8x#S==%?YYiN أ=sv"YHmu9I9*POR&yVAbiJ88 Z%x& #X Sp^%7pacv3/ .fT!_)ē pI+) TW0ŸkIc(W݃>`>\x8^') Z;t<\r`ِAd p?Z`aKO7;볺O={샿8 gL5_ϟٱ^aJhECᙸD. '+.T OΎvwߦis7~0 |xnG^}Qбs\?11gi/wUǔtx# ?~/9@“3v IRk<8Y2hցGIZV6Y|AMx,t}NLx}_cz i|A<+GZxxӾogGS'ޱ X*O]_kmpn*05' Kg12:(_'p?&gji+@؅k 1SŢ2agqu._ナ]񸃧hIN"2S*'W~8[W~Ƿk}}lށ}>~y?lj7'GϢEcی(^TD P$v}mw}اc2*ljEX<9c2OB9EZgrB7l*<jm!!jͯ($xԋgMq-Stm̡ ]VetM sPbpTgקj! Oq=>s .Kt>yj_g:3e_'6g,k[OÒh_|)xa< ^s-N< ku]5W.|~eС"R0,dmk:TZo)O3]T8 ҡx4N>`X z%Ŋ[fv2pB  $.k]2مw|/&ĒW pSI4jE͸l5-c+UL^v%]pmx/4onk.tEu|ߛǧO߅9qecq17&Kxxj :e!)w7WN+<9SPPs0>ن9xW VᰉŠCջ}s(|*yX?S= V*cا xEkG=ƧƿS]eRhsvB>ތ#ӸH|^ )/FӴk]M﮲O=~ XdL5#<Zepg'!DIC]#fm\G=DNv!ORx"S낖/^ˮ!ʹ[uB)-3ᙱC0kZwr-Ƨ,ʯpSRL_7#>'xlUEDxN|?9\߉28iK kxpy|_ampÚV(xߝܼ3Eƒ/uJcT} 7]CWN05 7^)X(%5%,֕jr!ӔC3S(34yMN,3J-l5xgpm{ =\Iv)TD3m:{wFc%j+B>ٌٲ3_o}w.|/Naޯ~._5\\4;AȟX c⡭0m{,xMfAn~09(IDEɒZ{3sWY>=Hūǡz̛>_',r/ۜhCg%,a4Gld*8CQ_ |Ѫ':VY-#=j=6N+: Ӻ*R|Sb}.1E|Ɇ`6= 10^mC<{Kj!}r9^y?~sAsaośgөMDgȭhx:lG>۷] ^} )$~p%΍3$}^_)__ē :8͆ |맸nş1!<])o$?!h“]<$Ó_B{&yNPxr]F׶x@$@Bs!ȠI|n n#fVlxrz=a 1.!f9؛&z |>MWخ}R#_?kr3œK+4fgugjOh1.=Wf/{]<elrcg'r#0›7 C&D@̯ OG2R ݈dA >g>\d}LYF+rSl0nAw.^᜗GZdޓhy5X9Yg^ߕ땼J<$'( )Rӊx8luhp‷`+,,nK7FgwO3#"Rq\p"lӰ2<ۏy|h+~}iO2lvEо̶NDj .;K EOx9E*jH2`W<ƄT C6;>-“#sE*}76g$췔3rgMgH9*j<~$'#'I cKTmT,T']4DRWgDl~o9\~RRE8\YYR~=[# vP7^-Y=Sgn7;K5bZ;ɡ2 hDZbOHֿ63qu<<~t'pR޵ro}-G]\d"'5ۯ[xw^kIfQ_PprS?ܹO]֌∹:|wH}+w%Ӟڧ3=DVҏSLF%i3eI\3fO(Ui*eÞ_1rSAkgA$x"' l/b0} w86YZ~g'vt>}B5F2V/H< OV+@H?܁__bUy: ,)c5>̬ e]Ü.DtfN5b=xIKNh"#<&'š$Aœ<92D."e5CcECCLa$#6h 5naۄҗK粵OtA2nHZDj"{0_`!*L0ΟO>MY(U_n|cjsS'ۥ+C[^8Ë]) K^'])8,g2=OѨqW sZӚIf{t|ug *ߣ;3UR',DrxV Ns{冭]@'zDDc@s1 ]")x* o̜'ҏiAf`)_牢C%2Y#w5cS"*; Ɇ޳O8mZzݹW~U5E9{~io xaxeaUgDBIl22V>]<;{R#G^L$WI-یj<Nm [|ڷ5uU;@5<ێmAZC2dhgpxy}xO H{̯,< \hzWognGsKgb~P_'eDOX Dvn VTVo~X޽h%kq~I(OC8D}]N{HQ4=9/nnv죠  iQ,_>vu<rxTge`[igvi%Mal;d=Dxr)ݺQ1Bqpv' ۋ(No/Y7꒸`"T =On'ηRTT|Zڃ9) 'tDOvlyl '\r8P t+]t7~E5vhn8C-^ DzԤ$xZJو2T%/wc摥f¤ogg /ǫw7b ֲOHdc,AmAN1l8ω$ʂVthNmo]7vz+P l'|OYY5ڰhmf_r.;Az<[)#Vk,$(耯 wNP8~f чD3`k-RkoDIX6= >O%llxsI4rs$mYbO/<=>]6FP&?p~I@Ǫ{1H{9XȮ- d( !ҳ[ϯlaw~q(2k8}BN>5"H OvV,ɸIν넥b" oJ?z~մOѨNm#M´|]ۂ{RRU2 [fiy+Ihi$eMktl$[:$:1  3rqsIAmas>B)\ %p7Hv&i/"öA^S<)&_rͮ{ Zg3ȴ9-c&~SC%qZYL\uPq+;xW1Y16v|DQjsS/xthkC|.]ϕp`z'KC-9z+1:Ah# bFÄ.*RBmŅyTJ`&f?Yfjn|r ϖێjXMa=<ٟ}~SN>3xRg~$6 k7Y!s\b5w!b#7L^⎞,sγG@ rrT N3`&2TW>I9$*XW/vuhl54r+J4x`M@4mCT"M/jp׮?S,։_E:ew$33'؅?J j|`p~yuùs8(<|1w1@> r ȕKvdϷ8`% bV1s+ 6ukZZ_%_AYu!,} mO^>u iVS?lp\[[#s2',I`߶woM Rg*a]}T.kEH{ o~l\1?.^U,J)pnpbW,im@Iy/n1k||?sĨ`,57wꞲZzȃ_B z~dGb$Lӊ[vMB#lHvL¿E(d@ɧ_D4U.^|j\4g v@$ -l \&4ӗ0q~N~GOg(QKavRJ#| *DzɊ䓢;*'imd 'UY60=<"BbU ;F E?Z !ޏbi-6-ey46dE%s9Guׯ߻/x 6ZX?(U3x5ᕧ!5xn)bLXm % ŴBC1xdxVC %DXfʤZZlr,ĵdF4a{|/G׬Eˏ-wqp|!Ɠ 1,G<38{4Exېw1;<gl(x6d:I{!oUoyxHK?(Ax DnJa([Q[zzO_[MNvCtw.|OF.>HlzWicƠ\uWa.OF1кǿo!O2-2 MdLs {q^}73C{#Sw*IOfJ<]Y[֍W FQ(RN8Z%'_-Smntkל&GZr{j߸Hy*{&oztm,$s*sp ل7?JcɗhR_d(E뱥 9_L~ϚO-f;dC;;2Nj'b<9I6O+Q3\\!}dmo[ idȥw$mC.Kᙶ&mvI/D"'? \ ~4$/C]<'oW ]ŲSx&/$Sg|1uBe`I툥PR-Ųyܬj7>uhOF!؀cF,MLpC^4SC8jLF|R-</;׾\_cd|Z#reD>E]Wc/V>T$27UIFߺÁ֧vOOjtWrΪ-GtR94nŧ~xh~xnm_ q!hՒ?_OmL0e65uI..C(?iDx ?x{-vM𬁋ӗéki ,{RJY7 '*. A>C*Lhy< hj'Յ͟%qА).dU4a' J&7'̓Oލg'qبJjPoU 8xT!;e Uҩۜ [dyȑ~d,,IZ!i?٦Ifm4F9?|?x9\;/OŔ:NV|/\-Jʤ2[5!|Fl.8H־bg5wr/6֋%KxyU 9x"³.J?'.[䁋䳴ȴgNjda[_.W%5:ڷV_Y@}PP?Ӿ'³O#]tI7Hdxe.s_Rg?te"hK.˹:Z_ _zob5BAS2: F&mD=P*REy}ezp:<f vndg5`|y0.n`#+KaVé,ó=fzF8w/ZS̕p|+p4r"Q>"<}yj|G=V]5mA ͊!|ux@PK"f" L 6lOvpe(d P>O*g֘ox&).;;OFtJI(;XT@ٺc,l^UN2\,85(IDz,w`OnI$<*œC ?? \ގ/ġyC^!,Oi[,lfx6vxsi jPr0;fvLK ԁG^y||o3W6 vP봅T OT:tp!P\_u?sR9O㴃x $z|mCOɱa.@1N7|S˃56WVEhyV,pMgP"c"VH]+;G'.ڇTLI[P`S}|_hl^SV&y_y]re¦ē3zWHp3 !&puztU ^"+ lh۴n'進@9cϿKUmv}PFJڊ7e5D 鏥06Y'zK3g*<})H[4Oʪ0 ^/f [9ϝSUb ف>B1le eUV~TDJ+xxjM6y|XTHjfN5M6rXReKn(spZ“-=]qڗ$tI~h/iB -&*zHuL>c'g4/Z0oɾ.Th80g(]SzrιRCOJ2H;,tI.S^葮ӌ wg&PnI CH٢ݷ\N,> c/eř'eaV|WJ^\yH܌5*Mh~W :~U_'_;{Xm 5v?y i}cS<ISaiմd_%6]g2\5B>r42ީ _6k>¹0l̢Ux:·#!۾k J&8%Axٮ_'amaC }߻n OD63J]1_49u ekilv<~+8(ںDїx >x.<:Yp2;fߤiD:߁ee^RTp+ 5պl%:YSF>f; 9eh˾wW8=_*κ׮5] |hoh'I䓰ȃrƓ<٘еlBi֣f3͘4?!Bc3EC/M4߀M}Kf{J4pX"'b7cߚ?7ƓcPGi_'ؑ#M·}DJS rבl$OGHߓfgR}jd'OxF[?!c"ainsI\g&T˓?^96LHĠKVSv||׳ry\ߝ6I30$sBb/3+D 6M!ĥJ;& ۺTtpxflf&x&PFpI91+G_j-7݋ʟTb yPY,3 _~GfpQpHv۹gpbzt]dhdF[]1 O1gJ 8ǗZ`tp.9\rA@U_] .|LEͥI.!{,Rl7 ?<'oGg3& ,On!b< MT1V@DthR%v#0ތ_9Z|t,֭/9cy= ۓe]!cV@5\ᙓq{_eӮ/$<:w!م;4:uaIH;8d}`-L=#j59`,"!+a͞Ʋ,.TϸQ͎~dWuOઇpcQGɠ[h2Խ̶3g4+OA#6} Xڇ S8A]Lea9Ƶd~b,"i!<Sx.Ō(M 2"-LppoWfm Y(]˛㩉t`uC tN,?&@ksp3 i'Bզ]O)$JҶ>A{OZN=x3 X蠳П3zvǧ5PEOWQfwVB?@/xeÞ|.GcKO?&Zqy<{?|ΟD,7ono_Oؽ#\$F^qVS}:<[ٚStm_ μNj+X6S qbaY+ 0UFpe=(>|{ґ<n2d`m=9eEڍPx`gt 7oBe'lʺm#I<ɋ-0 ۲RlOQ׍GPEiJgOUR+a|LOa"Zh'< 8tcZ!g{j#B,p\_α$g_Ċ!tv6L%-^r4xd$wz+z$>O]W!!9E|b&U8֒cT*AQ)~ uG$=R ON<۰ұEfK7> ³3WR_x`OR45޵a^'<MF'w\"x7\-ij~/w1lIGsWHj9ݚ#$K >SH&']w{Z0I-`5*̮_фAb%xjJ`|!K5?I^'ST 6ȾYaw^{Q *hdA-gr&N4yAⳁ_2a@qU~' *: I?CJ]YIO9vo }qD*Y0<9B/sxU8qܳ^[`؁0Z"BjOW(i&/OX_ I9G4/#Njg?t|{'t04GcLӷoچ -;OY O!=J022޵ ?^'b2ůBGzi~E"d/3x*h&c. فU櫳qP<<#LjV{_\]O_iBBfSqW޹ _<)ē  ͽOOșF-8r\sm+& OP+ (4ձu'%}t/݋ժ;RY?d4m_"4V`yO.ntMnexV9Ɖ|RxOz{]cNBLֿ220ӉO ~n ۯ,g|GB6#A-ʫW8< QUX*y 9ӚyVUu# fjr)a- e#"8 ;϶Z/t:8ֶ"L c/ؤ ]`%es[]2>pցh ˽4i"<-2!}a& u q}*/]0?O2QLȍk?S2&{>H2]3}$ p w+yTJ/ b`gC=tg€h<͸>.sn0?mA@_O=~ (?c2 _ H6{Df%s&K3xaz12cp;xб)D@z>o%Z>)i:Ii/d0|'l/,-ǡcC?a<@ nF4dM'I<<$ahH'.9mB\|FL eRpq3!<^EhR3ž<%^ %b*zE,z9C-btwK(ag6 cxTV 7,u?)^;DL4.h:gWLy++Sv_װD9afo;@*O lsuO OGկ rJ2^u$leڈx64i6NI1;ǛwƍY+8x;Y7#B-.̆.m[#Hbf!C1tϱ_xX7ݰ'ҿA|F` 12ų.y_ӯGnΦW]9q@0ҿ㉽U( UO>}K$xZ8'"P`gf:EA>O" mٍ> i6uEÒWjn 9jN/F8INMiF <kdzL~Q`xgMaڨˑ3Sœ04UfY{Oܼ'<&)VPME/<#=05`V`H 9yPx1ed^W^&eߜ~jsLiMr J#Ěav' zKt#az._|J p]WJ[ͲE81FPx%H^et|zY $#'0 O'4Z&xBMA6x s:<IaHvI 9aJF(mA4oMN%xR\h,:sS8 W$N fRSga/nM.NOтDs t 7m:EswGC6`;DYξ>'yJw4p"hOTR2 `$l*#ʶM O8vlvaߊv9$\C٨Kw2xBN-H>r#{1e~ ;"HI¾%لR_ {Txvt@I~^!q )sacnʀx#}YRf f8 :39ҖSʂfq'Ϫͧ> |w55ź\_2'S<)_$*<6i>?4z5! OZ~!ki=H2 WgNH˃ sxI.G+prc3іǓaj$226OG @ }*a9]u8k^Sʪ|F#LUAC 8H\7>ݙd/ݕtxN6aɆu iI83x]Nq#(kHֽO#4;ɁuxRV>x>yO|‘{5Ó%$ST3^CްqH y`}wto|;d>|hO2x7,J A77&Jv.ԡ P!Uwc/"ȤpO.O6Q9kGTtѐvf.ϯ֣EXrEɁTsE]yeDK/o+ хeQo-~cUYfc"‡ouʲע:24GBHkExz0kfx׬5T.qՃ{ iB T>gȧ_ q/`{oj[%OxVc!$*&xROxf˒ JIWLj-,h5Mcz! xB%ceW03 Q _Ffp$Ml'يǚʤ3C&ڳ=$pgW!Pv353CclNvS(}͓>%wSOm,0Q?=%oi֪؇xI+lА#_P[<[jmflu}+hab=eCIx? 9MYT:KlG}P9 B:&5^qq@S|Hed89$8I͜6*MJ' _7cQxÓbr!)[A`yVTQpVLmRXt*³paU$&:'7٪+m'ehNH |BMO?y ,Pџ!JťI O։u܁$' Os`q/t5AOR)+'3Ldg4$XIг!_|v}ۥ3/`  XigtБPdЖo ;A}cRyYS86x:|U8lgV7.~J,>ߐSȾ1âO4G?}' 3XIP;CƐᥜ3AY;ے*@uxRG5=E$Mwk9oLKHmEx-5d7+b|J ]K0J`;PG C~b:Kk:8Hlt{۰kl*Q mU;}NJi7lsgnk^Y;0''ekw]7_dA:@uI<|C0M NF={]?71Q+B7/;6*45IS&0]B r{,]y ~e w.ę?S3 pZhB1 *qi O Pɇ순YR详` >l&U 2&Culr-G 8o^CI|G=m-TⵑlnOy2p/ݑI̦<6!?N`s<LM^(!DAO[z߱dIu/;`@% =g HCJz;'5 eUNiPr8(91;PTZD*1=m _Ok:Rؑ2}'uH6.!O=Of`q%tMSָ̏kɌe'J*c+UMcl'Bqh?=+{xR~!FtB#wk$Y%dpN|\bcOU(ExÓ |zN' qgӤ:9| ~Aބ*Y<o،O`儈F 5FxrQ4$Q&A/p֓pӅ1:c$Qg+<9Wڐbx*4Sϴ3Vt/J>u۲ -Bw b|Fx#L3MԀ^H=g%y m|'/s8拵}AW F2aǓ 4VQc Ud=Odz@.r'Im]^ Eg~1ހj}䙙M+7MG:v-REԉ៎|tA_Ȑb.A;+_2yEp -V]S M͙S'@"opQ^GwAY viR5\z":98V4TXP $*ۈAMUt-ҷF̬`uaң'l+/6'"#{o! KVoos 14m*M\d{O"n}C.~֙*N*!O>@k/AuKՇ2us5kq6tfWS%[E)I }br/5, 1EJo/>_8{iGRr\@"@i/VœY gt(!R/t& &[ANZfz3ڻr~OJ O>_L3>$Ɍ,)T0OfQ4LfU"ÌCu1j|Tp&Dti"fir="B#'Wt2;MaSRW܋a;;wOᅨN5x&xCp(fgqJ[s[u6L9^x3W_"'bSaecSM]Cy2rc'zz wp!nG&S̥gM-,t3 [}̕2tx&AEH2jx 1 L5<; lJpQ˵qxt'OUmGOxcwGqgvz,r NDU~쿖Vp+06җ˒1k>UjAJYŐ)3|ڬ|xzYg›/^N "^ OՁؑy.&AMPx^(3`P5YBE;}S%%"acDfI'Ig=w_n-0mx8$R25:,<6>ss 00#u ؄Z~J{]ޤ­CS8n ~D|5ŷɧc3@_ &c;57Z$=}cx yUxx>8q&)`*>/I顴*&'\=p?1B+ZʬœU4N>thno9|^\pHIh/z0wd"(k4nY/= 3AOE!8y%N8jE1$a֟I~7BS{wb~ ,;_w| sYϞǁq /X}U'Q<;I7`"<3̳O*'jZ!٘*ۭѻ؅؈z vz„|~U8`47Z%'Ƀӷ=;*yKgm_<+ `Gs\+$'=$Ouj 2 sT)' ӫ4d@ZdzV4h "xQo"uh@aˠ;FCUa~aI-\D hTApFI(H3 %ۜ_O]w=w]%pws]txxz85ٷ J(Ez-+_1nR'lCWnMIDx z(f6kcv:$~਍8~/'N_æ0<]wRcimT{6-5M|8^hT<ߛSxj[uLb֎`AXaCŐt?or*uB_zf4=JBG<Mebo8_Ex"/hȅLsrQ D&n #iڂ۩hK&1;\&ub=ɹ`>iO2Q_#;u&fvdbh"C;03o.w}-ZԬvxO?F`=p3#``Cg-sY[BL$A:HV3IMiiڶl &s 8~-|Z b-h*;lW쩻Fm9+i<)g(խ䜥Lnm?x^SvV0?! c8'e\2r/q BqMg@ECڋBQ@/xfj)YpmyĒ|^^tl7`~h*NJc_)Yux q>A5C6yC+]@ $ } z*<3xGV_I C_,4S9lFڢp~F r^mͰ, <܆ߛw}YFvͷzF|Ѭ&i@(w(`^,cdvafYy{\'Dž|XmxxWqVˇsCQ)i ӑ4$;>Q阉OsUwp'@F3ٲhd+khێ]^bڍtMز+?^%"x> /3&w.3_.agﶺ^ >~3&UD=-'Ӌ3 =;0O=70U6Q{1Bɫ6#l/)*շ׺sʵ _D%l {n6CO*<v:4xv7e`ӃuT8ruqGa$g*7{1(j-Yh"۵xj*?QH2(箹/wW_E d6S8-ӷg(eQ2D8Wq8E:a Mf1Y 3)j>'OrʚDWGP#/}5Z|''5_ja=YH7V]{mW,QGFzdj>A0e(Fut \%<#GơZH{:JkgN9P{jip> hW֧8b'\'D@ќ˿٢'] I1*J_;i#i M|ht$Q5%ejw>w&xB8ɼIIyxµ1wk^khMmfZ|C{_m'C-_+-ʛ⣷@> 3ZL9ǭxD|E>(jC$ Ta _{\3]F_UsIĥ-ݮ # R5X⒡CJLouʃORcnAYKK[|9J]d2 AKYgxy c|.0x_Ϸ}7Z7o ^jhX' Vd[D-[B&x}]w1тS뙘#mц S^]N~ҕOf~ <B`L~cM0S9O̘=} !%IJb_0w!df<;Rlڴy4әd B&\JPb1;, Rg^!X|J$狿,xo7ͭj/?q19O<Ymxs\㗿^v1l_loe[}{z[<frT! LUӖ< "(n^],+PX%;KIBκ{mj@BfCA: #UX?Wز $ghOO}<$GpӪVl]5-tn5X]LS|H=YޕO*WR$kw=%D|DFW͈/| 21s0j_u/Z H.nF7d+ץenN 3Tl Ƴ~ Xgf/w-ڨ;CIDӤF:\p5vLKyxR>uT=6@ y}sxE"FH; |, YۛO#hR健̸ibzD\8oS'5W&.OMҢ tM?+&>0N$/ys/ #alJXǤwub"rEaUÿ!\lojoe4¿*0hr~7fg[q9i\@RO6٢(~glk?r{V٦7ksmԜgOo|]k-oOsn^x~%}=q.} ϲS!4E,Hrͧ nG/,\#B_MC7u J}zᎧYihAqCҁDy ?ѻ;.Ҳ$M&A/i#elk,[]Q9yk'$Oؾy/nnL`:HRȑc7!I뿅Y= C6Ԃ^ _a&7[ŇNjßx{mģ9T e P>&\Y[V &f+xkv߮l-9>^G#k`W2 ^Hx'&Al)Pŵ; 5J?׌U,Y_8O ~nb ObW0O?\8ڧЎ;s{q 7Ϩ 扊OXIzjۈS~VPSErwRĄ53} \P|aü=߆e|ө`AS<ң+ G^a*G2C\c_nz |j"exAm9 )n)s]Eeg{tHKwL3ݰ@ iIG+y+/5MM Ӷ*JNf"lܢB}?sN))Ob_q| 'Ԁ8֢};:Y.!LQ=dx5 ޅw]!H7 w-O>8َW|f9O'xԳ ϟ~ V*M46 OZcld;up'>?>rLi E | 9 Gam;G4 ظoƞ;HNUI,OU9AJt ~Ub 4у#-*iGRSIRS;B{M.Ih?mlNT$'S "Co=Oފ_ NleЫsuB|ݻ? דl 4DЧ;5T '(kx6tiSDQ}Cxcy?QVXxES`P⟽?8vm1x3)<~ n}hxjM㖱\?v3^f }z2!ԦE̿ e9[>?L%ӵ@{o~o۰y\Rא 3ZP_a^Ҝ\p(njzowws<'.sxخ!~&ÆoYT')hir3.ߡwP'o #O} oGu:c]q CO$z`ޫ9}+6&Cl%0tܾqS/wwݍǞb9ʦ +O'bGB΄ѧ_@Im] D9O޶_ oŃW䩰dR4LksVb|*?_U<Q7yrbH^rMO>[ZHbs8$ZhuLZY ;E8Ͽ_|_;7'/lg¿/a"1Ä}f:{cӣkyI|/Sg' 4PKڒ'ӧtNEXC%AM 囱BZ-IҤ%;̶,?xϪHq?Ұ<OW'0qvk;`/$;[h6nS,MƞeSɮ]]'h|׎L}0; H9*ܡt8\w-FaIL R9l]`ۏP}SH$5/ow; _/N+iǑ7}/ 9FD`zygp7^v9xc_;Oo/܄z;~^O>OIx*3W4>N5W<e0I޿ 7>7B7E}mLON-xe끵7R=4ʇN{+މ{y]_ŠR^_zw5I-OER=AJ=t z[+n9wuE={DLx?[ ~}~>}+14koCx W3_>|'kPX=v\&%_}zc!~GȀ؟y|_mue+?S_G%gq,>v;)qEp_Vs=RZ<?w ^78 yOþ3 $5oWRgb#$쏤Y/v~lŽGZy1"8!N;)g r2`?R\2ӥlG 7%}nYh.aKrbwM]S0yw=z/?p#iP<'Os7c?.d<GbSx]} n+m3"hFkPo;#xX\˚ϼr'K^o|WKͧSzWop?OaOh6`էO3( a0^]~/߇[*|-x)\{jSnloOޏ7{wt/SÉAx5R1)a#ny'/dОB&nnQc_}nx}v|sfY Oqޛz]Ji_f <='?,/3owixsq=0P)(oO5ыVw3o86_9K'axC 5x3 OX/L,/*|i]82O_߽zP/gGk[I}ZJZ}u2Clk(m"4ӽņ<SeX3/z<}{vq0\rAIeg<]l~mڋbP[Вf0U&MSC%HgzW!P}ψOy*8(Ht (O<)A^o"| /x 'b+]S ?_w]}K|!~̊g,*רWxN?}C_{' EgpU뀩0'p{?1ֻ dpӥlAâY™6<(܋,^{+^ nyxv͏><0^^yWp=i7> ³ڗW\v8Q Ϩķ|!'ٍ\8?9o?O  {5n59(m5uOS;~.Z ֪9*B-O:oNFFc| q[:qG>9&kϟ%Fe}|!~gqSyކ4~M8{Η&9q#oXSOPޥb³<5Lg$^ſ=U5'mĹѺf>ɖJ5 gDl'\_q X}zT =4K ߵu O[7u'pi=9'ogo'pY~#x\ss=4mo T_R|ӝpI8/gUɛ3!x44x/]*Riw} ^{^ n:n58u=8={oĥSq7Dy2}FB^?43Ӄ \AuKդ]?wKnĝ' Ix r~r' ?} > yo.<C { -CmYci@|+IW_b|xt§oĻ>_Yi6;4z/_t'<}jcyӵ/÷ _s ^x;nƇO>s`x6{\pj_bpO“ό.@0zɼҧMo^a>I6'odRқkkqn=­y))œp<z,=+H&ޮ'}yxMx<< xZy< s#x<^M.&x :"Yr7nǫ5ۋ #߉O5(zs$A闏ŏ,7~4 )H?!)DQVٛ6n'd:$xY =؈<V3l/f۶˝&y\q%vgX7Zy[Y&y.0OGDx} U۟Ss:N}.J #욫[m≴, {y7KS<|M0TaBcYaW}N!,$O>]k&ySއ_z\3= %<}tyጧȨ!Ue4 ^ChK"e@&9ETyl%c̰@'=O 1uzдvg!œxqt)_}N؎&L>ß46 $OĿ\\'B O%su &!03MIZ< !ٝ^/5?Wgzd']Iܬ]]r>\PNNaa'F\-x <ϕ߮X.G9,GaS~'b TyTt^AyB[ўֿ _d['؃SO:OMNA3\rL: 4Kxbgǿ>< M/!w~8;yJ Ox$OSs2S/S~_8zџ^\6z穁H>zy qaщ1{B0Ob.̒F_ӭd[J51}f# ODʓ%J]範&<|x _Zt>V|;3wd4&kO)p򩭼8(^0_p8ܜ+ UaEg.Hy̎"eʳG|Lj?!:^IDyA,\ʎs#*OLHD,x"C3S>8\j>!G!= ) Oi><}& pjJxf'fx"קl)Ltɞ<PW9)eX٣=xr=8'>!=x<ЂAy1=}JB;sJvgG Oi"}iCn9>Oj'81 sʿJ}ca)0&FvBǓsHx"O45OhVy}TSC<< 4#k}fiOÉ)G'u|nl\j? FGIͶ1rؕp233<$kyz%/M;!YHϥ]}f-O.Lx*略4Yfӎ mry}z=+<7& Ss}\j OS2]vDgqGTD_˳}J^2lY]xZ>xT<(g m$aԐJ\ϜٞTP2IDwEisIeX:XDnBC2|1_"+~^Ċ"'D:3)L8>AҔ@!ɋ&FIK-*7l2SdJ:*=gͳC'-L0OcI<ݻG}alQZl4wz<h.Ͼr{>yLxvP$o$cgm<1Oz:::Uz~< ٗg1$oG>'Zk=DU|h_ub&_%ϘByJ1H-?&]T,)RQJ& Ϙx Z'rf|4ϗf)2x> 4=ugOpyz0Ǖ6)4pf#E$dzF`}S 0)Lg̚z1YӬxקy Z<+=~Ry= Ѕ|SKBs^_+xf'C\0I/ Ey gZ޿r}ɓ /ʳ}"'O^3!<`zxV宥Ȁ% <0spVS/Fy^}Zw܈w:|:]fŠF#j+@ciy.;\{_εv@5Z H]}6TyQJ%繃XxhtzQ>Orcp>ŕԎDYktU]`τQ=z.jA#OxL%AyڿQB|tA9_O5zh]X+svlk :bu"BSp⟚ױN ^ ;e<_Y /Î~UnBS |B\!ssgǿJ "T;d<ݑrQwg/CdPusjQ'z(NYWtwUx$qY6Z?I=SVT̥JLwg%OqL_>#W 3s3tlNd69<] 9<]|r<(xz!}$`\,Nۈ҃,s Ij6_uOmnȯJi4pt[&i&[" bX/״XFt%LcHS=/I{z삧Nb=ptyyS'-ϾK1(O]xM rG<rX)OXE7.+I ns0' oB.q"-y+PM3vS-Į Bh|+%>XkD j$ BHy<9A%Oyr=Fh+Yaу֏=Z/h$OO g_yk!!E5AKKKW&jd3\Hz8=|8QS{<3!$Z}onrܡ&zz_L!ן2<5A@nob lΓοz#O)yfBpLc< ˫}_pU!+)I$T%FR{|Ц!qASXX7N7H=sb=Y#eF:< *rO['u @NvĿ&yҔ9=Γsz Լb(g~6jM쿪<ߍg*˕ "I|9e"YJU,^\l~'6>:T?I'̍˅|: ph@N%`T r`<-M+R5ZeČdEb 41“C%)OX)eIԔ0}U ƓSó1 VRSr}O0s5S5bc<9H}:O :)%OyJɓo'2Hyz'Ճ a-|.O8 ݲ]oHL$I?QI+O 'xHS<~2[ ߫lz(؟T;5o'YͪjsZ%T]^ke5WR<;z t $-CK$뮨y^eO[ 4KR%*>IVJÜ<;/˓reAkݼ>FV-ޥ'|幜m&<+Ots)4AˣlB5O NR)kx-'ַuyJųo$ʓVڿB&x"A㉜'xjSJ=P 2Z9IIDBtua9?D.0]j]4H, $b ㉜"~'|N q4.OSNz+x:OكmxzS)glCkV6RHS _4׃ݥD1O_(gxFL/,e$xJSiLܿR= '<>aP|'y6B/YSZ<]l_` JFs~*plql+p -4PƟjj8=rEf'*\g*3D4 l'W.$4$TR`ܿ\v̕BȂ$G%zyb OW!x>3<]$Oak2`tY>7Ub -=%QdJ |LG<%,_;]{<{|Q[Gq;m#珬%xf}+l=x<.OQxR6=ZYdRtOzn0v))O0Fwc&Jfݸ:Kד6W9QqXw͊3VvD@wmXbLf8OR}W)SXȓ[,ɖx;M <S<'wI+><z؏ӧ{{S:Ó;Drnj=兵|Th+9l}y_ND9yb-iTc<x"OS}jQS><(=a9Hx % D%OO6Sxr=;/]T~<|VX=L?$ xjS uy_z[xfAGҔN[Knsmu ~>b>vb'oJxhgUv&b`8=).{Ęx8ZO/Y?3hF"B}zX3.;hHJ񌇽;X_cj<> Cz"zgݥvKQShktS 2aON(9ReMqySBK&۰iYW"h~͙:]lWm<ݏ/ >Ԯ<i37b!扐Tiۮ!K\bUy6*e"2bwx;(O;V-OY@I鯂<xYߚd5 LxBln(<3ō="5k7϶ vPl'IqoPr*,p] t[ȓkc¿/vm$Tyi/#`υ顗!yZ !!du(+vN.ʜ աT˛amn.|m$6P4UcޢŸ|ƌ.O .O$x,0OИ}x)&<-]Ov@LҜ;֧HroBدͦW儭gxbĿ~&wS<%,>XIa\(lqG~h ]l3$%I[@{Wj71m06,ܡ@Ã=\ԶZSNEyjSbV$HQHy"fWs-_5~|F!㩖}"m"ϸFO'8O0)m`S)'LقM!^uym&y$z<6N'Cs~|3qS^u+ KhCg|`a=)l PHyF=L4AUMw2&2mL`81'0]wk @")iCYkڄ"%=ثx.83;O-OiBQ6o?Ik޿O/GO 2S5ߥ?Tlk8Qmj? TS<rI8.O3b>Ux[ 8g<Ǔ롹 OW}S;z9bgk?:<~OTFy8 r_z?D/iVxsS~zQwKCeOo@)bYք|E3}ސh;Y匮8O<6NUj=l/$EgX*?9e +?ĠĪi<Fzzv^>4'ʮOE(gwG}ShoyEP&YlUd}aYasp~!?&~vMz\=1IDrp@_ۅgZ4qV7W縝*͑ KmU|DbFQ;_Wv;Mq2]FhI9rYc̿ۢ2]Kk OY}~-Syb-OMk5<֛Ge;}cƦxj3ѧ8z8pS_=i+}$Ix%Ow Hyz>Rӏ=8xJ O_!D-Oc?[ gnˌ>0='4}!Ggx`ziA\SO2̳ 3{`P'. U5nl98O S9Osd6㭝$IlyRmqOQk} {E<3=LɜNH੻Oxbg\$ lڿOMx6 [S Ob3磨I)`ǿD/(O_vaT# 6$;,xϫ{C6aKh>FtW]|\ f4kV3<p엜'./O5P \B%O !C z`<xJÓ7<<13'BV¢Sc{<<v2rkrkL X_<$ 'C>)O<%[.[SNOj%`*D4ULzNtKc%̿Jቌ'R"D[N 9ow%X&ؐqPUAmJ,a0{6,1U@li ڏ>Ox0O҂.:o)=YkgyJӯV Ly֮zpW$O_<# Cمh燎ݨZ3= \ sLaE#Z!ѽ&y5>ϡ/JHn֯:_?OuBc2FqY䗜HICx<hg!%ۉHL<ǦRGq'ݖ޵<'zOb2aL`4ų-xFfk#<+Y!9ajdۻO:w /+õFmJNm+)R,>90cG{-B;m?wg.iJ]ha<`nWz$wy;I@/ꡤ'’⒑C;-O <%鋆0,0͓N!x y0=`P0mSW=j>͵FȢ\Bv{0?^%<%\#}^r\͓ a/O3ڟSztML4TM3</F ɉk=}DYwy9Oy񗖌_C6$Ys,$_Dl_ha>.T&Z6M1lONGYaq/<;j\ $OL>n}Ӥx\x<+xƗw`׿Xwx.xudvCs'<VXORkDIR _aMHxٝ32c.Gc<-ngzX`>}#=x&?/nXOLT3fy" ؟89 "<-zIOWϱ:6.>Ov(z=Q%OmA:Zl^E7yj2C44Y7M'9<Vu R[xFr%Qxb<{ QS]W"m9M""|W1E,W!ڪ_^aͮB3ox Op;$`ቆ'fxR+"ix6KEnkϓf$&bb;OUmAϚ$+ɡz`<57]xb$ѰC#ᩋDSD'y!IN%kx61o_iyfzpd³CsYCX}< _ Ot\tǧihb2\#Om[\=vmM.'>l~=~7t 2SSz,Yx<wyڜ̿z3$t]eyA/)Kz&^[yO@_B O )OiHb-};<ǎF'u|}<ӻWgz${옌z{@5uO=c/'~ēIyOhs_f$csY3<հ<V^MBXj,jTJL7x'$I[1* )3L/"Sp` x/~/zXxc|= =Os,\.5QȘYgZ/<-43oVrtE OOC{R< Skb=71>ЧnϿ,/ dO.^} bO yzDZNP@hsjMbsFl<-xE)g<=j@G4ͪ_kGNB{Zgy= /'h΃y4*=}Oj@4ͭ*'zVWybs^kOaovn\K+Oh9,爻hbs[[=לo-EğqDpD^(t/&\oR;rn.syM~A?3B/R`?'׃}οҵO̦/as/<~Dey|FEI$/z;= yw o,BbS1҃%}*Mũ>\u_"74~_u6Y uF"0V"Ͽ+i6bwZUSYhC$?RtuK^X[Lxk:cMIyc{;4ϪʓoI =3}"}QQۗN[j2(O,Sy`zHw_حNwቯvhh8u;;|gb{7yk[<'ܿ0C E]G`MD\O0`m>xĿ;>N˯q`C?O2 O_'ك)O^6|.Γx)s}*+OhĿbˇeS<;=ǢO5~=<)?3Kſ,Lk5/q+ ?J O3Aڟ4o/4OlxQՃA)g\XByITqxM;i /BFZ=@o#O<C.'!=cg{dER+P&ɺ td] ^ԜRvHd_-\S*~*!GEq_F"9OVȂq˳]w,ҔLqBN'i }m](O+-g!ύfg +OKLqy8z-Utwmq3O<}O/Qa\d$:R{x}JH!OZE$oӰI8<=R>u^psHos_Ɗk4Lx6z=+ceKq<~-8gu TlX2?uk@_چ"+׶wiOnTYC}1"/I&։ޟ O1j^[=LzπgYFPZj1OjJ>=Z ypA\yi5v= /scoL8ԀsRDsȳK e ?h(pr}Ĕ_9֫(mҝ`t^%It7]o|-1S+_꣠=V$)Z *OXd} Oj}#7-OLgxgB*Sk\dg9r%`<Ox&}ZiZ*ͬ5,~฼Hֿ| +Rr@:=(B0RO<})i'(V`ӗOqD<-VN/3_(g%Wl*^|sgf2ӷۉ1f8ɂ\wOLFY2X~t1)4l.M5O/w^@I>SZӢ[me>U:~3v*уiҿly: C3_}A,#03FÔ><2O/ӌ5])Ϫ2D@yO\#=@(lg<< :&Ojyz@Ox:!e;2R8`m'Mxj}_yW!ZZgeNBQm'?xx'XT wUz )Oi>릂'>ϡxZH{s_+yp'p''g>.œV떓wy*&ۺϞ'Wo*Iy6#}~~v@w'lxijnw7z(NT53sWIǓ8hzjy3t?u%>OH j3 xr%J̩Tghi2+O,H]sx3c˛=OTϵ- Oq=h}.M4<Bióܶ]GGn oD@^<$9ˣ*\^|Ǔ\Fyysfs8#6AtOA$@kZire/EyzNҏ`ƿ O?iH"aXIgg)L$P03(-~j"xf=R lx+E>٭fg<˯'gUx'^@zFOL4DS퐧 }t2Rs +=Ot!E$mKXAgXA~R1cO9 N^RZx֟GS<=ךjxJ-OϞ'X6ʳ-krRmS-fZv[}bs]a<9E E:'y_~]hRRHx>zhyb3EWV#[}bS/v 3}Bz&ύTz3pBOxbq&A<><׏Wxn<CM+E4O&f|g-HiC(;.Ӊ&TB FnK/;bs N3ᙌe#į(OZ̿va<7 Wffz`}MAJNւv/M;RZifZhkcv(t֊>*_ WlM{F yZgk2>u(x^וkx"rFx.l<-hx@j ʓ\æ3y9O=Πx'Nxb d|24xو<8qRz,^ruV亯\wyjsAó0J,zx6hy.:>Vz;[*6k-_n8Q=]y<kt\Oq/bSt a1/q;ng@ٟity?Gh8|3a)C5U&' .u$])ɣmT˔ *2/ /E]`y@Pw OON7'׃yzwbVX并qWk+O_qMyޡ!,LWJI$O~2#uq%\^&(bąp}wܦKp83ryH/E7 6TGh`bD*<;=D{ǭzFƊOpSڿ{~?g(Z}g- :y ܯ\"3%ω;/y=x`tg2 }6CR Ig}s.xDLy4^ѽ߄#{,fYՂ[cW?pR'e,gϽQGzrN2wOy{cZwTǹ>z}%jiWyR=Tz`$Ze7|KgtXxL1XӁz~1,Y+`)Kʐ4o3KV)J+ٯxz<->˜t0sCyzGyuN _&0韚j'O{)P韠:&9Q-O+g;}\7434O/A_xpau<=+<4p)Ot/phB/+ǬZSLW`-r Oqz&ڟ" Oic=b<= څ.yJ<=|$M/zy&[ DSˈe0> W]sĀɖdקz~"gXY,3dmH z(v3_3!wt/g^ʍOh^f<ÓuO/隧c=;}9Z ,<gi7.xؿ=Jrv|!OWoxڄQ\y5d'ÉKW}zyg j}= EG>tREB.CղKTtlL/̿,nw_iG@y @Ϧ=O/<ң`O_a}v j:f۵p^<%D 7_OZ+&<-;zKW@myf=,?x:?NovzLIʽ R11.U6|=k1䫂E*sv#M.hYzZxS0+ V bÀSӍ8zk d>YāČ'4O;Jؒe) -O<=VEz<1Ocr)9s'o'ʶVDlW -a Ϛva s?7rQO&?<7/CꁭB#O.(gx+xZ乞$ )w<'LtVSfm\uOILq> ;}:[};'igN9O O  Okē$B.Fx8'^gZy`v|Нa/lӽݮk?٧ Iyڜ'!/(R3ɰYB?yZiSOWN荠z^44PDoײU7}pvΫ>{|yh.,Mg+U&}c?i<ቅ'oxNyڌsrڪӿƳ4wy^zvYw DigCC P><OC(]ϸU<-Ay/c_%x9Tqzs]y]aȓ"ϼ,v^C;>yg[T\K (OZ';< C} _tzgIhv4[Gͺgz w(X̭>{CKG.@94陫1vG_8; [|,YS0Ÿ%=rР{;<!"H𴎧yNx{ XiYZZ`zz`<=a'<llo=~SW5\KY<|`Mؓs`C0k^XX`b=d Ys'gVlݟ/pvgAofvB. Q\44} ڭUóN^ڒx&Sm ]J_'m{-P)>|C}&/Z&nz_T !O>S>AFqٿԿZ{ZgFDm@d>x"иl6AK=2s!?_w8ZxP9Tύ>V3zڽ#ϺzO Ȗx#35whxb̓L!_XF{eS})/rh'3{iXgKU$f||<7cW$s->L)Oy)pS|b-CnkuOxnt'}`=?Hx%Mw pWxU'aSSگLx'cETvކ.'r2<gp1]듮jzH ;Hg2 :~<'l?D=O:ޮzA1O]Wic5-Ϻ@IK%g|z쁍4]O.-\aՖ jY#o H8ߐeecK$I'?!d=Ix:xz鰕KJ[~[aGDӐ[Sf?{}๶zV-OP u!<yF.zD<rϘ3;t+ϼy/sӝJY`yz?Wӄ><{=<=YYk k$-ן:>Axڟ]?'OKz~~+p5ϭxz?ϸ8 aGSAD'YG<n*ˑ=Y*̙xZbejWS}vkP36]OSu. i#~ OWPa>K蓂4DM.u 'md&BUgLJ81r);vw2"\[\wG jد|Zc^V O/l7W=Oc{>+s%O;lybO< xbӋ>1KʡK)ܜ]4VWNxgy\sϤOXn<@vj?뭻 <x,ak݋<%=i1@koXbj-ㆆ'CoAZ@N5G&zig|rFNKO~rIdz [q,VEZ0(e#=6 )Zp+-V-y:剖'Jt}T5̇i,'O0ndJ_ZS=<'y?BﶬO I\ sC({f 's݂V˿Ӻ阣ig拢OW;)Y넧 yNs }Zh6Z^SM0װn81Ҧ0ӧ }=/[yl&Ohv“W`ahg'WAe,FAIy F h=9]y&J]!öys&09r6x58"Z^9Oc<;i O[<7z`է%3^|c)'&w<LW(Ϩφ'`̈́M3G{vn^xH^I`'?^剆If=(ܲ[`r7G]rCLm@6X g)D}W gL^Y'=w1i Se9Ghb*䡴cݭVࠅ ?{2^rcMxf=< z5CzhAH}S!ϩ3*ϴ}HE-6ANq?3x+'`j0$AQ)9@㙂'+=X ,x7h#|\eX&Zj ,"Ax%E<}Ɠ|YybSe%>"eLUP_ Ӈ<|Ag y8<<_>֧x&=jOn~\5I'gt6+O\_1u|= =O KM' 㐧eyt@*"i5yB6Xϰsk\QI.}gVPL̚"R•ǻĥ1Ů+Oih4Oy}h7sgzp#N z`꡻T-OМiTz>O= zu#=3z'.: [۫ҿ4t5OmB:j6mOޤ4.kDNUh3N $wK]s۶xSL\5a/@xֹ< ϩK|}ݿ$,~i4 x<>ԦFLbf=a'w<;=0@7xא퓺<7<Q5}!]`Dependencies $(CXX) -MM $(CXXFLAGS) $(CXXSRCS) | sed -e '1,$$s/ \/usr\/include\/[^ ]*//g' -e '1,$$s/ \/usr\/local\/include\/[^ ]*//g' >>Dependencies # # htmldoc # htmldoc$(EXEEXT): $(HTMLDOCOBJS) $(COMMONOBJS) ../Makedefs echo Linking $@... $(CXX) $(LDFLAGS) -o htmldoc$(EXEEXT) $(HTMLDOCOBJS) $(COMMONOBJS) $(LIBS) if test `uname` = Darwin; then \ $(MAKE) -$(MAKEFLAGS) htmldoc.app || exit 1; \ fi htmldoc.app: htmldoc echo Creating application bundle... $(RM) -r htmldoc.app $(MKDIR) htmldoc.app $(MKDIR) htmldoc.app/Contents $(CP) ../desktop/htmldoc.plist htmldoc.app/Contents/Info.plist $(MKDIR) htmldoc.app/Contents/MacOS $(CP) htmldoc htmldoc.app/Contents/MacOS $(MKDIR) htmldoc.app/Contents/Resources $(CP) ../desktop/htmldoc.icns htmldoc.app/Contents/Resources $(CP) ../doc/help.html htmldoc.app/Contents/Resources $(MKDIR) htmldoc.app/Contents/Resources/data $(CP) ../data/cp-* htmldoc.app/Contents/Resources/data $(CP) ../data/iso-* htmldoc.app/Contents/Resources/data $(CP) ../data/koi8-r htmldoc.app/Contents/Resources/data $(CP) ../data/prolog.ps htmldoc.app/Contents/Resources/data $(CP) ../data/psglyphs htmldoc.app/Contents/Resources/data $(MKDIR) htmldoc.app/Contents/Resources/fonts $(CP) ../fonts/*.afm htmldoc.app/Contents/Resources/fonts $(CP) ../fonts/*.pfa htmldoc.app/Contents/Resources/fonts # # testhtml # testhtml$(EXEEXT): $(TESTOBJS) $(COMMONOBJS) echo Linking $@... $(CXX) $(LDFLAGS) -o testhtml$(EXEEXT) $(TESTOBJS) $(COMMONOBJS) $(LIBS) # # Dependencies... # $(OBJS): ../Makedefs tls.o: tls-darwin.c tls-gnutls.c tls-sspi.c include Dependencies htmldoc-1.9.20/htmldoc/debug.h000066400000000000000000000011161472561501400161320ustar00rootroot00000000000000/* * Debugging macros for HTMLDOC, a HTML document processing program. * * Copyright 2011 by Michael R Sweet. * Copyright 1997-2010 by Easy Software Products. All rights reserved. * * This program is free software. Distribution and use rights are outlined in * the file "COPYING". */ #ifndef _DEBUG_H_ # define _DEBUG_H_ /* * Include necessary headers. */ # include # ifdef DEBUG # define DEBUG_printf(x) printf x # define DEBUG_puts(x) puts(x) # else # define DEBUG_printf(x) # define DEBUG_puts(x) # endif /* DEBUG */ #endif /* !_DEBUG_H_ */ htmldoc-1.9.20/htmldoc/epub.cxx000066400000000000000000001203671472561501400163640ustar00rootroot00000000000000/* * EPUB exporting functions for HTMLDOC, a HTML document processing program. * * Copyright © 2017-2021 by Michael R Sweet. * * This program is free software. Distribution and use rights are outlined in * the file "COPYING". */ /* * Include necessary headers. */ #include "htmldoc.h" #include "markdown.h" #include "zipc.h" #include #include #include /* * Named link structure... */ typedef struct { uchar *filename; /* File for link */ uchar name[124]; /* Reference name */ } link_t; /* * Local globals... */ static size_t num_links = 0, alloc_links = 0; static link_t *links; static size_t num_images = 0, alloc_images = 0; static char **images = NULL; /* * Local functions... */ extern "C" { typedef int (*compare_func_t)(const void *, const void *); } static int write_header(zipc_file_t *out, uchar *title, uchar *author, uchar *copyright, uchar *docnumber, tree_t *t); static int write_title(zipc_file_t *out, tree_t *title_tree, uchar *title, uchar *author, uchar *copyright, uchar *docnumber); static int write_all(zipc_file_t *out, tree_t *t); static int write_node(zipc_file_t *out, tree_t *t); static int write_nodeclose(zipc_file_t *out, tree_t *t); static int write_toc(zipc_file_t *out, tree_t *t); static char *get_iso_date(time_t t); static uchar *get_title(tree_t *doc); static void add_link(uchar *name, uchar *filename); static link_t *find_link(uchar *name); static int compare_links(link_t *n1, link_t *n2); static int compare_images(char **a, char **b); static int copy_image(zipc_t *zipc, const char *filename); static int copy_images(zipc_t *zipc, tree_t *t); static void scan_links(tree_t *t, uchar *filename); static void update_links(tree_t *t, uchar *filename); static tree_t *walk_next(tree_t *t); static int write_xhtml(zipc_file_t *out, uchar *s); static int write_xhtmlf(zipc_file_t *out, const char *format, ...); /* * 'epub_export()' - Export to EPUB... */ int /* O - 0 = success, -1 = failure */ epub_export(tree_t *document, /* I - Document to export */ tree_t *toc) /* I - Table of contents for document */ { uchar *title, /* Title text */ *author, /* Author name */ *copyright, /* Copyright text */ *docnumber, /* Document number */ *language, /* Language */ *subject; /* Subject/category */ zipc_t *epub; /* EPUB output file */ zipc_file_t *epubf; /* File in container */ struct stat epubinfo; /* EPUB file information */ const char *title_ext; /* Extension of title image */ tree_t *title_tree = NULL; /* Title file document tree */ const char *cover_image = NULL; /* Do we have a cover image? */ int status = 0; /* Return status */ static const char *mimetype = /* mimetype file as a string */ "application/epub+zip"; static const char *container_xml = /* container.xml file as a string */ "\n" "\n" " \n" " \n" " \n" "\n"; /* * Create the EPUB file... */ if ((epub = zipcOpen(OutputPath, "w")) == NULL) { progress_error(HD_ERROR_WRITE_ERROR, "Unable to create \"%s\": %s", OutputPath, strerror(errno)); return (-1); } /* * Add the mimetype file... */ status |= zipcCreateFileWithString(epub, "mimetype", mimetype); /* * The META-INF/ directory... */ status |= zipcCreateDirectory(epub, "META-INF/"); /* * The META-INF/container.xml file... */ if ((epubf = zipcCreateFile(epub, "META-INF/container.xml", 1)) != NULL) { status |= zipcFilePuts(epubf, container_xml); status |= zipcFileFinish(epubf); } else status = -1; /* * The OEBPS/ directory... */ status |= zipcCreateDirectory(epub, "OEBPS/"); /* * Copy logo and title images... */ if (LogoImage[0]) status |= copy_image(epub, file_find(Path, LogoImage)); for (int hfi = 0; hfi < MAX_HF_IMAGES; hfi ++) { if (HFImage[hfi][0]) status |= copy_image(epub, file_find(Path, HFImage[hfi])); } title_ext = file_extension(TitleImage); if (TitleImage[0] && TitlePage) { #ifdef WIN32 if (!stricmp(title_ext, "bmp") || !stricmp(title_ext, "gif") || !stricmp(title_ext, "jpg") || !stricmp(title_ext, "png")) #else if (!strcmp(title_ext, "bmp") || !strcmp(title_ext, "gif") || !strcmp(title_ext, "jpg") || !strcmp(title_ext, "png")) #endif // WIN32 { status |= copy_image(epub, file_find(Path, TitleImage)); cover_image = file_basename(TitleImage); } else { FILE *fp; /* Title file */ const char *title_file; /* Location of title file */ // Find the title page file... if ((title_file = file_find(Path, TitleImage)) == NULL) { progress_error(HD_ERROR_FILE_NOT_FOUND, "Unable to find title file \"%s\".", TitleImage); return (-1); } // Read a HTML title page... if ((fp = fopen(title_file, "rb")) == NULL) { progress_error(HD_ERROR_FILE_NOT_FOUND, "Unable to open title file \"%s\" - %s!", TitleImage, strerror(errno)); return (-1); } #ifdef _WIN32 if (!stricmp(title_ext, "md")) #else if (!strcmp(title_ext, "md")) #endif // _WIN32 title_tree = mdReadFile(NULL, fp, file_directory(TitleImage)); else title_tree = htmlReadFile(NULL, fp, file_directory(TitleImage)); htmlFixLinks(title_tree, title_tree, (uchar *)file_directory(TitleImage)); fclose(fp); status |= copy_images(epub, title_tree); } } status |= copy_images(epub, document); /* * Get document strings... */ if ((title = get_title(title_tree)) == NULL) title = get_title(document); if ((author = htmlGetMeta(title_tree, (uchar *)"author")) == NULL) author = htmlGetMeta(document, (uchar *)"author"); if ((copyright = htmlGetMeta(title_tree, (uchar *)"copyright")) == NULL) copyright = htmlGetMeta(document, (uchar *)"copyright"); if ((docnumber = htmlGetMeta(title_tree, (uchar *)"docnumber")) == NULL) docnumber = htmlGetMeta(document, (uchar *)"docnumber"); if (!docnumber) { if ((docnumber = htmlGetMeta(title_tree, (uchar *)"version")) == NULL) docnumber = htmlGetMeta(document, (uchar *)"version"); } if ((language = htmlGetMeta(title_tree, (uchar *)"lang")) == NULL) language = htmlGetMeta(document, (uchar *)"lang"); if (!language) language = (uchar *)"en-US"; if ((subject = htmlGetMeta(title_tree, (uchar *)"keywords")) == NULL) subject = htmlGetMeta(document, (uchar *)"keywords"); if (!subject) subject = (uchar *)"Unknown"; /* * Scan for all links in the document, and then update them... */ num_links = 0; alloc_links = 0; links = NULL; scan_links(document, NULL); update_links(document, NULL); update_links(toc, NULL); /* * Write the document content... */ if (!status && (epubf = zipcCreateFile(epub, "OEBPS/body.xhtml", 1)) != NULL) { status |= write_header(epubf, title, author, copyright, docnumber, NULL); if (TitlePage) { progress_show("Copying title page to EPUB container..."); status |= write_title(epubf, title_tree, title, author, copyright, docnumber); } while (document != NULL) { progress_show("Copying \"%s\" to EPUB container...", (char *)htmlGetVariable(document, (uchar *)"_HD_FILENAME")); status |= write_all(epubf, document->child); document = document->next; } status |= zipcFilePuts(epubf, "\n\n"); status |= zipcFileFinish(epubf); } else status = -1; /* * Write the package manifest... */ if (!status && (epubf = zipcCreateFile(epub, "OEBPS/package.opf", 1)) != NULL) { const char *uid = docnumber ? (char *)docnumber : file_basename(OutputPath); status |= write_xhtmlf(epubf, "\n" "\n" " \n" " %s\n" " %s\n" " %s\n" " %s\n" " %s\n" " %s\n" " htmldoc\n" " %s\n", uid, title, author, get_iso_date(time(NULL)), language, subject, copyright, uid); if (cover_image) status |= write_xhtmlf(epubf, " \n", cover_image); status |= zipcFilePuts(epubf, " \n" " \n" " \n" " \n"); for (size_t i = 0; !status && i < num_images; i ++) { const char *image_mimetype, *image_ext = file_extension(images[i]); if (!strcmp(image_ext, "bmp")) image_mimetype = "image/bmp"; else if (!strcmp(image_ext, "gif")) image_mimetype = "image/gif"; else if (!strcmp(image_ext, "jpg")) image_mimetype = "image/jpeg"; else image_mimetype = "image/png"; status |= write_xhtmlf(epubf, " \n", images[i], images[i], image_mimetype); } status |= zipcFilePuts(epubf, " \n" " \n" " \n" " \n" "\n"); status |= zipcFileFinish(epubf); } /* * Finally the table-of-contents file... */ if ((epubf = zipcCreateFile(epub, "OEBPS/nav.xhtml", 1)) != NULL) { progress_show("Copying table of contents to EPUB container..."); status |= write_xhtmlf(epubf, "\n" "\n" "\n" " \n" " %s\n" " \n" " \n" " \n" " \n" " \n" "\n"); status |= zipcFileFinish(epubf); } else status = -1; status |= zipcClose(epub); if (!stat(OutputPath, &epubinfo)) progress_error(HD_ERROR_NONE, "BYTES: %ld", (long)epubinfo.st_size); if (title != NULL) free(title); if (title_tree) htmlDeleteTree(title_tree); if (alloc_links) { free(links); num_links = 0; alloc_links = 0; links = NULL; } return (status); } /* * 'write_header()' - Output the standard "header" for a HTML file. */ static int /* O - 0 on success, -1 on failure */ write_header( zipc_file_t *out, /* I - Output file */ uchar *title, /* I - Title for document */ uchar *author, /* I - Author for document */ uchar *copyright, /* I - Copyright for document */ uchar *docnumber, /* I - ID number for document */ tree_t *t) /* I - Current document file */ { int status = 0; /* Write status */ static const char *families[] = /* Typeface names */ { "monospace", "serif", "sans-serif", "monospace", "serif", "sans-serif", "symbol", "dingbats" }; status |= zipcFilePuts(out, "\n" "\n" "\n" " \n"); if (title != NULL) status |= write_xhtmlf(out, " %s\n", title); if (author != NULL) status |= write_xhtmlf(out, " \n", author); if (copyright != NULL) status |= write_xhtmlf(out, " \n", copyright); if (docnumber != NULL) status |= write_xhtmlf(out, " \n", docnumber); status |= zipcFilePuts(out, " \n" " \n" " \n"); return (status); } /* * 'write_title()' - Write a title page... */ static int /* O - 0 on success, -1 on failure */ write_title(zipc_file_t *out, /* I - Output file */ tree_t *title_tree, /* I - Title tree, if any */ uchar *title, /* I - Title for document */ uchar *author, /* I - Author for document */ uchar *copyright, /* I - Copyright for document */ uchar *docnumber) /* I - ID number for document */ { int status = 0; /* Write status */ if (title_tree) { // Write a custom HTML title page... status |= write_all(out, title_tree); } else { // Write a "standard" title page with image... status |= zipcFilePuts(out, "
\n"); if (TitleImage[0]) { image_t *img = image_load(TitleImage, !OutputColor); if (img) status |= write_xhtmlf(out, "

\"%s\"

\n", file_basename((char *)TitleImage), img->width, img->height, title ? title : (uchar *)""); } if (title != NULL) status |= write_xhtmlf(out, "

%s

\n", title); const char *prefix = "

"; if (docnumber) { status |= zipcFilePuts(out, prefix); status |= write_xhtml(out, docnumber); prefix = "
\n"; } if (author) { status |= zipcFilePuts(out, prefix); status |= write_xhtml(out, author); prefix = "
\n"; } if (copyright) { status |= zipcFilePuts(out, prefix); status |= write_xhtml(out, copyright); prefix = "
\n"; } if (prefix[0] == '<') status |= zipcFilePuts(out, "

\n"); status |= zipcFilePuts(out, "
\n"); } return (status); } /* * 'write_all()' - Write all markup text for the given tree. */ static int /* O - 0 on success, -1 on error */ write_all(zipc_file_t *out, /* I - Output file */ tree_t *t) /* I - Document tree */ { while (t != NULL) { if (write_node(out, t)) return (-1); if (t->markup != MARKUP_HEAD && t->markup != MARKUP_TITLE) { if (write_all(out, t->child)) return (-1); } if (write_nodeclose(out, t)) return (-1); t = t->next; } return (0); } /* * 'write_node()' - Write a single tree node. */ static int /* O - 0 on success, -1 on error */ write_node(zipc_file_t *out, /* I - Output file */ tree_t *t) /* I - Document tree node */ { int status = 0; /* Write status */ int i; /* Looping var */ switch (t->markup) { case MARKUP_NONE : if (t->data == NULL) break; if (!t->prev && t->parent && t->parent->markup == MARKUP_PRE && !strcmp((char *)t->data, "\n")) break; /* Skip initial blank line */ status |= write_xhtml(out, t->data); break; case MARKUP_CENTER : /* Not in XHTML, use
instead */ if (t->child) status |= zipcFilePuts(out, "
"); break; case MARKUP_TABLE : /* No HTML 3.x table attributes in XHTML... */ if (t->child) status |= zipcFilePuts(out, "\n"); break; case MARKUP_TT : /* Not in XHTML, use instead... */ if (t->child) status |= zipcFilePuts(out, ""); break; case MARKUP_COMMENT : case MARKUP_UNKNOWN : case MARKUP_AREA : case MARKUP_BODY : case MARKUP_DOCTYPE : case MARKUP_ERROR : case MARKUP_FILE : case MARKUP_HEAD : case MARKUP_HTML : case MARKUP_MAP : case MARKUP_META : case MARKUP_TITLE : break; case MARKUP_BR : case MARKUP_DD : case MARKUP_DL : case MARKUP_DT : case MARKUP_H1 : case MARKUP_H2 : case MARKUP_H3 : case MARKUP_H4 : case MARKUP_H5 : case MARKUP_H6 : case MARKUP_H7 : case MARKUP_H8 : case MARKUP_H9 : case MARKUP_H10 : case MARKUP_H11 : case MARKUP_H12 : case MARKUP_H13 : case MARKUP_H14 : case MARKUP_H15 : case MARKUP_HR : case MARKUP_LI : case MARKUP_OL : case MARKUP_P : case MARKUP_UL : status |= zipcFilePuts(out, "\n"); default : if (t->markup != MARKUP_EMBED) { status |= zipcFilePrintf(out, "<%s", _htmlMarkups[t->markup]); for (i = 0; i < t->nvars; i ++) { if (strcasecmp((char *)t->vars[i].name, "BREAK") == 0 && t->markup == MARKUP_HR) continue; if (strcasecmp((char *)t->vars[i].name, "REALSRC") == 0 && t->markup == MARKUP_IMG) continue; if (strncasecmp((char *)t->vars[i].name, "_HD_", 4) == 0) continue; if (t->vars[i].value == NULL) status |= write_xhtmlf(out, " %ls=\"%ls\"", t->vars[i].name, t->vars[i].name); else if (t->markup == MARKUP_A && !strcasecmp((char *)t->vars[i].name, "NAME")) status |= write_xhtmlf(out, " id=\"%s\"", t->vars[i].value); else if (!strcasecmp((char *)t->vars[i].name, "ALIGN")) status |= write_xhtmlf(out, " style=\"text-align: %ls;\"", t->vars[i].value); else status |= write_xhtmlf(out, " %ls=\"%s\"", t->vars[i].name, t->vars[i].value); } if (t->child) status |= zipcFilePuts(out, ">"); else status |= zipcFilePuts(out, " />"); } break; } return (status); } /* * 'write_nodeclose()' - Close a single tree node. */ static int /* O - 0 on success, -1 on error */ write_nodeclose(zipc_file_t *out, /* I - Output file */ tree_t *t) /* I - Document tree node */ { if (t->markup != MARKUP_HEAD && t->markup != MARKUP_TITLE) { switch (t->markup) { case MARKUP_BODY : case MARKUP_ERROR : case MARKUP_FILE : case MARKUP_HEAD : case MARKUP_HTML : case MARKUP_NONE : case MARKUP_TITLE : case MARKUP_APPLET : case MARKUP_AREA : case MARKUP_BR : case MARKUP_COMMENT : case MARKUP_DOCTYPE : case MARKUP_EMBED : case MARKUP_HR : case MARKUP_IMG : case MARKUP_INPUT : case MARKUP_ISINDEX : case MARKUP_LINK : case MARKUP_META : case MARKUP_NOBR : case MARKUP_SPACER : case MARKUP_WBR : case MARKUP_UNKNOWN : break; case MARKUP_DD : case MARKUP_DL : case MARKUP_DT : case MARKUP_H1 : case MARKUP_H2 : case MARKUP_H3 : case MARKUP_H4 : case MARKUP_H5 : case MARKUP_H6 : case MARKUP_H7 : case MARKUP_H8 : case MARKUP_H9 : case MARKUP_H10 : case MARKUP_H11 : case MARKUP_H12 : case MARKUP_H13 : case MARKUP_H14 : case MARKUP_H15 : case MARKUP_LI : case MARKUP_OL : case MARKUP_P : case MARKUP_PRE : case MARKUP_TR : case MARKUP_UL : if (!t->child) break; if (zipcFilePrintf(out, "\n", _htmlMarkups[t->markup])) return (-1); break; case MARKUP_CENTER : /* Not in XHTML, use
instead */ if (t->child) { if (zipcFilePuts(out, "
\n")) return (-1); } break; case MARKUP_TABLE : /* No HTML 3.x table attributes in XHTML... */ if (t->child) { if (zipcFilePuts(out, "
\n")) return (-1); } break; case MARKUP_TT : /* Not in XHTML, use instead... */ if (t->child) { if (zipcFilePuts(out, "")) return (-1); } break; default : if (!t->child) break; if (zipcFilePrintf(out, "", _htmlMarkups[t->markup])) return (-1); break; } } return (0); } /* * 'write_toc()' - Write all markup text for the given table-of-contents. */ static int /* O - 0 on success, -1 on error */ write_toc(zipc_file_t *out, /* I - Output file */ tree_t *t) /* I - Document tree */ { int status = 0; /* Write status */ uchar *href; /* Link to heading */ while (t) { if (htmlGetVariable(t, (uchar *)"_HD_OMIT_TOC") == NULL) { switch (t->markup) { case MARKUP_NONE : status |= write_xhtml(out, t->data); break; case MARKUP_A : if ((href = htmlGetVariable(t, (uchar *)"HREF")) != NULL) { status |= write_xhtmlf(out, "
", href); status |= write_toc(out, t->child); status |= zipcFilePuts(out, ""); } break; case MARKUP_B : status |= zipcFilePuts(out, "
  • "); status |= write_toc(out, t->child); if (!t->next || t->next->markup != MARKUP_UL) status |= zipcFilePuts(out, "
  • \n"); break; case MARKUP_LI : status |= zipcFilePuts(out, "
  • "); status |= write_toc(out, t->child); status |= zipcFilePuts(out, "
  • \n"); break; case MARKUP_UL : status |= zipcFilePuts(out, "
      \n"); status |= write_toc(out, t->child); status |= zipcFilePuts(out, "
    "); if (t->prev && t->prev->markup == MARKUP_B) status |= zipcFilePuts(out, "\n"); break; case MARKUP_H1 : case MARKUP_BR : break; default : if (t->child) status |= write_toc(out, t->child); break; } } t = t->next; } return (status); } /* * 'get_iso_date()' - Get an ISO-formatted date/time string. */ static char * /* O - ISO date/time string */ get_iso_date(time_t t) /* I - Time value */ { struct tm date; /* UTC date/time */ static char buffer[100]; /* String buffer */ gmtime_r(&t, &date); snprintf(buffer, sizeof(buffer), "%04d-%02d-%02dT%02d:%02d:%02dZ", date.tm_year + 1900, date.tm_mon + 1, date.tm_mday, date.tm_hour, date.tm_min, date.tm_sec); return (buffer); } /* * 'get_title()' - Get the title string for the given document... */ static uchar * /* O - Title string */ get_title(tree_t *doc) /* I - Document tree */ { uchar *temp; /* Temporary pointer to title */ while (doc != NULL) { if (doc->markup == MARKUP_TITLE) return (htmlGetText(doc->child)); else if (doc->child != NULL) if ((temp = get_title(doc->child)) != NULL) return (temp); doc = doc->next; } return (NULL); } /* * 'add_link()' - Add a named link... */ static void add_link(uchar *name, /* I - Name of link */ uchar *filename) /* I - File for link */ { link_t *temp; /* New name */ if ((temp = find_link(name)) != NULL) temp->filename = filename; else { // See if we need to allocate memory for links... if (num_links >= alloc_links) { // Allocate more links... alloc_links += ALLOC_LINKS; if (num_links == 0) temp = (link_t *)malloc(sizeof(link_t) * alloc_links); else temp = (link_t *)realloc(links, sizeof(link_t) * alloc_links); if (temp == NULL) { progress_error(HD_ERROR_OUT_OF_MEMORY, "Unable to allocate memory for %d links - %s", (int)alloc_links, strerror(errno)); alloc_links -= ALLOC_LINKS; return; } links = temp; } // Add a new link... temp = links + num_links; num_links ++; strlcpy((char *)temp->name, (char *)name, sizeof(temp->name)); temp->filename = filename; if (num_links > 1) qsort(links, num_links, sizeof(link_t), (compare_func_t)compare_links); } } /* * 'find_link()' - Find a named link... */ static link_t * find_link(uchar *name) /* I - Name to find */ { uchar *target; /* Pointer to target name portion */ link_t key, /* Search key */ *match; /* Matching name entry */ if (name == NULL || num_links == 0) return (NULL); if ((target = (uchar *)file_target((char *)name)) == NULL) return (NULL); strlcpy((char *)key.name, (char *)target, sizeof(key.name)); match = (link_t *)bsearch(&key, links, num_links, sizeof(link_t), (compare_func_t)compare_links); return (match); } /* * 'compare_links()' - Compare two named links. */ static int /* O - 0 = equal, -1 or 1 = not equal */ compare_links(link_t *n1, /* I - First name */ link_t *n2) /* I - Second name */ { return (strcasecmp((char *)n1->name, (char *)n2->name)); } /* * 'scan_links()' - Scan a document for link targets, and keep track of * the files they are in... */ static void scan_links(tree_t *t, /* I - Document tree */ uchar *filename) /* I - Filename */ { uchar *name; /* Name of link */ while (t != NULL) { if (t->markup == MARKUP_FILE) scan_links(t->child, (uchar *)file_basename((char *)htmlGetVariable(t, (uchar *)"_HD_FILENAME"))); else if (t->markup == MARKUP_A && (name = htmlGetVariable(t, (uchar *)"NAME")) != NULL) { add_link(name, filename); scan_links(t->child, filename); } else if (t->child != NULL) scan_links(t->child, filename); t = t->next; } } /* * 'update_links()' - Update links as needed. */ static void update_links(tree_t *t, /* I - Document tree */ uchar *filename) /* I - Current filename */ { link_t *link; /* Link */ uchar *href; /* Reference name */ uchar newhref[1024]; /* New reference name */ filename = (uchar *)file_basename((char *)filename); if (OutputFiles) { /* * Need to preserve/add filenames. */ while (t != NULL) { if (t->markup == MARKUP_A && (href = htmlGetVariable(t, (uchar *)"HREF")) != NULL) { /* * Update this link as needed... */ if (href[0] == '#' && (link = find_link(href)) != NULL) { #if defined(WIN32) || defined(__EMX__) if (filename == NULL || strcasecmp((char *)filename, (char *)link->filename) != 0) #else if (filename == NULL || strcmp((char *)filename, (char *)link->filename) != 0) #endif /* WIN32 || __EMX__ */ { snprintf((char *)newhref, sizeof(newhref), "%s%s", link->filename, href); htmlSetVariable(t, (uchar *)"HREF", newhref); } } } if (t->child != NULL) { if (t->markup == MARKUP_FILE) update_links(t->child, htmlGetVariable(t, (uchar *)"_HD_FILENAME")); else update_links(t->child, filename); } t = t->next; } } else { /* * Need to strip filenames. */ while (t != NULL) { if (t->markup == MARKUP_A && (href = htmlGetVariable(t, (uchar *)"HREF")) != NULL) { /* * Update this link as needed... */ if (href[0] != '#' && file_method((char *)href) == NULL && (link = find_link(href)) != NULL) { snprintf((char *)newhref, sizeof(newhref), "#%s", link->name); htmlSetVariable(t, (uchar *)"HREF", newhref); } } if (t->child != NULL) update_links(t->child, filename); t = t->next; } } } /* * 'compare_images()' - Compare two image filenames... */ static int compare_images(char **a, char **b) { return (strcmp(*a, *b)); } /* * 'copy_image()' - Copy an image to the ZIP container. */ static int /* O - 0 on success, -1 on failure */ copy_image(zipc_t *zipc, /* I - ZIP container */ const char *filename) /* I - File to copy */ { const char *base = file_basename(filename); /* Base filename */ char epubname[1024]; /* Name in ZIP container */ /* * Don't copy more than once for the same file... */ if (num_images > 0 && bsearch(&base, images, num_images, sizeof(char *), (compare_func_t)compare_images)) return (0); progress_show("Copying \"%s\" to EPUB container...", base); /* * Copy the file... */ snprintf(epubname, sizeof(epubname), "OEBPS/%s", base); if (zipcCopyFile(zipc, epubname, filename, 0, 0)) { progress_error(HD_ERROR_WRITE_ERROR, "Unable to copy \"%s\": %s", base, zipcError(zipc)); return (-1); } /* * Add it to the array of images... */ if (num_images >= alloc_images) { char **temp; alloc_images += 128; if (alloc_images == 128) temp = (char **)malloc(alloc_images * sizeof(char *)); else temp = (char **)realloc(images, alloc_images * sizeof(char *)); if (!temp) return (-1); images = temp; } images[num_images] = strdup(base); num_images ++; if (num_images > 1) qsort(images, num_images, sizeof(char *), (compare_func_t)compare_images); return (0); } /* * 'copy_images()' - Scan the tree for images and copy as needed... */ static int /* O - 0 on success, -1 on failure */ copy_images(zipc_t *zipc, /* I - ZIP container */ tree_t *t) /* I - Document tree */ { uchar *src, /* Image source */ *realsrc; /* Real image source */ while (t) { /* * If this is an image node, copy the image and update the SRC... */ if (t->markup == MARKUP_IMG && (src = htmlGetVariable(t, (uchar *)"SRC")) != NULL && (realsrc = htmlGetVariable(t, (uchar *)"REALSRC")) != NULL && file_method((char *)src) == NULL) { if (copy_image(zipc, (char *)realsrc)) return (-1); htmlSetVariable(t, (uchar *)"SRC", (uchar *)file_basename((char *)realsrc)); } /* * Move to the next node in the document tree... */ t = walk_next(t); } return (0); } /* * 'walk_next()' - Return the next node in the tree. */ static tree_t * /* O - Next node */ walk_next(tree_t *t) /* I - Current node */ { if (t->child) return (t->child); else if (t->next) return (t->next); else if (t->parent) { do { t = t->parent; } while (t && !t->next); if (t) return (t->next); else return (NULL); } else return (NULL); } /* * 'write_xhtml()' - Write an XHTML-safe string. */ static int /* O - 0 on success, -1 on error */ write_xhtml(zipc_file_t *out, /* I - Output file */ uchar *s) /* I - String to write */ { int status = 0; /* Return status */ uchar *start, /* First character in sequence */ *ptr; /* Current character */ for (ptr = s, start = s; *ptr; ptr ++) { if (*ptr > 0x7f || strchr("<>&\"", *ptr)) { if (ptr > start) status |= zipcFileWrite(out, start, (size_t)(ptr - start)); status |= zipcFilePuts(out, (char *)xhtml_entity(*ptr)); start = ptr + 1; } } if (ptr > start) status |= zipcFileWrite(out, start, (size_t)(ptr - start)); return (status); } /* * 'write_xhtmlf()' - Write an XHTML-safe printf string. */ static int /* O - 0 on success, -1 on error */ write_xhtmlf(zipc_file_t *out, /* I - Output file */ const char *format, /* I - Printf-style string to write */ ...) /* I - Additional args as needed */ { int status = 0; /* Return status */ va_list ap; /* Additional arguments */ uchar *start, /* First character in sequence */ *ptr; /* Current character */ const char *s; /* String pointer */ int d; /* Number */ char temp[32]; /* Temporary string buffer */ va_start(ap, format); for (ptr = (uchar *)format, start = (uchar *)format; *ptr; ptr ++) { if (*ptr == '%') { /* * Format character - write any pending text fragment... */ if (ptr > start) { /* * Include the % if the format char is %%... */ if (ptr[1] == '%') status |= zipcFileWrite(out, start, (size_t)(ptr - start + 1)); else status |= zipcFileWrite(out, start, (size_t)(ptr - start)); } /* * Start over and process the character... */ ptr ++; start = ptr + 1; switch (*ptr) { case '%' : /* Escaped % */ break; case 'd' : /* Substitute a single integer */ d = va_arg(ap, int); snprintf(temp, sizeof(temp), "%d", d); status |= zipcFilePuts(out, temp); break; case 'l' : /* Substitude (and lower-case) a single string */ if (ptr[1] != 's') { start = ptr - 1; break; } ptr ++; start = ptr + 1; s = va_arg(ap, const char *); if (!s) s = "(null)"; while (*s) { status |= zipcFilePuts(out, (char *)xhtml_entity((uchar)tolower(*s & 255))); s ++; } break; case 's' : /* Substitute a single string */ s = va_arg(ap, const char *); if (!s) s = "(null)"; status |= write_xhtml(out, (uchar *)s); break; default : /* Something else we don't support... */ start = ptr - 1; break; } } else if (*ptr > 0x7f) { if (ptr > start) status |= zipcFileWrite(out, start, (size_t)(ptr - start)); status |= zipcFilePuts(out, (char *)xhtml_entity(*ptr)); start = ptr + 1; } } if (ptr > start) status |= zipcFileWrite(out, start, (size_t)(ptr - start)); va_end(ap); return (status); } htmldoc-1.9.20/htmldoc/file.c000066400000000000000000000643171472561501400157720ustar00rootroot00000000000000/* * Filename routines for HTMLDOC, a HTML document processing program. * * Copyright © 2011-2024 by Michael R Sweet. * Copyright © 1997-2010 by Easy Software Products. All rights reserved. * * This program is free software. Distribution and use rights are outlined in * the file "COPYING". */ #include "file.h" #include #include "progress.h" #include "debug.h" #if defined(WIN32) # include #else # include #endif /* WIN32 */ #include #include #include #include #include /* * Temporary file definitions... */ #ifdef WIN32 # define getpid GetCurrentProcessId # define TEMPLATE "%s/%08lx.%06d.tmp" # define OPENMODE (_O_CREAT | _O_RDWR | _O_TRUNC | _O_BINARY) # define OPENPERM (_S_IREAD | _S_IWRITE) #else # define TEMPLATE "%s/%06ld.%06d.tmp" # define OPENMODE (O_CREAT | O_RDWR | O_EXCL | O_TRUNC) # define OPENPERM 0600 #endif /* WIN32 */ /* * Cache file structure... */ typedef struct /* Cache for all temporary files */ { char *name; /* Temporary filename */ char *url; /* URL */ } cache_t; /* * Local globals... */ char proxy_scheme[32] = "", /* Proxy scheme */ proxy_host[HTTP_MAX_URI] = ""; /* Proxy hostname */ int proxy_port = 0; /* Proxy port */ http_t *http = NULL; /* Connection to remote server */ size_t web_files = 0, /* Number of temporary files */ web_alloc = 0; /* Number of allocated files */ cache_t *web_cache = NULL; /* Cache array */ int no_local = 0; /* Non-zero to disable local files */ char cookies[1024] = ""; /* HTTP cookies, if any */ char referer_url[HTTP_MAX_VALUE] = ""; /* HTTP referer, if any */ /* * 'file_basename()' - Return the base filename without directory or target. */ const char * /* O - Base filename */ file_basename(const char *s) /* I - Filename or URL */ { const char *basename; /* Pointer to directory separator */ static char buf[1024]; /* Buffer for files with targets */ if (s == NULL) return (NULL); if (strchr(s, '#') != NULL) { char *bufptr; // Pointer into buffer strlcpy(buf, s, sizeof(buf)); s = buf; if ((bufptr = strchr(buf, '#')) != NULL) *bufptr = '\0'; } if ((basename = strrchr(s, '/')) != NULL) return (basename + 1); else if ((basename = strrchr(s, '\\')) != NULL) return (basename + 1); else return (s); } /* * 'file_cleanup()' - Close an open HTTP connection and remove temporary files... */ void file_cleanup(void) { size_t i; /* Looping var */ char filename[1024]; /* Temporary file */ struct stat fileinfo; /* File information */ size_t remotebytes; /* Size of remote data */ const char *tmpdir; /* Temporary directory */ #ifdef WIN32 char tmppath[1024]; /* Temporary directory */ #endif /* WIN32 */ const char *debug; /* HTMLDOC_DEBUG env var */ if (http) { httpClose(http); http = NULL; } #ifdef WIN32 if ((tmpdir = getenv("TEMP")) == NULL) { GetTempPath(sizeof(tmppath), tmppath); tmpdir = tmppath; } #else if ((tmpdir = getenv("TMPDIR")) == NULL) tmpdir = "/var/tmp"; #endif /* WIN32 */ /* * Report on the remote data bytes that were downloaded... */ debug = getenv("HTMLDOC_DEBUG"); if (debug && (strstr(debug, "all") != NULL || strstr(debug, "remotebytes") != NULL)) { for (i = 0, remotebytes = 0; i < web_files; i ++) if (web_cache[i].url) { snprintf(filename, sizeof(filename), TEMPLATE, tmpdir, (long)getpid(), (int)(i + 1)); if (!stat(filename, &fileinfo)) remotebytes += (size_t)fileinfo.st_size; } progress_error(HD_ERROR_NONE, "REMOTEBYTES: %ld", (long)remotebytes); } /* * Check to see if we want to leave the temporary files around for * debugging... */ if (debug && (strstr(debug, "all") != NULL || strstr(debug, "tempfiles") != NULL)) { /* * Yes, leave the files, but show the mapping from filename to URL... */ progress_error(HD_ERROR_NONE, "DEBUG: Temporary File Summary"); progress_error(HD_ERROR_NONE, "DEBUG:"); progress_error(HD_ERROR_NONE, "DEBUG: URL Filename"); progress_error(HD_ERROR_NONE, "DEBUG: ------------------------------- ---------------------"); for (i = 0; i < web_files; i ++) { snprintf(filename, sizeof(filename), TEMPLATE, tmpdir, (long)getpid(), (int)(i + 1)); progress_error(HD_ERROR_NONE, "DEBUG: %-31.31s %s\n", web_cache[i].url ? web_cache[i].url : "none", filename); } progress_error(HD_ERROR_NONE, "DEBUG:"); return; } while (web_files > 0) { snprintf(filename, sizeof(filename), TEMPLATE, tmpdir, (long)getpid(), (int)web_files); if (unlink(filename)) progress_error(HD_ERROR_DELETE_ERROR, "Unable to delete temporary file \"%s\": %s", filename, strerror(errno)); web_files --; if (web_cache[web_files].name) free(web_cache[web_files].name); if (web_cache[web_files].url) free(web_cache[web_files].url); } if (web_alloc) { free(web_cache); web_alloc = 0; web_cache = NULL; } } /* * 'file_cookies()' - Set the HTTP cookies for remote accesses. */ void file_cookies(const char *s) /* I - Cookie string or NULL */ { if (s) strlcpy(cookies, s, sizeof(cookies)); else cookies[0] = '\0'; } /* * 'file_directory()' - Return the directory without filename or target. */ const char * /* O - Directory for file */ file_directory(const char *s) /* I - Filename or URL */ { char *dir; /* Pointer to directory separator */ static char buf[1024]; /* Buffer for files with targets */ if (s == NULL || !strncmp(s, "data:", 5)) return (NULL); if (strncmp(s, "http://", 7) == 0 || strncmp(s, "https://", 8) == 0) { /* * Handle URLs... */ char scheme[HTTP_MAX_URI], username[HTTP_MAX_URI], hostname[HTTP_MAX_URI], resource[HTTP_MAX_URI]; int port; httpSeparateURI(HTTP_URI_CODING_ALL, s, scheme, sizeof(scheme), username, sizeof(username), hostname, sizeof(hostname), &port, resource, sizeof(resource)); if ((dir = strrchr(resource, '/')) != NULL) *dir = '\0'; httpAssembleURI(HTTP_URI_CODING_ALL, buf, sizeof(buf), scheme, username, hostname, port, resource); } else { /* * Normal stuff... */ strlcpy(buf, s, sizeof(buf)); if ((dir = strrchr(buf, '/')) != NULL) *dir = '\0'; else if ((dir = strrchr(buf, '\\')) != NULL) *dir = '\0'; else return ("."); if (strncmp(buf, "file:", 5) == 0) hd_strcpy(buf, buf + 5); if (!buf[0]) /* Safe because buf is more than 2 chars long */ strlcpy(buf, "/", sizeof(buf)); } return (buf); } /* * 'file_extension()' - Return the extension of a file without the target. */ const char * /* O - File extension */ file_extension(const char *s) /* I - Filename or URL */ { const char *extension; /* Pointer to directory separator */ char *bufptr; /* Pointer into buffer */ static char buf[1024]; /* Buffer for files with targets */ if (s == NULL) return (NULL); else if (!strncmp(s, "data:image/bmp;", 15)) return ("bmp"); else if (!strncmp(s, "data:image/gif;", 15)) return ("gif"); else if (!strncmp(s, "data:image/jpeg;", 16)) return ("jpg"); else if (!strncmp(s, "data:image/png;", 15)) return ("png"); else if ((extension = strrchr(s, '/')) != NULL) extension ++; else if ((extension = strrchr(s, '\\')) != NULL) extension ++; else extension = s; if ((extension = strrchr(extension, '.')) == NULL) return (""); else extension ++; if (strchr(extension, '#') == NULL) return (extension); strlcpy(buf, extension, sizeof(buf)); if ((bufptr = strchr(buf, '#')) != NULL) *bufptr = '\0'; return (buf); } /* * 'file_find_check()' - Check to see if the specified file or URL exists... */ static const char * /* O - Pathname or NULL */ file_find_check(const char *filename) /* I - File or URL */ { int i; /* Looping var */ int retry; /* Current retry */ char scheme[HTTP_MAX_URI], /* Method/scheme */ username[HTTP_MAX_URI], /* Username:password */ hostname[HTTP_MAX_URI], /* Hostname */ resource[HTTP_MAX_URI]; /* Resource */ int port; /* Port number */ const char *connscheme; /* Scheme for connection */ const char *connhost; /* Host to connect to */ int connport; /* Port to connect to */ char connpath[HTTP_MAX_URI], /* Path for GET */ connauth[HTTP_MAX_VALUE];/* Auth string */ http_status_t status; /* Status of request... */ FILE *fp; /* Web file */ ssize_t bytes, /* Bytes read */ count; /* Number of bytes so far */ off_t total; /* Total bytes in file */ char tempname[HTTP_MAX_URI]; /* Temporary filename */ DEBUG_printf(("file_find_check(filename=\"%s\")\n", filename)); if (strncmp(filename, "http:", 5) == 0 || strncmp(filename, "//", 2) == 0) strlcpy(scheme, "http", sizeof(scheme)); else if (strncmp(filename, "https:", 6) == 0) strlcpy(scheme, "https", sizeof(scheme)); else if (strncmp(filename, "data:", 5) == 0) strlcpy(scheme, "data", sizeof(scheme)); else strlcpy(scheme, "file", sizeof(scheme)); if (strcmp(scheme, "file") == 0) { /* * Return immediately if we aren't allowing access to local files... */ if (no_local) return (NULL); /* * If the filename exists, return the filename... */ if (!access(filename, 0)) { DEBUG_printf(("file_find_check: Returning \"%s\"!\n", filename)); return (filename); } } else if (!strcmp(scheme, "data")) { /* * Data URI; look it up in the web cache, then save to a temporary file... */ const char *data; /* Pointer to data */ int len; /* Number of bytes */ char buffer[8192]; /* Data buffer */ for (i = 0; i < (int)web_files; i ++) { if (web_cache[i].url && strcmp(web_cache[i].url, filename) == 0) { DEBUG_printf(("file_find_check: Returning \"%s\" for \"%s\".\n", web_cache[i].name, filename)); return (web_cache[i].name); } } if ((data = strstr(filename, ";base64,")) != NULL) { len = sizeof(buffer); httpDecode64_2(buffer, &len, data + 8); if ((fp = file_temp(tempname, sizeof(tempname))) == NULL) { progress_hide(); progress_error(HD_ERROR_WRITE_ERROR, "Unable to create temporary file \"%s\": %s", tempname, strerror(errno)); return (NULL); } fwrite(buffer, 1, (size_t)len, fp); fclose(fp); progress_hide(); web_cache[web_files - 1].url = strdup(filename); DEBUG_printf(("file_find_check: Returning \"%s\" for \"%s\".\n", tempname, filename)); return (web_cache[web_files - 1].name); } } else { /* * Remote file; look it up in the web cache, and then try getting it * from the remote system... */ for (i = 0; i < (int)web_files; i ++) { if (web_cache[i].url && strcmp(web_cache[i].url, filename) == 0) { DEBUG_printf(("file_find_check: Returning \"%s\" for \"%s\".\n", web_cache[i].name, filename)); return (web_cache[i].name); } } httpSeparateURI(HTTP_URI_CODING_ALL, filename, scheme, sizeof(scheme), username, sizeof(username), hostname, sizeof(hostname), &port, resource, sizeof(resource)); for (status = HTTP_STATUS_ERROR, retry = 0; status != HTTP_STATUS_OK && retry < 5; retry ++) { if (proxy_port) { // Send request to proxy host... connscheme = proxy_scheme; connhost = proxy_host; connport = proxy_port; httpAssembleURI(HTTP_URI_CODING_ALL, connpath, sizeof(connpath), scheme, NULL, hostname, port, resource); } else { // Send request to host directly... connscheme = scheme; connhost = hostname; connport = port; strlcpy(connpath, resource, sizeof(connpath)); } if (connport != httpAddrPort(httpGetAddress(http)) || #ifdef HAVE_SSL (!strcmp(connscheme, "https") && !httpIsEncrypted(http)) || (!strcmp(connscheme, "http") && httpIsEncrypted(http)) || #endif // HAVE_SSL strcasecmp(httpGetHostname(http, tempname, sizeof(tempname)), hostname)) { httpClose(http); http = NULL; } if (http == NULL) { progress_show("Connecting to %s...", connhost); http_encryption_t encryption = !strcmp(connscheme, "http") ? HTTP_ENCRYPTION_IF_REQUESTED : HTTP_ENCRYPTION_ALWAYS; if ((http = httpConnect2(connhost, connport, NULL, AF_UNSPEC, encryption, 1, 30000, NULL)) == NULL) { progress_hide(); progress_error(HD_ERROR_NETWORK_ERROR, "Unable to connect to %s:%d", connhost, connport); return (NULL); } } progress_show("Getting %s...", connpath); httpClearFields(http); httpSetField(http, HTTP_FIELD_HOST, hostname); httpSetField(http, HTTP_FIELD_CONNECTION, "Keep-Alive"); httpSetField(http, HTTP_FIELD_REFERER, referer_url); if (username[0]) { strlcpy(connauth, "Basic ", sizeof(connauth)); httpEncode64_2(connauth + 6, sizeof(connauth) - 6, username, strlen(username)); httpSetField(http, HTTP_FIELD_AUTHORIZATION, connauth); } if (cookies[0]) httpSetCookie(http, cookies); if (!httpGet(http, connpath)) { while ((status = httpUpdate(http)) == HTTP_STATUS_CONTINUE); } else status = HTTP_STATUS_ERROR; if (status >= HTTP_STATUS_MULTIPLE_CHOICES && status < HTTP_STATUS_BAD_REQUEST) { // Redirect status code, grab the new location... const char *newurl = httpGetField(http, HTTP_FIELD_LOCATION); // New URL char newresource[256]; // New resource progress_show("Redirecting to %s...", newurl); httpSeparateURI(HTTP_URI_CODING_ALL, newurl, scheme, sizeof(scheme), username, sizeof(username), hostname, sizeof(hostname), &port, newresource, sizeof(newresource)); // Don't use new resource path if it is empty... if (strchr(newurl + strlen(scheme) + 3, '/')) strlcpy(resource, newresource, sizeof(resource)); // ... then flush any text in the response... httpFlush(http); } } if (status != HTTP_STATUS_OK) { progress_hide(); progress_error((HDerror)status, "%s (%s)", httpStatus(status), filename); httpFlush(http); return (NULL); } if ((fp = file_temp(tempname, sizeof(tempname))) == NULL) { progress_hide(); progress_error(HD_ERROR_WRITE_ERROR, "Unable to create temporary file \"%s\": %s", tempname, strerror(errno)); httpFlush(http); return (NULL); } if ((total = httpGetLength2(http)) == 0) total = 8192; count = 0; while ((bytes = httpRead2(http, resource, sizeof(resource))) > 0) { count += bytes; progress_update((100 * count / total) % 101); fwrite(resource, 1, (size_t)bytes, fp); } progress_hide(); fclose(fp); web_cache[web_files - 1].url = strdup(filename); DEBUG_printf(("file_find_check: Returning \"%s\" for \"%s\".\n", tempname, filename)); return (web_cache[web_files - 1].name); } return (NULL); } /* * 'file_find()' - Find a file in one of the path directories. */ const char * /* O - Pathname or NULL */ file_find(const char *path, /* I - Path "dir;dir;dir" */ const char *s) /* I - File to find */ { int i; /* Looping var */ char *temp; /* Current position in filename */ const char *sptr; /* Pointer into "s" */ int ch; /* Quoted character */ char basename[HTTP_MAX_URI]; /* Base (unquoted) filename */ const char *realname; /* Real filename */ static char filename[HTTP_MAX_URI]; /* Current filename */ /* * If the filename is NULL, return NULL... */ if (s == NULL) return (NULL); DEBUG_printf(("file_find(path=\"%s\", s=\"%s\")\n", path ? path : "(null)", s)); /* * See if this is a cached remote file... */ for (i = 0; i < (int)web_files; i ++) { if (strcmp(s, web_cache[i].name) == 0) { DEBUG_printf(("file_find: Returning cache file \"%s\"!\n", s)); return (web_cache[i].name); } } DEBUG_printf(("file_find: \"%s\" not in web cache of %d files...\n", s, (int)web_files)); /* * Make sure the filename is not quoted... */ if (strchr(s, '%') == NULL) { strlcpy(basename, s, sizeof(basename)); } else { for (sptr = s, temp = basename; *sptr && temp < (basename + sizeof(basename) - 1);) { if (*sptr == '%' && isxdigit(sptr[1]) && isxdigit(sptr[2])) { /* * Dequote %HH... */ if (isalpha(sptr[1])) ch = (tolower(sptr[1]) - 'a' + 10) << 4; else ch = (sptr[1] - '0') << 4; if (isalpha(sptr[2])) ch |= tolower(sptr[2]) - 'a' + 10; else ch |= sptr[2] - '0'; *temp++ = (char)ch; sptr += 3; } else *temp++ = *sptr++; } *temp = '\0'; } /* * If we got a complete URL, we don't use the path... */ if (path != NULL && !path[0]) { DEBUG_puts("file_find: Resetting path to NULL since path is empty..."); path = NULL; } if (strncmp(s, "http:", 5) == 0 || strncmp(s, "https:", 6) == 0 || strncmp(s, "//", 2) == 0) { DEBUG_puts("file_find: Resetting path to NULL since filename is a URL..."); path = NULL; } /* * Loop through the path as needed... */ if (path != NULL) { filename[sizeof(filename) - 1] = '\0'; while (*path != '\0') { /* * Copy the path directory... */ temp = filename; while (*path != ';' && *path && temp < (filename + sizeof(filename) - 1)) *temp++ = *path++; if (*path == ';') path ++; /* * Append a slash as needed, then the filename... */ if (temp > filename && temp < (filename + sizeof(filename) - 1) && basename[0] != '/') *temp++ = '/'; strlcpy(temp, basename, sizeof(filename) - (size_t)(temp - filename)); /* * See if the file or URL exists... */ if ((realname = file_find_check(filename)) != NULL) return (realname); } } return (file_find_check(s)); } /* * 'file_gets()' - Read a line from a file terminated with CR, LF, or CR LF. */ char * /* O - Line from file or NULL on EOF */ file_gets(char *buf, /* I - Line buffer */ int buflen, /* I - Length of buffer */ FILE *fp) /* I - File to read from */ { int ch; /* Character from file */ char *ptr, /* Current position in line buffer */ *end; /* End of line buffer */ /* * Range check everything... */ if (fp == NULL || buf == NULL || buflen < 2) return (NULL); /* * Now loop until we have a valid line... */ ptr = buf; end = buf + buflen - 1; for (;;) { if ((ch = getc(fp)) == EOF) break; else if (ch == '\r') { /* * See if we have CR or CR LF... */ int nextch = getc(fp); if (nextch == EOF || nextch == '\n') break; /* * No LF, so save the next char for later... */ ungetc(nextch, fp); break; } else if (ch == '\n') break; else if (ch == '\\') { /* * Handle \ escapes, to continue to multiple lines... */ int nextch = getc(fp); if (nextch == EOF) break; else if (nextch == '\r') { nextch = getc(fp); if (nextch == EOF) break; else if (nextch != '\n') ungetc(nextch, fp); } else if (nextch != '\n' && ptr < end) *ptr++ = (char)nextch; } else if (ptr < end) *ptr++ = (char)ch; } *ptr = '\0'; if (ch != EOF || ptr > buf) return (buf); else return (NULL); } /* * 'file_localize()' - Localize a filename for the new working directory. */ const char * /* O - New filename */ file_localize(const char *filename, /* I - Filename */ const char *newcwd) /* I - New directory */ { const char *newslash; /* Directory separator */ char *slash; /* Directory separator */ char cwd[1024]; /* Current directory */ char temp[1024]; /* Temporary pathname */ static char newfilename[1024]; /* New filename */ if (filename[0] == '\0') return (""); if (file_method(filename)) return (filename); getcwd(cwd, sizeof(cwd)); if (newcwd == NULL) newcwd = cwd; #if defined(WIN32) || defined(__EMX__) if (filename[0] != '/' && filename[0] != '\\' && !(isalpha(filename[0]) && filename[1] == ':')) #else if (filename[0] != '/') #endif /* WIN32 || __EMX__ */ { for (newslash = filename; strncmp(newslash, "../", 3) == 0; newslash += 3) #if defined(WIN32) || defined(__EMX__) { if ((slash = strrchr(cwd, '/')) == NULL) slash = strrchr(cwd, '\\'); if (slash != NULL) *slash = '\0'; } #else if ((slash = strrchr(cwd, '/')) != NULL) *slash = '\0'; #endif /* WIN32 || __EMX__ */ snprintf(temp, sizeof(temp), "%s/%s", cwd, newslash); } else strlcpy(temp, filename, sizeof(temp)); for (slash = temp, newslash = newcwd; *slash != '\0' && *newslash != '\0'; slash ++, newslash ++) if ((*slash == '/' || *slash == '\\') && (*newslash == '/' || *newslash == '\\')) continue; else if (*slash != *newslash) break; while (*slash != '/' && *slash != '\\' && slash > temp) slash --; if (*slash == '/' || *slash == '\\') slash ++; #if defined(WIN32) || defined(__EMX__) if (isalpha(slash[0]) && slash[1] == ':') return ((char *)filename); /* Different drive letter... */ #endif /* WIN32 || __EMX__ */ if (*newslash != '\0') while (*newslash != '/' && *newslash != '\\' && newslash > newcwd) newslash --; newfilename[0] = '\0'; while (*newslash != '\0') { if (*newslash == '/' || *newslash == '\\') strlcat(newfilename, "../", sizeof(newfilename)); newslash ++; } strlcat(newfilename, slash, sizeof(newfilename)); return (newfilename); } /* * 'file_method()' - Return the method for a filename or URL. * * Returns NULL if the URL is a local file. */ const char * /* O - Method string ("http", "ftp", etc.) */ file_method(const char *s) /* I - Filename or URL */ { if (strncmp(s, "data:", 5) == 0) return ("data"); else if (strncmp(s, "http:", 5) == 0) return ("http"); else if (strncmp(s, "https:", 6) == 0) return ("https"); else if (strncmp(s, "ftp:", 4) == 0) return ("ftp"); else if (strncmp(s, "mailto:", 7) == 0) return ("mailto"); else if (strncmp(s, "file:", 5) == 0) return ("file"); else return (NULL); } /* * 'file_nolocal()' - Disable access to local files. */ void file_nolocal(void) { no_local = 1; } /* * 'file_proxy()' - Set the proxy host for all HTTP requests. */ void file_proxy(const char *url) /* I - URL of proxy server */ { char scheme[HTTP_MAX_URI], /* Method name (must be HTTP) */ username[HTTP_MAX_URI], /* Username:password information */ hostname[HTTP_MAX_URI], /* Hostname */ resource[HTTP_MAX_URI]; /* Resource name */ int port; /* Port number */ if (url == NULL || url[0] == '\0') { proxy_host[0] = '\0'; proxy_port = 0; } else { httpSeparateURI(HTTP_URI_CODING_ALL, url, scheme, sizeof(scheme), username, sizeof(username), hostname, sizeof(hostname), &port, resource, sizeof(resource)); if (strcmp(scheme, "http") == 0) { strlcpy(proxy_host, hostname, sizeof(proxy_host)); proxy_port = port; } } } /* * 'file_referer()' - Set the HTTP referer for remote accesses. */ void file_referer(const char *referer) /* I - Referer URL */ { if (referer) strlcpy(referer_url, referer, sizeof(referer_url)); else referer_url[0] = '\0'; } /* * 'file_rlookup()' - Lookup a filename to find the original URL, if applicable. */ const char * /* O - URL or filename */ file_rlookup(const char *filename) /* I - Filename */ { int i; /* Looping var */ cache_t *wc; /* Current cache file */ for (i = web_files, wc = web_cache; i > 0; i --, wc ++) { if (!strcmp(wc->name, filename)) { if (!strncmp(wc->url, "data:", 5)) return ("data URL"); else return (wc->url); } } return (filename); } /* * 'file_target()' - Return the target of a link. */ const char * /* O - Target name */ file_target(const char *s) /* I - Filename or URL */ { const char *basename; /* Pointer to directory separator */ const char *target; /* Pointer to target */ if (s == NULL) return (NULL); if ((basename = strrchr(s, '/')) != NULL) basename ++; else if ((basename = strrchr(s, '\\')) != NULL) basename ++; else basename = s; if ((target = strchr(basename, '#')) != NULL) return (target + 1); else return (NULL); } /* * 'file_temp()' - Create and open a temporary file. */ FILE * /* O - Temporary file */ file_temp(char *name, /* O - Filename */ int len) /* I - Length of filename buffer */ { cache_t *temp; /* Pointer to cache entry */ FILE *fp; /* File pointer */ int fd; /* File descriptor */ const char *tmpdir; /* Temporary directory */ #ifdef WIN32 char tmppath[1024]; /* Buffer for temp dir */ #endif /* WIN32 */ /* * Allocate memory for the file cache as needed... */ if (web_files >= web_alloc) { web_alloc += ALLOC_FILES; if (web_files == 0) temp = (cache_t *)malloc(sizeof(cache_t) * web_alloc); else temp = (cache_t *)realloc(web_cache, sizeof(cache_t) * web_alloc); if (temp == NULL) { progress_error(HD_ERROR_OUT_OF_MEMORY, "Unable to allocate memory for %d file entries - %s", (int)web_alloc, strerror(errno)); web_alloc -= ALLOC_FILES; return (NULL); } web_cache = temp; } /* * Clear a new file cache entry... */ temp = web_cache + web_files; temp->name = NULL; temp->url = NULL; web_files ++; #ifdef WIN32 if ((tmpdir = getenv("TEMP")) == NULL) { GetTempPath(sizeof(tmppath), tmppath); tmpdir = tmppath; } #else if ((tmpdir = getenv("TMPDIR")) == NULL) tmpdir = "/var/tmp"; #endif /* WIN32 */ snprintf(name, (size_t)len, TEMPLATE, tmpdir, (long)getpid(), (int)web_files); if ((fd = open(name, OPENMODE, OPENPERM)) >= 0) fp = fdopen(fd, "w+b"); else fp = NULL; if (!fp) web_files --; temp->name = strdup(name); return (fp); } htmldoc-1.9.20/htmldoc/file.h000066400000000000000000000024351472561501400157700ustar00rootroot00000000000000/* * Filename definitions for HTMLDOC, a HTML document processing program. * * Copyright 2011, 2014 by Michael R Sweet. * Copyright 1997-2010 by Easy Software Products. All rights reserved. * * This program is free software. Distribution and use rights are outlined in * the file "COPYING". */ #ifndef _FILE_H_ # define _FILE_H_ /* * Include necessary headers... */ # include "hdstring.h" # ifdef __cplusplus extern "C" { # endif /* __cplusplus */ /* * Prototypes... */ extern const char *file_basename(const char *s); extern void file_cleanup(void); extern void file_cookies(const char *s); extern const char *file_directory(const char *s); extern const char *file_extension(const char *s); extern const char *file_find(const char *path, const char *s); extern char *file_gets(char *buf, int buflen, FILE *fp); extern const char *file_localize(const char *filename, const char *newcwd); extern const char *file_method(const char *s); extern void file_nolocal(void); extern void file_proxy(const char *url); extern void file_referer(const char *referer); extern const char *file_rlookup(const char *filename); extern const char *file_target(const char *s); extern FILE *file_temp(char *name, int len); # ifdef __cplusplus } # endif /* __cplusplus */ #endif /* !_FILE_H_ */ htmldoc-1.9.20/htmldoc/gui.cxx000066400000000000000000003414601472561501400162140ustar00rootroot00000000000000// // GUI routines for HTMLDOC, an HTML document processing program. // // Copyright © 2011-2024 by Michael R Sweet. // Copyright © 1997-2010 by Easy Software Products. All rights reserved. // // This program is free software. Distribution and use rights are outlined in // the file "COPYING". // #include "htmldoc.h" #include "markdown.h" #ifdef HAVE_LIBFLTK // // Include necessary headers. // # include # include # include # include # include # include # include # include # include "../desktop/htmldoc.xpm" # ifdef WIN32 # include # include # include "icons.h" # else # include # ifdef HAVE_LIBXPM # include # elif !defined(__APPLE__) # include "../desktop/htmldoc.xbm" # endif // HAVE_LIBXPM # endif // WIN32 // // Class globals... // const char *GUI::help_dir = DOCUMENTATION; #ifdef __APPLE__ char *apple_filename = NULL; #endif // __APPLE__ // // 'GUI()' - Build the HTMLDOC GUI and load the indicated book as necessary. // GUI::GUI(const char *filename) // Book file to load initially { Fl_Group *group; // Group Fl_Box *label; // Label box static Fl_Menu sizeMenu[] = // Menu items for page size button */ { {"A3", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"A4", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Legal", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Letter", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Tabloid", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Universal", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {0} }; static Fl_Menu tocMenu[] = // Menu items for TOC chooser { {"None", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"1 level", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"2 levels", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"3 levels", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"4 Levels", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {0} }; static Fl_Menu formatMenu[] = // Menu items for header/footer choosers { {"Blank", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Title", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Chapter Title", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Heading", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Letterhead", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Logo", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"1,2,3,...", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"i,ii,iii,...", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"I,II,III,...", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"a,b,c,...", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"A,B,C,...", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Chapter Page", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"1/N,2/N,...", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"1/C,2/C,...", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Date", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Time", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Date + Time", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {0} }; static Fl_Menu nupMenu[] = // Menu items for number-up chooser { {"1", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"2", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"4", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"6", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"9", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"16", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {0} }; static Fl_Menu typefaceMenu[] = // Menu items for typeface choosers { {"Courier", 0, 0, 0, 0, 0, FL_COURIER, 14, 0}, {"Times", 0, 0, 0, 0, 0, FL_TIMES, 14, 0}, {"Helvetica", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Monospace", 0, 0, 0, 0, 0, FL_COURIER, 14, 0}, {"Serif", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Sans", 0, 0, 0, 0, 0, FL_TIMES, 14, 0}, {0} }; static Fl_Menu fontMenu[] = // Menu items for font choosers { {"Courier", 0, 0, 0, 0, 0, FL_COURIER, 14, 0}, {"Courier-Bold", 0, 0, 0, 0, 0, FL_COURIER_BOLD, 14, 0}, {"Courier-Oblique", 0, 0, 0, 0, 0, FL_COURIER_ITALIC, 14, 0}, {"Courier-BoldOblique", 0, 0, 0, 0, 0, FL_COURIER_BOLD_ITALIC, 14, 0}, {"Times-Roman", 0, 0, 0, 0, 0, FL_TIMES, 14, 0}, {"Times-Bold", 0, 0, 0, 0, 0, FL_TIMES_BOLD, 14, 0}, {"Times-Italic", 0, 0, 0, 0, 0, FL_TIMES_ITALIC, 14, 0}, {"Times-BoldItalic", 0, 0, 0, 0, 0, FL_TIMES_BOLD_ITALIC, 14, 0}, {"Helvetica", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Helvetica-Bold", 0, 0, 0, 0, 0, FL_HELVETICA_BOLD, 14, 0}, {"Helvetica-Oblique", 0, 0, 0, 0, 0, FL_HELVETICA_ITALIC, 14, 0}, {"Helvetica-BoldOblique", 0, 0, 0, 0, 0, FL_HELVETICA_BOLD_ITALIC, 14, 0}, {"Monospace", 0, 0, 0, 0, 0, FL_COURIER, 14, 0}, {"Monospace-Bold", 0, 0, 0, 0, 0, FL_COURIER_BOLD, 14, 0}, {"Monospace-Oblique", 0, 0, 0, 0, 0, FL_COURIER_ITALIC, 14, 0}, {"Monospace-BoldOblique", 0, 0, 0, 0, 0, FL_COURIER_BOLD_ITALIC, 14, 0}, {"Serif-Roman", 0, 0, 0, 0, 0, FL_TIMES, 14, 0}, {"Serif-Bold", 0, 0, 0, 0, 0, FL_TIMES_BOLD, 14, 0}, {"Serif-Italic", 0, 0, 0, 0, 0, FL_TIMES_ITALIC, 14, 0}, {"Serif-BoldItalic", 0, 0, 0, 0, 0, FL_TIMES_BOLD_ITALIC, 14, 0}, {"Sans", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Sans-Bold", 0, 0, 0, 0, 0, FL_HELVETICA_BOLD, 14, 0}, {"Sans-Oblique", 0, 0, 0, 0, 0, FL_HELVETICA_ITALIC, 14, 0}, {"Sans-BoldOblique", 0, 0, 0, 0, 0, FL_HELVETICA_BOLD_ITALIC, 14, 0}, {0} }; static Fl_Menu charsetMenu[] = // Menu items for charset chooser { {"cp-874", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"cp-1250", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"cp-1251", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"cp-1252", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"cp-1253", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"cp-1254", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"cp-1255", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"cp-1256", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"cp-1257", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"cp-1258", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"iso-8859-1", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"iso-8859-2", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"iso-8859-3", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"iso-8859-4", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"iso-8859-5", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"iso-8859-6", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"iso-8859-7", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"iso-8859-8", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"iso-8859-9", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"iso-8859-14", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"iso-8859-15", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"koi8-r", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"utf-8", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {0} }; static Fl_Menu modeMenu[] = // Menu items for mode chooser { {"Document", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Outline", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Full-Screen", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {0} }; static Fl_Menu layoutMenu[] = // Menu items for layout chooser { {"Single", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"One Column", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Two Column Left", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Two Column Right", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {0} }; static Fl_Menu firstMenu[] = // Menu items for first chooser { {"Page 1", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"TOC", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Chapter 1", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {0} }; static Fl_Menu effectMenu[] = // Menu items for effect chooser { {"None", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Box Inward", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Box Outward", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Dissolve", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Glitter Down", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Glitter Down+Right", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Glitter Right", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Horizontal Blinds", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Horizontal Sweep Inward", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Horizontal Sweep Outward", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Vertical Blinds", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Vertical Sweep Inward", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Vertical Sweep Outward ", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Wipe Down", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Wipe Left", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Wipe Right", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {"Wipe Up", 0, 0, 0, 0, 0, FL_HELVETICA, 14, 0}, {0} }; #ifdef __APPLE__ // Support opening of books via the finder... fl_open_callback(appleOpenCB); #endif // __APPLE__ // Enable/disable tooltips... Fl_Tooltip::enable(Tooltips); // Update the theme Fl::scheme("gtk+"); // // Create a dialog window... // window = new Fl_Double_Window(640, 400, "HTMLDOC " SVERSION); window->callback((Fl_Callback *)closeBookCB, this); controls = new Fl_Group(0, 0, 640, 360); tabs = new Fl_Tabs(10, 10, 620, 315); // // Input tab... // inputTab = new Fl_Group(10, 35, 620, 290, "Input"); group = new Fl_Group(180, 45, 250, 20, "Document Type: "); group->align(FL_ALIGN_LEFT); typeBook = new Fl_Round_Button(180, 45, 60, 20, "Book"); typeBook->type(FL_RADIO_BUTTON); typeBook->setonly(); typeBook->callback((Fl_Callback *)docTypeCB, this); typeBook->tooltip("Convert chapters into a book."); typeContinuous = new Fl_Round_Button(240, 45, 100, 20, "Continuous"); typeContinuous->type(FL_RADIO_BUTTON); typeContinuous->callback((Fl_Callback *)docTypeCB, this); typeContinuous->tooltip("Convert web pages without page breaks."); typeWebPage = new Fl_Round_Button(340, 45, 90, 20, "Web Page"); typeWebPage->type(FL_RADIO_BUTTON); typeWebPage->callback((Fl_Callback *)docTypeCB, this); typeWebPage->tooltip("Convert web pages with page breaks."); group->end(); group = new Fl_Group(180, 70, 250, 20, "Input Files: "); group->align(FL_ALIGN_LEFT); group->end(); inputFiles = new Fl_File_Browser(180, 70, 340, 150); inputFiles->iconsize(20); inputFiles->type(FL_MULTI_BROWSER); inputFiles->callback((Fl_Callback *)inputFilesCB, this); inputFiles->when(FL_WHEN_RELEASE | FL_WHEN_NOT_CHANGED); inputFiles->tooltip("This is the list of HTML files and URLs that will be converted."); addFile = new Fl_Button(520, 70, 100, 25, "Add Files..."); addFile->callback((Fl_Callback *)addFileCB, this); addFile->tooltip("Add HTML files to the list."); addURL = new Fl_Button(520, 95, 100, 25, "Add URL..."); addURL->callback((Fl_Callback *)addURLCB, this); addURL->tooltip("Add a URL to the list."); editFile = new Fl_Button(520, 120, 100, 25, "Edit Files..."); editFile->deactivate(); editFile->callback((Fl_Callback *)editFilesCB, this); editFile->tooltip("Edit HTML files in the list."); deleteFile = new Fl_Button(520, 145, 100, 25, "Delete Files"); deleteFile->deactivate(); deleteFile->callback((Fl_Callback *)deleteFilesCB, this); deleteFile->tooltip("Remove HTML files and URLs from the list."); moveUpFile = new Fl_Button(520, 170, 100, 25, "Move Up"); moveUpFile->deactivate(); moveUpFile->callback((Fl_Callback *)moveUpFilesCB, this); moveUpFile->tooltip("Move HTML files and URLs up in the list."); moveDownFile = new Fl_Button(520, 195, 100, 25, "Move Down"); moveDownFile->deactivate(); moveDownFile->callback((Fl_Callback *)moveDownFilesCB, this); moveDownFile->tooltip("Move HTML files and URLs down in the list."); lhImage = new Fl_Input(180, 230, 340, 25, "Letterhead Image: "); lhImage->when(FL_WHEN_CHANGED); lhImage->callback((Fl_Callback *)lhImageCB, this); lhImage->tooltip("The letterhead image for the header or footer."); lhBrowse = new Fl_Button(520, 230, 100, 25, "Browse..."); lhBrowse->callback((Fl_Callback *)lhImageCB, this); lhBrowse->tooltip("Choose a logo image file."); logoImage = new Fl_Input(180, 260, 340, 25, "Logo Image: "); logoImage->when(FL_WHEN_CHANGED); logoImage->callback((Fl_Callback *)logoImageCB, this); logoImage->tooltip("The logo image for the navigation bar and header or footer."); logoBrowse = new Fl_Button(520, 260, 100, 25, "Browse..."); logoBrowse->callback((Fl_Callback *)logoImageCB, this); logoBrowse->tooltip("Choose a logo image file."); titleImage = new Fl_Input(180, 290, 340, 25, "Title File/Image: "); titleImage->when(FL_WHEN_CHANGED); titleImage->callback((Fl_Callback *)titleImageCB, this); titleImage->tooltip("The title image or HTML file for the title page."); titleBrowse = new Fl_Button(520, 290, 100, 25, "Browse..."); titleBrowse->callback((Fl_Callback *)titleImageCB, this); titleBrowse->tooltip("Choose a title file."); inputTab->end(); inputTab->resizable(inputFiles); // // Output tab... // outputTab = new Fl_Group(10, 35, 620, 290, "Output"); outputTab->hide(); group = new Fl_Group(180, 45, 265, 20, "Output To: "); group->align(FL_ALIGN_LEFT); outputFile = new Fl_Round_Button(180, 45, 50, 20, "File"); outputFile->type(FL_RADIO_BUTTON); outputFile->setonly(); outputFile->callback((Fl_Callback *)outputTypeCB, this); outputFile->tooltip("Generate a single output file."); outputDirectory = new Fl_Round_Button(230, 45, 105, 20, "Directory"); outputDirectory->type(FL_RADIO_BUTTON); outputDirectory->callback((Fl_Callback *)outputTypeCB, this); outputDirectory->tooltip("Generate multiple output files in a directory."); group->end(); outputPath = new Fl_Input(180, 75, 340, 25, "Output Path: "); outputPath->when(FL_WHEN_CHANGED); outputPath->callback((Fl_Callback *)outputPathCB, this); outputPath->tooltip("The name of the output file or directory."); outputBrowse = new Fl_Button(520, 75, 100, 25, "Browse..."); outputBrowse->callback((Fl_Callback *)outputPathCB, this); outputBrowse->tooltip("Choose an output file."); group = new Fl_Group(180, 110, 325, 20, "Output Format: "); group->align(FL_ALIGN_LEFT); typeEPUB = new Fl_Round_Button(180, 110, 65, 20, "EPUB"); typeEPUB->type(FL_RADIO_BUTTON); typeEPUB->callback((Fl_Callback *)outputFormatCB, this); typeEPUB->tooltip("Generate EPUB file(s)."); typeHTML = new Fl_Round_Button(245, 110, 65, 20, "HTML"); typeHTML->type(FL_RADIO_BUTTON); typeHTML->setonly(); typeHTML->callback((Fl_Callback *)outputFormatCB, this); typeHTML->tooltip("Generate HTML file(s)."); typeHTMLSep = new Fl_Round_Button(310, 110, 95, 20, "Split HTML"); typeHTMLSep->type(FL_RADIO_BUTTON); typeHTMLSep->callback((Fl_Callback *)outputFormatCB, this); typeHTMLSep->tooltip("Generate separate HTML files for each TOC heading."); typePS = new Fl_Round_Button(405, 110, 45, 20, "PS"); typePS->type(FL_RADIO_BUTTON); typePS->callback((Fl_Callback *)outputFormatCB, this); typePS->tooltip("Generate Adobe PostScript(r) file(s)."); typePDF = new Fl_Round_Button(450, 110, 55, 20, "PDF"); typePDF->type(FL_RADIO_BUTTON); typePDF->callback((Fl_Callback *)outputFormatCB, this); typePDF->tooltip("Generate an Adobe Acrobat file."); group->end(); group = new Fl_Group(180, 140, 265, 20, "Output Options: "); group->align(FL_ALIGN_LEFT); group->end(); grayscale = new Fl_Check_Button(180, 140, 90, 20, "Grayscale"); grayscale->callback((Fl_Callback *)changeCB, this); grayscale->tooltip("Check to produce grayscale output."); titlePage = new Fl_Check_Button(280, 140, 90, 20, "Title Page"); titlePage->callback((Fl_Callback *)changeCB, this); titlePage->tooltip("Check to generate a title page."); jpegCompress = new Fl_Check_Button(380, 140, 140, 20, "JPEG Big Images"); jpegCompress->callback((Fl_Callback *)jpegCB, this); jpegCompress->tooltip("Check to reduce the size of large images using the JPEG algorithm."); compGroup = new Fl_Group(180, 170, 440, 40, "Compression: \n "); compGroup->align(FL_ALIGN_LEFT); compression = new Fl_Slider(180, 170, 440, 20); compression->type(FL_HOR_NICE_SLIDER); compression->minimum(0.0); compression->maximum(9.0); compression->value(1.0); compression->step(1.0); compression->callback((Fl_Callback *)changeCB, this); compression->tooltip("Reduce the size of output files."); label = new Fl_Box(180, 190, 30, 10, "None"); label->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE); label->labelsize(10); label = new Fl_Box(220, 190, 30, 10, "Fast"); label->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE); label->labelsize(10); label = new Fl_Box(590, 190, 30, 10, "Best"); label->align(FL_ALIGN_RIGHT | FL_ALIGN_INSIDE); label->labelsize(10); compGroup->end(); jpegGroup = new Fl_Group(180, 210, 440, 40, "JPEG Quality: \n "); jpegGroup->align(FL_ALIGN_LEFT); jpegQuality = new Fl_Value_Slider(180, 210, 440, 20); jpegQuality->type(FL_HOR_NICE_SLIDER); jpegQuality->minimum(50.0); jpegQuality->maximum(100.0); jpegQuality->value(90.0); jpegQuality->step(1.0); jpegQuality->callback((Fl_Callback *)changeCB, this); jpegQuality->tooltip("Set the quality of images using JPEG compression.\n" "(lower quality produces smaller output)"); label = new Fl_Box(215, 230, 40, 10, "Good"); label->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE); label->labelsize(10); label = new Fl_Box(580, 230, 40, 10, "Best"); label->align(FL_ALIGN_RIGHT | FL_ALIGN_INSIDE); label->labelsize(10); jpegGroup->end(); outputTab->end(); // // Page tab... // pageTab = new Fl_Group(10, 35, 620, 290, "Page"); pageTab->hide(); pageSize = new Fl_Input(180, 45, 100, 25, "Page Size: "); pageSize->when(FL_WHEN_CHANGED); pageSize->callback((Fl_Callback *)changeCB, this); pageSize->tooltip("Enter the page size."); pageSizeMenu = new Fl_Menu_Button(280, 45, 25, 25, ""); pageSizeMenu->menu(sizeMenu); pageSizeMenu->callback((Fl_Callback *)sizeCB, this); pageSizeMenu->tooltip("Click to choose a standard size."); pageDuplex = new Fl_Check_Button(310, 45, 70, 20, "2-Sided"); pageDuplex->callback((Fl_Callback *)changeCB, this); pageDuplex->tooltip("Produce output suitable for double-sided printing."); landscape = new Fl_Check_Button(385, 45, 90, 20, "Landscape"); landscape->callback((Fl_Callback *)changeCB, this); landscape->tooltip("Check to rotate the output to landscape orientation."); pageTop = new Fl_Input(265, 75, 60, 25, "Top"); pageTop->when(FL_WHEN_CHANGED); pageTop->callback((Fl_Callback *)changeCB, this); pageTop->tooltip("Enter the top margin."); pageLeft = new Fl_Input(230, 105, 60, 25, "Left"); pageLeft->when(FL_WHEN_CHANGED); pageLeft->callback((Fl_Callback *)changeCB, this); pageLeft->tooltip("Enter the left margin."); pageRight = new Fl_Input(295, 105, 60, 25, "Right"); pageRight->when(FL_WHEN_CHANGED); pageRight->align(FL_ALIGN_RIGHT); pageRight->callback((Fl_Callback *)changeCB, this); pageRight->tooltip("Enter the right margin."); pageBottom = new Fl_Input(265, 135, 60, 25, "Bottom"); pageBottom->when(FL_WHEN_CHANGED); pageBottom->callback((Fl_Callback *)changeCB, this); pageBottom->tooltip("Enter the bottom margin."); pageHeaderLeft = new Fl_Choice(180, 165, 110, 25, "Header: "); pageHeaderLeft->menu(formatMenu); pageHeaderLeft->callback((Fl_Callback *)changeCB, this); pageHeaderLeft->tooltip("Choose the left header."); pageHeaderCenter = new Fl_Choice(295, 165, 110, 25); pageHeaderCenter->menu(formatMenu); pageHeaderCenter->callback((Fl_Callback *)changeCB, this); pageHeaderCenter->tooltip("Choose the center header."); pageHeaderRight = new Fl_Choice(410, 165, 110, 25); pageHeaderRight->menu(formatMenu); pageHeaderRight->callback((Fl_Callback *)changeCB, this); pageHeaderRight->tooltip("Choose the right header."); pageHeader1Left = new Fl_Choice(180, 195, 110, 25, "Header (1st Page): "); pageHeader1Left->menu(formatMenu); pageHeader1Left->callback((Fl_Callback *)changeCB, this); pageHeader1Left->tooltip("Choose the left header1."); pageHeader1Center = new Fl_Choice(295, 195, 110, 25); pageHeader1Center->menu(formatMenu); pageHeader1Center->callback((Fl_Callback *)changeCB, this); pageHeader1Center->tooltip("Choose the center header1."); pageHeader1Right = new Fl_Choice(410, 195, 110, 25); pageHeader1Right->menu(formatMenu); pageHeader1Right->callback((Fl_Callback *)changeCB, this); pageHeader1Right->tooltip("Choose the right header1."); pageFooterLeft = new Fl_Choice(180, 225, 110, 25, "Footer: "); pageFooterLeft->menu(formatMenu); pageFooterLeft->callback((Fl_Callback *)changeCB, this); pageFooterLeft->tooltip("Choose the left footer."); pageFooterCenter = new Fl_Choice(295, 225, 110, 25); pageFooterCenter->menu(formatMenu); pageFooterCenter->callback((Fl_Callback *)changeCB, this); pageFooterCenter->tooltip("Choose the center header."); pageFooterRight = new Fl_Choice(410, 225, 110, 25); pageFooterRight->menu(formatMenu); pageFooterRight->callback((Fl_Callback *)changeCB, this); pageFooterRight->tooltip("Choose the right header."); numberUp = new Fl_Choice(180, 255, 50, 25, "Number Up: "); numberUp->menu(nupMenu); numberUp->callback((Fl_Callback *)changeCB, this); numberUp->tooltip("Set the number of pages on each sheet."); pageTab->end(); // // TOC tab... // tocTab = new Fl_Group(10, 35, 620, 280, "TOC"); tocTab->hide(); tocLevels = new Fl_Choice(180, 45, 100, 25, "Table of Contents: "); tocLevels->menu(tocMenu); tocLevels->callback((Fl_Callback *)tocCB, this); tocLevels->tooltip("Choose the number of table of contents levels."); numberedToc = new Fl_Check_Button(285, 47, 160, 20, "Numbered Headings"); numberedToc->callback((Fl_Callback *)changeCB, this); numberedToc->tooltip("Check to number all of the headings in the document."); tocHeader = new Fl_Group(180, 75, 345, 25, "Header: "); tocHeader->align(FL_ALIGN_LEFT); tocHeaderLeft = new Fl_Choice(180, 75, 110, 25); tocHeaderLeft->menu(formatMenu); tocHeaderLeft->callback((Fl_Callback *)changeCB, this); tocHeaderLeft->tooltip("Choose the left header."); tocHeaderCenter = new Fl_Choice(295, 75, 110, 25); tocHeaderCenter->menu(formatMenu); tocHeaderCenter->callback((Fl_Callback *)changeCB, this); tocHeaderCenter->tooltip("Choose the center header."); tocHeaderRight = new Fl_Choice(410, 75, 110, 25); tocHeaderRight->menu(formatMenu); tocHeaderRight->callback((Fl_Callback *)changeCB, this); tocHeaderRight->tooltip("Choose the right header."); tocHeader->end(); tocFooter = new Fl_Group(180, 105, 345, 25, "Footer: "); tocFooter->align(FL_ALIGN_LEFT); tocFooterLeft = new Fl_Choice(180, 105, 110, 25, "Footer: "); tocFooterLeft->menu(formatMenu); tocFooterLeft->callback((Fl_Callback *)changeCB, this); tocFooterLeft->tooltip("Choose the left footer."); tocFooterCenter = new Fl_Choice(295, 105, 110, 25); tocFooterCenter->menu(formatMenu); tocFooterCenter->callback((Fl_Callback *)changeCB, this); tocFooterCenter->tooltip("Choose the center footer."); tocFooterRight = new Fl_Choice(410, 105, 110, 25); tocFooterRight->menu(formatMenu); tocFooterRight->callback((Fl_Callback *)changeCB, this); tocFooterRight->tooltip("Choose the right footer."); tocFooter->end(); tocTitle = new Fl_Input(180, 135, 440, 25, "Title: "); tocTitle->when(FL_WHEN_CHANGED); tocTitle->callback((Fl_Callback *)changeCB, this); tocTitle->tooltip("Enter the title of the table of contents."); tocTab->end(); // // Colors tab... // colorsTab = new Fl_Group(10, 35, 620, 280, "Colors"); colorsTab->hide(); bodyColor = new Fl_Input(180, 45, 100, 25, "Body Color: "); bodyColor->when(FL_WHEN_CHANGED); bodyColor->callback((Fl_Callback *)bodyColorCB, this); bodyColor->tooltip("Enter the HTML color for the body (background)."); bodyLookup = new Fl_Button(280, 45, 80, 25, "Lookup..."); bodyLookup->callback((Fl_Callback *)bodyColorCB, this); bodyLookup->tooltip("Click to choose the HTML color for the body (background)."); bodyImage = new Fl_Input(180, 75, 340, 25, "Body Image: "); bodyImage->when(FL_WHEN_CHANGED); bodyImage->callback((Fl_Callback *)bodyImageCB, this); bodyImage->tooltip("Enter the image file for the body (background)."); bodyBrowse = new Fl_Button(520, 75, 100, 25, "Browse..."); bodyBrowse->callback((Fl_Callback *)bodyImageCB, this); bodyBrowse->tooltip("Click to choose the image file for the body (background)."); textColor = new Fl_Input(180, 105, 100, 25, "Text Color: "); textColor->when(FL_WHEN_CHANGED); textColor->callback((Fl_Callback *)textColorCB, this); textColor->tooltip("Enter the HTML color for the text."); textLookup = new Fl_Button(280, 105, 80, 25, "Lookup..."); textLookup->callback((Fl_Callback *)textColorCB, this); textLookup->tooltip("Click to choose the HTML color for the text."); linkColor = new Fl_Input(180, 135, 100, 25, "Link Color: "); linkColor->when(FL_WHEN_CHANGED); linkColor->callback((Fl_Callback *)linkColorCB, this); linkColor->tooltip("Enter the HTML color for links."); linkLookup = new Fl_Button(280, 135, 80, 25, "Lookup..."); linkLookup->callback((Fl_Callback *)linkColorCB, this); linkLookup->tooltip("Click to choose the HTML color for links."); linkStyle = new Fl_Choice(180, 165, 100, 25, "Link Style: "); linkStyle->add("Plain"); linkStyle->add("Underline"); linkStyle->callback((Fl_Callback *)changeCB, this); linkStyle->tooltip("Choose the appearance of links."); colorsTab->end(); // // Fonts tab... // fontsTab = new Fl_Group(10, 35, 620, 290, "Fonts"); fontsTab->hide(); fontBaseSize = new Fl_Counter(200, 45, 150, 25, "Base Font Size: "); fontBaseSize->callback((Fl_Callback *)changeCB, this); fontBaseSize->minimum(4.0); fontBaseSize->maximum(24.0); fontBaseSize->step(0.1); fontBaseSize->value(11.0); fontBaseSize->align(FL_ALIGN_LEFT); fontBaseSize->tooltip("Set the default size of text."); fontSpacing = new Fl_Counter(200, 75, 150, 25, "Line Spacing: "); fontSpacing->callback((Fl_Callback *)changeCB, this); fontSpacing->minimum(1.0); fontSpacing->maximum(3.0); fontSpacing->step(0.1); fontSpacing->value(1.2); fontSpacing->align(FL_ALIGN_LEFT); fontSpacing->tooltip("Set the spacing between lines of text."); bodyFont = new Fl_Choice(200, 105, 100, 25, "Body Typeface: "); bodyFont->menu(typefaceMenu); bodyFont->callback((Fl_Callback *)changeCB, this); bodyFont->tooltip("Choose the default typeface (font) of text."); headingFont = new Fl_Choice(200, 135, 100, 25, "Heading Typeface: "); headingFont->menu(typefaceMenu); headingFont->callback((Fl_Callback *)changeCB, this); headingFont->tooltip("Choose the default typeface (font) of headings."); headFootSize = new Fl_Counter(200, 165, 150, 25, "Header/Footer Size: "); headFootSize->callback((Fl_Callback *)changeCB, this); headFootSize->minimum(4.0); headFootSize->maximum(24.0); headFootSize->step(0.1); headFootSize->value(11.0); headFootSize->align(FL_ALIGN_LEFT); headFootSize->tooltip("Set the size of header and footer text."); headFootFont = new Fl_Choice(200, 195, 220, 25, "Header/Footer Font: "); headFootFont->menu(fontMenu); headFootFont->callback((Fl_Callback *)changeCB, this); headFootFont->tooltip("Choose the font for header and footer text."); charset = new Fl_Choice(200, 225, 110, 25, "Character Set: "); charset->menu(charsetMenu); charset->callback((Fl_Callback *)changeCB, this); charset->tooltip("Choose the encoding of text."); preIndent = new Fl_Input(200, 255, 60, 25, "PRE Indent: "); preIndent->when(FL_WHEN_CHANGED); preIndent->callback((Fl_Callback *)changeCB, this); preIndent->tooltip("Enter the indentation for pre-formatted text."); group = new Fl_Group(200, 285, 285, 25, "Options: "); group->align(FL_ALIGN_LEFT); embedFonts = new Fl_Check_Button(200, 285, 110, 25, "Embed Fonts"); embedFonts->callback((Fl_Callback *)changeCB, this); embedFonts->tooltip("Check to embed fonts in the output file."); group->end(); fontsTab->end(); // // PostScript tab... // psTab = new Fl_Group(10, 35, 620, 290, "PS"); psTab->hide(); psLevel = new Fl_Group(180, 45, 310, 20, "PostScript: "); psLevel->align(FL_ALIGN_LEFT); ps1 = new Fl_Round_Button(180, 45, 70, 20, "Level 1"); ps1->type(FL_RADIO_BUTTON); ps1->callback((Fl_Callback *)psCB, this); ps1->tooltip("Produce PostScript Level 1 output."); ps2 = new Fl_Round_Button(250, 45, 70, 20, "Level 2"); ps2->type(FL_RADIO_BUTTON); ps2->callback((Fl_Callback *)psCB, this); ps2->tooltip("Produce PostScript Level 2 output.\n" "(most common)"); ps3 = new Fl_Round_Button(320, 45, 70, 20, "Level 3"); ps3->type(FL_RADIO_BUTTON); ps3->callback((Fl_Callback *)psCB, this); ps3->tooltip("Produce PostScript Level 3 output."); psLevel->end(); psCommands = new Fl_Check_Button(180, 70, 310, 20, "Send Printer Commands"); psCommands->callback((Fl_Callback *)changeCB, this); psCommands->tooltip("Include PostScript commands to set the media size, etc."); xrxComments = new Fl_Check_Button(180, 95, 310, 20, "Include Xerox Job Comments"); xrxComments->callback((Fl_Callback *)changeCB, this); xrxComments->tooltip("Include Xerox job comments to set the media size, etc."); psTab->end(); // // PDF tab... // pdfTab = new Fl_Group(10, 35, 620, 290, "PDF"); pdfTab->hide(); pdfVersion = new Fl_Group(180, 45, 440, 40, "PDF Version: \n "); pdfVersion->align(FL_ALIGN_LEFT); pdf11 = new Fl_Round_Button(180, 45, 130, 20, "1.1 (Acrobat 2.x)"); pdf11->type(FL_RADIO_BUTTON); pdf11->callback((Fl_Callback *)pdfCB, this); pdf11->tooltip("Produce PDF files for Acrobat 2.x."); pdf12 = new Fl_Round_Button(320, 45, 130, 20, "1.2 (Acrobat 3.0)"); pdf12->type(FL_RADIO_BUTTON); pdf12->callback((Fl_Callback *)pdfCB, this); pdf12->tooltip("Produce PDF files for Acrobat 3.0."); pdf13 = new Fl_Round_Button(180, 65, 130, 20, "1.3 (Acrobat 4.0)"); pdf13->type(FL_RADIO_BUTTON); pdf13->callback((Fl_Callback *)pdfCB, this); pdf13->tooltip("Produce PDF files for Acrobat 4.0."); pdf14 = new Fl_Round_Button(320, 65, 130, 20, "1.4 (Acrobat 5.0)"); pdf14->type(FL_RADIO_BUTTON); pdf14->callback((Fl_Callback *)pdfCB, this); pdf14->tooltip("Produce PDF files for Acrobat 5.0."); pdfVersion->end(); pageMode = new Fl_Choice(180, 90, 120, 25, "Page Mode: "); pageMode->menu(modeMenu); pageMode->callback((Fl_Callback *)changeCB, this); pageMode->tooltip("Choose the initial viewing mode for the file."); pageLayout = new Fl_Choice(180, 120, 150, 25, "Page Layout: "); pageLayout->menu(layoutMenu); pageLayout->callback((Fl_Callback *)changeCB, this); pageLayout->tooltip("Choose the initial page layout for the file."); firstPage = new Fl_Choice(180, 150, 100, 25, "First Page: "); firstPage->menu(firstMenu); firstPage->callback((Fl_Callback *)changeCB, this); firstPage->tooltip("Choose the initial page that will be shown."); pageEffect = new Fl_Choice(180, 180, 210, 25, "Page Effect: "); pageEffect->menu(effectMenu); pageEffect->callback((Fl_Callback *)effectCB, this); pageEffect->tooltip("Choose the page transition effect."); pageDuration = new Fl_Value_Slider(180, 210, 440, 20, "Page Duration: "); pageDuration->align(FL_ALIGN_LEFT); pageDuration->type(FL_HOR_NICE_SLIDER); pageDuration->minimum(1.0); pageDuration->maximum(60.0); pageDuration->value(10.0); pageDuration->step(1.0); pageDuration->callback((Fl_Callback *)changeCB, this); pageDuration->tooltip("Set the amount of time each page is visible."); effectDuration = new Fl_Value_Slider(180, 235, 440, 20, "Effect Duration: "); effectDuration->align(FL_ALIGN_LEFT); effectDuration->type(FL_HOR_NICE_SLIDER); effectDuration->minimum(0.5); effectDuration->maximum(5.0); effectDuration->value(1.0); effectDuration->step(0.1); effectDuration->callback((Fl_Callback *)changeCB, this); effectDuration->tooltip("Set the amount of time to use for the page transition effect."); group = new Fl_Group(180, 260, 350, 25, "Options: "); group->align(FL_ALIGN_LEFT); links = new Fl_Check_Button(180, 260, 110, 25, "Include Links"); links->callback((Fl_Callback *)changeCB, this); links->tooltip("Check to include hyperlinks in the output file."); group->end(); pdfTab->end(); // // Security tab... // securityTab = new Fl_Group(10, 35, 620, 290, "Security"); securityTab->hide(); encryption = new Fl_Group(180, 45, 310, 20, "Encryption: "); encryption->align(FL_ALIGN_LEFT); encryptionNo = new Fl_Round_Button(180, 45, 40, 20, "No"); encryptionNo->type(FL_RADIO_BUTTON); encryptionNo->set(); encryptionNo->callback((Fl_Callback *)encryptionCB, this); encryptionNo->tooltip("Select to disable encryption (scrambling) of the output file."); encryptionYes = new Fl_Round_Button(220, 45, 45, 20, "Yes"); encryptionYes->type(FL_RADIO_BUTTON); encryptionYes->callback((Fl_Callback *)encryptionCB, this); encryptionYes->tooltip("Select to enable encryption (scrambling) of the output file.\n" "(128-bit encryption for Acrobat 5.0, 40-bit for older versions.)"); encryption->end(); permissions = new Fl_Group(180, 70, 310, 40, "Permissions: "); permissions->align(FL_ALIGN_LEFT); permPrint = new Fl_Check_Button(180, 70, 80, 20, "Print"); permPrint->tooltip("Check to allow the user to print the output file."); permModify = new Fl_Check_Button(260, 70, 80, 20, "Modify"); permModify->tooltip("Check to allow the user to modify the output file."); permCopy = new Fl_Check_Button(180, 90, 80, 20, "Copy"); permCopy->tooltip("Check to allow the user to copy text and images from the output file."); permAnnotate = new Fl_Check_Button(260, 90, 80, 20, "Annotate"); permAnnotate->tooltip("Check to allow the user to annotate the output file."); permissions->end(); ownerPassword = new Fl_Secret_Input(180, 115, 150, 25, "Owner Password: "); ownerPassword->maximum_size(32); ownerPassword->tooltip("Enter the password required to modify the file.\n" "(leave blank for a random password)"); userPassword = new Fl_Secret_Input(180, 145, 150, 25, "User Password: "); userPassword->maximum_size(32); userPassword->tooltip("Enter the password required to open the file.\n" "(leave blank for no password)"); securityTab->end(); // // Options tab... // optionsTab = new Fl_Group(10, 35, 620, 290, "Options"); optionsTab->hide(); htmlEditor = new Fl_Input(180, 45, 340, 25, "HTML Editor: "); htmlEditor->value(HTMLEditor); htmlEditor->when(FL_WHEN_CHANGED); htmlEditor->callback((Fl_Callback *)htmlEditorCB, this); htmlEditor->tooltip("Enter the command used to edit HTML files.\n" "(use \"%s\" to insert the filename)"); htmlBrowse = new Fl_Button(520, 45, 100, 25, "Browse..."); htmlBrowse->callback((Fl_Callback *)htmlEditorCB, this); htmlBrowse->tooltip("Click to choose the HTML editor."); browserWidth = new Fl_Value_Slider(180, 75, 440, 20, "Browser Width: "); browserWidth->align(FL_ALIGN_LEFT); browserWidth->type(FL_HOR_NICE_SLIDER); browserWidth->minimum(300.0); browserWidth->maximum(1200.0); browserWidth->value(_htmlBrowserWidth); browserWidth->step(5.0); browserWidth->callback((Fl_Callback *)changeCB, this); browserWidth->tooltip("Set the target browser width in pixels.\n" "(this determines the page scaling of images)"); path = new Fl_Input(180, 100, 440, 25, "Search Path: "); path->value(Path); path->maximum_size(sizeof(Path) - 1); path->when(FL_WHEN_CHANGED); path->callback((Fl_Callback *)changeCB, this); path->tooltip("Enter one or more directories or URLs to search for files.\n" "(separate each directory or URL with the ';' character)"); proxy = new Fl_Input(180, 130, 440, 25, "HTTP Proxy URL: "); proxy->value(Proxy); proxy->maximum_size(sizeof(Proxy) - 1); proxy->when(FL_WHEN_CHANGED); proxy->callback((Fl_Callback *)changeCB, this); proxy->tooltip("Enter a URL for your HTTP proxy server.\n" "(http://server:port)"); group = new Fl_Group(180, 160, 350, 80, "GUI Options: \n\n\n\n\n"); group->align(FL_ALIGN_LEFT); tooltips = new Fl_Check_Button(180, 160, 75, 20, "Tooltips"); tooltips->callback((Fl_Callback *)tooltipCB, this); tooltips->value(Tooltips); tooltips->tooltip("Check to show tooltips."); strict_html = new Fl_Check_Button(180, 180, 100, 20, "Strict HTML"); strict_html->value(StrictHTML); strict_html->tooltip("Check to require strict HTML conformance."); overflow_errors = new Fl_Check_Button(180, 200, 135, 20, "Error on Overflow"); overflow_errors->value(OverflowErrors); overflow_errors->tooltip("Check to display an error when the HTML content\n" "is too large to fit on the page."); group->end(); showAbout = new Fl_Button(140, 290, 150, 25, "About HTMLDOC"); showAbout->callback((Fl_Callback *)showAboutCB); showAbout->tooltip("Click to show information about HTMLDOC."); showLicense = new Fl_Button(300, 290, 90, 25, "License"); showLicense->callback((Fl_Callback *)showLicenseCB); showLicense->tooltip("Click to show the software license."); saveOptions = new Fl_Button(400, 290, 220, 25, "Save Options and Defaults"); saveOptions->callback((Fl_Callback *)saveOptionsCB, this); saveOptions->tooltip("Click to save the current options."); optionsTab->end(); tabs->end(); // // Button bar... // bookHelp = new Fl_Button(10, 335, 70, 25, "Help"); bookHelp->shortcut(FL_F + 1); bookHelp->callback((Fl_Callback *)helpCB, this); bookNew = new Fl_Button(90, 335, 65, 25, "New"); bookNew->shortcut(FL_CTRL | 'n'); bookNew->callback((Fl_Callback *)newBookCB, this); bookOpen = new Fl_Button(165, 335, 80, 25, "Open..."); bookOpen->shortcut(FL_CTRL | 'o'); bookOpen->callback((Fl_Callback *)openBookCB, this); bookSave = new Fl_Button(255, 335, 70, 25, "Save"); bookSave->shortcut(FL_CTRL | 's'); bookSave->callback((Fl_Callback *)saveBookCB, this); bookSaveAs = new Fl_Button(335, 335, 105, 25, "Save As..."); bookSaveAs->shortcut(FL_CTRL | FL_SHIFT | 's'); bookSaveAs->callback((Fl_Callback *)saveAsBookCB, this); bookGenerate = new Fl_Button(450, 335, 100, 25, "Generate"); bookGenerate->shortcut(FL_CTRL | 'g'); bookGenerate->callback((Fl_Callback *)generateBookCB, this); bookClose = new Fl_Button(560, 335, 70, 25, "Close"); bookClose->shortcut(FL_CTRL | 'q'); bookClose->callback((Fl_Callback *)closeBookCB, this); controls->end(); // // Progress bar... // progressBar = new Fl_Progress(10, 370, 620, 20, "HTMLDOC " SVERSION " Ready."); window->end(); // Set the class name to "htmldoc". window->xclass("htmldoc"); # ifdef WIN32 // Load the HTMLDOC icon image... window->icon((char *)LoadImage(fl_display, MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR)); # elif defined(__APPLE__) // MacOS X gets the icon from the application bundle... # elif defined(HAVE_LIBXPM) // X11 w/Xpm library Pixmap pixmap, mask; // Icon pixmaps XpmAttributes attrs; // Attributes of icon // Open the X display and load the HTMLDOC icon image... fl_open_display(); memset(&attrs, 0, sizeof(attrs)); XpmCreatePixmapFromData(fl_display, DefaultRootWindow(fl_display), (char **)htmldoc_xpm, &pixmap, &mask, &attrs); window->icon((char *)pixmap); # else // X11 w/o Xpm library // Open the X display and load the HTMLDOC icon image... fl_open_display(); window->icon((char *)XCreateBitmapFromData(fl_display, DefaultRootWindow(fl_display), (char *)htmldoc_bits, htmldoc_width, htmldoc_height)); # endif // WIN32 window->resizable(tabs); window->size_range(470, 360); // File chooser, icons, help dialog, error window... fc = new Fl_File_Chooser(".", "*", Fl_File_Chooser::SINGLE, "Title"); fc->iconsize(20); if (!Fl_File_Icon::first()) Fl_File_Icon::load_system_icons(); icon = Fl_File_Icon::find("file.html", Fl_File_Icon::PLAIN); help = new Fl_Help_Dialog(); error_window = new Fl_Window(400, 300, "Errors"); error_list = new Fl_Browser(10, 10, 380, 245); error_ok = new Fl_Button(335, 265, 55, 25, "Close"); error_ok->callback((Fl_Callback *)errorCB, this); error_window->end(); error_window->resizable(error_list); // // Load the given book or create a new one... // book_changed = 0; book_filename[0] = '\0'; #ifdef __APPLE__ if (apple_filename) { loadBook(apple_filename); free(apple_filename); apple_filename = NULL; } else #endif // __APPLE__ if (filename == NULL) newBookCB(NULL, this); else loadBook(filename); // Show the window... show(); #if 0 // Wait for the window to be drawn... while (window->damage()) Fl::check(); #endif // 0 } // // '~GUI()' - Destroy the HTMLDOC GUI. // GUI::~GUI(void) { delete window; delete fc; delete help; delete error_window; while (Fl_File_Icon::first()) delete Fl_File_Icon::first(); } // // 'GUI::show()' - Display the window. // void GUI::show(void) { static char *htmldoc[1] = { (char *)"htmldoc" }; // argv[] array window->show(1, htmldoc); } // // 'GUI::progress()' - Update the progress bar on the GUI. // void GUI::progress(int percent, // I - Percent complete const char *text) // I - Text prompt { if (text != NULL) progressBar->label(text); else if (percent == 0) progressBar->label("HTMLDOC " SVERSION " Ready."); if ((percent - (int)progressBar->value()) >= 10 || percent < (int)progressBar->value()) progressBar->value(percent); if (progressBar->damage()) Fl::check(); } // // 'GUI::title()' - Set the title bar of the window. // void GUI::title(const char *filename,// Name of file being edited int changed) // Whether or not the file is modified { book_changed = changed; if (filename == NULL || filename[0] == '\0') { book_filename[0] = '\0'; strlcpy(title_string, "NewBook", sizeof(title_string)); } else { strlcpy(book_filename, filename, sizeof(book_filename)); strlcpy(title_string, file_basename(filename), sizeof(title_string)); } if (changed) strlcat(title_string, "(modified) - ", sizeof(title_string)); else strlcat(title_string, " - ", sizeof(title_string)); strlcat(title_string, "HTMLDOC " SVERSION, sizeof(title_string)); window->label(title_string); if (window->visible()) Fl::check(); } // // 'GUI::loadSettings()' - Load the current settings into the HTMLDOC globals. // void GUI::loadSettings() { char temp[4]; // Format string static const char *formats = ".tchLl1iIaAC/:dTD"; // Format characters set_page_size((char *)pageSize->value()); PageLeft = get_measurement((char *)pageLeft->value()); PageRight = get_measurement((char *)pageRight->value()); PageTop = get_measurement((char *)pageTop->value()); PageBottom = get_measurement((char *)pageBottom->value()); PageDuplex = pageDuplex->value(); Landscape = landscape->value(); Compression = (int)compression->value(); OutputColor = !grayscale->value(); TocNumbers = numberedToc->value(); TocLevels = tocLevels->value(); TitlePage = titlePage->value(); if (jpegCompress->value()) OutputJPEG = (int)jpegQuality->value(); else OutputJPEG = 0; strlcpy(TocTitle, tocTitle->value(), sizeof(TocTitle)); temp[0] = formats[tocHeaderLeft->value()]; temp[1] = formats[tocHeaderCenter->value()]; temp[2] = formats[tocHeaderRight->value()]; temp[3] = '\0'; get_format(temp, TocHeader); temp[0] = formats[tocFooterLeft->value()]; temp[1] = formats[tocFooterCenter->value()]; temp[2] = formats[tocFooterRight->value()]; get_format(temp, TocFooter); temp[0] = formats[pageHeaderLeft->value()]; temp[1] = formats[pageHeaderCenter->value()]; temp[2] = formats[pageHeaderRight->value()]; get_format(temp, Header); temp[0] = formats[pageHeader1Left->value()]; temp[1] = formats[pageHeader1Center->value()]; temp[2] = formats[pageHeader1Right->value()]; get_format(temp, Header1); temp[0] = formats[pageFooterLeft->value()]; temp[1] = formats[pageFooterCenter->value()]; temp[2] = formats[pageFooterRight->value()]; get_format(temp, Footer); NumberUp = atoi(numberUp->text(numberUp->value())); _htmlBodyFont = (typeface_t)bodyFont->value(); _htmlHeadingFont = (typeface_t)headingFont->value(); htmlSetBaseSize(fontBaseSize->value(), fontSpacing->value()); HeadFootType = (typeface_t)(headFootFont->value() / 4); HeadFootStyle = (style_t)(headFootFont->value() & 3); HeadFootSize = headFootSize->value(); if (pdf11->value()) PDFVersion = 11; else if (pdf12->value()) PDFVersion = 12; else if (pdf13->value()) PDFVersion = 13; else PDFVersion = 14; PDFPageMode = pageMode->value(); PDFPageLayout = pageLayout->value(); PDFFirstPage = firstPage->value(); PDFEffect = pageEffect->value(); PDFPageDuration = pageDuration->value(); PDFEffectDuration = effectDuration->value(); Links = links->value(); EmbedFonts = embedFonts->value(); PreIndent = get_measurement((char *)preIndent->value()); Encryption = encryptionYes->value(); Permissions = -64; if (permPrint->value()) Permissions |= PDF_PERM_PRINT; if (permModify->value()) Permissions |= PDF_PERM_MODIFY; if (permCopy->value()) Permissions |= PDF_PERM_COPY; if (permAnnotate->value()) Permissions |= PDF_PERM_ANNOTATE; strlcpy(UserPassword, userPassword->value(), sizeof(UserPassword)); strlcpy(OwnerPassword, ownerPassword->value(), sizeof(OwnerPassword)); if (ps1->value()) PSLevel = 1; else if (ps2->value()) PSLevel = 2; else PSLevel = 3; PSCommands = psCommands->value(); XRXComments = xrxComments->value(); strlcpy(BodyColor, bodyColor->value(), sizeof(BodyColor)); strlcpy(BodyImage, bodyImage->value(), sizeof(BodyImage)); htmlSetTextColor((uchar *)textColor->value()); htmlSetCharSet(charset->text(charset->value())); strlcpy(LinkColor, linkColor->value(), sizeof(LinkColor)); LinkStyle = linkStyle->value(); _htmlBrowserWidth = browserWidth->value(); strlcpy(Path, path->value(), sizeof(Path)); strlcpy(Proxy, proxy->value(), sizeof(Proxy)); StrictHTML = strict_html->value(); OverflowErrors = overflow_errors->value(); } // // 'GUI::newBook()' - Clear out the current GUI settings for a new book. // int // O - 1 on success, 0 on failure GUI::newBook(void) { int i; // Looping var char size[255]; // Page size string char formats[256]; // Format characters const char *fmt; // Old format string prefs_load(); switch (OutputType) { case OUTPUT_BOOK : typeBook->setonly(); docTypeCB(typeBook, this); break; case OUTPUT_CONTINUOUS : typeContinuous->setonly(); docTypeCB(typeContinuous, this); break; case OUTPUT_WEBPAGES : typeWebPage->setonly(); docTypeCB(typeWebPage, this); break; } inputFiles->clear(); inputFilesCB(inputFiles, this); logoImage->value(""); titleImage->value(""); outputFile->setonly(); outputTypeCB(outputFile, this); outputPath->value(""); typeHTML->setonly(); outputFormatCB(typeHTML, this); grayscale->value(!OutputColor); titlePage->value(TitlePage); bodyColor->value(BodyColor); bodyImage->value(BodyImage); textColor->value((char *)_htmlTextColor); linkColor->value(LinkColor); linkStyle->value(LinkStyle); if (PageWidth == 595 && PageLength == 842) pageSize->value("A4"); else if (PageWidth == 595 && PageLength == 792) pageSize->value("Universal"); else if (PageWidth == 612 && PageLength == 792) pageSize->value("Letter"); else { snprintf(size, sizeof(size), "%.2fx%.2fin", PageWidth / 72.0f, PageLength / 72.0f); pageSize->value(size); } snprintf(size, sizeof(size), "%.2fin", PageLeft / 72.0f); pageLeft->value(size); snprintf(size, sizeof(size), "%.2fin", PageRight / 72.0f); pageRight->value(size); snprintf(size, sizeof(size), "%.2fin", PageTop / 72.0f); pageTop->value(size); snprintf(size, sizeof(size), "%.2fin", PageBottom / 72.0f); pageBottom->value(size); pageDuplex->value(PageDuplex); landscape->value(Landscape); memset(formats, 0, sizeof(formats)); formats[(int)'t'] = 1; formats[(int)'c'] = 2; formats[(int)'h'] = 3; formats[(int)'L'] = 4; formats[(int)'l'] = 5; formats[(int)'1'] = 6; formats[(int)'i'] = 7; formats[(int)'I'] = 8; formats[(int)'a'] = 9; formats[(int)'A'] = 10; formats[(int)'C'] = 11; formats[(int)'/'] = 12; formats[(int)':'] = 13; formats[(int)'d'] = 14; formats[(int)'T'] = 15; formats[(int)'D'] = 16; fmt = get_fmt(Header); pageHeaderLeft->value(formats[fmt[0]]); pageHeaderCenter->value(formats[fmt[1]]); pageHeaderRight->value(formats[fmt[2]]); fmt = get_fmt(Header1); pageHeader1Left->value(formats[fmt[0]]); pageHeader1Center->value(formats[fmt[1]]); pageHeader1Right->value(formats[fmt[2]]); fmt = get_fmt(Footer); pageFooterLeft->value(formats[fmt[0]]); pageFooterCenter->value(formats[fmt[1]]); pageFooterRight->value(formats[fmt[2]]); if (NumberUp == 1) numberUp->value(0); else if (NumberUp == 2) numberUp->value(1); else if (NumberUp == 4) numberUp->value(2); else if (NumberUp == 6) numberUp->value(3); else if (NumberUp == 9) numberUp->value(4); else if (NumberUp == 16) numberUp->value(5); tocLevels->value(TocLevels); numberedToc->value(TocNumbers); fmt = get_fmt(TocHeader); tocHeaderLeft->value(formats[fmt[0]]); tocHeaderCenter->value(formats[fmt[1]]); tocHeaderRight->value(formats[fmt[2]]); fmt = get_fmt(TocFooter); tocFooterLeft->value(formats[fmt[0]]); tocFooterCenter->value(formats[fmt[1]]); tocFooterRight->value(formats[fmt[2]]); tocTitle->value(TocTitle); headingFont->value(_htmlHeadingFont); bodyFont->value(_htmlBodyFont); headFootFont->value(HeadFootType * 4 + HeadFootStyle); fontBaseSize->value(_htmlSizes[SIZE_P]); fontSpacing->value(_htmlSpacings[SIZE_P] / _htmlSizes[SIZE_P]); headFootSize->value(HeadFootSize); for (i = 0; i < (charset->size() - 1); i ++) if (strcasecmp(_htmlCharSet, charset->text(i)) == 0) { charset->value(i); break; } snprintf(size, sizeof(size), "%.2fin", PreIndent / 72.0f); preIndent->value(size); compression->value(Compression); compGroup->deactivate(); jpegCompress->value(OutputJPEG > 0); jpegQuality->value(OutputJPEG > 0 ? OutputJPEG : 90); jpegGroup->deactivate(); pdfTab->deactivate(); if (PDFVersion < 12) { pdf11->setonly(); pdfCB(pdf11, this); } else if (PDFVersion < 13) { pdf12->setonly(); pdfCB(pdf12, this); } else if (PDFVersion < 14) { pdf13->setonly(); pdfCB(pdf13, this); } else { pdf14->setonly(); pdfCB(pdf14, this); } pageMode->value(PDFPageMode); pageLayout->value(PDFPageLayout); firstPage->value(PDFFirstPage); pageEffect->value(PDFEffect); effectCB(pageEffect, this); pageDuration->value(PDFPageDuration); effectDuration->value(PDFEffectDuration); links->value(Links); embedFonts->value(EmbedFonts); securityTab->deactivate(); if (Encryption) { encryptionYes->setonly(); encryptionCB(encryptionYes, this); } else { encryptionNo->setonly(); encryptionCB(encryptionNo, this); } if (Permissions & PDF_PERM_PRINT) permPrint->set(); else permPrint->clear(); if (Permissions & PDF_PERM_MODIFY) permModify->set(); else permModify->clear(); if (Permissions & PDF_PERM_COPY) permCopy->set(); else permCopy->clear(); if (Permissions & PDF_PERM_ANNOTATE) permAnnotate->set(); else permAnnotate->clear(); ownerPassword->value(OwnerPassword); userPassword->value(UserPassword); if (PSLevel == 1) ps1->setonly(); else if (PSLevel == 2) ps2->setonly(); else ps3->setonly(); if (PSLevel == 1) psCommands->deactivate(); else psCommands->activate(); psCommands->value(PSCommands); xrxComments->value(XRXComments); path->value(Path); proxy->value(Proxy); browserWidth->value(_htmlBrowserWidth); strict_html->value(StrictHTML); overflow_errors->value(OverflowErrors); title(NULL, 0); return (1); } // // 'GUI::loadBook()' - Load a book file from disk. // int // O - 1 = success, 0 = fail GUI::loadBook(const char *filename) // I - Name of book file { FILE *fp; // File to read from char line[10240]; // Line from file const char *dir; // Directory char basename[1024]; // Base filename // If the filename contains a path, chdir to it first... if ((dir = file_directory(filename)) != NULL) { /* * Filename contains a complete path - get the directory portion and do * a chdir()... */ strlcpy(basename, file_basename(filename), sizeof(basename)); filename = basename; chdir(dir); fc->directory("."); } // Open the file... fp = fopen(filename, "r"); if (fp == NULL) { fl_alert("Unable to open \"%s\"!", filename); return (0); } // Get the header... file_gets(line, sizeof(line), fp); if (strncmp(line, "#HTMLDOC", 8) != 0) { fclose(fp); fl_alert("Bad or missing #HTMLDOC header:\n%-80.80s", line); return (0); } // Reset the GUI... if (!newBook()) { fclose(fp); return (0); } // Read the second line from the book file; for older book files, this will // be the file count; for new files this will be the options... do { file_gets(line, sizeof(line), fp); if (line[0] == '-') parseOptions(line); } while (!line[0]); // Skip blank lines... // Get input files/options... while (file_gets(line, sizeof(line), fp) != NULL) { if (line[0] == '\0') continue; // Skip blank lines else if (line[0] == '-') parseOptions(line); else if (line[0] == '\\') inputFiles->add(line + 1, icon); else inputFiles->add(line, icon); } // Close the book file and update the GUI... fclose(fp); inputFiles->topline(1); title(filename, 0); return (1); } // // 'GUI::parseOptions()' - Parse options in a book file... // void GUI::parseOptions(const char *line) // I - Line from file { int i; // Looping var const char *lineptr; // Pointer into line char temp[1024], // Option name temp2[1024], // Option value *tempptr, // Pointer into option formats[256]; // Header/footer formats static const char *types[] = // Typeface names... { "Courier", "Times", "Helvetica", "Monospace", "Serif", "Sans" }; static const char *fonts[] = // Font names... { "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique", "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic", "Helvetica", "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-BoldOblique", "Monospace", "Monospace-Bold", "Monospace-Oblique", "Monospace-BoldOblique", "Serif-Roman", "Serif-Bold", "Serif-Oblique", "Serif-BoldOblique", "Sans", "Sans-Bold", "Sans-Oblique", "Sans-BoldOblique" }; // Initialize the format character lookup table... memset(formats, 0, sizeof(formats)); formats[(int)'t'] = 1; formats[(int)'c'] = 2; formats[(int)'h'] = 3; formats[(int)'L'] = 4; formats[(int)'l'] = 5; formats[(int)'1'] = 6; formats[(int)'i'] = 7; formats[(int)'I'] = 8; formats[(int)'a'] = 9; formats[(int)'A'] = 10; formats[(int)'C'] = 11; formats[(int)'/'] = 12; formats[(int)':'] = 13; formats[(int)'d'] = 14; formats[(int)'T'] = 15; formats[(int)'D'] = 16; // Parse the input line... for (lineptr = line; *lineptr != '\0';) { while (*lineptr == ' ') lineptr ++; for (tempptr = temp; *lineptr != '\0' && *lineptr != ' ';) *tempptr++ = *lineptr++; *tempptr = '\0'; while (*lineptr == ' ') lineptr ++; if (strcmp(temp, "--duplex") == 0) { pageDuplex->set(); continue; } else if (strcmp(temp, "--landscape") == 0) { landscape->set(); continue; } else if (strcmp(temp, "--portrait") == 0) { landscape->clear(); continue; } else if (strncmp(temp, "--jpeg", 6) == 0) { if (strlen(temp) > 7) jpegQuality->value(atof(temp + 7)); else jpegQuality->value(90.0); if (jpegQuality->value() > 0.0) { jpegCompress->set(); jpegGroup->activate(); } else { jpegCompress->clear(); jpegGroup->deactivate(); } continue; } else if (strcmp(temp, "--grayscale") == 0) { grayscale->set(); continue; } else if (strcmp(temp, "--color") == 0) { grayscale->clear(); continue; } else if (strcmp(temp, "--links") == 0) { links->set(); continue; } else if (strcmp(temp, "--no-links") == 0) { links->clear(); continue; } else if (strcmp(temp, "--truetype") == 0 || strcmp(temp, "--embedfonts") == 0) { embedFonts->set(); continue; } else if (strcmp(temp, "--no-truetype") == 0 || strcmp(temp, "--no-embedfonts") == 0) { embedFonts->clear(); continue; } else if (strcmp(temp, "--pscommands") == 0) { psCommands->set(); continue; } else if (strcmp(temp, "--no-pscommands") == 0) { psCommands->clear(); continue; } else if (strcmp(temp, "--xrxcomments") == 0) { xrxComments->set(); continue; } else if (strcmp(temp, "--no-xrxcomments") == 0) { xrxComments->clear(); continue; } else if (strncmp(temp, "--compression", 13) == 0) { if (strlen(temp) > 14) compression->value(atof(temp + 14)); else compression->value(1.0); continue; } else if (strcmp(temp, "--no-compression") == 0) { compression->value(0.0); continue; } else if (strcmp(temp, "--no-jpeg") == 0) { jpegCompress->clear(); jpegGroup->deactivate(); continue; } else if (strcmp(temp, "--numbered") == 0) { numberedToc->set(); continue; } else if (strcmp(temp, "--no-numbered") == 0) { numberedToc->clear(); continue; } else if (strcmp(temp, "--no-toc") == 0) { tocLevels->value(0); continue; } else if (strcmp(temp, "--title") == 0) { titlePage->set(); continue; } else if (strcmp(temp, "--no-title") == 0) { titlePage->clear(); continue; } else if (strcmp(temp, "--strict") == 0) { strict_html->set(); continue; } else if (strcmp(temp, "--no-strict") == 0) { strict_html->clear(); continue; } else if (strcmp(temp, "--overflow") == 0) { overflow_errors->set(); continue; } else if (strcmp(temp, "--no-overflow") == 0) { overflow_errors->clear(); continue; } else if (strcmp(temp, "--book") == 0) { typeBook->setonly(); docTypeCB(typeBook, this); continue; } else if (strcmp(temp, "--continuous") == 0) { typeContinuous->setonly(); docTypeCB(typeContinuous, this); continue; } else if (strcmp(temp, "--webpage") == 0) { typeWebPage->setonly(); docTypeCB(typeWebPage, this); continue; } else if (strcmp(temp, "--encryption") == 0) { encryptionYes->setonly(); encryptionCB(encryptionYes, this); continue; } else if (strcmp(temp, "--no-encryption") == 0) { encryptionNo->setonly(); encryptionCB(encryptionNo, this); continue; } else if (temp[0] != '-') { inputFiles->add(temp, icon); continue; } if (*lineptr == '\"') { lineptr ++; for (tempptr = temp2; *lineptr != '\0' && *lineptr != '\"';) *tempptr++ = *lineptr++; if (*lineptr == '\"') lineptr ++; } else { for (tempptr = temp2; *lineptr != '\0' && *lineptr != ' ';) *tempptr++ = *lineptr++; } *tempptr = '\0'; if (strcmp(temp, "-t") == 0) { if (strcmp(temp2, "epub") == 0) { typeEPUB->setonly(); outputFormatCB(typeEPUB, this); } else if (strcmp(temp2, "html") == 0) { typeHTML->setonly(); outputFormatCB(typeHTML, this); } else if (strcmp(temp2, "htmlsep") == 0) { typeHTMLSep->setonly(); outputFormatCB(typeHTMLSep, this); } else if (strcmp(temp2, "ps1") == 0) { typePS->setonly(); ps1->setonly(); outputFormatCB(typePS, this); psCB(ps1, this); } else if (strcmp(temp2, "ps") == 0 || strcmp(temp2, "ps2") == 0) { typePS->setonly(); ps2->setonly(); outputFormatCB(typePS, this); psCB(ps2, this); } else if (strcmp(temp2, "ps3") == 0) { typePS->setonly(); ps3->setonly(); outputFormatCB(typePS, this); psCB(ps3, this); } else if (strcmp(temp2, "pdf11") == 0) { typePDF->setonly(); pdf11->setonly(); outputFormatCB(typePDF, this); pdfCB(pdf11, this); } else if (strcmp(temp2, "pdf12") == 0) { typePDF->setonly(); pdf12->setonly(); outputFormatCB(typePDF, this); pdfCB(pdf12, this); } else if (strcmp(temp2, "pdf") == 0 || strcmp(temp2, "pdf13") == 0) { typePDF->setonly(); pdf13->setonly(); outputFormatCB(typePDF, this); pdfCB(pdf13, this); } else if (strcmp(temp2, "pdf14") == 0) { typePDF->setonly(); pdf14->setonly(); outputFormatCB(typePDF, this); pdfCB(pdf14, this); } } else if (strcmp(temp, "--letterhead") == 0) lhImage->value(temp2); else if (strcmp(temp, "--logo") == 0 || strcmp(temp, "--logoimage") == 0) logoImage->value(temp2); else if (strcmp(temp, "--titlefile") == 0 || strcmp(temp, "--titleimage") == 0) { titlePage->set(); titleImage->value(temp2); } else if (strcmp(temp, "-f") == 0) { outputPath->value(temp2); outputFile->setonly(); outputTypeCB(outputFile, this); } else if (strcmp(temp, "-d") == 0) { outputPath->value(temp2); outputDirectory->setonly(); outputTypeCB(outputDirectory, this); } else if (strcmp(temp, "--browserwidth") == 0) browserWidth->value(atof(temp2)); else if (strcmp(temp, "--size") == 0) pageSize->value(temp2); else if (strcmp(temp, "--left") == 0) pageLeft->value(temp2); else if (strcmp(temp, "--right") == 0) pageRight->value(temp2); else if (strcmp(temp, "--top") == 0) pageTop->value(temp2); else if (strcmp(temp, "--bottom") == 0) pageBottom->value(temp2); else if (strcmp(temp, "--header") == 0) { pageHeaderLeft->value(formats[temp2[0]]); pageHeaderCenter->value(formats[temp2[1]]); pageHeaderRight->value(formats[temp2[2]]); } else if (strcmp(temp, "--header1") == 0) { pageHeader1Left->value(formats[temp2[0]]); pageHeader1Center->value(formats[temp2[1]]); pageHeader1Right->value(formats[temp2[2]]); } else if (strcmp(temp, "--footer") == 0) { pageFooterLeft->value(formats[temp2[0]]); pageFooterCenter->value(formats[temp2[1]]); pageFooterRight->value(formats[temp2[2]]); } else if (strcmp(temp, "--nup") == 0) { i = atoi(temp2); if (i == 1) numberUp->value(0); else if (i == 2) numberUp->value(1); else if (i == 4) numberUp->value(2); else if (i == 6) numberUp->value(3); else if (i == 9) numberUp->value(4); else if (i == 16) numberUp->value(5); } else if (strcmp(temp, "--bodycolor") == 0) bodyColor->value(temp2); else if (strcmp(temp, "--bodyimage") == 0) bodyImage->value(temp2); else if (strcmp(temp, "--textcolor") == 0) textColor->value(temp2); else if (strcmp(temp, "--linkcolor") == 0) linkColor->value(temp2); else if (strcmp(temp, "--linkstyle") == 0) { if (strcmp(temp2, "plain") == 0) linkStyle->value(0); else linkStyle->value(1); } else if (strcmp(temp, "--toclevels") == 0) tocLevels->value(atoi(temp2)); else if (strcmp(temp, "--tocheader") == 0) { tocHeaderLeft->value(formats[temp2[0]]); tocHeaderCenter->value(formats[temp2[1]]); tocHeaderRight->value(formats[temp2[2]]); } else if (strcmp(temp, "--tocfooter") == 0) { tocFooterLeft->value(formats[temp2[0]]); tocFooterCenter->value(formats[temp2[1]]); tocFooterRight->value(formats[temp2[2]]); } else if (strcmp(temp, "--toctitle") == 0) tocTitle->value(temp2); else if (strcmp(temp, "--fontsize") == 0) fontBaseSize->value(atof(temp2)); else if (strcmp(temp, "--fontspacing") == 0) fontSpacing->value(atof(temp2)); else if (strcmp(temp, "--headingfont") == 0) { for (i = 0; i < (int)(sizeof(types) / sizeof(types[0])); i ++) if (strcasecmp(types[i], temp2) == 0) { headingFont->value(i); break; } } else if (strcmp(temp, "--bodyfont") == 0) { for (i = 0; i < (int)(sizeof(types) / sizeof(types[0])); i ++) if (strcasecmp(types[i], temp2) == 0) { bodyFont->value(i); break; } } else if (strcmp(temp, "--headfootsize") == 0) headFootSize->value(atof(temp2)); else if (strcmp(temp, "--headfootfont") == 0) { for (i = 0; i < (int)(sizeof(fonts) / sizeof(fonts[0])); i ++) if (strcasecmp(fonts[i], temp2) == 0) { headFootFont->value(i); break; } } else if (strcmp(temp, "--charset") == 0) { for (i = 0; i < (charset->size() - 1); i ++) if (strcasecmp(temp2, charset->text(i)) == 0) { charset->value(i); break; } } else if (strcmp(temp, "--pre-indent") == 0) preIndent->value(temp2); else if (strcmp(temp, "--pagemode") == 0) { for (i = 0; i < (int)(sizeof(PDFModes) / sizeof(PDFModes[0])); i ++) if (strcasecmp(temp2, PDFModes[i]) == 0) { pageMode->value(i); break; } } else if (strcmp(temp, "--pagelayout") == 0) { for (i = 0; i < (int)(sizeof(PDFLayouts) / sizeof(PDFLayouts[0])); i ++) if (strcasecmp(temp2, PDFLayouts[i]) == 0) { pageLayout->value(i); break; } } else if (strcmp(temp, "--firstpage") == 0) { for (i = 0; i < (int)(sizeof(PDFPages) / sizeof(PDFPages[0])); i ++) if (strcasecmp(temp2, PDFPages[i]) == 0) { firstPage->value(i); break; } } else if (strcmp(temp, "--pageeffect") == 0) { for (i = 0; i < (int)(sizeof(PDFEffects) / sizeof(PDFEffects[0])); i ++) if (strcasecmp(temp2, PDFEffects[i]) == 0) { pageEffect->value(i); effectCB(pageEffect, this); break; } } else if (strcmp(temp, "--pageduration") == 0) pageDuration->value(atof(temp2)); else if (strcmp(temp, "--effectduration") == 0) effectDuration->value(atof(temp2)); else if (strcmp(temp, "--permissions") == 0) { if (strcmp(temp2, "all") == 0) { permPrint->set(); permModify->set(); permCopy->set(); permAnnotate->set(); } else if (strcmp(temp2, "none") == 0) { permPrint->clear(); permModify->clear(); permCopy->clear(); permAnnotate->clear(); } else if (strcmp(temp2, "print") == 0) permPrint->set(); else if (strcmp(temp2, "no-print") == 0) permPrint->clear(); else if (strcmp(temp2, "modify") == 0) permModify->set(); else if (strcmp(temp2, "no-modify") == 0) permModify->clear(); else if (strcmp(temp2, "copy") == 0) permCopy->set(); else if (strcmp(temp2, "no-copy") == 0) permCopy->clear(); else if (strcmp(temp2, "annotate") == 0) permAnnotate->set(); else if (strcmp(temp2, "no-annotate") == 0) permAnnotate->clear(); } else if (strcmp(temp, "--user-password") == 0) userPassword->value(temp2); else if (strcmp(temp, "--owner-password") == 0) ownerPassword->value(temp2); else if (strcmp(temp, "--path") == 0) path->value(temp2); else if (strcmp(temp, "--proxy") == 0) proxy->value(temp2); } } #ifdef __APPLE__ // // 'GUI::appleOpenCB()' - Handle open file events from Finder. // void GUI::appleOpenCB(const char *f) // I - Book file to open { // Save the filename if the book GUI hasn't been initialized... if (!BookGUI) { apple_filename = strdup(f); return; } // See if the user wants to save the current book... if (!BookGUI->checkSave()) return; // Load the new book... BookGUI->loadBook(f); } #endif // __APPLE__ // // 'GUI::saveBook()' - Save a book to disk. // int // O - 1 = success, 0 = fail GUI::saveBook(const char *filename) // I - Name of book file { int i, // Looping var count; // Number of files FILE *fp; // Book file pointer static const char *formats = ".tchl1iIaAC/:dTD"; // Format characters static const char *types[] = // Typeface names... { "Courier", "Times", "Helvetica", "Monospace", "Serif", "Sans" }; static const char *fonts[] = // Font names... { "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique", "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic", "Helvetica", "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-BoldOblique", "Monospace", "Monospace-Bold", "Monospace-Oblique", "Monospace-BoldOblique", "Serif-Roman", "Serif-Bold", "Serif-Oblique", "Serif-BoldOblique", "Sans", "Sans-Bold", "Sans-Oblique", "Sans-BoldOblique" }; // Open the book file... fp = fopen(filename, "w"); if (fp == NULL) { fl_alert("Unable to create \"%s\"!", filename); return (0); } // Write the standard header... fputs("#HTMLDOC " SVERSION "\n", fp); // Write the options... if (typeEPUB->value()) fputs("-t epub", fp); else if (typeHTML->value()) fputs("-t html", fp); else if (typeHTMLSep->value()) fputs("-t htmlsep", fp); else if (typePS->value()) { if (ps1->value()) fputs("-t ps1", fp); else if (ps2->value()) fputs("-t ps2", fp); else if (ps3->value()) fputs("-t ps3", fp); } else if (pdf11->value()) fputs("-t pdf11", fp); else if (pdf12->value()) fputs("-t pdf12", fp); else if (pdf13->value()) fputs("-t pdf13", fp); else fputs("-t pdf14", fp); if (outputFile->value()) fprintf(fp, " -f \"%s\"", outputPath->value()); else fprintf(fp, " -d \"%s\"", outputPath->value()); if (typeWebPage->value()) fputs(" --webpage", fp); else if (typeContinuous->value()) fputs(" --continuous", fp); else { fputs(" --book", fp); if (tocLevels->value() == 0) fputs(" --no-toc", fp); else fprintf(fp, " --toclevels %d", tocLevels->value()); if (numberedToc->value()) fputs(" --numbered", fp); else fputs(" --no-numbered", fp); fprintf(fp, " --toctitle \"%s\"", tocTitle->value()); } if (titlePage->value()) { fputs(" --title", fp); if (titleImage->size() > 0) fprintf(fp, " --titleimage \"%s\"", titleImage->value()); } else fputs(" --no-title", fp); if (lhImage->size() > 0) fprintf(fp, " --letterhead \"%s\"", lhImage->value()); if (logoImage->size() > 0) fprintf(fp, " --logoimage \"%s\"", logoImage->value()); if (textColor->size() > 0) fprintf(fp, " --textcolor %s", textColor->value()); if (linkColor->size() > 0) fprintf(fp, " --linkcolor %s", linkColor->value()); if (linkStyle->value()) fputs(" --linkstyle underline", fp); else fputs(" --linkstyle plain", fp); if (bodyColor->size() > 0) fprintf(fp, " --bodycolor %s", bodyColor->value()); if (bodyImage->size() > 0) fprintf(fp, " --bodyimage %s", bodyImage->value()); if (!typeEPUB->value() && !typeHTML->value() && !typeHTMLSep->value()) { if (pageSize->size() > 0) fprintf(fp, " --size %s", pageSize->value()); if (pageLeft->size() > 0) fprintf(fp, " --left %s", pageLeft->value()); if (pageRight->size() > 0) fprintf(fp, " --right %s", pageRight->value()); if (pageTop->size() > 0) fprintf(fp, " --top %s", pageTop->value()); if (pageBottom->size() > 0) fprintf(fp, " --bottom %s", pageBottom->value()); fprintf(fp, " --header %c%c%c", formats[pageHeaderLeft->value()], formats[pageHeaderCenter->value()], formats[pageHeaderRight->value()]); fprintf(fp, " --header1 %c%c%c", formats[pageHeader1Left->value()], formats[pageHeader1Center->value()], formats[pageHeader1Right->value()]); fprintf(fp, " --footer %c%c%c", formats[pageFooterLeft->value()], formats[pageFooterCenter->value()], formats[pageFooterRight->value()]); fprintf(fp, " --nup %s", numberUp->text(numberUp->value())); fprintf(fp, " --tocheader %c%c%c", formats[tocHeaderLeft->value()], formats[tocHeaderCenter->value()], formats[tocHeaderRight->value()]); fprintf(fp, " --tocfooter %c%c%c", formats[tocFooterLeft->value()], formats[tocFooterCenter->value()], formats[tocFooterRight->value()]); if (pageDuplex->value()) fputs(" --duplex", fp); if (landscape->value()) fputs(" --landscape", fp); else fputs(" --portrait", fp); if (grayscale->value()) fputs(" --grayscale", fp); else fputs(" --color", fp); if (psCommands->value()) fputs(" --pscommands", fp); else fputs(" --no-pscommands", fp); if (xrxComments->value()) fputs(" --xrxcomments", fp); else fputs(" --no-xrxcomments", fp); if (compression->value() == 0.0f) fputs(" --no-compression", fp); else fprintf(fp, " --compression=%.0f", compression->value()); if (jpegCompress->value()) fprintf(fp, " --jpeg=%.0f", jpegQuality->value()); else fputs(" --jpeg=0", fp); } fprintf(fp, " --fontsize %.1f", fontBaseSize->value()); fprintf(fp, " --fontspacing %.1f", fontSpacing->value()); fprintf(fp, " --headingfont %s", types[headingFont->value()]); fprintf(fp, " --bodyfont %s", types[bodyFont->value()]); fprintf(fp, " --headfootsize %.1f", headFootSize->value()); fprintf(fp, " --headfootfont %s", fonts[headFootFont->value()]); fprintf(fp, " --charset %s", charset->text(charset->value())); if (pageLeft->size() > 0) fprintf(fp, " --pre-indent %s", preIndent->value()); if (typePDF->value()) { if (links->value()) fputs(" --links", fp); else fputs(" --no-links", fp); if (embedFonts->value()) fputs(" --embedfonts", fp); else fputs(" --no-embedfonts", fp); fprintf(fp, " --pagemode %s", PDFModes[pageMode->value()]); fprintf(fp, " --pagelayout %s", PDFLayouts[pageLayout->value()]); fprintf(fp, " --firstpage %s", PDFPages[firstPage->value()]); fprintf(fp, " --pageeffect %s", PDFEffects[pageEffect->value()]); fprintf(fp, " --pageduration %.0f", pageDuration->value()); fprintf(fp, " --effectduration %.1f", effectDuration->value()); fprintf(fp, " --%sencryption", encryptionYes->value() ? "" : "no-"); if (permPrint->value() && permModify->value() && permCopy->value() && permAnnotate->value()) fputs(" --permissions all", fp); else if (permPrint->value() || permModify->value() || permCopy->value() || permAnnotate->value()) { if (permPrint->value()) fputs(" --permissions print", fp); else fputs(" --permissions no-print", fp); if (permModify->value()) fputs(" --permissions modify", fp); else fputs(" --permissions no-modify", fp); if (permCopy->value()) fputs(" --permissions copy", fp); else fputs(" --permissions no-copy", fp); if (permAnnotate->value()) fputs(" --permissions annotate", fp); else fputs(" --permissions no-annotate", fp); } else fputs(" --permissions none", fp); fprintf(fp, " --owner-password \"%s\"", ownerPassword->value()); fprintf(fp, " --user-password \"%s\"", userPassword->value()); } fprintf(fp, " --browserwidth %.0f", browserWidth->value()); if (path->value()[0]) fprintf(fp, " --path \"%s\"", path->value()); if (proxy->value()[0]) fprintf(fp, " --proxy \"%s\"", proxy->value()); if (strict_html->value()) fputs(" --strict", fp); else fputs(" --no-strict", fp); if (overflow_errors->value()) fputs(" --overflow", fp); else fputs(" --no-overflow", fp); fputs("\n", fp); // Output the files... count = inputFiles->size(); for (i = 1; i <= count; i ++) if (inputFiles->text(i)[0] == '-') fprintf(fp, "\\%s\n", inputFiles->text(i)); else fprintf(fp, "%s\n", inputFiles->text(i)); // Close the file and update the GUI... fclose(fp); title(filename, 0); return (1); } // // 'GUI::checkSave()' - Check to see if a save is needed. // int // O - 1 if no save is needed, 0 if save is needed GUI::checkSave(void) { if (book_changed) { switch (fl_choice("The current book has been changed.\n" "Do you wish to save it first?", "Cancel", "Save", "Discard")) { case 0 : /* Cancel */ return (0); case 1 : /* Save */ if (book_filename[0] != '\0') return (saveBook(book_filename)); else { saveAsBookCB(NULL, this); return (!book_changed); } case 2 : /* Discard */ return (1); } } return (1); } // // 'GUI::changeCB()' - Mark the current book as changed. // void GUI::changeCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { REF(w); gui->title(gui->book_filename, 1); } // // 'GUI::docTypeCB()' - Handle input on the document type buttons. // void GUI::docTypeCB(Fl_Widget *w, // I - Toggle button widget GUI *gui) // I - GUI { gui->title(gui->book_filename, 1); if (w == gui->typeBook) { gui->typeEPUB->activate(); gui->typeHTML->activate(); gui->typeHTMLSep->activate(); gui->titlePage->value(1); gui->tocTab->activate(); gui->tocLevels->value(3); gui->firstPage->activate(); gui->pageMode->value(1); } else { gui->typeEPUB->deactivate(); gui->typeHTML->deactivate(); gui->typeHTMLSep->deactivate(); if (gui->typeEPUB->value() || gui->typeHTML->value() || gui->typeHTMLSep->value()) { gui->typePDF->setonly(); outputFormatCB(gui->typePDF, gui); } gui->titlePage->value(0); gui->tocTab->deactivate(); gui->firstPage->value(0); gui->firstPage->deactivate(); gui->pageMode->value(0); } } // // 'GUI::inputFilesCB()' - Handle selections in the input files browser. // void GUI::inputFilesCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { int i, // Looping var num_items; // Number of items in the file list REF(w); num_items = gui->inputFiles->size(); for (i = 1; i <= num_items; i ++) if (gui->inputFiles->selected(i)) break; if (i <= num_items) { gui->editFile->activate(); gui->deleteFile->activate(); } else { gui->editFile->deactivate(); gui->deleteFile->deactivate(); } if (gui->inputFiles->selected(1) || num_items == 0) gui->moveUpFile->deactivate(); else gui->moveUpFile->activate(); if (gui->inputFiles->selected(num_items) || num_items == 0) gui->moveDownFile->deactivate(); else gui->moveDownFile->activate(); if (Fl::event_clicks() && i <= num_items) editFilesCB(gui->editFile, gui); } // // 'GUI::addFileCB()' - Add a file to the input files list. // void GUI::addFileCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { int i; // Looping var REF(w); gui->fc->filter("WWW Files (*.{htm,html,md,shtml,book})"); gui->fc->type(Fl_File_Chooser::MULTI); gui->fc->label("Add Input Files"); gui->fc->show(); while (gui->fc->shown()) Fl::wait(); if (gui->fc->count()) { for (i = 1; i <= gui->fc->count(); i ++) { if (strcasecmp(file_extension(gui->fc->value(i)), "book") == 0) { // Import files from the book... FILE *fp; char line[1024]; char directory[1024]; int count; getcwd(directory, sizeof(directory)); chdir(file_directory(gui->fc->value(i))); if ((fp = fopen(gui->fc->value(i), "rb")) == NULL) { fl_alert("Unable to import %s:\n%s", gui->fc->value(i), strerror(errno)); chdir(directory); continue; } if (fgets(line, sizeof(line), fp) == NULL) { fl_alert("Unable to import %s:\nShort file.", gui->fc->value(i)); fclose(fp); chdir(directory); continue; } if (strncmp(line, "#HTMLDOC", 8) != 0) { fl_alert("Unable to import %s:\nBad header line.", gui->fc->value(i)); fclose(fp); chdir(directory); continue; } if (fgets(line, sizeof(line), fp) == NULL) { fl_alert("Unable to import %s:\nNo file count.", gui->fc->value(i)); fclose(fp); chdir(directory); continue; } count = atoi(line); while (count > 0) { count --; if (fgets(line, sizeof(line), fp) == NULL) { fl_alert("Unable to import %s:\nMissing file.", gui->fc->value(i)); break; } line[strlen(line) - 1] = '\0'; // strip newline gui->inputFiles->add(file_localize(line, directory), gui->icon); } fclose(fp); chdir(directory); } else gui->inputFiles->add(file_localize(gui->fc->value(i), NULL), gui->icon); } gui->title(gui->book_filename, 1); } } // // 'GUI::addURLCB()' - Add a URL to the input files list. // void GUI::addURLCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { const char *url; // New URL to add REF(w); if ((url = fl_input("URL?", "http://")) != NULL) { gui->inputFiles->add(url, gui->icon); gui->title(gui->book_filename, 1); } } // // 'GUI::editFilesCB()' - Edit one or more files in the input files list. // void GUI::editFilesCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { int i, // Looping var num_items; // Number of items in the file list char command[1024]; // Editor command #ifdef WIN32 STARTUPINFO suInfo; // Process startup information PROCESS_INFORMATION prInfo; // Process information #endif // WIN32 REF(w); num_items = gui->inputFiles->size(); for (i = 1; i <= num_items; i ++) if (gui->inputFiles->selected(i)) { snprintf(command, sizeof(command), gui->htmlEditor->value(), gui->inputFiles->text(i)); #ifdef WIN32 memset(&suInfo, 0, sizeof(suInfo)); suInfo.cb = sizeof(suInfo); if (!CreateProcess(NULL, command, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &suInfo, &prInfo)) fl_alert("Unable to start editor!"); #else strlcat(command, "&", sizeof(command)); if (system(command)) fl_alert("Unable to start editor!"); #endif // !WIN32 } } // // 'GUI::deleteFileCB()' - Delete one or more files from the input files list. // void GUI::deleteFilesCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { int i, // Looping var num_items; // Number of items in the file list REF(w); num_items = gui->inputFiles->size(); for (i = num_items; i > 0; i --) if (gui->inputFiles->selected(i)) { gui->inputFiles->select(i, 0); gui->inputFiles->remove(i); gui->title(gui->book_filename, 1); } } // // 'GUI::moveUpFileCB()' - Move one or more files up in the input files list. // void GUI::moveUpFilesCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { int i, // Looping var num_items; // Number of items in the file list char *file; // File to move up REF(w); num_items = gui->inputFiles->size(); for (i = 1; i <= num_items; i ++) if (gui->inputFiles->selected(i)) { file = (char *)gui->inputFiles->text(i); gui->inputFiles->insert(i - 1, file, gui->icon); gui->inputFiles->select(i - 1); gui->inputFiles->remove(i + 1); gui->inputFiles->select(i, 0); gui->title(gui->book_filename, 1); } for (i = 1; i <= num_items; i ++) if (gui->inputFiles->selected(i)) break; gui->inputFiles->make_visible(i); if (gui->inputFiles->selected(1)) gui->moveUpFile->deactivate(); if (!gui->inputFiles->selected(num_items)) gui->moveDownFile->activate(); } // // 'GUI::moveDownFileCB()' - Move one or more files down in the input files list. // void GUI::moveDownFilesCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { int i, // Looping var num_items; // Number of items in the file list char *file; // File to move down REF(w); num_items = gui->inputFiles->size(); for (i = num_items; i > 0; i --) if (gui->inputFiles->selected(i)) { file = (char *)gui->inputFiles->text(i); gui->inputFiles->insert(i + 2, file, gui->icon); gui->inputFiles->select(i + 2); gui->inputFiles->remove(i); gui->inputFiles->select(i, 0); gui->title(gui->book_filename, 1); } for (i = num_items; i >= 1; i --) if (gui->inputFiles->selected(i)) break; gui->inputFiles->make_visible(i); if (!gui->inputFiles->selected(1)) gui->moveUpFile->activate(); if (gui->inputFiles->selected(num_items)) gui->moveDownFile->deactivate(); } // // 'GUI::lhImageCB()' - Change the letterhead image file. // void GUI::lhImageCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { if (w == gui->lhBrowse) { gui->fc->filter("Image Files (*.{bmp,gif,jpg,png})"); gui->fc->label("Letterhead Image?"); gui->fc->type(Fl_File_Chooser::SINGLE); gui->fc->show(); while (gui->fc->shown()) Fl::wait(); if (gui->fc->count()) { gui->lhImage->value(file_localize(gui->fc->value(), NULL)); gui->title(gui->book_filename, 1); } } else gui->title(gui->book_filename, 1); } // // 'GUI::logoImageCB()' - Change the logo image file. // void GUI::logoImageCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { if (w == gui->logoBrowse) { gui->fc->filter("Image Files (*.{bmp,gif,jpg,png})"); gui->fc->label("Logo Image?"); gui->fc->type(Fl_File_Chooser::SINGLE); gui->fc->show(); while (gui->fc->shown()) Fl::wait(); if (gui->fc->count()) { gui->logoImage->value(file_localize(gui->fc->value(), NULL)); gui->title(gui->book_filename, 1); } } else gui->title(gui->book_filename, 1); } // // 'GUI::titleImageCB()' - Change the title image file. // void GUI::titleImageCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { if (w == gui->titleBrowse) { gui->fc->filter("Image Files (*.{bmp,gif,jpg,png})\tWWW Files (*.{htm,html,md,shtml})"); gui->fc->label("Title Image?"); gui->fc->type(Fl_File_Chooser::SINGLE); gui->fc->show(); while (gui->fc->shown()) Fl::wait(); if (gui->fc->count()) { gui->titleImage->value(file_localize(gui->fc->value(), NULL)); gui->title(gui->book_filename, 1); } } else gui->title(gui->book_filename, 1); } // // 'GUI::outputTypeCB()' - Set the output file type. // void GUI::outputTypeCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { if (w == gui->outputFile) { gui->outputBrowse->activate(); gui->typePDF->activate(); } else if (gui->typePDF->value()) gui->outputFile->setonly(); else { gui->outputBrowse->deactivate(); gui->typePDF->deactivate(); } gui->title(gui->book_filename, 1); } // // 'GUI::outputPathCB()' - Set the output path. // void GUI::outputPathCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { char filename[1024]; // Name of the output file const char *extension; // Extension of the output file if (w == gui->outputBrowse) { gui->fc->label("Output Path?"); if (gui->outputFile->value()) { gui->fc->type(Fl_File_Chooser::CREATE); if (gui->typeEPUB->value()) gui->fc->filter("EPUB Files (*.epub)"); else if (gui->typeHTML->value() || gui->typeHTMLSep->value()) gui->fc->filter("WWW Files (*.htm*)"); else if (gui->typePDF->value()) gui->fc->filter("PDF Files (*.pdf)"); else gui->fc->filter("PostScript Files (*.ps)"); } else { gui->fc->type(Fl_File_Chooser::DIRECTORY | Fl_File_Chooser::CREATE); gui->fc->filter("*"); } gui->fc->show(); while (gui->fc->shown()) Fl::wait(); if (gui->fc->count()) { // Get the selected file... strlcpy(filename, file_localize(gui->fc->value(), NULL), sizeof(filename)); extension = file_extension(filename); if (extension[0]) { // Have an extension - check it! if (strcasecmp(extension, "PS") == 0) { gui->typePS->setonly(); outputFormatCB(gui->typePS, gui); } else if (strcasecmp(extension, "PDF") == 0) { gui->typePDF->setonly(); outputFormatCB(gui->typePDF, gui); } } else if (gui->outputFile->value()) { // No extension - add one! if (gui->typeEPUB->value()) strlcat(filename, ".epub", sizeof(filename)); else if (gui->typeHTML->value() || gui->typeHTMLSep->value()) strlcat(filename, ".html", sizeof(filename)); else if (gui->typePS->value()) strlcat(filename, ".ps", sizeof(filename)); else strlcat(filename, ".pdf", sizeof(filename)); } gui->outputPath->value(filename); gui->title(gui->book_filename, 1); } } else gui->title(gui->book_filename, 1); } // // 'GUI::outputFormatCB()' - Set the output format. // void GUI::outputFormatCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { char filename[1024], // Output filename *ptr; // Pointer to extension const char *ext = NULL; // Extension gui->title(gui->book_filename, 1); if (w == gui->typePDF) { gui->pdfTab->activate(); gui->securityTab->activate(); gui->outputDirectory->deactivate(); gui->outputFile->setonly(); ext = ".pdf"; } else { gui->pdfTab->deactivate(); gui->securityTab->deactivate(); gui->outputDirectory->activate(); } if (w == gui->typeHTMLSep) { gui->outputFile->deactivate(); gui->outputDirectory->setonly(); } else gui->outputFile->activate(); if (w == gui->typeEPUB || w == gui->typeHTML || w == gui->typeHTMLSep) { gui->compression->value(0); gui->jpegCompress->value(0); gui->jpegCompress->deactivate(); gui->jpegGroup->deactivate(); gui->grayscale->value(0); gui->grayscale->deactivate(); gui->pageTab->deactivate(); gui->tocHeaderLeft->deactivate(); gui->tocHeaderCenter->deactivate(); gui->tocHeaderRight->deactivate(); gui->tocFooterLeft->deactivate(); gui->tocFooterCenter->deactivate(); gui->tocFooterRight->deactivate(); if (w == gui->typeEPUB) ext = ".epub"; else ext = ".html"; } else { gui->grayscale->activate(); gui->pageTab->activate(); gui->tocHeaderLeft->activate(); gui->tocHeaderCenter->activate(); gui->tocHeaderRight->activate(); gui->tocFooterLeft->activate(); gui->tocFooterCenter->activate(); gui->tocFooterRight->activate(); if (w == gui->typePDF || !gui->ps1->value()) gui->jpegCompress->activate(); else gui->jpegCompress->deactivate(); } if (w == gui->typePS) { gui->psTab->activate(); if (gui->ps1->value()) gui->psCommands->deactivate(); else gui->psCommands->activate(); ext = ".ps"; } else gui->psTab->deactivate(); if ((w == gui->typePDF && !gui->pdf11->value()) || (w == gui->typePS && gui->ps3->value())) gui->compGroup->activate(); else gui->compGroup->deactivate(); // Update the output filename's extension if we are writing to a file // and the output filename is not blank... if (gui->outputFile->value() && gui->outputPath->value()[0]) { strlcpy(filename, gui->outputPath->value(), sizeof(filename)); if ((ptr = strrchr(filename, '/')) == NULL) ptr = filename; if ((ptr = strrchr(ptr, '.')) == NULL) strlcat(filename, ext, sizeof(filename)); else strlcpy(ptr, ext, sizeof(filename) - (ptr - filename)); gui->outputPath->value(filename); } } // // 'GUI::jpegCB()' - Handle JPEG changes. // void GUI::jpegCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { REF(w); gui->title(gui->book_filename, 1); if (gui->jpegCompress->value()) gui->jpegGroup->activate(); else gui->jpegGroup->deactivate(); } // // 'GUI::sizeCB()' - Change the page size based on the menu selection. // void GUI::sizeCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { REF(w); gui->title(gui->book_filename, 1); gui->pageSize->value(gui->pageSizeMenu->text(gui->pageSizeMenu->value())); } // // 'GUI::tocCB()' - Handle Table-of-Contents changes. // void GUI::tocCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { REF(w); gui->title(gui->book_filename, 1); if (gui->tocLevels->value()) { gui->numberedToc->activate(); gui->tocHeader->activate(); gui->tocFooter->activate(); gui->tocTitle->activate(); } else { gui->numberedToc->deactivate(); gui->tocHeader->deactivate(); gui->tocFooter->deactivate(); gui->tocTitle->deactivate(); } } // // 'GUI::pdfCB()' - Handle PDF version changes. // void GUI::pdfCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { REF(w); if (gui->typePDF->value()) { if (w == gui->pdf11) gui->compGroup->deactivate(); else gui->compGroup->activate(); } gui->title(gui->book_filename, 1); } // // 'GUI::encryptionCB()' - Handle PDF encryption changes. // void GUI::encryptionCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { if (w == gui->encryptionYes) { gui->permissions->activate(); gui->ownerPassword->activate(); gui->userPassword->activate(); } else if (w == gui->encryptionNo) { gui->permissions->deactivate(); gui->ownerPassword->deactivate(); gui->userPassword->deactivate(); } gui->title(gui->book_filename, 1); } // // 'GUI::effectCB()' - Handle PDF effect changes. // void GUI::effectCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { REF(w); if (gui->pageEffect->value()) { gui->pageDuration->activate(); gui->effectDuration->activate(); } else { gui->pageDuration->deactivate(); gui->effectDuration->deactivate(); } gui->title(gui->book_filename, 1); } // // 'GUI::psCB()' - Handle PS language level changes. // void GUI::psCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { if (w == gui->ps1) { gui->jpegCompress->deactivate(); gui->psCommands->deactivate(); gui->psCommands->value(0); } else { gui->jpegCompress->activate(); gui->psCommands->activate(); } if (gui->typePS->value()) { if (w == gui->ps3) gui->compGroup->activate(); else gui->compGroup->deactivate(); } gui->title(gui->book_filename, 1); } // // 'GUI::htmlEditorCB()' - Change the HTML editor. // void GUI::htmlEditorCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { const char *filename; // New HTML editor file char command[1024]; // Command string if (w == gui->htmlBrowse) { # if defined(WIN32) || defined(__EMX__) gui->fc->filter("Program Files (*.exe)"); # else gui->fc->filter("*"); # endif // WIN32 || __EMX__ gui->fc->label("HTML Editor?"); gui->fc->type(Fl_File_Chooser::SINGLE); gui->fc->show(); while (gui->fc->shown()) Fl::wait(); if (gui->fc->count()) { filename = gui->fc->value(); if (strstr(filename, "netscape") != NULL || strstr(filename, "NETSCAPE") != NULL) #if defined(WIN32) || defined(__EMX__) snprintf(command, sizeof(command), "%s -edit \"%%s\"", filename); #else snprintf(command, sizeof(command), "%s -remote \'editFile(%%s)\'", filename); #endif // WIN32 || __EMX__ else snprintf(command, sizeof(command), "%s \"%%s\"", filename); gui->htmlEditor->value(command); } } strlcpy(HTMLEditor, gui->htmlEditor->value(), sizeof(HTMLEditor)); } // // 'GUI::tooltipCB()' - Enable or disable tooltips. // void GUI::tooltipCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI interface { REF(gui); Tooltips = ((Fl_Button *)w)->value(); Fl_Tooltip::enable(Tooltips); } #if 0 // // 'GUI::skinCB()' - Enable or disable the modern "skin". // void GUI::skinCB(Fl_Widget *, // I - Widget GUI *gui) // I - GUI interface { ModernSkin = gui->modern_skin->value(); Fl::scheme(ModernSkin ? "plastic" : ""); if (ModernSkin) { // Use alternate colors for the "modern" look-n-feel... gui->tabs->selection_color(FL_BLUE); gui->grayscale->color2(FL_RED); gui->titlePage->color2(FL_RED); gui->jpegCompress->color2(FL_RED); gui->pageDuplex->color2(FL_RED); gui->landscape->color2(FL_RED); gui->numberedToc->color2(FL_RED); gui->psCommands->color2(FL_RED); gui->xrxComments->color2(FL_RED); gui->links->color2(FL_RED); gui->embedFonts->color2(FL_RED); gui->permPrint->color2(FL_RED); gui->permModify->color2(FL_RED); gui->permCopy->color2(FL_RED); gui->permAnnotate->color2(FL_RED); gui->tooltips->color2(FL_RED); gui->modern_skin->color2(FL_RED); gui->strict_html->color2(FL_RED); gui->overflow_errors->color2(FL_RED); gui->progressBar->color2(FL_BLUE); gui->progressBar->box(FL_UP_BOX); } else { // Use standard colors... gui->tabs->selection_color(FL_GRAY); gui->grayscale->color2(FL_BLACK); gui->titlePage->color2(FL_BLACK); gui->jpegCompress->color2(FL_BLACK); gui->pageDuplex->color2(FL_BLACK); gui->landscape->color2(FL_BLACK); gui->numberedToc->color2(FL_BLACK); gui->psCommands->color2(FL_BLACK); gui->xrxComments->color2(FL_BLACK); gui->links->color2(FL_BLACK); gui->embedFonts->color2(FL_BLACK); gui->permPrint->color2(FL_BLACK); gui->permModify->color2(FL_BLACK); gui->permCopy->color2(FL_BLACK); gui->permAnnotate->color2(FL_BLACK); gui->tooltips->color2(FL_BLACK); gui->modern_skin->color2(FL_BLACK); gui->strict_html->color2(FL_BLACK); gui->overflow_errors->color2(FL_BLACK); gui->progressBar->color2(FL_YELLOW); gui->progressBar->box(FL_DOWN_BOX); } } #endif // 0 // // 'GUI::saveOptionsCB()' - Save preferences... // void GUI::saveOptionsCB(Fl_Widget *w, GUI *gui) { gui->loadSettings(); prefs_save(); } // // 'GUI::bodyColorCB()' - Set the body color. // void GUI::bodyColorCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { uchar r, g, b; // Color values int color; // Color from bar color char newcolor[255]; // New color string if (w == gui->bodyLookup) { if (sscanf(gui->bodyColor->value(), "#%x", &color) == 1) { r = color >> 16; g = (color >> 8) & 255; b = color & 255; } else { r = 191; g = 191; b = 191; } if (fl_color_chooser("Body Color?", r, g, b)) { snprintf(newcolor, sizeof(newcolor), "#%02x%02x%02x", r, g, b); gui->bodyColor->value(newcolor); gui->title(gui->book_filename, 1); } } else gui->title(gui->book_filename, 1); } // // 'GUI::bodyImageCB()' - Set the body image. // void GUI::bodyImageCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { if (w == gui->bodyBrowse) { gui->fc->filter("Image Files (*.{bmp,gif,jpg,png})"); gui->fc->label("Body Image?"); gui->fc->type(Fl_File_Chooser::SINGLE); gui->fc->show(); while (gui->fc->shown()) Fl::wait(); if (gui->fc->count()) { gui->bodyImage->value(file_localize(gui->fc->value(), NULL)); gui->title(gui->book_filename, 1); } } else gui->title(gui->book_filename, 1); } // // 'GUI::textColorCB()' - Set the text color. // void GUI::textColorCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { uchar r, g, b; // Color values int color; // Color from bar color char newcolor[255]; // New color string if (w == gui->textLookup) { if (sscanf(gui->textColor->value(), "#%x", &color) == 1) { r = color >> 16; g = (color >> 8) & 255; b = color & 255; } else { r = 0; g = 0; b = 0; } if (fl_color_chooser("Text Color?", r, g, b)) { snprintf(newcolor, sizeof(newcolor), "#%02x%02x%02x", r, g, b); gui->textColor->value(newcolor); gui->title(gui->book_filename, 1); } } else gui->title(gui->book_filename, 1); } // // 'GUI::linkColorCB()' - Set the link color. // void GUI::linkColorCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { uchar r, g, b; // Color values int color; // Color from bar color char newcolor[255]; // New color string if (w == gui->linkLookup) { if (sscanf(gui->linkColor->value(), "#%x", &color) == 1) { r = color >> 16; g = (color >> 8) & 255; b = color & 255; } else { r = 0; g = 0; b = 255; } if (fl_color_chooser("Link Color?", r, g, b)) { snprintf(newcolor, sizeof(newcolor), "#%02x%02x%02x", r, g, b); gui->linkColor->value(newcolor); gui->title(gui->book_filename, 1); } } else gui->title(gui->book_filename, 1); } // // 'GUI::helpCB()' - Show on-line help... // void GUI::helpCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { char link[1024]; // filename#link REF(w); snprintf(link, sizeof(link), "%s/help.html#%s", help_dir, gui->tabs->value()->label()); gui->help->load(link); gui->help->show(); } // // 'GUI::newBookCB()' - Create a new book. // void GUI::newBookCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { REF(w); if (!gui->checkSave()) return; gui->newBook(); } // // 'GUI::openBookCB()' - Open an existing book. // void GUI::openBookCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { REF(w); if (!gui->checkSave()) return; gui->fc->filter("Book Files (*.book)"); gui->fc->label("Book File?"); gui->fc->type(Fl_File_Chooser::SINGLE); gui->fc->show(); while (gui->fc->shown()) Fl::wait(); if (gui->fc->count()) gui->loadBook(gui->fc->value()); } // // 'GUI::saveBookCB()' - Save the current book to disk. // void GUI::saveBookCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { if (gui->book_filename[0] == '\0') saveAsBookCB(w, gui); else gui->saveBook(gui->book_filename); } // // 'GUI::saveAsBookCB()' - Save the current book to disk to a new file. // void GUI::saveAsBookCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { const char *filename; // Book filename char realname[1024]; // Real filename const char *extension; // Filename extension const char *newfile; // New filename const char *dir; // Book directory REF(w); gui->fc->filter("Book Files (*.book)"); gui->fc->label("Book File?"); gui->fc->type(Fl_File_Chooser::CREATE); gui->fc->show(); while (gui->fc->shown()) Fl::wait(); if (gui->fc->count()) { filename = gui->fc->value(); if (access(filename, 0) == 0) if (!fl_choice("File already exists! OK to overwrite?", "Cancel", "Overwrite", NULL)) return; extension = file_extension(filename); if (!extension[0]) { // No extension! Add .book to the name... snprintf(realname, sizeof(realname), "%s.book", filename); filename = realname; } else if (strcasecmp(extension, "pdf") == 0 || strcasecmp(extension, "html") == 0 || strcasecmp(extension, "ps") == 0) { gui->tabs->value(gui->outputTab); gui->outputPath->value(file_localize(filename, NULL)); gui->outputFile->setonly(); outputTypeCB(gui->outputFile, gui); if (strcasecmp(extension, "pdf") == 0) { gui->typePDF->setonly(); outputFormatCB(gui->typePDF, gui); } else if (strcasecmp(extension, "epub") == 0) { gui->typeEPUB->setonly(); outputFormatCB(gui->typeEPUB, gui); } else if (strcasecmp(extension, "html") == 0) { gui->typeHTML->setonly(); outputFormatCB(gui->typeHTML, gui); } else { gui->typePS->setonly(); outputFormatCB(gui->typePS, gui); } fl_alert("To generate a HTML, PDF, or PS file you must click on " "the GENERATE button. The SAVE and SAVE AS buttons " "save the current book file."); return; } dir = file_directory(filename); for (int i = 1; i <= gui->inputFiles->size(); i ++) { newfile = file_localize(gui->inputFiles->text(i), dir); gui->inputFiles->text(i, newfile); } newfile = file_localize(gui->logoImage->value(), dir); gui->logoImage->value(newfile); newfile = file_localize(gui->titleImage->value(), dir); gui->titleImage->value(newfile); newfile = file_localize(gui->bodyImage->value(), dir); gui->bodyImage->value(newfile); newfile = file_localize(gui->outputPath->value(), dir); gui->outputPath->value(newfile); chdir(dir); gui->saveBook(filename); } } // // 'GUI::generateBookCB()' - Generate the current book. // void GUI::generateBookCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { int i, // Looping var count; // Number of files char temp[1024]; // Temporary string FILE *docfile; // Document file tree_t *document, // Master HTML document *file, // HTML document file *toc; // Table of contents const char *filename, // HTML filename *ext; // Extension of filename char base[1024], // Base directory of HTML file bookbase[1024]; // Base directory of book file REF(w); // Do we have an output filename? if (gui->outputPath->size() == 0) { gui->tabs->value(gui->outputTab); gui->outputPath->take_focus(); fl_alert("You must specify an output directory or filename before " "you click on GENERATE."); return; } // Disable the GUI while we generate... gui->controls->deactivate(); gui->window->cursor(FL_CURSOR_WAIT); // Set global vars used for converting the HTML files to XYZ format... strlcpy(bookbase, file_directory(gui->book_filename), sizeof(bookbase)); Verbosity = 1; gui->loadSettings(); strlcpy(Letterhead, gui->lhImage->value(), sizeof(Letterhead)); strlcpy(LogoImage, gui->logoImage->value(), sizeof(LogoImage)); strlcpy(TitleImage, gui->titleImage->value(), sizeof(TitleImage)); strlcpy(OutputPath, gui->outputPath->value(), sizeof(OutputPath)); OutputFiles = gui->outputDirectory->value(); if (gui->typeBook->value()) OutputType = OUTPUT_BOOK; else if (gui->typeContinuous->value()) OutputType = OUTPUT_CONTINUOUS; else OutputType = OUTPUT_WEBPAGES; strlcpy(UserPassword, gui->userPassword->value(), sizeof(UserPassword)); strlcpy(OwnerPassword, gui->ownerPassword->value(), sizeof(OwnerPassword)); if (gui->typePDF->value()) PSLevel = 0; else if (gui->ps1->value()) PSLevel = 1; else if (gui->ps2->value()) PSLevel = 2; else PSLevel = 3; _htmlPPI = 72.0f * _htmlBrowserWidth / (PageWidth - PageLeft - PageRight); file_proxy(gui->proxy->value()); Errors = 0; gui->error_list->clear(); /* * Load the input files... */ count = gui->inputFiles->size(); document = NULL; for (i = 1; i <= count; i ++) { filename = file_find(Path, gui->inputFiles->text(i)); if (filename != NULL && (docfile = fopen(filename, "rb")) != NULL) { /* * Read from a file... */ snprintf(temp, sizeof(temp), "Loading \"%s\"...", filename); gui->progress(100 * i / count, temp); strlcpy(base, file_directory(gui->inputFiles->text(i)), sizeof(base)); ext = file_extension(filename); file = htmlAddTree(NULL, MARKUP_FILE, NULL); htmlSetVariable(file, (uchar *)"_HD_FILENAME", (uchar *)file_basename(filename)); htmlSetVariable(file, (uchar *)"_HD_BASE", (uchar *)base); if (ext && !strcmp(ext, "md")) { // Read markdown from a file... mdReadFile(file, docfile, base); } else { // Read HTML from a file... _htmlCurrentFile = gui->inputFiles->text(i); htmlReadFile(file, docfile, base); } fclose(docfile); if (file->child != NULL) { if (document == NULL) document = file; else { while (document->next != NULL) document = document->next; document->next = file; file->prev = document; } } else htmlDeleteTree(file); } else progress_error(HD_ERROR_FILE_NOT_FOUND, "Unable to open \"%s\" for reading!", gui->inputFiles->text(i)); } /* * We *must* have a document to process... */ if (document == NULL) progress_error(HD_ERROR_NO_FILES, "No input files to format, cannot generate document."); else { /* * Find the first one in the list... */ while (document->prev != NULL) document = document->prev; // Fix links... htmlFixLinks(document, document); // Show debug info... htmlDebugStats("Document Tree", document); // Build a table of contents for the documents... if (OutputType == OUTPUT_BOOK && TocLevels > 0) toc = toc_build(document); else toc = NULL; // Generate the output file(s). if (gui->typeEPUB->value()) epub_export(document, toc); else if (gui->typeHTML->value()) html_export(document, toc); else if (gui->typeHTMLSep->value()) htmlsep_export(document, toc); else pspdf_export(document, toc); htmlDeleteTree(document); htmlDeleteTree(toc); hd_strfreeall(); file_cleanup(); image_flush_cache(); } if (Errors == 0) fl_message("Document generated successfully!"); else if (fl_choice("%d error%s occurred while generating document.\n" "Would you like to see the list?", "Continue", "View Error List", NULL, Errors, Errors == 1 ? "" : "s")) gui->error_window->show(); gui->controls->activate(); gui->window->cursor(FL_CURSOR_DEFAULT); gui->progress(0); } // // 'GUI::closeBookCB()' - Close the current book. // void GUI::closeBookCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { REF(w); if (gui->checkSave()) gui->hide(); } // // 'GUI::errorCB()' - Close the error window. // void GUI::errorCB(Fl_Widget *w, // I - Widget GUI *gui) // I - GUI { REF(w); gui->error_window->hide(); } // // 'aboutCloseCB()' - Close the about window. // static void aboutCloseCB(Fl_Widget *w) // I - Widget { if (w && w->window()) w->window()->hide(); } // // 'GUI::showAboutCB()' - Show the about window. // void GUI::showAboutCB(void) { Fl_Window *about; // About window Fl_Group *group; // Group Fl_Box *label; // Labels Fl_Help_View *text; // Help text Fl_Button *button; // Close button Fl_Pixmap logo(htmldoc_xpm); // Logo image about = new Fl_Window(550, 300, "About HTMLDOC"); about->set_modal(); about->hotspot(about); group = new Fl_Group(10, 10, 530, 245, "About HTMLDOC"); group->align(FL_ALIGN_TOP_LEFT | FL_ALIGN_INSIDE); group->labelcolor(FL_BLUE); group->labelfont(FL_HELVETICA_BOLD); group->labelsize(18); group->box(FL_THIN_UP_BOX); label = new Fl_Box(20, 45, 35, 35); label->image(&logo); label = new Fl_Box(60, 45, 530, 35, "HTMLDOC " SVERSION "\nCopyright © 2011-2024 by Michael R Sweet." ); label->align(FL_ALIGN_TOP_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_WRAP); text = new Fl_Help_View(20, 90, 510, 155); text->value( "HTMLDOC converts HTML files and web pages to PDF and PostScript.\n\n" "

    HTMLDOC is provided under the terms of the GNU General Public License " "and comes with absolutely no warranty. Please report problems on the " "Github issues page at:\n" "

    \n\n"
        "    https://github.com/michaelrsweet/htmldoc/issues\n"
        "
    \n" ); text->textsize(FL_NORMAL_SIZE); group->end(); button = new Fl_Button(480, 265, 60, 25, "Close"); button->callback((Fl_Callback *)aboutCloseCB); about->end(); about->show(); while (about->shown()) Fl::wait(); delete about; } #endif // HAVE_LIBFLTK htmldoc-1.9.20/htmldoc/gui.h000066400000000000000000000154501472561501400156360ustar00rootroot00000000000000/* * GUI definitions for HTMLDOC, an HTML document processing program. * * Copyright 2011-2023 by Michael R Sweet. * Copyright 1997-2010 by Easy Software Products. All rights reserved. * * This program is free software. Distribution and use rights are outlined in * the file "COPYING". */ /* * Include necessary headers. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* * Class definition for HTMLDOC dialog... */ class GUI { private: Fl_Double_Window *window; Fl_Group *controls; Fl_Tabs *tabs; Fl_Group *inputTab; Fl_Round_Button *typeBook, *typeContinuous, *typeWebPage; Fl_File_Browser *inputFiles; Fl_Button *addFile, *addURL, *editFile, *deleteFile, *moveUpFile, *moveDownFile; Fl_Input *lhImage; Fl_Button *lhBrowse; Fl_Input *logoImage; Fl_Button *logoBrowse; Fl_Input *titleImage; Fl_Button *titleBrowse; Fl_Group *outputTab; Fl_Round_Button *outputFile, *outputDirectory; Fl_Input *outputPath; Fl_Button *outputBrowse; Fl_Round_Button *typeEPUB, *typeHTML, *typeHTMLSep, *typePS, *typePDF; Fl_Check_Button *grayscale, *titlePage, *jpegCompress; Fl_Group *compGroup; Fl_Slider *compression; Fl_Group *jpegGroup; Fl_Value_Slider *jpegQuality; Fl_Group *pageTab; Fl_Input *pageSize; Fl_Menu_Button *pageSizeMenu; Fl_Check_Button *pageDuplex, *landscape; Fl_Input *pageTop, *pageLeft, *pageRight, *pageBottom; Fl_Choice *pageHeaderLeft, *pageHeaderCenter, *pageHeaderRight, *pageHeader1Left, *pageHeader1Center, *pageHeader1Right, *pageFooterLeft, *pageFooterCenter, *pageFooterRight; Fl_Choice *numberUp; Fl_Group *tocTab; Fl_Choice *tocLevels; Fl_Check_Button *numberedToc; Fl_Group *tocHeader; Fl_Choice *tocHeaderLeft, *tocHeaderCenter, *tocHeaderRight; Fl_Group *tocFooter; Fl_Choice *tocFooterLeft, *tocFooterCenter, *tocFooterRight; Fl_Input *tocTitle; Fl_Group *colorsTab; Fl_Input *bodyColor; Fl_Button *bodyLookup; Fl_Input *bodyImage; Fl_Button *bodyBrowse; Fl_Input *textColor; Fl_Button *textLookup; Fl_Input *linkColor; Fl_Button *linkLookup; Fl_Choice *linkStyle; Fl_Group *fontsTab; Fl_Choice *headingFont, *bodyFont, *headFootFont; Fl_Counter *fontBaseSize, *fontSpacing, *headFootSize; Fl_Input *preIndent; Fl_Choice *charset; Fl_Check_Button *embedFonts; Fl_Group *psTab; Fl_Group *psLevel; Fl_Round_Button *ps1, *ps2, *ps3; Fl_Check_Button *psCommands, *xrxComments; Fl_Group *pdfTab; Fl_Group *pdfVersion; Fl_Round_Button *pdf11, *pdf12, *pdf13, *pdf14; Fl_Choice *pageMode, *pageLayout, *firstPage, *pageEffect; Fl_Value_Slider *pageDuration, *effectDuration; Fl_Check_Button *links; Fl_Group *securityTab; Fl_Group *encryption; Fl_Round_Button *encryptionYes, *encryptionNo; Fl_Group *permissions; Fl_Check_Button *permPrint, *permModify, *permCopy, *permAnnotate; Fl_Secret_Input *ownerPassword, *userPassword; Fl_Group *optionsTab; Fl_Input *htmlEditor; Fl_Button *htmlBrowse; Fl_Value_Slider *browserWidth; Fl_Input *path; Fl_Input *proxy; Fl_Check_Button *tooltips; Fl_Check_Button *strict_html; Fl_Check_Button *overflow_errors; Fl_Button *showAbout, *showLicense, *saveOptions; Fl_Button *bookHelp, *bookNew, *bookOpen, *bookSave, *bookSaveAs, *bookGenerate, *bookClose; Fl_Progress *progressBar; char book_filename[1024]; int book_changed; char title_string[1024]; Fl_File_Chooser *fc; Fl_File_Icon *icon; Fl_Help_Dialog *help; Fl_Window *error_window; Fl_Browser *error_list; Fl_Button *error_ok; void loadSettings(); void title(const char *filename = NULL, int changed = 0); static void changeCB(Fl_Widget *w, GUI *gui); static void docTypeCB(Fl_Widget *w, GUI *gui); static void inputFilesCB(Fl_Widget *w, GUI *gui); static void addFileCB(Fl_Widget *w, GUI *gui); static void addURLCB(Fl_Widget *w, GUI *gui); static void editFilesCB(Fl_Widget *w, GUI *gui); static void deleteFilesCB(Fl_Widget *w, GUI *gui); static void moveUpFilesCB(Fl_Widget *w, GUI *gui); static void moveDownFilesCB(Fl_Widget *w, GUI *gui); static void lhImageCB(Fl_Widget *w, GUI *gui); static void logoImageCB(Fl_Widget *w, GUI *gui); static void titleImageCB(Fl_Widget *w, GUI *gui); static void outputTypeCB(Fl_Widget *w, GUI *gui); static void outputPathCB(Fl_Widget *w, GUI *gui); static void outputFormatCB(Fl_Widget *w, GUI *gui); static void jpegCB(Fl_Widget *w, GUI *gui); static void sizeCB(Fl_Widget *w, GUI *gui); static void tocCB(Fl_Widget *w, GUI *gui); static void bodyColorCB(Fl_Widget *w, GUI *gui); static void bodyImageCB(Fl_Widget *w, GUI *gui); static void textColorCB(Fl_Widget *w, GUI *gui); static void linkColorCB(Fl_Widget *w, GUI *gui); static void psCB(Fl_Widget *w, GUI *gui); static void pdfCB(Fl_Widget *w, GUI *gui); static void effectCB(Fl_Widget *w, GUI *gui); static void encryptionCB(Fl_Widget *w, GUI *gui); static void htmlEditorCB(Fl_Widget *w, GUI *gui); static void tooltipCB(Fl_Widget *w, GUI *gui); static void saveOptionsCB(Fl_Widget *w, GUI *gui); static void helpCB(Fl_Widget *w, GUI *gui); static void newBookCB(Fl_Widget *w, GUI *gui); static void openBookCB(Fl_Widget *w, GUI *gui); static void saveBookCB(Fl_Widget *w, GUI *gui); static void saveAsBookCB(Fl_Widget *w, GUI *gui); static void generateBookCB(Fl_Widget *w, GUI *gui); static void closeBookCB(Fl_Widget *w, GUI *gui); static void errorCB(Fl_Widget *w, GUI *gui); #ifdef __APPLE__ static void appleOpenCB(const char *f); #endif // __APPLE__ public: static const char *help_dir; static void showAboutCB(void); static void showLicenseCB(void); GUI(const char *filename = NULL); ~GUI(void); void add_error(const char *s) { error_list->add(s); } int checkSave(); void hide() { window->hide(); help->hide(); fc->hide(); }; int loadBook(const char *bookfile); int newBook(); void parseOptions(const char *line); void progress(int percent, const char *text = NULL); int saveBook(const char *bookfile); void show(); int visible() { return (window->visible()); } }; htmldoc-1.9.20/htmldoc/hdstring.h000066400000000000000000000044041472561501400166710ustar00rootroot00000000000000// // String definitions for HTMLDOC, a HTML document processing program. // // Copyright © 2011-2024 by Michael R Sweet. // Copyright © 1997-2010 by Easy Software Products. All rights reserved. // // This program is free software. Distribution and use rights are outlined in // the file "COPYING". // #ifndef _HDSTRING_H_ # define _HDSTRING_H_ # include "config.h" # include # include # include # include # include # ifdef HAVE_STRINGS_H # include # endif // HAVE_STRINGS_H # ifdef __cplusplus extern "C" { # endif // __cplusplus // // Define some compatibility macros for Microsoft Windows... // # ifdef WIN32 # define strcasecmp(s,t) stricmp(s,t) # define strncasecmp(s,t,n) strnicmp(s,t,n) # define snprintf _snprintf # define vsnprintf _vsnprintf # endif // WIN32 // // Implementation of strcpy() that allows for overlapping buffers. // extern void hd_strcpy(char *dst, const char *src); // // Simple string pool functions to replace strdup/free usage in most places... // extern char *hd_strdup(const char *); extern void hd_strfreeall(void); extern size_t hd_strgetsize(void); // // Standard string functions that might not be available... // # ifndef HAVE_SNPRINTF extern int hd_snprintf(char *, size_t, const char *, ...) # ifdef __GNUC__ __attribute__ ((__format__ (__printf__, 3, 4))) # endif // __GNUC__ ; # define snprintf hd_snprintf # endif // !HAVE_SNPRINTF # ifndef HAVE_STRCASECMP extern int hd_strcasecmp(const char *, const char *); # define strcasecmp hd_strcasecmp # endif // !HAVE_STRCASECMP # ifndef HAVE_STRLCAT extern size_t hd_strlcat(char *, const char *, size_t); # define strlcat hd_strlcat # endif // !HAVE_STRLCAT # ifndef HAVE_STRLCPY extern size_t hd_strlcpy(char *, const char *, size_t); # define strlcpy hd_strlcpy # endif // !HAVE_STRLCPY # ifndef HAVE_STRNCASECMP extern int hd_strncasecmp(const char *, const char *, size_t n); # define strncasecmp hd_strncasecmp # endif // !HAVE_STRNCASECMP # ifndef HAVE_VSNPRINTF extern int hd_vsnprintf(char *, size_t, const char *, va_list); # define vsnprintf hd_vsnprintf # endif // !HAVE_VSNPRINTF # ifdef __cplusplus } # endif // __cplusplus #endif // !_HDSTRING_H_ htmldoc-1.9.20/htmldoc/html.cxx000066400000000000000000000634751472561501400164030ustar00rootroot00000000000000/* * HTML exporting functions for HTMLDOC, a HTML document processing program. * * Copyright 2011-2021 by Michael R Sweet. * Copyright 1997-2010 by Easy Software Products. All rights reserved. * * This program is free software. Distribution and use rights are outlined in * the file "COPYING". */ /* * Include necessary headers. */ #include "htmldoc.h" #include "markdown.h" #include /* * Named link structure... */ typedef struct { uchar *filename; /* File for link */ uchar name[124]; /* Reference name */ } link_t; /* * Local globals... */ static size_t num_links = 0, alloc_links = 0; static link_t *links; /* * Local functions... */ extern "C" { typedef int (*compare_func_t)(const void *, const void *); } static void write_header(FILE **out, uchar *filename, uchar *title, uchar *author, uchar *copyright, uchar *docnumber, tree_t *t); static void write_footer(FILE **out, tree_t *t); static void write_title(FILE *out, uchar *title, uchar *author, uchar *copyright, uchar *docnumber); static int write_all(FILE *out, tree_t *t, int col); static int write_node(FILE *out, tree_t *t, int col); static int write_nodeclose(FILE *out, tree_t *t, int col); static int write_toc(FILE *out, tree_t *t, int col); static uchar *get_title(tree_t *doc); static void add_link(uchar *name, uchar *filename); static link_t *find_link(uchar *name); static int compare_links(link_t *n1, link_t *n2); static void scan_links(tree_t *t, uchar *filename); static void update_links(tree_t *t, uchar *filename); /* * 'html_export()' - Export to HTML... */ int /* O - 0 = success, -1 = failure */ html_export(tree_t *document, /* I - Document to export */ tree_t *toc) /* I - Table of contents for document */ { uchar *title, /* Title text */ *author, /* Author name */ *copyright, /* Copyright text */ *docnumber; /* Document number */ FILE *out; /* Output file */ /* * Copy logo and title images... */ if (OutputFiles) { if (LogoImage[0]) image_copy(LogoImage, file_find(LogoImage, Path), OutputPath); for (int hfi = 0; hfi < MAX_HF_IMAGES; hfi ++) if (HFImage[hfi][0]) image_copy(HFImage[hfi], file_find(HFImage[hfi], Path), OutputPath); } if (OutputFiles && TitleImage[0] && TitlePage && #ifdef WIN32 (stricmp(file_extension(TitleImage), "bmp") == 0 || stricmp(file_extension(TitleImage), "gif") == 0 || stricmp(file_extension(TitleImage), "jpg") == 0 || stricmp(file_extension(TitleImage), "png") == 0)) #else (strcmp(file_extension(TitleImage), "bmp") == 0 || strcmp(file_extension(TitleImage), "gif") == 0 || strcmp(file_extension(TitleImage), "jpg") == 0 || strcmp(file_extension(TitleImage), "png") == 0)) #endif // WIN32 image_copy(TitleImage, file_find(TitleImage, Path), OutputPath); /* * Get document strings... */ title = get_title(document); author = htmlGetMeta(document, (uchar *)"author"); copyright = htmlGetMeta(document, (uchar *)"copyright"); docnumber = htmlGetMeta(document, (uchar *)"docnumber"); if (!docnumber) docnumber = htmlGetMeta(document, (uchar *)"version"); /* * Scan for all links in the document, and then update them... */ num_links = 0; alloc_links = 0; links = NULL; scan_links(document, NULL); update_links(document, NULL); update_links(toc, NULL); /* * Generate title pages and a table of contents... */ out = NULL; if (TitlePage) { write_header(&out, (uchar *)"index.html", title, author, copyright, docnumber, NULL); if (out != NULL) write_title(out, title, author, copyright, docnumber); write_footer(&out, NULL); write_header(&out, (uchar *)"toc.html", title, author, copyright, docnumber, NULL); } else write_header(&out, (uchar *)"index.html", title, author, copyright, docnumber, NULL); if (out != NULL) write_toc(out, toc, 0); write_footer(&out, NULL); /* * Then write each output file... */ while (document != NULL) { write_header(&out, htmlGetVariable(document, (uchar *)"_HD_FILENAME"), title, author, copyright, docnumber, document); if (out != NULL) write_all(out, document->child, 0); write_footer(&out, document); document = document->next; } if (!OutputFiles && out != stdout && out != NULL) { fputs("\n", out); fputs("\n", out); progress_error(HD_ERROR_NONE, "BYTES: %ld", ftell(out)); fclose(out); } if (title != NULL) free(title); if (alloc_links) { free(links); num_links = 0; alloc_links = 0; links = NULL; } return (out == NULL); } /* * 'write_header()' - Output the standard "header" for a HTML file. */ static void write_header(FILE **out, /* IO - Output file */ uchar *filename, /* I - Output filename */ uchar *title, /* I - Title for document */ uchar *author, /* I - Author for document */ uchar *copyright, /* I - Copyright for document */ uchar *docnumber, /* I - ID number for document */ tree_t *t) /* I - Current document file */ { char realname[1024]; /* Real filename */ const char *basename; /* Filename without directory */ int newfile; /* Non-zero if this is a new file */ static const char *families[] =/* Typeface names */ { "monospace", "serif", "sans-serif", "monospace", "serif", "sans-serif", "symbol", "dingbats" }; if (OutputFiles) { newfile = 1; basename = file_basename((char *)filename); snprintf(realname, sizeof(realname), "%s/%s", OutputPath, basename); *out = fopen(realname, "wb"); } else if (OutputPath[0]) { if (*out == NULL) { *out = fopen(OutputPath, "wb"); newfile = 1; } else newfile = 0; } else { if (*out == NULL) { *out = stdout; newfile = 1; } else newfile = 0; } if (*out == NULL) { progress_error(HD_ERROR_WRITE_ERROR, "Unable to create output file \"%s\" - %s.\n", OutputFiles ? realname : OutputPath, strerror(errno)); return; } if (newfile) { fputs("\n", *out); fputs("\n", *out); fputs("\n", *out); if (title != NULL) fprintf(*out, "%s\n", title); if (author != NULL) fprintf(*out, "\n", author); if (copyright != NULL) fprintf(*out, "\n", copyright); if (docnumber != NULL) fprintf(*out, "\n", docnumber); fprintf(*out, "\n", _htmlCharSet); if (OutputFiles) { fputs("\n", *out); if (TitlePage) fputs("\n", *out); else fputs("\n", *out); if (t) { if (t->prev != NULL) fprintf(*out, "\n", file_basename((char *)htmlGetVariable(t->prev, (uchar *)"_HD_FILENAME"))); if (t->next != NULL) fprintf(*out, "\n", file_basename((char *)htmlGetVariable(t->next, (uchar *)"_HD_FILENAME"))); } } fputs("\n", *out); fputs("\n", *out); if (BodyImage[0]) fprintf(*out, "\n", *out); } else fputs("
    \n", *out); if (OutputFiles && t != NULL && (t->prev != NULL || t->next != NULL)) { if (LogoImage[0]) fprintf(*out, "\n", file_basename(LogoImage)); for (int hfi = 0; hfi < MAX_HF_IMAGES; ++hfi) if (HFImage[hfi][0]) fprintf(*out, "\n", file_basename(HFImage[hfi])); if (TitlePage) fputs("Contents\n", *out); else fputs("Contents\n", *out); if (t->prev != NULL) fprintf(*out, "Previous\n", file_basename((char *)htmlGetVariable(t->prev, (uchar *)"_HD_FILENAME"))); if (t->next != NULL) fprintf(*out, "Next\n", file_basename((char *)htmlGetVariable(t->next, (uchar *)"_HD_FILENAME"))); fputs("
    \n", *out); } } /* * 'write_footer()' - Output the standard "footer" for a HTML file. */ static void write_footer(FILE **out, /* IO - Output file pointer */ tree_t *t) /* I - Current document file */ { if (*out == NULL) return; if (OutputFiles && t != NULL && (t->prev != NULL || t->next != NULL)) { fputs("
    \n", *out); if (LogoImage[0]) fprintf(*out, "\n", file_basename(LogoImage)); for (int hfi = 0; hfi < MAX_HF_IMAGES; ++hfi) if (HFImage[hfi][0]) fprintf(*out, "\n", file_basename(HFImage[hfi])); if (TitlePage) fputs("Contents\n", *out); else fputs("Contents\n", *out); if (t->prev != NULL) fprintf(*out, "Previous\n", file_basename((char *)htmlGetVariable(t->prev, (uchar *)"_HD_FILENAME"))); if (t->next != NULL) fprintf(*out, "Next\n", file_basename((char *)htmlGetVariable(t->next, (uchar *)"_HD_FILENAME"))); } if (OutputFiles) { fputs("\n", *out); fputs("\n", *out); progress_error(HD_ERROR_NONE, "BYTES: %ld", ftell(*out)); fclose(*out); *out = NULL; } } /* * 'write_title()' - Write a title page... */ static void write_title(FILE *out, /* I - Output file */ uchar *title, /* I - Title for document */ uchar *author, /* I - Author for document */ uchar *copyright, /* I - Copyright for document */ uchar *docnumber) /* I - ID number for document */ { FILE *fp; /* Title file */ const char *title_ext, /* Extension of title file */ *title_file; /* Location of title file */ tree_t *t; /* Title file document tree */ if (out == NULL) return; title_ext = file_extension(TitleImage); #ifdef WIN32 if (TitleImage[0] && stricmp(title_ext, "bmp") != 0 && stricmp(title_ext, "gif") != 0 && stricmp(title_ext, "jpg") != 0 && stricmp(title_ext, "png") != 0) #else if (TitleImage[0] && strcmp(title_ext, "bmp") != 0 && strcmp(title_ext, "gif") != 0 && strcmp(title_ext, "jpg") != 0 && strcmp(title_ext, "png") != 0) #endif // WIN32 { // Find the title page file... if ((title_file = file_find(Path, TitleImage)) == NULL) { progress_error(HD_ERROR_FILE_NOT_FOUND, "Unable to find title file \"%s\"!", TitleImage); return; } // Write a title page from HTML source... if ((fp = fopen(title_file, "rb")) == NULL) { progress_error(HD_ERROR_FILE_NOT_FOUND, "Unable to open title file \"%s\" - %s!", TitleImage, strerror(errno)); return; } #ifdef _WIN32 if (!stricmp(title_ext, "md")) #else if (!strcmp(title_ext, "md")) #endif // _WIN32 t = mdReadFile(NULL, fp, file_directory(TitleImage)); else t = htmlReadFile(NULL, fp, file_directory(TitleImage)); htmlFixLinks(t, t, (uchar *)file_directory(TitleImage)); fclose(fp); write_all(out, t, 0); htmlDeleteTree(t); } else { // Write a "standard" title page with image... if (OutputFiles) fputs("
    ", out); else fputs("
    ", out); if (TitleImage[0]) { image_t *img = image_load(TitleImage, !OutputColor); if (img) { if (OutputFiles) fprintf(out, "
    \n", file_basename((char *)TitleImage), img->width, img->height, title ? (char *)title : ""); else fprintf(out, "
    \n", TitleImage, img->width, img->height, title ? (char *)title : ""); } } if (title != NULL) fprintf(out, "

    %s


    \n", title); else fputs("\n", out); if (docnumber != NULL) fprintf(out, "%s
    \n", docnumber); if (author != NULL) fprintf(out, "%s
    \n", author); if (copyright != NULL) fprintf(out, "%s
    \n", copyright); fputs("
    \n", out); } } /* * 'write_all()' - Write all markup text for the given tree. */ static int /* O - Current column */ write_all(FILE *out, /* I - Output file */ tree_t *t, /* I - Document tree */ int col) /* I - Current column */ { if (out == NULL) return (0); while (t != NULL) { col = write_node(out, t, col); if (t->markup != MARKUP_HEAD && t->markup != MARKUP_TITLE) col = write_all(out, t->child, col); col = write_nodeclose(out, t, col); t = t->next; } return (col); } /* * 'write_node()' - Write a single tree node. */ static int /* O - Current column */ write_node(FILE *out, /* I - Output file */ tree_t *t, /* I - Document tree node */ int col) /* I - Current column */ { int i; /* Looping var */ uchar *ptr, /* Pointer to output string */ *entity, /* Entity string */ *src, /* Source image */ *realsrc, /* Real source image */ newsrc[1024]; /* New source image filename */ if (out == NULL) return (0); switch (t->markup) { case MARKUP_NONE : if (t->data == NULL) break; if (t->preformatted) { for (ptr = t->data; *ptr; ptr ++) fputs((char *)iso8859(*ptr), out); if (t->data[0] && t->data[strlen((char *)t->data) - 1] == '\n') col = 0; else col += strlen((char *)t->data); } else { if ((col + (int)strlen((char *)t->data)) > 72 && col > 0) { putc('\n', out); col = 0; } for (ptr = t->data; *ptr; ptr ++) fputs((char *)iso8859(*ptr), out); col += strlen((char *)t->data); if (col > 72) { putc('\n', out); col = 0; } } break; case MARKUP_COMMENT : case MARKUP_UNKNOWN : fputs("\n\n", out); col = 0; break; case MARKUP_AREA : case MARKUP_BODY : case MARKUP_DOCTYPE : case MARKUP_ERROR : case MARKUP_FILE : case MARKUP_HEAD : case MARKUP_HTML : case MARKUP_MAP : case MARKUP_META : case MARKUP_TITLE : break; case MARKUP_BR : case MARKUP_CENTER : case MARKUP_DD : case MARKUP_DL : case MARKUP_DT : case MARKUP_H1 : case MARKUP_H2 : case MARKUP_H3 : case MARKUP_H4 : case MARKUP_H5 : case MARKUP_H6 : case MARKUP_H7 : case MARKUP_H8 : case MARKUP_H9 : case MARKUP_H10 : case MARKUP_H11 : case MARKUP_H12 : case MARKUP_H13 : case MARKUP_H14 : case MARKUP_H15 : case MARKUP_HR : case MARKUP_LI : case MARKUP_OL : case MARKUP_P : case MARKUP_PRE : case MARKUP_TABLE : case MARKUP_TR : case MARKUP_UL : if (col > 0) { putc('\n', out); col = 0; } default : if (t->markup == MARKUP_IMG && OutputFiles && (src = htmlGetVariable(t, (uchar *)"SRC")) != NULL && (realsrc = htmlGetVariable(t, (uchar *)"REALSRC")) != NULL) { /* * Update and copy local images... */ if (file_method((char *)src) == NULL && src[0] != '/' && src[0] != '\\' && (!isalpha(src[0]) || src[1] != ':')) { image_copy((char *)src, (char *)realsrc, OutputPath); strlcpy((char *)newsrc, file_basename((char *)src), sizeof(newsrc)); htmlSetVariable(t, (uchar *)"SRC", newsrc); } } if (t->markup != MARKUP_EMBED) { col += fprintf(out, "<%s", _htmlMarkups[t->markup]); for (i = 0; i < t->nvars; i ++) { if (strcasecmp((char *)t->vars[i].name, "BREAK") == 0 && t->markup == MARKUP_HR) continue; if (strcasecmp((char *)t->vars[i].name, "REALSRC") == 0 && t->markup == MARKUP_IMG) continue; if (strncasecmp((char *)t->vars[i].name, "_HD_", 4) == 0) continue; if (col > 72 && !t->preformatted) { putc('\n', out); col = 0; } if (col > 0) { putc(' ', out); col ++; } if (t->vars[i].value == NULL) col += fprintf(out, "%s", t->vars[i].name); else { col += fprintf(out, "%s=\"", t->vars[i].name); for (ptr = t->vars[i].value; *ptr; ptr ++) { entity = iso8859(*ptr); fputs((char *)entity, out); col += strlen((char *)entity); } putc('\"', out); col ++; } } putc('>', out); col ++; if (col > 72 && !t->preformatted) { putc('\n', out); col = 0; } } break; } return (col); } /* * 'write_nodeclose()' - Close a single tree node. */ static int /* O - Current column */ write_nodeclose(FILE *out, /* I - Output file */ tree_t *t, /* I - Document tree node */ int col) /* I - Current column */ { if (out == NULL) return (0); if (t->markup != MARKUP_HEAD && t->markup != MARKUP_TITLE) { if (col > 72 && !t->preformatted) { putc('\n', out); col = 0; } switch (t->markup) { case MARKUP_BODY : case MARKUP_ERROR : case MARKUP_FILE : case MARKUP_HEAD : case MARKUP_HTML : case MARKUP_NONE : case MARKUP_TITLE : case MARKUP_APPLET : case MARKUP_AREA : case MARKUP_BR : case MARKUP_COMMENT : case MARKUP_DOCTYPE : case MARKUP_EMBED : case MARKUP_HR : case MARKUP_IMG : case MARKUP_INPUT : case MARKUP_ISINDEX : case MARKUP_LINK : case MARKUP_META : case MARKUP_NOBR : case MARKUP_SPACER : case MARKUP_WBR : case MARKUP_UNKNOWN : break; case MARKUP_CENTER : case MARKUP_DD : case MARKUP_DL : case MARKUP_DT : case MARKUP_H1 : case MARKUP_H2 : case MARKUP_H3 : case MARKUP_H4 : case MARKUP_H5 : case MARKUP_H6 : case MARKUP_H7 : case MARKUP_H8 : case MARKUP_H9 : case MARKUP_H10 : case MARKUP_H11 : case MARKUP_H12 : case MARKUP_H13 : case MARKUP_H14 : case MARKUP_H15 : case MARKUP_LI : case MARKUP_OL : case MARKUP_P : case MARKUP_PRE : case MARKUP_TABLE : case MARKUP_TR : case MARKUP_UL : fprintf(out, "\n", _htmlMarkups[t->markup]); col = 0; break; default : col += fprintf(out, "", _htmlMarkups[t->markup]); break; } } return (col); } /* * 'write_toc()' - Write all markup text for the given table-of-contents. */ static int /* O - Current column */ write_toc(FILE *out, /* I - Output file */ tree_t *t, /* I - Document tree */ int col) /* I - Current column */ { if (out == NULL) return (0); while (t != NULL) { if (htmlGetVariable(t, (uchar *)"_HD_OMIT_TOC") == NULL) { col = write_node(out, t, col); if (t->markup != MARKUP_HEAD && t->markup != MARKUP_TITLE) col = write_toc(out, t->child, col); col = write_nodeclose(out, t, col); } t = t->next; } return (col); } /* * 'get_title()' - Get the title string for the given document... */ static uchar * /* O - Title string */ get_title(tree_t *doc) /* I - Document tree */ { uchar *temp; /* Temporary pointer to title */ while (doc != NULL) { if (doc->markup == MARKUP_TITLE) return (htmlGetText(doc->child)); else if (doc->child != NULL) if ((temp = get_title(doc->child)) != NULL) return (temp); doc = doc->next; } return (NULL); } /* * 'add_link()' - Add a named link... */ static void add_link(uchar *name, /* I - Name of link */ uchar *filename) /* I - File for link */ { link_t *temp; /* New name */ if ((temp = find_link(name)) != NULL) temp->filename = filename; else { // See if we need to allocate memory for links... if (num_links >= alloc_links) { // Allocate more links... alloc_links += ALLOC_LINKS; if (num_links == 0) temp = (link_t *)malloc(sizeof(link_t) * alloc_links); else temp = (link_t *)realloc(links, sizeof(link_t) * alloc_links); if (temp == NULL) { progress_error(HD_ERROR_OUT_OF_MEMORY, "Unable to allocate memory for %d links - %s", (int)alloc_links, strerror(errno)); alloc_links -= ALLOC_LINKS; return; } links = temp; } // Add a new link... temp = links + num_links; num_links ++; strlcpy((char *)temp->name, (char *)name, sizeof(temp->name)); temp->filename = filename; if (num_links > 1) qsort(links, num_links, sizeof(link_t), (compare_func_t)compare_links); } } /* * 'find_link()' - Find a named link... */ static link_t * find_link(uchar *name) /* I - Name to find */ { uchar *target; /* Pointer to target name portion */ link_t key, /* Search key */ *match; /* Matching name entry */ if (name == NULL || num_links == 0) return (NULL); if ((target = (uchar *)file_target((char *)name)) == NULL) return (NULL); strlcpy((char *)key.name, (char *)target, sizeof(key.name)); match = (link_t *)bsearch(&key, links, num_links, sizeof(link_t), (compare_func_t)compare_links); return (match); } /* * 'compare_links()' - Compare two named links. */ static int /* O - 0 = equal, -1 or 1 = not equal */ compare_links(link_t *n1, /* I - First name */ link_t *n2) /* I - Second name */ { return (strcasecmp((char *)n1->name, (char *)n2->name)); } /* * 'scan_links()' - Scan a document for link targets, and keep track of * the files they are in... */ static void scan_links(tree_t *t, /* I - Document tree */ uchar *filename) /* I - Filename */ { uchar *name; /* Name of link */ while (t != NULL) { if (t->markup == MARKUP_FILE) scan_links(t->child, (uchar *)file_basename((char *)htmlGetVariable(t, (uchar *)"_HD_FILENAME"))); else if (t->markup == MARKUP_A && (name = htmlGetVariable(t, (uchar *)"NAME")) != NULL) { add_link(name, filename); scan_links(t->child, filename); } else if (t->child != NULL) scan_links(t->child, filename); t = t->next; } } /* * 'update_links()' - Update links as needed. */ static void update_links(tree_t *t, /* I - Document tree */ uchar *filename) /* I - Current filename */ { link_t *link; /* Link */ uchar *href; /* Reference name */ uchar newhref[1024]; /* New reference name */ filename = (uchar *)file_basename((char *)filename); if (OutputFiles) { /* * Need to preserve/add filenames. */ while (t != NULL) { if (t->markup == MARKUP_A && (href = htmlGetVariable(t, (uchar *)"HREF")) != NULL) { /* * Update this link as needed... */ if (href[0] == '#' && (link = find_link(href)) != NULL) { #if defined(WIN32) || defined(__EMX__) if (filename == NULL || strcasecmp((char *)filename, (char *)link->filename) != 0) #else if (filename == NULL || strcmp((char *)filename, (char *)link->filename) != 0) #endif /* WIN32 || __EMX__ */ { snprintf((char *)newhref, sizeof(newhref), "%s%s", link->filename, href); htmlSetVariable(t, (uchar *)"HREF", newhref); } } } if (t->child != NULL) { if (t->markup == MARKUP_FILE) update_links(t->child, htmlGetVariable(t, (uchar *)"_HD_FILENAME")); else update_links(t->child, filename); } t = t->next; } } else { /* * Need to strip filenames. */ while (t != NULL) { if (t->markup == MARKUP_A && (href = htmlGetVariable(t, (uchar *)"HREF")) != NULL) { /* * Update this link as needed... */ if (href[0] != '#' && file_method((char *)href) == NULL && (link = find_link(href)) != NULL) { snprintf((char *)newhref, sizeof(newhref), "#%s", link->name); htmlSetVariable(t, (uchar *)"HREF", newhref); } } if (t->child != NULL) update_links(t->child, filename); t = t->next; } } } htmldoc-1.9.20/htmldoc/html.h000066400000000000000000000147111472561501400160150ustar00rootroot00000000000000/* * HTML parsing definitions for HTMLDOC, a HTML document processing program. * * Copyright 2011-2019 by Michael R Sweet. * Copyright 1997-2010 by Easy Software Products. All rights reserved. * * This program is free software. Distribution and use rights are outlined in * the file "COPYING". */ #ifndef _HTML_H_ # define _HTML_H_ /* * Include necessary headers... */ # include # include # include "file.h" # include "hdstring.h" # include "iso8859.h" # ifdef __cplusplus extern "C" { # endif /* __cplusplus */ /* * Define some compatibility macros for Microsoft Windows... */ # ifdef WIN32 # define strcasecmp(s,t) stricmp(s,t) # define strncasecmp(s,t,n) strnicmp(s,t,n) # endif /* WIN32 */ /* * Markup constants... */ typedef enum { MARKUP_FILE = -3, /* File Delimiter */ MARKUP_UNKNOWN = -2, /* Unknown element */ MARKUP_ERROR = -1, MARKUP_NONE = 0, MARKUP_COMMENT, MARKUP_DOCTYPE, MARKUP_A, MARKUP_ACRONYM, MARKUP_ADDRESS, MARKUP_APPLET, MARKUP_AREA, MARKUP_B, MARKUP_BASE, MARKUP_BASEFONT, MARKUP_BIG, MARKUP_BLINK, MARKUP_BLOCKQUOTE, MARKUP_BODY, MARKUP_BR, MARKUP_CAPTION, MARKUP_CENTER, MARKUP_CITE, MARKUP_CODE, MARKUP_COL, MARKUP_COLGROUP, MARKUP_DD, MARKUP_DEL, MARKUP_DFN, MARKUP_DIR, MARKUP_DIV, MARKUP_DL, MARKUP_DT, MARKUP_EM, MARKUP_EMBED, MARKUP_FONT, MARKUP_FORM, MARKUP_FRAME, MARKUP_FRAMESET, MARKUP_H1, MARKUP_H2, MARKUP_H3, MARKUP_H4, MARKUP_H5, MARKUP_H6, MARKUP_H7, MARKUP_H8, MARKUP_H9, MARKUP_H10, MARKUP_H11, MARKUP_H12, MARKUP_H13, MARKUP_H14, MARKUP_H15, MARKUP_HEAD, MARKUP_HR, MARKUP_HTML, MARKUP_I, MARKUP_IMG, MARKUP_INPUT, MARKUP_INS, MARKUP_ISINDEX, MARKUP_KBD, MARKUP_LI, MARKUP_LINK, MARKUP_MAP, MARKUP_MENU, MARKUP_META, MARKUP_MULTICOL, MARKUP_NOBR, MARKUP_NOFRAMES, MARKUP_OL, MARKUP_OPTION, MARKUP_P, MARKUP_PRE, MARKUP_S, MARKUP_SAMP, MARKUP_SCRIPT, MARKUP_SELECT, MARKUP_SMALL, MARKUP_SPACER, MARKUP_SPAN, MARKUP_STRIKE, MARKUP_STRONG, MARKUP_STYLE, MARKUP_SUB, MARKUP_SUP, MARKUP_TABLE, MARKUP_TBODY, MARKUP_TD, MARKUP_TEXTAREA, MARKUP_TFOOT, MARKUP_TH, MARKUP_THEAD, MARKUP_TITLE, MARKUP_TR, MARKUP_TT, MARKUP_U, MARKUP_UL, MARKUP_VAR, MARKUP_WBR } markup_t; /* * Horizontal alignment... */ typedef enum { ALIGN_LEFT = 0, ALIGN_CENTER, ALIGN_RIGHT, ALIGN_JUSTIFY } halignment_t; /* * Vertical alignment... */ typedef enum { ALIGN_TOP = 0, ALIGN_MIDDLE, ALIGN_BOTTOM } valignment_t; /* * Typeface... */ typedef enum { TYPE_COURIER = 0, TYPE_TIMES, TYPE_HELVETICA, TYPE_MONOSPACE, TYPE_SERIF, TYPE_SANS_SERIF, TYPE_SYMBOL, TYPE_DINGBATS } typeface_t; #define TYPE_MAX (typeface_t)(TYPE_DINGBATS + 1) /* * Style... */ typedef enum { STYLE_NORMAL = 0, STYLE_BOLD, STYLE_ITALIC, STYLE_BOLD_ITALIC } style_t; #define STYLE_MAX (style_t)(STYLE_BOLD_ITALIC + 1) /* * Sizes... */ # define SIZE_H1 6 # define SIZE_H2 5 # define SIZE_H3 4 # define SIZE_H4 3 # define SIZE_H5 2 # define SIZE_H6 1 # define SIZE_H7 0 # define SIZE_P 3 # define SIZE_PRE 2 # define SIZE_SUB -2 # define SIZE_SUP -2 /* * Markup variables... */ typedef struct { uchar *name, /* Variable name */ *value; /* Variable value */ } var_t; /* * Parsing tree... */ typedef struct tree_str { struct tree_str *parent, /* Parent tree entry */ *child, /* First child entry */ *last_child, /* Last child entry */ *prev, /* Previous entry on this level */ *next, /* Next entry on this level */ *link; /* Linked-to */ markup_t markup; /* Markup code */ uchar *data; /* Text (MARKUP_NONE or MARKUP_COMMENT) */ unsigned halignment:2, /* Horizontal alignment */ valignment:2, /* Vertical alignment */ typeface:3, /* Typeface code */ size:3, /* Size of text */ style:2, /* Style of text */ underline:1, /* Text is underlined? */ strikethrough:1,/* Text is struck-through? */ subscript:1, /* Text is subscripted? */ superscript:1, /* Text is superscripted? */ preformatted:1, /* Preformatted text? */ indent:4; /* Indentation level 0-15 */ uchar red, /* Color of this fragment */ green, blue; float width, /* Width of this fragment in points */ height; /* Height of this fragment in points */ int nvars; /* Number of variables... */ var_t *vars; /* Variables... */ } tree_t; /* * Globals... */ extern const char *_htmlCurrentFile; extern const char *_htmlMarkups[]; extern const char *_htmlData; extern float _htmlPPI; extern int _htmlGrayscale; extern uchar _htmlTextColor[]; extern float _htmlBrowserWidth; extern float _htmlSizes[], _htmlSpacings[]; extern typeface_t _htmlBodyFont, _htmlHeadingFont; extern int _htmlInitialized; extern char _htmlCharSet[]; extern int _htmlWidthsLoaded[TYPE_MAX][STYLE_MAX]; extern short _htmlWidths[TYPE_MAX][STYLE_MAX][256]; extern short _htmlWidthsAll[TYPE_MAX][STYLE_MAX][65536]; extern int _htmlUnicode[]; extern uchar _htmlCharacters[]; extern int _htmlUTF8; extern const char *_htmlGlyphs[]; extern const char *_htmlGlyphsAll[]; extern const char *_htmlFonts[TYPE_MAX][STYLE_MAX]; extern int _htmlStandardFonts[TYPE_MAX]; /* * Prototypes... */ extern tree_t *htmlReadFile(tree_t *parent, FILE *fp, const char *base); extern int htmlWriteFile(tree_t *parent, FILE *fp); extern tree_t *htmlAddTree(tree_t *parent, markup_t markup, uchar *data); extern int htmlDeleteTree(tree_t *parent); extern tree_t *htmlInsertTree(tree_t *parent, markup_t markup, uchar *data); extern tree_t *htmlNewTree(tree_t *parent, markup_t markup, uchar *data); extern tree_t *htmlFindFile(tree_t *doc, uchar *filename); extern tree_t *htmlFindTarget(tree_t *doc, uchar *name); extern void htmlFixLinks(tree_t *doc, tree_t *tree, uchar *base = 0); extern uchar *htmlGetText(tree_t *tree); extern uchar *htmlGetMeta(tree_t *tree, uchar *name); extern uchar *htmlGetVariable(tree_t *t, uchar *name); extern int htmlSetVariable(tree_t *t, uchar *name, uchar *value); extern uchar *htmlGetStyle(tree_t *t, uchar *name); extern void htmlSetBaseSize(double p, double s); extern void htmlSetCharSet(const char *cs); extern void htmlSetTextColor(uchar *color); extern void htmlLoadFontWidths(int typeface, int style); extern uchar htmlMapUnicode(int ch); extern void htmlDebugStats(const char *title, tree_t *t); # ifdef __cplusplus } # endif /* __cplusplus */ #endif /* !_HTML_H_ */ htmldoc-1.9.20/htmldoc/htmldoc.cxx000066400000000000000000002240631472561501400170610ustar00rootroot00000000000000/* * Main entry for HTMLDOC, a HTML document processing program. * * Copyright 2011-2024 by Michael R Sweet. * Copyright 1997-2010 by Easy Software Products. All rights reserved. * * This program is free software. Distribution and use rights are outlined in * the file "COPYING". */ /* * Include necessary headers. */ #define _HTMLDOC_CXX_ #include "htmldoc.h" #include "markdown.h" #include #include #include #ifdef HAVE_LOCALE_H # include #endif // HAVE_LOCALE_H #ifdef WIN32 # include # include #else # include # include # include #endif // WIN32 #ifdef __APPLE__ # include #endif // __APPLE__ #ifdef __EMX__ extern "C" { const char *__XOS2RedirRoot(const char *); } #endif /* * Local types... */ typedef int (*exportfunc_t)(tree_t *, tree_t *); /* * Local functions... */ static int compare_strings(const char *s, const char *t, int tmin); static double get_seconds(void); static int load_book(const char *filename, tree_t **document, exportfunc_t *exportfunc, int set_nolocal = 0); static void parse_options(const char *line, exportfunc_t *exportfunc); static const char *prefs_getrc(void); static int read_file(const char *filename, tree_t **document, const char *path); static void set_permissions(const char *p); #ifndef WIN32 extern "C" { static void term_handler(int signum); } #endif // !WIN32 static void usage(const char *arg = NULL); /* * 'main()' - Main entry for HTMLDOC. */ int main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { int i, j; /* Looping vars */ tree_t *document, /* Master HTML document */ *file, /* HTML document file */ *toc; /* Table of contents */ exportfunc_t exportfunc; /* Export function */ const char *extension; /* Extension of output filename */ double fontsize, /* Base font size */ fontspacing; /* Base font spacing */ int num_files; /* Number of files provided on the command-line */ double start_time, /* Start time */ load_time, /* Load time */ end_time; /* End time */ const char *debug; /* HTMLDOC_DEBUG environment variable */ start_time = get_seconds(); #ifdef __APPLE__ /* * OSX passes an extra command-line option when run from the Finder. * If the first command-line argument is "-psn..." then skip it... */ if (argc > 1 && strncmp(argv[1], "-psn", 4) == 0) { argv ++; argc --; } #endif // __APPLE__ /* * Localize as needed... */ #ifdef HAVE_LOCALE_H setlocale(LC_TIME, ""); #endif // HAVE_LOCALE_H /* * Catch CTRL-C and term signals... */ #ifdef WIN32 #else signal(SIGTERM, term_handler); #endif // WIN32 /* * Set the location of data and help files... */ prefs_set_paths(); /* * Check if we are being executed as a CGI program... * * Note: We can't short-circuit this test to include a check for * PATH_INFO since that could lead to a remote execution hole. * Instead, we'll display an error message later if we can't find * a PATH_INFO variable and advise the administrator on how to * correct the problem... */ if (!getenv("HTMLDOC_NOCGI") && getenv("GATEWAY_INTERFACE") && getenv("SERVER_NAME") && getenv("SERVER_SOFTWARE")) { const char *path_translated; // PATH_TRANSLATED env var char bookfile[1024]; // Book filename // CGI mode implies the following options: // // --no-localfiles // --webpage // -t pdf // -f - // // Additional args cannot be provided on the command-line, however // we load directory-specific options from the ".book" file in the // current web server directory... CGIMode = 1; TocLevels = 0; TitlePage = 0; OutputPath[0] = '\0'; OutputType = OUTPUT_WEBPAGES; document = NULL; exportfunc = (exportfunc_t)pspdf_export; PSLevel = 0; PDFVersion = 14; PDFPageMode = PDF_DOCUMENT; PDFFirstPage = PDF_PAGE_1; file_cookies(getenv("HTTP_COOKIE")); file_referer(getenv("HTTP_REFERER")); progress_error(HD_ERROR_NONE, "INFO: HTMLDOC " SVERSION " starting in CGI mode."); #ifdef WIN32 progress_error(HD_ERROR_NONE, "INFO: TEMP is \"%s\"", getenv("TEMP")); #else progress_error(HD_ERROR_NONE, "INFO: TMPDIR is \"%s\"", getenv("TMPDIR")); #endif // WIN32 argc = 1; // Look for a book file in the following order: // // $PATH_TRANSLATED.book // `dirname $PATH_TRANSLATED`/.book // .book // // If we find one, use it... if ((path_translated = getenv("PATH_TRANSLATED")) != NULL) { // Try $PATH_TRANSLATED.book... snprintf(bookfile, sizeof(bookfile), "%s.book", path_translated); if (access(bookfile, 0)) { // Not found, try `dirname $PATH_TRANSLATED`/.book snprintf(bookfile, sizeof(bookfile), "%s/.book", file_directory(path_translated)); if (access(bookfile, 0)) strlcpy(bookfile, ".book", sizeof(bookfile)); } } else strlcpy(bookfile, ".book", sizeof(bookfile)); if (!access(bookfile, 0)) load_book(bookfile, &document, &exportfunc, 1); else file_nolocal(); } else { /* * Default to producing HTML files. */ document = NULL; exportfunc = (exportfunc_t)html_export; /* * Load preferences... */ prefs_load(); } /* * Parse command-line options... */ fontsize = 11.0f; fontspacing = 1.2f; num_files = 0; Errors = 0; for (i = 1; i < argc; i ++) { #ifdef DEBUG printf("argv[%d] = \"%s\"\n", i, argv[i]); #endif // DEBUG if (compare_strings(argv[i], "--batch", 4) == 0) { i ++; if (i < argc) { num_files ++; load_book(argv[i], &document, &exportfunc); } else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--bodycolor", 7) == 0) { i ++; if (i < argc) strlcpy((char *)BodyColor, argv[i], sizeof(BodyColor)); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--bodyfont", 7) == 0 || compare_strings(argv[i], "--textfont", 7) == 0) { i ++; if (i < argc) { if (!strcasecmp(argv[i], "monospace")) _htmlBodyFont = TYPE_MONOSPACE; else if (!strcasecmp(argv[i], "serif")) _htmlBodyFont = TYPE_SERIF; else if (!strcasecmp(argv[i], "sans-serif") || !strcasecmp(argv[i], "sans")) _htmlBodyFont = TYPE_SANS_SERIF; else if (!strcasecmp(argv[i], "courier")) _htmlBodyFont = TYPE_COURIER; else if (!strcasecmp(argv[i], "times")) _htmlBodyFont = TYPE_TIMES; else if (!strcasecmp(argv[i], "helvetica") || !strcasecmp(argv[i], "arial")) _htmlBodyFont = TYPE_HELVETICA; } else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--bodyimage", 7) == 0) { i ++; if (i < argc) strlcpy((char *)BodyImage, argv[i], sizeof(BodyImage)); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--book", 5) == 0) OutputType = OUTPUT_BOOK; else if (compare_strings(argv[i], "--bottom", 5) == 0) { i ++; if (i < argc) PageBottom = get_measurement(argv[i]); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--browserwidth", 4) == 0) { i ++; if (i < argc) { _htmlBrowserWidth = atof(argv[i]); if (_htmlBrowserWidth < 1.0f) { progress_error(HD_ERROR_INTERNAL_ERROR, "Bad browser width \"%s\"!", argv[i]); usage(); } } else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--charset", 4) == 0) { i ++; if (i < argc) htmlSetCharSet(argv[i]); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--color", 5) == 0) { OutputColor = 1; _htmlGrayscale = 0; } else if (compare_strings(argv[i], "--compression", 5) == 0 || strncmp(argv[i], "--compression=", 14) == 0) { if (strlen(argv[i]) > 14 && PDFVersion >= 12) Compression = atoi(argv[i] + 14); else if (PDFVersion >= 12) Compression = 1; } else if (compare_strings(argv[i], "--continuous", 5) == 0) { TocLevels = 0; TitlePage = 0; OutputType = OUTPUT_CONTINUOUS; PDFPageMode = PDF_DOCUMENT; PDFFirstPage = PDF_PAGE_1; } else if (compare_strings(argv[i], "--cookies", 5) == 0) { i ++; if (i < argc) file_cookies(argv[i]); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--datadir", 4) == 0) { i ++; if (i < argc) _htmlData = argv[i]; else usage(argv[i - 1]); } #if defined(HAVE_LIBFLTK) && !WIN32 else if (compare_strings(argv[i], "-display", 3) == 0 || compare_strings(argv[i], "--display", 4) == 0) { // The X standard requires support for the -display option, but // we also support the GNU standard --display... i ++; if (i < argc) Fl::display(argv[i]); else usage(argv[i - 1]); } #endif // HAVE_LIBFLTK && !WIN32 else if (compare_strings(argv[i], "--duplex", 4) == 0) PageDuplex = 1; else if (compare_strings(argv[i], "--effectduration", 4) == 0) { i ++; if (i < argc) { PDFEffectDuration = atof(argv[i]); if (PDFEffectDuration < 0.0f) { progress_error(HD_ERROR_INTERNAL_ERROR, "Bad effect duration \"%s\"!", argv[i]); usage(); } } else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--embedfonts", 4) == 0) EmbedFonts = 1; else if (compare_strings(argv[i], "--encryption", 4) == 0) Encryption = 1; else if (compare_strings(argv[i], "--firstpage", 4) == 0) { i ++; if (i >= argc) usage(argv[i - 1]); for (j = 0; j < (int)(sizeof(PDFPages) / sizeof(PDFPages[0])); j ++) if (strcasecmp(argv[i], PDFPages[j]) == 0) { PDFFirstPage = j; break; } } else if (compare_strings(argv[i], "--fontsize", 8) == 0) { i ++; if (i < argc) { fontsize = atof(argv[i]); if (fontsize < 4.0f) fontsize = 4.0f; else if (fontsize > 24.0f) fontsize = 24.0f; htmlSetBaseSize(fontsize, fontspacing); } else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--fontspacing", 8) == 0) { i ++; if (i < argc) { fontspacing = atof(argv[i]); if (fontspacing < 1.0f) fontspacing = 1.0f; else if (fontspacing > 3.0f) fontspacing = 3.0f; htmlSetBaseSize(fontsize, fontspacing); } else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--footer", 5) == 0) { i ++; if (i < argc) get_format(argv[i], Footer); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--format", 5) == 0 || strcmp(argv[i], "-t") == 0) { i ++; if (i < argc) { if (strcasecmp(argv[i], "epub") == 0) exportfunc = (exportfunc_t)epub_export; else if (strcasecmp(argv[i], "html") == 0) exportfunc = (exportfunc_t)html_export; else if (strcasecmp(argv[i], "htmlsep") == 0) exportfunc = (exportfunc_t)htmlsep_export; else if (strcasecmp(argv[i], "pdf14") == 0 || strcasecmp(argv[i], "pdf") == 0) { exportfunc = (exportfunc_t)pspdf_export; PSLevel = 0; PDFVersion = 14; } else if (strcasecmp(argv[i], "pdf13") == 0) { exportfunc = (exportfunc_t)pspdf_export; PSLevel = 0; PDFVersion = 13; } else if (strcasecmp(argv[i], "pdf12") == 0) { exportfunc = (exportfunc_t)pspdf_export; PSLevel = 0; PDFVersion = 12; } else if (strcasecmp(argv[i], "pdf11") == 0) { exportfunc = (exportfunc_t)pspdf_export; PSLevel = 0; PDFVersion = 11; Compression = 0; } else if (strcasecmp(argv[i], "ps1") == 0) { exportfunc = (exportfunc_t)pspdf_export; PSLevel = 1; } else if (strcasecmp(argv[i], "ps2") == 0 || strcasecmp(argv[i], "ps") == 0) { exportfunc = (exportfunc_t)pspdf_export; PSLevel = 2; } else if (strcasecmp(argv[i], "ps3") == 0) { exportfunc = (exportfunc_t)pspdf_export; PSLevel = 3; } else usage(argv[i - 1]); } else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--grayscale", 3) == 0) { OutputColor = 0; _htmlGrayscale = 1; } else if (!strcmp(argv[i], "--header")) { i ++; if (i < argc) get_format(argv[i], Header); else usage(argv[i - 1]); } else if (!strcmp(argv[i], "--header1")) { i ++; if (i < argc) get_format(argv[i], Header1); else usage(argv[i - 1]); } else if (!compare_strings(argv[i], "--headfootfont", 11)) { i ++; if (i < argc) { if (!strcasecmp(argv[i], "courier")) { HeadFootType = TYPE_COURIER; HeadFootStyle = STYLE_NORMAL; } else if (!strcasecmp(argv[i], "courier-bold")) { HeadFootType = TYPE_COURIER; HeadFootStyle = STYLE_BOLD; } else if (!strcasecmp(argv[i], "courier-oblique")) { HeadFootType = TYPE_COURIER; HeadFootStyle = STYLE_ITALIC; } else if (!strcasecmp(argv[i], "courier-boldoblique")) { HeadFootType = TYPE_COURIER; HeadFootStyle = STYLE_BOLD_ITALIC; } else if (!strcasecmp(argv[i], "times") || !strcasecmp(argv[i], "times-roman")) { HeadFootType = TYPE_TIMES; HeadFootStyle = STYLE_NORMAL; } else if (!strcasecmp(argv[i], "times-bold")) { HeadFootType = TYPE_TIMES; HeadFootStyle = STYLE_BOLD; } else if (!strcasecmp(argv[i], "times-italic")) { HeadFootType = TYPE_TIMES; HeadFootStyle = STYLE_ITALIC; } else if (!strcasecmp(argv[i], "times-bolditalic")) { HeadFootType = TYPE_TIMES; HeadFootStyle = STYLE_BOLD_ITALIC; } else if (!strcasecmp(argv[i], "helvetica")) { HeadFootType = TYPE_HELVETICA; HeadFootStyle = STYLE_NORMAL; } else if (!strcasecmp(argv[i], "helvetica-bold")) { HeadFootType = TYPE_HELVETICA; HeadFootStyle = STYLE_BOLD; } else if (!strcasecmp(argv[i], "helvetica-oblique")) { HeadFootType = TYPE_HELVETICA; HeadFootStyle = STYLE_ITALIC; } else if (!strcasecmp(argv[i], "helvetica-boldoblique")) { HeadFootType = TYPE_HELVETICA; HeadFootStyle = STYLE_BOLD_ITALIC; } else if (!strcasecmp(argv[i], "monospace")) { HeadFootType = TYPE_MONOSPACE; HeadFootStyle = STYLE_NORMAL; } else if (!strcasecmp(argv[i], "monospace-bold")) { HeadFootType = TYPE_MONOSPACE; HeadFootStyle = STYLE_BOLD; } else if (!strcasecmp(argv[i], "monospace-oblique")) { HeadFootType = TYPE_MONOSPACE; HeadFootStyle = STYLE_ITALIC; } else if (!strcasecmp(argv[i], "monospace-boldoblique")) { HeadFootType = TYPE_MONOSPACE; HeadFootStyle = STYLE_BOLD_ITALIC; } else if (!strcasecmp(argv[i], "serif") || !strcasecmp(argv[i], "serif-roman")) { HeadFootType = TYPE_SERIF; HeadFootStyle = STYLE_NORMAL; } else if (!strcasecmp(argv[i], "serif-bold")) { HeadFootType = TYPE_SERIF; HeadFootStyle = STYLE_BOLD; } else if (!strcasecmp(argv[i], "serif-italic")) { HeadFootType = TYPE_SERIF; HeadFootStyle = STYLE_ITALIC; } else if (!strcasecmp(argv[i], "serif-bolditalic")) { HeadFootType = TYPE_SERIF; HeadFootStyle = STYLE_BOLD_ITALIC; } else if (!strcasecmp(argv[i], "sans-serif") || !strcasecmp(argv[i], "sans")) { HeadFootType = TYPE_SANS_SERIF; HeadFootStyle = STYLE_NORMAL; } else if (!strcasecmp(argv[i], "sans-serif-bold") || !strcasecmp(argv[i], "sans-bold")) { HeadFootType = TYPE_SANS_SERIF; HeadFootStyle = STYLE_BOLD; } else if (!strcasecmp(argv[i], "sans-serif-oblique") || !strcasecmp(argv[i], "sans-oblique")) { HeadFootType = TYPE_SANS_SERIF; HeadFootStyle = STYLE_ITALIC; } else if (!strcasecmp(argv[i], "sans-serif-boldoblique") || !strcasecmp(argv[i], "sans-boldoblique")) { HeadFootType = TYPE_SANS_SERIF; HeadFootStyle = STYLE_BOLD_ITALIC; } } else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--headfootsize", 11) == 0) { i ++; if (i < argc) { HeadFootSize = atof(argv[i]); if (HeadFootSize < 6.0f) HeadFootSize = 6.0f; else if (HeadFootSize > 24.0f) HeadFootSize = 24.0f; } else usage(argv[i - 1]); } else if (!compare_strings(argv[i], "--headingfont", 7)) { i ++; if (i < argc) { if (!strcasecmp(argv[i], "courier")) _htmlHeadingFont = TYPE_COURIER; else if (!strcasecmp(argv[i], "times")) _htmlHeadingFont = TYPE_TIMES; else if (!strcasecmp(argv[i], "helvetica") || !strcasecmp(argv[i], "arial")) _htmlHeadingFont = TYPE_HELVETICA; else if (!strcasecmp(argv[i], "monospace")) _htmlHeadingFont = TYPE_MONOSPACE; else if (!strcasecmp(argv[i], "serif")) _htmlHeadingFont = TYPE_SERIF; else if (!strcasecmp(argv[i], "sans-serif") || !strcasecmp(argv[i], "sans")) _htmlHeadingFont = TYPE_SANS_SERIF; } else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--help", 6) == 0) usage(argv[i - 1]); #ifdef HAVE_LIBFLTK else if (compare_strings(argv[i], "--helpdir", 7) == 0) { i ++; if (i < argc) GUI::help_dir = argv[i]; else usage(argv[i - 1]); } #endif // HAVE_LIBFLTK else if (strncmp(argv[i], "--hfimage", 9) == 0) { int hfimgnum; // Image number char *hfptr; // Pointer into option if (strlen(argv[i]) > 9) { hfimgnum = strtol(argv[i] + 9, &hfptr, 10); if (hfimgnum < 0 || hfimgnum >= MAX_HF_IMAGES || *hfptr) usage(argv[i]); } else hfimgnum = 0; i ++; if (i >= argc) usage(argv[i - 1]); strlcpy(HFImage[hfimgnum], argv[i], sizeof(HFImage[0])); } else if (compare_strings(argv[i], "--jpeg", 3) == 0 || strncmp(argv[i], "--jpeg=", 7) == 0) { if (strlen(argv[i]) > 7) OutputJPEG = atoi(argv[i] + 7); else OutputJPEG = 90; } else if (compare_strings(argv[i], "--landscape", 4) == 0) Landscape = 1; else if (compare_strings(argv[i], "--left", 5) == 0) { i ++; if (i < argc) PageLeft = get_measurement(argv[i]); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--letterhead", 5) == 0) { i ++; if (i < argc) strlcpy(Letterhead, argv[i], sizeof(Letterhead)); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--linkcolor", 7) == 0) { i ++; if (i < argc) strlcpy(LinkColor, argv[i], sizeof(LinkColor)); else usage(argv[i - 1]); } else if (strcmp(argv[i], "--links") == 0) Links = 1; else if (compare_strings(argv[i], "--linkstyle", 8) == 0) { i ++; if (i < argc) { if (strcmp(argv[i], "plain") == 0) LinkStyle = 0; else if (strcmp(argv[i], "underline") == 0) LinkStyle = 1; else usage(argv[i - 1]); } else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--logoimage", 5) == 0) { i ++; if (i < argc) strlcpy(LogoImage, argv[i], sizeof(LogoImage)); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--no-compression", 6) == 0) Compression = 0; else if (compare_strings(argv[i], "--no-duplex", 4) == 0) PageDuplex = 0; else if (compare_strings(argv[i], "--no-embedfonts", 7) == 0) EmbedFonts = 0; else if (compare_strings(argv[i], "--no-encryption", 7) == 0) Encryption = 0; else if (compare_strings(argv[i], "--no-jpeg", 6) == 0) OutputJPEG = 0; else if (compare_strings(argv[i], "--no-links", 7) == 0) Links = 0; else if (compare_strings(argv[i], "--no-localfiles", 7) == 0) file_nolocal(); else if (compare_strings(argv[i], "--no-numbered", 6) == 0) TocNumbers = 0; else if (compare_strings(argv[i], "--no-overflow", 6) == 0) OverflowErrors = 0; else if (compare_strings(argv[i], "--no-pscommands", 6) == 0) PSCommands = 0; else if (compare_strings(argv[i], "--no-strict", 6) == 0) StrictHTML = 0; else if (compare_strings(argv[i], "--no-title", 7) == 0) TitlePage = 0; else if (compare_strings(argv[i], "--no-toc", 7) == 0) TocLevels = 0; else if (compare_strings(argv[i], "--no-truetype", 7) == 0) { fputs("htmldoc: Warning, --no-truetype option superseded by --no-embedfonts!\n", stderr); EmbedFonts = 0; } else if (compare_strings(argv[i], "--no-xrxcomments", 6) == 0) XRXComments = 0; else if (compare_strings(argv[i], "--numbered", 5) == 0) TocNumbers = 1; else if (compare_strings(argv[i], "--nup", 5) == 0) { i ++; if (i >= argc) usage(argv[i - 1]); NumberUp = atoi(argv[i]); if (NumberUp != 1 && NumberUp != 2 && NumberUp != 4 && NumberUp != 6 && NumberUp != 9 && NumberUp != 16) usage(argv[i - 1]); } else if (compare_strings(argv[i], "--outdir", 6) == 0 || strcmp(argv[i], "-d") == 0) { i ++; if (i < argc) { strlcpy(OutputPath, argv[i], sizeof(OutputPath)); OutputFiles = 1; } else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--outfile", 6) == 0 || strcmp(argv[i], "-f") == 0) { i ++; if (i < argc) { strlcpy(OutputPath, argv[i], sizeof(OutputPath)); OutputFiles = 0; if ((extension = file_extension(argv[i])) != NULL) { if (strcasecmp(extension, "epub") == 0) exportfunc = (exportfunc_t)epub_export; else if (strcasecmp(extension, "html") == 0) exportfunc = (exportfunc_t)html_export; else if (strcasecmp(extension, "pdf") == 0) { exportfunc = (exportfunc_t)pspdf_export; PSLevel = 0; } else if (strcasecmp(extension, "ps") == 0) { exportfunc = (exportfunc_t)pspdf_export; if (PSLevel == 0) PSLevel = 2; } } } else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--overflow", 4) == 0) OverflowErrors = 1; else if (compare_strings(argv[i], "--owner-password", 4) == 0) { i ++; if (i < argc) strlcpy(OwnerPassword, argv[i], sizeof(OwnerPassword)); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--pageduration", 7) == 0) { i ++; if (i < argc) { PDFPageDuration = atof(argv[i]); if (PDFPageDuration < 1.0f) { progress_error(HD_ERROR_INTERNAL_ERROR, "Bad page duration \"%s\"!", argv[i]); usage(); } } else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--pageeffect", 7) == 0) { i ++; if (i >= argc) usage(argv[i - 1]); for (j = 0; j < (int)(sizeof(PDFEffects) / sizeof(PDFEffects[0])); j ++) if (strcasecmp(argv[i], PDFEffects[j]) == 0) { PDFEffect = j; break; } } else if (compare_strings(argv[i], "--pagelayout", 7) == 0) { i ++; if (i >= argc) usage(argv[i - 1]); for (j = 0; j < (int)(sizeof(PDFLayouts) / sizeof(PDFLayouts[0])); j ++) if (strcasecmp(argv[i], PDFLayouts[j]) == 0) { PDFPageLayout = j; break; } } else if (compare_strings(argv[i], "--pagemode", 7) == 0) { i ++; if (i >= argc) usage(argv[i - 1]); for (j = 0; j < (int)(sizeof(PDFModes) / sizeof(PDFModes[0])); j ++) if (strcasecmp(argv[i], PDFModes[j]) == 0) { PDFPageMode = j; break; } } else if (compare_strings(argv[i], "--path", 5) == 0) { i ++; if (i < argc) strlcpy(Path, argv[i], sizeof(Path)); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--permissions", 4) == 0) { i ++; if (i >= argc) usage(argv[i - 1]); set_permissions(argv[i]); } else if (compare_strings(argv[i], "--portrait", 4) == 0) Landscape = 0; else if (compare_strings(argv[i], "--pre-indent", 5) == 0) { i ++; if (i < argc) PreIndent = get_measurement(argv[i]); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--proxy", 4) == 0) { i ++; if (i < argc) { strlcpy(Proxy, argv[i], sizeof(Proxy)); file_proxy(Proxy); } else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--pscommands", 3) == 0) PSCommands = 1; else if (compare_strings(argv[i], "--quiet", 3) == 0) Verbosity = -1; else if (!compare_strings(argv[i], "--referer", 4)) { i ++; if (i < argc) file_referer(argv[i]); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--right", 4) == 0) { i ++; if (i < argc) PageRight = get_measurement(argv[i]); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--size", 4) == 0) { i ++; if (i < argc) set_page_size(argv[i]); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--strict", 4) == 0) StrictHTML = 1; else if (compare_strings(argv[i], "--textcolor", 7) == 0) { i ++; if (i < argc) htmlSetTextColor((uchar *)argv[i]); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--title", 7) == 0) TitlePage = 1; else if (compare_strings(argv[i], "--titlefile", 8) == 0 || compare_strings(argv[i], "--titleimage", 8) == 0) { i ++; if (i < argc) strlcpy(TitleImage, argv[i], sizeof(TitleImage)); else usage(argv[i - 1]); TitlePage = 1; } else if (compare_strings(argv[i], "--tocfooter", 6) == 0) { i ++; if (i < argc) get_format(argv[i], TocFooter); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--tocheader", 6) == 0) { i ++; if (i < argc) get_format(argv[i], TocHeader); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--toclevels", 6) == 0) { i ++; if (i < argc) TocLevels = atoi(argv[i]); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--toctitle", 6) == 0) { i ++; if (i < argc) strlcpy(TocTitle, argv[i], sizeof(TocTitle)); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--top", 5) == 0) { i ++; if (i < argc) PageTop = get_measurement(argv[i]); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--user-password", 4) == 0) { i ++; if (i < argc) strlcpy(UserPassword, argv[i], sizeof(UserPassword)); else usage(argv[i - 1]); } else if (compare_strings(argv[i], "--truetype", 4) == 0) { fputs("htmldoc: Warning, --truetype option superseded by --embedfonts!\n", stderr); EmbedFonts = 1; } else if (compare_strings(argv[i], "--verbose", 6) == 0 || strcmp(argv[i], "-v") == 0) { Verbosity ++; } else if (compare_strings(argv[i], "--version", 6) == 0) { puts(SVERSION); return (0); } else if (compare_strings(argv[i], "--webpage", 3) == 0) { TocLevels = 0; TitlePage = 0; OutputType = OUTPUT_WEBPAGES; PDFPageMode = PDF_DOCUMENT; PDFFirstPage = PDF_PAGE_1; } else if (compare_strings(argv[i], "--xrxcomments", 3) == 0) XRXComments = 1; else if (strcmp(argv[i], "-") == 0) { /* * Read from stdin... */ num_files ++; _htmlPPI = 72.0f * _htmlBrowserWidth / (PageWidth - PageLeft - PageRight); file = htmlAddTree(NULL, MARKUP_FILE, NULL); htmlSetVariable(file, (uchar *)"_HD_FILENAME", (uchar *)""); htmlSetVariable(file, (uchar *)"_HD_BASE", (uchar *)"."); #ifdef WIN32 // Make sure stdin is in binary mode. // (I hate Microsoft... I hate Microsoft... Everybody join in!) setmode(0, O_BINARY); #elif defined(__EMX__) // OS/2 has a setmode for FILE's... fflush(stdin); _fsetmode(stdin, "b"); #endif // WIN32 || __EMX__ _htmlCurrentFile = "(stdin)"; htmlReadFile(file, stdin, "."); if (document == NULL) document = file; else { while (document->next != NULL) document = document->next; document->next = file; file->prev = document; } } else if (argv[i][0] == '-') usage(argv[i]); #ifdef HAVE_LIBFLTK else if (strlen(argv[i]) > 5 && strcmp(argv[i] + strlen(argv[i]) - 5, ".book") == 0) { /* * GUI mode... */ if (BookGUI == NULL) BookGUI = new GUI(argv[i]); else BookGUI->loadBook(argv[i]); } #endif /* HAVE_LIBFLTK */ else { num_files ++; read_file(argv[i], &document, Path); } } if (CGIMode) { char url[1024]; // URL const char *https, // HTTPS env var, if any *path_info, // Path info, if any *query, // Query string, if any *server_name, // Server name *server_port; // Server port https = getenv("HTTPS"); path_info = getenv("PATH_INFO"); query = getenv("QUERY_STRING"); server_name = getenv("SERVER_NAME"); server_port = getenv("SERVER_PORT"); if (server_port && path_info && *path_info) { // Read the referenced file from the local server... if (https && strcmp(https, "off")) httpAssembleURI(HTTP_URI_CODING_ALL, url, sizeof(url), "https", NULL, server_name, atoi(server_port), path_info); else httpAssembleURI(HTTP_URI_CODING_ALL, url, sizeof(url), "http", NULL, server_name, atoi(server_port), path_info); if (query && *query && *query != '-') { // Include query string on end of URL, which is already URI encoded... strlcat(url, "?", sizeof(url)); strlcat(url, query, sizeof(url)); } progress_error(HD_ERROR_NONE, "INFO: HTMLDOC converting \"%s\".", url); num_files ++; read_file(url, &document, Path); } else progress_error(HD_ERROR_FILE_NOT_FOUND, "PATH_INFO is not set in the environment!"); } /* * Display the GUI if necessary... */ #ifdef HAVE_LIBFLTK if (num_files == 0 && BookGUI == NULL) BookGUI = new GUI(); if (BookGUI != NULL) { Fl_File_Icon::load_system_icons(); BookGUI->show(); i = Fl::run(); delete BookGUI; return (i); } #endif /* HAVE_LIBFLTK */ /* * We *must* have a document to process... */ if (num_files == 0 || document == NULL) usage("No HTML files!"); /* * Find the first one in the list... */ while (document && document->prev != NULL) document = document->prev; // Fix links... htmlFixLinks(document, document); load_time = get_seconds(); // Show debug info... htmlDebugStats("Document Tree", document); /* * Build a table of contents for the documents if necessary... */ if (OutputType == OUTPUT_BOOK && TocLevels > 0) { toc = toc_build(document); } else { if (TocNumbers) htmlDeleteTree(toc_build(document)); toc = NULL; } htmlDebugStats("Table of Contents Tree", toc); /* * Generate the output file(s). */ (*exportfunc)(document, toc); end_time = get_seconds(); /* * Report running time statistics as needed... */ if ((debug = getenv("HTMLDOC_DEBUG")) != NULL && (strstr(debug, "all") != NULL || strstr(debug, "timing") != NULL)) progress_error(HD_ERROR_NONE, "TIMING: %.3f %.3f %.3f", load_time - start_time, end_time - load_time, end_time - start_time); /* * Cleanup... */ htmlDeleteTree(document); htmlDeleteTree(toc); file_cleanup(); image_flush_cache(); return (Errors); } /* * 'prefs_getrc()' - Get the rc file for preferences... */ static const char * prefs_getrc(void) { #ifdef WIN32 HKEY key; // Registry key DWORD size; // Size of string char home[1024]; // Home (profile) directory #else const char *home; // Home directory #endif // WIN32 static char htmldocrc[1024];// HTMLDOC RC file // Find the home directory... #ifdef WIN32 // Open the registry... if (RegOpenKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_READ, &key)) { // Use the install directory... strlcpy(home, _htmlData, sizeof(home)); } else { // Grab the current user's AppData directory... size = sizeof(home); if (RegQueryValueEx(key, "AppData", NULL, NULL, (unsigned char *)home, &size)) strlcpy(home, _htmlData, sizeof(home)); RegCloseKey(key); } #else if ((home = getenv("HOME")) == NULL) home = _htmlData; #endif // WIN32 // Format the rc filename and return... snprintf(htmldocrc, sizeof(htmldocrc), "%s/.htmldocrc", home); return (htmldocrc); } /* * 'prefs_load()' - Load HTMLDOC preferences... */ void prefs_load(void) { int pos; // Header/footer position char line[2048]; // Line from RC file FILE *fp; // File pointer // // Read the preferences file... // if ((fp = fopen(prefs_getrc(), "r")) != NULL) { while (fgets(line, sizeof(line), fp) != NULL) { if (line[strlen(line) - 1] == '\n') line[strlen(line) - 1] = '\0'; if (strncasecmp(line, "TEXTCOLOR=", 10) == 0) htmlSetTextColor((uchar *)(line + 10)); else if (strncasecmp(line, "BODYCOLOR=", 10) == 0) strlcpy(BodyColor, line + 10, sizeof(BodyColor)); else if (strncasecmp(line, "BODYIMAGE=", 10) == 0) strlcpy(BodyImage, line + 10, sizeof(BodyImage)); else if (strncasecmp(line, "LINKCOLOR=", 10) == 0) strlcpy(LinkColor, line + 10, sizeof(LinkColor)); else if (strncasecmp(line, "LINKSTYLE=", 10) == 0) LinkStyle = atoi(line + 10); else if (strncasecmp(line, "BROWSERWIDTH=", 13) == 0) _htmlBrowserWidth = atof(line + 13); else if (strncasecmp(line, "PAGEWIDTH=", 10) == 0) PageWidth = atoi(line + 10); else if (strncasecmp(line, "PAGELENGTH=", 11) == 0) PageLength = atoi(line + 11); else if (strncasecmp(line, "PAGELEFT=", 9) == 0) PageLeft = atoi(line + 9); else if (strncasecmp(line, "PAGERIGHT=", 10) == 0) PageRight = atoi(line + 10); else if (strncasecmp(line, "PAGETOP=", 8) == 0) PageTop = atoi(line + 8); else if (strncasecmp(line, "PAGEBOTTOM=", 11) == 0) PageBottom = atoi(line + 11); else if (strncasecmp(line, "PAGEDUPLEX=", 11) == 0) PageDuplex = atoi(line + 11); else if (strncasecmp(line, "LANDSCAPE=", 10) == 0) Landscape = atoi(line + 10); else if (strncasecmp(line, "COMPRESSION=", 12) == 0) Compression = atoi(line + 12); else if (strncasecmp(line, "OUTPUTCOLOR=", 12) == 0) { OutputColor = atoi(line + 12); _htmlGrayscale = !OutputColor; } else if (strncasecmp(line, "TOCNUMBERS=", 11) == 0) TocNumbers = atoi(line + 11); else if (strncasecmp(line, "TOCLEVELS=", 10) == 0) TocLevels = atoi(line + 10); else if (strncasecmp(line, "JPEG=", 5) == 0) OutputJPEG = atoi(line + 1); else if (strncasecmp(line, "PAGEHEADER=", 11) == 0) get_format(line + 11, Header); else if (strncasecmp(line, "PAGEFOOTER=", 11) == 0) get_format(line + 11, Footer); else if (strncasecmp(line, "NUMBERUP=", 9) == 0) NumberUp = atoi(line + 9); else if (strncasecmp(line, "TOCHEADER=", 10) == 0) get_format(line + 10, TocHeader); else if (strncasecmp(line, "TOCFOOTER=", 10) == 0) get_format(line + 10, TocFooter); else if (strncasecmp(line, "TOCTITLE=", 9) == 0) strlcpy(TocTitle, line + 9, sizeof(TocTitle)); else if (strncasecmp(line, "BODYFONT=", 9) == 0) _htmlBodyFont = (typeface_t)atoi(line + 9); else if (strncasecmp(line, "HEADINGFONT=", 12) == 0) _htmlHeadingFont = (typeface_t)atoi(line + 12); else if (strncasecmp(line, "FONTSIZE=", 9) == 0) htmlSetBaseSize(atof(line + 9), _htmlSpacings[SIZE_P] / _htmlSizes[SIZE_P]); else if (strncasecmp(line, "FONTSPACING=", 12) == 0) htmlSetBaseSize(_htmlSizes[SIZE_P], atof(line + 12)); else if (strncasecmp(line, "HEADFOOTTYPE=", 13) == 0) HeadFootType = (typeface_t)atoi(line + 13); else if (strncasecmp(line, "HEADFOOTSTYLE=", 14) == 0) HeadFootStyle = (style_t)atoi(line + 14); else if (strncasecmp(line, "HEADFOOTSIZE=", 13) == 0) HeadFootSize = atof(line + 13); else if (strncasecmp(line, "PDFVERSION=", 11) == 0) { if (strchr(line + 11, '.') != NULL) PDFVersion = (int)(atof(line + 11) * 10.0 + 0.5); else PDFVersion = atoi(line + 11); } else if (strncasecmp(line, "PSLEVEL=", 8) == 0) PSLevel = atoi(line + 8); else if (strncasecmp(line, "PSCOMMANDS=", 11) == 0) PSCommands = atoi(line + 11); else if (strncasecmp(line, "XRXCOMMENTS=", 12) == 0) XRXComments = atoi(line + 12); else if (strncasecmp(line, "CHARSET=", 8) == 0) htmlSetCharSet(line + 8); else if (strncasecmp(line, "PAGEMODE=", 9) == 0) PDFPageMode = atoi(line + 9); else if (strncasecmp(line, "PAGELAYOUT=", 11) == 0) PDFPageLayout = atoi(line + 11); else if (strncasecmp(line, "FIRSTPAGE=", 10) == 0) PDFFirstPage = atoi(line + 10); else if (strncasecmp(line, "PAGEEFFECT=", 11) == 0) PDFEffect = atoi(line + 11); else if (strncasecmp(line, "PAGEDURATION=", 14) == 0) PDFPageDuration = atof(line + 14); else if (strncasecmp(line, "EFFECTDURATION=", 16) == 0) PDFEffectDuration = atof(line + 16); else if (strncasecmp(line, "ENCRYPTION=", 11) == 0) Encryption = atoi(line + 11); else if (strncasecmp(line, "PERMISSIONS=", 12) == 0) Permissions = atoi(line + 12); else if (strncasecmp(line, "OWNERPASSWORD=", 14) == 0) strlcpy(OwnerPassword, line + 14, sizeof(OwnerPassword)); else if (strncasecmp(line, "USERPASSWORD=", 13) == 0) strlcpy(UserPassword, line + 13, sizeof(UserPassword)); else if (strncasecmp(line, "LINKS=", 6) == 0) Links = atoi(line + 6); else if (strncasecmp(line, "TRUETYPE=", 9) == 0) EmbedFonts = atoi(line + 9); else if (strncasecmp(line, "EMBEDFONTS=", 11) == 0) EmbedFonts = atoi(line + 11); else if (strncasecmp(line, "PATH=", 5) == 0) strlcpy(Path, line + 5, sizeof(Path)); else if (strncasecmp(line, "PROXY=", 6) == 0) strlcpy(Proxy, line + 6, sizeof(Proxy)); else if (strncasecmp(line, "STRICTHTML=", 11) == 0) StrictHTML = atoi(line + 11); # ifdef HAVE_LIBFLTK else if (strncasecmp(line, "EDITOR=", 7) == 0) strlcpy(HTMLEditor, line + 7, sizeof(HTMLEditor)); else if (strncasecmp(line, "TOOLTIPS=", 9) == 0) Tooltips = atoi(line + 9); # endif // HAVE_LIBFLTK } fclose(fp); } // Check header/footer formats... for (pos = 0; pos < 3; pos ++) if (Header[pos]) break; if (pos == 3) get_format(".t.", Header); for (pos = 0; pos < 3; pos ++) if (Footer[pos]) break; if (pos == 3) get_format("h.1", Footer); for (pos = 0; pos < 3; pos ++) if (TocHeader[pos]) break; if (pos == 3) get_format(".t.", TocHeader); for (pos = 0; pos < 3; pos ++) if (TocFooter[pos]) break; if (pos == 3) get_format("..i", TocFooter); } /* * 'prefs_save()' - Save HTMLDOC preferences... */ void prefs_save(void) { FILE *fp; // File pointer if ((fp = fopen(prefs_getrc(), "w")) != NULL) { fputs("#HTMLDOCRC " SVERSION "\n", fp); fprintf(fp, "TEXTCOLOR=%s\n", _htmlTextColor); fprintf(fp, "BODYCOLOR=%s\n", BodyColor); fprintf(fp, "BODYIMAGE=%s\n", BodyImage); fprintf(fp, "LINKCOLOR=%s\n", LinkColor); fprintf(fp, "LINKSTYLE=%d\n", LinkStyle); fprintf(fp, "BROWSERWIDTH=%.0f\n", _htmlBrowserWidth); fprintf(fp, "PAGEWIDTH=%d\n", PageWidth); fprintf(fp, "PAGELENGTH=%d\n", PageLength); fprintf(fp, "PAGELEFT=%d\n", PageLeft); fprintf(fp, "PAGERIGHT=%d\n", PageRight); fprintf(fp, "PAGETOP=%d\n", PageTop); fprintf(fp, "PAGEBOTTOM=%d\n", PageBottom); fprintf(fp, "PAGEDUPLEX=%d\n", PageDuplex); fprintf(fp, "LANDSCAPE=%d\n", Landscape); fprintf(fp, "COMPRESSION=%d\n", Compression); fprintf(fp, "OUTPUTCOLOR=%d\n", OutputColor); fprintf(fp, "TOCNUMBERS=%d\n", TocNumbers); fprintf(fp, "TOCLEVELS=%d\n", TocLevels); fprintf(fp, "JPEG=%d\n", OutputJPEG); fprintf(fp, "PAGEHEADER=%s\n", get_fmt(Header)); fprintf(fp, "PAGEFOOTER=%s\n", get_fmt(Footer)); fprintf(fp, "NUMBERUP=%d\n", NumberUp); fprintf(fp, "TOCHEADER=%s\n", get_fmt(TocHeader)); fprintf(fp, "TOCFOOTER=%s\n", get_fmt(TocFooter)); fprintf(fp, "TOCTITLE=%s\n", TocTitle); fprintf(fp, "BODYFONT=%d\n", _htmlBodyFont); fprintf(fp, "HEADINGFONT=%d\n", _htmlHeadingFont); fprintf(fp, "FONTSIZE=%.2f\n", _htmlSizes[SIZE_P]); fprintf(fp, "FONTSPACING=%.2f\n", _htmlSpacings[SIZE_P] / _htmlSizes[SIZE_P]); fprintf(fp, "HEADFOOTTYPE=%d\n", HeadFootType); fprintf(fp, "HEADFOOTSTYLE=%d\n", HeadFootStyle); fprintf(fp, "HEADFOOTSIZE=%.2f\n", HeadFootSize); fprintf(fp, "PDFVERSION=%d\n", PDFVersion); fprintf(fp, "PSLEVEL=%d\n", PSLevel); fprintf(fp, "PSCOMMANDS=%d\n", PSCommands); fprintf(fp, "XRXCOMMENTS=%d\n", XRXComments); fprintf(fp, "CHARSET=%s\n", _htmlCharSet); fprintf(fp, "PAGEMODE=%d\n", PDFPageMode); fprintf(fp, "PAGELAYOUT=%d\n", PDFPageLayout); fprintf(fp, "FIRSTPAGE=%d\n", PDFFirstPage); fprintf(fp, "PAGEEFFECT=%d\n", PDFEffect); fprintf(fp, "PAGEDURATION=%.0f\n", PDFPageDuration); fprintf(fp, "EFFECTDURATION=%.1f\n", PDFEffectDuration); fprintf(fp, "ENCRYPTION=%d\n", Encryption); fprintf(fp, "PERMISSIONS=%d\n", Permissions); fprintf(fp, "OWNERPASSWORD=%s\n", OwnerPassword); fprintf(fp, "USERPASSWORD=%s\n", UserPassword); fprintf(fp, "LINKS=%d\n", Links); fprintf(fp, "EMBEDFONTS=%d\n", EmbedFonts); fprintf(fp, "PATH=%s\n", Path); fprintf(fp, "PROXY=%s\n", Proxy); fprintf(fp, "STRICTHTML=%d\n", StrictHTML); #ifdef HAVE_LIBFLTK fprintf(fp, "EDITOR=%s\n", HTMLEditor); fprintf(fp, "TOOLTIPS=%d\n", Tooltips); #endif // HAVE_LIBFLTK fclose(fp); } } /* * 'prefs_set_paths()' - Set HTMLDOC data/help paths... */ void prefs_set_paths(void) { // // Get the installed directories... // #ifdef WIN32 //// Do registry magic... HKEY key; // Registry key DWORD size; // Size of string static char data[1024]; // Data directory static char doc[1024]; // Documentation directory static char path[4096]; // PATH environment variable // Open the registry... if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\HTMLDOC", 0, KEY_READ, &key)) { // Grab the installed directories... size = sizeof(data); if (!RegQueryValueEx(key, "data", NULL, NULL, (unsigned char *)data, &size)) _htmlData = data; else progress_error(HD_ERROR_FILE_NOT_FOUND, "Unable to read \"data\" value from registry!"); # ifdef HAVE_LIBFLTK size = sizeof(doc); if (!RegQueryValueEx(key, "doc", NULL, NULL, (unsigned char *)doc, &size)) GUI::help_dir = doc; # endif // HAVE_LIBFLTK RegCloseKey(key); } else progress_error(HD_ERROR_FILE_NOT_FOUND, "Unable to read HTMLDOC installation from registry!"); // See if the HTMLDOC program folder is in the system execution path... if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_READ | KEY_WRITE, &key)) { // Grab the current path... size = sizeof(path); if (!RegQueryValueEx(key, "Path", NULL, NULL, (unsigned char *)path, &size)) if (strstr(path, _htmlData) == NULL) { // The data directory is not in the path, so add it... strlcat(path, ";", sizeof(path)); strlcat(path, _htmlData, sizeof(path)); RegSetValueEx(key, "Path", 0, REG_EXPAND_SZ, (unsigned char *)path, strlen(path) + 1); } } #elif defined(__EMX__) && defined(HAVE_LIBFLTK) // If being installed within XFree86 OS/2 Environment // we can use those values which are overwritten by // the according environment variables. _htmlData = strdup(__XOS2RedirRoot("/XFree86/lib/X11/htmldoc")); GUI::help_dir = strdup(__XOS2RedirRoot("/XFree86/lib/X11/htmldoc/doc")); #elif defined(__APPLE__) && defined(HAVE_LIBFLTK) char path[PROC_PIDPATHINFO_MAXSIZE + 1]; // Process path int pathlen; // Length of path string static char resources[1024]; // Resources directory if ((pathlen = proc_pidpath(getpid(), path, sizeof(path) - 1)) >= 0) { char *ptr; // Pointer into path path[pathlen] = '\0'; // printf("proc_pidpath returned \"%s\"\n", path); if ((ptr = strstr(path, "/Contents/MacOS")) != NULL) { *ptr = '\0'; // printf("Bundle path is \"%s\"\n", path); snprintf(resources, sizeof(resources), "%s/Contents/Resources", path); _htmlData = resources; GUI::help_dir = resources; } } // else // perror("proc_pidpath failed"); #elif defined(__linux) const char *snap; // SNAP environment variable // Support HTMLDOC as a snap package... if ((snap = getenv("SNAP")) != NULL) { static char datadir[1024]; // Data directory snprintf(datadir, sizeof(datadir), "%s/share/htmldoc", snap); _htmlData = datadir; # ifdef HAVE_LIBFLTK static char docdir[1024]; // Documentation directory snprintf(docdir, sizeof(docdir), "%s/share/doc/htmldoc", snap); GUI::help_dir = docdir; # endif // HAVE_LIBFLTK } #endif // WIN32 // // See if the installed directories have been overridden by // environment variables... // if (getenv("HTMLDOC_DATA") != NULL) _htmlData = getenv("HTMLDOC_DATA"); #ifdef HAVE_LIBFLTK if (getenv("HTMLDOC_HELP") != NULL) GUI::help_dir = getenv("HTMLDOC_HELP"); #endif // HAVE_LIBFLTK } /* * 'compare_strings()' - Compare two command-line strings. */ static int /* O - -1 or 1 = no match, 0 = match */ compare_strings(const char *s, /* I - Command-line string */ const char *t, /* I - Option string */ int tmin) /* I - Minimum number of unique chars in option */ { size_t slen; /* Length of command-line string */ slen = strlen(s); if (slen < (size_t)tmin) return (-1); else return (strncmp(s, t, slen)); } /* * 'get_seconds()' - Get the current fractional time in seconds. */ static double /* O - Number of seconds */ get_seconds(void) { #ifdef WIN32 return (GetTickCount() * 0.001); #else struct timeval curtime; /* Current time */ gettimeofday(&curtime, NULL); return (curtime.tv_sec + curtime.tv_usec * 0.000001); #endif /* WIN32 */ } // // 'load_book()' - Load a book file... // static int // O - 1 = success, 0 = failure load_book(const char *filename, // I - Book file tree_t **document, // IO - Document tree exportfunc_t *exportfunc, // O - Export function int set_nolocal) // I - Set file_nolocal() after lookup? { FILE *fp; // File to read from char line[10240]; // Line from file const char *dir; // Directory const char *local; // Local filename char path[2048]; // Current path // See if the filename contains a path... dir = file_directory(filename); if (dir != NULL) snprintf(path, sizeof(path), "%s;%s", dir, Path); else strlcpy(path, Path, sizeof(path)); // Open the file... local = file_find(Path, filename); if (set_nolocal) file_nolocal(); if (!local) return (0); if ((fp = fopen(local, "rb")) == NULL) { progress_error(HD_ERROR_READ_ERROR, "Unable to open book file \"%s\": %s", local, strerror(errno)); return (0); } // Get the header... file_gets(line, sizeof(line), fp); if (strncmp(line, "#HTMLDOC", 8) != 0) { fclose(fp); progress_error(HD_ERROR_BAD_FORMAT, "Bad or missing #HTMLDOC header in \"%s\".", filename); return (0); } // Read the second line from the book file; for older book files, this will // be the file count; for new files this will be the options... do { file_gets(line, sizeof(line), fp); if (line[0] == '-') { parse_options(line, exportfunc); if (dir != NULL) snprintf(path, sizeof(path), "%s;%s", dir, Path); else strlcpy(path, Path, sizeof(path)); } } while (!line[0]); // Skip blank lines // Get input files/options... while (file_gets(line, sizeof(line), fp) != NULL) { if (!line[0]) continue; // Skip blank lines else if (line[0] == '-') { parse_options(line, exportfunc); if (dir != NULL) snprintf(path, sizeof(path), "%s;%s", dir, Path); else strlcpy(path, Path, sizeof(path)); } else if (line[0] == '\\') read_file(line + 1, document, path); else read_file(line, document, path); } // Close the book file and return... fclose(fp); return (1); } // // 'parse_options()' - Parse options from a book file... // static void parse_options(const char *line, // I - Options from book file exportfunc_t *exportfunc) // O - Export function { int i; // Looping var const char *lineptr; // Pointer into line char temp[1024], // Option name temp2[1024], // Option value *tempptr; // Pointer into option double fontsize, // Size of body text fontspacing; // Spacing between lines // Parse the input line... for (lineptr = line; *lineptr != '\0';) { while (*lineptr == ' ') lineptr ++; for (tempptr = temp; *lineptr != '\0' && *lineptr != ' '; lineptr ++) if (tempptr < (temp + sizeof(temp) - 1)) *tempptr++ = *lineptr; *tempptr = '\0'; while (*lineptr == ' ') lineptr ++; if (strcmp(temp, "--duplex") == 0) { PageDuplex = 1; continue; } else if (strcmp(temp, "--landscape") == 0) { Landscape = 1; continue; } else if (strcmp(temp, "--portrait") == 0) { Landscape = 0; continue; } else if (strncmp(temp, "--jpeg", 6) == 0) { if (strlen(temp) > 7) OutputJPEG = atoi(temp + 7); else OutputJPEG = 90; continue; } else if (strcmp(temp, "--grayscale") == 0) { OutputColor = 0; continue; } else if (strcmp(temp, "--color") == 0) { OutputColor = 1; continue; } else if (strcmp(temp, "--links") == 0) { Links = 1; continue; } else if (strcmp(temp, "--no-links") == 0) { Links = 0; continue; } else if (strcmp(temp, "--embedfonts") == 0 || strcmp(temp, "--truetype") == 0) { EmbedFonts = 1; continue; } else if (strcmp(temp, "--no-embedfonts") == 0 || strcmp(temp, "--no-truetype") == 0) { EmbedFonts = 0; continue; } else if (strcmp(temp, "--pscommands") == 0) { PSCommands = 1; continue; } else if (strcmp(temp, "--no-pscommands") == 0) { PSCommands = 0; continue; } else if (strcmp(temp, "--xrxcomments") == 0) { XRXComments = 1; continue; } else if (strcmp(temp, "--no-xrxcomments") == 0) { XRXComments = 0; continue; } else if (strncmp(temp, "--compression", 13) == 0) { if (strlen(temp) > 14) Compression = atoi(temp + 14); else Compression = 1; continue; } else if (strcmp(temp, "--no-compression") == 0) { Compression = 0; continue; } else if (strcmp(temp, "--no-jpeg") == 0) { OutputJPEG = 0; continue; } else if (strcmp(temp, "--numbered") == 0) { TocNumbers = 1; continue; } else if (strcmp(temp, "--no-numbered") == 0) { TocNumbers = 0; continue; } else if (strcmp(temp, "--no-toc") == 0) { TocLevels = 0; continue; } else if (strcmp(temp, "--title") == 0) { TitlePage = 1; continue; } else if (strcmp(temp, "--no-title") == 0) { TitlePage = 0; continue; } else if (strcmp(temp, "--book") == 0) { OutputType = OUTPUT_BOOK; continue; } else if (strcmp(temp, "--continuous") == 0) { OutputType = OUTPUT_CONTINUOUS; continue; } else if (strcmp(temp, "--webpage") == 0) { OutputType = OUTPUT_WEBPAGES; continue; } else if (strcmp(temp, "--encryption") == 0) { Encryption = 1; continue; } else if (strcmp(temp, "--no-encryption") == 0) { Encryption = 0; continue; } else if (strcmp(temp, "--strict") == 0) StrictHTML = 1; else if (strcmp(temp, "--no-strict") == 0) StrictHTML = 0; else if (strcmp(temp, "--overflow") == 0) OverflowErrors = 1; else if (strcmp(temp, "--no-overflow") == 0) OverflowErrors = 0; if (*lineptr == '\"') { lineptr ++; for (tempptr = temp2; *lineptr != '\0' && *lineptr != '\"'; lineptr ++) if (tempptr < (temp2 + sizeof(temp2) - 1)) *tempptr++ = *lineptr; if (*lineptr == '\"') lineptr ++; } else { for (tempptr = temp2; *lineptr != '\0' && *lineptr != ' '; lineptr ++) if (tempptr < (temp2 + sizeof(temp2) - 1)) *tempptr++ = *lineptr; } *tempptr = '\0'; if (strcmp(temp, "-t") == 0 && !CGIMode) { if (strcmp(temp2, "epub") == 0) *exportfunc = (exportfunc_t)epub_export; else if (strcmp(temp2, "html") == 0) *exportfunc = (exportfunc_t)html_export; else if (strcmp(temp2, "htmlsep") == 0) *exportfunc = (exportfunc_t)htmlsep_export; else if (strcmp(temp2, "pdf11") == 0) { *exportfunc = (exportfunc_t)pspdf_export; PSLevel = 0; PDFVersion = 11; } else if (strcmp(temp2, "pdf12") == 0) { *exportfunc = (exportfunc_t)pspdf_export; PSLevel = 0; PDFVersion = 12; } else if (strcmp(temp2, "pdf13") == 0) { *exportfunc = (exportfunc_t)pspdf_export; PSLevel = 0; PDFVersion = 13; } else if (strcmp(temp2, "pdf") == 0 || strcmp(temp2, "pdf14") == 0) { *exportfunc = (exportfunc_t)pspdf_export; PSLevel = 0; PDFVersion = 14; } else if (strcmp(temp2, "ps1") == 0) { *exportfunc = (exportfunc_t)pspdf_export; PSLevel = 1; } else if (strcmp(temp2, "ps") == 0 || strcmp(temp2, "ps2") == 0) { *exportfunc = (exportfunc_t)pspdf_export; PSLevel = 2; } else if (strcmp(temp2, "ps3") == 0) { *exportfunc = (exportfunc_t)pspdf_export; PSLevel = 3; } } else if (strcmp(temp, "--letterhead") == 0) strlcpy(Letterhead, temp2, sizeof(Letterhead)); else if (strcmp(temp, "--logo") == 0 || strcmp(temp, "--logoimage") == 0) strlcpy(LogoImage, temp2, sizeof(LogoImage)); else if (strcmp(temp, "--titlefile") == 0 || strcmp(temp, "--titleimage") == 0) { TitlePage = 1; strlcpy(TitleImage, temp2, sizeof(TitleImage)); } else if (strcmp(temp, "-f") == 0 && !CGIMode) { OutputFiles = 0; strlcpy(OutputPath, temp2, sizeof(OutputPath)); } else if (strcmp(temp, "-d") == 0 && !CGIMode) { OutputFiles = 1; strlcpy(OutputPath, temp2, sizeof(OutputPath)); } else if (strcmp(temp, "--browserwidth") == 0) _htmlBrowserWidth = atof(temp2); else if (strcmp(temp, "--nup") == 0) NumberUp = atoi(temp2); else if (strcmp(temp, "--size") == 0) set_page_size(temp2); else if (strcmp(temp, "--left") == 0) PageLeft = get_measurement(temp2); else if (strcmp(temp, "--right") == 0) PageRight = get_measurement(temp2); else if (strcmp(temp, "--top") == 0) PageTop = get_measurement(temp2); else if (strcmp(temp, "--bottom") == 0) PageBottom = get_measurement(temp2); else if (strcmp(temp, "--pre-indent") == 0) PreIndent = get_measurement(temp2); else if (strcmp(temp, "--header") == 0) get_format(temp2, Header); else if (strcmp(temp, "--header1") == 0) get_format(temp2, Header1); else if (strcmp(temp, "--footer") == 0) get_format(temp2, Footer); else if (strcmp(temp, "--bodycolor") == 0) strlcpy(BodyColor, temp2, sizeof(BodyColor)); else if (strcmp(temp, "--bodyimage") == 0) strlcpy(BodyImage, temp2, sizeof(BodyImage)); else if (strcmp(temp, "--textcolor") == 0) htmlSetTextColor((uchar *)temp2); else if (strcmp(temp, "--linkcolor") == 0) strlcpy(LinkColor, temp2, sizeof(LinkColor)); else if (strcmp(temp, "--linkstyle") == 0) { if (strcmp(temp2, "plain") == 0) LinkStyle = 0; else LinkStyle = 1; } else if (strcmp(temp, "--toclevels") == 0) TocLevels = atoi(temp2); else if (strcmp(temp, "--tocheader") == 0) get_format(temp2, TocHeader); else if (strcmp(temp, "--tocfooter") == 0) get_format(temp2, TocFooter); else if (strcmp(temp, "--toctitle") == 0) strlcpy(TocTitle, temp2, sizeof(TocTitle)); else if (strcmp(temp, "--fontsize") == 0) { fontsize = atof(temp2); fontspacing = _htmlSpacings[SIZE_P] / _htmlSizes[SIZE_P]; if (fontsize < 4.0f) fontsize = 4.0f; else if (fontsize > 24.0f) fontsize = 24.0f; htmlSetBaseSize(fontsize, fontspacing); } else if (strcmp(temp, "--fontspacing") == 0) { fontsize = _htmlSizes[SIZE_P]; fontspacing = atof(temp2); if (fontspacing < 1.0f) fontspacing = 1.0f; else if (fontspacing > 3.0f) fontspacing = 3.0f; htmlSetBaseSize(fontsize, fontspacing); } else if (!strcmp(temp, "--headingfont")) { if (!strcasecmp(temp2, "courier")) _htmlHeadingFont = TYPE_COURIER; else if (!strcasecmp(temp2, "times")) _htmlHeadingFont = TYPE_TIMES; else if (!strcasecmp(temp2, "helvetica") || !strcasecmp(temp2, "arial")) _htmlHeadingFont = TYPE_HELVETICA; else if (!strcasecmp(temp2, "monospace")) _htmlHeadingFont = TYPE_MONOSPACE; else if (!strcasecmp(temp2, "serif")) _htmlHeadingFont = TYPE_SERIF; else if (!strcasecmp(temp2, "sans")) _htmlHeadingFont = TYPE_SANS_SERIF; } else if (!strcmp(temp, "--bodyfont")) { if (!strcasecmp(temp2, "monospace")) _htmlBodyFont = TYPE_MONOSPACE; else if (!strcasecmp(temp2, "serif")) _htmlBodyFont = TYPE_SERIF; else if (!strcasecmp(temp2, "sans")) _htmlBodyFont = TYPE_SANS_SERIF; else if (!strcasecmp(temp2, "courier")) _htmlBodyFont = TYPE_COURIER; else if (!strcasecmp(temp2, "times")) _htmlBodyFont = TYPE_TIMES; else if (!strcasecmp(temp2, "helvetica") || !strcasecmp(temp2, "arial")) _htmlBodyFont = TYPE_HELVETICA; } else if (strcmp(temp, "--headfootsize") == 0) HeadFootSize = atof(temp2); else if (!strcmp(temp, "--headfootfont")) { if (!strcasecmp(temp2, "courier")) { HeadFootType = TYPE_COURIER; HeadFootStyle = STYLE_NORMAL; } else if (!strcasecmp(temp2, "courier-bold")) { HeadFootType = TYPE_COURIER; HeadFootStyle = STYLE_BOLD; } else if (!strcasecmp(temp2, "courier-oblique")) { HeadFootType = TYPE_COURIER; HeadFootStyle = STYLE_ITALIC; } else if (!strcasecmp(temp2, "courier-boldoblique")) { HeadFootType = TYPE_COURIER; HeadFootStyle = STYLE_BOLD_ITALIC; } else if (!strcasecmp(temp2, "times") || !strcasecmp(temp2, "times-roman")) { HeadFootType = TYPE_TIMES; HeadFootStyle = STYLE_NORMAL; } else if (!strcasecmp(temp2, "times-bold")) { HeadFootType = TYPE_TIMES; HeadFootStyle = STYLE_BOLD; } else if (!strcasecmp(temp2, "times-italic")) { HeadFootType = TYPE_TIMES; HeadFootStyle = STYLE_ITALIC; } else if (!strcasecmp(temp2, "times-bolditalic")) { HeadFootType = TYPE_TIMES; HeadFootStyle = STYLE_BOLD_ITALIC; } else if (!strcasecmp(temp2, "helvetica")) { HeadFootType = TYPE_HELVETICA; HeadFootStyle = STYLE_NORMAL; } else if (!strcasecmp(temp2, "helvetica-bold")) { HeadFootType = TYPE_HELVETICA; HeadFootStyle = STYLE_BOLD; } else if (!strcasecmp(temp2, "helvetica-oblique")) { HeadFootType = TYPE_HELVETICA; HeadFootStyle = STYLE_ITALIC; } else if (!strcasecmp(temp2, "helvetica-boldoblique")) { HeadFootType = TYPE_HELVETICA; HeadFootStyle = STYLE_BOLD_ITALIC; } else if (!strcasecmp(temp2, "monospace")) { HeadFootType = TYPE_MONOSPACE; HeadFootStyle = STYLE_NORMAL; } else if (!strcasecmp(temp2, "monospace-bold")) { HeadFootType = TYPE_MONOSPACE; HeadFootStyle = STYLE_BOLD; } else if (!strcasecmp(temp2, "monospace-oblique")) { HeadFootType = TYPE_MONOSPACE; HeadFootStyle = STYLE_ITALIC; } else if (!strcasecmp(temp2, "monospace-boldoblique")) { HeadFootType = TYPE_MONOSPACE; HeadFootStyle = STYLE_BOLD_ITALIC; } else if (!strcasecmp(temp2, "serif") || !strcasecmp(temp2, "serif-roman")) { HeadFootType = TYPE_SERIF; HeadFootStyle = STYLE_NORMAL; } else if (!strcasecmp(temp2, "serif-bold")) { HeadFootType = TYPE_SERIF; HeadFootStyle = STYLE_BOLD; } else if (!strcasecmp(temp2, "serif-italic")) { HeadFootType = TYPE_SERIF; HeadFootStyle = STYLE_ITALIC; } else if (!strcasecmp(temp2, "serif-bolditalic")) { HeadFootType = TYPE_SERIF; HeadFootStyle = STYLE_BOLD_ITALIC; } else if (!strcasecmp(temp2, "sans")) { HeadFootType = TYPE_SANS_SERIF; HeadFootStyle = STYLE_NORMAL; } else if (!strcasecmp(temp2, "sans-bold")) { HeadFootType = TYPE_SANS_SERIF; HeadFootStyle = STYLE_BOLD; } else if (!strcasecmp(temp2, "sans-oblique")) { HeadFootType = TYPE_SANS_SERIF; HeadFootStyle = STYLE_ITALIC; } else if (!strcasecmp(temp2, "sans-boldoblique")) { HeadFootType = TYPE_SANS_SERIF; HeadFootStyle = STYLE_BOLD_ITALIC; } } else if (strcmp(temp, "--charset") == 0) htmlSetCharSet(temp2); else if (strcmp(temp, "--pagemode") == 0) { for (i = 0; i < (int)(sizeof(PDFModes) / sizeof(PDFModes[0])); i ++) if (strcasecmp(temp2, PDFModes[i]) == 0) { PDFPageMode = i; break; } } else if (strcmp(temp, "--pagelayout") == 0) { for (i = 0; i < (int)(sizeof(PDFLayouts) / sizeof(PDFLayouts[0])); i ++) if (strcasecmp(temp2, PDFLayouts[i]) == 0) { PDFPageLayout = i; break; } } else if (strcmp(temp, "--firstpage") == 0) { for (i = 0; i < (int)(sizeof(PDFPages) / sizeof(PDFPages[0])); i ++) if (strcasecmp(temp2, PDFPages[i]) == 0) { PDFFirstPage = i; break; } } else if (strcmp(temp, "--pageeffect") == 0) { for (i = 0; i < (int)(sizeof(PDFEffects) / sizeof(PDFEffects[0])); i ++) if (strcasecmp(temp2, PDFEffects[i]) == 0) { PDFEffect = i; break; } } else if (strcmp(temp, "--pageduration") == 0) PDFPageDuration = atof(temp2); else if (strcmp(temp, "--effectduration") == 0) PDFEffectDuration = atof(temp2); else if (strcmp(temp, "--permissions") == 0) set_permissions(temp2); else if (strcmp(temp, "--user-password") == 0) strlcpy(UserPassword, temp2, sizeof(UserPassword)); else if (strcmp(temp, "--owner-password") == 0) strlcpy(OwnerPassword, temp2, sizeof(OwnerPassword)); else if (strcmp(temp, "--path") == 0) strlcpy(Path, temp2, sizeof(Path) - 1); else if (strcmp(temp, "--proxy") == 0) { strlcpy(Proxy, temp2, sizeof(Proxy)); file_proxy(Proxy); } else if (strcmp(temp, "--cookies") == 0) file_cookies(temp2); } } // // 'read_file()' - Read a file into the current document. // static int // O - 1 on success, 0 on failure read_file(const char *filename, // I - File/URL to read tree_t **document, // IO - Current document const char *path) // I - Search path { FILE *docfile; // Document file tree_t *file; // HTML document file const char *realname, // Real name of file *ext; // Extension of filename char base[1024]; // Base directory name of file DEBUG_printf(("read_file(filename=\"%s\", document=%p, path=\"%s\")\n", filename, (void *)document, path)); if ((realname = file_find(path, filename)) != NULL) { if ((docfile = fopen(realname, "rb")) != NULL) { // Prepare to read the file... if (Verbosity > 0) progress_error(HD_ERROR_NONE, "INFO: Reading %s...", filename); _htmlPPI = 72.0f * _htmlBrowserWidth / (PageWidth - PageLeft - PageRight); strlcpy(base, file_directory(filename), sizeof(base)); ext = file_extension(filename); file = htmlAddTree(NULL, MARKUP_FILE, NULL); htmlSetVariable(file, (uchar *)"_HD_URL", (uchar *)filename); htmlSetVariable(file, (uchar *)"_HD_FILENAME", (uchar *)file_basename(filename)); htmlSetVariable(file, (uchar *)"_HD_BASE", (uchar *)base); if (ext && !strcmp(ext, "md")) { // Read markdown from a file... mdReadFile(file, docfile, base); } else { // Read HTML from a file... _htmlCurrentFile = filename; htmlReadFile(file, docfile, base); } fclose(docfile); if (*document == NULL) *document = file; else { while ((*document)->next != NULL) *document = (*document)->next; (*document)->next = file; file->prev = *document; } } else { file = NULL; progress_error(HD_ERROR_FILE_NOT_FOUND, "Unable to open \"%s\" for reading...", filename); } } else { file = NULL; progress_error(HD_ERROR_FILE_NOT_FOUND, "Unable to find \"%s\"...", filename); } return (file != NULL); } // // 'set_permissions()' - Set the PDF permission bits. // void set_permissions(const char *p) // I - Permission string { char *copyp, // Copy of string *start, // Start of current keyword *ptr; // Pointer into string // Range check input... if (!p || !*p) return; // Make a copy of the string and parse it... copyp = strdup(p); if (!copyp) return; for (start = copyp; *start; start = ptr) { for (ptr = start; *ptr; ptr ++) if (*ptr == ',') { *ptr++ = '\0'; break; } if (!strcasecmp(start, "all")) Permissions = -4; else if (!strcasecmp(start, "none")) Permissions = -64; else if (!strcasecmp(start, "print")) Permissions |= PDF_PERM_PRINT; else if (!strcasecmp(start, "no-print")) Permissions &= ~PDF_PERM_PRINT; else if (!strcasecmp(start, "modify")) Permissions |= PDF_PERM_MODIFY; else if (!strcasecmp(start, "no-modify")) Permissions &= ~PDF_PERM_MODIFY; else if (!strcasecmp(start, "copy")) Permissions |= PDF_PERM_COPY; else if (!strcasecmp(start, "no-copy")) Permissions &= ~PDF_PERM_COPY; else if (!strcasecmp(start, "annotate")) Permissions |= PDF_PERM_ANNOTATE; else if (!strcasecmp(start, "no-annotate")) Permissions &= ~PDF_PERM_ANNOTATE; } if (Permissions != -4) Encryption = 1; free(copyp); } #ifndef WIN32 // // 'term_handler()' - Handle CTRL-C or kill signals... // static void term_handler(int signum) // I - Signal number { REF(signum); file_cleanup(); image_flush_cache(); exit(1); } #endif // !WIN32 /* * 'usage()' - Show program version and command-line options. */ static void usage(const char *arg) // I - Bad argument string { if (CGIMode) puts("Content-Type: text/plain\r\n\r"); puts("HTMLDOC Version " SVERSION " Copyright 2011-2024 by Michael R Sweet."); puts("HTMLDOC is provided under the terms of the GNU General Public License and"); puts("comes with absolutely no warranty. This software is based in part on the work"); puts("of the Independent JPEG Group."); puts(""); #ifdef HAVE_SSL puts("This copy of HTMLDOC has been built to support both http: and https: URLs."); #else puts("This copy of HTMLDOC has been built to support http: URLs only."); #endif /* HAVE_SSL */ puts(""); if (CGIMode) { puts("HTMLDOC is running in CGI mode. To disable CGI mode when running"); puts("from a server-side script/page, set the HTMLDOC_NOCGI environment"); puts("variable prior to running HTMLDOC."); puts(""); puts("If you are trying to use CGI mode, make sure that the ServerName"); puts("for the web server is accessible from the local system. If you"); puts("are using Apache 2.0.30 or later, make sure you set 'AcceptPathInfo'"); puts("to 'On' for the HTMLDOC/cgi-bin directory."); } else { if (arg && arg[0] == '-') printf("ERROR: Bad option argument \"%s\"!\n\n", arg); else printf("ERROR: %s\n", arg); puts(""); puts("Usage:"); puts(" htmldoc [options] filename1.html [ ... filenameN.html ]"); #ifdef HAVE_LIBFLTK puts(" htmldoc filename.book"); #endif // HAVE_LIBFLTK puts(""); puts("Options:"); puts(""); puts(" --batch filename.book"); puts(" --bodycolor color"); puts(" --bodyfont {courier,helvetica,monospace,sans,serif,times}"); puts(" --bodyimage filename.{bmp,gif,jpg,png}"); puts(" --book"); puts(" --bottom margin{in,cm,mm}"); puts(" --browserwidth pixels"); puts(" --charset {cp-874...1258,iso-8859-1...-15,koi8-r,utf-8}"); puts(" --color"); puts(" --compression[=level]"); puts(" --continuous"); puts(" --cookies 'name=\"value with space\"; name=value'"); puts(" --datadir directory"); puts(" --duplex"); puts(" --effectduration {0.1..10.0}"); puts(" --embedfonts"); puts(" --encryption"); puts(" --firstpage {p1,toc,c1}"); puts(" --fontsize {4.0..24.0}"); puts(" --fontspacing {1.0..3.0}"); puts(" --footer fff"); puts(" {--format, -t} {epub,html,htmlsep,pdf11,pdf12,pdf13,pdf14,ps1,ps2,ps3}"); puts(" --gray"); puts(" --header fff"); puts(" --header1 fff"); puts(" --headfootfont {courier{-bold,-oblique,-boldoblique},\n" " helvetica{-bold,-oblique,-boldoblique},\n" " monospace{-bold,-oblique,-boldoblique},\n" " sans{-bold,-oblique,-boldoblique},\n" " serif{-bold,-italic,-bolditalic},\n" " times{-roman,-bold,-italic,-bolditalic}}\n"); puts(" --headfootsize {6.0..24.0}"); puts(" --headingfont {courier,helvetica,monospace,sans,serif,times}"); puts(" --help"); #ifdef HAVE_LIBFLTK puts(" --helpdir directory"); #endif // HAVE_LIBFLTK for (int i = 0; i < MAX_HF_IMAGES; i ++) printf(" --hfimage%d filename.{bmp,gif,jpg,png}\n", i); puts(" --jpeg[=quality]"); puts(" --landscape"); puts(" --left margin{in,cm,mm}"); puts(" --letterhead filename.{bmp,gif,jpg,png}"); puts(" --linkcolor color"); puts(" --links"); puts(" --linkstyle {plain,underline}"); puts(" --logoimage filename.{bmp,gif,jpg,png}"); puts(" --no-compression"); puts(" --no-duplex"); puts(" --no-embedfonts"); puts(" --no-encryption"); puts(" --no-links"); puts(" --no-localfiles"); puts(" --no-numbered"); puts(" --no-overflow"); puts(" --no-pscommands"); puts(" --no-strict"); puts(" --no-title"); puts(" --no-toc"); puts(" --numbered"); puts(" --nup {1,2,4,6,9,16}"); puts(" {--outdir, -d} dirname"); puts(" {--outfile, -f} filename.{epub,html,pdf,ps}"); puts(" --overflow"); puts(" --owner-password password"); puts(" --pageduration {1.0..60.0}"); puts(" --pageeffect {none,bi,bo,d,gd,gdr,gr,hb,hsi,hso,vb,vsi,vso,wd,wl,wr,wu}"); puts(" --pagelayout {single,one,twoleft,tworight}"); puts(" --pagemode {document,outline,fullscreen}"); puts(" --path \"dir1;dir2;dir3;...;dirN\""); puts(" --permissions {all,annotate,copy,modify,print,no-annotate,no-copy,no-modify,no-print,none}"); puts(" --portrait"); puts(" --proxy http://host:port"); puts(" --pscommands"); puts(" --quiet"); puts(" --referer url"); puts(" --right margin{in,cm,mm}"); puts(" --size {letter,a4,WxH{in,cm,mm},etc}"); puts(" --strict"); puts(" --textcolor color"); puts(" --textfont {courier,times,helvetica}"); puts(" --title"); puts(" --titlefile filename.{htm,html,shtml}"); puts(" --titleimage filename.{bmp,gif,jpg,png}"); puts(" --tocfooter fff"); puts(" --tocheader fff"); puts(" --toclevels levels"); puts(" --toctitle string"); puts(" --top margin{in,cm,mm}"); puts(" --user-password password"); puts(" {--verbose, -v}"); puts(" --version"); puts(" --webpage"); puts(""); puts(" fff = heading format string; each \'f\' can be one of:"); puts(""); puts(" . = blank"); puts(" / = n/N arabic page numbers (1/3, 2/3, 3/3)"); puts(" : = c/C arabic chapter page numbers (1/2, 2/2, 1/4, 2/4, ...)"); puts(" 1 = arabic numbers (1, 2, 3, ...)"); puts(" a = lowercase letters"); puts(" A = uppercase letters"); puts(" c = current chapter heading"); puts(" C = current chapter page number (arabic)"); puts(" d = current date"); puts(" D = current date and time"); puts(" h = current heading"); puts(" i = lowercase roman numerals"); puts(" I = uppercase roman numerals"); puts(" l = logo image"); puts(" L = letterhead image"); puts(" t = title text"); puts(" T = current time"); puts(" u = current file/URL"); } exit(1); } htmldoc-1.9.20/htmldoc/htmldoc.h000066400000000000000000000163301472561501400165020ustar00rootroot00000000000000/* * Header file for HTMLDOC, a HTML document processing program. * * Copyright 2011-2023 by Michael R Sweet. * Copyright 1997-2010 by Easy Software Products. All rights reserved. * * This program is free software. Distribution and use rights are outlined in * the file "COPYING". */ /* * Include necessary headers. */ #include #include #include #include "html.h" #include "image.h" #include "debug.h" #include "progress.h" #ifdef HAVE_LIBFLTK # include "gui.h" #endif /* HAVE_LIBFLTK */ #ifdef WIN32 /* Include all 8 million Windows header files... */ # include #endif /* WIN32 */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* * Macro to get rid of "unreferenced variable xyz" warnings... */ #define REF(x) (void)x; /* * Output type... */ enum { OUTPUT_BOOK, OUTPUT_CONTINUOUS, OUTPUT_WEBPAGES }; /* * PDF constants... */ enum /* PDF page mode */ { PDF_DOCUMENT, PDF_OUTLINE, PDF_FULLSCREEN }; enum /* PDF page layout */ { PDF_SINGLE, PDF_ONE_COLUMN, PDF_TWO_COLUMN_LEFT, PDF_TWO_COLUMN_RIGHT }; enum /* PDF first page */ { PDF_PAGE_1, PDF_TOC, PDF_CHAPTER_1 }; enum /* PDF transition effect */ { PDF_NONE, PDF_BOX_INWARD, PDF_BOX_OUTWARD, PDF_DISSOLVE, PDF_GLITTER_DOWN, PDF_GLITTER_DOWN_RIGHT, PDF_GLITTER_RIGHT, PDF_HORIZONTAL_BLINDS, PDF_HORIZONTAL_SWEEP_INWARD, PDF_HORIZONTAL_SWEEP_OUTWARD, PDF_VERTICAL_BLINDS, PDF_VERTICAL_SWEEP_INWARD, PDF_VERTICAL_SWEEP_OUTWARD, PDF_WIPE_DOWN, PDF_WIPE_LEFT, PDF_WIPE_RIGHT, PDF_WIPE_UP }; enum /* PDF document permissions */ { PDF_PERM_PRINT = 4, PDF_PERM_MODIFY = 8, PDF_PERM_COPY = 16, PDF_PERM_ANNOTATE = 32 }; /* * Globals... */ #ifdef _HTMLDOC_CXX_ # define VAR # define VALUE(x) =x # define NULL3 ={0,0,0} #else # define VAR extern # define VALUE(x) # define NULL3 #endif /* _HTML_DOC_CXX_ */ VAR int Verbosity VALUE(0); /* Verbosity */ VAR int OverflowErrors VALUE(0); /* Show errors on overflow */ VAR int StrictHTML VALUE(0); /* Do strict HTML checking */ VAR int CGIMode VALUE(0); /* Running as CGI? */ VAR int Errors VALUE(0); /* Number of errors */ VAR int Compression VALUE(1); /* Non-zero means compress PDFs */ VAR int TitlePage VALUE(1), /* Need a title page */ TocLevels VALUE(3), /* Number of table-of-contents levels */ TocLinks VALUE(1), /* Generate links */ TocNumbers VALUE(0), /* Generate heading numbers */ TocDocCount VALUE(0); /* Number of chapters */ VAR int OutputType VALUE(OUTPUT_BOOK); /* Output a "book", etc. */ VAR char OutputPath[1024] VALUE(""); /* Output directory/name */ VAR int OutputFiles VALUE(0), /* Generate multiple files? */ OutputColor VALUE(1); /* Output color images */ VAR int OutputJPEG VALUE(0); /* JPEG compress images? */ VAR int PDFVersion VALUE(13); /* Version of PDF to support */ VAR int PDFPageMode VALUE(PDF_OUTLINE), /* PageMode attribute */ PDFPageLayout VALUE(PDF_SINGLE), /* PageLayout attribute */ PDFFirstPage VALUE(PDF_CHAPTER_1), /* First page */ PDFEffect VALUE(PDF_NONE);/* Page transition effect */ VAR double PDFEffectDuration VALUE(1.0), /* Page effect duration */ PDFPageDuration VALUE(10.0); /* Page duration */ VAR int Encryption VALUE(0), /* Encrypt the PDF file? */ Permissions VALUE(-4); /* File permissions? */ VAR char OwnerPassword[33] VALUE(""), /* Owner password */ UserPassword[33] VALUE(""); /* User password */ VAR int EmbedFonts VALUE(1); /* Embed fonts? */ VAR int PSLevel VALUE(2), /* Language level (0 for PDF) */ PSCommands VALUE(0), /* Output PostScript commands? */ XRXComments VALUE(0); /* Output Xerox comments? */ VAR int PageWidth VALUE(595), /* Page width in points */ PageLength VALUE(792), /* Page length in points */ PageLeft VALUE(72), /* Left margin */ PageRight VALUE(36), /* Right margin */ PageTop VALUE(36), /* Top margin */ PageBottom VALUE(36), /* Bottom margin */ PagePrintWidth, /* Printable width */ PagePrintLength, /* Printable length */ PageDuplex VALUE(0), /* Adjust margins/pages for duplexing? */ Landscape VALUE(0), /* Landscape orientation? */ NumberUp VALUE(1); /* Number-up pages */ VAR int PreIndent VALUE(36); /* Indentation of PRE content */ VAR typeface_t HeadFootType VALUE(TYPE_HELVETICA); /* Typeface for header & footer */ VAR style_t HeadFootStyle VALUE(STYLE_NORMAL); /* Type style */ VAR double HeadFootSize VALUE(11.0f); /* Size of header & footer */ VAR char *Header[3] NULL3, /* Header for regular pages */ *Header1[3] NULL3, /* Header for first pages */ *TocHeader[3] NULL3, /* Header for TOC pages */ *Footer[3] NULL3, /* Regular page footer */ *TocFooter[3] NULL3, /* Footer for TOC pages */ TocTitle[1024] VALUE("Table of Contents"); /* TOC title string */ VAR char TitleImage[1024] VALUE(""), /* Title page image */ Letterhead[1024] VALUE(""), /* Letterhead image */ LogoImage[1024] VALUE(""), /* Logo image */ BodyColor[255] VALUE(""), /* Body color */ BodyImage[1024] VALUE(""), /* Body image */ LinkColor[255] VALUE(""); /* Link color */ VAR char HFImage[MAX_HF_IMAGES][1024] /* Header/footer images */ # ifdef _HTMLDOC_CXX_ = { "" } # endif /* _HTMLDOC_CXX_ */ ; VAR int LinkStyle VALUE(1); /* 1 = underline, 0 = plain */ VAR int Links VALUE(1); /* 1 = generate links, 0 = no links */ VAR char Path[2048] VALUE(""), /* Search path */ Proxy[1024] VALUE(""); /* Proxy URL */ VAR const char *PDFModes[3] /* Mode strings */ # ifdef _HTMLDOC_CXX_ = { "document", "outline", "fullscreen" } # endif /* _HTMLDOC_CXX_ */ ; VAR const char *PDFLayouts[4] /* Layout strings */ # ifdef _HTMLDOC_CXX_ = { "single", "one", "twoleft", "tworight" } # endif /* _HTMLDOC_CXX_ */ ; VAR const char *PDFPages[3] /* First page strings */ # ifdef _HTMLDOC_CXX_ = { "p1", "toc", "c1" } # endif /* _HTMLDOC_CXX_ */ ; VAR const char *PDFEffects[17] /* Effect strings */ # ifdef _HTMLDOC_CXX_ = { "none", "bi", "bo", "d", "gd", "gdr", "gr", "hb", "hsi", "hso", "vb", "vsi", "vso", "wd", "wl", "wr", "wu" } # endif /* _HTMLDOC_CXX_ */ ; #ifdef HAVE_LIBFLTK VAR GUI *BookGUI VALUE(NULL); /* GUI for book files */ # ifdef WIN32 /* Editor for HTML files */ VAR char HTMLEditor[1024] VALUE("notepad.exe \"%s\""); # elif defined(__APPLE__) VAR char HTMLEditor[1024] VALUE("bbedit %s"); # elif defined(__linux) VAR char HTMLEditor[1024] VALUE("gedit %s"); # else VAR char HTMLEditor[1024] VALUE("nedit %s"); # endif /* WIN32 */ VAR int Tooltips VALUE(0); /* Show tooltips? */ #endif /* HAVE_LIBFLTK */ /* * Prototypes... */ extern int pspdf_export(tree_t *document, tree_t *toc); extern int epub_export(tree_t *document, tree_t *toc); extern int html_export(tree_t *document, tree_t *toc); extern int htmlsep_export(tree_t *document, tree_t *toc); extern tree_t *toc_build(tree_t *tree); extern void get_color(const uchar *c, float *rgb, int defblack = 1); extern const char *get_fmt(char **formats); extern void get_format(const char *fmt, char **formats); extern int get_measurement(const char *s, float mul = 1.0f); extern void set_page_size(const char *size); extern void prefs_load(void); extern void prefs_save(void); extern void prefs_set_paths(void); extern char *format_number(int n, char f); #ifdef __cplusplus } #endif /* __cplusplus */ htmldoc-1.9.20/htmldoc/htmllib.cxx000066400000000000000000002604331472561501400170630ustar00rootroot00000000000000// // HTML parsing routines for HTMLDOC, a HTML document processing program. // // Copyright 2011-2024 by Michael R Sweet. // Copyright 1997-2010 by Easy Software Products. All rights reserved. // // This program is free software. Distribution and use rights are outlined in // the file "COPYING". // #include "htmldoc.h" #include #include // // Markup strings... // const char *_htmlMarkups[] = { "", // MARKUP_NONE "!--", // MARKUP_COMMENT "!DOCTYPE", "a", "acronym", "address", "applet", "area", "b", "base", "basefont", "big", "blink", "blockquote", "body", "br", "caption", "center", "cite", "code", "col", "colgroup", "dd", "del", "dfn", "dir", "div", "dl", "dt", "em", "embed", "font", "form", "frame", "frameset", "h1", "h2", "h3", "h4", "h5", "h6", "h7", "h8", "h9", "h10", "h11", "h12", "h13", "h14", "h15", "head", "hr", "html", "i", "img", "input", "ins", "isindex", "kbd", "li", "link", "map", "menu", "meta", "multicol", "nobr", "noframes", "ol", "option", "p", "pre", "s", "samp", "script", "select", "small", "spacer", "span", "strike", "strong", "style", "sub", "sup", "table", "tbody", "td", "textarea", "tfoot", "th", "thead", "title", "tr", "tt", "u", "ul", "var", "wbr" }; const char *_htmlCurrentFile = "UNKNOWN"; // Current file const char *_htmlData = HTML_DATA; // Data directory float _htmlPPI = 80.0f; // Image resolution int _htmlGrayscale = 0; // Grayscale output? uchar _htmlTextColor[255] = // Default text color { 0 }; float _htmlBrowserWidth = 680.0f; // Browser width for pixel scaling float _htmlSizes[8] = // Point size for each HTML size { 6.0f, 8.0f, 9.0f, 11.0f, 14.0f, 17.0f, 20.0f, 24.0f }; float _htmlSpacings[8] = // Line height for each HTML size { 7.2f, 9.6f, 10.8f, 13.2f, 16.8f, 20.4f, 24.0f, 28.8f }; typeface_t _htmlBodyFont = TYPE_TIMES, _htmlHeadingFont = TYPE_HELVETICA; int _htmlInitialized = 0; // Initialized glyphs yet? char _htmlCharSet[256] = "iso-8859-1"; // Character set name int _htmlWidthsLoaded[TYPE_MAX][STYLE_MAX] = { // Have the widths been loaded? { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; short _htmlWidths[TYPE_MAX][STYLE_MAX][256]; // Character widths of fonts short _htmlWidthsAll[TYPE_MAX][STYLE_MAX][65536]; // Unicode widths of fonts int _htmlUnicode[256]; // Character to Unicode mapping uchar _htmlCharacters[65536]; // Unicode to character mapping int _htmlUTF8 = 0; // Doing UTF-8? const char *_htmlGlyphsAll[65536]; // Character glyphs for Unicode const char *_htmlGlyphs[256]; // Character glyphs for charset int _htmlNumSorted = 0; // Number of sorted glyphs const char *_htmlSorted[256]; // Sorted character glyphs for charset uchar _htmlSortedChars[256]; // Sorted character indices const char *_htmlFonts[TYPE_MAX][STYLE_MAX] = { { "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique" }, { "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic" }, { "Helvetica", "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-BoldOblique" }, { "Monospace", "Monospace-Bold", "Monospace-Oblique", "Monospace-BoldOblique" }, { "Serif-Roman", "Serif-Bold", "Serif-Oblique", "Serif-BoldOblique" }, { "Sans", "Sans-Bold", "Sans-Oblique", "Sans-BoldOblique" }, { "Symbol", "Symbol", "Symbol", "Symbol" }, { "Dingbats", "Dingbats", "Dingbats", "Dingbats" } }; int _htmlStandardFonts[TYPE_MAX] = { 1, // Courier 1, // Times 1, // Helvetica 0, // Monospace 0, // Sans 0, // Serif 1, // Symbol 1 // Dingbats }; // // Local functions. // extern "C" { typedef int (*compare_func_t)(const void *, const void *); } static int write_file(tree_t *t, FILE *fp, int col); static int compare_variables(var_t *v0, var_t *v1); static int compare_markups(uchar **m0, uchar **m1); static void delete_node(tree_t *t); static void insert_space(tree_t *parent, tree_t *t); static int parse_markup(tree_t *t, FILE *fp, int *linenum); static int parse_variable(tree_t *t, FILE *fp, int *linenum); static int compute_size(tree_t *t); static int compute_color(tree_t *t, uchar *color); static int get_alignment(tree_t *t); static const char *fix_filename(char *path, char *base); static int utf8_getc(int ch, FILE *fp); #define issuper(x) ((x) == MARKUP_CENTER || (x) == MARKUP_DIV ||\ (x) == MARKUP_BLOCKQUOTE) #define isblock(x) ((x) == MARKUP_ADDRESS || \ (x) == MARKUP_P || (x) == MARKUP_PRE ||\ ((x) >= MARKUP_H1 && (x) <= MARKUP_H6) ||\ (x) == MARKUP_HR || (x) == MARKUP_TABLE) #define islist(x) ((x) == MARKUP_DL || (x) == MARKUP_OL ||\ (x) == MARKUP_UL || (x) == MARKUP_DIR ||\ (x) == MARKUP_MENU) #define islentry(x) ((x) == MARKUP_LI || (x) == MARKUP_DD ||\ (x) == MARKUP_DT) #define istable(x) ((x) == MARKUP_TBODY || (x) == MARKUP_THEAD ||\ (x) == MARKUP_TFOOT || (x) == MARKUP_TR) #define istentry(x) ((x) == MARKUP_TD || (x) == MARKUP_TH) #ifdef DEBUG static uchar indent[255] = ""; #endif // DEBUG // // 'htmlReadFile()' - Read a file for HTML markup codes. // tree_t * // O - Pointer to top of file tree htmlReadFile(tree_t *parent, // I - Parent tree entry FILE *fp, // I - File pointer const char *base) // I - Base directory for file { int ch; // Character from file uchar *ptr, // Pointer in string entity[16], // Character entity name (&#nnn; or &name;) *eptr; // Pointer in entity string tree_t *tree, // "top" of this tree *t, // New tree entry *prev, // Previous tree entry *temp; // Temporary looping var int descend; // Descend into node? FILE *embed; // File pointer for EMBED char newbase[1024]; // New base directory for EMBED uchar *filename, // Filename for EMBED tag *face, // Typeface for FONT tag *color, // Color for FONT tag *size, // Size for FONT tag *type, // Type for EMBED tag *span; // Value for SPAN tag int sizeval; // Size value from FONT tag int linenum; // Line number in file static uchar s[10240]; // String from file static int have_whitespace = 0; // Non-zero if there was leading whitespace DEBUG_printf(("htmlReadFile(parent=%p, fp=%p, base=\"%s\")\n", (void *)parent, (void *)fp, base ? base : "(null)")); #ifdef DEBUG indent[0] = '\0'; #endif // DEBUG // Start off with no previous tree entry... prev = NULL; tree = NULL; // Parse data until we hit end-of-file... linenum = 1; while ((ch = getc(fp)) != EOF) { // Ignore leading whitespace... if (parent == NULL || !parent->preformatted) { while (isspace(ch)) { if (ch == '\n') linenum ++; have_whitespace = 1; ch = getc(fp); } if (ch == EOF) break; } // Allocate a new tree entry - use calloc() to get zeroed data... t = (tree_t *)calloc(sizeof(tree_t), 1); if (t == NULL) { #ifndef DEBUG progress_error(HD_ERROR_OUT_OF_MEMORY, "Unable to allocate memory for HTML tree node!"); #endif // !DEBUG break; } // Set/copy font characteristics... if (parent == NULL) { t->halignment = ALIGN_LEFT; t->valignment = ALIGN_BOTTOM; t->typeface = _htmlBodyFont; t->size = SIZE_P; compute_color(t, _htmlTextColor); } else { t->link = parent->link; t->halignment = parent->halignment; t->valignment = parent->valignment; t->typeface = parent->typeface; t->size = parent->size; t->style = parent->style; t->superscript = parent->superscript; t->subscript = parent->subscript; t->preformatted = parent->preformatted; t->indent = parent->indent; t->red = parent->red; t->green = parent->green; t->blue = parent->blue; t->underline = parent->underline; t->strikethrough = parent->strikethrough; } // See what the character was... if (ch == '<') { // Markup char; grab the next char to see if this is a /... ch = getc(fp); if (isspace(ch) || ch == '=' || ch == '<') { // Sigh... "<" followed by anything but an element name is // invalid HTML, but so many people have asked for this to // be supported that we have added this hack... progress_error(HD_ERROR_HTML_ERROR, "Unquoted < on line %d of %s.", linenum, _htmlCurrentFile); if (ch == '\n') linenum ++; ptr = s; if (have_whitespace) { *ptr++ = ' '; have_whitespace = 0; } *ptr++ = '<'; if (ch == '=') *ptr++ = '='; else if (ch == '<') ungetc(ch, fp); else have_whitespace = 1; *ptr++ = '\0'; t->markup = MARKUP_NONE; t->data = (uchar *)hd_strdup((char *)s); } else { // Start of a markup... if (ch != '/') ungetc(ch, fp); if (parse_markup(t, fp, &linenum) == MARKUP_ERROR) { #ifndef DEBUG progress_error(HD_ERROR_READ_ERROR, "Unable to parse HTML element on line %d of %s!", linenum, _htmlCurrentFile); #endif // !DEBUG delete_node(t); break; } // Eliminate extra whitespace... if (issuper(t->markup) || isblock(t->markup) || islist(t->markup) || islentry(t->markup) || istable(t->markup) || istentry(t->markup) || t->markup == MARKUP_TITLE) have_whitespace = 0; // If this is the matching close mark, or if we are starting the same // markup, or if we've completed a list, we're done! if (ch == '/') { // Close markup; find matching markup... for (temp = parent; temp != NULL; temp = temp->parent) { if (temp->markup == t->markup) { break; } else if (temp->markup == MARKUP_EMBED) { temp = NULL; break; } } } else if (t->markup == MARKUP_BODY || t->markup == MARKUP_HEAD) { // Make sure we aren't inside an existing HEAD or BODY... for (temp = parent; temp != NULL; temp = temp->parent) { if (temp->markup == MARKUP_BODY || temp->markup == MARKUP_HEAD) { break; } else if (temp->markup == MARKUP_EMBED) { temp = NULL; break; } } } else if (t->markup == MARKUP_EMBED) { // Close any text blocks... for (temp = parent; temp != NULL; temp = temp->parent) { if (isblock(temp->markup) || islentry(temp->markup)) { break; } else if (istentry(temp->markup) || islist(temp->markup) || issuper(temp->markup) || temp->markup == MARKUP_EMBED) { temp = NULL; break; } } } else if (issuper(t->markup)) { for (temp = parent; temp != NULL; temp = temp->parent) { if (istentry(temp->markup) || temp->markup == MARKUP_EMBED) { temp = NULL; break; } } } else if (islist(t->markup)) { for (temp = parent; temp != NULL; temp = temp->parent) { if (isblock(temp->markup)) { break; } else if (islentry(temp->markup) || istentry(temp->markup) || issuper(temp->markup) || temp->markup == MARKUP_EMBED) { temp = NULL; break; } } } else if (islentry(t->markup)) { for (temp = parent; temp != NULL; temp = temp->parent) { if (islentry(temp->markup)) { break; } else if (islist(temp->markup) || issuper(temp->markup) || istentry(temp->markup) || temp->markup == MARKUP_EMBED) { temp = NULL; break; } } } else if (isblock(t->markup)) { for (temp = parent; temp != NULL; temp = temp->parent) { if (isblock(temp->markup)) { break; } else if (istentry(temp->markup) || islist(temp->markup) || islentry(temp->markup) || issuper(temp->markup) || temp->markup == MARKUP_EMBED) { temp = NULL; break; } } } else if (t->markup == MARKUP_THEAD || t->markup == MARKUP_TBODY || t->markup == MARKUP_TFOOT) { for (temp = parent; temp != NULL; temp = temp->parent) { if (temp->markup == MARKUP_TABLE || temp->markup == MARKUP_EMBED) { temp = NULL; break; } } } else if (t->markup == MARKUP_TR) { for (temp = parent; temp != NULL; temp = temp->parent) { if (temp->markup == MARKUP_TR) { break; } else if (temp->markup == MARKUP_TABLE || t->markup == MARKUP_THEAD || t->markup == MARKUP_TBODY || t->markup == MARKUP_TFOOT || temp->markup == MARKUP_EMBED) { temp = NULL; break; } } } else if (istentry(t->markup)) { for (temp = parent; temp != NULL; temp = temp->parent) { if (istentry(temp->markup)) { break; } else if (temp->markup == MARKUP_TABLE || istable(temp->markup) || temp->markup == MARKUP_EMBED) { if (temp->markup != MARKUP_TR) { // Strictly speaking, this is an error - TD/TH can only // be found under TR, but web browsers automatically // inject a TR... progress_error(HD_ERROR_HTML_ERROR, "No TR element before %s element on line %d of %s.", _htmlMarkups[t->markup], linenum, _htmlCurrentFile); parent = htmlAddTree(temp, MARKUP_TR, NULL); prev = NULL; DEBUG_printf(("%str (inserted) under %s, line %d\n", indent, _htmlMarkups[temp->markup], linenum)); } temp = NULL; break; } } } else { temp = NULL; } if (temp != NULL) { DEBUG_printf(("%s>>>> Auto-ascend <<<\n", indent)); if (ch != '/' && temp->markup != MARKUP_BODY && temp->markup != MARKUP_DD && temp->markup != MARKUP_DT && temp->markup != MARKUP_HEAD && temp->markup != MARKUP_HTML && temp->markup != MARKUP_LI && temp->markup != MARKUP_OPTION && temp->markup != MARKUP_P && temp->markup != MARKUP_TBODY && temp->markup != MARKUP_TD && temp->markup != MARKUP_TFOOT && temp->markup != MARKUP_TH && temp->markup != MARKUP_THEAD && temp->markup != MARKUP_TR) { // Log this condition as an error... progress_error(HD_ERROR_HTML_ERROR, "No /%s element before %s element on line %d of %s.", _htmlMarkups[temp->markup], _htmlMarkups[t->markup], linenum, _htmlCurrentFile); DEBUG_printf(("%sNo /%s element before %s element on line %d.\n", indent, _htmlMarkups[temp->markup], _htmlMarkups[t->markup], linenum)); } #ifdef DEBUG for (tree_t *p = parent; p && p != temp && indent[0]; p = p->parent) indent[strlen((char *)indent) - 4] = '\0'; if (indent[0]) indent[strlen((char *)indent) - 4] = '\0'; #endif // DEBUG // Safety check; should never happen, since MARKUP_FILE is // the root node created by the caller... if (temp->parent) { parent = temp->parent; prev = parent->last_child; } else { for (prev = temp; prev->next; prev = prev->next); parent = NULL; } if (ch == '/') { // Closing element, so delete this node... delete_node(t); continue; } else { // Reparent the node... if (parent == NULL) { t->halignment = ALIGN_LEFT; t->valignment = ALIGN_BOTTOM; t->typeface = _htmlBodyFont; t->size = SIZE_P; compute_color(t, _htmlTextColor); } else { t->link = parent->link; t->halignment = parent->halignment; t->valignment = parent->valignment; t->typeface = parent->typeface; t->size = parent->size; t->style = parent->style; t->superscript = parent->superscript; t->subscript = parent->subscript; t->preformatted = parent->preformatted; t->indent = parent->indent; t->red = parent->red; t->green = parent->green; t->blue = parent->blue; t->underline = parent->underline; t->strikethrough = parent->strikethrough; } } } else if (ch == '/') { // Log this condition as an error... if (t->markup != MARKUP_UNKNOWN && t->markup != MARKUP_COMMENT) { progress_error(HD_ERROR_HTML_ERROR, "Dangling /%s element on line %d of %s.", _htmlMarkups[t->markup], linenum, _htmlCurrentFile); DEBUG_printf(("%sDangling /%s element on line %d.\n", indent, _htmlMarkups[t->markup], linenum)); } delete_node(t); continue; } } } else if (t->preformatted) { // Read a pre-formatted string into the current tree entry... ptr = s; while (ch != '<' && ch != EOF && ptr < (s + sizeof(s) - 1)) { if (ch == '&') { // Possibly a character entity... eptr = entity; while (eptr < (entity + sizeof(entity) - 1) && (ch = getc(fp)) != EOF) if (!isalnum(ch) && ch != '#') break; else *eptr++ = (uchar)ch; if (ch != ';') { ungetc(ch, fp); ch = 0; } *eptr = '\0'; if (!ch) { progress_error(HD_ERROR_HTML_ERROR, "Unquoted & on line %d of %s.", linenum, _htmlCurrentFile); if (ptr < (s + sizeof(s) - 1)) *ptr++ = '&'; strlcpy((char *)ptr, (char *)entity, sizeof(s) - (size_t)(ptr - s)); ptr += strlen((char *)ptr); } else if ((ch = iso8859(entity)) == 0) { progress_error(HD_ERROR_HTML_ERROR, "Unknown character entity \"&%s;\" on line %d of %s.", entity, linenum, _htmlCurrentFile); if (ptr < (s + sizeof(s) - 1)) *ptr++ = '&'; strlcpy((char *)ptr, (char *)entity, sizeof(s) - (size_t)(ptr - s)); ptr += strlen((char *)ptr); if (ptr < (s + sizeof(s) - 1)) *ptr++ = ';'; } else *ptr++ = (uchar)ch; } else if ((ch & 0x80) && _htmlUTF8) { // Collect UTF-8 value... ch = utf8_getc(ch, fp); if (ch) *ptr++ = (uchar)ch; } else if (ch != 0 && ch != '\r') { *ptr++ = (uchar)ch; if (ch == '\n') { linenum ++; break; } } ch = getc(fp); } *ptr = '\0'; if (ch == '<') ungetc(ch, fp); t->markup = MARKUP_NONE; t->data = (uchar *)hd_strdup((char *)s); DEBUG_printf(("%sfragment \"%s\", line %d\n", indent, s, linenum)); } else { // Read the next string fragment... ptr = s; if (have_whitespace) { *ptr++ = ' '; have_whitespace = 0; } while (!isspace(ch) && ch != '<' && ch != EOF && ptr < (s + sizeof(s) - 1)) { if (ch == '&') { // Possibly a character entity... eptr = entity; while (eptr < (entity + sizeof(entity) - 1) && (ch = getc(fp)) != EOF) if (!isalnum(ch) && ch != '#') break; else *eptr++ = (uchar)ch; *eptr = '\0'; if (ch != ';') { ungetc(ch, fp); ch = 0; } if (!ch) { progress_error(HD_ERROR_HTML_ERROR, "Unquoted & on line %d of %s.", linenum, _htmlCurrentFile); if (ptr < (s + sizeof(s) - 1)) *ptr++ = '&'; strlcpy((char *)ptr, (char *)entity, sizeof(s) - (size_t)(ptr - s)); ptr += strlen((char *)ptr); } else if ((ch = iso8859(entity)) == 0) { progress_error(HD_ERROR_HTML_ERROR, "Unknown character entity \"&%s;\" on line %d of %s.", entity, linenum, _htmlCurrentFile); if (ptr < (s + sizeof(s) - 1)) *ptr++ = '&'; strlcpy((char *)ptr, (char *)entity, sizeof(s) - (size_t)(ptr - s)); ptr += strlen((char *)ptr); if (ptr < (s + sizeof(s) - 1)) *ptr++ = ';'; } else *ptr++ = (uchar)ch; } else { if ((ch & 0x80) && _htmlUTF8) { // Collect UTF-8 value... ch = utf8_getc(ch, fp); } if (ch) *ptr++ = (uchar)ch; } if ((_htmlUTF8 && ch == _htmlCharacters[173]) || (!_htmlUTF8 && ch == 173)) break; ch = getc(fp); } if (ch == '\n') linenum ++; if (isspace(ch)) have_whitespace = 1; *ptr = '\0'; if (ch == '<') ungetc(ch, fp); t->markup = MARKUP_NONE; t->data = (uchar *)hd_strdup((char *)s); DEBUG_printf(("%sfragment \"%s\" (len=%d), line %d\n", indent, s, (int)(ptr - s), linenum)); } // If the parent tree pointer is not null and this is the first // entry we've read, set the child pointer... DEBUG_printf(("%sADDING %s node to %s parent!\n", indent, _htmlMarkups[t->markup], parent ? _htmlMarkups[parent->markup] : "ROOT")); if (parent != NULL && prev == NULL) parent->child = t; if (parent != NULL) parent->last_child = t; // Do the prev/next links... t->parent = parent; t->prev = prev; if (prev != NULL) prev->next = t; if (tree == NULL) tree = t; prev = t; // Do markup-specific stuff... descend = 0; switch (t->markup) { case MARKUP_BODY : // Update the text color as necessary... if ((color = htmlGetVariable(t, (uchar *)"TEXT")) != NULL) compute_color(t, color); else compute_color(t, _htmlTextColor); if ((color = htmlGetVariable(t, (uchar *)"BGCOLOR")) != NULL && !BodyColor[0]) strlcpy(BodyColor, (char *)color, sizeof(BodyColor)); // Update the background image as necessary... if ((filename = htmlGetVariable(t, (uchar *)"BACKGROUND")) != NULL) htmlSetVariable(t, (uchar *)"BACKGROUND", (uchar *)fix_filename((char *)filename, (char *)base)); descend = 1; break; case MARKUP_IMG : if (have_whitespace) { // Insert a space before this image... insert_space(parent, t); have_whitespace = 0; } // Get the image alignment... t->valignment = ALIGN_BOTTOM; get_alignment(t); // Update the image source as necessary... if ((filename = htmlGetVariable(t, (uchar *)"SRC")) != NULL) htmlSetVariable(t, (uchar *)"REALSRC", (uchar *)fix_filename((char *)filename, (char *)base)); case MARKUP_BR : case MARKUP_NONE : case MARKUP_SPACER : // Figure out the width & height of this markup... compute_size(t); break; case MARKUP_H1 : case MARKUP_H2 : case MARKUP_H3 : case MARKUP_H4 : case MARKUP_H5 : case MARKUP_H6 : case MARKUP_H7 : case MARKUP_H8 : case MARKUP_H9 : case MARKUP_H10 : case MARKUP_H11 : case MARKUP_H12 : case MARKUP_H13 : case MARKUP_H14 : case MARKUP_H15 : get_alignment(t); t->typeface = _htmlHeadingFont; t->subscript = 0; t->superscript = 0; t->strikethrough = 0; t->preformatted = 0; if (t->markup > MARKUP_H6) { t->size = SIZE_H7; t->style = STYLE_ITALIC; } else { t->size = (unsigned)(SIZE_H1 - t->markup + MARKUP_H1); t->style = STYLE_BOLD; } descend = 1; break; case MARKUP_P : get_alignment(t); t->typeface = _htmlBodyFont; t->size = SIZE_P; t->style = STYLE_NORMAL; t->subscript = 0; t->superscript = 0; t->strikethrough = 0; t->preformatted = 0; descend = 1; break; case MARKUP_PRE : t->typeface = _htmlBodyFont >= TYPE_MONOSPACE ? TYPE_MONOSPACE : TYPE_COURIER; t->size = SIZE_PRE; t->style = STYLE_NORMAL; t->subscript = 0; t->superscript = 0; t->strikethrough = 0; t->preformatted = 1; descend = 1; break; case MARKUP_BLOCKQUOTE : case MARKUP_DIR : case MARKUP_MENU : case MARKUP_UL : case MARKUP_OL : case MARKUP_DL : t->indent ++; descend = 1; break; case MARKUP_DIV : get_alignment(t); descend = 1; break; case MARKUP_HR : t->halignment = ALIGN_CENTER; get_alignment(t); break; case MARKUP_DOCTYPE : case MARKUP_AREA : case MARKUP_COMMENT : case MARKUP_INPUT : case MARKUP_ISINDEX : case MARKUP_LINK : case MARKUP_META : case MARKUP_WBR : case MARKUP_COL : break; case MARKUP_EMBED : if ((type = htmlGetVariable(t, (uchar *)"TYPE")) != NULL && strncasecmp((const char *)type, "text/html", 9) != 0) break; if ((filename = htmlGetVariable(t, (uchar *)"SRC")) != NULL) { const char *save_name = _htmlCurrentFile; filename = (uchar *)fix_filename((char *)filename, (char *)base); if ((embed = fopen((char *)filename, "r")) != NULL) { strlcpy(newbase, file_directory((char *)filename), sizeof(newbase)); _htmlCurrentFile = (char *)filename; htmlReadFile(t, embed, newbase); fclose(embed); _htmlCurrentFile = save_name; } #ifndef DEBUG else progress_error(HD_ERROR_FILE_NOT_FOUND, "Unable to embed \"%s\" - %s", filename, strerror(errno)); #endif // !DEBUG } break; case MARKUP_TH : if (htmlGetVariable(t->parent, (uchar *)"ALIGN") != NULL) t->halignment = t->parent->halignment; else t->halignment = ALIGN_CENTER; if (htmlGetVariable(t->parent, (uchar *)"VALIGN") != NULL) t->valignment = t->parent->valignment; else t->valignment = ALIGN_MIDDLE; get_alignment(t); t->style = STYLE_BOLD; descend = 1; break; case MARKUP_TD : if (htmlGetVariable(t->parent, (uchar *)"ALIGN") != NULL) t->halignment = t->parent->halignment; else t->halignment = ALIGN_LEFT; if (htmlGetVariable(t->parent, (uchar *)"VALIGN") != NULL) t->valignment = t->parent->valignment; else t->valignment = ALIGN_MIDDLE; get_alignment(t); t->style = STYLE_NORMAL; descend = 1; break; case MARKUP_SPAN : // Pull style data, if present... if (have_whitespace) { // Insert a space before this element... insert_space(parent, t); have_whitespace = 0; } get_alignment(t); if ((color = htmlGetStyle(t, (uchar *)"color:")) != NULL) compute_color(t, color); if ((face = htmlGetStyle(t, (uchar *)"font-family:")) != NULL) { char font[255], // Font name *fontptr; // Pointer into font name for (ptr = face; *ptr;) { while (isspace(*ptr) || *ptr == ',') ptr ++; if (!*ptr) break; for (fontptr = font; *ptr && *ptr != ',' && !isspace(*ptr); ptr ++) if (fontptr < (font + sizeof(font) - 1)) *fontptr++ = (char)*ptr; *fontptr = '\0'; if (!strcasecmp(font, "serif")) { t->typeface = TYPE_SERIF; break; } else if (!strcasecmp(font, "sans-serif") || !strcasecmp(font, "sans")) { t->typeface = TYPE_SANS_SERIF; break; } else if (!strcasecmp(font, "monospace")) { t->typeface = TYPE_MONOSPACE; break; } else if (!strcasecmp(font, "arial") || !strcasecmp(font, "helvetica")) { t->typeface = TYPE_HELVETICA; break; } else if (!strcasecmp(font, "times")) { t->typeface = TYPE_TIMES; break; } else if (!strcasecmp(font, "courier")) { t->typeface = TYPE_COURIER; break; } else if (!strcasecmp(font, "symbol")) { t->typeface = TYPE_SYMBOL; break; } else if (!strcasecmp(font, "dingbat")) { t->typeface = TYPE_DINGBATS; break; } } } if ((size = htmlGetStyle(t, (uchar *)"font-size:")) != NULL) { // Find the closest size to the fixed sizes... unsigned i; double fontsize = atof((char *)size); for (i = 0; i < 7; i ++) if (fontsize <= _htmlSizes[i]) break; t->size = i; } if ((span = htmlGetStyle(t, (uchar *)"font-style:")) != NULL) { if (!strcmp((char *)span, "normal")) t->style &= ~STYLE_ITALIC; else if (!strcmp((char *)span, "italic") || !strcmp((char *)span, "oblique")) t->style |= STYLE_ITALIC; } if ((span = htmlGetStyle(t, (uchar *)"font-weight:")) != NULL) { if (!strcmp((char *)span, "bold") || !strcmp((char *)span, "bolder") || !strcmp((char *)span, "700") || !strcmp((char *)span, "800") || !strcmp((char *)span, "900")) t->style |= STYLE_BOLD; else if (strcmp((char *)span, "inherit")) t->style &= ~STYLE_BOLD; } if ((span = htmlGetStyle(t, (uchar *)"text-decoration:")) != NULL) { if (!strcmp((char *)span, "underline")) t->underline = 1; else if (!strcmp((char *)span, "line-through")) t->strikethrough = 1; else if (strcmp((char *)span, "inherit")) t->underline = t->strikethrough = 0; } if ((span = htmlGetStyle(t, (uchar *)"vertical-align:")) != NULL) { if (!strcmp((char *)span, "sub")) t->subscript = 1; else if (!strcmp((char *)span, "super")) t->superscript = 1; else if (strcmp((char *)span, "inherit")) t->subscript = t->superscript = 0; } descend = 1; break; case MARKUP_FONT : if (have_whitespace) { // Insert a space before this element... insert_space(parent, t); have_whitespace = 0; } if ((face = htmlGetVariable(t, (uchar *)"FACE")) != NULL) { char font[255], // Font name *fontptr; // Pointer into font name for (ptr = face; *ptr;) { while (isspace(*ptr) || *ptr == ',') ptr ++; if (!*ptr) break; for (fontptr = font; *ptr && *ptr != ',' && !isspace(*ptr); ptr ++) if (fontptr < (font + sizeof(font) - 1)) *fontptr++ = (char)*ptr; *fontptr = '\0'; if (!strcasecmp(font, "serif")) { t->typeface = TYPE_SERIF; break; } else if (!strcasecmp(font, "sans-serif") || !strcasecmp(font, "sans")) { t->typeface = TYPE_SANS_SERIF; break; } else if (!strcasecmp(font, "mono") || !strcasecmp(font, "monospace")) { t->typeface = TYPE_MONOSPACE; break; } else if (!strcasecmp(font, "arial") || !strcasecmp(font, "helvetica")) { t->typeface = TYPE_HELVETICA; break; } else if (!strcasecmp(font, "times")) { t->typeface = TYPE_TIMES; break; } else if (!strcasecmp(font, "courier")) { t->typeface = TYPE_COURIER; break; } else if (!strcasecmp(font, "symbol")) { t->typeface = TYPE_SYMBOL; break; } else if (!strcasecmp(font, "dingbat")) { t->typeface = TYPE_DINGBATS; break; } } } if ((color = htmlGetVariable(t, (uchar *)"COLOR")) != NULL) compute_color(t, color); if ((size = htmlGetVariable(t, (uchar *)"SIZE")) != NULL) { if (have_whitespace) { // Insert a space before sized text... insert_space(parent, t); have_whitespace = 0; } if (isdigit(size[0])) sizeval = atoi((char *)size); else sizeval = t->size + atoi((char *)size); if (sizeval < 0) t->size = 0; else if (sizeval > 7) t->size = 7; else t->size = (unsigned)sizeval; } descend = 1; break; case MARKUP_BIG : if (have_whitespace) { // Insert a space before big text... insert_space(parent, t); have_whitespace = 0; } if (t->size < 6) t->size += 2; else t->size = 7; descend = 1; break; case MARKUP_SMALL : if (have_whitespace) { // Insert a space before small text... insert_space(parent, t); have_whitespace = 0; } if (t->size > 2) t->size -= 2; else t->size = 0; descend = 1; break; case MARKUP_SUP : if (have_whitespace) { // Insert a space before superscript text... insert_space(parent, t); have_whitespace = 0; } t->superscript = 1; if ((sizeval = t->size + SIZE_SUP) < 0) t->size = 0; else t->size = (unsigned)sizeval; descend = 1; break; case MARKUP_SUB : if (have_whitespace) { // Insert a space before subscript text... insert_space(parent, t); have_whitespace = 0; } t->subscript = 1; if ((sizeval = t->size + SIZE_SUB) < 0) t->size = 0; else t->size = (unsigned)sizeval; descend = 1; break; case MARKUP_KBD : t->style = STYLE_BOLD; case MARKUP_TT : case MARKUP_CODE : case MARKUP_SAMP : if (isspace(ch = getc(fp))) have_whitespace = 1; else ungetc(ch, fp); if (have_whitespace) { // Insert a space before monospaced text... insert_space(parent, t); have_whitespace = 0; } t->typeface = _htmlBodyFont >= TYPE_MONOSPACE ? TYPE_MONOSPACE : TYPE_COURIER; descend = 1; break; case MARKUP_STRONG : case MARKUP_B : t->style = (style_t)(t->style | STYLE_BOLD); descend = 1; break; case MARKUP_DD : t->indent ++; descend = 1; break; case MARKUP_VAR : t->style = (style_t)(t->style | STYLE_ITALIC); case MARKUP_DFN : t->typeface = _htmlBodyFont >= TYPE_MONOSPACE ? TYPE_SANS_SERIF : TYPE_HELVETICA; descend = 1; break; case MARKUP_CITE : case MARKUP_EM : case MARKUP_I : t->style = (style_t)(t->style | STYLE_ITALIC); descend = 1; break; case MARKUP_U : case MARKUP_INS : if (have_whitespace) { // Insert a space before underlined text... insert_space(parent, t); have_whitespace = 0; } t->underline = 1; descend = 1; break; case MARKUP_STRIKE : case MARKUP_S : case MARKUP_DEL : if (have_whitespace) { // Insert a space before struck-through text... insert_space(parent, t); have_whitespace = 0; } t->strikethrough = 1; descend = 1; break; case MARKUP_CENTER : t->halignment = ALIGN_CENTER; descend = 1; break; case MARKUP_A : if (have_whitespace) { // Insert a space before this link... insert_space(parent, t); have_whitespace = 0; } descend = 1; break; default : // All other markup types should be using ... get_alignment(t); descend = 1; break; } if (descend) { #ifdef DEBUG strlcat((char *)indent, " ", sizeof(indent)); #endif // DEBUG parent = t; prev = NULL; } } return (tree); } // // 'write_file()' - Write a tree entry to a file... // static int // I - New column write_file(tree_t *t, // I - Tree entry FILE *fp, // I - File to write to int col) // I - Current column { int i; // Looping var uchar *ptr; // Character pointer while (t != NULL) { if (t->markup == MARKUP_NONE) { if (t->preformatted) { for (ptr = t->data; *ptr != '\0'; ptr ++) fputs((char *)iso8859(*ptr), fp); if (t->data[0] && t->data[strlen((char *)t->data) - 1] == '\n') col = 0; else col += strlen((char *)t->data); } else { if ((col + (int)strlen((char *)t->data)) > 72 && col > 0) { putc('\n', fp); col = 0; } for (ptr = t->data; *ptr != '\0'; ptr ++) fputs((char *)iso8859(*ptr), fp); col += strlen((char *)t->data); if (col > 72) { putc('\n', fp); col = 0; } } } else if (t->markup == MARKUP_COMMENT) fprintf(fp, "\n\n", t->data); else if (t->markup > 0) { switch (t->markup) { case MARKUP_AREA : case MARKUP_BR : case MARKUP_CENTER : case MARKUP_COMMENT : case MARKUP_DD : case MARKUP_DL : case MARKUP_DT : case MARKUP_H1 : case MARKUP_H2 : case MARKUP_H3 : case MARKUP_H4 : case MARKUP_H5 : case MARKUP_H6 : case MARKUP_HEAD : case MARKUP_HR : case MARKUP_LI : case MARKUP_MAP : case MARKUP_OL : case MARKUP_P : case MARKUP_PRE : case MARKUP_TABLE : case MARKUP_TITLE : case MARKUP_TR : case MARKUP_UL : case MARKUP_DIR : case MARKUP_MENU : if (col > 0) { putc('\n', fp); col = 0; } default : break; } col += fprintf(fp, "<%s", _htmlMarkups[t->markup]); for (i = 0; i < t->nvars; i ++) { if (col > 72 && !t->preformatted) { putc('\n', fp); col = 0; } if (col > 0) { putc(' ', fp); col ++; } if (t->vars[i].value == NULL) col += fprintf(fp, "%s", t->vars[i].name); else if (strchr((char *)t->vars[i].value, '\"') != NULL) col += fprintf(fp, "%s=\'%s\'", t->vars[i].name, t->vars[i].value); else col += fprintf(fp, "%s=\"%s\"", t->vars[i].name, t->vars[i].value); } putc('>', fp); col ++; if (col > 72 && !t->preformatted) { putc('\n', fp); col = 0; } if (t->child != NULL) { col = write_file(t->child, fp, col); if (col > 72 && !t->preformatted) { putc('\n', fp); col = 0; } col += fprintf(fp, "", _htmlMarkups[t->markup]); switch (t->markup) { case MARKUP_AREA : case MARKUP_BR : case MARKUP_CENTER : case MARKUP_COMMENT : case MARKUP_DD : case MARKUP_DL : case MARKUP_DT : case MARKUP_H1 : case MARKUP_H2 : case MARKUP_H3 : case MARKUP_H4 : case MARKUP_H5 : case MARKUP_H6 : case MARKUP_HEAD : case MARKUP_HR : case MARKUP_LI : case MARKUP_MAP : case MARKUP_OL : case MARKUP_P : case MARKUP_PRE : case MARKUP_TABLE : case MARKUP_TITLE : case MARKUP_TR : case MARKUP_UL : case MARKUP_DIR : case MARKUP_MENU : putc('\n', fp); col = 0; default : break; } } } t = t->next; } return (col); } // // 'htmlWriteFile()' - Write an HTML markup tree to a file. // int // O - Write status: 0 = success, -1 = fail htmlWriteFile(tree_t *parent, // I - Parent tree entry FILE *fp) // I - File to write to { if (write_file(parent, fp, 0) < 0) return (-1); else return (0); } // // 'htmlAddTree()' - Add a tree node to the parent. // tree_t * // O - New entry htmlAddTree(tree_t *parent, // I - Parent entry markup_t markup, // I - Markup code uchar *data) // I - Data/text { tree_t *t; // New tree entry if ((t = htmlNewTree(parent, markup, data)) == NULL) return (NULL); // Add the tree entry to the end of the chain of children... if (parent != NULL) { if (parent->last_child != NULL) { parent->last_child->next = t; t->prev = parent->last_child; } else parent->child = t; parent->last_child = t; } return (t); } // // 'htmlDeleteTree()' - Free all memory associated with a tree... // int // O - 0 for success, -1 for failure htmlDeleteTree(tree_t *parent) // I - Parent to delete { tree_t *next; // Next tree entry if (parent == NULL) return (-1); while (parent != NULL) { next = parent->next; if (parent->child != NULL) if (htmlDeleteTree(parent->child)) return (-1); delete_node(parent); parent = next; } return (0); } // // 'htmlInsertTree()' - Insert a tree node under the parent. // tree_t * // O - New entry htmlInsertTree(tree_t *parent,// I - Parent entry markup_t markup, // I - Markup code uchar *data) // I - Data/text { tree_t *t; // New tree entry if ((t = htmlNewTree(parent, markup, data)) == NULL) return (NULL); // Insert the tree entry at the beginning of the chain of children... if (parent != NULL) { if (parent->child != NULL) { parent->child->prev = t; t->next = parent->child; } else parent->last_child = t; parent->child = t; } return (t); } // // 'htmlMapUnicode()' - Map a Unicode character to the custom character set. // uchar // O - Charset character htmlMapUnicode(int ch) // I - Unicode character { uchar newch; // New charset character // If we already have a mapping for this character, return it... if (_htmlCharacters[ch]) return (_htmlCharacters[ch]); if (_htmlUTF8 >= 0x100) { progress_error(HD_ERROR_READ_ERROR, "Too many Unicode code points."); return (0); } newch = _htmlUTF8++; _htmlCharacters[ch] = (uchar)newch; _htmlUnicode[newch] = ch; _htmlGlyphs[newch] = _htmlGlyphsAll[ch]; for (int i = 0; i < TYPE_MAX; i ++) for (int j = 0; j < STYLE_MAX; j ++) _htmlWidths[i][j][newch] = _htmlWidthsAll[i][j][ch]; return (newch); } // // 'htmlNewTree()' - Create a new tree node for the parent. // tree_t * // O - New entry htmlNewTree(tree_t *parent, // I - Parent entry markup_t markup, // I - Markup code uchar *data) // I - Data/text { tree_t *t; // New tree entry // Allocate a new tree entry - use calloc() to get zeroed data... t = (tree_t *)calloc(sizeof(tree_t), 1); if (t == NULL) return (NULL); // Set the markup code and copy the data if necessary... t->markup = markup; if (data != NULL) t->data = (uchar *)hd_strdup((char *)data); // Set/copy font characteristics... if (parent == NULL) { t->halignment = ALIGN_LEFT; t->valignment = ALIGN_BOTTOM; t->typeface = _htmlBodyFont; t->size = SIZE_P; compute_color(t, _htmlTextColor); } else { t->link = parent->link; t->halignment = parent->halignment; t->valignment = parent->valignment; t->typeface = parent->typeface; t->size = parent->size; t->style = parent->style; t->preformatted = parent->preformatted; t->indent = parent->indent; t->red = parent->red; t->green = parent->green; t->blue = parent->blue; t->underline = parent->underline; t->strikethrough = parent->strikethrough; } switch (t->markup) { case MARKUP_NONE : case MARKUP_IMG : // Figure out the width & height of this fragment... compute_size(t); break; case MARKUP_H1 : case MARKUP_H2 : case MARKUP_H3 : case MARKUP_H4 : case MARKUP_H5 : case MARKUP_H6 : get_alignment(t); t->typeface = _htmlHeadingFont; t->size = (unsigned)(SIZE_H1 - t->markup + MARKUP_H1); t->subscript = 0; t->superscript = 0; t->strikethrough = 0; t->preformatted = 0; t->style = STYLE_BOLD; break; case MARKUP_P : get_alignment(t); t->typeface = _htmlBodyFont; t->size = SIZE_P; t->style = STYLE_NORMAL; t->subscript = 0; t->superscript = 0; t->strikethrough = 0; t->preformatted = 0; break; case MARKUP_PRE : t->typeface = _htmlBodyFont >= TYPE_MONOSPACE ? TYPE_MONOSPACE : TYPE_COURIER; t->size = SIZE_PRE; t->style = STYLE_NORMAL; t->subscript = 0; t->superscript = 0; t->strikethrough = 0; t->preformatted = 1; break; case MARKUP_DIV : get_alignment(t); break; case MARKUP_BLOCKQUOTE : t->style = STYLE_ITALIC; case MARKUP_UL : case MARKUP_DIR : case MARKUP_MENU : case MARKUP_OL : case MARKUP_DL : t->indent ++; break; case MARKUP_AREA : case MARKUP_BR : case MARKUP_COMMENT : case MARKUP_HR : case MARKUP_INPUT : case MARKUP_ISINDEX : case MARKUP_META : case MARKUP_WBR : break; case MARKUP_TH : t->style = STYLE_BOLD; case MARKUP_TD : get_alignment(t); break; case MARKUP_SUP : t->superscript = 1; t->size = SIZE_P + SIZE_SUP; break; case MARKUP_SUB : t->subscript = 1; t->size = SIZE_P + SIZE_SUB; break; case MARKUP_B : t->style = (style_t)(t->style | STYLE_BOLD); break; case MARKUP_DD : t->indent ++; break; case MARKUP_DT : case MARKUP_I : t->style = (style_t)(t->style | STYLE_ITALIC); break; case MARKUP_U : case MARKUP_INS : t->underline = 1; break; case MARKUP_STRIKE : case MARKUP_DEL : t->strikethrough = 1; break; default : break; } t->parent = parent; return (t); } // // 'htmlGetText()' - Get all text from the given tree. // uchar * // O - String containing text nodes htmlGetText(tree_t *t) // I - Tree to pick { uchar *s, // String *s2, // New string *tdata = NULL, // Temporary string data *talloc = NULL; // Allocated string data size_t slen, // Length of string tlen; // Length of node string // Loop through all of the nodes in the tree and collect text... slen = 0; s = NULL; while (t != NULL) { if (t->child) tdata = talloc = htmlGetText(t->child); else tdata = t->data; tlen = tdata ? strlen((char *)tdata) : 0; if (tdata != NULL && tlen > 0) { // Add the text to this string... if (s) s2 = (uchar *)realloc(s, 1 + slen + tlen); else s2 = (uchar *)malloc(1 + tlen); if (!s2) break; s = s2; memcpy((char *)s + slen, (char *)tdata, tlen); slen += tlen; } if (talloc) { free(talloc); talloc = NULL; } t = t->next; } if (slen) s[slen] = '\0'; if (talloc) free(talloc); return (s); } // // 'htmlGetMeta()' - Get document "meta" data... // uchar * // O - Content string htmlGetMeta(tree_t *tree, // I - Document tree uchar *name) // I - Metadata name { uchar *tname, // Name value from tree entry *tcontent; // Content value from tree entry while (tree != NULL) { // Check this tree entry... if (tree->markup == MARKUP_META && (tname = htmlGetVariable(tree, (uchar *)"NAME")) != NULL && (tcontent = htmlGetVariable(tree, (uchar *)"CONTENT")) != NULL) { if (strcasecmp((char *)name, (char *)tname) == 0) return (tcontent); } else if (tree->markup == MARKUP_HTML && !strcasecmp((char *)name, "LANG") && (tcontent = htmlGetVariable(tree, (uchar *)"LANG")) != NULL) { return (tcontent); } // Check child entries... if (tree->child != NULL) if ((tcontent = htmlGetMeta(tree->child, name)) != NULL) return (tcontent); // Next tree entry... tree = tree->next; } return (NULL); } // // 'htmlGetStyle()' - Get a style value from a node's STYLE attribute. // uchar * // O - Value or NULL htmlGetStyle(tree_t *t, // I - Node uchar *name) // I - Name (including ":") { uchar *ptr, // Pointer in STYLE attribute *bufptr; // Pointer in buffer size_t ptrlen, // Length of STYLE attribute namelen; // Length of name static uchar buffer[1024]; // Buffer for value // See if we have a STYLE attribute... if ((ptr = htmlGetVariable(t, (uchar *)"STYLE")) == NULL) return (NULL); // Loop through the STYLE attribute looking for the name... for (namelen = strlen((char *)name), ptrlen = strlen((char *)ptr); ptrlen > namelen; ptr ++, ptrlen --) if (strncasecmp((char *)name, (char *)ptr, namelen) == 0) { for (ptr += namelen; isspace(*ptr); ptr ++); for (bufptr = buffer; *ptr && *ptr != ';' && bufptr < (buffer + sizeof(buffer) - 1); *bufptr++ = *ptr++); *bufptr = '\0'; return (buffer); } return (NULL); } // // 'htmlGetVariable()' - Get a variable value from a markup entry. // uchar * // O - Value or NULL if variable does not exist htmlGetVariable(tree_t *t, // I - Tree entry uchar *name) // I - Variable name { var_t *v, // Matching variable key; // Search key if (t == NULL || name == NULL || t->nvars == 0) return (NULL); key.name = name; v = (var_t *)bsearch(&key, t->vars, (size_t)t->nvars, sizeof(var_t), (compare_func_t)compare_variables); if (v == NULL) return (NULL); else if (v->value == NULL) return ((uchar *)""); else return (v->value); } // // 'htmlLoadFontWidths()' - Load all of the font width files. // void htmlLoadFontWidths(int typeface, int style) { char filename[1024]; // Filenames FILE *fp; // Files int ch; // Character float width; // Width value char glyph[64]; // Glyph name char line[1024]; // Line from AFM file // Now read all of the font widths... for (ch = 0; ch < 256; ch ++) _htmlWidths[typeface][style][ch] = 600; if (_htmlUTF8) { for (ch = 0; ch < 65536; ch ++) _htmlWidthsAll[typeface][style][ch] = 600; } snprintf(filename, sizeof(filename), "%s/fonts/%s.afm", _htmlData, _htmlFonts[typeface][style]); if ((fp = fopen(filename, "r")) == NULL) { #ifndef DEBUG progress_error(HD_ERROR_FILE_NOT_FOUND, "Unable to open font width file %s!", filename); #endif // !DEBUG return; } while (fgets(line, sizeof(line), fp) != NULL) { if (strncmp(line, "C ", 2) != 0) continue; if (typeface < TYPE_SYMBOL) { // Handle encoding of regular fonts using assigned charset... if (sscanf(line, "%*s%*s%*s%*s%f%*s%*s%63s", &width, glyph) != 2) continue; for (ch = 0; ch < 256; ch ++) { if (_htmlGlyphs[ch] && !strcmp(_htmlGlyphs[ch], glyph)) { _htmlWidths[typeface][style][ch] = (short)width; break; } } if (_htmlUTF8) { for (ch = 0; ch < 65536; ch ++) { if (_htmlGlyphsAll[ch] && !strcmp(_htmlGlyphsAll[ch], glyph)) { _htmlWidthsAll[typeface][style][ch] = (short)width; break; } } } } else { // Symbol and Dingbats fonts uses their own encoding... if (sscanf(line, "%*s%d%*s%*s%f", &ch, &width) != 2) continue; if (ch < 256 && ch >= 0) { _htmlWidths[typeface][style][ch] = (short)width; _htmlWidthsAll[typeface][style][ch] = (short)width; } } } fclose(fp); // Make sure that non-breaking space has the same width as a breaking space... _htmlWidths[typeface][style][160] = _htmlWidths[typeface][style][32]; _htmlWidthsAll[typeface][style][160] = _htmlWidthsAll[typeface][style][32]; _htmlWidthsLoaded[typeface][style] = 1; } // // 'htmlSetVariable()' - Set a variable for a markup entry. // int // O - Set status: 0 = success, -1 = fail htmlSetVariable(tree_t *t, // I - Tree entry uchar *name, // I - Variable name uchar *value) // I - Variable value { var_t *v, // Matching variable key; // Search key DEBUG_printf(("%shtmlSetVariable(%p, \"%s\", \"%s\")\n", indent, (void *)t, name, value ? (const char *)value : "(null)")); if (t->nvars == 0) v = NULL; else { key.name = name; v = (var_t *)bsearch(&key, t->vars, (size_t)t->nvars, sizeof(var_t), (compare_func_t)compare_variables); } if (v == NULL) { if (t->nvars == 0) v = (var_t *)malloc(sizeof(var_t)); else v = (var_t *)realloc(t->vars, sizeof(var_t) * (size_t)(t->nvars + 1)); if (v == NULL) { DEBUG_printf(("%s==== MALLOC/REALLOC FAILED! ====\n", indent)); return (-1); } t->vars = v; v += t->nvars; t->nvars ++; v->name = (uchar *)hd_strdup((char *)name); if (value != NULL) v->value = (uchar *)hd_strdup((char *)value); else v->value = NULL; if (strcasecmp((char *)name, "HREF") == 0) { DEBUG_printf(("%s---- Set link to %s ----\n", indent, value)); t->link = t; } if (t->nvars > 1) qsort(t->vars, (size_t)t->nvars, sizeof(var_t), (compare_func_t)compare_variables); } else if (v->value != value) { v->value = (uchar *)hd_strdup((char *)value); } return (0); } // // 'htmlSetBaseSize()' - Set the font sizes and spacings... // void htmlSetBaseSize(double p, // I - Point size of paragraph font double s) // I - Spacing { int i; // Looping var p /= 1.2 * 1.2 * 1.2; for (i = 0; i < 8; i ++, p *= 1.2) { _htmlSizes[i] = p; _htmlSpacings[i] = p * s; } } // // 'htmlSetCharSet()' - Set the character set for output. // void htmlSetCharSet(const char *cs) // I - Character set file to load { int i; // Looping var char filename[1024]; // Filenames FILE *fp; // Files int ch, unicode; // Character values char glyph[64]; // Glyph name char line[1024]; // Line from charset file int chars[256]; // Character encoding array strlcpy(_htmlCharSet, cs, sizeof(_htmlCharSet)); if (!_htmlInitialized) { // Load the PostScript glyph names for all of Unicode... memset(_htmlGlyphsAll, 0, sizeof(_htmlGlyphsAll)); snprintf(line, sizeof(line), "%s/data/psglyphs", _htmlData); if ((fp = fopen(line, "r")) != NULL) { while (fscanf(fp, "%x%63s", &unicode, glyph) == 2) _htmlGlyphsAll[unicode] = strdup(glyph); fclose(fp); _htmlInitialized = 1; } #ifndef DEBUG else progress_error(HD_ERROR_FILE_NOT_FOUND, "Unable to open psglyphs data file!"); #endif // !DEBUG } memset(_htmlGlyphs, 0, sizeof(_htmlGlyphs)); if (!strcmp(cs, "utf-8")) { // Generate a dynamic mapping of Unicode to an 8-bit charset with the // bottom 128 characters matching US ASCII... _htmlUTF8 = 0x80; memset(_htmlCharacters, 0, sizeof(_htmlCharacters)); for (i = 0; i < 128; i ++) { // Add the glyph to the charset array... _htmlGlyphs[i] = _htmlGlyphsAll[i]; _htmlUnicode[i] = i; } memset(_htmlWidthsLoaded, 0, sizeof(_htmlWidthsLoaded)); return; } if (strncmp(cs, "8859-", 5) == 0) snprintf(filename, sizeof(filename), "%s/data/iso-%s", _htmlData, cs); else snprintf(filename, sizeof(filename), "%s/data/%s", _htmlData, cs); if ((fp = fopen(filename, "r")) == NULL) { // Can't open charset file; use ISO-8859-1... #ifndef DEBUG progress_error(HD_ERROR_FILE_NOT_FOUND, "Unable to open character set file %s!", cs); #endif // !DEBUG for (i = 0; i < 256; i ++) chars[i] = i; } else { // Read the lines from the file... memset(chars, 0, sizeof(chars)); while (fscanf(fp, "%x%x", &ch, &unicode) == 2) chars[ch] = unicode; fclose(fp); } // Build the glyph array... for (i = 0; i < 256; i ++) { // Add the glyph to the charset array... if (chars[i] == 0) { _htmlGlyphs[i] = NULL; continue; } else _htmlGlyphs[i] = _htmlGlyphsAll[chars[i]]; if (_htmlGlyphs[i]) _htmlUnicode[i] = chars[i]; } memset(_htmlWidthsLoaded, 0, sizeof(_htmlWidthsLoaded)); } // // 'htmlSetTextColor()' - Set the default text color. // void htmlSetTextColor(uchar *color) // I - Text color { strlcpy((char *)_htmlTextColor, (char *)color, sizeof(_htmlTextColor)); } // // 'compare_variables()' - Compare two markup variables. // static int // O - -1 if v0 < v1, 0 if v0 == v1, 1 if v0 > v1 compare_variables(var_t *v0, // I - First variable var_t *v1) // I - Second variable { return (strcasecmp((char *)v0->name, (char *)v1->name)); } // // 'compare_markups()' - Compare two markup strings... // static int // O - -1 if m0 < m1, 0 if m0 == m1, 1 if m0 > m1 compare_markups(uchar **m0, // I - First markup uchar **m1) // I - Second markup { if (tolower((*m0)[0]) == 'h' && isdigit((*m0)[1]) && tolower((*m1)[0]) == 'h' && isdigit((*m1)[1])) return (atoi((char *)*m0 + 1) - atoi((char *)*m1 + 1)); else return (strcasecmp((char *)*m0, (char *)*m1)); } // // 'delete_node()' - Free all memory associated with a node... // static void delete_node(tree_t *t) // I - Node to delete { if (t == NULL) return; free(t->vars); free(t); } // // 'insert_space()' - Insert a whitespace character before the // specified node. // static void insert_space(tree_t *parent, // I - Parent node tree_t *t) // I - Node to insert before { tree_t *space; // Space node // Allocate memory for the whitespace... space = (tree_t *)calloc(sizeof(tree_t), 1); if (space == NULL) { #ifndef DEBUG progress_error(HD_ERROR_OUT_OF_MEMORY, "Unable to allocate memory for HTML tree node!"); #endif // !DEBUG return; } // Set/copy font characteristics... if (parent) { space->typeface = parent->typeface; space->size = parent->size; space->style = parent->style; } else { space->typeface = _htmlBodyFont; space->size = SIZE_P; } // Initialize element data... space->markup = MARKUP_NONE; space->data = (uchar *)" "; // Set tree pointers... space->parent = parent; space->prev = t->prev; space->next = t; if (space->prev) space->prev->next = space; else if (parent) parent->child = space; t->prev = space; compute_size(space); } // // 'parse_markup()' - Parse a markup string. // static int // O - -1 on error, MARKUP_nnnn otherwise parse_markup(tree_t *t, // I - Current tree entry FILE *fp, // I - Input file int *linenum) // O - Current line number { int ch, ch2; // Characters from file uchar markup[255], // Markup string... *mptr, // Current character... comment[10240], // Comment string *cptr, // Current char... **temp; // Markup variable entry mptr = markup; while ((ch = getc(fp)) != EOF && mptr < (markup + sizeof(markup) - 1)) if (ch == '>' || isspace(ch)) break; else if (ch == '/' && mptr > markup) { // Look for "/>"... ch = getc(fp); if (ch != '>') return (MARKUP_ERROR); break; } else { if ((ch & 0x80) && _htmlUTF8) { // Collect UTF-8 value... ch = utf8_getc(ch, fp); } if (ch) *mptr++ = (uchar)ch; // Handle comments without whitespace... if ((mptr - markup) == 3 && strncmp((const char *)markup, "!--", 3) == 0) { ch = getc(fp); break; } } *mptr = '\0'; if (ch == EOF) return (MARKUP_ERROR); mptr = markup; temp = (uchar **)bsearch(&mptr, _htmlMarkups, sizeof(_htmlMarkups) / sizeof(_htmlMarkups[0]), sizeof(_htmlMarkups[0]), (compare_func_t)compare_markups); if (temp == NULL) { // Unrecognized markup stuff... t->markup = MARKUP_UNKNOWN; strlcpy((char *)comment, (char *)markup, sizeof(comment)); cptr = comment + strlen((char *)comment); DEBUG_printf(("%s%s (unrecognized!)\n", indent, markup)); } else { t->markup = (markup_t)((const char **)temp - _htmlMarkups); cptr = comment; DEBUG_printf(("%s%s, line %d\n", indent, markup, *linenum)); } if (t->markup == MARKUP_COMMENT || t->markup == MARKUP_UNKNOWN) { int lastch = ch; // Last character seen while (ch != EOF && cptr < (comment + sizeof(comment) - 2)) { if (ch == '>' && temp == NULL) break; if (ch == '\n') (*linenum) ++; if (ch == '-' && lastch == '-') { *cptr++ = (uchar)ch; if ((ch2 = getc(fp)) == '>') { // Erase trailing --> cptr -= 2; if (cptr < comment) cptr = comment; // Issue #316: buffer underflow break; } else ch = ch2; } else { if (ch == '&') { // Handle character entities... uchar entity[16], // Character entity name *eptr; // Pointer into name eptr = entity; while (eptr < (entity + sizeof(entity) - 1) && (ch = getc(fp)) != EOF) if (!isalnum(ch) && ch != '#') break; else *eptr++ = (uchar)ch; if (ch != ';') { ungetc(ch, fp); ch = 0; } *eptr = '\0'; if (!ch) { progress_error(HD_ERROR_HTML_ERROR, "Unquoted & on line %d of %s.", *linenum, _htmlCurrentFile); if (cptr < (comment + sizeof(comment) - 1)) *cptr++ = '&'; strlcpy((char *)cptr, (char *)entity, sizeof(comment) - (size_t)(cptr - comment)); cptr += strlen((char *)cptr); } else if ((ch = iso8859(entity)) == 0) { progress_error(HD_ERROR_HTML_ERROR, "Unknown character entity \"&%s;\" on line %d of %s.", entity, *linenum, _htmlCurrentFile); if (cptr < (comment + sizeof(comment) - 1)) *cptr++ = '&'; strlcpy((char *)cptr, (char *)entity, sizeof(comment) - (size_t)(cptr - comment)); cptr += strlen((char *)cptr); if (cptr < (comment + sizeof(comment) - 1)) *cptr++ = ';'; } else *cptr++ = (uchar)ch; } else { if ((ch & 0x80) && _htmlUTF8) { // Collect UTF-8 value... ch = utf8_getc(ch, fp); } if (ch) *cptr++ = (uchar)ch; } lastch = ch; ch = getc(fp); } } *cptr = '\0'; t->data = (uchar *)hd_strdup((char *)comment); } else { while (ch != EOF && ch != '>') { if (ch == '\n') (*linenum) ++; if (!isspace(ch)) { ungetc(ch, fp); parse_variable(t, fp, linenum); } ch = getc(fp); if (ch == '/') { // Look for "/>"... ch = getc(fp); if (ch != '>') return (MARKUP_ERROR); break; } } } return (t->markup); } // // 'parse_variable()' - Parse a markup variable string. // static int // O - -1 on error, 0 on success parse_variable(tree_t *t, // I - Current tree entry FILE *fp, // I - Input file int *linenum) // I - Current line number { uchar name[1024], // Name of variable value[10240], // Value of variable *ptr, // Temporary pointer entity[16], // Character entity name *eptr; // Pointer into name int ch; // Character from file ptr = name; while ((ch = getc(fp)) != EOF) if (isspace(ch) || ch == '=' || ch == '>' || ch == '\r') break; else if (ch == '/' && ptr == name) break; else if (ptr < (name + sizeof(name) - 1)) { if ((ch & 0x80) && _htmlUTF8) { // Collect UTF-8 value... ch = utf8_getc(ch, fp); } if (ch) *ptr++ = (uchar)ch; } *ptr = '\0'; if (ch == '\n') (*linenum) ++; while (isspace(ch) || ch == '\r') { ch = getc(fp); if (ch == '\n') (*linenum) ++; } switch (ch) { default : ungetc(ch, fp); return (htmlSetVariable(t, name, NULL)); case EOF : return (-1); case '=' : ptr = value; ch = getc(fp); while (isspace(ch) || ch == '\r') ch = getc(fp); if (ch == EOF) return (-1); if (ch == '\'') { while ((ch = getc(fp)) != EOF) { if (ch == '\'') break; else if (ch == '&') { // Possibly a character entity... eptr = entity; while (eptr < (entity + sizeof(entity) - 1) && (ch = getc(fp)) != EOF) if (!isalnum(ch) && ch != '#') break; else *eptr++ = (uchar)ch; if (ch != ';') { ungetc(ch, fp); ch = 0; } *eptr = '\0'; if (!ch) { progress_error(HD_ERROR_HTML_ERROR, "Unquoted & on line %d of %s.", *linenum, _htmlCurrentFile); if (ptr < (value + sizeof(value) - 1)) *ptr++ = '&'; strlcpy((char *)ptr, (char *)entity, sizeof(value) - (size_t)(ptr - value)); ptr += strlen((char *)ptr); } else if ((ch = iso8859(entity)) == 0) { progress_error(HD_ERROR_HTML_ERROR, "Unknown character entity \"&%s;\" on line %d of %s.", entity, *linenum, _htmlCurrentFile); if (ptr < (value + sizeof(value) - 1)) *ptr++ = '&'; strlcpy((char *)ptr, (char *)entity, sizeof(value) - (size_t)(ptr - value)); ptr += strlen((char *)ptr); if (ptr < (value + sizeof(value) - 1)) *ptr++ = ';'; } else if (ptr < (value + sizeof(value) - 1)) *ptr++ = (uchar)ch; } else if (ptr < (value + sizeof(value) - 1) && ch != '\n' && ch != '\r') { if ((ch & 0x80) && _htmlUTF8) { // Collect UTF-8 value... ch = utf8_getc(ch, fp); } if (ch) *ptr++ = (uchar)ch; } else if (ch == '\n') { if (ptr < (value + sizeof(value) - 1)) *ptr++ = ' '; (*linenum) ++; } } *ptr = '\0'; } else if (ch == '\"') { while ((ch = getc(fp)) != EOF) { if (ch == '\"') break; else if (ch == '&') { // Possibly a character entity... eptr = entity; while (eptr < (entity + sizeof(entity) - 1) && (ch = getc(fp)) != EOF) if (!isalnum(ch) && ch != '#') break; else *eptr++ = (uchar)ch; if (ch != ';') { ungetc(ch, fp); ch = 0; } *eptr = '\0'; if (!ch) { progress_error(HD_ERROR_HTML_ERROR, "Unquoted & on line %d of %s.", *linenum, _htmlCurrentFile); if (ptr < (value + sizeof(value) - 1)) *ptr++ = '&'; strlcpy((char *)ptr, (char *)entity, sizeof(value) - (size_t)(ptr - value)); ptr += strlen((char *)ptr); } else if ((ch = iso8859(entity)) == 0) { progress_error(HD_ERROR_HTML_ERROR, "Unknown character entity \"&%s;\" on line %d of %s.", entity, *linenum, _htmlCurrentFile); if (ptr < (value + sizeof(value) - 1)) *ptr++ = '&'; strlcpy((char *)ptr, (char *)entity, sizeof(value) - (size_t)(ptr - value)); ptr += strlen((char *)ptr); if (ptr < (value + sizeof(value) - 1)) *ptr++ = ';'; } else if (ptr < (value + sizeof(value) - 1)) *ptr++ = (uchar)ch; } else if (ptr < (value + sizeof(value) - 1) && ch != '\n' && ch != '\r') { if ((ch & 0x80) && _htmlUTF8) { // Collect UTF-8 value... ch = utf8_getc(ch, fp); } if (ch) *ptr++ = (uchar)ch; } else if (ch == '\n') { if (ptr < (value + sizeof(value) - 1)) *ptr++ = ' '; (*linenum) ++; } } *ptr = '\0'; } else { *ptr++ = (uchar)ch; while ((ch = getc(fp)) != EOF) { if (isspace(ch) || ch == '>' || ch == '\r') break; else if (ch == '&') { // Possibly a character entity... eptr = entity; while (eptr < (entity + sizeof(entity) - 1) && (ch = getc(fp)) != EOF) if (!isalnum(ch) && ch != '#') break; else *eptr++ = (uchar)ch; if (ch != ';') { ungetc(ch, fp); ch = 0; } *eptr = '\0'; if (!ch) { progress_error(HD_ERROR_HTML_ERROR, "Unquoted & on line %d of %s.", *linenum, _htmlCurrentFile); if (ptr < (value + sizeof(value) - 1)) *ptr++ = '&'; strlcpy((char *)ptr, (char *)entity, sizeof(value) - (size_t)(ptr - value)); ptr += strlen((char *)ptr); } else if ((ch = iso8859(entity)) == 0) { progress_error(HD_ERROR_HTML_ERROR, "Unknown character entity \"&%s;\" on line %d of %s.", entity, *linenum, _htmlCurrentFile); if (ptr < (value + sizeof(value) - 1)) *ptr++ = '&'; strlcpy((char *)ptr, (char *)entity, sizeof(value) - (size_t)(ptr - value)); ptr += strlen((char *)ptr); if (ptr < (value + sizeof(value) - 1)) *ptr++ = ';'; } else if (ptr < (value + sizeof(value) - 1)) *ptr++ = (uchar)ch; } else if (ptr < (value + sizeof(value) - 1)) { if ((ch & 0x80) && _htmlUTF8) { // Collect UTF-8 value... ch = utf8_getc(ch, fp); } if (ch) *ptr++ = (uchar)ch; } } if (ch == '\n') (*linenum) ++; *ptr = '\0'; if (ch == '>') ungetc(ch, fp); } return (htmlSetVariable(t, name, value)); } } // // 'compute_size()' - Compute the width and height of a tree entry. // static int // O - 0 = success, -1 = failure compute_size(tree_t *t) // I - Tree entry { uchar *ptr; // Current character float width; // Current width int int_width; // Integer width uchar *width_ptr, // Pointer to width string *height_ptr, // Pointer to height string *size_ptr, // Pointer to size string *type_ptr; // Pointer to spacer type string image_t *img; // Image char number[255]; // Width or height value if (!_htmlInitialized) htmlSetCharSet("iso-8859-1"); if (t->markup == MARKUP_IMG) { width_ptr = htmlGetVariable(t, (uchar *)"WIDTH"); height_ptr = htmlGetVariable(t, (uchar *)"HEIGHT"); img = image_load((char *)htmlGetVariable(t, (uchar *)"REALSRC"), _htmlGrayscale); if (width_ptr != NULL && height_ptr != NULL) { t->width = (float)(atoi((char *)width_ptr) / _htmlPPI * 72.0f); t->height = (float)(atoi((char *)height_ptr) / _htmlPPI * 72.0f); return (0); } if (img == NULL) return (-1); if (width_ptr != NULL) { t->width = (float)(atoi((char *)width_ptr) / _htmlPPI * 72.0f); t->height = (float)(t->width * img->height / img->width); snprintf(number, sizeof(number), "%d", atoi((char *)width_ptr) * img->height / img->width); if (strchr((char *)width_ptr, '%') != NULL) strlcat(number, "%", sizeof(number)); htmlSetVariable(t, (uchar *)"HEIGHT", (uchar *)number); } else if (height_ptr != NULL) { t->height = (float)(atoi((char *)height_ptr) / _htmlPPI * 72.0f); t->width = (float)(t->height * img->width / img->height); snprintf(number, sizeof(number), "%d", atoi((char *)height_ptr) * img->width / img->height); if (strchr((char *)height_ptr, '%') != NULL) strlcat(number, "%", sizeof(number)); htmlSetVariable(t, (uchar *)"WIDTH", (uchar *)number); } else { t->width = (float)(img->width / _htmlPPI * 72.0f); t->height = (float)(img->height / _htmlPPI * 72.0f); snprintf(number, sizeof(number), "%d", img->width); htmlSetVariable(t, (uchar *)"WIDTH", (uchar *)number); snprintf(number, sizeof(number), "%d", img->height); htmlSetVariable(t, (uchar *)"HEIGHT", (uchar *)number); } return (0); } else if (t->markup == MARKUP_SPACER) { width_ptr = htmlGetVariable(t, (uchar *)"WIDTH"); height_ptr = htmlGetVariable(t, (uchar *)"HEIGHT"); size_ptr = htmlGetVariable(t, (uchar *)"SIZE"); type_ptr = htmlGetVariable(t, (uchar *)"TYPE"); if (width_ptr != NULL) t->width = (float)(atoi((char *)width_ptr) / _htmlPPI * 72.0f); else if (size_ptr != NULL) t->width = (float)(atoi((char *)size_ptr) / _htmlPPI * 72.0f); else t->width = 1.0f; if (height_ptr != NULL) t->height = (float)(atoi((char *)height_ptr) / _htmlPPI * 72.0f); else if (size_ptr != NULL) t->height = (float)(atoi((char *)size_ptr) / _htmlPPI * 72.0f); else t->height = 1.0f; if (type_ptr == NULL) return (0); if (strcasecmp((char *)type_ptr, "horizontal") == 0) t->height = 0.0; else if (strcasecmp((char *)type_ptr, "vertical") == 0) t->width = 0.0; return (0); } else if (t->markup == MARKUP_BR) { t->width = 0.0; t->height = (float)_htmlSizes[t->size]; return (0); } else if (t->preformatted && t->data) { int max_width = 0; // Maximum width for (int_width = 0, ptr = t->data; *ptr != '\0'; ptr ++) { if (*ptr == '\n') { if (int_width > max_width) max_width = int_width; int_width = 0; } else if (*ptr == '\t') int_width = (int_width + 7) & ~7; else int_width ++; } if (int_width > max_width) max_width = int_width; if (!_htmlWidthsLoaded[t->typeface][t->style]) htmlLoadFontWidths(t->typeface, t->style); width = _htmlWidths[t->typeface][t->style][0x20] * max_width * 0.001f; } else if (t->data) { if (!_htmlWidthsLoaded[t->typeface][t->style]) htmlLoadFontWidths(t->typeface, t->style); for (int_width = 0, ptr = t->data; *ptr != '\0'; ptr ++) int_width += _htmlWidths[t->typeface][t->style][(int)*ptr & 255]; width = 0.001f * int_width; } else width = 0.0f; t->width = (float)(width * _htmlSizes[t->size]); t->height = (float)_htmlSizes[t->size]; DEBUG_printf(("%swidth = %.1f, height = %.1f\n", indent, t->width, t->height)); return (0); } // // 'compute_color()' - Compute the red, green, blue color from the given // string. // static int compute_color(tree_t *t, // I - Tree entry uchar *color) // I - Color string { float rgb[3]; // RGB color get_color(color, rgb); t->red = (uchar)(rgb[0] * 255.0f + 0.5f); t->green = (uchar)(rgb[1] * 255.0f + 0.5f); t->blue = (uchar)(rgb[2] * 255.0f + 0.5f); return (0); } // // 'get_alignment()' - Get horizontal & vertical alignment values. // static int // O - 0 for success, -1 for failure get_alignment(tree_t *t) // I - Tree entry { uchar *align; // Alignment string if ((align = htmlGetVariable(t, (uchar *)"ALIGN")) == NULL) align = htmlGetStyle(t, (uchar *)"text-align"); if (align != NULL) { if (!strcasecmp((char *)align, "left")) t->halignment = ALIGN_LEFT; else if (!strcasecmp((char *)align, "center")) t->halignment = ALIGN_CENTER; else if (!strcasecmp((char *)align, "right")) t->halignment = ALIGN_RIGHT; else if (!strcasecmp((char *)align, "justify")) t->halignment = ALIGN_JUSTIFY; else if (!strcasecmp((char *)align, "top")) t->valignment = ALIGN_TOP; else if (!strcasecmp((char *)align, "middle") || !strcasecmp((char *)align, "absmiddle")) t->valignment = ALIGN_MIDDLE; else if (!strcasecmp((char *)align, "bottom")) t->valignment = ALIGN_BOTTOM; } if ((align = htmlGetVariable(t, (uchar *)"VALIGN")) == NULL) align = htmlGetStyle(t, (uchar *)"vertical-align"); if (align != NULL) { if (!strcasecmp((char *)align, "top")) t->valignment = ALIGN_TOP; else if (!strcasecmp((char *)align, "middle")) t->valignment = ALIGN_MIDDLE; else if (!strcasecmp((char *)align, "center")) t->valignment = ALIGN_MIDDLE; else if (!strcasecmp((char *)align, "bottom")) t->valignment = ALIGN_BOTTOM; } return (0); } // // 'fix_filename()' - Fix a filename to be relative to the base directory. // static const char * // O - Fixed filename fix_filename(char *filename, // I - Original filename char *base) // I - Base directory { char *slash; // Location of slash char *tempptr; // Pointer into filename static char temp[1024]; // Temporary filename static char newfilename[1024]; // New filename // printf("fix_filename(filename=\"%s\", base=\"%s\")\n", filename, base); if (filename == NULL) return (NULL); #ifdef DEBUG // to silence Clang static analyzer, totally unnecessary memset(temp, 0, sizeof(temp)); #endif // DEBUG // Unescape filenames as needed... if (strchr(filename, '%') && !strstr(filename, "//")) { for (tempptr = temp; *filename && tempptr < (temp + sizeof(temp) - 1);) { if (*filename == '%') { // Decode hex-escaped filename character... filename ++; if (isxdigit(filename[0] & 255) && isxdigit(filename[1] & 255)) { if (isdigit(filename[0] & 255)) *tempptr = (char)((filename[0] - '0') << 4); else *tempptr = (char)((tolower(filename[0]) - 'a' + 10) << 4); if (isdigit(filename[1] & 255)) *tempptr |= filename[1] - '0'; else *tempptr |= tolower(filename[0]) - 'a' + 10; tempptr ++; filename += 2; } else *tempptr++ = '%'; } else *tempptr++ = *filename++; } *tempptr = '\0'; filename = temp; } if (strcmp(base, ".") == 0 || strstr(filename, "//") != NULL) return (file_find(Path, filename)); if (strncmp(filename, "./", 2) == 0 || strncmp(filename, ".\\", 2) == 0) filename += 2; if (strncmp(base, "http://", 7) == 0 || strncmp(base, "https://", 8) == 0) { // Base is a URL... char scheme[32], // URI scheme userpass[256], // Username:password host[256], // Hostname or IP address resource[256]; // Resource path int port; // Port number httpSeparateURI(HTTP_URI_CODING_ALL, base, scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)); if (filename[0] == '/') { // Absolute path, so just use the server... httpAssembleURI(HTTP_URI_CODING_ALL, newfilename, sizeof(newfilename), scheme, userpass, host, port, filename); } else { // Handle "../" in filename... while (!strncmp(filename, "../", 3)) { // Strip one level of directory in the resource filename += 3; if ((slash = strrchr(resource, '/')) != NULL) *slash = '\0'; } // Combine the resource and remaining relative filename to make a URL... httpAssembleURIf(HTTP_URI_CODING_ALL, newfilename, sizeof(newfilename), scheme, userpass, host, port, "%s/%s", resource, filename); } } else { // Base is a filename... if (filename[0] == '/' || filename[0] == '\\' || base == NULL || base[0] == '\0' || (isalpha(filename[0]) && filename[1] == ':')) { // No change needed for absolute path... return (file_find(Path, filename)); } strlcpy(newfilename, base, sizeof(newfilename)); base = newfilename; #if defined(WIN32) || defined(__EMX__) while (!strncmp(filename, "../", 3) || !strncmp(filename, "..\\", 3)) #else while (!strncmp(filename, "../", 3)) #endif // WIN32 || __EMX__ { filename += 3; #if defined(WIN32) || defined(__EMX__) if ((slash = strrchr(base, '/')) != NULL) *slash = '\0'; else if ((slash = strrchr(base, '\\')) != NULL) *slash = '\0'; #else if ((slash = strrchr(base, '/')) != NULL) *slash = '\0'; #endif // WIN32 || __EMX__ else { filename -= 3; break; } } if (filename[0] != '/' && *base && base[strlen(base) - 1] != '/') strlcat(newfilename, "/", sizeof(newfilename)); strlcat(newfilename, filename, sizeof(newfilename)); } // printf(" newfilename=\"%s\"\n", newfilename); return (file_find(Path, newfilename)); } // // 'html_memory_used()' - Figure out the amount of memory that was used. // static int // O - Bytes used html_memory_used(tree_t *t) // I - Tree node { int bytes; // Bytes used if (t == NULL) return (0); bytes = 0; while (t != NULL) { bytes += sizeof(tree_t); bytes += (size_t)t->nvars * sizeof(var_t); bytes += html_memory_used(t->child); t = t->next; } return (bytes); } // // 'htmlDebugStats()' - Display debug statistics for HTML tree memory use. // void htmlDebugStats(const char *title, // I - Title tree_t *t) // I - Document root node { const char *debug; // HTMLDOC_DEBUG env var if ((debug = getenv("HTMLDOC_DEBUG")) == NULL || (strstr(debug, "all") == NULL && strstr(debug, "memory") == NULL)) return; progress_error(HD_ERROR_NONE, "DEBUG: %s = %d kbytes", title, (html_memory_used(t) + 1023) / 1024); } // // 'htmlFindFile()' - Find a file in the document. // tree_t * // O - Node for file htmlFindFile(tree_t *doc, // I - Document pointer uchar *filename) // I - Filename { tree_t *tree; // Current node uchar *treename; // Filename from node if (!filename || !doc) return (NULL); for (tree = doc; tree; tree = tree->next) if ((treename = htmlGetVariable(tree, (uchar *)"_HD_FILENAME")) != NULL && !strcmp((char *)treename, (char *)filename)) return (tree); return (NULL); } // // 'htmlFixLinks()' - Fix the external links in the document. // void htmlFixLinks(tree_t *doc, // I - Top node tree_t *tree, // I - Current node uchar *base) // I - Base directory/path { uchar *href; // HREF attribute char full_href[1024]; // Full HREF value const char *debug; // HTMLDOC_DEBUG environment variable static int show_debug = -1; // Show debug messages? if (show_debug < 0) { if ((debug = getenv("HTMLDOC_DEBUG")) == NULL || (strstr(debug, "all") == NULL && strstr(debug, "links") == NULL)) show_debug = 0; else show_debug = 1; if (show_debug) progress_error(HD_ERROR_NONE, "DEBUG: Updating links in document."); } DEBUG_printf(("htmlFixLinks: base=\"%s\"\n", (char *)base)); while (tree) { if (tree->markup == MARKUP_A && base && base[0] && (href = htmlGetVariable(tree, (uchar *)"HREF")) != NULL) { // Check if the link needs to be localized... DEBUG_printf(("htmlFixLinks: href=\"%s\", file_method(href)=\"%s\", file_method(base)=\"%s\"\\n", (char *)href, file_method((char *)href), file_method((char *)base))); if (href[0] != '#' && file_method((char *)href) == NULL) { // Yes, localize it... DEBUG_puts("htmlFixLinks: Localizing"); if (href[0] == '/') { // Absolute URL, just copy scheme, server, etc. char *ptr; // Pointer into URL... DEBUG_puts("htmlFixLinks: Absolute"); strlcpy(full_href, (char *)base, sizeof(full_href)); if (href[1] == '/') { // Just use scheme... if ((ptr = strstr(full_href, "//")) != NULL) *ptr ='\0'; } else if ((ptr = strstr(full_href, "//")) != NULL && (ptr = strchr(ptr + 2, '/')) != NULL) *ptr ='\0'; strlcat(full_href, (char *)href, sizeof(full_href)); } else if (!strncmp((char *)href, "./", 2)) { // Relative URL of the form "./foo/bar", append href sans // "./" to base to form full href... DEBUG_puts("htmlFixLinks: Current directory"); snprintf(full_href, sizeof(full_href), "%s/%s", base, href + 2); } else if (!strncmp((char *)href, "../", 3)) { // Relative URL of the form "../foo/bar", append href sans // "../" to parent to form full href... char parent[1024], *pptr; // Parent directory strlcpy(parent, (char *)base, sizeof(parent)); while (!strncmp((char *)href, "../", 3)) { href += 3; if ((pptr = strrchr(parent, '/')) != NULL) pptr[1] = '\0'; else parent[0] = '\0'; } DEBUG_printf(("htmlFixLinks: Subdirectory, parent=\"%s\"\n", parent)); snprintf(full_href, sizeof(full_href), "%s%s", parent, href); } else { // Relative URL, append href to base to form full href... DEBUG_puts("htmlFixLinks: Relative"); if (strcmp((char *)base, ".")) snprintf(full_href, sizeof(full_href), "%s/%s", (char *)base, (char *)href); else strlcpy(full_href, (char *)href, sizeof(full_href)); } if (show_debug) progress_error(HD_ERROR_NONE, "DEBUG: Mapping \"%s\" to \"%s\"...", href, full_href); htmlSetVariable(tree, (uchar *)"_HD_FULL_HREF", (uchar *)full_href); } else { // No, just mirror the link in the _HD_FULL_HREF attribute... htmlSetVariable(tree, (uchar *)"_HD_FULL_HREF", href); } } else if (tree->markup == MARKUP_FILE) base = htmlGetVariable(tree, (uchar *)"_HD_BASE"); if (tree->child) htmlFixLinks(doc, tree->child, base); tree = tree->next; } } // // 'utf8_getc()' - Get a UTF-8 encoded character. // static int // O - Unicode equivalent utf8_getc(int ch, // I - Initial character FILE *fp) // I - File to read from { int ch2 = -1, ch3 = -1; // Temporary characters if ((ch & 0xe0) == 0xc0) { // Two-byte sequence for 0x80 to 0x7ff... ch = (ch & 0x1f) << 6; ch2 = getc(fp); if ((ch2 & 0xc0) == 0x80) ch |= ch2 & 0x3f; else goto bad_sequence; } else if ((ch & 0xf0) == 0xe0) { // Three-byte sequence from 0x800 to 0xffff... ch = (ch & 0x0f) << 12; ch2 = getc(fp); if ((ch2 & 0xc0) == 0x80) ch |= (ch2 & 0x3f) << 6; else goto bad_sequence; ch3 = getc(fp); if ((ch3 & 0xc0) == 0x80) ch |= ch3 & 0x3f; else goto bad_sequence; } else if (ch & 0x80) goto bad_sequence; if (ch == 0xfeff) { // BOMs are invalid in UTF-8 text, but Microsoft insists on still using // them... Try reading another character... // // TODO: Emit a warning about this... return (utf8_getc(getc(fp), fp)); } return (htmlMapUnicode(ch)); bad_sequence: if (ch3 >= 0) progress_error(HD_ERROR_READ_ERROR, "Bad UTF-8 character sequence %02X %02X %02X.", ch, ch2, ch3); else if (ch2 >= 0) progress_error(HD_ERROR_READ_ERROR, "Bad UTF-8 character sequence %02X %02X.", ch, ch2); else progress_error(HD_ERROR_READ_ERROR, "Bad UTF-8 character sequence %02X.", ch); return (0); } htmldoc-1.9.20/htmldoc/htmlsep.cxx000066400000000000000000000675701472561501400171130ustar00rootroot00000000000000// // Separated HTML export functions for HTMLDOC, a HTML document processing // program. // // Copyright © 2011-2024 by Michael R Sweet. // Copyright © 1997-2010 by Easy Software Products. All rights reserved. // // This program is free software. Distribution and use rights are outlined in // the file "COPYING". // #include "htmldoc.h" #include "markdown.h" #include // // Local type... // typedef struct // Named link structure... { uchar *filename; // File for link uchar name[124]; // Reference name } link_t; // // Local globals... // // Heading strings used for filenames... static size_t num_headings = 0, // Number of headings alloc_headings = 0; // Allocated headings static uchar **headings; // Heading strings // Links in document - used to add the correct filename to the link static size_t num_links = 0, // Number of links alloc_links = 0; // Allocated links static link_t *links; // Links // // Local functions... // extern "C" { typedef int (*compare_func_t)(const void *, const void *); } static void write_header(FILE **out, uchar *filename, uchar *title, uchar *author, uchar *copyright, uchar *docnumber, int heading); static void write_footer(FILE **out, int heading); static void write_title(FILE *out, uchar *title, uchar *author, uchar *copyright, uchar *docnumber); static int write_all(FILE *out, tree_t *t, int col); static int write_doc(FILE **out, tree_t *t, int col, int *heading, uchar *title, uchar *author, uchar *copyright, uchar *docnumber); static int write_node(FILE *out, tree_t *t, int col); static int write_nodeclose(FILE *out, tree_t *t, int col); static int write_toc(FILE *out, tree_t *t, int col); static uchar *get_title(tree_t *doc); static void add_heading(tree_t *t); static void add_link(uchar *name); static link_t *find_link(uchar *name); static int compare_links(link_t *n1, link_t *n2); static void scan_links(tree_t *t); static void update_links(tree_t *t, int *heading); // // 'htmlsep_export()' - Export to separated HTML files... // int // O - 0 = success, -1 = failure htmlsep_export(tree_t *document, // I - Document to export tree_t *toc) // I - Table of contents for document { size_t i; // Looping var int heading; // Current heading number uchar *title, // Title text *author, // Author name *copyright, // Copyright text *docnumber; // Document number FILE *out; // Output file // We only support writing to a directory... if (!OutputFiles) { progress_error(HD_ERROR_INTERNAL_ERROR, "Unable to generate separated HTML to a single file!"); return (-1); } // Copy logo and title images... if (LogoImage[0]) image_copy(LogoImage, file_find(LogoImage, Path), OutputPath); for (int hfi = 0; hfi < MAX_HF_IMAGES; hfi ++) if (HFImage[hfi][0]) image_copy(HFImage[hfi], file_find(HFImage[hfi], Path), OutputPath); if (TitleImage[0] && TitlePage && #ifdef WIN32 (stricmp(file_extension(TitleImage), "bmp") == 0 || stricmp(file_extension(TitleImage), "gif") == 0 || stricmp(file_extension(TitleImage), "jpg") == 0 || stricmp(file_extension(TitleImage), "png") == 0)) #else (strcmp(file_extension(TitleImage), "bmp") == 0 || strcmp(file_extension(TitleImage), "gif") == 0 || strcmp(file_extension(TitleImage), "jpg") == 0 || strcmp(file_extension(TitleImage), "png") == 0)) #endif // WIN32 image_copy(TitleImage, file_find(TitleImage, Path), OutputPath); // Get document strings... title = get_title(document); author = htmlGetMeta(document, (uchar *)"author"); copyright = htmlGetMeta(document, (uchar *)"copyright"); docnumber = htmlGetMeta(document, (uchar *)"docnumber"); if (!docnumber) docnumber = htmlGetMeta(document, (uchar *)"version"); // Scan for all links in the document, and then update them... num_links = 0; alloc_links = 0; links = NULL; scan_links(document); // printf("num_headings = %d\n", num_headings); // for (i = 0; i < num_headings; i ++) // printf("headings[%d] = \"%s\"\n", i, headings[i]); heading = -1; update_links(document, &heading); update_links(toc, NULL); // Generate title pages and a table of contents... out = NULL; if (TitlePage) { write_header(&out, (uchar *)"index.html", title, author, copyright, docnumber, -1); if (out != NULL) write_title(out, title, author, copyright, docnumber); write_footer(&out, -1); write_header(&out, (uchar *)"toc.html", title, author, copyright, docnumber, -1); } else write_header(&out, (uchar *)"index.html", title, author, copyright, docnumber, -1); if (out != NULL) write_toc(out, toc, 0); write_footer(&out, -1); // Then write each output file... heading = -1; write_doc(&out, document, 0, &heading, title, author, copyright, docnumber); if (out != NULL) write_footer(&out, heading); // Free memory... if (title != NULL) free(title); if (alloc_links) { free(links); num_links = 0; alloc_links = 0; links = NULL; } if (alloc_headings) { for (i = 0; i < num_headings; i ++) free(headings[i]); free(headings); num_headings = 0; alloc_headings = 0; headings = NULL; } return (out == NULL); } // // 'write_header()' - Output the standard "header" for a HTML file. // static void write_header(FILE **out, // IO - Output file uchar *filename, // I - Output filename uchar *title, // I - Title for document uchar *author, // I - Author for document uchar *copyright, // I - Copyright for document uchar *docnumber, // I - ID number for document int heading) // I - Current heading { char realname[1024]; // Real filename const char *basename; // Filename without directory static const char *families[] = // Typeface names { "monospace", "serif", "sans-serif", "monospace", "serif", "sans-serif", "symbol", "dingbats" }; basename = file_basename((char *)filename); snprintf(realname, sizeof(realname), "%s/%s", OutputPath, basename); *out = fopen(realname, "wb"); if (*out == NULL) { progress_error(HD_ERROR_WRITE_ERROR, "Unable to create output file \"%s\" - %s.\n", realname, strerror(errno)); return; } fputs("\n", *out); fputs("\n", *out); fputs("\n", *out); if (title != NULL) fprintf(*out, "%s\n", title); if (author != NULL) fprintf(*out, "\n", author); if (copyright != NULL) fprintf(*out, "\n", copyright); if (docnumber != NULL) fprintf(*out, "\n", docnumber); fprintf(*out, "\n", _htmlCharSet); fputs("\n", *out); if (TitlePage) fputs("\n", *out); else fputs("\n", *out); if (heading >= 0) { if (heading > 0) fprintf(*out, "\n", headings[heading - 1]); if ((size_t)heading < (num_headings - 1)) fprintf(*out, "\n", headings[heading + 1]); } fputs("\n", *out); fputs("\n", *out); if (BodyImage[0]) fprintf(*out, "\n", *out); if (heading >= 0) { if (LogoImage[0]) fprintf(*out, "\n", file_basename(LogoImage)); for (int hfi = 0; hfi < MAX_HF_IMAGES; ++hfi) if (HFImage[hfi][0]) fprintf(*out, "\n", file_basename(HFImage[hfi])); if (TitlePage) fputs("Contents\n", *out); else fputs("Contents\n", *out); if (heading > 0) fprintf(*out, "Previous\n", headings[heading - 1]); if ((size_t)heading < (num_headings - 1)) fprintf(*out, "Next\n", headings[heading + 1]); fputs("
    \n", *out); } } // // 'write_footer()' - Output the standard "footer" for a HTML file. // static void write_footer(FILE **out, // IO - Output file pointer int heading) // I - Current heading { if (*out == NULL) return; fputs("
    \n", *out); if (heading >= 0) { if (LogoImage[0]) fprintf(*out, "\n", file_basename(LogoImage)); for (int hfi = 0; hfi < MAX_HF_IMAGES; ++hfi) if (HFImage[hfi][0]) fprintf(*out, "\n", file_basename(HFImage[hfi])); if (TitlePage) fputs("Contents\n", *out); else fputs("Contents\n", *out); if (heading > 0) fprintf(*out, "Previous\n", headings[heading - 1]); if ((size_t)heading < (num_headings - 1)) fprintf(*out, "Next\n", headings[heading + 1]); } fputs("\n", *out); fputs("\n", *out); progress_error(HD_ERROR_NONE, "BYTES: %ld", ftell(*out)); fclose(*out); *out = NULL; } // // 'write_title()' - Write a title page... // static void write_title(FILE *out, // I - Output file uchar *title, // I - Title for document uchar *author, // I - Author for document uchar *copyright, // I - Copyright for document uchar *docnumber) // I - ID number for document { FILE *fp; // Title file const char *title_ext, // Extension of title file *title_file; // Location of title file tree_t *t; // Title file document tree if (out == NULL) return; title_ext = file_extension(TitleImage); #ifdef WIN32 if (TitleImage[0] && stricmp(title_ext, "bmp") != 0 && stricmp(title_ext, "gif") != 0 && stricmp(title_ext, "jpg") != 0 && stricmp(title_ext, "png") != 0) #else if (TitleImage[0] && strcmp(title_ext, "bmp") != 0 && strcmp(title_ext, "gif") != 0 && strcmp(title_ext, "jpg") != 0 && strcmp(title_ext, "png") != 0) #endif // WIN32 { // Find the title page file... if ((title_file = file_find(Path, TitleImage)) == NULL) { progress_error(HD_ERROR_FILE_NOT_FOUND, "Unable to find title file \"%s\"!", TitleImage); return; } // Write a title page from HTML source... if ((fp = fopen(title_file, "rb")) == NULL) { progress_error(HD_ERROR_FILE_NOT_FOUND, "Unable to open title file \"%s\" - %s!", TitleImage, strerror(errno)); return; } #ifdef _WIN32 if (!stricmp(title_ext, "md")) #else if (!strcmp(title_ext, "md")) #endif // _WIN32 t = mdReadFile(NULL, fp, file_directory(TitleImage)); else t = htmlReadFile(NULL, fp, file_directory(TitleImage)); htmlFixLinks(t, t, (uchar *)file_directory(TitleImage)); fclose(fp); write_all(out, t, 0); htmlDeleteTree(t); } else { // Write a "standard" title page with image... fputs("
    ", out); if (TitleImage[0]) { image_t *img = image_load(TitleImage, !OutputColor); if (img) fprintf(out, "
    \n", file_basename((char *)TitleImage), img->width, img->height, title ? (char *)title : ""); } if (title != NULL) fprintf(out, "

    %s


    \n", title); else fputs("\n", out); if (docnumber != NULL) fprintf(out, "%s
    \n", docnumber); if (author != NULL) fprintf(out, "%s
    \n", author); if (copyright != NULL) fprintf(out, "%s
    \n", copyright); fputs("Table of Contents", out); fputs("
    \n", out); } } // // 'write_all()' - Write all markup text for the given tree. // static int // O - Current column write_all(FILE *out, // I - Output file tree_t *t, // I - Document tree int col) // I - Current column { if (out == NULL) return (0); while (t != NULL) { col = write_node(out, t, col); if (t->markup != MARKUP_HEAD && t->markup != MARKUP_TITLE) col = write_all(out, t->child, col); col = write_nodeclose(out, t, col); t = t->next; } return (col); } // // 'write_doc()' - Write the entire document. // static int // O - Current column write_doc(FILE **out, // I - Output file tree_t *t, // I - Document tree int col, // I - Current column int *heading, // IO - Current heading uchar *title, // I - Title uchar *author, // I - Author uchar *copyright, // I - Copyright uchar *docnumber) // I - Document number { uchar filename[1024]; // Filename while (t != NULL) { if (t->markup >= MARKUP_H1 && t->markup < (MARKUP_H1 + TocLevels) && htmlGetVariable(t, (uchar *)"_HD_OMIT_TOC") == NULL) { if (*heading >= 0) write_footer(out, *heading); (*heading) ++; if (*heading >= 0) { snprintf((char *)filename, sizeof(filename), "%s.html", headings[*heading]); write_header(out, filename, title, author, copyright, docnumber, *heading); } } col = write_node(*out, t, col); if (t->markup != MARKUP_HEAD && t->markup != MARKUP_TITLE) col = write_doc(out, t->child, col, heading, title, author, copyright, docnumber); col = write_nodeclose(*out, t, col); t = t->next; } return (col); } // // 'write_node()' - Write a single tree node. // static int // O - Current column write_node(FILE *out, // I - Output file tree_t *t, // I - Document tree node int col) // I - Current column { int i; // Looping var uchar *ptr, // Pointer to output string *entity, // Entity string *src, // Source image *realsrc, // Real source image newsrc[1024]; // New source image filename if (out == NULL) return (0); switch (t->markup) { case MARKUP_NONE : if (t->data == NULL) break; if (t->preformatted) { for (ptr = t->data; *ptr; ptr ++) fputs((char *)iso8859(*ptr), out); if (t->data[0] && t->data[strlen((char *)t->data) - 1] == '\n') col = 0; else col += strlen((char *)t->data); } else { if ((col + (int)strlen((char *)t->data)) > 72 && col > 0) { putc('\n', out); col = 0; } for (ptr = t->data; *ptr; ptr ++) fputs((char *)iso8859(*ptr), out); col += strlen((char *)t->data); if (col > 72) { putc('\n', out); col = 0; } } break; case MARKUP_COMMENT : case MARKUP_UNKNOWN : fputs("\n\n", out); col = 0; break; case MARKUP_AREA : case MARKUP_BODY : case MARKUP_DOCTYPE : case MARKUP_ERROR : case MARKUP_FILE : case MARKUP_HEAD : case MARKUP_HTML : case MARKUP_MAP : case MARKUP_META : case MARKUP_TITLE : break; case MARKUP_BR : case MARKUP_CENTER : case MARKUP_DD : case MARKUP_DL : case MARKUP_DT : case MARKUP_H1 : case MARKUP_H2 : case MARKUP_H3 : case MARKUP_H4 : case MARKUP_H5 : case MARKUP_H6 : case MARKUP_H7 : case MARKUP_H8 : case MARKUP_H9 : case MARKUP_H10 : case MARKUP_H11 : case MARKUP_H12 : case MARKUP_H13 : case MARKUP_H14 : case MARKUP_H15 : case MARKUP_HR : case MARKUP_LI : case MARKUP_OL : case MARKUP_P : case MARKUP_PRE : case MARKUP_TABLE : case MARKUP_TR : case MARKUP_UL : if (col > 0) { putc('\n', out); col = 0; } default : if (t->markup == MARKUP_IMG && (src = htmlGetVariable(t, (uchar *)"SRC")) != NULL && (realsrc = htmlGetVariable(t, (uchar *)"REALSRC")) != NULL) { /* * Update local images... */ if (file_method((char *)src) == NULL && src[0] != '/' && src[0] != '\\' && (!isalpha(src[0]) || src[1] != ':')) { image_copy((char *)src, (char *)realsrc, OutputPath); strlcpy((char *)newsrc, file_basename((char *)src), sizeof(newsrc)); htmlSetVariable(t, (uchar *)"SRC", newsrc); } } if (t->markup != MARKUP_EMBED) { col += fprintf(out, "<%s", _htmlMarkups[t->markup]); for (i = 0; i < t->nvars; i ++) { if (strcasecmp((char *)t->vars[i].name, "BREAK") == 0 && t->markup == MARKUP_HR) continue; if (strcasecmp((char *)t->vars[i].name, "REALSRC") == 0 && t->markup == MARKUP_IMG) continue; if (strncasecmp((char *)t->vars[i].name, "_HD_", 4) == 0) continue; if (col > 72 && !t->preformatted) { putc('\n', out); col = 0; } if (col > 0) { putc(' ', out); col ++; } if (t->vars[i].value == NULL) col += fprintf(out, "%s", t->vars[i].name); else { col += fprintf(out, "%s=\"", t->vars[i].name); for (ptr = t->vars[i].value; *ptr; ptr ++) { entity = iso8859(*ptr); fputs((char *)entity, out); col += strlen((char *)entity); } putc('\"', out); col ++; } } putc('>', out); col ++; if (col > 72 && !t->preformatted) { putc('\n', out); col = 0; } } break; } return (col); } // // 'write_nodeclose()' - Close a single tree node. // static int // O - Current column write_nodeclose(FILE *out, // I - Output file tree_t *t, // I - Document tree node int col) // I - Current column { if (out == NULL) return (0); if (t->markup != MARKUP_HEAD && t->markup != MARKUP_TITLE) { if (col > 72 && !t->preformatted) { putc('\n', out); col = 0; } switch (t->markup) { case MARKUP_BODY : case MARKUP_ERROR : case MARKUP_FILE : case MARKUP_HEAD : case MARKUP_HTML : case MARKUP_NONE : case MARKUP_TITLE : case MARKUP_APPLET : case MARKUP_AREA : case MARKUP_BR : case MARKUP_COMMENT : case MARKUP_DOCTYPE : case MARKUP_EMBED : case MARKUP_HR : case MARKUP_IMG : case MARKUP_INPUT : case MARKUP_ISINDEX : case MARKUP_LINK : case MARKUP_META : case MARKUP_NOBR : case MARKUP_SPACER : case MARKUP_WBR : case MARKUP_UNKNOWN : break; case MARKUP_CENTER : case MARKUP_DD : case MARKUP_DL : case MARKUP_DT : case MARKUP_H1 : case MARKUP_H2 : case MARKUP_H3 : case MARKUP_H4 : case MARKUP_H5 : case MARKUP_H6 : case MARKUP_H7 : case MARKUP_H8 : case MARKUP_H9 : case MARKUP_H10 : case MARKUP_H11 : case MARKUP_H12 : case MARKUP_H13 : case MARKUP_H14 : case MARKUP_H15 : case MARKUP_LI : case MARKUP_OL : case MARKUP_P : case MARKUP_PRE : case MARKUP_TABLE : case MARKUP_TR : case MARKUP_UL : fprintf(out, "\n", _htmlMarkups[t->markup]); col = 0; break; default : col += fprintf(out, "", _htmlMarkups[t->markup]); break; } } return (col); } // // 'write_toc()' - Write all markup text for the given table-of-contents. // static int // O - Current column write_toc(FILE *out, // I - Output file tree_t *t, // I - Document tree int col) // I - Current column { if (out == NULL) return (0); while (t != NULL) { if (htmlGetVariable(t, (uchar *)"_HD_OMIT_TOC") == NULL) { col = write_node(out, t, col); if (t->markup != MARKUP_HEAD && t->markup != MARKUP_TITLE) col = write_toc(out, t->child, col); col = write_nodeclose(out, t, col); } t = t->next; } return (col); } // // 'get_title()' - Get the title string for the given document... // static uchar * // O - Title string get_title(tree_t *doc) // I - Document tree { uchar *temp; // Temporary pointer to title while (doc != NULL) { if (doc->markup == MARKUP_TITLE) return (htmlGetText(doc->child)); else if (doc->child != NULL) if ((temp = get_title(doc->child)) != NULL) return (temp); doc = doc->next; } return (NULL); } // // 'add_heading()' - Add a heading to the list of headings... // static void add_heading(tree_t *t) // I - Heading node { size_t i, // Looping var count; // Count of headings with this name uchar *heading, // Heading text for this node *ptr, // Pointer into text *ptr2, // Second pointer into text s[1024], // New text if we have a conflict **temp; // New heading array pointer // Start by getting the heading text... heading = htmlGetText(t->child); if (!heading || !*heading) { free(heading); return; // Nothing to do! } // Sanitize the text... for (ptr = heading; *ptr;) if (!isalnum(*ptr)) { // Remove anything but letters and numbers from the filename for (ptr2 = ptr; *ptr2; ptr2 ++) *ptr2 = ptr2[1]; *ptr2 = '\0'; } else ptr ++; // Now loop through the existing headings and check for dups... for (ptr = heading, i = 0, count = 0; i < num_headings; i ++) if (strcmp((char *)headings[i], (char *)ptr) == 0) { // Create a new instance of the heading... count ++; snprintf((char *)s, sizeof(s), "%s%d", heading, (int)count); ptr = s; } // Now add the heading... if (num_headings >= alloc_headings) { // Allocate more headings... alloc_headings += ALLOC_HEADINGS; if (num_headings == 0) temp = (uchar **)malloc(sizeof(uchar *) * alloc_headings); else temp = (uchar **)realloc(headings, sizeof(uchar *) * alloc_headings); if (temp == NULL) { progress_error(HD_ERROR_OUT_OF_MEMORY, "Unable to allocate memory for %d headings - %s", (int)alloc_headings, strerror(errno)); alloc_headings -= ALLOC_HEADINGS; return; } headings = temp; } if (ptr == heading) { // Reuse the already-allocated string... headings[num_headings] = ptr; } else { // Make a copy of the string "s" and free the old heading string... headings[num_headings] = (uchar *)hd_strdup((char *)s); free(heading); } num_headings ++; } // // 'add_link()' - Add a named link... // static void add_link(uchar *name) // I - Name of link { uchar *filename; // File for link link_t *temp; // New name if (num_headings) filename = headings[num_headings - 1]; else filename = (uchar *)"noheading"; if ((temp = find_link(name)) != NULL) { temp->filename = filename; } else { // See if we need to allocate memory for links... if (num_links >= alloc_links) { // Allocate more links... alloc_links += ALLOC_LINKS; if (num_links == 0) temp = (link_t *)malloc(sizeof(link_t) * alloc_links); else temp = (link_t *)realloc(links, sizeof(link_t) * alloc_links); if (temp == NULL) { progress_error(HD_ERROR_OUT_OF_MEMORY, "Unable to allocate memory for %d links - %s", (int)alloc_links, strerror(errno)); alloc_links -= ALLOC_LINKS; return; } links = temp; } // Add a new link... temp = links + num_links; num_links ++; strlcpy((char *)temp->name, (char *)name, sizeof(temp->name)); temp->filename = filename; if (num_links > 1) qsort(links, num_links, sizeof(link_t), (compare_func_t)compare_links); } } // // 'find_link()' - Find a named link... // static link_t * find_link(uchar *name) // I - Name to find { uchar *target; // Pointer to target name portion link_t key, // Search key *match; // Matching name entry if (name == NULL || num_links == 0) return (NULL); if ((target = (uchar *)file_target((char *)name)) == NULL) return (NULL); strlcpy((char *)key.name, (char *)target, sizeof(key.name)); key.name[sizeof(key.name) - 1] = '\0'; match = (link_t *)bsearch(&key, links, num_links, sizeof(link_t), (compare_func_t)compare_links); return (match); } // // 'compare_links()' - Compare two named links. // static int // O - 0 = equal, -1 or 1 = not equal compare_links(link_t *n1, // I - First name link_t *n2) // I - Second name { return (strcasecmp((char *)n1->name, (char *)n2->name)); } // // 'scan_links()' - Scan a document for link targets, and keep track of // the files they are in... // static void scan_links(tree_t *t) // I - Document tree { uchar *name; // Name of link while (t != NULL) { if (t->markup >= MARKUP_H1 && t->markup < (MARKUP_H1 + TocLevels) && htmlGetVariable(t, (uchar *)"_HD_OMIT_TOC") == NULL) add_heading(t); if (t->markup == MARKUP_A && (name = htmlGetVariable(t, (uchar *)"NAME")) != NULL) add_link(name); if (t->child != NULL) scan_links(t->child); t = t->next; } } // // 'update_links()' - Update links as needed. // static void update_links(tree_t *t, // I - Document tree int *heading) // I - Current heading { link_t *link; // Link uchar *href; // Reference name uchar newhref[1024]; // New reference name uchar *filename; // Current filename // Scan the document, rewriting HREF's as needed... while (t != NULL) { if (t->markup >= MARKUP_H1 && t->markup < (MARKUP_H1 + TocLevels) && htmlGetVariable(t, (uchar *)"_HD_OMIT_TOC") == NULL && heading) (*heading) ++; // Figure out the current filename based upon the current heading number... if (!heading || *heading < 0 || (size_t)*heading >= num_headings) filename = (uchar *)"noheading"; else filename = headings[*heading]; if (t->markup == MARKUP_A && (href = htmlGetVariable(t, (uchar *)"HREF")) != NULL) { // Update this link as needed... if (href[0] == '#' && (link = find_link(href)) != NULL) { // The filename in the link structure is a copy of the heading // pointer... if (filename != link->filename) { // Rewrite using the new name... snprintf((char *)newhref, sizeof(newhref), "%s.html%s", link->filename, href); htmlSetVariable(t, (uchar *)"HREF", newhref); } } } // Descend the tree as needed... if (t->child != NULL) update_links(t->child, heading); // Move to the next node at this level... t = t->next; } } htmldoc-1.9.20/htmldoc/image.cxx000066400000000000000000001233011472561501400165020ustar00rootroot00000000000000/* * Image handling routines for HTMLDOC, a HTML document processing program. * * Copyright © 2011-2022 by Michael R Sweet. * Copyright © 1997-2010 by Easy Software Products. All rights reserved. * * This program is free software. Distribution and use rights are outlined in * the file "COPYING". */ /* * Include necessary headers. */ #include "htmldoc.h" #include #ifdef HAVE_LIBJPEG extern "C" { /* Workaround for JPEG header problems... */ # include /* JPEG/JFIF image definitions */ } #endif // HAVE_JPEG #ifdef HAVE_LIBPNG # include /* Portable Network Graphics (PNG) definitions */ #endif // HAVE_LIBPNG /* * Limits... */ #define IMAGE_MAX_DIM 37837 // Maximum dimension - sqrt(4GiB / 3) /* * GIF definitions... */ #define GIF_INTERLACE 0x40 #define GIF_COLORMAP 0x80 typedef uchar gif_cmap_t[256][3]; /* * BMP definitions... */ #ifndef BI_RGB # define BI_RGB 0 /* No compression - straight BGR data */ # define BI_RLE8 1 /* 8-bit run-length compression */ # define BI_RLE4 2 /* 4-bit run-length compression */ # define BI_BITFIELDS 3 /* RGB bitmap with RGB masks */ #endif /* !BI_RGB */ /* * Local globals... */ static size_t num_images = 0, /* Number of images in cache */ alloc_images = 0; /* Allocated images */ static image_t **images = NULL; /* Images in cache */ static int gif_eof = 0; /* Did we hit EOF? */ /* * Local functions... */ static int gif_read_cmap(FILE *fp, int ncolors, gif_cmap_t cmap, int *gray); static int gif_get_block(FILE *fp, uchar *buffer); static int gif_get_code (FILE *fp, int code_size, int first_time); static int gif_read_image(FILE *fp, image_t *img, gif_cmap_t cmap, int interlace, int transparent); static int gif_read_lzw(FILE *fp, int first_time, int input_code_size); static int image_compare(image_t **img1, image_t **img2); static int image_load_bmp(image_t *img, FILE *fp, int gray, int load_data); static int image_load_gif(image_t *img, FILE *fp, int gray, int load_data); #ifdef HAVE_LIBJPEG static int image_load_jpeg(image_t *img, FILE *fp, int gray, int load_data); static void jpeg_error_handler(j_common_ptr); #endif // HAVE_LIBJPEG #ifdef HAVE_LIBPNG static int image_load_png(image_t *img, FILE *fp, int gray, int load_data); #endif // HAVE_LIBPNG static void image_need_mask(image_t *img, int scaling = 1); static void image_set_mask(image_t *img, int x, int y, uchar alpha = 0); static int read_long(FILE *fp); static unsigned short read_word(FILE *fp); static unsigned int read_dword(FILE *fp); /* * 'gif_read_cmap()' - Read the colormap from a GIF file... */ static int /* O - 0 on success, -1 on error */ gif_read_cmap(FILE *fp, /* I - File to read from */ int ncolors, /* I - Number of colors */ gif_cmap_t cmap, /* IO - Colormap array */ int *gray) /* IO - 1 = grayscale */ { int i; /* Looping var */ /* * Read the colormap... */ if (fread(cmap, 3, (size_t)ncolors, fp) < (size_t)ncolors) { progress_error(HD_ERROR_READ_ERROR, "Unable to read GIF colormap: %s", strerror(errno)); return (-1); } /* * Check to see if the colormap is a grayscale ramp... */ for (i = 0; i < ncolors; i ++) if (cmap[i][0] != cmap[i][1] || cmap[i][1] != cmap[i][2]) break; if (i == ncolors) { *gray = 1; return (0); } /* * If this needs to be a grayscale image, convert the RGB values to * luminance values... */ if (*gray) for (i = 0; i < ncolors; i ++) cmap[i][0] = (cmap[i][0] * 31 + cmap[i][1] * 61 + cmap[i][2] * 8) / 100; return (0); } /* * 'gif_get_block()' - Read a GIF data block... */ static int /* O - Number characters read */ gif_get_block(FILE *fp, /* I - File to read from */ uchar *buf) /* I - Input buffer */ { int count; /* Number of character to read */ /* * Read the count byte followed by the data from the file... */ if ((count = getc(fp)) == EOF) { gif_eof = 1; return (-1); } else if (count == 0) gif_eof = 1; else if (fread(buf, 1, (size_t)count, fp) < (size_t)count) { progress_error(HD_ERROR_READ_ERROR, "Unable to read GIF block of %d bytes: %s", count, strerror(errno)); gif_eof = 1; return (-1); } else gif_eof = 0; return (count); } /* * 'gif_get_code()' - Get a LZW code from the file... */ static int /* O - LZW code */ gif_get_code(FILE *fp, /* I - File to read from */ int code_size, /* I - Size of code in bits */ int first_time) /* I - 1 = first time, 0 = not first time */ { unsigned i, j, /* Looping vars */ ret; /* Return value */ int count; /* Number of bytes read */ static uchar buf[280]; /* Input buffer */ static unsigned curbit, /* Current bit */ lastbit, /* Last bit in buffer */ done, /* Done with this buffer? */ last_byte; /* Last byte in buffer */ static unsigned bits[8] = /* Bit masks for codes */ { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; if (first_time) { /* * Just initialize the input buffer... */ curbit = 0; lastbit = 0; last_byte = 0; done = 0; return (0); } if ((curbit + (unsigned)code_size) >= lastbit) { /* * Don't have enough bits to hold the code... */ if (done) { progress_error(HD_ERROR_READ_ERROR, "Not enough data left to read GIF compression code."); return (-1); /* Sorry, no more... */ } /* * Move last two bytes to front of buffer... */ if (last_byte > 1) { buf[0] = buf[last_byte - 2]; buf[1] = buf[last_byte - 1]; last_byte = 2; } else if (last_byte == 1) { buf[0] = buf[last_byte - 1]; last_byte = 1; } /* * Read in another buffer... */ if ((count = gif_get_block(fp, buf + last_byte)) <= 0) { /* * Whoops, no more data! */ done = 1; return (-1); } /* * Update buffer state... */ curbit = curbit + 8 * last_byte - lastbit; last_byte += (unsigned)count; lastbit = last_byte * 8; } for (ret = 0, i = curbit + (unsigned)code_size - 1, j = (unsigned)code_size; j > 0; i --, j --) ret = (ret << 1) | ((buf[i / 8] & bits[i & 7]) != 0); curbit += (unsigned)code_size; return (int)ret; } /* * 'gif_read_image()' - Read a GIF image stream... */ static int /* I - 0 = success, -1 = failure */ gif_read_image(FILE *fp, /* I - Input file */ image_t *img, /* I - Image pointer */ gif_cmap_t cmap, /* I - Colormap */ int interlace, /* I - Non-zero = interlaced image */ int transparent) /* I - Transparent color */ { uchar code_size, /* Code size */ *temp; /* Current pixel */ int xpos, /* Current X position */ ypos, /* Current Y position */ pass; /* Current pass */ int pixel; /* Current pixel */ static int xpasses[4] = { 8, 8, 4, 2 }, ypasses[5] = { 0, 4, 2, 1, 999999 }; xpos = 0; ypos = 0; pass = 0; code_size = (uchar)getc(fp); if (code_size > 12) { progress_error(HD_ERROR_READ_ERROR, "Bad GIF file \"%s\" - invalid code size %d.", img->filename, code_size); return (-1); } if (gif_read_lzw(fp, 1, code_size) < 0) return (-1); temp = img->pixels; while ((pixel = gif_read_lzw(fp, 0, code_size)) >= 0 && pixel < 256) { temp[0] = cmap[pixel][0]; if (img->depth > 1) { temp[1] = cmap[pixel][1]; temp[2] = cmap[pixel][2]; } if (pixel == transparent) image_set_mask(img, xpos, ypos); xpos ++; temp += img->depth; if (xpos == img->width) { xpos = 0; if (interlace) { ypos += xpasses[pass]; temp += (xpasses[pass] - 1) * img->width * img->depth; if (ypos >= img->height) { pass ++; ypos = ypasses[pass]; temp = img->pixels + ypos * img->width * img->depth; } } else ypos ++; } if (ypos >= img->height) break; } return (0); } /* * 'gif_read_lzw()' - Read a byte from the LZW stream... */ static int /* I - Byte from stream */ gif_read_lzw(FILE *fp, /* I - File to read from */ int first_time, /* I - 1 = first time, 0 = not first time */ int input_code_size) /* I - Code size in bits */ { int i, /* Looping var */ code, /* Current code */ incode; /* Input code */ static short fresh = 0, /* 1 = empty buffers */ code_size = 0, /* Current code size */ set_code_size = 0, /* Initial code size set */ max_code = 0, /* Maximum code used */ max_code_size = 0, /* Maximum code size */ firstcode = 0, /* First code read */ oldcode = 0, /* Last code read */ clear_code = 0, /* Clear code for LZW input */ end_code = 0, /* End code for LZW input */ table[2][4096], /* String table */ stack[8192], /* Output stack */ *sp = stack; /* Current stack pointer */ if (first_time) { /* * Setup LZW state... */ set_code_size = (short)input_code_size; code_size = set_code_size + 1; clear_code = (short)(1 << set_code_size); end_code = clear_code + 1; max_code_size = 2 * clear_code; max_code = clear_code + 2; /* * Initialize input buffers... */ gif_get_code(fp, 0, 1); /* * Wipe the decompressor table... */ fresh = 1; for (i = 0; i < clear_code; i ++) { table[0][i] = 0; table[1][i] = (short)i; } for (; i < 4096; i ++) table[0][i] = table[1][0] = 0; sp = stack; return (0); } else if (fresh) { fresh = 0; do firstcode = oldcode = (short)gif_get_code(fp, code_size, 0); while (firstcode == clear_code); return (firstcode); } if (sp > stack) return (*--sp); while ((code = gif_get_code(fp, code_size, 0)) >= 0) { if (code == clear_code) { for (i = 0; i < clear_code; i ++) { table[0][i] = 0; table[1][i] = (short)i; } for (; i < 4096; i ++) table[0][i] = table[1][i] = 0; code_size = set_code_size + 1; max_code_size = 2 * clear_code; max_code = clear_code + 2; sp = stack; firstcode = oldcode = (short)gif_get_code(fp, code_size, 0); return (firstcode); } else if (code == end_code) { uchar buf[260]; if (!gif_eof) while (gif_get_block(fp, buf) > 0); return (-2); } incode = code; if (code >= max_code) { *sp++ = firstcode; code = oldcode; } while (code >= clear_code) { if (sp >= (stack + sizeof(stack) / sizeof(stack[0]))) return (255); *sp++ = table[1][code]; if (code == table[0][code]) return (255); code = table[0][code]; } if (sp >= (stack + sizeof(stack) / sizeof(stack[0]))) return (255); *sp++ = firstcode = table[1][code]; if ((code = max_code) < 4096) { table[0][code] = oldcode; table[1][code] = firstcode; max_code ++; if (max_code >= max_code_size && max_code_size < 4096) { max_code_size *= 2; code_size ++; } } oldcode = (short)incode; if (sp > stack) return (*--sp); } return (code); } /* * 'image_compare()' - Compare two image filenames... */ static int /* O - Result of comparison */ image_compare(image_t **img1, /* I - First image */ image_t **img2) /* I - Second image */ { #ifdef WIN32 return (strcasecmp((*img1)->filename, (*img2)->filename)); #else return (strcmp((*img1)->filename, (*img2)->filename)); #endif /* WIN32 */ } /* * 'image_copy()' - Copy image files to the destination directory... */ void image_copy(const char *src, /* I - Source file */ const char *realsrc, /* I - Real source file */ const char *destpath) /* I - Destination path */ { char dest[255]; /* Destination file */ FILE *in, *out; /* Input/output files */ uchar buffer[8192]; /* Data buffer */ int nbytes; /* Number of bytes in buffer */ if (!src || !realsrc || !destpath) return; /* * Figure out the destination filename... */ if (!strcmp(destpath, ".")) strlcpy(dest, file_basename(src), sizeof(dest)); else snprintf(dest, sizeof(dest), "%s/%s", destpath, file_basename(src)); if (!strcmp(dest, realsrc)) return; /* * Open files and copy... */ if ((in = fopen(realsrc, "rb")) == NULL) { progress_error(HD_ERROR_READ_ERROR, "Unable to open \"%s\" - %s", realsrc, strerror(errno)); return; } if ((out = fopen(dest, "wb")) == NULL) { progress_error(HD_ERROR_READ_ERROR, "Unable to create \"%s\" - %s", dest, strerror(errno)); fclose(in); return; } while ((nbytes = fread(buffer, 1, sizeof(buffer), in)) > 0) fwrite(buffer, 1, (size_t)nbytes, out); progress_error(HD_ERROR_NONE, "BYTES: %ld", ftell(out)); fclose(in); fclose(out); } /* * 'image_find()' - Find an image file in memory... */ image_t * /* O - Pointer to image */ image_find(const char *filename,/* I - Name of image file */ int load_data)/* I - 1 = load image data */ { image_t key, /* Search key... */ *keyptr, /* Pointer to search key... */ **match; /* Matching image */ /* * Range check... */ if (filename == NULL) return (NULL); if (filename[0] == '\0') /* Microsoft VC++ runtime bug workaround... */ return (NULL); /* * See if we've already loaded it... */ if (num_images > 0) { strlcpy(key.filename, filename, sizeof(key.filename)); keyptr = &key; match = (image_t **)bsearch(&keyptr, images, (size_t)num_images, sizeof(image_t *), (int (*)(const void *, const void *))image_compare); if (match != NULL) { if (load_data && !(*match)->pixels) return (image_load((*match)->filename, (*match)->depth == 1, 1)); else return (*match); } } return (NULL); } /* * 'image_flush_cache()' - Flush the image cache... */ void image_flush_cache(void) { size_t i; /* Looping var */ /* * Free the memory used by each image... */ for (i = 0; i < num_images; i ++) { if (images[i]->mask) free(images[i]->mask); if (images[i]->pixels) free(images[i]->pixels); free(images[i]); } if (alloc_images) { free(images); alloc_images = 0; } num_images = 0; } /* * 'image_getlist()' - Get the list of images that are loaded. */ int /* O - Number of images in array */ image_getlist(image_t ***ptrs) /* O - Pointer to images array */ { *ptrs = images; return (num_images); } /* * 'image_load()' - Load an image file from disk... */ image_t * /* O - Pointer to image */ image_load(const char *filename,/* I - Name of image file */ int gray, /* I - 0 = color, 1 = grayscale */ int load_data)/* I - 1 = load image data, 0 = just info */ { #ifdef DEBUG int i; /* Looping var */ #endif // DEBUG FILE *fp; /* File pointer */ uchar header[16]; /* First 16 bytes of file */ image_t *img, /* New image buffer */ key, /* Search key... */ *keyptr, /* Pointer to search key... */ **match, /* Matching image */ **temp; /* Temporary array pointer */ int status; /* Status of load... */ const char *realname; /* Real filename */ /* * Range check... */ if (filename == NULL) return (NULL); if (filename[0] == '\0') /* Microsoft VC++ runtime bug workaround... */ return (NULL); DEBUG_printf(("image_load(filename=\"%s\", gray=%d, load_data=%d)\n", filename, gray, load_data)); DEBUG_printf(("Path = \"%s\"\n", Path)); /* * See if we've already loaded it... */ if (num_images > 0) { strlcpy(key.filename, filename, sizeof(key.filename)); keyptr = &key; match = (image_t **)bsearch(&keyptr, images, (size_t)num_images, sizeof(image_t *), (int (*)(const void *, const void *))image_compare); if (match != NULL && (!load_data || (*match)->pixels)) { (*match)->use ++; return (*match); } } else match = NULL; /* * Figure out the file type... */ if ((realname = file_find(Path, filename)) == NULL) { progress_error(HD_ERROR_FILE_NOT_FOUND, "Unable to find image file \"%s\"!", filename); return (NULL); } if ((fp = fopen(realname, "rb")) == NULL) { progress_error(HD_ERROR_FILE_NOT_FOUND, "Unable to open image file \"%s\" (%s) for reading!", filename, realname); return (NULL); } if (fread(header, 1, sizeof(header), fp) == 0) { progress_error(HD_ERROR_READ_ERROR, "Unable to read image file \"%s\"!", filename); fclose(fp); return (NULL); } #ifdef DEBUG printf("Header for \"%s\" (%s): \"", filename, realname); for (i = 0; i < (int)sizeof(header); i ++) if (header[i] < ' ' || header[i] >= 127) printf("\\x%02X", header[i]); else putchar(header[i]); puts("\"\n"); printf("match = %p\n", (void *)match); #endif // DEBUG rewind(fp); // See if the images array needs to be resized... if (!match) { if (num_images >= alloc_images) { // Yes... alloc_images += ALLOC_FILES; if (num_images == 0) temp = (image_t **)malloc(sizeof(image_t *) * alloc_images); else temp = (image_t **)realloc(images, sizeof(image_t *) * alloc_images); if (temp == NULL) { progress_error(HD_ERROR_OUT_OF_MEMORY, "Unable to allocate memory for %d images - %s", (int)alloc_images, strerror(errno)); fclose(fp); return (NULL); } images = temp; } // Allocate memory... img = (image_t *)calloc(sizeof(image_t), 1); if (img == NULL) { progress_error(HD_ERROR_READ_ERROR, "Unable to allocate memory for \"%s\"", filename); fclose(fp); return (NULL); } images[num_images] = img; strlcpy(img->filename, filename, sizeof(img->filename)); img->use = 1; } else img = *match; // Load the image as appropriate... if (memcmp(header, "GIF87a", 6) == 0 || memcmp(header, "GIF89a", 6) == 0) status = image_load_gif(img, fp, gray, load_data); else if (memcmp(header, "BM", 2) == 0) status = image_load_bmp(img, fp, gray, load_data); #ifdef HAVE_LIBPNG else if (memcmp(header, "\211PNG", 4) == 0) status = image_load_png(img, fp, gray, load_data); #endif // HAVE_LIBPNG #ifdef HAVE_LIBJPEG else if (memcmp(header, "\377\330\377", 3) == 0) status = image_load_jpeg(img, fp, gray, load_data); #endif // HAVE_LIBJPEG else { progress_error(HD_ERROR_BAD_FORMAT, "Unknown image file format for \"%s\".", file_rlookup(filename)); fclose(fp); free(img); return (NULL); } fclose(fp); if (status) { progress_error(HD_ERROR_READ_ERROR, "Unable to load image file \"%s\"!", file_rlookup(filename)); if (!match) free(img); return (NULL); } if (!match) { num_images ++; if (num_images > 1) qsort(images, num_images, sizeof(image_t *), (int (*)(const void *, const void *))image_compare); } return (img); } /* * 'image_load_bmp()' - Read a BMP image file. */ static int /* O - 0 = success, -1 = fail */ image_load_bmp(image_t *img, /* I - Image to load into */ FILE *fp, /* I - File to read from */ int gray, /* I - Grayscale image? */ int load_data)/* I - 1 = load image data, 0 = just info */ { int info_size, /* Size of info header */ depth, /* Depth of image (bits) */ compression, /* Type of compression */ colors_used, /* Number of colors used */ x, y, /* Looping vars */ color, /* Color of RLE pixel */ count, /* Number of times to repeat */ temp, /* Temporary color */ align; /* Alignment bytes */ uchar bit, /* Bit in image */ byte; /* Byte in image */ uchar *ptr; /* Pointer into pixels */ uchar colormap[256][4];/* Colormap */ // Get the header... getc(fp); /* Skip "BM" sync chars */ getc(fp); read_dword(fp); /* Skip size */ read_word(fp); /* Skip reserved stuff */ read_word(fp); read_dword(fp); // Then the bitmap information... info_size = (int)read_dword(fp); img->width = read_long(fp); img->height = read_long(fp); read_word(fp); depth = read_word(fp); compression = (int)read_dword(fp); read_dword(fp); read_long(fp); read_long(fp); colors_used = (int)read_dword(fp); read_dword(fp); if (img->width <= 0 || img->width > IMAGE_MAX_DIM || img->height <= 0 || img->height > IMAGE_MAX_DIM || info_size < 0) return (-1); if (info_size > 40) { for (info_size -= 40; info_size > 0; info_size --) getc(fp); } // Get colormap... if (colors_used == 0 && depth <= 8) colors_used = 1 << depth; else if (colors_used < 0 || colors_used > 256) return (-1); fread(colormap, (size_t)colors_used, 4, fp); // Setup image and buffers... img->depth = gray ? 1 : 3; // If this image is indexed and we are writing an encrypted PDF file, bump the use count so // we create an image object (Acrobat 6 bug workaround) if (depth <= 8 && Encryption) img->use ++; // Return now if we only need the dimensions... if (!load_data) return (0); img->pixels = (uchar *)malloc((size_t)(img->width * img->height * img->depth)); if (img->pixels == NULL) return (-1); if (gray && depth <= 8) { // Convert colormap to grayscale... for (color = colors_used - 1; color >= 0; color --) colormap[color][0] = (colormap[color][2] * 31 + colormap[color][1] * 61 + colormap[color][0] * 8) / 100; } // Read the image data... color = 0; count = 0; align = 0; byte = 0; temp = 0; for (y = img->height - 1; y >= 0; y --) { ptr = img->pixels + y * img->width * img->depth; switch (depth) { case 1 : /* Bitmap */ for (x = img->width, bit = 128; x > 0; x --) { if (bit == 128) byte = (uchar)getc(fp); if (byte & bit) { if (!gray) { *ptr++ = colormap[1][2]; *ptr++ = colormap[1][1]; } *ptr++ = colormap[1][0]; } else { if (!gray) { *ptr++ = colormap[0][2]; *ptr++ = colormap[0][1]; } *ptr++ = colormap[0][0]; } if (bit > 1) bit >>= 1; else bit = 128; } /* * Read remaining bytes to align to 32 bits... */ for (temp = (img->width + 7) / 8; temp & 3; temp ++) getc(fp); break; case 4 : /* 16-color */ for (x = img->width, bit = 0xf0; x > 0; x --) { /* * Get a new count as needed... */ if (compression != BI_RLE4 && count == 0) { count = 2; color = -1; } if (count == 0) { while (align > 0) { align --; getc(fp); } if ((count = getc(fp)) == 0) { if ((count = getc(fp)) == 0) { /* * End of line... */ x ++; continue; } else if (count == 1) { /* * End of image... */ break; } else if (count == 2) { /* * Delta... */ count = getc(fp) * getc(fp) * img->width; color = 0; } else { /* * Absolute... */ color = -1; align = ((4 - (count & 3)) / 2) & 1; } } else color = getc(fp); } /* * Get a new color as needed... */ count --; if (bit == 0xf0) { if (color < 0) temp = getc(fp) & 255; else temp = color; /* * Copy the color value... */ if (!gray) { *ptr++ = colormap[temp >> 4][2]; *ptr++ = colormap[temp >> 4][1]; } *ptr++ = colormap[temp >> 4][0]; bit = 0x0f; } else { /* * Copy the color value... */ if (!gray) { *ptr++ = colormap[temp & 15][2]; *ptr++ = colormap[temp & 15][1]; } *ptr++ = colormap[temp & 15][0]; bit = 0xf0; } } break; case 8 : /* 256-color */ for (x = img->width; x > 0; x --) { /* * Get a new count as needed... */ if (compression != BI_RLE8) { count = 1; color = -1; } if (count == 0) { while (align > 0) { align --; getc(fp); } if ((count = getc(fp)) == 0) { if ((count = getc(fp)) == 0) { /* * End of line... */ x ++; continue; } else if (count == 1) { /* * End of image... */ break; } else if (count == 2) { /* * Delta... */ count = getc(fp) * getc(fp) * img->width; color = 0; } else { /* * Absolute... */ color = -1; align = (2 - (count & 1)) & 1; } } else color = getc(fp); } /* * Get a new color as needed... */ if (color < 0) temp = getc(fp) & 255; else temp = color; count --; /* * Copy the color value... */ if (!gray) { *ptr++ = colormap[temp][2]; *ptr++ = colormap[temp][1]; } *ptr++ = colormap[temp][0]; } break; case 24 : /* 24-bit RGB */ if (gray) { for (x = img->width; x > 0; x --) { temp = getc(fp) * 8; temp += getc(fp) * 61; temp += getc(fp) * 31; *ptr++ = (uchar)(temp / 100); } } else { for (x = img->width; x > 0; x --, ptr += 3) { ptr[2] = (uchar)getc(fp); ptr[1] = (uchar)getc(fp); ptr[0] = (uchar)getc(fp); } } /* * Read remaining bytes to align to 32 bits... */ for (temp = img->width * 3; temp & 3; temp ++) getc(fp); break; } } return (0); } /* * 'image_load_gif()' - Load a GIF image file... */ static int /* O - 0 = success, -1 = fail */ image_load_gif(image_t *img, /* I - Image pointer */ FILE *fp, /* I - File to load from */ int gray, /* I - 0 = color, 1 = grayscale */ int load_data)/* I - 1 = load image data, 0 = just info */ { uchar buf[1024]; /* Input buffer */ gif_cmap_t cmap; /* Colormap */ int ncolors, /* Bits per pixel */ transparent; /* Transparent color index */ /* * Read the header; we already know it is a GIF file... */ fread(buf, 13, 1, fp); img->width = (buf[7] << 8) | buf[6]; img->height = (buf[9] << 8) | buf[8]; ncolors = 2 << (buf[10] & 0x07); if (img->width <= 0 || img->width > IMAGE_MAX_DIM || img->height <= 0 || img->height > IMAGE_MAX_DIM) return (-1); // If we are writing an encrypted PDF file, bump the use count so we create // an image object (Acrobat 6 bug workaround) if (Encryption) img->use ++; if (buf[10] & GIF_COLORMAP) if (gif_read_cmap(fp, ncolors, cmap, &gray)) return (-1); transparent = -1; while (1) { switch (getc(fp)) { case ';' : /* End of image */ return (-1); /* Early end of file */ case '!' : /* Extension record */ buf[0] = (uchar)getc(fp); if (buf[0] == 0xf9) /* Graphic Control Extension */ { gif_get_block(fp, buf); if (buf[0] & 1) /* Get transparent color index */ transparent = buf[3]; } while (gif_get_block(fp, buf) != 0); break; case ',' : /* Image data */ fread(buf, 9, 1, fp); if (buf[8] & GIF_COLORMAP) { ncolors = 2 << (buf[8] & 0x07); if (gif_read_cmap(fp, ncolors, cmap, &gray)) return (-1); } img->width = (buf[5] << 8) | buf[4]; img->height = (buf[7] << 8) | buf[6]; img->depth = gray ? 1 : 3; if (img->width <= 0 || img->width > IMAGE_MAX_DIM || img->height <= 0 || img->height > IMAGE_MAX_DIM) return (-1); if (transparent >= 0) { /* * Map transparent color to background color... */ if (BodyColor[0]) { float rgb[3]; /* RGB color */ get_color((uchar *)BodyColor, rgb); cmap[transparent][0] = (uchar)(rgb[0] * 255.0f + 0.5f); cmap[transparent][1] = (uchar)(rgb[1] * 255.0f + 0.5f); cmap[transparent][2] = (uchar)(rgb[2] * 255.0f + 0.5f); } else { cmap[transparent][0] = 255; cmap[transparent][1] = 255; cmap[transparent][2] = 255; } /* * Allocate a mask image... */ image_need_mask(img); } if (!load_data) return (0); img->pixels = (uchar *)malloc((size_t)(img->width * img->height * img->depth)); if (img->pixels == NULL) return (-1); return (gif_read_image(fp, img, cmap, buf[8] & GIF_INTERLACE, transparent)); } } } #ifdef HAVE_LIBJPEG typedef struct hd_jpeg_err_s // JPEG error manager extension { struct jpeg_error_mgr jerr; // JPEG error manager information jmp_buf retbuf; // setjmp() return buffer char message[JMSG_LENGTH_MAX]; // Last error message } hd_jpeg_err_t; /* * 'image_load_jpeg()' - Load a JPEG image file. */ static int /* O - 0 = success, -1 = fail */ image_load_jpeg(image_t *img, /* I - Image pointer */ FILE *fp, /* I - File to load from */ int gray, /* I - 0 = color, 1 = grayscale */ int load_data)/* I - 1 = load image data, 0 = just info */ { struct jpeg_decompress_struct cinfo; /* Decompressor info */ hd_jpeg_err_t jerr; // JPEG error handler JSAMPROW row; /* Sample row pointer */ jpeg_std_error(&jerr.jerr); jerr.jerr.error_exit = jpeg_error_handler; if (setjmp(jerr.retbuf)) { progress_error(HD_ERROR_BAD_FORMAT, "%s (%s)", jerr.message, file_rlookup(img->filename)); jpeg_destroy_decompress(&cinfo); return (-1); } cinfo.err = (struct jpeg_error_mgr *)&jerr; jpeg_create_decompress(&cinfo); jpeg_stdio_src(&cinfo, fp); jpeg_read_header(&cinfo, (boolean)1); cinfo.quantize_colors = FALSE; if (gray || cinfo.num_components == 1) { cinfo.out_color_space = JCS_GRAYSCALE; cinfo.out_color_components = 1; cinfo.output_components = 1; } else if (cinfo.num_components != 3) { jpeg_destroy_decompress(&cinfo); progress_error(HD_ERROR_BAD_FORMAT, "CMYK JPEG files are not supported! (%s)", file_rlookup(img->filename)); return (-1); } else { cinfo.out_color_space = JCS_RGB; cinfo.out_color_components = 3; cinfo.output_components = 3; } jpeg_calc_output_dimensions(&cinfo); img->width = (int)cinfo.output_width; img->height = (int)cinfo.output_height; img->depth = (int)cinfo.output_components; if (img->width <= 0 || img->width > IMAGE_MAX_DIM || img->height <= 0 || img->height > IMAGE_MAX_DIM) { jpeg_destroy_decompress(&cinfo); return (-1); } if (!load_data) { jpeg_destroy_decompress(&cinfo); return (0); } img->pixels = (uchar *)malloc((size_t)(img->width * img->height * img->depth)); if (img->pixels == NULL) { jpeg_destroy_decompress(&cinfo); return (-1); } jpeg_start_decompress(&cinfo); while (cinfo.output_scanline < cinfo.output_height) { row = (JSAMPROW)(img->pixels + (size_t)cinfo.output_scanline * (size_t)cinfo.output_width * (size_t)cinfo.output_components); jpeg_read_scanlines(&cinfo, &row, (JDIMENSION)1); } jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); return (0); } #endif // HAVE_LIBJPEG #ifdef HAVE_LIBPNG /* * 'image_load_png()' - Load a PNG image file. */ static int /* O - 0 = success, -1 = fail */ image_load_png(image_t *img, /* I - Image pointer */ FILE *fp, /* I - File to read from */ int gray, /* I - 0 = color, 1 = grayscale */ int load_data)/* I - 1 = load image data, 0 = just info */ { int i, j; /* Looping vars */ png_structp pp; /* PNG read pointer */ png_infop info; /* PNG info pointers */ int depth; /* Input image depth */ png_bytep *rows = NULL; /* PNG row pointers */ uchar *inptr, /* Input pixels */ *outptr; /* Output pixels */ int color_type, /* PNG color mode */ bit_depth; /* PNG bit depth */ /* * Setup the PNG data structures... */ pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!pp) { progress_error(HD_ERROR_OUT_OF_MEMORY, "Unable to allocate memory for PNG file: %s", strerror(errno)); return (-1); } info = png_create_info_struct(pp); if (!info) { progress_error(HD_ERROR_OUT_OF_MEMORY, "Unable to allocate memory for PNG info: %s", strerror(errno)); png_destroy_read_struct(&pp, NULL, NULL); return (-1); } if (setjmp(png_jmpbuf(pp))) { progress_error(HD_ERROR_BAD_FORMAT, "PNG file contains errors!"); png_destroy_read_struct(&pp, &info, NULL); if (img != NULL) { free(img->pixels); img->pixels = NULL; } free(rows); rows = NULL; return (-1); } /* * Initialize the PNG read "engine"... */ png_init_io(pp, fp); # if defined(PNG_SKIP_sRGB_CHECK_PROFILE) && defined(PNG_SET_OPTION_SUPPORTED) // Don't throw errors with "invalid" sRGB profiles produced by Adobe apps. png_set_option(pp, PNG_SKIP_sRGB_CHECK_PROFILE, PNG_OPTION_ON); # endif // PNG_SKIP_sRGB_CHECK_PROFILE && PNG_SET_OPTION_SUPPORTED /* * Get the image dimensions and convert to grayscale or RGB... */ png_read_info(pp, info); bit_depth = png_get_bit_depth(pp, info); color_type = png_get_color_type(pp, info); if (png_get_valid(pp, info, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha(pp); color_type |= PNG_COLOR_MASK_ALPHA; } if (color_type & PNG_COLOR_MASK_PALETTE) { png_set_palette_to_rgb(pp); // If we are writing an encrypted PDF file, bump the use count so we create // an image object (Acrobat 6 bug workaround) if (Encryption) img->use ++; } else if (!(color_type & PNG_COLOR_MASK_COLOR) && bit_depth < 8) { png_set_expand_gray_1_2_4_to_8(pp); } else if (bit_depth == 16) { # if PNG_LIBPNG_VER >= 10504 png_set_scale_16(pp); # else png_set_strip_16(pp); # endif // PNG_LIBPNG_VER >= 10504 } if (color_type & PNG_COLOR_MASK_COLOR) { depth = 3; img->depth = gray ? 1 : 3; } else { depth = 1; img->depth = 1; } img->width = (int)png_get_image_width(pp, info); img->height = (int)png_get_image_height(pp, info); if (img->width <= 0 || img->width > IMAGE_MAX_DIM || img->height <= 0 || img->height > IMAGE_MAX_DIM) { png_destroy_read_struct(&pp, &info, NULL); return (-1); } if (color_type & PNG_COLOR_MASK_ALPHA) { if ((PSLevel == 0 && PDFVersion >= 14) || PSLevel == 3) image_need_mask(img, 8); else if (PSLevel == 0 && PDFVersion == 13) image_need_mask(img, 2); else image_need_mask(img); depth ++; } # ifdef DEBUG printf("bit_depth=%d, color_type=0x%04x, depth=%d, img->width=%d, img->height=%d, img->depth=%d\n", bit_depth, color_type, depth, img->width, img->height, img->depth); if (color_type & PNG_COLOR_MASK_COLOR) puts(" COLOR"); else puts(" GRAYSCALE"); if (color_type & PNG_COLOR_MASK_ALPHA) puts(" ALPHA"); if (color_type & PNG_COLOR_MASK_PALETTE) puts(" PALETTE"); # endif // DEBUG if (!load_data) { png_destroy_read_struct(&pp, &info, NULL); return (0); } img->pixels = (uchar *)calloc(1, (size_t)(img->width * img->height * depth)); /* * Allocate pointers... */ rows = (png_bytep *)calloc(png_get_image_height(pp, info), sizeof(png_bytep)); for (i = 0; i < (int)png_get_image_height(pp, info); i ++) rows[i] = img->pixels + i * img->width * depth; /* * Read the image, handling interlacing as needed... */ for (i = png_set_interlace_handling(pp); i > 0; i --) png_read_rows(pp, rows, NULL, (png_uint_32)img->height); /* * Generate the alpha mask as necessary... */ if (color_type & PNG_COLOR_MASK_ALPHA) { # ifdef DEBUG for (inptr = img->pixels, i = 0; i < img->height; i ++) { for (j = 0; j < img->width; j ++, inptr += depth) switch (depth) { case 2 : printf(" %02X%02X", inptr[0], inptr[1]); break; case 4 : printf(" %02X%02X%02X%02X", inptr[0], inptr[1], inptr[2], inptr[3]); break; } putchar('\n'); } # endif // DEBUG for (inptr = img->pixels + depth - 1, i = 0; i < img->height; i ++) for (j = 0; j < img->width; j ++, inptr += depth) image_set_mask(img, j, i, *inptr); } /* * Reformat the data as necessary for the reader... */ if (gray && (color_type & PNG_COLOR_MASK_COLOR)) { /* * Grayscale output needed... */ for (inptr = img->pixels, outptr = img->pixels, i = img->width * img->height; i > 0; inptr += depth, outptr ++, i --) *outptr = (31 * inptr[0] + 61 * inptr[1] + 8 * inptr[2]) / 100; } else if (img->depth != depth) { /* * Remove alpha from final array... */ if (depth == 4) { for (inptr = img->pixels, outptr = img->pixels, i = img->width * img->height; i > 0; inptr ++, i --) { *outptr++ = *inptr++; *outptr++ = *inptr++; *outptr++ = *inptr++; } } else { for (inptr = img->pixels, outptr = img->pixels, i = img->width * img->height; i > 0; inptr ++, i --) *outptr++ = *inptr++; } } /* * Free memory and return... */ png_read_end(pp, info); png_destroy_read_struct(&pp, &info, NULL); free(rows); return (0); } #endif // HAVE_LIBPNG /* * 'image_need_mask()' - Allocate memory for the image mask... */ static void image_need_mask(image_t *img, /* I - Image to add mask to */ int scaling) /* I - Scaling for mask image */ { size_t size; /* Byte size of mask image */ if (img == NULL || img->mask != NULL) return; /* * Figure out the size of the mask image, and then allocate and set all the * bits needed... */ img->maskscale = scaling; if (scaling == 8) { // Alpha image img->maskwidth = img->width; size = (size_t)(img->width * img->height); } else { // Alpha mask img->maskwidth = (img->width * scaling + 7) / 8; size = (size_t)(img->maskwidth * img->height * scaling + 1); } img->mask = (uchar *)calloc(size, 1); } /* * 'image_set_mask()' - Set a bit in the image mask. */ static void image_set_mask(image_t *img, /* I - Image to operate on */ int x, /* I - X coordinate */ int y, /* I - Y coordinate */ uchar alpha) /* I - Alpha value */ { int i, j; /* Looping vars */ uchar *maskptr; /* Pointer into mask image */ static uchar masks[8] = /* Masks for each bit */ { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; static uchar dither[4][4] = // Simple 4x4 clustered-dot dither { { 0, 2, 15, 6 }, { 4, 12, 9, 11 }, { 14, 7, 1, 3 }, { 8, 10, 5, 13 } }; if (img == NULL || img->mask == NULL || x < 0 || x >= img->width || y < 0 || y >= img->height) return; if (img->maskscale == 8) { // Store the alpha value directly... if (PSLevel) img->mask[y * img->maskwidth + x] = 255 - alpha; else img->mask[y * img->maskwidth + x] = alpha; } else { // Store an alpha mask... x *= img->maskscale; y *= img->maskscale; alpha >>= 4; for (i = 0; i < img->maskscale; i ++, y ++, x -= img->maskscale) for (j = 0; j < img->maskscale; j ++, x ++) { maskptr = img->mask + y * img->maskwidth + x / 8; if (alpha <= dither[x & 3][y & 3]) *maskptr |= masks[x & 7]; } } } /* * 'image_unload()' - Unload an image from memory. */ void image_unload(image_t *img) // I - Image { if (!img) return; if (!img->use || !img->pixels) return; if (img->obj) img->use = 0; else img->use --; if (img->use) return; free(img->pixels); img->pixels = NULL; } #ifdef HAVE_LIBJPEG /* * 'jpeg_error_handler()' - Handle JPEG errors by not exiting. */ static void jpeg_error_handler(j_common_ptr p) // Common JPEG data { hd_jpeg_err_t *jerr = (hd_jpeg_err_t *)p->err; // JPEG error handler // Save the error message in the string buffer... (jerr->jerr.format_message)(p, jerr->message); // Return to the point we called setjmp()... longjmp(jerr->retbuf, 1); } #endif // HAVE_LIBJPEG /* * 'read_word()' - Read a 16-bit unsigned integer. */ static unsigned short /* O - 16-bit unsigned integer */ read_word(FILE *fp) /* I - File to read from */ { unsigned char b0, b1; /* Bytes from file */ b0 = (uchar)getc(fp); b1 = (uchar)getc(fp); return (unsigned short)((b1 << 8) | b0); } /* * 'read_dword()' - Read a 32-bit unsigned integer. */ static unsigned int /* O - 32-bit unsigned integer */ read_dword(FILE *fp) /* I - File to read from */ { unsigned char b0, b1, b2, b3; /* Bytes from file */ b0 = (uchar)getc(fp); b1 = (uchar)getc(fp); b2 = (uchar)getc(fp); b3 = (uchar)getc(fp); return (unsigned)((((((b3 << 8) | b2) << 8) | b1) << 8) | b0); } /* * 'read_long()' - Read a 32-bit signed integer. */ static int /* O - 32-bit signed integer */ read_long(FILE *fp) /* I - File to read from */ { unsigned char b0, b1, b2, b3; /* Bytes from file */ b0 = (uchar)getc(fp); b1 = (uchar)getc(fp); b2 = (uchar)getc(fp); b3 = (uchar)getc(fp); return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0); } htmldoc-1.9.20/htmldoc/image.h000066400000000000000000000030221472561501400161240ustar00rootroot00000000000000/* * Image management definitions for HTMLDOC, a HTML document processing * program. * * Copyright 2011 by Michael R Sweet. * Copyright 1997-2010 by Easy Software Products. All rights reserved. * * This program is free software. Distribution and use rights are outlined in * the file "COPYING". */ #ifndef _IMAGE_H_ # define _IMAGE_H_ /* * Include necessary headers. */ # include # include # include "hdstring.h" # include "types.h" # ifdef __cplusplus extern "C" { # endif /* __cplusplus */ /* * Image structure... */ typedef struct /**** Image structure ****/ { char filename[1024]; /* Name of image file (for caching of images */ int width, /* Width of image in pixels */ height, /* Height of image in pixels */ depth, /* 1 for grayscale, 3 for RGB */ use, /* Number of times this image was used */ obj; /* Object number */ uchar *pixels; /* 8-bit pixel data */ uchar *mask; /* 1-bit mask data, if any */ int maskwidth, /* Byte width of mask data */ maskscale; /* Scaling of mask data */ } image_t; /* * Prototypes... */ extern void image_copy(const char *src, const char *realsrc, const char *destpath); extern image_t *image_find(const char *filename, int load_data = 0); extern void image_flush_cache(void); extern int image_getlist(image_t ***ptrs); extern image_t *image_load(const char *filename, int gray, int load_data = 0); extern void image_unload(image_t *img); # ifdef __cplusplus } # endif /* __cplusplus */ #endif /* !_IMAGE_H_ */ htmldoc-1.9.20/htmldoc/iso8859.cxx000066400000000000000000000302611472561501400165520ustar00rootroot00000000000000/* * ISO-8859-1 conversion routines for HTMLDOC, an HTML document * processing program. * * Copyright 2011-2024 by Michael R Sweet. * Copyright 1997-2010 by Easy Software Products. All rights reserved. * * This program is free software. Distribution and use rights are outlined in * the file "COPYING". */ #include #include #include "html.h" #include "types.h" /* * Lookup table structure... */ typedef struct { uchar name[12]; int value; } lut_t; static lut_t iso8859_numbers[] = { { "AElig", 198 }, { "Aacute", 193 }, { "Acirc", 194 }, { "Agrave", 192 }, { "Alpha", 913 }, { "Aring", 197 }, { "Atilde", 195 }, { "Auml", 196 }, { "Beta", 914 }, { "Ccedil", 199 }, { "Chi", 935 }, { "Dagger", 8225 }, { "Delta", 916 }, { "ETH", 208 }, { "Eacute", 201 }, { "Ecirc", 202 }, { "Egrave", 200 }, { "Epsilon", 917 }, { "Eta", 919 }, { "Euml", 203 }, { "Gamma", 915 }, { "Iacute", 205 }, { "Icirc", 206 }, { "Igrave", 204 }, { "Iota", 921 }, { "Iuml", 207 }, { "Kappa", 922 }, { "Lambda", 923 }, { "Mu", 924 }, { "Ntilde", 209 }, { "Nu", 925 }, { "OElig", 338 }, { "Oacute", 211 }, { "Ocirc", 212 }, { "Ograve", 210 }, { "Omega", 937 }, { "Omicron", 927 }, { "Oslash", 216 }, { "Otilde", 213 }, { "Ouml", 214 }, { "Phi", 934 }, { "Pi", 928 }, { "Prime", 8243 }, { "Psi", 936 }, { "Rho", 929 }, { "Scaron", 352 }, { "Sigma", 931 }, { "THORN", 222 }, { "Tau", 932 }, { "Theta", 920 }, { "Uacute", 218 }, { "Ucirc", 219 }, { "Ugrave", 217 }, { "Upsilon", 933 }, { "Uuml", 220 }, { "Xi", 926 }, { "Yacute", 221 }, { "Yuml", 376 }, { "Zeta", 918 }, { "aacute", 225 }, { "acirc", 226 }, { "acute", 180 }, { "aelig", 230 }, { "agrave", 224 }, { "alefsym", 8501 }, { "alpha", 945 }, { "amp", 38 }, { "and", 8743 }, { "ang", 8736 }, { "aring", 229 }, { "asymp", 8776 }, { "atilde", 227 }, { "auml", 228 }, { "bdquo", 8222 }, { "beta", 946 }, { "brvbar", 166 }, { "bull", 8226 }, { "cap", 8745 }, { "ccedil", 231 }, { "cedil", 184 }, { "cent", 162 }, { "chi", 967 }, { "circ", 710 }, { "clubs", 9827 }, { "cong", 8773 }, { "copy", 169 }, { "crarr", 8629 }, { "cup", 8746 }, { "curren", 164 }, { "dArr", 8659 }, { "dagger", 8224 }, { "darr", 8595 }, { "deg", 176 }, { "delta", 948 }, { "diams", 9830 }, { "divide", 247 }, { "eacute", 233 }, { "ecirc", 234 }, { "egrave", 232 }, { "empty", 8709 }, { "emsp", 8195 }, { "ensp", 8194 }, { "epsilon", 949 }, { "equiv", 8801 }, { "eta", 951 }, { "eth", 240 }, { "euml", 235 }, { "euro", 8364 }, { "exist", 8707 }, { "fnof", 402 }, { "forall", 8704 }, { "frac12", 189 }, { "frac14", 188 }, { "frac34", 190 }, { "frasl", 8260 }, { "gamma", 947 }, { "ge", 8805 }, { "gt", 62 }, { "hArr", 8660 }, { "harr", 8596 }, { "hearts", 9829 }, { "hellip", 8230 }, { "iacute", 237 }, { "icirc", 238 }, { "iexcl", 161 }, { "igrave", 236 }, { "image", 8465 }, { "infin", 8734 }, { "int", 8747 }, { "iota", 953 }, { "iquest", 191 }, { "isin", 8712 }, { "iuml", 239 }, { "kappa", 954 }, { "lArr", 8656 }, { "lambda", 955 }, { "lang", 9001 }, { "laquo", 171 }, { "larr", 8592 }, { "lceil", 8968 }, { "ldquo", 8220 }, { "le", 8804 }, { "lfloor", 8970 }, { "lowast", 8727 }, { "loz", 9674 }, { "lrm", 8206 }, { "lsaquo", 8249 }, { "lsquo", 8216 }, { "lt", 60 }, { "macr", 175 }, { "mdash", 8212 }, { "micro", 181 }, { "middot", 183 }, { "minus", 8722 }, { "mu", 956 }, { "nabla", 8711 }, { "nbsp", 160 }, { "ndash", 8211 }, { "ne", 8800 }, { "ni", 8715 }, { "not", 172 }, { "notin", 8713 }, { "nsub", 8836 }, { "ntilde", 241 }, { "nu", 957 }, { "oacute", 243 }, { "ocirc", 244 }, { "oelig", 339 }, { "ograve", 242 }, { "oline", 8254 }, { "omega", 969 }, { "omicron", 959 }, { "oplus", 8853 }, { "or", 8744 }, { "ordf", 170 }, { "ordm", 186 }, { "oslash", 248 }, { "otilde", 245 }, { "otimes", 8855 }, { "ouml", 246 }, { "para", 182 }, { "part", 8706 }, { "permil", 8240 }, { "perp", 8869 }, { "phi", 966 }, { "pi", 960 }, { "piv", 982 }, { "plusmn", 177 }, { "pound", 163 }, { "prime", 8242 }, { "prod", 8719 }, { "prop", 8733 }, { "psi", 968 }, { "quot", 34 }, { "rArr", 8658 }, { "radic", 8730 }, { "rang", 9002 }, { "raquo", 187 }, { "rarr", 8594 }, { "rceil", 8969 }, { "rdquo", 8221 }, { "real", 8476 }, { "reg", 174 }, { "rfloor", 8971 }, { "rho", 961 }, { "rlm", 8207 }, { "rsaquo", 8250 }, { "rsquo", 8217 }, { "sbquo", 8218 }, { "scaron", 353 }, { "sdot", 8901 }, { "sect", 167 }, { "shy", 173 }, { "sigma", 963 }, { "sigmaf", 962 }, { "sim", 8764 }, { "spades", 9824 }, { "sub", 8834 }, { "sube", 8838 }, { "sum", 8721 }, { "sup", 8835 }, { "sup1", 185 }, { "sup2", 178 }, { "sup3", 179 }, { "supe", 8839 }, { "szlig", 223 }, { "tau", 964 }, { "there4", 8756 }, { "theta", 952 }, { "thetasym", 977 }, { "thinsp", 8201 }, { "thorn", 254 }, { "tilde", 732 }, { "times", 215 }, { "trade", 8482 }, { "uArr", 8657 }, { "uacute", 250 }, { "uarr", 8593 }, { "ucirc", 251 }, { "ugrave", 249 }, { "uml", 168 }, { "upsih", 978 }, { "upsilon", 965 }, { "uuml", 252 }, { "weierp", 8472 }, { "xi", 958 }, { "yacute", 253 }, { "yen", 165 }, { "yuml", 255 }, { "zeta", 950 }, { "zwj", 8205 }, { "zwnj", 8204 } }; static lut_t *iso8859_names[256]; static int compare_lut(lut_t *, lut_t *); /* * 'iso8859()' - Return the 8-bit character value of a glyph name. */ uchar /* O - ISO-8859-1 equivalent */ iso8859(uchar *name) /* I - Glyph name */ { lut_t key, /* Lookup table key */ *match; /* Matching entry pointer */ int ch; /* Character */ if (strlen((char *)name) == 1) return (name[0]); else if (name[0] == '#') { // Return a decimal or hex character... if (name[1] == 'x') ch = strtol((char *)name + 2, NULL, 16); else ch = strtol((char *)name + 1, NULL, 10); if (ch > 0xffff || ch <= 0) return (0); } else { strlcpy((char *)key.name, (char *)name, sizeof(key.name)); match = (lut_t *)bsearch(&key, iso8859_numbers, sizeof(iso8859_numbers) / sizeof(iso8859_numbers[0]), sizeof(iso8859_numbers[0]), (int (*)(const void *, const void *))compare_lut); if (match == NULL) return (0); else ch = match->value; } if (ch > 0x7f && _htmlUTF8) { // Map Unicode value... ch = htmlMapUnicode(ch); } else if (ch > 0x7f) { // Lookup Unicode value in the current charset... const char *glyph; char uniglyph[32]; int newch; if (!_htmlInitialized) htmlSetCharSet("iso-8859-1"); if ((glyph = _htmlGlyphsAll[ch]) == NULL) { snprintf(uniglyph, sizeof(uniglyph), "uni%04x", ch); glyph = uniglyph; } for (newch = 128; newch < 256; newch ++) if (_htmlGlyphs[newch] && !strcmp(_htmlGlyphs[newch], glyph)) break; if (newch >= 256) { // Not part of the standard charset, see if we have room for a // few extras... for (newch = 128; newch < 256; newch ++) if (!_htmlGlyphs[newch]) { // Yes, assign this character to it... if (glyph == uniglyph) _htmlGlyphsAll[ch] = _htmlGlyphs[newch] = strdup(glyph); else _htmlGlyphs[newch] = glyph; _htmlUnicode[newch] = ch; // Update font widths... for (int typeface = 0; typeface < TYPE_MAX; typeface ++) { for (int style = 0; style < STYLE_MAX; style ++) { if (_htmlWidthsLoaded[typeface][style]) { _htmlWidths[typeface][style][newch] = _htmlWidthsAll[typeface][style][ch]; } } } // Return the new character... return ((uchar)newch); } // No room, return nul... return (0); } else ch = newch; } return ((uchar)ch); } /* * 'iso8859()' - Return the glyph name of an 8-bit character value. */ uchar * /* O - Glyph name */ iso8859(uchar value) /* I - ISO-8859-1 equivalent */ { int i; /* Looping var */ int ch; /* Current character */ static int first_time = 1; /* First time called? */ static uchar buf[255]; /* Character buffer */ if (first_time) { memset(iso8859_names, 0, sizeof(iso8859_names)); for (i = 0; i < (int)(sizeof(iso8859_numbers) / sizeof(iso8859_numbers[0])); i ++) if ((ch = iso8859_numbers[i].value) < 128) iso8859_names[ch] = iso8859_numbers + i; else { // Lookup Unicode value in the current charset... const char *glyph; char uniglyph[32]; if ((glyph = _htmlGlyphsAll[ch]) == NULL) { snprintf(uniglyph, sizeof(uniglyph), "uni%04x", ch); glyph = uniglyph; } for (ch = 128; ch < 256; ch ++) if (_htmlGlyphs[ch] && !strcmp(_htmlGlyphs[ch], glyph)) { iso8859_names[ch] = iso8859_numbers + i; break; } } first_time = 0; } if (iso8859_names[value] == NULL) { if (value < 127) { // ASCII... buf[0] = value; buf[1] = '\0'; } else if (_htmlUTF8) { // UTF-8... int unich = _htmlUnicode[value]; // Unicode character if (unich < 0x400) { buf[0] = 0xc0 | (unich >> 6); buf[1] = 0x80 | (unich & 0x3f); buf[2] = '\0'; } else if (unich < 0x10000) { buf[0] = 0xe0 | (unich >> 12); buf[1] = 0x80 | ((unich >> 6) & 0x3f); buf[2] = 0x80 | (unich & 0x3f); buf[3] = '\0'; } else { buf[0] = 0xf0 | (unich >> 18); buf[1] = 0x80 | ((unich >> 12) & 0x3f); buf[2] = 0x80 | ((unich >> 6) & 0x3f); buf[3] = 0x80 | (unich & 0x3f); buf[4] = '\0'; } } else { // Character-set neutral way to map to Unicode... snprintf((char *)buf, sizeof(buf), "&#%d;", _htmlUnicode[value]); } } else { snprintf((char *)buf, sizeof(buf), "&%s;", iso8859_names[value]->name); } return (buf); } /* * 'xhtml_entity()' - Return the UTF-8 character or XHTML entity. */ const uchar * /* O - XHTML string */ xhtml_entity(uchar ch) /* I - Character */ { static uchar buf[5]; /* UTF-8 character buffer */ if (ch == '&') return ((uchar *)"&"); else if (ch == '<') return ((uchar *)"<"); else if (ch == '>') return ((uchar *)">"); else if (ch == '\"') return ((uchar *)"""); else if (ch >= ' ' && ch < 0x7f) { // US ASCII buf[0] = ch; buf[1] = '\0'; return (buf); } else { // Unicode -> UTF-8 int unich = _htmlUnicode[ch]; if (unich < 0x80) { // 1-byte US ASCII buf[0] = (uchar)unich; buf[1] = '\0'; } else if (unich < 0x800) { // 2-byte UTF-8 buf[0] = (uchar)(0xc0 | (unich >> 6)); buf[1] = (uchar)(0x80 | (unich & 0x3f)); buf[2] = '\0'; } else if (unich < 0x10000) { // 3-byte UTF-8 buf[0] = (uchar)(0xe0 | (unich >> 12)); buf[1] = (uchar)(0x80 | ((unich >> 6) & 0x3f)); buf[2] = (uchar)(0x80 | (unich & 0x3f)); buf[3] = '\0'; } else { // 4-byte UTF-8 buf[0] = (uchar)(0xf0 | (unich >> 18)); buf[1] = (uchar)(0x80 | ((unich >> 12) & 0x3f)); buf[2] = (uchar)(0x80 | ((unich >> 6) & 0x3f)); buf[3] = (uchar)(0x80 | (unich & 0x3f)); buf[4] = '\0'; } return (buf); } } /* * 'compare_lut()' - Compare two glyphs. */ static int /* O - 0 if equal, -1 if ab */ compare_lut(lut_t *a, /* I - First glyph */ lut_t *b) /* I - Second glyph */ { return (strcmp((char *)a->name, (char *)b->name)); } htmldoc-1.9.20/htmldoc/iso8859.h000066400000000000000000000011211472561501400161700ustar00rootroot00000000000000/* * ISO-8859-1 definitions for HTMLDOC, an HTML document processing program. * * Copyright 2011-2017 by Michael R Sweet. * Copyright 1997-2010 by Easy Software Products. All rights reserved. * * This program is free software. Distribution and use rights are outlined in * the file "COPYING". */ #ifndef _ISO8859_H_ # define _ISO8859_H_ /* * Include necessary headers. */ # include "types.h" /* * Prototypes... */ extern uchar iso8859(uchar *name); extern uchar *iso8859(uchar value); extern const uchar *xhtml_entity(uchar ch); #endif /* !_ISO8859_H_ */ htmldoc-1.9.20/htmldoc/license.cxx000066400000000000000000000533571472561501400170570ustar00rootroot00000000000000// // GUI license dialog routines for HTMLDOC, an HTML document processing // program. // // Copyright 2011-2024 by Michael R Sweet. // Copyright 1997-2010 by Easy Software Products. All rights reserved. // // This program is free software. Distribution and use rights are outlined in // the file "COPYING". // #include "htmldoc.h" #ifdef HAVE_LIBFLTK // // Include necessary headers. // # include # include # include # include # include // // Local functions... // static void closeLicenseCB(Fl_Widget *w); // // 'GUI::showLicenseCB()' - Show the current license. // void GUI::showLicenseCB(void) { Fl_Window *dialog; // Dialog window Fl_Group *group; // Raised area Fl_Help_View *help; // License agreement viewer Fl_Button *button; // Button Fl_Box *box; // Text box // Create the window complete with the license agreement and // button to add a new license... dialog = new Fl_Window(640, 480, "HTMLDOC " SVERSION " License"); dialog->set_modal(); dialog->hotspot(dialog); group = new Fl_Group(10, 10, 620, 425, "HTMLDOC " SVERSION " License"); group->align((Fl_Align)(FL_ALIGN_LEFT | FL_ALIGN_TOP | FL_ALIGN_INSIDE)); group->box(FL_THIN_UP_BOX); group->labelcolor(FL_BLUE); group->labelfont(FL_HELVETICA_BOLD); group->labelsize(18); box = new Fl_Box(20, 45, 600, 110, "Copyright © 2011-2024 by Michael R Sweet.\n\n" "HTMLDOC is provided under the terms of the GNU General Public License and " "comes with absolutely no warranty. Please report problems on the Github " "issues page at:\n\n" " https://github.com/michaelrsweet/htmldoc/issues\n" ); box->align((Fl_Align)(FL_ALIGN_TOP_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_WRAP)); help = new Fl_Help_View(20, 190, 600, 235, "Software License Agreement:"); help->align(FL_ALIGN_TOP_LEFT); help->value( "

    GNU GENERAL PUBLIC LICENSE

    \n" "

    Version 2, June 1991 " "

    \n"
        "Copyright 1989, 1991 Free Software Foundation, Inc.\n"
        "59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n"
        "Everyone is permitted to copy and distribute verbatim\n"
        "copies of this license document, but changing it is not\n"
        "allowed.\n"
        "\n"
        "
    \n" "

    Preamble

    \n" "

    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
    \n" "TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

    \n" "

    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

    \n" "

    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. " "

    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

    \n" "

    How to Apply These Terms to Your New Programs

    \n" "\n" "

    If you develop a new program, and you want it to be of the greatest\n" "possible use to the public, the best way to achieve this is to make it\n" "free software which everyone can redistribute and change under these terms.\n" "\n" "

    To do so, attach the following notices to the program. It is safest\n" "to attach them to the start of each source file to most effectively\n" "convey the exclusion of warranty; and each file should have at least\n" "the \"copyright\" line and a pointer to where the full notice is found.\n" "\n" "

    \n"
        "one line to give the program's name and an idea of what it does.\n"
        "Copyright (C) yyyy  name of author\n"
        "\n"
        "This program is free software; you can redistribute it and/or\n"
        "modify it under the terms of the GNU General Public License\n"
        "as published by the Free Software Foundation; either version 2\n"
        "of the License, or (at your option) any later version.\n"
        "\n"
        "This program is distributed in the hope that it will be useful,\n"
        "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
        "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
        "GNU General Public License for more details.\n"
        "\n"
        "You should have received a copy of the GNU General Public License\n"
        "along with this program; if not, write to the Free Software\n"
        "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\n"
        "
    \n" "\n" "

    Also add information on how to contact you by electronic and paper mail.\n" "\n" "

    If the program is interactive, make it output a short notice like this\n" "when it starts in an interactive mode:\n" "\n" "

    \n"
        "Gnomovision version 69, Copyright (C) year name of author\n"
        "Gnomovision comes with ABSOLUTELY NO WARRANTY; for details\n"
        "type `show w'.  This is free software, and you are welcome\n"
        "to redistribute it under certain conditions; type `show c' \n"
        "for details.\n"
        "
    \n" "\n" "

    The hypothetical commands `show w' and `show c' should show\n" "the appropriate parts of the General Public License. Of course, the\n" "commands you use may be called something other than `show w' and\n" "`show c'; they could even be mouse-clicks or menu items--whatever\n" "suits your program.\n" "\n" "

    You should also get your employer (if you work as a programmer) or your\n" "school, if any, to sign a \"copyright disclaimer\" for the program, if\n" "necessary. Here is a sample; alter the names:\n" "\n" "

    \n"
        "Yoyodyne, Inc., hereby disclaims all copyright\n"
        "interest in the program `Gnomovision'\n"
        "(which makes passes at compilers) written \n"
        "by James Hacker.\n"
        "\n"
        "signature of Ty Coon, 1 April 1989\n"
        "Ty Coon, President of Vice\n"
        "
    \n" ); group->end(); button = new Fl_Button(565, 445, 65, 25, "Close"); button->callback((Fl_Callback *)closeLicenseCB); // Show the window and wait... dialog->end(); dialog->show(); while (dialog->shown()) Fl::wait(); delete dialog; } // // 'closeLicenseCB()' - Close the license window. // static void closeLicenseCB(Fl_Widget *w) // I - Close button { if (w && w->window()) w->window()->hide(); } #endif // HAVE_LIBFLTK htmldoc-1.9.20/htmldoc/markdown.cxx000066400000000000000000000320471472561501400172500ustar00rootroot00000000000000/* * Markdown parsing definitions for HTMLDOC, a HTML document processing program. * * Copyright © 2017-2024 by Michael R Sweet. * * This program is free software. Distribution and use rights are outlined in * the file "COPYING". */ /* * Include necessary headers... */ # include "markdown.h" # include "mmd.h" # include "progress.h" /* * Local functions... */ static void add_block(tree_t *hparent, mmd_t *parent); static void add_leaf(tree_t *hparent, mmd_t *node); static uchar *get_text(uchar *text); static uchar *make_anchor(mmd_t *block); static uchar *make_anchor(const uchar *text); /* * 'mdReadFile()' - Read a Markdown file. */ tree_t * /* O - HTML document tree */ mdReadFile(tree_t *parent, /* I - Parent node */ FILE *fp, /* I - File to read from */ const char *base) /* I - Base path/URL */ { mmd_t *doc; /* Markdown document */ tree_t *html, /* HTML element */ *head, /* HEAD element */ *temp, /* META/TITLE element */ *body; /* BODY element */ const char *meta; /* Title, author, etc. */ doc = mmdLoadFile(NULL, fp); html = htmlAddTree(parent, MARKUP_HTML, NULL); if ((meta = mmdGetMetadata(doc, "lang")) != NULL) htmlSetVariable(html, (uchar *)"lang", get_text((uchar *)meta)); head = htmlAddTree(html, MARKUP_HEAD, NULL); if ((meta = mmdGetMetadata(doc, "title")) != NULL) { temp = htmlAddTree(head, MARKUP_TITLE, NULL); htmlAddTree(temp, MARKUP_NONE, get_text((uchar *)meta)); } if ((meta = mmdGetMetadata(doc, "author")) != NULL) { temp = htmlAddTree(head, MARKUP_META, NULL); htmlSetVariable(temp, (uchar *)"name", (uchar *)"author"); htmlSetVariable(temp, (uchar *)"content", get_text((uchar *)meta)); } if ((meta = mmdGetMetadata(doc, "copyright")) != NULL) { temp = htmlAddTree(head, MARKUP_META, NULL); htmlSetVariable(temp, (uchar *)"name", (uchar *)"copyright"); htmlSetVariable(temp, (uchar *)"content", get_text((uchar *)meta)); } if ((meta = mmdGetMetadata(doc, "version")) != NULL) { temp = htmlAddTree(head, MARKUP_META, NULL); htmlSetVariable(temp, (uchar *)"name", (uchar *)"version"); htmlSetVariable(temp, (uchar *)"content", get_text((uchar *)meta)); } if ((meta = mmdGetMetadata(doc, "language")) != NULL) { htmlSetVariable(html, (uchar *)"lang", get_text((uchar *)meta)); } if ((meta = mmdGetMetadata(doc, "subject")) != NULL) { temp = htmlAddTree(head, MARKUP_META, NULL); htmlSetVariable(temp, (uchar *)"name", (uchar *)"keywords"); htmlSetVariable(temp, (uchar *)"content", get_text((uchar *)meta)); } body = htmlAddTree(html, MARKUP_BODY, NULL); add_block(body, doc); mmdFree(doc); return (html); } /* * 'add_block()' - Add a block node. */ static void add_block(tree_t *html, /* I - Parent HTML node */ mmd_t *parent) /* I - Parent node */ { markup_t element; /* Enclosing element, if any */ mmd_t *node; /* Current child node */ mmd_type_t type; /* Node type */ tree_t *block; /* Block node */ const char *align = NULL; /* Alignment */ switch (type = mmdGetType(parent)) { case MMD_TYPE_BLOCK_QUOTE : element = MARKUP_BLOCKQUOTE; break; case MMD_TYPE_ORDERED_LIST : element = MARKUP_OL; break; case MMD_TYPE_UNORDERED_LIST : element = MARKUP_UL; break; case MMD_TYPE_LIST_ITEM : element = MARKUP_LI; break; case MMD_TYPE_HEADING_1 : element = MARKUP_H1; break; case MMD_TYPE_HEADING_2 : element = MARKUP_H2; break; case MMD_TYPE_HEADING_3 : element = MARKUP_H3; break; case MMD_TYPE_HEADING_4 : element = MARKUP_H4; break; case MMD_TYPE_HEADING_5 : element = MARKUP_H5; break; case MMD_TYPE_HEADING_6 : element = MARKUP_H6; break; case MMD_TYPE_PARAGRAPH : element = MARKUP_P; break; case MMD_TYPE_CODE_BLOCK : block = htmlAddTree(html, MARKUP_PRE, NULL); for (node = mmdGetFirstChild(parent); node; node = mmdGetNextSibling(node)) htmlAddTree(block, MARKUP_NONE, get_text((uchar *)mmdGetText(node))); return; case MMD_TYPE_THEMATIC_BREAK : htmlAddTree(html, MARKUP_HR, NULL); return; case MMD_TYPE_TABLE : element = MARKUP_TABLE; break; case MMD_TYPE_TABLE_HEADER : element = MARKUP_THEAD; break; case MMD_TYPE_TABLE_BODY : element = MARKUP_TBODY; break; case MMD_TYPE_TABLE_ROW : element = MARKUP_TR; break; case MMD_TYPE_TABLE_HEADER_CELL : element = MARKUP_TH; break; case MMD_TYPE_TABLE_BODY_CELL_LEFT : element = MARKUP_TD; break; case MMD_TYPE_TABLE_BODY_CELL_CENTER : element = MARKUP_TD; align = "center"; break; case MMD_TYPE_TABLE_BODY_CELL_RIGHT : element = MARKUP_TD; align = "right"; break; default : element = MARKUP_NONE; break; } if (element != MARKUP_NONE) block = htmlAddTree(html, element, NULL); else block = html; if (align) { htmlSetVariable(block, (uchar *)"align", (uchar *)align); if (!strcmp(align, "center")) block->halignment = ALIGN_CENTER; else block->halignment = ALIGN_RIGHT; } else if (element == MARKUP_TH) { block->halignment = ALIGN_CENTER; htmlSetVariable(block, (uchar *)"bgcolor", (uchar *)"#cccccc"); } else if (element == MARKUP_TABLE) { htmlSetVariable(block, (uchar *)"border", (uchar *)"1"); htmlSetVariable(block, (uchar *)"cellpadding", (uchar *)"2"); } if (type >= MMD_TYPE_HEADING_1 && type <= MMD_TYPE_HEADING_6) { /* * Add an anchor for each heading... */ block = htmlAddTree(block, MARKUP_A, NULL); htmlSetVariable(block, (uchar *)"id", make_anchor(parent)); } if (type >= MMD_TYPE_TABLE_BODY_CELL_LEFT && type <= MMD_TYPE_TABLE_BODY_CELL_RIGHT && !mmdGetFirstChild(parent)) { // Make sure table body cells have at least a non-breaking space... htmlAddTree(block, MARKUP_NONE, (uchar *)" "); } else { for (node = mmdGetFirstChild(parent); node; node = mmdGetNextSibling(node)) { if (mmdIsBlock(node)) add_block(block, node); else add_leaf(block, node); } } } /* * 'add_leaf()' - Add a leaf node. */ static void add_leaf(tree_t *html, /* I - Parent HTML node */ mmd_t *node) /* I - Leaf node */ { tree_t *parent; /* HTML node for this text */ markup_t element; /* HTML element for this text */ uchar buffer[1024], /* Text with any added whitespace */ *text, /* Text to write */ *url; /* URL to write */ int whitespace; /* Whitespace before text? */ unsigned style; /* Style for node */ unsigned typeface; /* Typeface for node */ unsigned strikethrough; /* Struck-through text? */ style = html->style; strikethrough = html->strikethrough; typeface = html->typeface; text = get_text((uchar *)mmdGetText(node)); url = (uchar *)mmdGetURL(node); whitespace = mmdGetWhitespace(node); switch (mmdGetType(node)) { case MMD_TYPE_EMPHASIZED_TEXT : element = MARKUP_EM; style = STYLE_ITALIC; break; case MMD_TYPE_STRONG_TEXT : element = MARKUP_STRONG; style = STYLE_BOLD; break; case MMD_TYPE_STRUCK_TEXT : element = MARKUP_DEL; strikethrough = 1; break; case MMD_TYPE_LINKED_TEXT : element = MARKUP_A; break; case MMD_TYPE_CODE_TEXT : element = MARKUP_CODE; typeface = _htmlBodyFont >= TYPE_MONOSPACE ? TYPE_MONOSPACE : TYPE_COURIER; break; case MMD_TYPE_IMAGE : if (mmdGetWhitespace(node)) htmlAddTree(html, MARKUP_NONE, (uchar *)" "); parent = htmlAddTree(html, MARKUP_IMG, NULL); htmlSetVariable(parent, (uchar *)"src", url); if (text) htmlSetVariable(parent, (uchar *)"alt", text); return; case MMD_TYPE_HARD_BREAK : htmlAddTree(html, MARKUP_BR, NULL); return; case MMD_TYPE_SOFT_BREAK : htmlAddTree(html, MARKUP_WBR, NULL); return; case MMD_TYPE_METADATA_TEXT : return; default : element = MARKUP_NONE; break; } if (element == MARKUP_NONE) { parent = html; } else if ((parent = html->last_child) == NULL || parent->markup != element) { if (whitespace) { htmlAddTree(html, MARKUP_NONE, (uchar *)" "); whitespace = 0; } parent = htmlAddTree(html, element, NULL); parent->style = style; parent->strikethrough = strikethrough; parent->typeface = typeface; if (element == MARKUP_A && url) { if (!strcmp((char *)url, "@")) htmlSetVariable(parent, (uchar *)"href", make_anchor(text)); else htmlSetVariable(parent, (uchar *)"href", url); } } if (whitespace) { buffer[0] = ' '; strlcpy((char *)buffer + 1, (char *)text, sizeof(buffer) - 1); text = buffer; } htmlAddTree(parent, MARKUP_NONE, text); } /* * 'get_text()' - Get Markdown text in HTMLDOC's charset. */ static uchar * /* O - Encoded text */ get_text(uchar *text) /* I - Markdown text */ { uchar *bufptr, /* Pointer into buffer */ *bufend; /* End of buffer */ int unich; /* Unicode character */ static uchar buffer[8192]; /* Temporary buffer */ if (!_htmlUTF8) return (text); bufptr = buffer; bufend = buffer + sizeof(buffer) - 1; while (*text && bufptr < bufend) { if (*text & 0x80) { unich = 0; if ((*text & 0xe0) == 0xc0) { if ((text[1] & 0xc0) != 0x80) { progress_error(HD_ERROR_READ_ERROR, "Bad UTF-8 character sequence %02X %02X.", *text, text[1]); *bufptr++ = '?'; text ++; } else { unich = ((*text & 0x1f) << 6) | (text[1] & 0x3f); text += 2; } } else if ((*text & 0xf0) == 0xe0) { if ((text[1] & 0xc0) != 0x80 || (text[2] & 0xc0) != 0x80) { progress_error(HD_ERROR_READ_ERROR, "Bad UTF-8 character sequence %02X %02X %02X.", *text, text[1], text[2]); *bufptr++ = '?'; text ++; } else { unich = ((*text & 0x0f) << 12) | ((text[1] & 0x3f) << 6) | (text[2] & 0x3f); text += 3; } } else { progress_error(HD_ERROR_READ_ERROR, "Bad UTF-8 character sequence %02X.", *text); *bufptr++ = '?'; text ++; } if (unich) { uchar ch = htmlMapUnicode(unich); /* 8-bit character */ *bufptr++ = ch ? ch : '?'; } } else *bufptr++ = *text++; } *bufptr = '\0'; return (buffer); } /* * 'make_anchor()' - Make an anchor for internal links from a block node. */ static uchar * /* O - Anchor string */ make_anchor(mmd_t *block) /* I - Block node */ { mmd_t *node; /* Current child node */ const char *text; /* Text from block */ uchar *bufptr; /* Pointer into buffer */ static uchar buffer[1024]; /* Buffer for anchor string */ for (bufptr = buffer, node = mmdGetFirstChild(block); node; node = mmdGetNextSibling(node)) { if (mmdGetWhitespace(node) && bufptr < (buffer + sizeof(buffer) - 1)) *bufptr++ = '-'; for (text = mmdGetText(node); text && *text && bufptr < (buffer + sizeof(buffer) -1); text ++) { if ((*text >= '0' && *text <= '9') || (*text >= 'a' && *text <= 'z') || (*text >= 'A' && *text <= 'Z') || *text == '.' || *text == '-') *bufptr++ = (uchar)tolower(*text); else if (*text == ' ') *bufptr++ = '-'; } } *bufptr = '\0'; return (buffer); } /* * 'make_anchor()' - Make an anchor for internal links from text. */ static uchar * /* O - Anchor string */ make_anchor(const uchar *text) /* I - Text */ { uchar *bufptr; /* Pointer into buffer */ static uchar buffer[1024]; /* Buffer for anchor string */ for (bufptr = buffer; *text && bufptr < (buffer + sizeof(buffer) - 1); text ++) { if ((*text >= '0' && *text <= '9') || (*text >= 'a' && *text <= 'z') || (*text >= 'A' && *text <= 'Z') || *text == '.' || *text == '-') *bufptr++ = (uchar)tolower(*text); else if (*text == ' ') *bufptr++ = '-'; } *bufptr = '\0'; return (buffer); } htmldoc-1.9.20/htmldoc/markdown.h000066400000000000000000000011271472561501400166700ustar00rootroot00000000000000/* * Markdown parsing definitions for HTMLDOC, a HTML document processing program. * * Copyright 2017 by Michael R Sweet. * * This program is free software. Distribution and use rights are outlined in * the file "COPYING". */ #ifndef _MARKDOWN_H_ # define _MARKDOWN_H_ /* * Include necessary headers... */ # include "html.h" # include "mmd.h" # ifdef __cplusplus extern "C" { # endif /* __cplusplus */ /* * Prototypes... */ extern tree_t *mdReadFile(tree_t *parent, FILE *fp, const char *base); # ifdef __cplusplus } # endif /* __cplusplus */ #endif /* !_MARKDOWN_H_ */ htmldoc-1.9.20/htmldoc/md5-private.h000066400000000000000000000050401472561501400172010ustar00rootroot00000000000000/* * Private MD5 definitions for CUPS. * * Copyright 2007-2010 by Apple Inc. * Copyright 2005 by Easy Software Products * * Copyright (C) 1999 Aladdin Enterprises. All rights reserved. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. * * L. Peter Deutsch * ghost@aladdin.com */ /* Independent implementation of MD5 (RFC 1321). This code implements the MD5 Algorithm defined in RFC 1321. It is derived directly from the text of the RFC and not from the reference implementation. The original and principal author of md5.h is L. Peter Deutsch . Other authors are noted in the change history that follows (in reverse chronological order): 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); added conditionalization for C++ compilation from Martin Purschke . 1999-05-03 lpd Original version. */ #ifndef _CUPS_MD5_PRIVATE_H_ # define _CUPS_MD5_PRIVATE_H_ /* Define the state of the MD5 Algorithm. */ typedef struct _cups_md5_state_s { unsigned int count[2]; /* message length in bits, lsw first */ unsigned int abcd[4]; /* digest buffer */ unsigned char buf[64]; /* accumulate block */ } _cups_md5_state_t; # ifdef __cplusplus extern "C" { # endif /* __cplusplus */ /* Initialize the algorithm. */ void _cupsMD5Init(_cups_md5_state_t *pms); /* Append a string to the message. */ void _cupsMD5Append(_cups_md5_state_t *pms, const unsigned char *data, int nbytes); /* Finish the message and return the digest. */ void _cupsMD5Finish(_cups_md5_state_t *pms, unsigned char digest[16]); # ifdef __cplusplus } /* end extern "C" */ # endif /* __cplusplus */ #endif /* !_CUPS_MD5_PRIVATE_H_ */ htmldoc-1.9.20/htmldoc/md5.c000066400000000000000000000232741472561501400155350ustar00rootroot00000000000000/* * Private MD5 implementation for CUPS. * * Copyright 2007-2010 by Apple Inc. * Copyright 2005 by Easy Software Products * * Copyright (C) 1999 Aladdin Enterprises. All rights reserved. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. * * L. Peter Deutsch * ghost@aladdin.com */ /* Independent implementation of MD5 (RFC 1321). This code implements the MD5 Algorithm defined in RFC 1321. It is derived directly from the text of the RFC and not from the reference implementation. The original and principal author of md5.c is L. Peter Deutsch . Other authors are noted in the change history that follows (in reverse chronological order): 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). 1999-05-03 lpd Original version. */ #include "md5-private.h" #include #define T1 0xd76aa478 #define T2 0xe8c7b756 #define T3 0x242070db #define T4 0xc1bdceee #define T5 0xf57c0faf #define T6 0x4787c62a #define T7 0xa8304613 #define T8 0xfd469501 #define T9 0x698098d8 #define T10 0x8b44f7af #define T11 0xffff5bb1 #define T12 0x895cd7be #define T13 0x6b901122 #define T14 0xfd987193 #define T15 0xa679438e #define T16 0x49b40821 #define T17 0xf61e2562 #define T18 0xc040b340 #define T19 0x265e5a51 #define T20 0xe9b6c7aa #define T21 0xd62f105d #define T22 0x02441453 #define T23 0xd8a1e681 #define T24 0xe7d3fbc8 #define T25 0x21e1cde6 #define T26 0xc33707d6 #define T27 0xf4d50d87 #define T28 0x455a14ed #define T29 0xa9e3e905 #define T30 0xfcefa3f8 #define T31 0x676f02d9 #define T32 0x8d2a4c8a #define T33 0xfffa3942 #define T34 0x8771f681 #define T35 0x6d9d6122 #define T36 0xfde5380c #define T37 0xa4beea44 #define T38 0x4bdecfa9 #define T39 0xf6bb4b60 #define T40 0xbebfbc70 #define T41 0x289b7ec6 #define T42 0xeaa127fa #define T43 0xd4ef3085 #define T44 0x04881d05 #define T45 0xd9d4d039 #define T46 0xe6db99e5 #define T47 0x1fa27cf8 #define T48 0xc4ac5665 #define T49 0xf4292244 #define T50 0x432aff97 #define T51 0xab9423a7 #define T52 0xfc93a039 #define T53 0x655b59c3 #define T54 0x8f0ccc92 #define T55 0xffeff47d #define T56 0x85845dd1 #define T57 0x6fa87e4f #define T58 0xfe2ce6e0 #define T59 0xa3014314 #define T60 0x4e0811a1 #define T61 0xf7537e82 #define T62 0xbd3af235 #define T63 0x2ad7d2bb #define T64 0xeb86d391 static void _cups_md5_process(_cups_md5_state_t *pms, const unsigned char *data /*[64]*/) { unsigned int a = pms->abcd[0], b = pms->abcd[1], c = pms->abcd[2], d = pms->abcd[3]; unsigned int t; #ifndef ARCH_IS_BIG_ENDIAN # define ARCH_IS_BIG_ENDIAN 1 /* slower, default implementation */ #endif #if ARCH_IS_BIG_ENDIAN /* * On big-endian machines, we must arrange the bytes in the right * order. (This also works on machines of unknown byte order.) */ unsigned int X[16]; const unsigned char *xp = data; int i; for (i = 0; i < 16; ++i, xp += 4) X[i] = xp[0] + (unsigned)(xp[1] << 8) + (unsigned)(xp[2] << 16) + (unsigned)(xp[3] << 24); #else /* !ARCH_IS_BIG_ENDIAN */ /* * On little-endian machines, we can process properly aligned data * without copying it. */ unsigned int xbuf[16]; const unsigned int *X; if (!((data - (const unsigned char *)0) & 3)) { /* data are properly aligned */ X = (const unsigned int *)data; } else { /* not aligned */ memcpy(xbuf, data, 64); X = xbuf; } #endif #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) /* Round 1. */ /* Let [abcd k s i] denote the operation a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + F(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 0, 7, T1); SET(d, a, b, c, 1, 12, T2); SET(c, d, a, b, 2, 17, T3); SET(b, c, d, a, 3, 22, T4); SET(a, b, c, d, 4, 7, T5); SET(d, a, b, c, 5, 12, T6); SET(c, d, a, b, 6, 17, T7); SET(b, c, d, a, 7, 22, T8); SET(a, b, c, d, 8, 7, T9); SET(d, a, b, c, 9, 12, T10); SET(c, d, a, b, 10, 17, T11); SET(b, c, d, a, 11, 22, T12); SET(a, b, c, d, 12, 7, T13); SET(d, a, b, c, 13, 12, T14); SET(c, d, a, b, 14, 17, T15); SET(b, c, d, a, 15, 22, T16); #undef SET /* Round 2. */ /* Let [abcd k s i] denote the operation a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + G(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 1, 5, T17); SET(d, a, b, c, 6, 9, T18); SET(c, d, a, b, 11, 14, T19); SET(b, c, d, a, 0, 20, T20); SET(a, b, c, d, 5, 5, T21); SET(d, a, b, c, 10, 9, T22); SET(c, d, a, b, 15, 14, T23); SET(b, c, d, a, 4, 20, T24); SET(a, b, c, d, 9, 5, T25); SET(d, a, b, c, 14, 9, T26); SET(c, d, a, b, 3, 14, T27); SET(b, c, d, a, 8, 20, T28); SET(a, b, c, d, 13, 5, T29); SET(d, a, b, c, 2, 9, T30); SET(c, d, a, b, 7, 14, T31); SET(b, c, d, a, 12, 20, T32); #undef SET /* Round 3. */ /* Let [abcd k s t] denote the operation a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ #define H(x, y, z) ((x) ^ (y) ^ (z)) #define SET(a, b, c, d, k, s, Ti)\ t = a + H(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 5, 4, T33); SET(d, a, b, c, 8, 11, T34); SET(c, d, a, b, 11, 16, T35); SET(b, c, d, a, 14, 23, T36); SET(a, b, c, d, 1, 4, T37); SET(d, a, b, c, 4, 11, T38); SET(c, d, a, b, 7, 16, T39); SET(b, c, d, a, 10, 23, T40); SET(a, b, c, d, 13, 4, T41); SET(d, a, b, c, 0, 11, T42); SET(c, d, a, b, 3, 16, T43); SET(b, c, d, a, 6, 23, T44); SET(a, b, c, d, 9, 4, T45); SET(d, a, b, c, 12, 11, T46); SET(c, d, a, b, 15, 16, T47); SET(b, c, d, a, 2, 23, T48); #undef SET /* Round 4. */ /* Let [abcd k s t] denote the operation a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ #define I(x, y, z) ((y) ^ ((x) | ~(z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + I(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 0, 6, T49); SET(d, a, b, c, 7, 10, T50); SET(c, d, a, b, 14, 15, T51); SET(b, c, d, a, 5, 21, T52); SET(a, b, c, d, 12, 6, T53); SET(d, a, b, c, 3, 10, T54); SET(c, d, a, b, 10, 15, T55); SET(b, c, d, a, 1, 21, T56); SET(a, b, c, d, 8, 6, T57); SET(d, a, b, c, 15, 10, T58); SET(c, d, a, b, 6, 15, T59); SET(b, c, d, a, 13, 21, T60); SET(a, b, c, d, 4, 6, T61); SET(d, a, b, c, 11, 10, T62); SET(c, d, a, b, 2, 15, T63); SET(b, c, d, a, 9, 21, T64); #undef SET /* Then perform the following additions. (That is increment each of the four registers by the value it had before this block was started.) */ pms->abcd[0] += a; pms->abcd[1] += b; pms->abcd[2] += c; pms->abcd[3] += d; } void _cupsMD5Init(_cups_md5_state_t *pms) { pms->count[0] = pms->count[1] = 0; pms->abcd[0] = 0x67452301; pms->abcd[1] = 0xefcdab89; pms->abcd[2] = 0x98badcfe; pms->abcd[3] = 0x10325476; } void _cupsMD5Append(_cups_md5_state_t *pms, const unsigned char *data, int nbytes) { const unsigned char *p = data; int left = nbytes; int offset = (pms->count[0] >> 3) & 63; unsigned int nbits = (unsigned int)(nbytes << 3); if (nbytes <= 0) return; /* Update the message length. */ pms->count[1] += (unsigned)(nbytes >> 29); pms->count[0] += nbits; if (pms->count[0] < nbits) pms->count[1]++; /* Process an initial partial block. */ if (offset) { int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); memcpy(pms->buf + offset, p, copy); if (offset + copy < 64) return; p += copy; left -= copy; _cups_md5_process(pms, pms->buf); } /* Process full blocks. */ for (; left >= 64; p += 64, left -= 64) _cups_md5_process(pms, p); /* Process a final partial block. */ if (left) memcpy(pms->buf, p, left); } void _cupsMD5Finish(_cups_md5_state_t *pms, unsigned char digest[16]) { static const unsigned char pad[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; unsigned char data[8]; int i; /* Save the length before padding. */ for (i = 0; i < 8; ++i) data[i] = (unsigned char)(pms->count[i >> 2] >> ((i & 3) << 3)); /* Pad to 56 bytes mod 64. */ _cupsMD5Append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); /* Append the length. */ _cupsMD5Append(pms, data, 8); for (i = 0; i < 16; ++i) digest[i] = (unsigned char)(pms->abcd[i >> 2] >> ((i & 3) << 3)); } htmldoc-1.9.20/htmldoc/mmd.c000066400000000000000000001556361472561501400156350ustar00rootroot00000000000000// // Implementation of miniature markdown library. // // https://www.msweet.org/mmd // // Copyright © 2017-2024 by Michael R Sweet. // // Licensed under Apache License v2.0. See the file "LICENSE" for more // information. // // // Define DEBUG to get debug printf messages to stderr. // #define DEBUG 0 #if DEBUG > 0 # define DEBUG_printf(...) fprintf(stderr, __VA_ARGS__) # define DEBUG_puts(s) fputs(s, stderr); #else # define DEBUG_printf(...) # define DEBUG_puts(s) #endif // DEBUG > 0 #if DEBUG > 1 # define DEBUG2_printf(...) fprintf(stderr, __VA_ARGS__) # define DEBUG2_puts(s) fputs(s, stderr); #else # define DEBUG2_printf(...) # define DEBUG2_puts(s) #endif // DEBUG > 1 // // Beginning with VC2005, Microsoft breaks ISO C and POSIX conformance // by deprecating a number of functions in the name of security, even // when many of the affected functions are otherwise completely secure. // The _CRT_SECURE_NO_DEPRECATE definition ensures that we won't get // warnings from their use... // // Then Microsoft decided that they should ignore this in VC2008 and use // yet another define (_CRT_SECURE_NO_WARNINGS) instead... // #define _CRT_SECURE_NO_DEPRECATE #define _CRT_SECURE_NO_WARNINGS #if _WIN32 # define strcasecmp stricmp #endif // _WIN32 #include "mmd.h" #include #include #include // // Microsoft renames the POSIX functions to _name, and introduces a broken // compatibility layer using the original names. As a result, random crashes // can occur when, for example, strdup() allocates memory from a different heap // than used by malloc() and free(). // // To avoid moronic problems like this, we #define the POSIX function names to // the corresponding non-standard Microsoft names. // #ifdef _WIN32 # define snprintf _snprintf # define strdup _strdup #endif // _WIN32 // // Private structures... // struct _mmd_s { mmd_type_t type; // Node type bool whitespace; // Leading whitespace? char *text, // Text *url, // Reference URL (image/link/etc.) *extra; // Title, language name, etc. mmd_t *parent, // Parent node *first_child, // First child node *last_child, // Last child node *prev_sibling, // Previous sibling node *next_sibling; // Next sibling node }; typedef struct _mmd_filebuf_s // Buffered file { mmd_iocb_t cb; // Read callback function void *cbdata; // Read callback data char buffer[65536], // Buffer *bufptr, // Pointer into buffer *bufend; // End of buffer } _mmd_filebuf_t; typedef struct _mmd_ref_s // Reference link { char *name, // Name of reference *url, // Reference URL *title; // Title, if any size_t num_pending; // Number of pending nodes mmd_t **pending; // Pending nodes } _mmd_ref_t; typedef struct _mmd_doc_s // Markdown document { mmd_t *root; // Root node size_t num_references; // Number of references _mmd_ref_t *references; // References } _mmd_doc_t; typedef struct _mmd_stack_s // Markdown block stack { mmd_t *parent; // Parent node int indent; // Indentation char fence; // Code fence character size_t fencelen; // Length of code fence } _mmd_stack_t; // // Local globals... // static mmd_option_t mmd_options = MMD_OPTION_ALL; // Markdown extensions to support // // Local functions... // static mmd_t *mmd_add(mmd_t *parent, mmd_type_t type, int whitespace, char *text, char *url); static void mmd_free(mmd_t *node); static int mmd_has_continuation(const char *line, _mmd_filebuf_t *file, int indent); static size_t mmd_iocb_file(FILE *fp, char *buffer, size_t bytes); static size_t mmd_iocb_string(const char **s, char *buffer, size_t bytes); static size_t mmd_is_chars(const char *lineptr, const char *chars, size_t minchars); static size_t mmd_is_codefence(char *lineptr, char fence, size_t fencelen, char **language); static bool mmd_is_table(_mmd_filebuf_t *file, int indent); static void mmd_parse_inline(_mmd_doc_t *doc, mmd_t *parent, char *lineptr); static char *mmd_parse_link(_mmd_doc_t *doc, char *lineptr, char **text, char **url, char **title, char **refname); static void mmd_read_buffer(_mmd_filebuf_t *file); static char *mmd_read_line(_mmd_filebuf_t *file, char *line, size_t linesize); static void mmd_ref_add(_mmd_doc_t *doc, mmd_t *node, const char *name, const char *url, const char *title); static _mmd_ref_t *mmd_ref_find(_mmd_doc_t *doc, const char *name); static void mmd_remove(mmd_t *node); #if DEBUG static const char *mmd_type_string(mmd_type_t type); #endif // DEBUG // // 'mmdCopyAllText()' - Make a copy of all the text under a given node. // // The returned string must be freed using free(). // char * // O - Copied string mmdCopyAllText(mmd_t *node) // I - Parent node { char *all = NULL, // String buffer *allptr = NULL, // Pointer into string buffer *temp; // Temporary pointer size_t allsize = 0, // Size of "all" buffer textlen; // Length of "text" string mmd_t *current, // Current node *next; // Next node current = mmdGetFirstChild(node); while (current != node) { if (current->text) { // Append this node's text to the string... textlen = strlen(current->text); allsize += textlen + (size_t)current->whitespace; temp = realloc(all, allsize); if (!temp) { free(all); return (NULL); } allptr = temp + (allptr - all); all = temp; if (current->whitespace) *allptr++ = ' '; memcpy(allptr, current->text, textlen); allptr += textlen; } // Find the next logical node... if ((next = mmdGetNextSibling(current)) == NULL) { next = mmdGetParent(current); while (next && next != node && mmdGetNextSibling(next) == NULL) next = mmdGetParent(next); if (next != node) next = mmdGetNextSibling(next); } current = next; } if (allptr) *allptr = '\0'; return (all); } // // 'mmdFree()' - Free a markdown tree. // void mmdFree(mmd_t *node) // I - First node { mmd_t *current, // Current node *next; // Next node mmd_remove(node); for (current = node->first_child; current; current = next) { // Get the next node... if ((next = current->first_child) != NULL) { // Free parent nodes after child nodes have been freed... current->first_child = NULL; continue; } if ((next = current->next_sibling) == NULL) { // Next node is the parent, which we'll free as needed... if ((next = current->parent) == node) next = NULL; } // Free child... mmd_free(current); } // Then free the memory used by the parent node... mmd_free(node); } // // 'mmdGetExtra()' - Get extra text (title, language, etc.) associated with a // node. // const char * // O - Extra text or NULL if none mmdGetExtra(mmd_t *node) // I - Node { return (node ? node->extra : NULL); } // // 'mmdGetFirstChild()' - Return the first child of a node, if any. // mmd_t * // O - First child or @code NULL@ if none mmdGetFirstChild(mmd_t *node) // I - Node { return (node ? node->first_child : NULL); } // // 'mmdGetLastChild()' - Return the last child of a node, if any. // mmd_t * // O - Last child or @code NULL@ if none mmdGetLastChild(mmd_t *node) // I - Node { return (node ? node->last_child : NULL); } // // 'mmdGetMetadata()' - Return the metadata for the given keyword. // const char * // O - Value or @code NULL@ if none mmdGetMetadata(mmd_t *doc, // I - Document const char *keyword) // I - Keyword { mmd_t *metadata, // Metadata node *current; // Current node char prefix[256]; // Prefix string size_t prefix_len; // Length of prefix string const char *value; // Pointer to value if (!doc || (metadata = doc->first_child) == NULL || metadata->type != MMD_TYPE_METADATA) return (NULL); snprintf(prefix, sizeof(prefix), "%s:", keyword); prefix_len = strlen(prefix); for (current = metadata->first_child; current; current = current->next_sibling) { if (strncmp(current->text, prefix, prefix_len)) continue; value = current->text + prefix_len; while (isspace(*value & 255)) value ++; return (value); } return (NULL); } // // 'mmdGetNextSibling()' - Return the next sibling of a node, if any. // mmd_t * // O - Next sibling or @code NULL@ if none mmdGetNextSibling(mmd_t *node) // I - Node { return (node ? node->next_sibling : NULL); } // // 'mmdGetOptions()' - Get the enabled markdown processing options/extensions. // mmd_option_t // O - Enabled options mmdGetOptions(void) { return (mmd_options); } // // 'mmdGetParent()' - Return the parent of a node, if any. // mmd_t * // O - Parent node or @code NULL@ if none mmdGetParent(mmd_t *node) // I - Node { return (node ? node->parent : NULL); } // // 'mmdGetPrevSibling()' - Return the previous sibling of a node, if any. // mmd_t * // O - Previous sibling or @code NULL@ if none mmdGetPrevSibling(mmd_t *node) // I - Node { return (node ? node->prev_sibling : NULL); } // // 'mmdGetText()' - Return the text associated with a node, if any. // const char * // O - Text or @code NULL@ if none mmdGetText(mmd_t *node) // I - Node { return (node ? node->text : NULL); } // // 'mmdGetType()' - Return the type of a node, if any. // mmd_type_t // O - Type or @code MMD_TYPE_NONE@ if none mmdGetType(mmd_t *node) // I - Node { return (node ? node->type : MMD_TYPE_NONE); } // // 'mmdGetURL()' - Return the URL associated with a node, if any. // const char * // O - URL or @code NULL@ if none mmdGetURL(mmd_t *node) // I - Node { return (node ? node->url : NULL); } // // 'mmdGetWhitespace()' - Return whether whitespace preceded a node. // bool // O - `true` for leading whitespace, `false` for none mmdGetWhitespace(mmd_t *node) // I - Node { return (node ? node->whitespace : false); } // // 'mmdIsBlock()' - Return whether the node is a block. // bool // O - `true` for block nodes, `false` otherwise mmdIsBlock(mmd_t *node) // I - Node { return (node ? node->type < MMD_TYPE_NORMAL_TEXT : false); } // // 'mmdLoad()' - Load a markdown file into nodes. // mmd_t * // O - Root node in markdown mmdLoad(mmd_t *root, // I - Root node for document or `NULL` for a new document const char *filename) // I - File to load { FILE *fp; // File // Open the file and load the document... if ((fp = fopen(filename, "r")) == NULL) return (NULL); root = mmdLoadIO(root, (mmd_iocb_t)mmd_iocb_file, fp); // Close and return... fclose(fp); return (root); } // // 'mmdLoadFile()' - Load a markdown file into nodes from a stdio file. // mmd_t * // O - First node in markdown mmdLoadFile(mmd_t *root, // I - Root node for document or `NULL` for a new document FILE *fp) // I - File to load { return (mmdLoadIO(root, (mmd_iocb_t)mmd_iocb_file, fp)); } // // 'mmdLoadIO()' - Load a markdown file into nodes using a callback. // mmd_t * // O - First node in markdown mmdLoadIO(mmd_t *root, // I - Root node for document or `NULL` for a new document mmd_iocb_t cb, // I - Read callback function void *cbdata) // I - Read callback data { size_t i; // Looping var _mmd_doc_t doc; // Document _mmd_ref_t *reference; // Current reference mmd_t *block = NULL; // Current block mmd_type_t type; // Type for line _mmd_filebuf_t file; // File buffer char line[8192], // Read line *linestart, // Start of line *lineptr, // Pointer into line *lineend, // End of line *temp; // Temporary pointer int newindent; // New indentation int blank_code = 0; // Saved indented blank code line mmd_type_t columns[256]; // Alignment of table columns int num_columns = 0, // Number of columns in table rows = 0; // Number of rows in table _mmd_stack_t stack[32], // Block stack *stackptr = stack; // Pointer to top of stack // Create an empty document as needed... DEBUG_printf("mmdLoadIO: mmd_options=%d%s%s\n", mmd_options, (mmd_options & MMD_OPTION_METADATA) ? " METADATA" : "", (mmd_options & MMD_OPTION_TABLES) ? " TABLES" : ""); memset(&doc, 0, sizeof(doc)); if (root) doc.root = root; else doc.root = mmd_add(NULL, MMD_TYPE_DOCUMENT, 0, NULL, NULL); if (!doc.root) return (NULL); // Initialize the block stack... memset(stack, 0, sizeof(stack)); stackptr->parent = doc.root; // Read lines until end-of-file... memset(&file, 0, sizeof(file)); file.cb = cb; file.cbdata = cbdata; #ifdef __clang_analyzer__ memset(line, 0, sizeof(line)); #endif // __clang_analyzer__ while ((lineptr = mmd_read_line(&file, line, sizeof(line))) != NULL) { DEBUG_printf("%03d %-12s %s", stackptr->indent, mmd_type_string(stackptr->parent->type) + 9, lineptr); #if DEBUG if (stackptr->parent->type == MMD_TYPE_CODE_BLOCK) DEBUG2_printf(" blank_code=%d\n", blank_code); #endif // DEBUG linestart = lineptr; while (isspace(*lineptr & 255)) lineptr ++; DEBUG2_printf(" line indent=%d\n", (int)(lineptr - line)); DEBUG2_printf(" stackptr=%d\n", (int)(stackptr - stack)); if (!*lineptr && stackptr->parent->type == MMD_TYPE_TABLE) { DEBUG2_puts("END TABLE\n"); stackptr --; block = NULL; continue; } else if (*lineptr == '>' && (lineptr - linestart) < 4) { // Block quote. See if there is an existing blockquote... DEBUG_printf(" BLOCKQUOTE (stackptr=%ld)\n", stackptr - stack); if (stackptr == stack || stack[1].parent->type != MMD_TYPE_BLOCK_QUOTE) { block = NULL; stackptr = stack + 1; stackptr->parent = mmd_add(doc.root, MMD_TYPE_BLOCK_QUOTE, 0, NULL, NULL); stackptr->indent = 2; stackptr->fence = '\0'; } // Skip whitespace after the ">"... lineptr ++; if (isspace(*lineptr & 255)) lineptr ++; linestart = lineptr; while (isspace(*lineptr & 255)) lineptr ++; } else if (*lineptr != '>' && stackptr > stack && stack[1].parent->type == MMD_TYPE_BLOCK_QUOTE && (!block || *lineptr == '\n' || mmd_is_chars(lineptr, "- \t", 3) || mmd_is_chars(lineptr, "_ \t", 3) || mmd_is_chars(lineptr, "* \t", 3))) { // Not a lazy continuation so terminate this block quote... DEBUG_puts(" Terminating BLOCKQUOTE\n"); block = NULL; stackptr = stack; } // Now handle all other markup not related to block quotes... DEBUG2_printf(" stackptr=%d (%s), block=%p (%s)\n", (int)(stackptr - stack), mmd_type_string(stackptr->parent->type) + 9, block, block ? mmd_type_string(block->type) + 9 : ""); DEBUG2_printf(" strchr(lineptr, '|')=%p, mmd_is_table(&file, stackptr->indent)=%d\n", strchr(lineptr, '|'), mmd_is_table(&file, stackptr->indent)); DEBUG2_printf(" linestart=%d, lineptr=%d\n", (int)(linestart - line), (int)(lineptr - line)); DEBUG2_printf(" mmd_is_chars(lineptr, \"-\", 1)=%d\n", (int)mmd_is_chars(lineptr, "-", 1)); DEBUG2_printf(" mmd_is_chars(lineptr, \"=\", 1)=%d\n", (int)mmd_is_chars(lineptr, "=", 1)); if ((lineptr - line - stackptr->indent) < 4 && ((stackptr->parent->type != MMD_TYPE_CODE_BLOCK && !stackptr->fence && mmd_is_codefence(lineptr, '\0', 0, NULL)) || (stackptr->fence && mmd_is_codefence(lineptr, stackptr->fence, stackptr->fencelen, NULL)))) { // Code fence... DEBUG2_printf("stackptr->indent=%d, fence='%c', fencelen=%d\n", stackptr->indent, stackptr->fence, (int)stackptr->fencelen); if (stackptr->parent->type == MMD_TYPE_CODE_BLOCK) { DEBUG2_puts("Ending code block...\n"); stackptr --; } else if (stackptr < (stack + sizeof(stack) / sizeof(stack[0]) - 1)) { char *language; // Language name, if any DEBUG2_printf("Starting code block with fence '%c'.\n", *lineptr); block = NULL; stackptr[1].parent = mmd_add(stackptr->parent, MMD_TYPE_CODE_BLOCK, 0, NULL, NULL); stackptr[1].indent = lineptr - line; stackptr[1].fence = *lineptr; stackptr[1].fencelen = mmd_is_codefence(lineptr, '\0', 0, &language); stackptr ++; DEBUG2_printf("Code language=\"%s\"\n", language); if (language) stackptr->parent->extra = strdup(language); blank_code = 0; } continue; } else if (stackptr->parent->type == MMD_TYPE_CODE_BLOCK && (lineptr - line) >= stackptr->indent) { if (line[stackptr->indent] == '\n') { blank_code ++; } else { while (blank_code > 0) { mmd_add(stackptr->parent, MMD_TYPE_CODE_TEXT, 0, "\n", NULL); blank_code --; } mmd_add(stackptr->parent, MMD_TYPE_CODE_TEXT, 0, line + stackptr->indent, NULL); } continue; } else if (stackptr->parent->type == MMD_TYPE_CODE_BLOCK && stackptr->fence) { DEBUG2_printf(" fence='%c'\n", stackptr->fence); if (!*lineptr) { blank_code ++; } else { while (blank_code > 0) { mmd_add(stackptr->parent, MMD_TYPE_CODE_TEXT, 0, "\n", NULL); blank_code --; } mmd_add(stackptr->parent, MMD_TYPE_CODE_TEXT, 0, lineptr, NULL); } continue; } else if (!strncmp(lineptr, "---", 3) && doc.root->first_child == NULL && (mmd_options & MMD_OPTION_METADATA)) { // Document metadata... block = mmd_add(doc.root, MMD_TYPE_METADATA, 0, NULL, NULL); while ((lineptr = mmd_read_line(&file, line, sizeof(line))) != NULL) { while (isspace(*lineptr & 255)) lineptr ++; if (!strncmp(lineptr, "---", 3) || !strncmp(lineptr, "...", 3)) break; lineend = lineptr + strlen(lineptr) - 1; if (lineend > lineptr && *lineend == '\n') *lineend = '\0'; mmd_add(block, MMD_TYPE_METADATA_TEXT, 0, lineptr, NULL); } continue; } else if (block && block->type == MMD_TYPE_PARAGRAPH && (lineptr - linestart) < 4 && (lineptr - line) >= stackptr->indent && (mmd_is_chars(lineptr, "-", 1) || mmd_is_chars(lineptr, "=", 1))) { int ch = *lineptr; DEBUG_puts(" SETEXT HEADING\n"); lineptr += 3; while (*lineptr == ch) lineptr ++; while (isspace(*lineptr & 255)) lineptr ++; if (!*lineptr) { if (ch == '=') block->type = MMD_TYPE_HEADING_1; else block->type = MMD_TYPE_HEADING_2; block = NULL; continue; } type = MMD_TYPE_PARAGRAPH; } else if ((lineptr - linestart) < 4 && (mmd_is_chars(lineptr, "- \t", 3) || mmd_is_chars(lineptr, "_ \t", 3) || mmd_is_chars(lineptr, "* \t", 3))) { DEBUG_puts(" THEMATIC BREAK\n"); if (line[0] == '>') stackptr = stack + 1; else stackptr = stack; mmd_add(stackptr->parent, MMD_TYPE_THEMATIC_BREAK, 0, NULL, NULL); // type = MMD_TYPE_PARAGRAPH; block = NULL; continue; } else if ((*lineptr == '-' || *lineptr == '+' || *lineptr == '*') && (lineptr[1] == '\t' || lineptr[1] == ' ')) { // Bulleted list... DEBUG_puts(" UNORDERED LIST\n"); lineptr += 2; linestart = lineptr; newindent = linestart - line; while (isspace(*lineptr & 255)) lineptr ++; while (stackptr > stack && stackptr->indent > newindent) stackptr --; if (stackptr > stack && stackptr->parent->type == MMD_TYPE_LIST_ITEM && stackptr->indent == newindent) stackptr --; if (stackptr > stack && stackptr->parent->type == MMD_TYPE_ORDERED_LIST && stackptr->indent == newindent) stackptr --; if (stackptr > stack && stackptr->parent->type == MMD_TYPE_BLOCK_QUOTE && line[0] != '>') stackptr --; if (stackptr->parent->type != MMD_TYPE_UNORDERED_LIST && stackptr < (stack + sizeof(stack) / sizeof(stack[0]) - 1)) { stackptr[1].parent = mmd_add(stackptr->parent, MMD_TYPE_UNORDERED_LIST, 0, NULL, NULL); stackptr[1].indent = linestart - line; stackptr[1].fence = '\0'; stackptr ++; } if (stackptr < (stack + sizeof(stack) / sizeof(stack[0]) - 1)) { stackptr[1].parent = mmd_add(stackptr->parent, MMD_TYPE_LIST_ITEM, 0, NULL, NULL); stackptr[1].indent = linestart - line; stackptr[1].fence = '\0'; stackptr ++; } type = MMD_TYPE_PARAGRAPH; block = NULL; if (mmd_is_chars(lineptr, "- \t", 3) || mmd_is_chars(lineptr, "_ \t", 3) || mmd_is_chars(lineptr, "* \t", 3)) { mmd_add(stackptr->parent, MMD_TYPE_THEMATIC_BREAK, 0, NULL, NULL); continue; } } else if (isdigit(*lineptr & 255)) { // Ordered list? DEBUG_puts(" ORDERED LIST?\n"); temp = lineptr + 1; while (isdigit(*temp & 255)) temp ++; if ((*temp == '.' || *temp == ')') && (temp[1] == '\t' || temp[1] == ' ')) { // Yes, ordered list. lineptr = temp + 2; linestart = lineptr; newindent = linestart - line; while (isspace(*lineptr & 255)) lineptr ++; while (stackptr > stack && stackptr->indent > newindent) stackptr --; if (stackptr->parent->type == MMD_TYPE_LIST_ITEM && stackptr->indent == newindent) stackptr --; if (stackptr->parent->type == MMD_TYPE_UNORDERED_LIST && stackptr->indent == newindent) stackptr --; if (stackptr->parent->type == MMD_TYPE_BLOCK_QUOTE && line[0] != '>') stackptr --; if (stackptr->parent->type != MMD_TYPE_ORDERED_LIST && stackptr < (stack + sizeof(stack) / sizeof(stack[0]) - 1)) { stackptr[1].parent = mmd_add(stackptr->parent, MMD_TYPE_ORDERED_LIST, 0, NULL, NULL); stackptr[1].indent = linestart - line; stackptr[1].fence = '\0'; stackptr ++; } if (stackptr < (stack + sizeof(stack) / sizeof(stack[0]) - 1)) { stackptr[1].parent = mmd_add(stackptr->parent, MMD_TYPE_LIST_ITEM, 0, NULL, NULL); stackptr[1].indent = linestart - line; stackptr[1].fence = '\0'; stackptr ++; } type = MMD_TYPE_PARAGRAPH; block = NULL; } else { // No, just a regular paragraph... type = block ? block->type : MMD_TYPE_PARAGRAPH; } } else if (*lineptr == '#' && (lineptr - linestart) < 4) { // Heading, count the number of '#' for the heading level... DEBUG_puts(" HEADING?\n"); newindent = lineptr - line; temp = lineptr + 1; while (*temp == '#') temp ++; if ((temp - lineptr) <= 6 && isspace(*temp & 255)) { // Heading 1-6... type = MMD_TYPE_HEADING_1 + (temp - lineptr - 1); block = NULL; // Skip whitespace after "#"... lineptr = temp; while (isspace(*lineptr & 255)) lineptr ++; linestart = lineptr; // Strip trailing "#" characters and whitespace... temp = lineptr + strlen(lineptr) - 1; while (temp > lineptr && isspace(*temp & 255)) *temp-- = '\0'; while (temp > lineptr && *temp == '#') temp --; if (isspace(*temp & 255)) { while (temp > lineptr && isspace(*temp & 255)) *temp-- = '\0'; } else if (temp == lineptr) *temp = '\0'; while (stackptr > stack && stackptr->indent > newindent) stackptr --; block = mmd_add(stackptr->parent, type, 0, NULL, NULL); } else { // More than 6 #'s, just treat as a paragraph... type = MMD_TYPE_PARAGRAPH; } } else if (block && block->type >= MMD_TYPE_HEADING_1 && block->type <= MMD_TYPE_HEADING_6) { DEBUG_puts(" PARAGRAPH\n"); type = MMD_TYPE_PARAGRAPH; block = NULL; } else if (!block) { type = MMD_TYPE_PARAGRAPH; if (lineptr == line && stackptr->parent->type != MMD_TYPE_TABLE) stackptr = stack; } else type = block->type; if (!*lineptr) { if (stackptr->parent->type == MMD_TYPE_CODE_BLOCK) blank_code ++; else if (stackptr->parent->type == MMD_TYPE_BLOCK_QUOTE && line[0] != '>') stackptr --; block = NULL; continue; } else if (!strcmp(lineptr, "+")) { if (block) { if (block->type == MMD_TYPE_LIST_ITEM) block = mmd_add(block, MMD_TYPE_PARAGRAPH, 0, NULL, NULL); else if (block->parent->type == MMD_TYPE_LIST_ITEM) block = mmd_add(block->parent, MMD_TYPE_PARAGRAPH, 0, NULL, NULL); else block = NULL; } continue; } else if ((mmd_options & MMD_OPTION_TABLES) && strchr(lineptr, '|') && (stackptr->parent->type == MMD_TYPE_TABLE || mmd_is_table(&file, stackptr->indent))) { // Table... int col; // Current column char *start, // Start of column/cell *end; // End of column/cell mmd_t *row = NULL, // Current row *cell; // Current cell DEBUG2_printf("TABLE stackptr->parent=%p (%d), rows=%d\n", stackptr->parent, stackptr->parent->type, rows); if (stackptr->parent->type != MMD_TYPE_TABLE && stackptr < (stack + sizeof(stack) / sizeof(stack[0]) - 1)) { DEBUG2_printf("ADDING NEW TABLE to %p (%s)\n", stackptr->parent, mmd_type_string(stackptr->parent->type)); stackptr[1].parent = mmd_add(stackptr->parent, MMD_TYPE_TABLE, 0, NULL, NULL); stackptr[1].indent = stackptr->indent; stackptr[1].fence = '\0'; stackptr ++; block = mmd_add(stackptr->parent, MMD_TYPE_TABLE_HEADER, 0, NULL, NULL); for (col = 0; col < (int)(sizeof(columns) / sizeof(columns[0])); col ++) columns[col] = MMD_TYPE_TABLE_BODY_CELL_LEFT; num_columns = 0; rows = -1; } else if (rows > 0) { if (rows == 1) block = mmd_add(stackptr->parent, MMD_TYPE_TABLE_BODY, 0, NULL, NULL); } else block = NULL; if (block) row = mmd_add(block, MMD_TYPE_TABLE_ROW, 0, NULL, NULL); if (*lineptr == '|') lineptr ++; // Skip leading pipe if ((end = lineptr + strlen(lineptr) - 1) > lineptr) { while ((*end == '\n' || *end == 'r') && end > lineptr) end --; if (end > lineptr && *end == '|') *end = '\0'; // Truncate trailing pipe } for (col = 0; lineptr && *lineptr && col < (int)(sizeof(columns) / sizeof(columns[0])); col ++) { // Get the bounds of the stackptr->parent cell... start = lineptr; if ((lineptr = strchr(lineptr + 1, '|')) != NULL) *lineptr++ = '\0'; if (block) { // Add a cell to this row... if (block->type == MMD_TYPE_TABLE_HEADER) cell = mmd_add(row, MMD_TYPE_TABLE_HEADER_CELL, 0, NULL, NULL); else cell = mmd_add(row, columns[col], 0, NULL, NULL); mmd_parse_inline(&doc, cell, start); } else { // Process separator row for alignment... while (isspace(*start & 255)) start ++; for (end = start + strlen(start) - 1; end > start && isspace(*end & 255); end --) ; // Find the last non-space character if (*start == ':' && *end == ':') columns[col] = MMD_TYPE_TABLE_BODY_CELL_CENTER; else if (*end == ':') columns[col] = MMD_TYPE_TABLE_BODY_CELL_RIGHT; DEBUG2_printf("COLUMN %d SEPARATOR=\"%s\", TYPE=%d\n", col, start, columns[col]); } } // Make sure the table is balanced... if (col > num_columns) { num_columns = col; } else if (block && block->type != MMD_TYPE_TABLE_HEADER) { while (col < num_columns) { mmd_add(row, columns[col], 0, NULL, NULL); col ++; } } rows ++; continue; } else if (stackptr->parent->type == MMD_TYPE_TABLE) { DEBUG2_puts("END TABLE\n"); stackptr --; block = NULL; } if (stackptr->parent->type != MMD_TYPE_CODE_BLOCK && (!block || block->type == MMD_TYPE_CODE_BLOCK) && (lineptr - linestart) >= (stackptr->indent + 4)) { // Indented code block. if (stackptr->parent->type != MMD_TYPE_CODE_BLOCK && stackptr < (stack + sizeof(stack) / sizeof(stack[0]) - 1)) { stackptr[1].parent = mmd_add(stackptr->parent, MMD_TYPE_CODE_BLOCK, 0, NULL, NULL); stackptr[1].indent = stackptr->indent + 4; stackptr[1].fence = '\0'; stackptr ++; blank_code = 0; } while (blank_code > 0) { mmd_add(stackptr->parent, MMD_TYPE_CODE_TEXT, 0, "\n", NULL); blank_code --; } mmd_add(stackptr->parent, MMD_TYPE_CODE_TEXT, 0, line + stackptr->indent, NULL); continue; } if (!block || block->type != type) { if (stackptr->parent->type == MMD_TYPE_CODE_BLOCK) stackptr --; block = mmd_add(stackptr->parent, type, 0, NULL, NULL); } // Read continuation lines before parsing this... while (mmd_has_continuation(line, &file, stackptr->indent)) { char *ptr = line + strlen(line); if (!mmd_read_line(&file, ptr, sizeof(line) - (size_t)(ptr - line))) break; else if (line[0] == '>' && *ptr == '>') memmove(ptr, ptr + 1, strlen(ptr)); } mmd_parse_inline(&doc, block, lineptr); if (block->type == MMD_TYPE_PARAGRAPH && !block->first_child) { mmd_remove(block); mmd_free(block); block = NULL; } } // Free any references... for (i = doc.num_references, reference = doc.references; i > 0; i --, reference ++) { if (reference->pending) { char text[8192]; // Reference text size_t j; // Looping var DEBUG2_printf("Clearing links for '%s'.\n", reference->name); snprintf(text, sizeof(text), "[%s]", reference->name); for (j = 0; j < reference->num_pending; j ++) { free(reference->pending[j]->text); reference->pending[j]->text = strdup(text); reference->pending[j]->type = MMD_TYPE_NORMAL_TEXT; } free(reference->pending); } free(reference->name); free(reference->url); } free(doc.references); // Return the root node... return (doc.root); } // // 'mmdLoadString()' - Load a markdown string into nodes. // mmd_t * // O - Root node in markdown mmdLoadString(mmd_t *root, // I - Root node for document or `NULL` for a new document const char *s) // I - String to load { return (mmdLoadIO(root, (mmd_iocb_t)mmd_iocb_string, &s)); } // // 'mmdSetOptions()' - Set (enable/disable) support for various markdown options. // void mmdSetOptions(mmd_option_t options) // I - Options { mmd_options = options; } // // 'mmd_add()' - Add a new markdown node. // static mmd_t * // O - New node mmd_add(mmd_t *parent, // I - Parent node mmd_type_t type, // I - Node type int whitespace, // I - 1 if whitespace precedes this node char *text, // I - Text, if any char *url) // I - URL, if any { mmd_t *temp; // New node DEBUG2_printf("Adding %s to %p(%s), whitespace=%d, text=\"%s\", url=\"%s\"\n", mmd_type_string(type), parent, parent ? mmd_type_string(parent->type) : "", whitespace, text ? text : "(null)", url ? url : "(null)"); if (!parent && type != MMD_TYPE_DOCUMENT) return (NULL); // Only document nodes can be at the root if ((temp = calloc(1, sizeof(mmd_t))) != NULL) { if (parent) { // Add node to the parent... temp->parent = parent; if (parent->last_child) { parent->last_child->next_sibling = temp; temp->prev_sibling = parent->last_child; parent->last_child = temp; } else { parent->first_child = parent->last_child = temp; } } // Copy the node values... temp->type = type; temp->whitespace = whitespace; if (text) temp->text = strdup(text); if (url) temp->url = strdup(url); } return (temp); } // // 'mmd_free()' - Free memory used by a node. // static void mmd_free(mmd_t *node) // I - Node { free(node->text); free(node->url); free(node->extra); free(node); } // // 'mmd_has_continuation()' - Determine whether the next line is a continuation // of the current one. // static int // O - 1 if the next line continues, 0 otherwise mmd_has_continuation( const char *line, // I - Current line _mmd_filebuf_t *file, // I - File buffer int indent) // I - Indentation for current block { const char *lineptr = line; // Pointer into current line const char *fileptr = file->bufptr;// Pointer into next line if (*fileptr == '\n' || *fileptr == '\r') return (0); do { while (isspace(*lineptr & 255)) lineptr ++; if (*lineptr == '[' && (lineptr - line - indent) < 4 && (*fileptr == ' ' || *fileptr == '\t')) return (1); while (isspace(*fileptr & 255)) fileptr ++; if (*lineptr == '>' && *fileptr == '>') { lineptr ++; fileptr ++; } else if (*fileptr == '>') return (0); if (*fileptr == '\n' || *fileptr == '\r') return (0); } while (isspace(*lineptr & 255) || isspace(*fileptr & 255)); if (*lineptr == '#') return (0); if (strchr("-+*", *fileptr) && isspace(fileptr[1] & 255)) { // Bullet list item... return (0); } if (isdigit(*fileptr & 255)) { // Ordered list item... while (*fileptr && isdigit(*fileptr & 255)) fileptr ++; if (*fileptr == '.' || *fileptr == '(') return (0); } if (mmd_is_codefence((char *)fileptr, '\0', 0, NULL)) return (0); if (mmd_is_chars(fileptr, "- \t", 3) || mmd_is_chars(fileptr, "_ \t", 3) || mmd_is_chars(fileptr, "* \t", 3)) { // Thematic break... return (0); } if (mmd_is_chars(fileptr, "-", 1) || mmd_is_chars(fileptr, "=", 1)) { // Heading... return (0); } if (*fileptr == '#') { // Possible heading... int count = 0; while (*fileptr == '#') { fileptr ++; count ++; } if (count <= 6) return (0); } return ((fileptr - file->bufptr) <= indent); } // // 'mmd_iocb_file()' - Read from a file. // static size_t // O - Number of bytes read mmd_iocb_file(FILE *fp, // I - File pointer char *buffer, // I - Buffer size_t bytes) // I - Number of bytes to read { return (fread(buffer, 1, bytes, fp)); } // // 'mmd_iocb_string()' - Read from a string. // static size_t // O - Number of bytes read mmd_iocb_string(const char **s, // I - Pointer into string char *buffer, // I - Buffer size_t bytes) // I - Number of bytes to read { size_t ret; // Bytes read/returned // See how many bytes remain in the string... if ((ret = strlen(*s)) > bytes) ret = bytes; if (ret > 0) { // Copy bytes from the string... memcpy(buffer, *s, ret); (*s) += ret; } return (ret); } // // 'mmd_is_chars()' - Determine whether a line consists solely of whitespace // and the specified character. // static size_t // O - 1 if as specified, 0 otherwise mmd_is_chars(const char *lineptr, // I - Current line const char *chars, // I - Non-space character size_t minchars) // I - Minimum number of non-space characters { size_t found_ch = 0; // Did we find the specified characters? while (*lineptr == *chars) { found_ch ++; lineptr ++; } if (minchars > 1) { while (*lineptr && strchr(chars, *lineptr)) { if (*lineptr == *chars) found_ch ++; lineptr ++; } } while (*lineptr && isspace(*lineptr & 255) && *lineptr != '\n') lineptr ++; if ((*lineptr && *lineptr != '\n') || found_ch < minchars) return (0); else return (found_ch); } // // 'mmd_is_codefence()' - Determine whether the line contains a code fence. // static size_t // O - Length of fence or 0 otherwise mmd_is_codefence(char *lineptr, // I - Line char fence, // I - Current fence character, if any size_t fencelen, // I - Current fence length char **language) // O - Language name, if any { char match = fence; // Character to match size_t len = 0; // Length of fence chars if (language) *language = NULL; if (!match) { if (*lineptr == '~' || *lineptr == '`') match = *lineptr; else return (0); } while (*lineptr == match) { lineptr ++; len ++; } if (len < 3 || (fencelen && len < fencelen)) return (0); if (*lineptr && *lineptr != '\n' && fence) return (0); else if (*lineptr && *lineptr != '\n' && !fence) { if (match == '`' && strchr(lineptr, match)) return (0); while (isspace(*lineptr & 255)) lineptr ++; if (*lineptr && language) { *language = lineptr; while (*lineptr && !isspace(*lineptr & 255)) { if (*lineptr == '\\' && lineptr[1]) { // Remove "\" memmove(lineptr, lineptr + 1, strlen(lineptr)); } lineptr ++; } *lineptr = '\0'; } } return (len); } // // 'mmd_is_table()' - Look ahead to see if the next line contains a heading // divider for a table. // static bool // O - `true` if this is a table, `false` otherwise mmd_is_table(_mmd_filebuf_t *file, // I - File to read from int indent) // I - Indentation of table line { const char *ptr; // Pointer into buffer ptr = file->bufptr; while (*ptr) { if (!strchr(" \t>", *ptr)) break; ptr ++; } if ((ptr - file->bufptr - indent) >= 4) return (false); while (*ptr) { if (!strchr(" \t:-|", *ptr)) break; ptr ++; } return (*ptr == '\r' || *ptr == '\n'); } // // 'mmd_parse_inline()' - Parse inline formatting. // static void mmd_parse_inline(_mmd_doc_t *doc, // I - Document mmd_t *parent, // I - Parent node char *lineptr) // I - Pointer into line { mmd_t *node; // New node mmd_type_t type; // Current node type int whitespace; // Whitespace precedes? char *text, // Text fragment in line *title, // Link title *url, // URL in link *refname; // Reference name const char *delim = NULL; // Delimiter size_t delimlen = 0; // Length of delimiter whitespace = parent->last_child != NULL; for (text = NULL, type = MMD_TYPE_NORMAL_TEXT; *lineptr; lineptr ++) { DEBUG2_printf("mmd_parse_inline: lineptr=%p(\"%32.32s...\"), type=%d, text=%p, whitespace=%d\n", lineptr, lineptr, type, text, whitespace); if (isspace(*lineptr & 255) && type != MMD_TYPE_CODE_TEXT) { if (text) { *lineptr = '\0'; mmd_add(parent, type, whitespace, text, NULL); text = NULL; } if (!strncmp(lineptr + 1, " \n", 2) && lineptr[3]) { DEBUG2_printf("mmd_parse_inline: Adding hard break to %p(%d)\n", parent, parent->type); mmd_add(parent, MMD_TYPE_HARD_BREAK, 0, NULL, NULL); lineptr += 2; whitespace = 0; } else { whitespace = 1; } } else if (*lineptr == '!' && lineptr[1] == '[' && type != MMD_TYPE_CODE_TEXT) { // Image... if (text) { mmd_add(parent, type, whitespace, text, NULL); text = NULL; whitespace = 0; } lineptr = mmd_parse_link(doc, lineptr + 1, &text, &url, NULL, &refname); if (url || refname) { node = mmd_add(parent, MMD_TYPE_IMAGE, whitespace, text, url); if (refname) mmd_ref_add(doc, node, refname, NULL, NULL); } if (!*lineptr) return; text = url = NULL; whitespace = 0; lineptr --; } else if (*lineptr == '[' && type != MMD_TYPE_CODE_TEXT) { // Link or checkbox... if (text) { *lineptr = '\0'; mmd_add(parent, type, whitespace, text, NULL); *lineptr = '['; text = NULL; whitespace = 0; } if ((mmd_options & MMD_OPTION_TASKS) && (!strncmp(lineptr, "[ ]", 3) || !strncmp(lineptr, "[x]", 3) || !strncmp(lineptr, "[X]", 3))) { // Checkbox mmd_add(parent, MMD_TYPE_CHECKBOX, 0, lineptr[1] == ' ' ? NULL : "x", NULL); lineptr += 2; } else { // Link lineptr = mmd_parse_link(doc, lineptr, &text, &url, &title, &refname); if (text) { char *end = text + strlen(text) - 1; // End of text fragment if (*text == '`' && *end == '`' && end != text) { // Code text text ++; if (end > text && *end == '`') *end = '\0'; node = mmd_add(parent, MMD_TYPE_CODE_TEXT, whitespace, text, url); } else if (*text == '*' && *end == '*' && end > text) { // Emphasized or strong text text ++; if (*text == '*' && (end - 1) > text && end[-1] == '*') { text ++; end[-1] = '\0'; node = mmd_add(parent, MMD_TYPE_STRONG_TEXT, whitespace, text, url); } else { *end = '\0'; node = mmd_add(parent, MMD_TYPE_EMPHASIZED_TEXT, whitespace, text, url); } } else if (type == MMD_TYPE_NORMAL_TEXT) { // Plain linked text... node = mmd_add(parent, MMD_TYPE_LINKED_TEXT, whitespace, text, url); } else { // Preserve style of linked text... node = mmd_add(parent, type, whitespace, text, url); } if (title) node->extra = strdup(title); } else { // No text, no node... node = NULL; } DEBUG2_printf("mmd_parse_inline: text=\"%s\", refname=\"%s\", node=%p\n", text, refname, node); if (refname && node) mmd_ref_add(doc, node, refname, NULL, title); if (!*lineptr) return; text = url = NULL; whitespace = 0; lineptr --; } } else if (*lineptr == '<' && type != MMD_TYPE_CODE_TEXT && strchr(lineptr + 1, '>')) { // Autolink... *lineptr++ = '\0'; if (text) { mmd_add(parent, type, whitespace, text, NULL); text = NULL; whitespace = 0; } url = lineptr; lineptr = strchr(lineptr, '>'); *lineptr = '\0'; mmd_add(parent, MMD_TYPE_LINKED_TEXT, whitespace, url, url); text = url = NULL; whitespace = 0; } else if ((*lineptr == '*' || *lineptr == '_') && (!text || ispunct(lineptr[-1] & 255) || type != MMD_TYPE_NORMAL_TEXT) && type != MMD_TYPE_CODE_TEXT) { const char *end; // End delimiter if (type != MMD_TYPE_NORMAL_TEXT || !delim) { if (!strncmp(lineptr, "**", 2)) delim = "**"; else if (!strncmp(lineptr, "__", 2)) delim = "__"; else if (*lineptr == '*') delim = "*"; else delim = "_"; delimlen = strlen(delim); } if (type == MMD_TYPE_NORMAL_TEXT && delim && ((end = strstr(lineptr + delimlen, delim)) == NULL || end == (lineptr + delimlen) || isspace(end[-1] & 255))) { if (!text) text = lineptr; delim = NULL; delimlen = 0; continue; } if (text) { char save = *lineptr; *lineptr = '\0'; mmd_add(parent, type, whitespace, text, NULL); *lineptr = save; text = NULL; whitespace = 0; } if (type == MMD_TYPE_NORMAL_TEXT) { if (!strncmp(lineptr, delim, delimlen) && !isspace(lineptr[delimlen] & 255)) { type = delimlen == 2 ? MMD_TYPE_STRONG_TEXT : MMD_TYPE_EMPHASIZED_TEXT; text = lineptr + delimlen; lineptr += delimlen - 1; } else { text = lineptr; } } else if (!strncmp(lineptr, delim, delimlen)) { lineptr += delimlen - 1; type = MMD_TYPE_NORMAL_TEXT; delim = NULL; delimlen = 0; } } else if (lineptr[0] == '~' && lineptr[1] == '~' && type != MMD_TYPE_CODE_TEXT) { if (text) { *lineptr = '\0'; mmd_add(parent, type, whitespace, text, NULL); *lineptr = '~'; text = NULL; whitespace = 0; } if (!isspace(lineptr[2] & 255) && type == MMD_TYPE_NORMAL_TEXT) { type = MMD_TYPE_STRUCK_TEXT; text = lineptr + 2; } else { lineptr ++; type = MMD_TYPE_NORMAL_TEXT; } } else if (*lineptr == '`' && (type != MMD_TYPE_CODE_TEXT || lineptr[-1] != '\\')) { if (type != MMD_TYPE_NORMAL_TEXT || !delim) { if (lineptr[1] == '`') { if (lineptr[2] == '`') { delim = "```"; delimlen = 3; } else { delim = "``"; delimlen = 2; } } else { delim = "`"; delimlen = 1; } } if (type != MMD_TYPE_CODE_TEXT && delim && !strstr(lineptr + delimlen, delim)) { if (!text) text = lineptr; delim = NULL; delimlen = 0; continue; } if (text) { DEBUG2_printf("mmd_parse_inline: text=\"%s\"\n", text); if (!strncmp(lineptr, delim, delimlen)) { char *textptr = lineptr; while (textptr > text && isspace(textptr[-1] & 255)) textptr --; *textptr = '\0'; lineptr += delimlen - 1; } if (type == MMD_TYPE_CODE_TEXT) { if (whitespace && !*text) { mmd_add(parent, type, 0, " ", NULL); whitespace = 0; } } mmd_add(parent, type, whitespace, text, NULL); text = NULL; whitespace = 0; } if (type == MMD_TYPE_CODE_TEXT) { DEBUG2_puts("mmd_parse_inline: Reverting to normal text.\n"); type = MMD_TYPE_NORMAL_TEXT; delim = NULL; delimlen = 0; } else { type = MMD_TYPE_CODE_TEXT; lineptr += delimlen - 1; while (isspace(lineptr[1] & 255)) lineptr ++; text = lineptr + 1; } } else if (!strncmp(lineptr, "\\\n", 2)) { // Hard break *lineptr++ = '\0'; if (text) { mmd_add(parent, type, whitespace, text, NULL); text = NULL; whitespace = false; } mmd_add(parent, MMD_TYPE_HARD_BREAK, false, NULL, NULL); } else if (!text) { if (*lineptr == '\\' && ispunct(lineptr[1] & 255) && type != MMD_TYPE_CODE_TEXT) { // Escaped character... lineptr ++; } text = lineptr; } else if (*lineptr == '\\' && ispunct(lineptr[1] & 255) && type != MMD_TYPE_CODE_TEXT) { // Escaped character... memmove(lineptr, lineptr + 1, strlen(lineptr)); } } if (text) { DEBUG_puts("mms_parse_inline: Adding text at end.\n"); mmd_add(parent, type, whitespace, text, NULL); } } // // 'mmd_parse_link()' - Parse a link. // static char * // O - End of link text mmd_parse_link(_mmd_doc_t *doc, // I - Document char *lineptr, // I - Pointer into line char **text, // O - Text char **url, // O - URL char **title, // O - Title, if any char **refname) // O - Reference name { lineptr ++; // skip "[" *text = lineptr; *url = NULL; *refname = NULL; if (title) *title = NULL; while (*lineptr && *lineptr != ']') { if (*lineptr == '\"' || *lineptr == '\'') { char quote = *lineptr++; while (*lineptr && *lineptr != quote) lineptr ++; if (!*lineptr) return (lineptr); } lineptr ++; } if (!*lineptr) return (lineptr); *lineptr++ = '\0'; if (*lineptr == '(') { // Get URL... lineptr ++; *url = lineptr; while (*lineptr && *lineptr != ')') { if (isspace(*lineptr & 255)) { *lineptr = '\0'; } else if (*lineptr == '\\' && lineptr[1]) { if (lineptr[1] == ')') { // Remove "\" memmove(lineptr, lineptr + 1, strlen(lineptr)); } else { // Keep "\" lineptr ++; } } else if (*lineptr == '\"' || *lineptr == '\'') { char quote = *lineptr++; if (title) *title = lineptr; while (*lineptr && *lineptr != quote) { if (*lineptr == '\\' && lineptr[1]) { // Remove "\" memmove(lineptr, lineptr + 1, strlen(lineptr)); } lineptr ++; } if (!*lineptr) return (lineptr); else if (title) *lineptr = '\0'; } lineptr ++; } *lineptr++ = '\0'; } else if (*lineptr == '[') { // Get reference... lineptr ++; *refname = lineptr; while (*lineptr && *lineptr != ']') { if (isspace(*lineptr & 255)) { *lineptr = '\0'; } else if (*lineptr == '\\' && lineptr[1]) { if (lineptr[1] == ']') { // Remove "\" memmove(lineptr, lineptr + 1, strlen(lineptr)); } else { // Keep "\" lineptr ++; } } else if (*lineptr == '\"' || *lineptr == '\'') { char quote = *lineptr++; if (title) *title = lineptr; while (*lineptr && *lineptr != quote) lineptr ++; if (!*lineptr) return (lineptr); else *lineptr = '\0'; } lineptr ++; } *lineptr++ = '\0'; if (!**refname) *refname = *text; } else if (*lineptr == ':') { // Get reference definition... lineptr ++; while (*lineptr && isspace(*lineptr & 255)) lineptr ++; *url = lineptr; while (*lineptr && !isspace(*lineptr & 255)) { if (*lineptr == '\\' && lineptr[1]) { // Remove "\" memmove(lineptr, lineptr + 1, strlen(lineptr)); } lineptr ++; } if (*lineptr) { *lineptr++ = '\0'; while (*lineptr && isspace(*lineptr & 255)) lineptr ++; if (*lineptr == '\"' || *lineptr == '\'') { char quote = *lineptr++; if (title) *title = lineptr; while (*lineptr && *lineptr != quote) { if (*lineptr == '\\' && lineptr[1]) { // Remove "\" memmove(lineptr, lineptr + 1, strlen(lineptr)); } lineptr ++; } if (!*lineptr) return (lineptr); else *lineptr = '\0'; } } mmd_ref_add(doc, NULL, *text, *url, title ? *title : NULL); *text = NULL; *url = NULL; if (title) *title = NULL; } else { // Shortcut reference... *refname = *text; } return (lineptr); } // // 'mmd_read_buffer()' - Fill the file buffer with more data from a file. // static void mmd_read_buffer(_mmd_filebuf_t *file) // I - File buffer { size_t bytes; // Bytes read if (file->bufptr && file->bufptr > file->buffer) { // Discard previous characters in the buffer. memmove(file->buffer, file->bufptr, file->bufend - file->bufptr); file->bufend -= (file->bufptr - file->buffer); } else { // Otherwise just clear the buffer... file->bufend = file->buffer; } if ((bytes = (file->cb)(file->cbdata, file->bufend, sizeof(file->buffer) - (size_t)(file->bufend - file->buffer - 1))) > 0) file->bufend += bytes; *(file->bufend) = '\0'; file->bufptr = file->buffer; } // // 'mmd_read_line()' - Read a line from a file in a Markdown-aware way. // static char * // O - Pointer to line or `NULL` on EOF mmd_read_line(_mmd_filebuf_t *file, // I - File buffer char *line, // I - Line buffer size_t linesize) // I - Size of line buffer { int ch, // Current character column = 0; // Current column char *lineptr = line, // Pointer into line *lineend = line + linesize - 1; // Pointer to end of buffer // Fill the buffer as needed... if (!file->bufptr || (file->bufptr >= file->bufend) || !strchr(file->bufptr, '\n')) mmd_read_buffer(file); // Copy a line out of the file buffer... while (file->bufptr < file->bufend) { ch = *(file->bufptr); file->bufptr ++; if (ch == '\t') { // Expand tabs since nobody uses the same tab width and Markdown says // 4 columns per tab... do { column ++; if (lineptr < lineend) *lineptr++ = ' '; } while (column & 3); } else if (ch != '\r' && lineptr < lineend) { column ++; *lineptr++ = ch; } if (ch == '\n') break; } *lineptr = '\0'; if (file->bufptr == file->bufend && lineptr == line) return (NULL); else if (!strchr(file->bufptr, '\n')) mmd_read_buffer(file); return (line); } // // 'mmd_ref_add()' - Add or update a reference... // static void mmd_ref_add(_mmd_doc_t *doc, // I - Document mmd_t *node, // I - Link node, if any const char *name, // I - Reference name const char *url, // I - Reference URL const char *title) // I - Title, if any { size_t i; // Looping var _mmd_ref_t *ref = mmd_ref_find(doc, name); // Reference DEBUG2_printf("mmd_ref_add(doc=%p, node=%p, name=\"%s\", url=\"%s\", title=\"%s\")\n", doc, node, name, url, title); if (ref) { DEBUG2_printf("mmd_ref_add: ref=%p, ref->url=\"%s\"\n", ref, ref->url); if (!ref->url && url) { if (node) node->url = strdup(url); ref->url = strdup(url); if (title) { if (node) node->extra = strdup(title); ref->title = strdup(title); } for (i = 0; i < ref->num_pending; i ++) { ref->pending[i]->url = strdup(url); if (title) ref->pending[i]->extra = strdup(title); } free(ref->pending); ref->num_pending = 0; ref->pending = NULL; return; } } else if ((ref = realloc(doc->references, (doc->num_references + 1) * sizeof(_mmd_ref_t))) != NULL) { doc->references = ref; ref += doc->num_references; doc->num_references ++; ref->name = strdup(name); ref->url = url ? strdup(url) : NULL; ref->title = title ? strdup(title) : NULL; ref->num_pending = 0; ref->pending = NULL; } else return; if (node) { if (ref->url) { node->url = strdup(ref->url); node->extra = ref->title ? strdup(ref->title) : NULL; } else if ((ref->pending = realloc(ref->pending, (ref->num_pending + 1) * sizeof(mmd_t *))) != NULL) { ref->pending[ref->num_pending ++] = node; } } } // // 'mmd_ref_find()' - Find a reference... // static _mmd_ref_t * // O - Reference or NULL mmd_ref_find(_mmd_doc_t *doc, // I - Document const char *name) // I - Reference name { size_t i; // Looping var for (i = 0; i < doc->num_references; i ++) if (!strcasecmp(name, doc->references[i].name)) return (doc->references + i); return (NULL); } // // 'mmd_remove()' - Remove a node from its parent. // static void mmd_remove(mmd_t *node) // I - Node { if (node && node->parent) { if (node->prev_sibling) node->prev_sibling->next_sibling = node->next_sibling; else node->parent->first_child = node->next_sibling; if (node->next_sibling) node->next_sibling->prev_sibling = node->prev_sibling; else node->parent->last_child = node->prev_sibling; node->parent = NULL; node->prev_sibling = NULL; node->next_sibling = NULL; } } #if DEBUG // // 'mmd_type_string()' - Return a string for the specified type enumeration. // static const char * // O - String representing the type mmd_type_string(mmd_type_t type) // I - Type value { static char unknown[64]; // Unknown type buffer switch (type) { case MMD_TYPE_NONE : return ("MMD_TYPE_NONE"); case MMD_TYPE_DOCUMENT : return "MMD_TYPE_DOCUMENT"; case MMD_TYPE_METADATA : return "MMD_TYPE_METADATA"; case MMD_TYPE_BLOCK_QUOTE : return "MMD_TYPE_BLOCK_QUOTE"; case MMD_TYPE_ORDERED_LIST : return "MMD_TYPE_ORDERED_LIST"; case MMD_TYPE_UNORDERED_LIST : return "MMD_TYPE_UNORDERED_LIST"; case MMD_TYPE_LIST_ITEM : return "MMD_TYPE_LIST_ITEM"; case MMD_TYPE_TABLE : return "MMD_TYPE_TABLE"; case MMD_TYPE_TABLE_HEADER : return "MMD_TYPE_TABLE_HEADER"; case MMD_TYPE_TABLE_BODY : return "MMD_TYPE_TABLE_BODY"; case MMD_TYPE_TABLE_ROW : return "MMD_TYPE_TABLE_ROW"; case MMD_TYPE_HEADING_1 : return "MMD_TYPE_HEADING_1"; case MMD_TYPE_HEADING_2 : return "MMD_TYPE_HEADING_2"; case MMD_TYPE_HEADING_3 : return "MMD_TYPE_HEADING_3"; case MMD_TYPE_HEADING_4 : return "MMD_TYPE_HEADING_4"; case MMD_TYPE_HEADING_5 : return "MMD_TYPE_HEADING_5"; case MMD_TYPE_HEADING_6 : return "MMD_TYPE_HEADING_6"; case MMD_TYPE_PARAGRAPH : return "MMD_TYPE_PARAGRAPH"; case MMD_TYPE_CODE_BLOCK : return "MMD_TYPE_CODE_BLOCK"; case MMD_TYPE_THEMATIC_BREAK : return "MMD_TYPE_THEMATIC_BREAK"; case MMD_TYPE_TABLE_HEADER_CELL : return "MMD_TYPE_TABLE_HEADER_CELL"; case MMD_TYPE_TABLE_BODY_CELL_LEFT : return "MMD_TYPE_TABLE_BODY_CELL_LEFT"; case MMD_TYPE_TABLE_BODY_CELL_CENTER : return "MMD_TYPE_TABLE_BODY_CELL_CENTER"; case MMD_TYPE_TABLE_BODY_CELL_RIGHT : return "MMD_TYPE_TABLE_BODY_CELL_RIGHT"; case MMD_TYPE_NORMAL_TEXT : return "MMD_TYPE_NORMAL_TEXT"; case MMD_TYPE_EMPHASIZED_TEXT : return "MMD_TYPE_EMPHASIZED_TEXT"; case MMD_TYPE_STRONG_TEXT : return "MMD_TYPE_STRONG_TEXT"; case MMD_TYPE_STRUCK_TEXT : return "MMD_TYPE_STRUCK_TEXT"; case MMD_TYPE_LINKED_TEXT : return "MMD_TYPE_LINKED_TEXT"; case MMD_TYPE_CODE_TEXT : return "MMD_TYPE_CODE_TEXT"; case MMD_TYPE_IMAGE : return "MMD_TYPE_IMAGE"; case MMD_TYPE_HARD_BREAK : return "MMD_TYPE_HARD_BREAK"; case MMD_TYPE_SOFT_BREAK : return "MMD_TYPE_SOFT_BREAK"; case MMD_TYPE_METADATA_TEXT : return "MMD_TYPE_METADATA_TEXT"; default : snprintf(unknown, sizeof(unknown), "?? %d ??", (int)type); return (unknown); } } #endif // DEBUG htmldoc-1.9.20/htmldoc/mmd.h000066400000000000000000000066371472561501400156360ustar00rootroot00000000000000// // Header file for miniature markdown library. // // https://www.msweet.org/mmd // // Copyright © 2017-2024 by Michael R Sweet. // // Licensed under Apache License v2.0. See the file "LICENSE" for more // information. // #ifndef MMD_H # define MMD_H # include # include # ifdef __cplusplus extern "C" { # endif // __cplusplus // // Constants... // enum mmd_option_e { MMD_OPTION_NONE = 0x00, // No markdown extensions MMD_OPTION_METADATA = 0x01, // Jekyll metadata extension MMD_OPTION_TABLES = 0x02, // Github table extension MMD_OPTION_TASKS = 0x04, // Github task item extension (check boxes) MMD_OPTION_ALL = 0x07 // All supported markdown extensions }; typedef unsigned mmd_option_t; typedef enum mmd_type_e { MMD_TYPE_NONE = -1, MMD_TYPE_DOCUMENT, // The document root MMD_TYPE_METADATA, // Document metadata MMD_TYPE_BLOCK_QUOTE, //
    MMD_TYPE_ORDERED_LIST, //
      MMD_TYPE_UNORDERED_LIST, //