From 5dc173537c1bc9fd033d1c6b3498e847d3a6d38a Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sat, 20 Sep 2008 23:48:30 +0000 Subject: pax aka pdfannotextractor git-svn-id: svn://tug.org/texlive/trunk@10666 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/source/latex/pax/build.xml | 49 ++ .../source/latex/pax/license/LaTeX/lppl.txt | 416 ++++++++++++ .../latex/pax/license/PDFAnnotExtractor/gpl.txt | 340 ++++++++++ .../texmf-dist/source/latex/pax/src/Constants.java | 132 ++++ Master/texmf-dist/source/latex/pax/src/Entry.java | 174 +++++ .../source/latex/pax/src/EntryWriteException.java | 27 + Master/texmf-dist/source/latex/pax/src/MANIFEST.MF | 4 + .../source/latex/pax/src/PDFAnnotExtractor.java | 733 +++++++++++++++++++++ .../source/latex/pax/src/StringVisitor.java | 131 ++++ 9 files changed, 2006 insertions(+) create mode 100644 Master/texmf-dist/source/latex/pax/build.xml create mode 100644 Master/texmf-dist/source/latex/pax/license/LaTeX/lppl.txt create mode 100644 Master/texmf-dist/source/latex/pax/license/PDFAnnotExtractor/gpl.txt create mode 100644 Master/texmf-dist/source/latex/pax/src/Constants.java create mode 100644 Master/texmf-dist/source/latex/pax/src/Entry.java create mode 100644 Master/texmf-dist/source/latex/pax/src/EntryWriteException.java create mode 100644 Master/texmf-dist/source/latex/pax/src/MANIFEST.MF create mode 100644 Master/texmf-dist/source/latex/pax/src/PDFAnnotExtractor.java create mode 100644 Master/texmf-dist/source/latex/pax/src/StringVisitor.java (limited to 'Master/texmf-dist/source/latex/pax') diff --git a/Master/texmf-dist/source/latex/pax/build.xml b/Master/texmf-dist/source/latex/pax/build.xml new file mode 100644 index 00000000000..230cd3e59d6 --- /dev/null +++ b/Master/texmf-dist/source/latex/pax/build.xml @@ -0,0 +1,49 @@ + + + + Build file for PDFAnnotExtractor + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Master/texmf-dist/source/latex/pax/license/LaTeX/lppl.txt b/Master/texmf-dist/source/latex/pax/license/LaTeX/lppl.txt new file mode 100644 index 00000000000..90e5e3ab797 --- /dev/null +++ b/Master/texmf-dist/source/latex/pax/license/LaTeX/lppl.txt @@ -0,0 +1,416 @@ +The LaTeX Project Public License +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +LPPL Version 1.3c 2006-05-20 + +Copyright 1999 2002-2006 LaTeX3 Project + Everyone is allowed to distribute verbatim copies of this + license document, but modification of it is not allowed. + + +PREAMBLE +======== + +The LaTeX Project Public License (LPPL) is the primary license under +which the the LaTeX kernel and the base LaTeX packages are distributed. + +You may use this license for any work of which you hold the copyright +and which you wish to distribute. This license may be particularly +suitable if your work is TeX-related (such as a LaTeX package), but +it is written in such a way that you can use it even if your work is +unrelated to TeX. + +The section `WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE', +below, gives instructions, examples, and recommendations for authors +who are considering distributing their works under this license. + +This license gives conditions under which a work may be distributed +and modified, as well as conditions under which modified versions of +that work may be distributed. + +We, the LaTeX3 Project, believe that the conditions below give you +the freedom to make and distribute modified versions of your work +that conform with whatever technical specifications you wish while +maintaining the availability, integrity, and reliability of +that work. If you do not see how to achieve your goal while +meeting these conditions, then read the document `cfgguide.tex' +and `modguide.tex' in the base LaTeX distribution for suggestions. + + +DEFINITIONS +=========== + +In this license document the following terms are used: + + `Work' + Any work being distributed under this License. + + `Derived Work' + Any work that under any applicable law is derived from the Work. + + `Modification' + Any procedure that produces a Derived Work under any applicable + law -- for example, the production of a file containing an + original file associated with the Work or a significant portion of + such a file, either verbatim or with modifications and/or + translated into another language. + + `Modify' + To apply any procedure that produces a Derived Work under any + applicable law. + + `Distribution' + Making copies of the Work available from one person to another, in + whole or in part. Distribution includes (but is not limited to) + making any electronic components of the Work accessible by + file transfer protocols such as FTP or HTTP or by shared file + systems such as Sun's Network File System (NFS). + + `Compiled Work' + A version of the Work that has been processed into a form where it + is directly usable on a computer system. This processing may + include using installation facilities provided by the Work, + transformations of the Work, copying of components of the Work, or + other activities. Note that modification of any installation + facilities provided by the Work constitutes modification of the Work. + + `Current Maintainer' + A person or persons nominated as such within the Work. If there is + no such explicit nomination then it is the `Copyright Holder' under + any applicable law. + + `Base Interpreter' + A program or process that is normally needed for running or + interpreting a part or the whole of the Work. + + A Base Interpreter may depend on external components but these + are not considered part of the Base Interpreter provided that each + external component clearly identifies itself whenever it is used + interactively. Unless explicitly specified when applying the + license to the Work, the only applicable Base Interpreter is a + `LaTeX-Format' or in the case of files belonging to the + `LaTeX-format' a program implementing the `TeX language'. + + + +CONDITIONS ON DISTRIBUTION AND MODIFICATION +=========================================== + +1. Activities other than distribution and/or modification of the Work +are not covered by this license; they are outside its scope. In +particular, the act of running the Work is not restricted and no +requirements are made concerning any offers of support for the Work. + +2. You may distribute a complete, unmodified copy of the Work as you +received it. Distribution of only part of the Work is considered +modification of the Work, and no right to distribute such a Derived +Work may be assumed under the terms of this clause. + +3. You may distribute a Compiled Work that has been generated from a +complete, unmodified copy of the Work as distributed under Clause 2 +above, as long as that Compiled Work is distributed in such a way that +the recipients may install the Compiled Work on their system exactly +as it would have been installed if they generated a Compiled Work +directly from the Work. + +4. If you are the Current Maintainer of the Work, you may, without +restriction, modify the Work, thus creating a Derived Work. You may +also distribute the Derived Work without restriction, including +Compiled Works generated from the Derived Work. Derived Works +distributed in this manner by the Current Maintainer are considered to +be updated versions of the Work. + +5. If you are not the Current Maintainer of the Work, you may modify +your copy of the Work, thus creating a Derived Work based on the Work, +and compile this Derived Work, thus creating a Compiled Work based on +the Derived Work. + +6. If you are not the Current Maintainer of the Work, you may +distribute a Derived Work provided the following conditions are met +for every component of the Work unless that component clearly states +in the copyright notice that it is exempt from that condition. Only +the Current Maintainer is allowed to add such statements of exemption +to a component of the Work. + + a. If a component of this Derived Work can be a direct replacement + for a component of the Work when that component is used with the + Base Interpreter, then, wherever this component of the Work + identifies itself to the user when used interactively with that + Base Interpreter, the replacement component of this Derived Work + clearly and unambiguously identifies itself as a modified version + of this component to the user when used interactively with that + Base Interpreter. + + b. Every component of the Derived Work contains prominent notices + detailing the nature of the changes to that component, or a + prominent reference to another file that is distributed as part + of the Derived Work and that contains a complete and accurate log + of the changes. + + c. No information in the Derived Work implies that any persons, + including (but not limited to) the authors of the original version + of the Work, provide any support, including (but not limited to) + the reporting and handling of errors, to recipients of the + Derived Work unless those persons have stated explicitly that + they do provide such support for the Derived Work. + + d. You distribute at least one of the following with the Derived Work: + + 1. A complete, unmodified copy of the Work; + if your distribution of a modified component is made by + offering access to copy the modified component from a + designated place, then offering equivalent access to copy + the Work from the same or some similar place meets this + condition, even though third parties are not compelled to + copy the Work along with the modified component; + + 2. Information that is sufficient to obtain a complete, + unmodified copy of the Work. + +7. If you are not the Current Maintainer of the Work, you may +distribute a Compiled Work generated from a Derived Work, as long as +the Derived Work is distributed to all recipients of the Compiled +Work, and as long as the conditions of Clause 6, above, are met with +regard to the Derived Work. + +8. The conditions above are not intended to prohibit, and hence do not +apply to, the modification, by any method, of any component so that it +becomes identical to an updated version of that component of the Work as +it is distributed by the Current Maintainer under Clause 4, above. + +9. Distribution of the Work or any Derived Work in an alternative +format, where the Work or that Derived Work (in whole or in part) is +then produced by applying some process to that format, does not relax or +nullify any sections of this license as they pertain to the results of +applying that process. + +10. a. A Derived Work may be distributed under a different license + provided that license itself honors the conditions listed in + Clause 6 above, in regard to the Work, though it does not have + to honor the rest of the conditions in this license. + + b. If a Derived Work is distributed under a different license, that + Derived Work must provide sufficient documentation as part of + itself to allow each recipient of that Derived Work to honor the + restrictions in Clause 6 above, concerning changes from the Work. + +11. This license places no restrictions on works that are unrelated to +the Work, nor does this license place any restrictions on aggregating +such works with the Work by any means. + +12. Nothing in this license is intended to, or may be used to, prevent +complete compliance by all parties with all applicable laws. + + +NO WARRANTY +=========== + +There is no warranty for the Work. Except when otherwise stated in +writing, the Copyright Holder provides the Work `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 Work is with you. Should the Work 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 The Copyright Holder, or any author named in the components of the +Work, or any other party who may distribute and/or modify the Work as +permitted above, be liable to you for damages, including any general, +special, incidental or consequential damages arising out of any use of +the Work or out of inability to use the Work (including, but not limited +to, loss of data, data being rendered inaccurate, or losses sustained by +anyone as a result of any failure of the Work to operate with any other +programs), even if the Copyright Holder or said author or said other +party has been advised of the possibility of such damages. + + +MAINTENANCE OF THE WORK +======================= + +The Work has the status `author-maintained' if the Copyright Holder +explicitly and prominently states near the primary copyright notice in +the Work that the Work can only be maintained by the Copyright Holder +or simply that it is `author-maintained'. + +The Work has the status `maintained' if there is a Current Maintainer +who has indicated in the Work that they are willing to receive error +reports for the Work (for example, by supplying a valid e-mail +address). It is not required for the Current Maintainer to acknowledge +or act upon these error reports. + +The Work changes from status `maintained' to `unmaintained' if there +is no Current Maintainer, or the person stated to be Current +Maintainer of the work cannot be reached through the indicated means +of communication for a period of six months, and there are no other +significant signs of active maintenance. + +You can become the Current Maintainer of the Work by agreement with +any existing Current Maintainer to take over this role. + +If the Work is unmaintained, you can become the Current Maintainer of +the Work through the following steps: + + 1. Make a reasonable attempt to trace the Current Maintainer (and + the Copyright Holder, if the two differ) through the means of + an Internet or similar search. + + 2. If this search is successful, then enquire whether the Work + is still maintained. + + a. If it is being maintained, then ask the Current Maintainer + to update their communication data within one month. + + b. If the search is unsuccessful or no action to resume active + maintenance is taken by the Current Maintainer, then announce + within the pertinent community your intention to take over + maintenance. (If the Work is a LaTeX work, this could be + done, for example, by posting to comp.text.tex.) + + 3a. If the Current Maintainer is reachable and agrees to pass + maintenance of the Work to you, then this takes effect + immediately upon announcement. + + b. If the Current Maintainer is not reachable and the Copyright + Holder agrees that maintenance of the Work be passed to you, + then this takes effect immediately upon announcement. + + 4. If you make an `intention announcement' as described in 2b. above + and after three months your intention is challenged neither by + the Current Maintainer nor by the Copyright Holder nor by other + people, then you may arrange for the Work to be changed so as + to name you as the (new) Current Maintainer. + + 5. If the previously unreachable Current Maintainer becomes + reachable once more within three months of a change completed + under the terms of 3b) or 4), then that Current Maintainer must + become or remain the Current Maintainer upon request provided + they then update their communication data within one month. + +A change in the Current Maintainer does not, of itself, alter the fact +that the Work is distributed under the LPPL license. + +If you become the Current Maintainer of the Work, you should +immediately provide, within the Work, a prominent and unambiguous +statement of your status as Current Maintainer. You should also +announce your new status to the same pertinent community as +in 2b) above. + + +WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE +====================================================== + +This section contains important instructions, examples, and +recommendations for authors who are considering distributing their +works under this license. These authors are addressed as `you' in +this section. + +Choosing This License or Another License +---------------------------------------- + +If for any part of your work you want or need to use *distribution* +conditions that differ significantly from those in this license, then +do not refer to this license anywhere in your work but, instead, +distribute your work under a different license. You may use the text +of this license as a model for your own license, but your license +should not refer to the LPPL or otherwise give the impression that +your work is distributed under the LPPL. + +The document `modguide.tex' in the base LaTeX distribution explains +the motivation behind the conditions of this license. It explains, +for example, why distributing LaTeX under the GNU General Public +License (GPL) was considered inappropriate. Even if your work is +unrelated to LaTeX, the discussion in `modguide.tex' may still be +relevant, and authors intending to distribute their works under any +license are encouraged to read it. + +A Recommendation on Modification Without Distribution +----------------------------------------------------- + +It is wise never to modify a component of the Work, even for your own +personal use, without also meeting the above conditions for +distributing the modified component. While you might intend that such +modifications will never be distributed, often this will happen by +accident -- you may forget that you have modified that component; or +it may not occur to you when allowing others to access the modified +version that you are thus distributing it and violating the conditions +of this license in ways that could have legal implications and, worse, +cause problems for the community. It is therefore usually in your +best interest to keep your copy of the Work identical with the public +one. Many works provide ways to control the behavior of that work +without altering any of its licensed components. + +How to Use This License +----------------------- + +To use this license, place in each of the components of your work both +an explicit copyright notice including your name and the year the work +was authored and/or last substantially modified. Include also a +statement that the distribution and/or modification of that +component is constrained by the conditions in this license. + +Here is an example of such a notice and statement: + + %% pig.dtx + %% Copyright 2005 M. Y. Name + % + % This work may be distributed and/or modified under the + % conditions of the LaTeX Project Public License, either version 1.3 + % of this license or (at your option) any later version. + % The latest version of this license is in + % http://www.latex-project.org/lppl.txt + % and version 1.3 or later is part of all distributions of LaTeX + % version 2005/12/01 or later. + % + % This work has the LPPL maintenance status `maintained'. + % + % The Current Maintainer of this work is M. Y. Name. + % + % This work consists of the files pig.dtx and pig.ins + % and the derived file pig.sty. + +Given such a notice and statement in a file, the conditions +given in this license document would apply, with the `Work' referring +to the three files `pig.dtx', `pig.ins', and `pig.sty' (the last being +generated from `pig.dtx' using `pig.ins'), the `Base Interpreter' +referring to any `LaTeX-Format', and both `Copyright Holder' and +`Current Maintainer' referring to the person `M. Y. Name'. + +If you do not want the Maintenance section of LPPL to apply to your +Work, change `maintained' above into `author-maintained'. +However, we recommend that you use `maintained', as the Maintenance +section was added in order to ensure that your Work remains useful to +the community even when you can no longer maintain and support it +yourself. + +Derived Works That Are Not Replacements +--------------------------------------- + +Several clauses of the LPPL specify means to provide reliability and +stability for the user community. They therefore concern themselves +with the case that a Derived Work is intended to be used as a +(compatible or incompatible) replacement of the original Work. If +this is not the case (e.g., if a few lines of code are reused for a +completely different task), then clauses 6b and 6d shall not apply. + + +Important Recommendations +------------------------- + + Defining What Constitutes the Work + + The LPPL requires that distributions of the Work contain all the + files of the Work. It is therefore important that you provide a + way for the licensee to determine which files constitute the Work. + This could, for example, be achieved by explicitly listing all the + files of the Work near the copyright notice of each file or by + using a line such as: + + % This work consists of all files listed in manifest.txt. + + in that place. In the absence of an unequivocal list it might be + impossible for the licensee to determine what is considered by you + to comprise the Work and, in such a case, the licensee would be + entitled to make reasonable conjectures as to which files comprise + the Work. + diff --git a/Master/texmf-dist/source/latex/pax/license/PDFAnnotExtractor/gpl.txt b/Master/texmf-dist/source/latex/pax/license/PDFAnnotExtractor/gpl.txt new file mode 100644 index 00000000000..f90922eea38 --- /dev/null +++ b/Master/texmf-dist/source/latex/pax/license/PDFAnnotExtractor/gpl.txt @@ -0,0 +1,340 @@ + 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. diff --git a/Master/texmf-dist/source/latex/pax/src/Constants.java b/Master/texmf-dist/source/latex/pax/src/Constants.java new file mode 100644 index 00000000000..d97312684fe --- /dev/null +++ b/Master/texmf-dist/source/latex/pax/src/Constants.java @@ -0,0 +1,132 @@ +/* Constants.java +Copyright (C) 2006 Heiko Oberdiek + +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 + +This file is part of PDFAnnotExtractor. See README. +*/ +package pax; + +public interface Constants { + + public String PAX_VERSION = "0.01"; + + public String ENTRY_BEG = "\\["; + public String ENTRY_END = "\\\\\n"; + public String CMD_BEG = "{"; + public String CMD_END = "}"; + public String ARG_BEG = "{"; + public String ARG_END = "}"; + public String KVS_BEG = "{"; + public String KVS_END = "\n}"; + public String KVS_EMPTY = "{}"; + public String KV_BEG = "\n "; + public String KV_END = ","; + public String KEY_BEG = ""; + public String KEY_END = ""; + public String VALUE_BEG = "={"; + public String VALUE_END = "}"; + public String HEX_STR_BEG = "\\<"; + public String HEX_STR_END = "\\>"; + + public String CMD_ANNOT = "annot"; + public String CMD_BASEURL = "baseurl"; + public String CMD_DEST = "dest"; + public String CMD_FILE = "file"; + public String CMD_INFO = "info"; + public String CMD_PAGENUM = "pagenum"; + public String CMD_PAGE = "page"; + public String CMD_PAX = "pax"; + + // cmd file + public String KEY_SIZE = "Size"; + public String KEY_DATE = "Date"; + + // cmd info + public String KEY_AUTHOR = "Author"; + public String KEY_CREATOR = "Creator"; + public String KEY_KEYWORDS = "Keywords"; + public String KEY_PRODUCER = "Producer"; + public String KEY_SUBJECT = "Subject"; + public String KEY_TITLE = "Title"; + + // cmd page + public String KEY_ROTATE = "Rotate"; + public String KEY_MEDIA_BOX = "MediaBox"; + public String KEY_CROP_BOX = "CropBox"; + public String KEY_BLEED_BOX = "BleedBox"; + public String KEY_TRIM_BOX = "TrimBox"; + public String KEY_ART_BOX = "ArtBox"; + + // cmd annot attributes + public String KEY_C = "C"; + public String KEY_BORDER = "Border"; + public String KEY_BS = "BS"; + public String KEY_H = "H"; + + // cmd annot/link/URI + public String KEY_URI = "URI"; + public String KEY_IS_MAP = "IsMap"; + + + // cmd annot/link/GoToR + public String KEY_FILE = "File"; + public String KEY_DEST_NAME = "DestName"; + public String KEY_DEST_PAGE = "DestPage"; + public String KEY_DEST_VIEW = "DestView"; + + // cmd annot/link/GoTo + public String KEY_DEST_RECT = "Rect"; + public String KEY_DEST_X = "DestX"; + public String KEY_DEST_Y = "DestY"; + public String KEY_DEST_ZOOM = "DestZoom"; + public String KEY_DEST_LABEL = "DestLabel"; + + // cmd annot/link/Named + public String KEY_NAME = "Name"; + + // baseurl + public String PDF_URI = "URI"; + public String PDF_BASE = "Base"; + + // annotations + public String PDF_ANNOT = "Annot"; + public String PDF_RECT = "Rect"; + public String PDF_LINK = "Link"; + public String PDF_A = "A"; + public String PDF_C = "C"; + public String PDF_BORDER = "Border"; + public String PDF_BS = "BS"; + public String PDF_H = "H"; + public String PDF_GOTO = "GoTo"; + public String PDF_DEST = "Dest"; + + // destination views + public String PDF_XYZ = "XYZ"; + public String PDF_FIT = "Fit"; + public String PDF_FITH = "FitH"; + public String PDF_FITV = "FitV"; + public String PDF_FITR = "FitR"; + public String PDF_FITB = "FitB"; + public String PDF_FITBH = "FitBH"; + public String PDF_FITBV = "FitBV"; + + public String PDF_NULL = "null"; + + public String PDF_S = "S"; + public String PDF_NAMED = "Named"; + public String PDF_N = "N"; +} diff --git a/Master/texmf-dist/source/latex/pax/src/Entry.java b/Master/texmf-dist/source/latex/pax/src/Entry.java new file mode 100644 index 00000000000..b0fc6324106 --- /dev/null +++ b/Master/texmf-dist/source/latex/pax/src/Entry.java @@ -0,0 +1,174 @@ +/* Entry.java +Copyright (C) 2006 Heiko Oberdiek + +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 + +This file is part of PDFAnnotExtractor. See README. +*/ +package pax; + +import java.io.*; +import java.util.*; + +public class Entry implements Constants { + + protected Writer out; + + protected String cmd; + protected List args; + protected Map kvs; + protected boolean withKV; + protected List delayedList; + + public Entry(Writer out) { + this.out = out; + cmd = null; + args = new Vector(); + kvs = null; + withKV = false; + delayedList = new Vector(); + } + + public void clear() { + cmd = null; + args.clear(); + kvs = null; + withKV = false; + } + + public void setCmd(String cmd) { + clear(); + this.cmd = cmd; + } + + public String getCmd() { + return cmd; + } + + public void withKV() { + this.withKV = true; + if (kvs == null) { + kvs = new HashMap(); + } + } + + public void addArg(String arg) { + args.add(arg); + } + + public void putKV(String key, String value) { + withKV(); + if (value == null) { + return; + } + kvs.put(key, value); + } + + public boolean isEmptyKV() { + return !withKV || kvs.isEmpty(); + } + + public void writeDelayed() throws EntryWriteException { + Writer saved = out; + try { + out = new StringWriter(); + write(); + delayedList.add(out.toString()); + } + catch (Exception e) { throw new EntryWriteException(e); } + finally { + out = saved; + } + } + + public void write() throws EntryWriteException { + try { + out.write(ENTRY_BEG); + + // write command + out.write(CMD_BEG); + out.write(cmd); + out.write(CMD_END); + + // write arguments + Iterator it = args.iterator(); + while (it.hasNext()) { + String arg = (String)it.next(); + out.write(ARG_BEG); + out.write(arg); + out.write(ARG_END); + } + + // write key value pairs + if (withKV) { + if (kvs.isEmpty()) { + out.write(KVS_EMPTY); + } + else { + out.write(KVS_BEG); + it = kvs.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry kv = (Map.Entry)it.next(); + String key = (String)kv.getKey(); + String value = (String)kv.getValue(); + out.write(KV_BEG); + out.write(KEY_BEG); + out.write(key); + out.write(KEY_END); + if (value != null) { + out.write(VALUE_BEG); + out.write(value); + out.write(VALUE_END); + } + out.write(KV_END); + } + out.write(KVS_END); + } + } + + out.write(ENTRY_END); + out.flush(); + } + catch (IOException e) { + throw new EntryWriteException(e); + } + finally { + clear(); + } + } + + public void flushDelayed() throws EntryWriteException { + try { + Iterator it = delayedList.iterator(); + while (it.hasNext()) { + out.write((String)it.next()); + } + out.flush(); + } + catch (IOException e) { + throw new EntryWriteException(e); + } + } + + public void close() throws EntryWriteException { + try { + out.close(); + } + catch (IOException e) { + throw new EntryWriteException(e); + } + } +} diff --git a/Master/texmf-dist/source/latex/pax/src/EntryWriteException.java b/Master/texmf-dist/source/latex/pax/src/EntryWriteException.java new file mode 100644 index 00000000000..7f066f60732 --- /dev/null +++ b/Master/texmf-dist/source/latex/pax/src/EntryWriteException.java @@ -0,0 +1,27 @@ +/* EntryWriteException.java +Copyright (C) 2006 Heiko Oberdiek + +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 + +This file is part of PDFAnnotExtractor. See README. +*/ +package pax; + +public class EntryWriteException extends Exception { + public EntryWriteException(Throwable cause) { + super(cause); + } +} diff --git a/Master/texmf-dist/source/latex/pax/src/MANIFEST.MF b/Master/texmf-dist/source/latex/pax/src/MANIFEST.MF new file mode 100644 index 00000000000..741120a2091 --- /dev/null +++ b/Master/texmf-dist/source/latex/pax/src/MANIFEST.MF @@ -0,0 +1,4 @@ +Manifest-Version: 1.0 +Created-By: Heiko Oberdiek +Main-Class: pax.PDFAnnotExtractor +Class-Path: lib/PDFBox-0.7.2.jar diff --git a/Master/texmf-dist/source/latex/pax/src/PDFAnnotExtractor.java b/Master/texmf-dist/source/latex/pax/src/PDFAnnotExtractor.java new file mode 100644 index 00000000000..91684e5bac5 --- /dev/null +++ b/Master/texmf-dist/source/latex/pax/src/PDFAnnotExtractor.java @@ -0,0 +1,733 @@ +/* PDFAnnotExtractor.java +Copyright (C) 2006, 2007 Heiko Oberdiek + +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 + +This file is part of PDFAnnotExtractor. See README. +*/ +package pax; + +import java.io.*; +import java.text.*; +import java.util.*; + +import org.pdfbox.cos.*; +import org.pdfbox.pdfparser.*; +import org.pdfbox.pdmodel.*; +import org.pdfbox.pdmodel.common.*; +import org.pdfbox.pdmodel.interactive.action.*; +import org.pdfbox.pdmodel.interactive.action.type.*; +import org.pdfbox.pdmodel.interactive.annotation.*; +import org.pdfbox.pdmodel.interactive.documentnavigation.destination.*; + +public class PDFAnnotExtractor implements Constants { + + protected File inputFile; + protected File outputFile; + protected PDDocument doc; + protected PDDocumentCatalog catalog; + protected Entry entry; + protected int destCount; + + protected static final String USAGE = + "Syntax: java PDFAnnotExtractor "; + protected static final String EXT_PDF = ".pdf"; + protected static final String EXT_PAX = ".pax"; + + public static void main(String[] argv) { + if (argv.length < 1) { + System.err.println(USAGE); + System.exit(1); + } + for(int i = 0; i < argv.length; i++) { + processFile(argv[i]); + } + } + + public static void processFile(String fileName) { + File file = new File(fileName); + if (file.isFile()) { + fileName = stripFromEnd(fileName, EXT_PDF); + } + else { + File testFile = new File(fileName + EXT_PDF); + if (testFile.isFile()) { + file = testFile; + } + else { + System.err.println(USAGE); + error("PDF file not found: " + fileName, null); + } + } + System.out.println("* Processing file `" + file.toString() + "' ..."); + PDFAnnotExtractor p = + new PDFAnnotExtractor(file, new File(fileName + EXT_PAX)); + p.parse(); + p.close(); + } + + public PDFAnnotExtractor(File inputFile, File outputFile) { + this.inputFile = inputFile; + this.outputFile = outputFile; + destCount = 0; + try { + doc = PDDocument.load(inputFile); + catalog = doc.getDocumentCatalog(); + } + catch (IOException e) { + error("Loading failed: " + inputFile, e); + } + try { + entry = new Entry(new BufferedWriter(new FileWriter(outputFile))); + } + catch (IOException e) { + error("Cannot open output: " + outputFile, e); + } + } + + public void close() { + try { + doc.close(); + } + catch (IOException e) { + error("Closing failed: " + inputFile, e); + } + try { + entry.close(); + } + catch (EntryWriteException e) { + error("Closing failed: " + outputFile, e); + } + } + + public void parse() { + cmd_pax(); + cmd_file(); + cmd_pagenum(); + cmd_baseurl(); + parse_pages(); + } + + public void cmd_pax() { + try { + // PAX version info + entry.setCmd(CMD_PAX); + entry.addArg(PAX_VERSION); + entry.write(); + } + catch (Exception e) { handleCmdException(e); } + } + + public void cmd_file() { + try { + entry.setCmd(CMD_FILE); + entry.addArg(formatString(inputFile.toString())); + long size = inputFile.length(); + if (size > 0) { + entry.putKV(KEY_SIZE, "" + size); + } + long time = inputFile.lastModified(); + if (time != 0) { + Date d = new Date(time); + DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); + String date = "D:" + df.format(d); + df = new SimpleDateFormat("Z"); + String zone = df.format(d); + if (zone.equals("+0000")) { + zone = "Z"; + } + else { + // ISO format: SIGN DIGIT DIGIT DIGIT DIGIT + zone = zone.substring(0, 3) + + "'" + + zone.substring(3, 5) + + "'"; + } + entry.putKV(KEY_DATE, date + zone); + } + entry.write(); + } + catch (Exception e) { handleCmdException(e); } + } + + public void cmd_pagenum() { + try { + // pagenum + int pagenum = doc.getNumberOfPages(); + entry.setCmd(CMD_PAGENUM); + entry.addArg("" + pagenum); + entry.write(); + } + catch (Exception e) { handleCmdException(e); } + } + + public void cmd_info() { + try { + // info + entry.setCmd(CMD_INFO); + PDDocumentInformation info = doc.getDocumentInformation(); + entry.putKV(KEY_AUTHOR, formatString(info.getAuthor())); + entry.putKV(KEY_CREATOR, formatString(info.getCreator())); + entry.putKV(KEY_KEYWORDS, formatString(info.getKeywords())); + entry.putKV(KEY_PRODUCER, formatString(info.getProducer())); + entry.putKV(KEY_SUBJECT, formatString(info.getSubject())); + entry.putKV(KEY_TITLE, formatString(info.getTitle())); + if (!entry.isEmptyKV()) { + entry.write(); + } + } + catch (Exception e) { handleCmdException(e); } + } + + public void cmd_baseurl() { + try { + // baseurl + entry.setCmd(CMD_BASEURL); + COSDictionary dict = catalog.getCOSDictionary(); + dict = (COSDictionary) + dict.getItem(COSName.getPDFName(PDF_URI)); + String baseurl = dict.getString(PDF_BASE); + if (baseurl.length() > 0) { + entry.addArg(formatString(baseurl)); + entry.write(); + } + } + catch (EntryWriteException e) { handleCmdException(e); } + catch (Exception e) {} + } + + public void parse_pages() { + ListIterator iter = catalog.getAllPages().listIterator(); + while (iter.hasNext()) { + // page + PDPage page = (PDPage)iter.next(); + int num = iter.nextIndex(); + parse_page(num, page); + } + try { + entry.flushDelayed(); + } + catch (EntryWriteException e) { + System.err.println("Write error: " + outputFile); + System.err.println(e.getCause().toString()); + } + } + + public void parse_page(int num, PDPage page) { + cmd_page(num, page); + parse_annots(num, page); + } + + public void cmd_page(int num, PDPage page) { + try { + entry.setCmd(CMD_PAGE); + entry.addArg("" + num); + entry.withKV(); + + // rotate entry + int rot = page.findRotation(); + if (rot != 0) { + entry.putKV(KEY_ROTATE, "" + rot); + } + + // box entries + PDRectangle mediaBox = page.findMediaBox(); + PDRectangle cropBox = page.findCropBox(); + PDRectangle bleedBox = page.getBleedBox(); + PDRectangle trimBox = page.getTrimBox(); + PDRectangle artBox = page.getArtBox(); + entry.addArg(formatBox(mediaBox)); + if (!equals(cropBox, mediaBox)) { + entry.putKV(KEY_CROP_BOX, formatBox(cropBox)); + } + if (!equals(bleedBox, cropBox)) { + entry.putKV(KEY_BLEED_BOX, formatBox(bleedBox)); + } + if (!equals(trimBox, cropBox)) { + entry.putKV(KEY_TRIM_BOX, formatBox(trimBox)); + } + if (!equals(artBox, cropBox)) { + entry.putKV(KEY_ART_BOX, formatBox(artBox)); + } + entry.write(); + } + catch (Exception e) { handleCmdException(e); } + } + + public void parse_annots(int num, PDPage page) { + // get annotations + COSArray annots = null; + try { + COSDictionary page_dict = page.getCOSDictionary(); + annots = (COSArray)page_dict.getDictionaryObject(COSName.ANNOTS); + } + catch (Exception e) {} + if (annots == null) { + return; + } + + for (int i = 0; i < annots.size(); i++) { + try { + COSDictionary annot = (COSDictionary)annots.getObject(i); + cmd_annot(num, annot); + } + catch (Exception e) {} + } + } + + public void cmd_annot(int num, COSDictionary annot) { + try { + entry.setCmd(CMD_ANNOT); + entry.addArg("" + num); + + // Type + String type = annot.getNameAsString(COSName.TYPE, PDF_ANNOT); + if (!type.equals(PDF_ANNOT)) { + throw new Exception("Wrong annotation type: " + type); + } + // Subtype + String subtype = annot.getNameAsString(COSName.SUBTYPE); + if (subtype == null) { + throw new Exception("Missing annotation subtype."); + } + if (!subtype.equals(PDF_LINK)) { + throw new Exception("Unsupported annotation subtype: " + + subtype); + } + entry.addArg(subtype); + entry.withKV(); + // Rect + COSArray array = (COSArray) + annot.getDictionaryObject(PDF_RECT); + PDRectangle rect = new PDRectangle(array); + entry.addArg(formatBox(rect)); + // A + COSDictionary a = (COSDictionary) + annot.getDictionaryObject(PDF_A); + if (a == null) { + COSBase cos = annot.getDictionaryObject(PDF_DEST); + if (cos == null) { + throw new Exception("Unsupported link annotation " + + "without action."); + } + entry.addArg(PDF_GOTO); + destCount++; + entry.putKV(KEY_DEST_LABEL, "" + destCount); + annot_attrs(annot); + entry.write(); + add_dest(PDDestination.create(cos)); + entry.writeDelayed(); + return; + } + PDAction action = PDActionFactory.createAction(a); + if (action == null) { + // try named action, unsupported by PDFBox + if (a.getNameAsString(PDF_S).equals(PDF_NAMED)) { + entry.addArg(PDF_NAMED); + String name = a.getNameAsString(PDF_N); + if (name != null) { + entry.putKV(KEY_NAME, name); + annot_attrs(annot); + entry.write(); + return; + } + } + throw new Exception("Unsupported link annotation."); + } + String actionSubtype = action.getSubType(); + entry.addArg(actionSubtype); + if (action instanceof PDActionURI) { + PDActionURI uri = (PDActionURI)action; + entry.putKV(KEY_URI, formatString(uri.getURI())); + if (uri.shouldTrackMousePosition()) { + entry.putKV(KEY_IS_MAP, null); + } + } + else if (action instanceof PDActionGoTo) { + destCount++; + entry.putKV(KEY_DEST_LABEL, "" + destCount); + annot_attrs(annot); + entry.write(); + add_dest(((PDActionGoTo)action).getDestination()); + entry.writeDelayed(); + return; + } + else if (action instanceof PDActionRemoteGoTo) { + PDActionRemoteGoTo gotor = (PDActionRemoteGoTo)action; + String file = gotor.getFile().getFile(); + if (file == null || file.length() == 0) { + throw new Exception("GoToR: missing file"); + } + entry.putKV(KEY_FILE, formatString(gotor.getFile().getFile())); + + /* + PDDestination d = PDDestination.create(gotor.getD()); + String view = "/"; + if (d instanceof PDNamedDestination) { + entry.putKV(KEY_DEST_NAME, + ((PDNamedDestination)d) + .getNamedDestination()); + } + else { + if (d instanceof PDPageFitDestination) { + PDPageFitDestination p = + (PDPageFitDestination)d; + view += (p.fitBoundingBox()) ? PDF_FITB : PDF_FIT; + } + else if (d instanceof PDPageFitHeightDestination) { + PDPageFitHeightDestination p = + (PDPageFitHeightDestination)d; + view += (p.fitBoundingBox()) ? PDF_FITBV : PDF_FITV; + view += " "; + view += (p.getLeft() == -1) ? PDF_NULL : "" + p.getLeft(); + } + else if (d instanceof PDPageFitWidthDestination) { + PDPageFitWidthDestination p = + (PDPageFitWidthDestination)d; + view += (p.fitBoundingBox()) ? PDF_FITBH : PDF_FITH; + view += " "; + view += (p.getTop() == -1) ? PDF_NULL : "" + p.getTop(); + } + else if (d instanceof PDPageXYZDestination) { + PDPageXYZDestination p = + (PDPageXYZDestination)d; + view += PDF_XYZ; + view += " "; + view += (p.getLeft() == -1) ? PDF_NULL : "" + p.getLeft(); + view += " "; + view += (p.getTop() == -1) ? PDF_NULL : "" + p.getTop(); + view += " "; + view += (p.getZoom() == -1) ? PDF_NULL : "" + p.getZoom(); + } + else if (d instanceof PDPageFitRectangleDestination) { + PDPageFitRectangleDestination p = + (PDPageFitRectangleDestination)d; + view += PDF_FITR; + view += " " + p.getLeft() + " " + p.getBottom(); + view += " " + p.getRight() + " " + p.getTop(); + } + else { + throw new Exception("Unknown destination type"); + } + entry.putKV(KEY_DEST_VIEW, view); + } + */ + + COSBase d = gotor.getD(); + if (d instanceof COSString) { + entry.putKV(KEY_DEST_NAME, + formatString(((COSString)d).getString())); + } + else if (d instanceof COSName) { + entry.putKV(KEY_DEST_NAME, + formatString(((COSName)d).getName())); + } + else if (d instanceof COSArray) { + COSArray dest = (COSArray)d; + int page_num = dest.getInt(0); + entry.putKV(KEY_DEST_PAGE, "" + page_num); + String view = dest.getName(1); + int size = dest.size(); + if (view.equals(PDF_FIT) || view.equals(PDF_FITB)) { + } + else if (view.equals(PDF_FITH) || view.equals(PDF_FITBH) + || view.equals(PDF_FITV) || view.equals(PDF_FITBV)) { + if (size >= 3) { + try { + String args = formatNumber( + ((COSNumber)dest.getObject(2)).floatValue()); + view += " " + args; + } + catch (Exception e) { + size = 0; + } + } + if (size < 3) { + if (view.equals(PDF_FITH) || view.equals(PDF_FITV)) { + view = PDF_FIT; + } + else { + view = PDF_FITB; + } + } + } + else if (view.equals(PDF_XYZ)) { + COSBase obj; + view += " "; + if (size >= 3) { + obj = dest.getObject(2); + if (obj instanceof COSNumber) { + view += formatNumber(((COSNumber)obj).floatValue()); + } + else { + view += PDF_NULL; + } + } + else { + view += PDF_NULL; + } + view += " "; + if (size >= 4) { + obj = dest.getObject(3); + if (obj instanceof COSNumber) { + view += formatNumber(((COSNumber)obj).floatValue()); + } + else { + view += PDF_NULL; + } + } + else { + view += PDF_NULL; + } + view += " "; + if (size >= 5) { + obj = dest.getObject(4); + if (obj instanceof COSNumber) { + view += formatNumber(((COSNumber)obj).floatValue()); + } + else { + view += PDF_NULL; + } + } + else { + view += PDF_NULL; + } + } + else if (view.equals(PDF_FITR)) { + view += " " + + formatNumber(((COSNumber)dest.getObject(2)).floatValue()) + + " " + + formatNumber(((COSNumber)dest.getObject(3)).floatValue()) + + " " + + formatNumber(((COSNumber)dest.getObject(4)).floatValue()) + + " " + + formatNumber(((COSNumber)dest.getObject(5)).floatValue()); + } + else { + throw new Exception("Unknown destination view type"); + } + entry.putKV(KEY_DEST_VIEW, "/" + view); + } + else { + throw new Exception("GoToR: unknown dest type"); + } + } + else { + throw new Exception("Unsupported link annotation type: " + + actionSubtype); + } + annot_attrs(annot); + entry.write(); + } + catch (EntryWriteException e) { handleCmdException(e); } + catch (Exception e) { + System.err.println("!!! Warning: Annotation on page " + num + + " not recognized!"); + System.err.println(" " + e.toString()); + String msg = e.getMessage(); + Throwable cause = e.getCause(); + if (cause != null) { + System.err.println(" " + cause.toString()); + } + if (e instanceof ClassCastException) { + e.printStackTrace(); + } + } + } + + private void add_dest(PDDestination dest) throws Exception { + entry.setCmd(CMD_DEST); + entry.withKV(); + if (dest instanceof PDNamedDestination) { + String name = ((PDNamedDestination)dest).getNamedDestination(); + Object obj = catalog.getNames().getDests().getValue(name); + if (obj instanceof PDDestination) { + dest = (PDDestination)obj; + } + } + if (dest instanceof PDPageDestination) { + PDPageDestination pd = (PDPageDestination)dest; + PDPage page = pd.getPage(); + int pagenum = catalog.getAllPages().indexOf(page); + if (pagenum < 0) { + throw new Exception("Link to unknown page"); + } + entry.addArg("" + (pagenum + 1)); + entry.addArg("" + destCount); + if (pd instanceof PDPageFitDestination) { + PDPageFitDestination d = (PDPageFitDestination)pd; + entry.addArg(d.fitBoundingBox() ? PDF_FITB : PDF_FIT); + return; + } + if (pd instanceof PDPageFitHeightDestination) { + PDPageFitHeightDestination d = (PDPageFitHeightDestination)pd; + entry.addArg(d.fitBoundingBox() ? PDF_FITBV : PDF_FITV); + COSArray a = d.getCOSArray(); + if (a.size() > 2) { + COSNumber n = (COSNumber)a.getObject(2); + if (n != null) { + entry.putKV(KEY_DEST_X, formatNumber(n)); + } + } + return; + } + if (pd instanceof PDPageFitWidthDestination) { + PDPageFitWidthDestination d = (PDPageFitWidthDestination)pd; + entry.addArg(d.fitBoundingBox() ? PDF_FITBH : PDF_FITH); + COSArray a = d.getCOSArray(); + if (a.size() > 2) { + COSNumber n = (COSNumber)a.getObject(2); + if (n != null) { + entry.putKV(KEY_DEST_Y, formatNumber(n)); + } + } + return; + } + if (pd instanceof PDPageFitRectangleDestination) { + PDPageFitRectangleDestination d = (PDPageFitRectangleDestination)pd; + entry.addArg(PDF_FITR); + COSArray a = d.getCOSArray(); + int size = a.size(); + if (size != 6) { + throw new Exception("Rectangle destination without" + + " correct number of parameters"); + } + entry.putKV(KEY_DEST_RECT, + formatNumber((COSNumber)a.getObject(2)) + " " + + formatNumber((COSNumber)a.getObject(3)) + " " + + formatNumber((COSNumber)a.getObject(4)) + " " + + formatNumber((COSNumber)a.getObject(5))); + return; + } + if (pd instanceof PDPageXYZDestination) { + PDPageXYZDestination d = (PDPageXYZDestination)pd; + entry.addArg(PDF_XYZ); + COSArray a = d.getCOSArray(); + int size = a.size(); + COSNumber n; + if (size > 2) { + n = (COSNumber)a.getObject(2); + if (n != null) { + entry.putKV(KEY_DEST_X, formatNumber(n)); + } + } + if (size > 3) { + n = (COSNumber)a.getObject(3); + if (n != null) { + entry.putKV(KEY_DEST_Y, formatNumber(n)); + } + } + if (size > 4) { + n = (COSNumber)a.getObject(4); + if (n != null) { + entry.putKV(KEY_DEST_ZOOM, formatNumber(n)); + } + } + return; + } + } + throw new Exception("Unknown destination type"); + } + + protected void annot_attrs(COSDictionary annot) { + put_attr(annot, PDF_C, KEY_C); + put_attr(annot, PDF_BORDER, KEY_BORDER); + put_attr(annot, PDF_BS, KEY_BS); + put_attr(annot, PDF_H, KEY_H); + } + + protected void put_attr(COSDictionary annot, + String pdfKey, String entryKey) { + try { + COSBase value = annot.getDictionaryObject(pdfKey); + if (value == null) { + return; + } + String str = value.accept(new StringVisitor()).toString(); + if (str == null || str.length() == 0) { + return; + } + entry.putKV(entryKey, str); + } + catch (Exception e) {} + } + + protected boolean equals(PDRectangle a, PDRectangle b) { + return a.getLowerLeftX() == b.getLowerLeftX() + && a.getLowerLeftY() == b.getLowerLeftY() + && a.getUpperRightX() == b.getUpperRightX() + && a.getUpperRightY() == b.getUpperRightY(); + } + + protected String formatBox(PDRectangle r) { + return formatNumber(r.getLowerLeftX()) + ' ' + + formatNumber(r.getLowerLeftY()) + ' ' + + formatNumber(r.getUpperRightX()) + ' ' + + formatNumber(r.getUpperRightY()); + } + + protected String formatString(String s) { + if (s == null || s.length() == 0) { + return s; + } + return HEX_STR_BEG + + (new COSString(s)).getHexString() + + HEX_STR_END; + } + + protected String formatNumber(float f) { + String s = "" + f; + return stripFromEnd(s, ".0"); + } + protected String formatNumber(COSNumber obj) { + return formatNumber(obj.floatValue()); + } + + protected static String stripFromEnd(String str, String ext) { + if (str.endsWith(ext)) { + return str.substring(0, str.length() - ext.length()); + } + return str; + } + + protected static void error(String msg, Exception e, boolean stackTrace) { + System.err.println("!!! Error: " + msg); + if (e != null) { + if (stackTrace) { + e.printStackTrace(); + } + else { + System.err.println(e.toString()); + } + } + System.exit(1); + } + protected static void error(String msg, Exception e) { + error(msg, e, false); + } + + protected void handleCmdException(Exception e) { + System.err.println("!!! Error during write of entry `" + + entry.getCmd() + "'!\n"); + if (e instanceof EntryWriteException) { + System.err.println("Write error: " + outputFile); + System.err.println(((EntryWriteException)e).getCause().toString()); + } + else { + e.printStackTrace(); + } + } +} diff --git a/Master/texmf-dist/source/latex/pax/src/StringVisitor.java b/Master/texmf-dist/source/latex/pax/src/StringVisitor.java new file mode 100644 index 00000000000..dcec104d9ad --- /dev/null +++ b/Master/texmf-dist/source/latex/pax/src/StringVisitor.java @@ -0,0 +1,131 @@ +/* StringVisitor.java +Copyright (C) 2006 Heiko Oberdiek + +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 + +This file is part of PDFAnnotExtractor. See README. +*/ +package pax; + +import java.io.*; +import java.util.*; +import org.pdfbox.cos.*; +import org.pdfbox.exceptions.*; + +public class StringVisitor implements ICOSVisitor { + + protected StringBuffer buf; + boolean nodelim; + + public StringVisitor() { + buf = new StringBuffer(); + nodelim = false; + } + + public Object visitFromNull(COSNull obj) { + if (nodelim) { + buf.append(' '); + } + buf.append("null"); + nodelim = true; + return buf; + } + + public Object visitFromBoolean(COSBoolean obj) { + if (nodelim) { + buf.append(' '); + } + buf.append(obj.getValue()); + nodelim = true; + return buf; + } + + public Object visitFromInt(COSInteger obj) { + if (nodelim) { + buf.append(' '); + } + buf.append(obj.intValue()); + nodelim = true; + return buf; + } + + public Object visitFromFloat(COSFloat obj) { + if (nodelim) { + buf.append(' '); + } + String s = "" + obj.floatValue(); + if (s.endsWith(".0")) { + buf.append(s.substring(0, s.length() - ".0".length())); + } + else { + buf.append(s); + } + nodelim = true; + return buf; + } + + public Object visitFromName(COSName obj) { + ByteArrayOutputStream a = new ByteArrayOutputStream(); + try { + obj.writePDF(a); + } + catch (IOException e) {} + buf.append(a.toString()); + nodelim = true; + return buf; + } + + public Object visitFromString(COSString obj) { + buf.append("\\<"); + buf.append(obj.getHexString()); + buf.append("\\>"); + nodelim = false; + return buf; + } + + public Object visitFromArray(COSArray obj) throws COSVisitorException { + buf.append('['); + nodelim = false; + for (int i = 0; i < obj.size(); i++) { + obj.getObject(i).accept(this); + } + buf.append(']'); + nodelim = false; + return buf; + } + + public Object visitFromDictionary(COSDictionary obj) throws COSVisitorException { + buf.append("<<"); + nodelim = false; + Iterator iter = obj.keyList().iterator(); + while (iter.hasNext()) { + COSName key = (COSName)iter.next(); + COSBase value = obj.getDictionaryObject(key); + key.accept(this); + value.accept(this); + } + buf.append(">>"); + nodelim = false; + return buf; + } + + public Object visitFromStream(COSStream obj) throws COSVisitorException { + throw new COSVisitorException(new Exception("Unsupported stream object")); + } + public Object visitFromDocument(COSDocument obj) throws COSVisitorException { + throw new COSVisitorException(new Exception("Unsupported documetn object")); + } +} -- cgit v1.2.3