diff options
author | Karl Berry <karl@freefriends.org> | 2008-09-20 23:48:30 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2008-09-20 23:48:30 +0000 |
commit | 5dc173537c1bc9fd033d1c6b3498e847d3a6d38a (patch) | |
tree | 896be0734f25575e9ac83417976c9d268a64b981 /Master/texmf-dist | |
parent | 4b95f16c338118ec28786de9563f1361d9b42989 (diff) |
pax aka pdfannotextractor
git-svn-id: svn://tug.org/texlive/trunk@10666 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist')
-rw-r--r-- | Master/texmf-dist/doc/latex/pax/README | 208 | ||||
-rw-r--r-- | Master/texmf-dist/scripts/pax/pax.jar | bin | 0 -> 11487 bytes | |||
-rwxr-xr-x | Master/texmf-dist/scripts/pax/pdfannotextractor.texlua | 43 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/pax/build.xml | 49 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/pax/license/LaTeX/lppl.txt | 416 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/pax/license/PDFAnnotExtractor/gpl.txt | 340 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/pax/src/Constants.java | 132 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/pax/src/Entry.java | 174 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/pax/src/EntryWriteException.java | 27 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/pax/src/MANIFEST.MF | 4 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/pax/src/PDFAnnotExtractor.java | 733 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/pax/src/StringVisitor.java | 131 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/pax/pax.sty | 607 |
13 files changed, 2864 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/latex/pax/README b/Master/texmf-dist/doc/latex/pax/README new file mode 100644 index 00000000000..03e070a9853 --- /dev/null +++ b/Master/texmf-dist/doc/latex/pax/README @@ -0,0 +1,208 @@ +README for project pax (PDFAnnotExtractor), 2007/07/19 v0.1h + + +TABLE OF CONTENTS +================= + +A. Project pax +B. Copyright, License +C. Files +D. Author +E. Requirements +F. Download +G. Installation +H. Use +I. History + + +A. PROJECT PAX +============== + +If PDF files are included using pdfTeX, PDF annotations +are stripped. This project tries a solution without +altering pdfTeX. A Java program (pax.jar) parses the PDF file that +will later be included. It writes the data of the annotations +in a file that can be read by TeX. Then a LaTeX package (pax.sty) +extends the graphics package. If a PDF file is included, the package +looks for the file with the annotation data, reads them and puts +the annotations in the right place. + +Project status: experimental + + +B. COPYRIGHT, LICENSE +===================== + +Copyright (C) 2006, 2007 Heiko Oberdiek. + +The project consists of two parts: +* The Java program pax.jar with sources. + License is GPL, see license/gpl.txt. +* The LaTeX package pax.sty. + License is LPPL 1.3. +The file README belongs to both parts. + +The Java program uses the PDF library PDFBox, +see http://www.pdfbox.org/. + + +C. FILES +======== + +The project is available in CTAN (ftp.ctan.org): + CTAN:macros/latex/contrib/pax/ + +There are the following files: +* README + This file. +* pax-tds.zip + The whole project, ready to unpack in a TDS (texmf) tree. + +The files inside pax-tds.zip: +* doc/latex/pax/README + This file. +* scripts/pax/pax.jar + The Java program. +* source/latex/pax/license/LaTeX/lppl.txt + License (LPPL) for the LaTeX package. +* source/latex/pax/license/PDFAnnotExtractor/gpl.txt + License (GPL) for the Java program. +* source/latex/pax/src/Constants.java + source/latex/pax/src/Entry.java + source/latex/pax/src/EntryWriteException.java + source/latex/pax/src/PDFAnnotExtractor.java + source/latex/pax/src/StringVisitor.java + Java source files. +* source/latex/pax/src/MANIFEST.MF + Manifest file for the JAR file. +* source/latex/pax/src/build.xml + Ant build file for generating the JAR file. +* tex/latex/pax/pax.sty + The LaTeX package. + + +D. AUTHOR +========= + +Heiko Oberdiek <oberdiek@uni-freiburg.de> + +E. REQUIREMENTS +=============== + +* Java 1.4+. +* PDFBox 0.7.2+. + +F. DOWNLOAD +=========== + +1. Download pax-tds.zip from CTAN: + ftp://ftp.ctan.org/tex-archive/macros/latex/contrib/pax/pax-tds.zip + +2. Download PDFBox-0.7.2.jar from http://www.pdfbox.org/: + http://prdownloads.sourceforge.net/pdfbox/PDFBox-0.7.2.zip?download + +G. INSTALLATION +=============== + +Examples are given for linux. + +3. Install PDFBox. In the following it is assumed, that the JAR file + is available as: + /usr/local/share/PDFBox-0.7.2/lib/PDFBox-0.7.2.jar + +4. Unzip pax-tds.zip inside the TDS tree, where you want to put this + project, e.g.: + unzip pax-tds -d /usr/local/share/texmf + Don't forget to update the database (texhash, mktexlsr, ...). + +5. Put the PDFBox library in the right place: + mkdir /usr/local/share/texmf/scripts/pax/lib + ln /usr/local/share/PDFBox-0.7.2/lib/PDFBox-0.7.2.jar \ + /usr/local/share/texmf/scripts/pax/lib/ + (A symbol link does not seam to work, a hard link or copy is needed.) + Alternatively, include PDFBox-0.7.2.jar in your CLASSPATH and/or + adjust the Class-Path entry in MANIFEST.MF of pax.jar for the + right location of the PDFBox library. + +6. Write a wrapper script or whatever to ease the call of the + Java program, e.g.: + #!/bin/sh + java -jar /usr/local/share/texmf/scripts/pax/pax.jar "$@" + +Version of PDFBox +----------------- +Developing the pax project I have used and tested version 0.7.2. +However, you may try a more uptodate version of PDFBox. +Then fix the entry in the file MANIFEST.MF inside pax.jar or +create a symbol link that TDS:scripts/pax/lib/PDFBox-0.7.2.jar +points to the new JAR file. + + +H. USE +====== + +As example I am using usrguide.pdf (with links from project latex-tds) +that will be included in test.tex: + +%%% cut %%% test.tex %%% cut %%% +\documentclass[a4paper,12pt,landscape]{article} +\usepackage[ + hmargin=1in, + vmargin=1in, +]{geometry} + +\usepackage{pdfpages} +% pdfpages loads graphicx + +\usepackage{pax} + +\iffalse + \usepackage{hyperref} + \hypersetup{ + filebordercolor={1 1 0}, + } +\fi + +\begin{document} + \includepdf[pages=-,nup=2x1]{usrguide} +\end{document} +%%% cut %%% test.tex %%% cut %%% + +First run the Java program on usrguide.pdf: + + $ java -jar pax.jar usrguide.pdf + +It generates usrguide.pax. +Next run pdflatex on test.tex twice at least: + + $ pdflatex test + $ pdflatex test + +Then the links should work. + +Additionally package hyperref can be used (replace \iffase by \iftrue). +Then the links can be configured using hyperref settings. +(But keep in mind, the colored links by option colorlinks can't +be changed in included documents. + + +I. History +========== + +2006/08/24 v0.1a + * First release. +2006/09/04 v0.1b + * Bug fix in PDFAnnotExtractor.add_dest()/named destinations. +2007/06/29 v0.1c + * \l@addto@macro renamed to \PAX@l@addto@macro to avoid + collision with classes of KOMA-Script. +2007/06/30 v0.1d + * Use of package `etexmcds'. +2007/07/12 v0.1e + * The Java program can be called with several files. +2007/07/16 v0.1f + * PDF files are explicitely closed to avoid warnings. +2007/07/18 v0.1g + * Compiled for Java 1.4. +2007/07/19 v0.1h + * JAR file without TDS tree. diff --git a/Master/texmf-dist/scripts/pax/pax.jar b/Master/texmf-dist/scripts/pax/pax.jar Binary files differnew file mode 100644 index 00000000000..86366738add --- /dev/null +++ b/Master/texmf-dist/scripts/pax/pax.jar diff --git a/Master/texmf-dist/scripts/pax/pdfannotextractor.texlua b/Master/texmf-dist/scripts/pax/pdfannotextractor.texlua new file mode 100755 index 00000000000..3fa9f8aa314 --- /dev/null +++ b/Master/texmf-dist/scripts/pax/pdfannotextractor.texlua @@ -0,0 +1,43 @@ +#!/usr/bin/env texlua +--*-Lua-*- +-- $Id: ppower4.texlua 6969 2008-03-14 22:17:00Z reinhardk $ + +-- Copyright (C) 2008 Reinhard Kotucha. +-- You may freely use, modify and/or distribute this file. + +-- Launch ppower4 + +function fixwin(args_unix) + if os.type == 'windows' then + local args_win={} -- new table + args_win[0]=args_unix[1] + for i=1, #args_unix do + args_win[i]='"'..args_unix[i]..'"' + end + return args_win + else + return args_unix + end +end + +kpse.set_program_name('pdfannotextractor.texlua', 'pdfannotextractor') + +jarfile=kpse.find_file(pax.jar', 'texmfscripts') + +command={'java', '-jar', jarfile} + +for i=1, #arg do + command[#command+1]=arg[i] +end + +command=fixwin(command) + +--[[ prepend an additional hyphen to activate this code +for i=0, #command do + print (command[i]) +end +os.exit(ret) +--]] + +ret=os.spawn(command) +os.exit(ret) 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 @@ +<?xml version="1.0" encoding="us-ascii"?> +<project name="pax" default="dist" basedir="."> + <description> + Build file for PDFAnnotExtractor + </description> + + <property name="src" location="src"/> + <property name="build" location="build"/> + <property name="dist" location="."/> + <property name="pdfbox.home" location="${basedir}"/> <!-- or somewhere else --> + <property name="pdfbox.name" value="PDFBox-0.7.2.jar"/> + + <target name="init"> + <mkdir dir="${build}"/> + </target> + + <target name="compile" + depends="init" + description="compile the source" + > + <javac srcdir="${src}" destdir="${build}" target="1.4" source="1.4"> + <classpath> + <!-- try with and without subdirectory `lib' --> + <pathelement location="${pdfbox.home}/lib/${pdfbox.name}"/> + <pathelement location="${pdfbox.home}/${pdfbox.name}"/> + </classpath> + </javac> + </target> + + <target name="dist" + depends="compile" + description="generate the distribution" + > + <mkdir dir="${dist}"/> + <jar jarfile="${dist}/${ant.project.name}.jar" + manifest="${src}/MANIFEST.MF" + basedir="${build}" + includes="pax/**" + /> + </target> + + <target name="clean" + description="clean up" + > + <delete dir="${build}"/> + <delete file="${dist}/${ant.project.name}.jar"/> + </target> + +</project> 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. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <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., 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. + + <signature of Ty Coon>, 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 <pdffiles[.pdf]>"; + 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")); + } +} diff --git a/Master/texmf-dist/tex/latex/pax/pax.sty b/Master/texmf-dist/tex/latex/pax/pax.sty new file mode 100644 index 00000000000..7623c87c769 --- /dev/null +++ b/Master/texmf-dist/tex/latex/pax/pax.sty @@ -0,0 +1,607 @@ +%% pax.sty +%% Copyright 2006, 2007 Heiko Oberdiek +% +% 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 Heiko Oberdiek. +% +% This work consists of the file pax.sty. +% See README for more details and documentation. +% +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{pax}% + [2007/07/19 v0.1h Annotation support for PDF graphics (HO)]% + +\RequirePackage{ifpdf} +\ifpdf +\else + \PackageError{pax}{Missing pdfTeX in PDF mode}{% + Other drivers are not supported.% + }% + \expandafter\endinput +\fi + +\begingroup\expandafter\expandafter\expandafter\endgroup +\expandafter\ifx\csname pdfstrcmp\endcsname\relax + \PackageError{pax}{pdfTeX is too old}{% + The package uses features of pdfTeX 1.30.% + }% + \expandafter\endinput +\fi + +\RequirePackage{graphicx} +\RequirePackage{kvoptions}[2006/08/17] +\RequirePackage{auxhook} +\RequirePackage{etexcmds} + +% the local variant to LaTeX's \g@addto@macro, +% see also discussion in de.comp.text.tex. +\ifetex@unexpanded + \newcommand{\PAX@l@addto@macro}[2]{% + \edef#1{% + \etex@unexpanded\expandafter{#1#2}% + }% + }% +\else + \newcommand{\PAX@l@addto@macro}[2]{% + \global\let\PAX@g@temp#1% + \g@addto@macro\PAX@g@temp{#2}% + \let#1\PAX@g@temp + }% +\fi + +% Hook into \includegraphics of graphicx with one optional +% star, one optional argument with key value pairs and +% the graphics name +\let\PAX@ORG@includegraphics\includegraphics +\def\includegraphics{% + \@ifstar{% + \@ifnextchar[{% + \begingroup + \def\x{\endgroup + \PAX@includegraphics[clip,% + }% + \expandafter\x\@gobble + }{% + \PAX@includegraphics[clip]% + }% + }{% + \@ifnextchar[{% + \PAX@includegraphics + }{% + \PAX@includegraphics[]% + }% + }% +} +\def\PAX@includegraphics[#1]#2{% + \begingroup + \sbox0{\PAX@ORG@includegraphics[{#1}]{#2}}% + \edef\PAX@inc@width{\the\wd0}% + \edef\PAX@inc@height{\the\dimexpr\dp0+\ht0}% + \leavevmode + \hbox to \wd0{% + \rlap{\copy0}% + \raise-\dp0\hbox{% + \PAX@AddAnnots{#1}{#2}% + }% + \hfill + }% + \endgroup +} + +\SetupKeyvalOptions{family=PAX@Gin,prefix=PAX@Gin@} +\DeclareStringOption[1]{page} +\DeclareStringOption[0]{angle} +\DeclareBoolOption{clip} +\define@key{PAX@Gin}{viewport}{% + \PAX@l@addto@macro\PAX@Gin@box@opts{% + \PAX@viewport#1\\% + }% +} +\define@key{PAX@Gin}{trim}{% + \PAX@l@addto@macro\PAX@Gin@box@opts{% + \PAX@trim#1\\% + }% +} +\let\PAX@Gin@box@opts\@empty + +\def\PAX@viewport#1 #2 #3 #4\\{% + \PAX@defaultbp\PAX@vllx{#1}% + \PAX@defaultbp\PAX@vlly{#2}% + \PAX@defaultbp\PAX@vurx{#3}% + \PAX@defaultbp\PAX@vury{#4}% + \edef\PAX@page@llx{\dimexpr\PAX@page@llx+\PAX@vllx\relax}% + \edef\PAX@page@lly{\dimexpr\PAX@page@lly+\PAX@vlly\relax}% + \edef\PAX@page@urx{\dimexpr\PAX@page@llx+\PAX@vlly\relax}% + \edef\PAX@page@ury{\dimexpr\PAX@page@lly+\PAX@vury\relax}% +} +\def\PAX@trim#1 #2 #3 #4\\{% + \PAX@defaultbp\PAX@tllx{#1}% + \PAX@defaultbp\PAX@tlly{#2}% + \PAX@defaultbp\PAX@turx{#3}% + \PAX@defaultbp\PAX@tury{#4}% + \edef\PAX@page@llx{\dimexpr\PAX@page@llx+\PAX@tllx\relax}% + \edef\PAX@page@lly{\dimexpr\PAX@page@lly+\PAX@tlly\relax}% + \edef\PAX@page@urx{\dimexpr\PAX@page@urx-\PAX@turx\relax}% + \edef\PAX@page@ury{\dimexpr\PAX@page@ury-\PAX@tury\relax}% +} + +\def\PAX@defaultbp#1#2{% + \afterassignment\PAX@def@bp\dimen@#2bp\relax{#1}{#2}% +} +\def\PAX@def@bp#1\relax#2#3{% + \if!#1!% + \edef#2{#3bp}% + \else + \edef#2{#3}% + \fi +} + +\def\PAX@KV@errx#1{} + +\def\PAX@AddAnnots#1#2{% + \let\KV@errx\PAX@KV@errx + \setkeys{PAX@Gin}{#1}% + \Grot@setangle{\PAX@Gin@angle}% + % a little careful, is type of angle int or real? + \loop + \ifdim\PAX@Gin@angle\p@<360\p@ + \else + \edef\PAX@Gin@angle{\the\numexpr-360+\number\PAX@Gin@angle}% + \repeat + \loop + \ifdim\PAX@Gin@angle\p@<\z@ + \edef\PAX@Gin@angle{\strip@pt\dimexpr\PAX@Gin@angle\p@+360\p@}% + \repeat + \ifcase0\ifnum\PAX@Gin@angle=0 1\fi + \ifnum\PAX@Gin@angle=90 1\fi + \ifnum\PAX@Gin@angle=180 1\fi + \ifnum\PAX@Gin@angle=270 1\fi + \PackageWarning{pax}{Unsupported value for option angle}% + \fi + \filename@parse{#2}% + \def\PAX@file{\filename@area\filename@base.pax}% + \let\[\PAX@parser + \def\<{<}% + \def\>{>}% + \endlinechar=-1 % + \InputIfFileExists\PAX@file{% + }{% + \typeout{* Missing: \PAX@file}% + }% +} +\def\PAX@parser#1{\PAX@call{cmd}{#1}{}}% +\def\PAX@call#1#2#3{% + \@ifundefined{PAX@#1@#2}\PAX@skip{#3\csname PAX@#1@#2\endcsname}% +} +\def\PAX@skip#1\\{} +\def\PAX@stop#1\\{} + +\def\PAX@cmd@page#1#2{% + \PAX@filter@page{#1}{% + \PAX@getrect{page}#2\@nil + \PAX@Gin@box@opts + \ifcase0\ifnum\PAX@Gin@angle=90 1\fi + \ifnum\PAX@Gin@angle=270 1\fi + \else + \let\PAX@temp\PAX@inc@width + \let\PAX@inc@width\PAX@inc@height + \let\PAX@inc@height\PAX@temp + \fi + \Gscale@div\PAX@scale@x\PAX@inc@width{% + \dimexpr\PAX@page@urx-\PAX@page@llx\relax + }% + \Gscale@div\PAX@scale@y\PAX@inc@height{% + \dimexpr\PAX@page@ury-\PAX@page@lly\relax + }% + \PAX@skip + }% +} +\def\PAX@filter@page#1{% + \ifnum\PAX@Gin@page=#1 % + \expandafter\@firstofone + \else + \ifnum\PAX@Gin@page<#1 % + \csname fi\endcsname + \csname fi\endcsname + \expandafter\PAX@stop\@gobblefour + \fi + \expandafter\PAX@skip + \fi +} +\def\PAX@getrect#1#2 #3 #4 #5\@nil{% + \@namedef{PAX@#1@llx}{#2bp}% + \@namedef{PAX@#1@lly}{#3bp}% + \@namedef{PAX@#1@urx}{#4bp}% + \@namedef{PAX@#1@ury}{#5bp}% +} + +\def\PAX@cmd@annot#1#2{% + \PAX@filter@page{#1}{% + \PAX@call{annot}{#2}{}% + }% +} +\def\PAX@annot@Link#1#2#3{% + \def\PAX@link@type{#2}% + \PAX@call{link}{#2}{% + \begingroup + \PAX@getrect{annot}#1\@nil + \setkeys{PAX}{#3}% + }% + \PAX@skip +} +\newif\ifPAX@ok +\PAX@oktrue + +\newif\ifPAX@GoTo + +\def\PAX@pdf@annot#1{% + \ifPAX@Gin@clip + \ifdim\PAX@annot@llx<\PAX@page@llx + \let\PAX@annot@llx\PAX@pagellx + \fi + \ifdim\PAX@annot@lly<\PAX@page@lly + \let\PAX@annot@lly\PAX@page@lly + \fi + \ifdim\PAX@annot@urx>\PAX@page@urx + \let\PAX@annot@urx\PAX@page@urx + \fi + \ifdim\PAX@annot@ury>\PAX@page@ury + \let\PAX@annot@ury\PAX@page@ury + \fi + \PAX@okfalse + \ifdim\PAX@annot@llx<\PAX@annot@urx + \ifdim\PAX@annot@lly<\PAX@annot@ury + \PAX@oktrue + \fi + \fi + \else + \PAX@oktrue + \fi + \ifPAX@ok + \ifcase 0\ifnum\PAX@Gin@angle=90 1\fi + \ifnum\PAX@Gin@angle=180 2\fi + \ifnum\PAX@Gin@angle=270 3\fi\space + % angle = 0 + \def\PAX@raise{% + \PAX@scale@y\dimexpr\PAX@annot@lly-\PAX@page@lly\relax + }% + \def\PAX@right{% + \PAX@scale@x\dimexpr\PAX@annot@llx-\PAX@page@llx\relax + }% + \or % angle = 90 + \def\PAX@raise{% + \PAX@scale@x\dimexpr\PAX@annot@llx-\PAX@page@llx\relax + }% + \def\PAX@right{% + \PAX@scale@y\dimexpr\PAX@page@ury-\PAX@annot@ury\relax + }% + \or % angle = 180 + \def\PAX@raise{% + \PAX@scale@y\dimexpr\PAX@page@ury-\PAX@annot@ury\relax + }% + \def\PAX@right{% + \PAX@scale@x\dimexpr\PAX@page@urx-\PAX@annot@urx\relax + }% + \or % angle = 270 + \def\PAX@raise{% + \PAX@scale@x\dimexpr\PAX@page@urx-\PAX@annot@urx\relax + }% + \def\PAX@right{% + \PAX@scale@y\dimexpr\PAX@annot@lly-\PAX@page@lly\relax + }% + \fi + \@namedef{% + PAX@% + \ifcase0\ifnum\PAX@Gin@angle=90 1\fi + \ifnum\PAX@Gin@angle=270 1\fi\space + width% + \else + height% + \fi + }{% + \PAX@scale@x\dimexpr\PAX@annot@urx-\PAX@annot@llx\relax + }% + \@namedef{% + PAX@% + \ifcase0\ifnum\PAX@Gin@angle=90 1\fi + \ifnum\PAX@Gin@angle=270 1\fi\space + height% + \else + width% + \fi + }{% + \PAX@scale@y\dimexpr\PAX@annot@ury-\PAX@annot@lly\relax + }% + \raise\PAX@raise\hb@xt@\z@{% + \kern\PAX@right + \ifPAX@GoTo + \pdfstartlink\@width\PAX@width\@height\PAX@height\@depth\z@ + attr{\PAX@set@attrs}% + goto name{PAX@\PAX@file @\PAX@key@DestLabel}\relax + \pdfendlink + \else + \pdfannot\@width\PAX@width\@height\PAX@height{% + /Subtype/Link% + \PAX@set@attrs + /A<<% + /Type/Action% + /S/\PAX@link@type + #1% + >>% + }% + \fi + \hss + }% + \fi + \endgroup +} + +\def\PAX@set@attrs{% + \PAX@attrs\PAX@link@type{% + \PAX@set@attr{C}\PAX@key@C + \PAX@set@attr{Border}\PAX@key@Border + \PAX@set@attr{BS}\PAX@key@BS + \PAX@set@attr{H}\PAX@key@H + }% +} + +\def\PAX@set@attr#1#2{% + \ifx#2\@empty + \else + /#1 #2% + \fi +} + +\def\PAX@attrs#1{% + \@ifundefined{PAX@attrs@#1}{% + \@ifundefined{hyperref}{% + \@firstofone + }{% + \Hy@setpdfborder + /H\@pdfhighlight + \@ifundefined{PAX@htype@#1}\@firstofone{% + \@ifundefined{@\@nameuse{PAX@htype@#1}bordercolor}\@firstofone{% + /C[\@nameuse{@\@nameuse{PAX@htype@#1}bordercolor}]% + \@gobble + }% + }{% + \PAX@set@attr{C}\PAX@key@C + }% + \@gobble + }% + }{% + \@nameuse{PAX@attrs@#1}% + }% +} +\def\PAX@htype@GoToR{file} +\def\PAX@htype@GoTo{link} +\def\PAX@htype@Named{link} +\def\PAX@htype@URI{url} + +\def\PAX@link@URI{% + \PAX@pdf@annot{% + /URI\PAX@key@URI + }% +} +\def\PAX@link@Named{% + \PAX@pdf@annot{% + /N/\pdfescapename{\PAX@key@Name}% + }% +} +\def\PAX@link@GoToR{% + \PAX@pdf@annot{% + /F\PAX@key@File + /D% + \ifx\PAX@key@DestName\@empty + [\PAX@key@DestPage\space\PAX@key@DestView]% + \else + \PAX@key@DestName + \fi + }% +} + +% GoTo + +\AddLineBeginAux{% + \string\providecommand{\string\PAX@DestReq}[2]{}% +} +\AddLineBeginAux{% + \string\providecommand{\string\PAX@DestProv}[2]{}% +} +\AtBeginDocument{% + \let\PAX@DestReq\@gobbletwo + \let\PAX@DestProv\@gobbletwo +} +\def\PAX@DestReq#1#2{% + \expandafter\gdef\csname PAX@REQ@#1@#2\endcsname{}% +} +\def\PAX@DestProv#1#2{% + \expandafter\gdef\csname PAX@PROV@#1@#2\endcsname{}% +} + +\def\PAX@link@GoTo{% + \ifnum0<0\PAX@key@DestLabel\relax + \expandafter\@firstofone + \else + \endgroup + \expandafter\@gobble + \fi + {% + \if@filesw + \protected@write\@auxout{}{% + \string\PAX@DestReq{\PAX@file}{\PAX@key@DestLabel}% + }% + \fi + % Generate link, if destination exists + \@ifundefined{PAX@PROV@\PAX@file @\PAX@key@DestLabel}{% + \endgroup + }{% + \PAX@GoTotrue + \PAX@pdf@annot{}% + }% + }% +} + +% Read destinations +\def\PAX@cmd@dest#1#2#3#4{% + \PAX@filter@page{#1}{% + \if@filesw + \protected@write\@auxout{}{% + \string\PAX@DestProv{\PAX@file}{#2}% + }% + \fi + \@ifundefined{PAX@REQ@\PAX@file @#2}{% + }{% + \begingroup + \let\PAX@key@DestY\PAX@page@ury + \let\PAX@key@DestX\PAX@page@llx + \setkeys{PAX}{#4}% + \let\PAX@dest@llx\PAX@key@DestX + \let\PAX@dest@urx\PAX@key@DestX + \let\PAX@dest@lly\PAX@key@DestY + \let\PAX@dest@ury\PAX@key@DestY + \ifx\PAX@key@DestRect\@empty + \else + \def\PAX@temp{dest}% + \expandafter\PAX@getrect\expandafter\PAX@temp + \PAX@key@DestRect\@nil + \fi + \ifPAX@Gin@clip + \ifx\PAX@dest@llx<\PAX@page@llx + \let\PAX@dest@llx\PAX@page@llx + \fi + \ifx\PAX@dest@lly<\PAX@page@lly + \let\PAX@dest@lly\PAX@page@lly + \fi + \ifx\PAX@dest@urx>\PAX@page@urx + \let\PAX@dest@urx\PAX@page@urx + \fi + \ifx\PAX@dest@ury>\PAX@page@ury + \let\PAX@dest@ury\PAX@page@ury + \fi + % at least prevent destinations outside the window + \ifx\PAX@dest@llx>\PAX@page@urx + \PAX@dest@llx\PAX@page@urx + \fi + \ifx\PAX@dest@lly>\PAX@page@ury + \PAX@dest@lly\PAX@page@ury + \fi + \ifx\PAX@dest@urx<\PAX@page@llx + \PAX@dest@urx\PAX@page@llx + \fi + \ifx\PAX@dest@ury<\PAX@page@lly + \PAX@dest@ury\PAX@page@lly + \fi + \fi + % I don't know, what is the best idea for rotated stuff, + % perhaps using the corner llx/ury + \ifcase 0\ifnum\PAX@Gin@angle=90 1\fi + \ifnum\PAX@Gin@angle=180 2\fi + \ifnum\PAX@Gin@angle=270 3\fi\space + % angle = 0 + \def\PAX@raise{% + \PAX@scale@y\dimexpr\PAX@dest@lly-\PAX@page@lly\relax + }% + \def\PAX@right{% + \PAX@scale@x\dimexpr\PAX@dest@llx-\PAX@page@llx\relax + }% + \or % angle = 90 + \def\PAX@raise{% + \PAX@scale@x\dimexpr\PAX@dest@llx-\PAX@page@llx\relax + }% + \def\PAX@right{% + \PAX@scale@y\dimexpr\PAX@page@ury-\PAX@dest@ury\relax + }% + \or % angle = 180 + \def\PAX@raise{% + \PAX@scale@y\dimexpr\PAX@page@ury-\PAX@dest@ury\relax + }% + \def\PAX@right{% + \PAX@scale@x\dimexpr\PAX@page@urx-\PAX@dest@urx\relax + }% + \or % angle = 270 + \def\PAX@raise{% + \PAX@scale@x\dimexpr\PAX@page@urx-\PAX@dest@urx\relax + }% + \def\PAX@right{% + \PAX@scale@y\dimexpr\PAX@dest@lly-\PAX@page@lly\relax + }% + \fi + \edef\PAX@name{name{PAX@\PAX@file @#2}}% + \let\PAX@type\@empty + \ifcase\pdfstrcmp{#3}{FITR}\relax + \def\PAX@type{xyz}% too lazy for now + \fi + \ifcase\pdfstrcmp{#3}{XYZ}\relax + \def\PAX@type{xyz}% + \ifx\PAX@key@DestZoom\@empty + \else + \edef\PAX@type{% + \PAX@type + zoom\numexpr1000*\number\dimexpr\PAX@key@DestZoom pt\relax + /\number\p@\relax + }% + \fi + \fi + \ifcase\pdfstrcmp{#3}{FIT}\relax + \def\PAX@type{fit}% + \fi + \ifcase\pdfstrcmp{#3}{FITB}\relax + \def\PAX@type{fitb}% + \fi + \ifcase\pdfstrcmp{#3}{FITH}\relax + \def\PAX@type{fith}% + \fi + \ifcase\pdfstrcmp{#3}{FITBH}\relax + \def\PAX@type{fitbh}% + \fi + \ifcase\pdfstrcmp{#3}{FITV}\relax + \def\PAX@type{fitv}% + \fi + \ifcase\pdfstrcmp{#3}{FITBV}\relax + \def\PAX@type{fitbv}% + \fi + \ifx\PAX@type\@empty + \def\PAX@type{xyz}% + \fi + \raise\PAX@raise\hb@xt@\z@{% + \kern\PAX@right + \pdfdest\PAX@name\PAX@type\relax + \hss + }% + \endgroup + }% + \PAX@skip + }% +} + +\SetupKeyvalOptions{family=PAX,prefix=PAX@key@} +\DeclareStringOption{URI} +\DeclareStringOption{Name} +\DeclareStringOption{DestName} +\DeclareStringOption{DestPage} +\DeclareStringOption{DestView} +\DeclareStringOption{File} +\DeclareStringOption{C} +\DeclareStringOption{Border} +\DeclareStringOption{BS} +\DeclareStringOption{H} +\DeclareStringOption{DestLabel} +\DeclareStringOption{DestRect} +\DeclareStringOption{DestZoom} +\define@key{PAX}{DestX}{% + \PAX@defaultbp\PAX@key@DestX{#1}% +} +\define@key{PAX}{DestY}{% + \PAX@defaultbp\PAX@key@DestY{#1}% +} +\endinput |